revert between 56095 -> 55830 in arch
[AROS.git] / arch / all-hosted / hidd / x11 / x11gfx_hiddclass.c
blob9cdef10bf7c79b9262fc129eced5dda377979753
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: X11 gfx HIDD for AROS.
6 Lang: English.
7 */
9 #include "x11_debug.h"
11 #define __OOP_NOATTRBASES__
13 #include <proto/utility.h>
15 #include <X11/cursorfont.h>
16 #include <signal.h>
18 #include "x11_types.h"
19 #include LC_LIBDEFS_FILE
20 #include "x11_hostlib.h"
21 #include "x11_xshm.h"
23 #define XFLUSH(x) XCALL(XFlush, x)
25 /****************************************************************************************/
27 #define IS_X11GFX_ATTR(attr, idx) ( ( (idx) = (attr) - HiddX11GfxAB) < num_Hidd_BitMap_X11_Attrs)
29 int xshm_major;
31 /* Some attrbases needed as global vars.
32 These are write-once read-many */
34 OOP_AttrBase HiddBitMapAttrBase;
35 OOP_AttrBase HiddX11BitMapAB;
36 OOP_AttrBase HiddSyncAttrBase;
37 OOP_AttrBase HiddPixFmtAttrBase;
38 OOP_AttrBase HiddGfxAttrBase;
39 OOP_AttrBase HiddAttrBase;
41 static const struct OOP_ABDescr attrbases[] =
43 { IID_Hidd_BitMap , &HiddBitMapAttrBase },
44 { IID_Hidd_BitMap_X11 , &HiddX11BitMapAB },
45 { IID_Hidd_Sync , &HiddSyncAttrBase },
46 { IID_Hidd_PixFmt , &HiddPixFmtAttrBase },
47 { IID_Hidd_Gfx , &HiddGfxAttrBase },
48 { IID_Hidd , &HiddAttrBase },
49 { NULL , NULL }
52 static VOID cleanupx11stuff(struct x11_staticdata *xsd);
53 static BOOL initx11stuff(struct x11_staticdata *xsd);
54 static ULONG mask_to_shift(ULONG mask);
56 /****************************************************************************************/
58 OOP_Object *X11Cl__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
60 struct TagItem pftags[] =
62 { aHidd_PixFmt_RedShift , 0 }, /* 0 */
63 { aHidd_PixFmt_GreenShift , 0 }, /* 1 */
64 { aHidd_PixFmt_BlueShift , 0 }, /* 2 */
65 { aHidd_PixFmt_AlphaShift , 0 }, /* 3 */
66 { aHidd_PixFmt_RedMask , 0 }, /* 4 */
67 { aHidd_PixFmt_GreenMask , 0 }, /* 5 */
68 { aHidd_PixFmt_BlueMask , 0 }, /* 6 */
69 { aHidd_PixFmt_AlphaMask , 0 }, /* 7 */
70 { aHidd_PixFmt_ColorModel , 0 }, /* 8 */
71 { aHidd_PixFmt_Depth , 0 }, /* 9 */
72 { aHidd_PixFmt_BytesPerPixel, 0 }, /* 10 */
73 { aHidd_PixFmt_BitsPerPixel , 0 }, /* 11 */
74 { aHidd_PixFmt_StdPixFmt , 0 }, /* 12 */
75 { aHidd_PixFmt_CLUTShift , 0 }, /* 13 */
76 { aHidd_PixFmt_CLUTMask , 0 }, /* 14 */
77 { aHidd_PixFmt_BitMapType , 0 }, /* 15 */
78 { TAG_DONE , 0UL }
81 struct TagItem tags_160_160[] =
83 { aHidd_Sync_HDisp , 160 },
84 { aHidd_Sync_VDisp , 160 },
85 { aHidd_Sync_Description, (IPTR)"X11:160x160" },
86 { TAG_DONE , 0UL }
89 struct TagItem tags_240_320[] =
91 { aHidd_Sync_HDisp , 240 },
92 { aHidd_Sync_VDisp , 320 },
93 { aHidd_Sync_Description, (IPTR)"X11:240x320" },
94 { TAG_DONE , 0UL }
97 struct TagItem tags_320_240[] =
99 { aHidd_Sync_HDisp , 320 },
100 { aHidd_Sync_VDisp , 240 },
101 { aHidd_Sync_Description, (IPTR)"X11:320x240" },
102 { TAG_DONE , 0UL }
105 struct TagItem tags_512_384[] =
107 { aHidd_Sync_HDisp , 512 },
108 { aHidd_Sync_VDisp , 384 },
109 { aHidd_Sync_Description, (IPTR)"X11:512x384" },
110 { TAG_DONE , 0UL }
113 struct TagItem tags_640_480[] =
115 { aHidd_Sync_HDisp , 640 },
116 { aHidd_Sync_VDisp , 480 },
117 { aHidd_Sync_Description, (IPTR)"X11:640x480" },
118 { TAG_DONE , 0UL }
121 struct TagItem tags_800_600[] =
123 { aHidd_Sync_HDisp , 800 },
124 { aHidd_Sync_VDisp , 600 },
125 { aHidd_Sync_Description, (IPTR)"X11:800x600" },
126 { TAG_DONE , 0UL }
129 struct TagItem tags_1024_768[] =
131 { aHidd_Sync_HDisp , 1024 },
132 { aHidd_Sync_VDisp , 768 },
133 { aHidd_Sync_Description, (IPTR)"X11:1024x768" },
134 { TAG_DONE , 0UL }
137 struct TagItem tags_1152_864[] =
139 { aHidd_Sync_HDisp , 1152 },
140 { aHidd_Sync_VDisp , 864 },
141 { aHidd_Sync_Description, (IPTR)"X11:1152x864" },
142 { TAG_DONE , 0UL }
145 struct TagItem tags_1280_800[] =
147 { aHidd_Sync_HDisp , 1280 },
148 { aHidd_Sync_VDisp , 800 },
149 { aHidd_Sync_Description, (IPTR)"X11:1280x800" },
150 { TAG_DONE , 0UL }
153 struct TagItem tags_1280_960[] =
155 { aHidd_Sync_HDisp , 1280 },
156 { aHidd_Sync_VDisp , 960 },
157 { aHidd_Sync_Description, (IPTR)"X11:1280x960" },
158 { TAG_DONE , 0UL }
161 struct TagItem tags_1280_1024[] =
163 { aHidd_Sync_HDisp , 1280 },
164 { aHidd_Sync_VDisp , 1024 },
165 { aHidd_Sync_Description, (IPTR)"X11:1280x1024" },
166 { TAG_DONE , 0UL }
169 struct TagItem tags_1400_1050[] =
171 { aHidd_Sync_HDisp , 1400 },
172 { aHidd_Sync_VDisp , 1050 },
173 { aHidd_Sync_Description, (IPTR)"X11:1400x1050" },
174 { TAG_DONE , 0UL }
177 struct TagItem tags_1600_1200[] =
179 { aHidd_Sync_HDisp , 1600 },
180 { aHidd_Sync_VDisp , 1200 },
181 { aHidd_Sync_Description, (IPTR)"X11:1600x1200" },
182 { TAG_DONE , 0UL }
185 struct TagItem tags_1680_1050[] =
187 { aHidd_Sync_HDisp , 1680 },
188 { aHidd_Sync_VDisp , 1050 },
189 { aHidd_Sync_Description, (IPTR)"X11:1680x1050" },
190 { TAG_DONE , 0UL }
193 struct TagItem tags_1920_1080[] =
195 { aHidd_Sync_HDisp , 1920 },
196 { aHidd_Sync_VDisp , 1080 },
197 { aHidd_Sync_Description, (IPTR)"X11:1920x1080" },
198 { TAG_DONE , 0UL }
201 struct TagItem tags_1920_1200[] =
203 { aHidd_Sync_HDisp , 1920 },
204 { aHidd_Sync_VDisp , 1200 },
205 { aHidd_Sync_Description, (IPTR)"X11:1920x1200" },
206 { TAG_DONE , 0UL }
209 /* Default display modes. Used on displays which do not support Free86-VidModeExtension */
210 struct TagItem default_mode_tags[] =
212 { aHidd_Gfx_PixFmtTags , (IPTR)pftags },
213 { aHidd_Gfx_SyncTags , (IPTR)tags_160_160 },
214 { aHidd_Gfx_SyncTags , (IPTR)tags_240_320 },
215 { aHidd_Gfx_SyncTags , (IPTR)tags_320_240 },
216 { aHidd_Gfx_SyncTags , (IPTR)tags_512_384 },
217 { aHidd_Gfx_SyncTags , (IPTR)tags_640_480 },
218 { aHidd_Gfx_SyncTags , (IPTR)tags_800_600 },
219 { aHidd_Gfx_SyncTags , (IPTR)tags_1024_768 },
220 { aHidd_Gfx_SyncTags , (IPTR)tags_1152_864 },
221 { aHidd_Gfx_SyncTags , (IPTR)tags_1280_800 },
222 { aHidd_Gfx_SyncTags , (IPTR)tags_1280_960 },
223 { aHidd_Gfx_SyncTags , (IPTR)tags_1280_1024 },
224 { aHidd_Gfx_SyncTags , (IPTR)tags_1400_1050 },
225 { aHidd_Gfx_SyncTags , (IPTR)tags_1600_1200 },
226 { aHidd_Gfx_SyncTags , (IPTR)tags_1680_1050 },
227 { aHidd_Gfx_SyncTags , (IPTR)tags_1920_1080 },
228 { aHidd_Gfx_SyncTags , (IPTR)tags_1920_1200 },
229 { TAG_DONE , 0UL }
232 struct TagItem *mode_tags = NULL;
234 struct TagItem mytags[] =
236 { aHidd_Gfx_ModeTags , (IPTR)default_mode_tags },
237 { aHidd_Name , (IPTR)"X11" },
238 { aHidd_HardwareName , (IPTR)"X Window Gfx Host" },
239 { aHidd_ProducerName , (IPTR)"X.Org Foundation" },
240 { TAG_MORE , (IPTR)msg->attrList }
243 struct pRoot_New mymsg = { msg->mID, mytags };
245 struct TagItem *resolution = NULL;
246 XF86VidModeModeInfo** modes = NULL;
247 static int modeNum = 0;
248 ULONG realmode = 0;
250 ULONG i, screen;
251 Display *disp;
253 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
255 /* Do GfxHidd initalization here */
256 if (!initx11stuff(XSD(cl)))
258 D(bug("[X11Gfx] %s: initialisation failed!\n", __PRETTY_FUNCTION__));
259 return NULL;
262 /* Get supported X11 resolution from RandR resources */
264 disp = XCALL(XOpenDisplay, NULL);
265 screen = XCALL(XDefaultScreen, disp);
266 // rootwin = XCALL(XRootWindow, disp, screen);
268 if (!(XSD(cl)->options & OPTION_FORCESTDMODES))
270 XVMCALL(XF86VidModeGetAllModeLines, disp, screen, &modeNum, &modes);
271 D(bug("[X11Gfx] Found %u modes, table at 0x%P\n", modeNum, modes));
273 if (modeNum)
275 /* Got XF86VidMode data, use it */
276 if ((resolution = AllocMem(modeNum * sizeof(struct TagItem) * 4, MEMF_PUBLIC)) == NULL)
278 D(bug("[X11] failed to allocate memory for %d modes: %d !!!\n", modeNum, XSD(cl)->vi->class));
280 XCALL(XCloseDisplay, disp);
281 cleanupx11stuff(XSD(cl));
283 return NULL;
286 for(i = 0; i < modeNum; i++)
288 ULONG j;
289 BOOL insert;
290 insert = TRUE;
292 /* avoid duplicated resolution */
293 for(j = 0; j < realmode; j++)
295 if(resolution[j * 4].ti_Data == modes[i]->hdisplay && resolution[j * 4 + 1].ti_Data == modes[i]->vdisplay)
296 { /* Found a matching resolution. Don't insert ! */
297 insert = FALSE;
301 if(insert)
303 resolution[realmode * 4 + 0].ti_Tag = aHidd_Sync_HDisp;
304 resolution[realmode * 4 + 0].ti_Data = modes[i]->hdisplay;
306 resolution[realmode * 4 + 1].ti_Tag = aHidd_Sync_VDisp;
307 resolution[realmode * 4 + 1].ti_Data = modes[i]->vdisplay;
309 resolution[realmode * 4 + 2].ti_Tag = aHidd_Sync_Description;
310 resolution[realmode * 4 + 2].ti_Data = (IPTR)"X11: %hx%v";
312 resolution[realmode * 4 + 3].ti_Tag = TAG_DONE;
313 resolution[realmode * 4 + 3].ti_Data = 0UL;
315 realmode++;
319 if((mode_tags = AllocMem(sizeof(struct TagItem) * (realmode + 2), MEMF_PUBLIC)) == NULL)
321 D(bug("[X11] failed to allocate memory for mode tag's: %d !!!\n", XSD(cl)->vi->class));
323 FreeMem(resolution, modeNum * sizeof(struct TagItem) * 4);
324 XCALL(XCloseDisplay, disp);
325 cleanupx11stuff(XSD(cl));
327 return NULL;
330 mode_tags[0].ti_Tag = aHidd_Gfx_PixFmtTags;
331 mode_tags[0].ti_Data = (IPTR)pftags;
333 /* The different screenmode from XF86VMODE */
334 for(i=0; i < realmode; i++)
336 mode_tags[1 + i].ti_Tag = aHidd_Gfx_SyncTags;
337 mode_tags[1 + i].ti_Data = (IPTR)(resolution + i*4);
340 mode_tags[1 + i].ti_Tag = TAG_DONE;
341 mode_tags[1 + i].ti_Data = 0UL;
343 /* Use our new mode tags instead of default ones */
344 mytags[0].ti_Data = (IPTR)mode_tags;
348 /* Register gfxmodes */
349 pftags[0].ti_Data = XSD(cl)->red_shift;
350 pftags[1].ti_Data = XSD(cl)->green_shift;
351 pftags[2].ti_Data = XSD(cl)->blue_shift;
352 pftags[3].ti_Data = 0;
354 pftags[4].ti_Data = XSD(cl)->vi->red_mask;
355 pftags[5].ti_Data = XSD(cl)->vi->green_mask;
356 pftags[6].ti_Data = XSD(cl)->vi->blue_mask;
357 pftags[7].ti_Data = 0x00000000;
359 /* Support 32-bit modes (ie. odroid XU4 with 3D driver) */
360 if (XSD(cl)->depth > 24)
362 pftags[7].ti_Data = 0xFFFFFFFF ^ (XSD(cl)->vi->red_mask
363 | XSD(cl)->vi->green_mask | XSD(cl)->vi->blue_mask);
364 pftags[3].ti_Data = mask_to_shift(pftags[7].ti_Data);
367 if (XSD(cl)->vi->class == TrueColor)
369 pftags[8].ti_Data = vHidd_ColorModel_TrueColor;
371 else if (XSD(cl)->vi->class == PseudoColor)
373 pftags[8].ti_Data = vHidd_ColorModel_Palette;
374 pftags[13].ti_Data = XSD(cl)->clut_shift;
375 pftags[14].ti_Data = XSD(cl)->clut_mask;
377 else
379 D(bug("[X11Gfx] unsupported color model: %d\n", XSD(cl)->vi->class));
380 if (resolution)
382 FreeMem(resolution, modeNum * sizeof(struct TagItem) * 4);
383 FreeMem(mode_tags, sizeof(struct TagItem) * (realmode + 2));
385 XCALL(XCloseDisplay, disp);
386 cleanupx11stuff(XSD(cl));
388 return NULL;
391 pftags[9].ti_Data = XSD(cl)->depth;
392 pftags[10].ti_Data = XSD(cl)->bytes_per_pixel;
393 pftags[11].ti_Data = XSD(cl)->depth;
394 pftags[12].ti_Data = vHidd_StdPixFmt_Native;
396 /* FIXME: Do better than this */
398 /* We assume chunky */
399 pftags[15].ti_Data = vHidd_BitMapType_Chunky;
401 D(bug("Calling super method\n"));
403 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)&mymsg);
405 D(bug("Super method returned\n"));
407 FreeMem(resolution, modeNum * sizeof(struct TagItem) * 4);
408 FreeMem(mode_tags, sizeof(struct TagItem) * (realmode + 2));
409 XCALL(XCloseDisplay, disp);
411 if (NULL != o)
413 XColor bg, fg;
414 struct gfx_data *data = OOP_INST_DATA(cl, o);
416 data->basebm = OOP_FindClass(CLID_Hidd_BitMap);
417 bug("[X11] BitMap class @ 0x%p\n", data->basebm);
419 LOCK_X11
420 data->display = XSD(cl)->display;
421 data->screen = DefaultScreen( data->display );
422 data->depth = DisplayPlanes( data->display, data->screen );
423 data->colmap = DefaultColormap( data->display, data->screen );
424 D(bug("x11_func.XCreateFontCursor(%x), display(%x)\n", x11_func.XCreateFontCursor, data->display));
425 /* Create cursor */
426 data->cursor = XCALL(XCreateFontCursor, data->display, XC_top_left_arrow);
428 fg.pixel = BlackPixel(data->display, data->screen);
429 fg.red = 0x0000; fg.green = 0x0000; fg.blue = 0x0000;
430 fg.flags = (DoRed | DoGreen | DoBlue);
431 bg.pixel = WhitePixel(data->display, data->screen);
432 bg.red = 0xFFFF; bg.green = 0xFFFF; bg.blue = 0xFFFF;
433 bg.flags = (DoRed | DoGreen | DoBlue);
435 XCALL(XRecolorCursor, data->display, data->cursor, &fg, &bg);
437 if (XSD(cl)->options & OPTION_BACKINGSTORE)
439 switch(DoesBackingStore(ScreenOfDisplay(data->display, data->screen)))
441 case WhenMapped:
442 case Always:
443 break;
445 case NotUseful:
446 bug("\n"
447 "+----------------------------------------------------------+\n"
448 "| Your X Server seems to have backing store disabled! |\n"
449 "| =================================================== |\n"
450 "| |\n"
451 "| If possible you should try to switch it on, otherwise |\n"
452 "| AROS will have problems with its display. When the AROS |\n"
453 "| X window is hidden by other X windows, or is dragged |\n"
454 "| off screen, then the graphics in those parts will get |\n"
455 "| lost, unless backing store support is enabled. |\n"
456 "| |\n"
457 "| In case your X11 Server is XFree 4.x then switching on |\n"
458 "| backingstore support can be done by starting the X11 |\n"
459 "| server with something like \"startx -- +bs\". Depending |\n"
460 "| on what X driver you use it might also be possible |\n"
461 "| to turn it on by adding |\n"
462 "| |\n"
463 "| Option \"Backingstore\" |\n"
464 "| |\n"
465 "| to the Device Section of your X Window config file, |\n"
466 "| which usually is \"/etc/X11/xorg.conf\" |\n"
467 "| or \"/etc/X11/XFree86Config\" |\n"
468 "+----------------------------------------------------------+\n"
469 "\n");
470 break;
474 UNLOCK_X11
476 D(bug("[X11Gfx] Got object from super\n"));
478 data->display = XSD(cl)->display;
481 ReturnPtr("X11Gfx::New", OOP_Object *, o);
484 /********** GfxHidd::Dispose() ******************************/
485 VOID X11Cl__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
487 D(bug("[X11Gfx] %s(0x%p)\n", __PRETTY_FUNCTION__, o));
489 cleanupx11stuff(XSD(cl));
491 D(bug("X11Gfx::Dispose: calling super\n"));
492 OOP_DoSuperMethod(cl, o, msg);
496 /****************************************************************************************/
498 OOP_Object *X11Cl__Hidd_Gfx__CreateObject(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CreateObject *msg)
500 struct gfx_data *data = OOP_INST_DATA(cl, o);
501 OOP_Object *object = NULL;
503 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
505 if (msg->cl == data->basebm)
507 struct pHidd_Gfx_CreateObject p;
508 HIDDT_ModeID modeid;
509 struct gfx_data *data;
510 struct TagItem tags[] =
512 { aHidd_BitMap_X11_SysDisplay , 0 }, /* 0 */
513 { aHidd_BitMap_X11_SysScreen , 0 }, /* 1 */
514 { aHidd_BitMap_X11_SysCursor , 0 }, /* 2 */
515 { aHidd_BitMap_X11_ColorMap , 0 }, /* 3 */
516 { aHidd_BitMap_X11_VisualClass , 0 }, /* 4 */
517 { TAG_IGNORE , 0 }, /* 5 */
518 { TAG_MORE , 0 } /* 6 */
521 data = OOP_INST_DATA(cl, o);
523 tags[0].ti_Data = (IPTR)data->display;
524 tags[1].ti_Data = data->screen;
525 tags[2].ti_Data = (IPTR)data->cursor;
526 tags[3].ti_Data = data->colmap;
527 tags[4].ti_Data = XSD(cl)->vi->class;
528 tags[6].ti_Data = (IPTR)msg->attrList;
530 /* Displayable bitmap ? */
531 modeid = GetTagData(aHidd_BitMap_ModeID, vHidd_ModeID_Invalid, msg->attrList);
533 if (modeid != vHidd_ModeID_Invalid)
535 /* ModeID supplied, it's for sure X11 bitmap */
536 tags[5].ti_Tag = aHidd_BitMap_ClassPtr;
537 tags[5].ti_Data = (IPTR)XSD(cl)->bmclass;
540 p.mID = msg->mID;
541 p.cl = msg->cl;
542 p.attrList = tags;
544 object = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)&p);
546 else
547 object = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
549 ReturnPtr("X11Gfx::CreateObject", OOP_Object *, object);
552 /****************************************************************************************/
554 VOID X11Cl__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
556 ULONG idx;
558 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
560 if (IS_GFX_ATTR(msg->attrID, idx))
562 switch (idx)
564 case aoHidd_Gfx_IsWindowed:
565 *msg->storage = TRUE;
566 return;
568 case aoHidd_Gfx_HWSpriteTypes:
569 #if X11SOFTMOUSE
570 *msg->storage = 0;
571 #else
572 *msg->storage = vHidd_SpriteType_DirectColor;
573 return;
575 case aoHidd_Gfx_SupportsHWCursor:
576 *msg->storage = TRUE;
577 #endif
578 return;
580 case aoHidd_Gfx_DriverName:
581 *msg->storage = (IPTR) "X11";
582 return;
585 OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
588 /****************************************************************************************/
590 VOID X11Cl__Root__Set(OOP_Class *cl, OOP_Object *obj, struct pRoot_Set *msg)
592 struct TagItem *tag, *tstate;
593 ULONG idx;
594 struct x11_staticdata *data = XSD(cl);
596 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
598 tstate = msg->attrList;
599 while ((tag = NextTagItem(&tstate)))
601 if (IS_GFX_ATTR(tag->ti_Tag, idx))
603 switch (idx)
605 case aoHidd_Gfx_ActiveCallBack:
606 data->activecallback = (void *) tag->ti_Data;
607 break;
609 case aoHidd_Gfx_ActiveCallBackData:
610 data->callbackdata = (void *) tag->ti_Data;
611 break;
615 OOP_DoSuperMethod(cl, obj, &msg->mID);
618 /****************************************************************************************/
620 VOID X11Cl__Hidd_Gfx__CopyBox(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CopyBox *msg)
622 ULONG mode;
623 Drawable src = 0, dest = 0;
624 GC gc = 0;
626 struct gfx_data *data = OOP_INST_DATA(cl, o);
628 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
630 mode = GC_DRMD(msg->gc);
632 OOP_GetAttr(msg->src, aHidd_BitMap_X11_Drawable, (IPTR *) &src);
633 OOP_GetAttr(msg->dest, aHidd_BitMap_X11_Drawable, (IPTR *) &dest);
635 if (0 == dest || 0 == src)
638 * One of objects is not an X11 bitmap.
639 * Let the superclass do the copying in a more general way
641 OOP_DoSuperMethod(cl, o, &msg->mID);
642 return;
645 OOP_GetAttr(msg->src, aHidd_BitMap_X11_GC, (IPTR *) &gc);
647 HostLib_Lock();
649 XCALL(XSetFunction, data->display, gc, mode);
650 XCALL(XCopyArea,
651 data->display, src, dest, gc, msg->srcX, msg->srcY, msg->width, msg->height, msg->destX, msg->destY);
653 HostLib_Unlock();
656 /****************************************************************************************/
658 BOOL X11Cl__Hidd_Gfx__SetCursorShape(OOP_Class *cl, OOP_Object *o,
659 struct pHidd_Gfx_SetCursorShape *msg)
661 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
663 #if X11SOFTMOUSE
664 /* Dummy implementation */
665 return TRUE;
666 #else
667 BOOL success = TRUE;
668 IPTR width, height;
669 XcursorImage *image;
670 struct MsgPort *port;
671 struct notify_msg nmsg;
672 struct gfx_data *data = OOP_INST_DATA(cl, o);
674 /* Create an X11 cursor from the passed bitmap */
675 OOP_GetAttr(msg->shape, aHidd_BitMap_Width, &width);
676 OOP_GetAttr(msg->shape, aHidd_BitMap_Height, &height);
677 image = XCCALL(XcursorImageCreate, width, height);
679 HIDD_BM_GetImage(msg->shape, (UBYTE *)image->pixels, width * 4, 0, 0,
680 width, height, vHidd_StdPixFmt_BGRA32);
682 image->xhot = -msg->xoffset;
683 image->yhot = -msg->yoffset;
685 data->cursor = XCCALL(XcursorImageLoadCursor, data->display, image);
686 XCCALL(XcursorImageDestroy, image);
688 /* Tell the X11 task to change the pointer on all X windows */
689 port = CreateMsgPort();
690 if (port == NULL)
691 success = FALSE;
693 if (success)
695 nmsg.notify_type = NOTY_NEWCURSOR;
696 nmsg.xdisplay = data->display;
697 nmsg.xwindow = (Window)data->cursor;
698 nmsg.execmsg.mn_ReplyPort = port;
700 X11DoNotify(XSD(cl), &nmsg);
701 DeleteMsgPort(port);
704 return success;
705 #endif
708 /****************************************************************************************/
710 VOID X11Cl__Hidd_Gfx__SetCursorVisible(OOP_Class *cl, OOP_Object *o,
711 struct pHidd_Gfx_SetCursorVisible *msg)
713 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
715 #if X11SOFTMOUSE
716 /* Dummy implementation */
717 #else
718 BOOL success = TRUE;
719 struct MsgPort *port;
720 struct notify_msg nmsg;
721 struct gfx_data *data = OOP_INST_DATA(cl, o);
723 /* Tell the X11 task to change the pointer on all X windows */
724 port = CreateMsgPort();
725 if (port == NULL)
726 success = FALSE;
728 if (success)
730 nmsg.notify_type = NOTY_NEWCURSOR;
731 nmsg.xdisplay = data->display;
732 nmsg.xwindow = (Window) (msg->visible ? data->cursor : None);
733 nmsg.execmsg.mn_ReplyPort = port;
735 X11DoNotify(XSD(cl), &nmsg);
736 DeleteMsgPort(port);
738 #endif
740 return;
743 /****************************************************************************************/
745 static ULONG mask_to_shift(ULONG mask)
747 ULONG i;
749 for (i = 32; mask; i--)
751 mask >>= 1;
754 if (mask == 32)
756 i = 0;
759 return i;
762 /****************************************************************************************/
764 #undef XSD
765 #define XSD(cl) xsd
768 Inits sysdisplay, sysscreen, colormap, etc.. */
769 static BOOL initx11stuff(struct x11_staticdata *xsd)
771 /* XColor fg, bg; */
772 BOOL ok = TRUE;
773 XVisualInfo template;
774 XVisualInfo *visinfo;
775 int template_mask;
776 int numvisuals;
777 XImage *testimage;
779 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
781 if (!X11_Init(xsd))
782 return FALSE;
784 LOCK_X11
786 /* Get some info on the display */
787 template.visualid = XCALL(XVisualIDFromVisual, DefaultVisual(xsd->display, DefaultScreen(xsd->display)));
788 template_mask = VisualIDMask;
790 visinfo = XCALL(XGetVisualInfo, xsd->display, template_mask, &template, &numvisuals);
792 if (numvisuals > 1)
794 D(bug("[X11Gfx] %s: got %d visualinfo from X\n", __PRETTY_FUNCTION__, numvisuals));
796 // CCALL(raise, SIGSTOP);
799 if (NULL == visinfo)
801 D(bug("[X11Gfx] %s: no visualinfo available!\n", __PRETTY_FUNCTION__));
803 CCALL(raise, SIGSTOP);
805 ok = FALSE;
807 else
809 /* Store the visual info structure */
810 xsd->vi = AllocMem(sizeof(XVisualInfo), MEMF_ANY);
811 memcpy(xsd->vi, visinfo, sizeof(XVisualInfo));
813 XCALL(XFree, visinfo);
815 visinfo = xsd->vi;
817 /* We only support TrueColor for now */
819 switch (visinfo->class)
821 case TrueColor:
822 /* Get the pixel masks */
823 xsd->red_shift = mask_to_shift(xsd->vi->red_mask);
824 xsd->green_shift = mask_to_shift(xsd->vi->green_mask);
825 xsd->blue_shift = mask_to_shift(xsd->vi->blue_mask);
826 break;
828 case PseudoColor:
829 /* stegerg */
830 xsd->vi->red_mask = ((1 << xsd->vi->bits_per_rgb) - 1) << (xsd->vi->bits_per_rgb * 2);
831 xsd->vi->green_mask = ((1 << xsd->vi->bits_per_rgb) - 1) << (xsd->vi->bits_per_rgb * 1);
832 xsd->vi->blue_mask = ((1 << xsd->vi->bits_per_rgb) - 1);
833 xsd->red_shift = mask_to_shift(xsd->vi->red_mask);
834 xsd->green_shift = mask_to_shift(xsd->vi->green_mask);
835 xsd->blue_shift = mask_to_shift(xsd->vi->blue_mask);
836 /* end stegerg */
837 break;
839 default:
840 D(bug("[X11Gfx] %s: unsupported display mode!\n", __PRETTY_FUNCTION__));
842 CCALL(raise, SIGSTOP);
845 xsd->depth = 0;
847 /* stegerg: based on xwininfo source */
850 XWindowAttributes win_attributes;
852 if (!XCALL(XGetWindowAttributes, xsd->display,
853 RootWindow(xsd->display, DefaultScreen(xsd->display)),
854 &win_attributes))
856 D(bug("[X11Gfx] %s: failed to obtain bits per pixel\n", __PRETTY_FUNCTION__));
858 CCALL(raise, SIGSTOP);
860 xsd->depth = win_attributes.depth;
862 bug("\n");
863 bug("[X11Gfx] %s: Display Depth = %dbit (Default = %dbit)\n", __PRETTY_FUNCTION__, DisplayPlanes(xsd->display, DefaultScreen(xsd->display)), DefaultDepth(xsd->display, DefaultScreen(xsd->display)));
864 #if (0)
865 bug("[X11Gfx] %s: %d Bits per Pixel\n", __PRETTY_FUNCTION__, xsd->depth);
866 #endif
870 /* Create a dummy X image to get bits per pixel */
871 testimage = XCALL(XGetImage, xsd->display, RootWindow(xsd->display,
872 DefaultScreen(xsd->display)), 0, 0, 1, 1,
873 AllPlanes, ZPixmap);
875 if (NULL != testimage)
877 xsd->bytes_per_pixel = (testimage->bits_per_pixel + 7) >> 3;
878 XDestroyImage(testimage);
880 else
882 D(bug("[X11Gfx] %s: failed to create query image\n", __PRETTY_FUNCTION__));
883 CCALL(raise, SIGSTOP);
886 if (PseudoColor == xsd->vi->class)
888 xsd->clut_mask = (1L << xsd->depth) - 1;
889 xsd->clut_shift = 0;
893 /* Create a dummy window for pixmaps */
894 xsd->dummy_window_for_creating_pixmaps = XCALL(XCreateSimpleWindow, xsd->display,
895 DefaultRootWindow(xsd->display),
896 0, 0, 100, 100,
898 BlackPixel(xsd->display, DefaultScreen(xsd->display)),
899 BlackPixel(xsd->display, DefaultScreen(xsd->display)));
900 if (0 == xsd->dummy_window_for_creating_pixmaps)
902 D(bug("[X11Gfx] %s: failed to create pixmap window\n", __PRETTY_FUNCTION__));
903 ok = FALSE;
906 #if USE_XSHM
908 char *displayname = XCALL(XDisplayName, NULL);
910 if ((strncmp(displayname, ":", 1) == 0) ||
911 (strncmp(displayname, "unix:", 5) == 0))
913 /* Display is local, not remote. XSHM is possible */
915 /* Do we have Xshm support ? */
916 xsd->xshm_info = init_shared_mem(xsd->display);
918 if (NULL == xsd->xshm_info)
920 /* ok = FALSE; */
921 D(bug("INITIALIZATION OF XSHM FAILED !!\n"));
923 else
925 int a, b;
927 InitSemaphore(&xsd->shm_sema);
928 xsd->use_xshm = TRUE;
930 XCALL(XQueryExtension, xsd->display, "MIT-SHM", &xshm_major, &a, &b);
934 #endif
936 UNLOCK_X11
938 ReturnBool("initx11stuff", ok);
942 /****************************************************************************************/
944 static VOID cleanupx11stuff(struct x11_staticdata *xsd)
946 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
948 LOCK_X11
950 /* Do nothing for now */
951 if (0 != xsd->dummy_window_for_creating_pixmaps)
953 XCALL(XDestroyWindow, xsd->display, xsd->dummy_window_for_creating_pixmaps);
956 #if USE_XSHM
957 cleanup_shared_mem(xsd->display, xsd->xshm_info);
958 #endif
959 FreeMem(xsd->vi, sizeof(XVisualInfo));
960 xsd->vi = NULL;
962 UNLOCK_X11
965 /****************************************************************************************/
967 //#define xsd (&LIBBASE->xsd)
968 /****************************************************************************************/
970 static int x11gfx_init(LIBBASETYPEPTR LIBBASE)
972 D(bug("[X11Gfx] %s: initialising semaphore @ 0x%p\n", __PRETTY_FUNCTION__, &LIBBASE->xsd.sema));
974 InitSemaphore(&LIBBASE->xsd.sema);
976 return OOP_ObtainAttrBases(attrbases);
979 /****************************************************************************************/
981 static int x11gfx_expunge(LIBBASETYPEPTR LIBBASE)
983 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
985 OOP_ReleaseAttrBases(attrbases);
986 return TRUE;
989 /****************************************************************************************/
991 ADD2INITLIB(x11gfx_init, 0);
992 ADD2EXPUNGELIB(x11gfx_expunge, 0);
994 /****************************************************************************************/