Added a test for MUIA_Listview_SelectChange.
[AROS.git] / arch / all-hosted / hidd / x11 / x11gfx.c
blobfc3631d2ab70f3b9b0869de4273ef81c3118bc8d
1 /*
2 Copyright © 1995-2015, 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 <stddef.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <unistd.h>
18 #include <X11/Xlib.h>
19 #include <X11/cursorfont.h>
20 #include <X11/Xutil.h>
22 #include <signal.h>
23 #include <string.h>
25 #include <exec/libraries.h>
26 #include <exec/types.h>
27 #include <exec/resident.h>
28 #include <exec/memory.h>
29 #include <aros/libcall.h>
30 #include <proto/exec.h>
31 #include <proto/oop.h>
32 #include <proto/utility.h>
33 #include <oop/oop.h>
35 #include <hidd/hidd.h>
36 #include <hidd/graphics.h>
38 #include <aros/symbolsets.h>
40 #include "bitmap_class.h"
41 #include "x11gfx_intern.h"
42 #include "x11.h"
44 #include LC_LIBDEFS_FILE
46 #define XFLUSH(x) XCALL(XFlush, x)
47 //#define XFLUSH(x)
49 /****************************************************************************************/
51 #define IS_X11GFX_ATTR(attr, idx) ( ( (idx) = (attr) - HiddX11GfxAB) < num_Hidd_X11BitMap_Attrs)
53 int xshm_major;
55 /* Some attrbases needed as global vars.
56 These are write-once read-many */
58 OOP_AttrBase HiddBitMapAttrBase;
59 OOP_AttrBase HiddX11BitMapAB;
60 OOP_AttrBase HiddSyncAttrBase;
61 OOP_AttrBase HiddPixFmtAttrBase;
62 OOP_AttrBase HiddGfxAttrBase;
63 OOP_AttrBase HiddAttrBase;
65 static const struct OOP_ABDescr attrbases[] =
67 { IID_Hidd_BitMap , &HiddBitMapAttrBase },
68 { IID_Hidd_BitMap_X11 , &HiddX11BitMapAB },
69 { IID_Hidd_Sync , &HiddSyncAttrBase },
70 { IID_Hidd_PixFmt , &HiddPixFmtAttrBase },
71 { IID_Hidd_Gfx , &HiddGfxAttrBase },
72 { IID_Hidd , &HiddAttrBase },
73 { NULL , NULL }
76 static VOID cleanupx11stuff(struct x11_staticdata *xsd);
77 static BOOL initx11stuff(struct x11_staticdata *xsd);
79 /****************************************************************************************/
81 OOP_Object *X11Cl__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
83 struct TagItem pftags[] =
85 { aHidd_PixFmt_RedShift , 0 }, /* 0 */
86 { aHidd_PixFmt_GreenShift , 0 }, /* 1 */
87 { aHidd_PixFmt_BlueShift , 0 }, /* 2 */
88 { aHidd_PixFmt_AlphaShift , 0 }, /* 3 */
89 { aHidd_PixFmt_RedMask , 0 }, /* 4 */
90 { aHidd_PixFmt_GreenMask , 0 }, /* 5 */
91 { aHidd_PixFmt_BlueMask , 0 }, /* 6 */
92 { aHidd_PixFmt_AlphaMask , 0 }, /* 7 */
93 { aHidd_PixFmt_ColorModel , 0 }, /* 8 */
94 { aHidd_PixFmt_Depth , 0 }, /* 9 */
95 { aHidd_PixFmt_BytesPerPixel, 0 }, /* 10 */
96 { aHidd_PixFmt_BitsPerPixel , 0 }, /* 11 */
97 { aHidd_PixFmt_StdPixFmt , 0 }, /* 12 */
98 { aHidd_PixFmt_CLUTShift , 0 }, /* 13 */
99 { aHidd_PixFmt_CLUTMask , 0 }, /* 14 */
100 { aHidd_PixFmt_BitMapType , 0 }, /* 15 */
101 { TAG_DONE , 0UL }
104 struct TagItem tags_160_160[] =
106 { aHidd_Sync_HDisp , 160 },
107 { aHidd_Sync_VDisp , 160 },
108 { aHidd_Sync_Description, (IPTR)"X11:160x160" },
109 { TAG_DONE , 0UL }
112 struct TagItem tags_240_320[] =
114 { aHidd_Sync_HDisp , 240 },
115 { aHidd_Sync_VDisp , 320 },
116 { aHidd_Sync_Description, (IPTR)"X11:240x320" },
117 { TAG_DONE , 0UL }
120 struct TagItem tags_320_240[] =
122 { aHidd_Sync_HDisp , 320 },
123 { aHidd_Sync_VDisp , 240 },
124 { aHidd_Sync_Description, (IPTR)"X11:320x240" },
125 { TAG_DONE , 0UL }
128 struct TagItem tags_512_384[] =
130 { aHidd_Sync_HDisp , 512 },
131 { aHidd_Sync_VDisp , 384 },
132 { aHidd_Sync_Description, (IPTR)"X11:512x384" },
133 { TAG_DONE , 0UL }
136 struct TagItem tags_640_480[] =
138 { aHidd_Sync_HDisp , 640 },
139 { aHidd_Sync_VDisp , 480 },
140 { aHidd_Sync_Description, (IPTR)"X11:640x480" },
141 { TAG_DONE , 0UL }
144 struct TagItem tags_800_600[] =
146 { aHidd_Sync_HDisp , 800 },
147 { aHidd_Sync_VDisp , 600 },
148 { aHidd_Sync_Description, (IPTR)"X11:800x600" },
149 { TAG_DONE , 0UL }
152 struct TagItem tags_1024_768[] =
154 { aHidd_Sync_HDisp , 1024 },
155 { aHidd_Sync_VDisp , 768 },
156 { aHidd_Sync_Description, (IPTR)"X11:1024x768" },
157 { TAG_DONE , 0UL }
160 struct TagItem tags_1152_864[] =
162 { aHidd_Sync_HDisp , 1152 },
163 { aHidd_Sync_VDisp , 864 },
164 { aHidd_Sync_Description, (IPTR)"X11:1152x864" },
165 { TAG_DONE , 0UL }
168 struct TagItem tags_1280_800[] =
170 { aHidd_Sync_HDisp , 1280 },
171 { aHidd_Sync_VDisp , 800 },
172 { aHidd_Sync_Description, (IPTR)"X11:1280x800" },
173 { TAG_DONE , 0UL }
176 struct TagItem tags_1280_960[] =
178 { aHidd_Sync_HDisp , 1280 },
179 { aHidd_Sync_VDisp , 960 },
180 { aHidd_Sync_Description, (IPTR)"X11:1280x960" },
181 { TAG_DONE , 0UL }
184 struct TagItem tags_1280_1024[] =
186 { aHidd_Sync_HDisp , 1280 },
187 { aHidd_Sync_VDisp , 1024 },
188 { aHidd_Sync_Description, (IPTR)"X11:1280x1024" },
189 { TAG_DONE , 0UL }
192 struct TagItem tags_1400_1050[] =
194 { aHidd_Sync_HDisp , 1400 },
195 { aHidd_Sync_VDisp , 1050 },
196 { aHidd_Sync_Description, (IPTR)"X11:1400x1050" },
197 { TAG_DONE , 0UL }
200 struct TagItem tags_1600_1200[] =
202 { aHidd_Sync_HDisp , 1600 },
203 { aHidd_Sync_VDisp , 1200 },
204 { aHidd_Sync_Description, (IPTR)"X11:1600x1200" },
205 { TAG_DONE , 0UL }
208 struct TagItem tags_1680_1050[] =
210 { aHidd_Sync_HDisp , 1680 },
211 { aHidd_Sync_VDisp , 1050 },
212 { aHidd_Sync_Description, (IPTR)"X11:1680x1050" },
213 { TAG_DONE , 0UL }
216 struct TagItem tags_1920_1080[] =
218 { aHidd_Sync_HDisp , 1920 },
219 { aHidd_Sync_VDisp , 1080 },
220 { aHidd_Sync_Description, (IPTR)"X11:1920x1080" },
221 { TAG_DONE , 0UL }
224 struct TagItem tags_1920_1200[] =
226 { aHidd_Sync_HDisp , 1920 },
227 { aHidd_Sync_VDisp , 1200 },
228 { aHidd_Sync_Description, (IPTR)"X11:1920x1200" },
229 { TAG_DONE , 0UL }
232 /* Default display modes. Used on displays which do not support Free86-VidModeExtension */
233 struct TagItem default_mode_tags[] =
235 { aHidd_Gfx_PixFmtTags , (IPTR)pftags },
236 { aHidd_Gfx_SyncTags , (IPTR)tags_160_160 },
237 { aHidd_Gfx_SyncTags , (IPTR)tags_240_320 },
238 { aHidd_Gfx_SyncTags , (IPTR)tags_320_240 },
239 { aHidd_Gfx_SyncTags , (IPTR)tags_512_384 },
240 { aHidd_Gfx_SyncTags , (IPTR)tags_640_480 },
241 { aHidd_Gfx_SyncTags , (IPTR)tags_800_600 },
242 { aHidd_Gfx_SyncTags , (IPTR)tags_1024_768 },
243 { aHidd_Gfx_SyncTags , (IPTR)tags_1152_864 },
244 { aHidd_Gfx_SyncTags , (IPTR)tags_1280_800 },
245 { aHidd_Gfx_SyncTags , (IPTR)tags_1280_960 },
246 { aHidd_Gfx_SyncTags , (IPTR)tags_1280_1024 },
247 { aHidd_Gfx_SyncTags , (IPTR)tags_1400_1050 },
248 { aHidd_Gfx_SyncTags , (IPTR)tags_1600_1200 },
249 { aHidd_Gfx_SyncTags , (IPTR)tags_1680_1050 },
250 { aHidd_Gfx_SyncTags , (IPTR)tags_1920_1080 },
251 { aHidd_Gfx_SyncTags , (IPTR)tags_1920_1200 },
252 { TAG_DONE , 0UL }
255 struct TagItem *mode_tags = NULL;
257 struct TagItem mytags[] =
259 { aHidd_Gfx_ModeTags , (IPTR)default_mode_tags },
260 { aHidd_Name , (IPTR)"x11_1.monitor" },
261 { aHidd_HardwareName , (IPTR)"X Window system" },
262 { aHidd_ProducerName , (IPTR)"X.Org Foundation" },
263 { TAG_MORE , (IPTR)msg->attrList }
266 struct pRoot_New mymsg = { msg->mID, mytags };
268 struct TagItem *resolution = NULL;
269 XF86VidModeModeInfo** modes = NULL;
270 static int modeNum = 0;
271 ULONG realmode = 0;
273 ULONG i, screen;
274 Display *disp;
276 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
278 /* Do GfxHidd initalization here */
279 if (!initx11stuff(XSD(cl)))
281 D(bug("[X11Gfx] %s: initialisation failed!\n", __PRETTY_FUNCTION__));
282 return NULL;
285 /* Get supported X11 resolution from RandR resources */
287 disp = XCALL(XOpenDisplay, NULL);
288 screen = XCALL(XDefaultScreen, disp);
289 // rootwin = XCALL(XRootWindow, disp, screen);
291 if (!(XSD(cl)->options & OPTION_FORCESTDMODES))
293 XVMCALL(XF86VidModeGetAllModeLines, disp, screen, &modeNum, &modes);
294 D(bug("[X11Gfx] Found %u modes, table at 0x%P\n", modeNum, modes));
296 if (modeNum)
298 /* Got XF86VidMode data, use it */
299 if ((resolution = AllocMem(modeNum * sizeof(struct TagItem) * 4, MEMF_PUBLIC)) == NULL)
301 D(bug("[X11] failed to allocate memory for %d modes: %d !!!\n", modeNum, XSD(cl)->vi.class));
303 XCALL(XCloseDisplay, disp);
304 cleanupx11stuff(XSD(cl));
306 return NULL;
309 for(i = 0; i < modeNum; i++)
311 ULONG j;
312 BOOL insert;
313 insert = TRUE;
315 /* avoid duplicated resolution */
316 for(j = 0; j < realmode; j++)
318 if(resolution[j * 4].ti_Data == modes[i]->hdisplay && resolution[j * 4 + 1].ti_Data == modes[i]->vdisplay)
319 { /* Found a matching resolution. Don't insert ! */
320 insert = FALSE;
324 if(insert)
326 resolution[realmode * 4 + 0].ti_Tag = aHidd_Sync_HDisp;
327 resolution[realmode * 4 + 0].ti_Data = modes[i]->hdisplay;
329 resolution[realmode * 4 + 1].ti_Tag = aHidd_Sync_VDisp;
330 resolution[realmode * 4 + 1].ti_Data = modes[i]->vdisplay;
332 resolution[realmode * 4 + 2].ti_Tag = aHidd_Sync_Description;
333 resolution[realmode * 4 + 2].ti_Data = (IPTR)"X11: %hx%v";
335 resolution[realmode * 4 + 3].ti_Tag = TAG_DONE;
336 resolution[realmode * 4 + 3].ti_Data = 0UL;
338 realmode++;
342 if((mode_tags = AllocMem(sizeof(struct TagItem) * (realmode + 2), MEMF_PUBLIC)) == NULL)
344 D(bug("[X11] failed to allocate memory for mode tag's: %d !!!\n", XSD(cl)->vi.class));
346 FreeMem(resolution, modeNum * sizeof(struct TagItem) * 4);
347 XCALL(XCloseDisplay, disp);
348 cleanupx11stuff(XSD(cl));
350 return NULL;
353 mode_tags[0].ti_Tag = aHidd_Gfx_PixFmtTags;
354 mode_tags[0].ti_Data = (IPTR)pftags;
356 /* The different screenmode from XF86VMODE */
357 for(i=0; i < realmode; i++)
359 mode_tags[1 + i].ti_Tag = aHidd_Gfx_SyncTags;
360 mode_tags[1 + i].ti_Data = (IPTR)(resolution + i*4);
363 mode_tags[1 + i].ti_Tag = TAG_DONE;
364 mode_tags[1 + i].ti_Data = 0UL;
366 /* Use our new mode tags instead of default ones */
367 mytags[0].ti_Data = (IPTR)mode_tags;
371 /* Register gfxmodes */
372 pftags[0].ti_Data = XSD(cl)->red_shift;
373 pftags[1].ti_Data = XSD(cl)->green_shift;
374 pftags[2].ti_Data = XSD(cl)->blue_shift;
375 pftags[3].ti_Data = 0;
377 pftags[4].ti_Data = XSD(cl)->vi.red_mask;
378 pftags[5].ti_Data = XSD(cl)->vi.green_mask;
379 pftags[6].ti_Data = XSD(cl)->vi.blue_mask;
380 pftags[7].ti_Data = 0x00000000;
382 if (XSD(cl)->vi.class == TrueColor)
384 pftags[8].ti_Data = vHidd_ColorModel_TrueColor;
386 else if (XSD(cl)->vi.class == PseudoColor)
388 pftags[8].ti_Data = vHidd_ColorModel_Palette;
389 pftags[13].ti_Data = XSD(cl)->clut_shift;
390 pftags[14].ti_Data = XSD(cl)->clut_mask;
392 else
394 D(bug("[X11Gfx] unsupported color model: %d\n", XSD(cl)->vi.class));
395 if (resolution)
397 FreeMem(resolution, modeNum * sizeof(struct TagItem) * 4);
398 FreeMem(mode_tags, sizeof(struct TagItem) * (realmode + 2));
400 XCALL(XCloseDisplay, disp);
401 cleanupx11stuff(XSD(cl));
403 return NULL;
406 pftags[9].ti_Data = XSD(cl)->depth;
407 pftags[10].ti_Data = XSD(cl)->bytes_per_pixel;
408 pftags[11].ti_Data = XSD(cl)->depth;
409 pftags[12].ti_Data = vHidd_StdPixFmt_Native;
411 /* FIXME: Do better than this */
413 /* We assume chunky */
414 pftags[15].ti_Data = vHidd_BitMapType_Chunky;
416 D(bug("Calling super method\n"));
418 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)&mymsg);
420 D(bug("Super method returned\n"));
422 FreeMem(resolution, modeNum * sizeof(struct TagItem) * 4);
423 FreeMem(mode_tags, sizeof(struct TagItem) * (realmode + 2));
424 XCALL(XCloseDisplay, disp);
426 if (NULL != o)
428 XColor bg, fg;
429 struct gfx_data *data = OOP_INST_DATA(cl, o);
431 data->basebm = OOP_FindClass(CLID_Hidd_BitMap);
432 bug("[X11] BitMap class @ 0x%p\n", data->basebm);
434 LOCK_X11
435 data->display = XSD(cl)->display;
436 data->screen = DefaultScreen( data->display );
437 data->depth = DisplayPlanes( data->display, data->screen );
438 data->colmap = DefaultColormap( data->display, data->screen );
439 D(bug("x11_func.XCreateFontCursor(%x), display(%x)\n", x11_func.XCreateFontCursor, data->display));
440 /* Create cursor */
441 data->cursor = XCALL(XCreateFontCursor, data->display, XC_top_left_arrow);
443 fg.pixel = BlackPixel(data->display, data->screen);
444 fg.red = 0x0000; fg.green = 0x0000; fg.blue = 0x0000;
445 fg.flags = (DoRed | DoGreen | DoBlue);
446 bg.pixel = WhitePixel(data->display, data->screen);
447 bg.red = 0xFFFF; bg.green = 0xFFFF; bg.blue = 0xFFFF;
448 bg.flags = (DoRed | DoGreen | DoBlue);
450 XCALL(XRecolorCursor, data->display, data->cursor, &fg, &bg);
452 if (XSD(cl)->options & OPTION_BACKINGSTORE)
454 switch(DoesBackingStore(ScreenOfDisplay(data->display, data->screen)))
456 case WhenMapped:
457 case Always:
458 break;
460 case NotUseful:
461 bug("\n"
462 "+----------------------------------------------------------+\n"
463 "| Your X Server seems to have backing store disabled! |\n"
464 "| =================================================== |\n"
465 "| |\n"
466 "| If possible you should try to switch it on, otherwise |\n"
467 "| AROS will have problems with its display. When the AROS |\n"
468 "| X window is hidden by other X windows, or is dragged |\n"
469 "| off screen, then the graphics in those parts will get |\n"
470 "| lost, unless backing store support is enabled. |\n"
471 "| |\n"
472 "| In case your X11 Server is XFree 4.x then switching on |\n"
473 "| backingstore support can be done by starting the X11 |\n"
474 "| server with something like \"startx -- +bs\". Depending |\n"
475 "| on what X driver you use it might also be possible |\n"
476 "| to turn it on by adding |\n"
477 "| |\n"
478 "| Option \"Backingstore\" |\n"
479 "| |\n"
480 "| to the Device Section of your X Window config file, |\n"
481 "| which usually is \"/etc/X11/xorg.conf\" |\n"
482 "| or \"/etc/X11/XFree86Config\" |\n"
483 "+----------------------------------------------------------+\n"
484 "\n");
485 break;
489 UNLOCK_X11
491 D(bug("[X11Gfx] Got object from super\n"));
493 data->display = XSD(cl)->display;
496 ReturnPtr("X11Gfx::New", OOP_Object *, o);
499 /********** GfxHidd::Dispose() ******************************/
500 VOID X11Cl__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
502 D(bug("[X11Gfx] %s(0x%p)\n", __PRETTY_FUNCTION__, o));
504 cleanupx11stuff(XSD(cl));
506 D(bug("X11Gfx::Dispose: calling super\n"));
507 OOP_DoSuperMethod(cl, o, msg);
511 /****************************************************************************************/
513 OOP_Object *X11Cl__Hidd_Gfx__CreateObject(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CreateObject *msg)
515 struct gfx_data *data = OOP_INST_DATA(cl, o);
516 OOP_Object *object = NULL;
518 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
520 if (msg->cl == data->basebm)
522 struct pHidd_Gfx_CreateObject p;
523 HIDDT_ModeID modeid;
524 struct gfx_data *data;
525 struct TagItem tags[] =
527 { aHidd_X11BitMap_SysDisplay , 0 }, /* 0 */
528 { aHidd_X11BitMap_SysScreen , 0 }, /* 1 */
529 { aHidd_X11BitMap_SysCursor , 0 }, /* 2 */
530 { aHidd_X11BitMap_ColorMap , 0 }, /* 3 */
531 { aHidd_X11BitMap_VisualClass , 0 }, /* 4 */
532 { TAG_IGNORE , 0 }, /* 5 */
533 { TAG_MORE , 0 } /* 6 */
536 data = OOP_INST_DATA(cl, o);
538 tags[0].ti_Data = (IPTR)data->display;
539 tags[1].ti_Data = data->screen;
540 tags[2].ti_Data = (IPTR)data->cursor;
541 tags[3].ti_Data = data->colmap;
542 tags[4].ti_Data = XSD(cl)->vi.class;
543 tags[6].ti_Data = (IPTR)msg->attrList;
545 /* Displayable bitmap ? */
546 modeid = GetTagData(aHidd_BitMap_ModeID, vHidd_ModeID_Invalid, msg->attrList);
548 if (modeid != vHidd_ModeID_Invalid)
550 /* ModeID supplied, it's for sure X11 bitmap */
551 tags[5].ti_Tag = aHidd_BitMap_ClassPtr;
552 tags[5].ti_Data = (IPTR)XSD(cl)->bmclass;
555 p.mID = msg->mID;
556 p.cl = msg->cl;
557 p.attrList = tags;
559 object = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)&p);
561 else
562 object = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
564 ReturnPtr("X11Gfx::CreateObject", OOP_Object *, object);
567 /****************************************************************************************/
569 VOID X11Cl__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
571 ULONG idx;
573 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
575 if (IS_GFX_ATTR(msg->attrID, idx))
577 switch (idx)
579 case aoHidd_Gfx_IsWindowed:
580 *msg->storage = TRUE;
581 return;
583 case aoHidd_Gfx_HWSpriteTypes:
584 #if X11SOFTMOUSE
585 *msg->storage = 0;
586 #else
587 *msg->storage = vHidd_SpriteType_DirectColor;
588 #endif
589 return;
591 case aoHidd_Gfx_DriverName:
592 *msg->storage = (IPTR) "X11";
593 return;
596 OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
599 /****************************************************************************************/
601 VOID X11Cl__Root__Set(OOP_Class *cl, OOP_Object *obj, struct pRoot_Set *msg)
603 struct TagItem *tag, *tstate;
604 ULONG idx;
605 struct x11_staticdata *data = XSD(cl);
607 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
609 tstate = msg->attrList;
610 while ((tag = NextTagItem(&tstate)))
612 if (IS_GFX_ATTR(tag->ti_Tag, idx))
614 switch (idx)
616 case aoHidd_Gfx_ActiveCallBack:
617 data->activecallback = (void *) tag->ti_Data;
618 break;
620 case aoHidd_Gfx_ActiveCallBackData:
621 data->callbackdata = (void *) tag->ti_Data;
622 break;
626 OOP_DoSuperMethod(cl, obj, &msg->mID);
629 /****************************************************************************************/
631 VOID X11Cl__Hidd_Gfx__CopyBox(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CopyBox *msg)
633 ULONG mode;
634 Drawable src = 0, dest = 0;
635 GC gc = 0;
637 struct gfx_data *data = OOP_INST_DATA(cl, o);
639 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
641 mode = GC_DRMD(msg->gc);
643 OOP_GetAttr(msg->src, aHidd_X11BitMap_Drawable, (IPTR *) &src);
644 OOP_GetAttr(msg->dest, aHidd_X11BitMap_Drawable, (IPTR *) &dest);
646 if (0 == dest || 0 == src)
649 * One of objects is not an X11 bitmap.
650 * Let the superclass do the copying in a more general way
652 OOP_DoSuperMethod(cl, o, &msg->mID);
653 return;
656 OOP_GetAttr(msg->src, aHidd_X11BitMap_GC, (IPTR *) &gc);
658 HostLib_Lock();
660 XCALL(XSetFunction, data->display, gc, mode);
661 XCALL(XCopyArea,
662 data->display, src, dest, gc, msg->srcX, msg->srcY, msg->width, msg->height, msg->destX, msg->destY);
664 HostLib_Unlock();
667 /****************************************************************************************/
669 BOOL X11Cl__Hidd_Gfx__SetCursorShape(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
671 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
673 /* Dummy implementation */
674 return TRUE;
677 /****************************************************************************************/
679 BOOL X11Cl__Hidd_Gfx__SetCursorPos(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
681 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
683 /* Dummy implementation */
684 return TRUE;
687 /****************************************************************************************/
689 VOID X11Cl__Hidd_Gfx__SetCursorVisible(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
691 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
693 /* Dummy implementation */
694 return;
697 /****************************************************************************************/
699 static ULONG mask_to_shift(ULONG mask)
701 ULONG i;
703 for (i = 32; mask; i--)
705 mask >>= 1;
708 if (mask == 32)
710 i = 0;
713 return i;
716 /****************************************************************************************/
718 #undef XSD
719 #define XSD(cl) xsd
722 Inits sysdisplay, sysscreen, colormap, etc.. */
723 static BOOL initx11stuff(struct x11_staticdata *xsd)
725 /* XColor fg, bg; */
726 BOOL ok = TRUE;
727 XVisualInfo template;
728 XVisualInfo *visinfo;
729 int template_mask;
730 int numvisuals;
731 XImage *testimage;
733 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
735 if (!X11_Init(xsd))
736 return FALSE;
738 LOCK_X11
740 /* Get some info on the display */
741 template.visualid = XCALL(XVisualIDFromVisual, DefaultVisual(xsd->display, DefaultScreen(xsd->display)));
742 template_mask = VisualIDMask;
744 visinfo = XCALL(XGetVisualInfo, xsd->display, template_mask, &template, &numvisuals);
746 if (numvisuals > 1)
748 D(bug("[X11Gfx] %s: got %d visualinfo from X\n", __PRETTY_FUNCTION__, numvisuals));
750 // CCALL(raise, SIGSTOP);
753 if (NULL == visinfo)
755 D(bug("[X11Gfx] %s: no visualinfo available!\n", __PRETTY_FUNCTION__));
757 CCALL(raise, SIGSTOP);
759 ok = FALSE;
761 else
763 /* Store the visual info structure */
765 memcpy(&xsd->vi, visinfo, sizeof(XVisualInfo));
767 XCALL(XFree, visinfo);
769 visinfo = &xsd->vi;
771 /* We only support TrueColor for now */
773 switch (visinfo->class)
775 case TrueColor:
776 /* Get the pixel masks */
777 xsd->red_shift = mask_to_shift(xsd->vi.red_mask);
778 xsd->green_shift = mask_to_shift(xsd->vi.green_mask);
779 xsd->blue_shift = mask_to_shift(xsd->vi.blue_mask);
780 break;
782 case PseudoColor:
783 /* stegerg */
784 xsd->vi.red_mask = ((1 << xsd->vi.bits_per_rgb) - 1) << (xsd->vi.bits_per_rgb * 2);
785 xsd->vi.green_mask = ((1 << xsd->vi.bits_per_rgb) - 1) << (xsd->vi.bits_per_rgb * 1);
786 xsd->vi.blue_mask = ((1 << xsd->vi.bits_per_rgb) - 1);
787 xsd->red_shift = mask_to_shift(xsd->vi.red_mask);
788 xsd->green_shift = mask_to_shift(xsd->vi.green_mask);
789 xsd->blue_shift = mask_to_shift(xsd->vi.blue_mask);
790 /* end stegerg */
791 break;
793 default:
794 D(bug("[X11Gfx] %s: unsupported display mode!\n", __PRETTY_FUNCTION__));
796 CCALL(raise, SIGSTOP);
799 xsd->depth = 0;
801 /* stegerg: based on xwininfo source */
804 XWindowAttributes win_attributes;
806 if (!XCALL(XGetWindowAttributes, xsd->display,
807 RootWindow(xsd->display, DefaultScreen(xsd->display)),
808 &win_attributes))
810 D(bug("[X11Gfx] %s: failed to obtain bits per pixel\n", __PRETTY_FUNCTION__));
812 CCALL(raise, SIGSTOP);
814 xsd->depth = win_attributes.depth;
816 bug("\n");
817 bug("[X11Gfx] %s: Display Depth = %dbit (Default = %dbit)\n", __PRETTY_FUNCTION__, DisplayPlanes(xsd->display, DefaultScreen(xsd->display)), DefaultDepth(xsd->display, DefaultScreen(xsd->display)));
818 #if (0)
819 bug("[X11Gfx] %s: %d Bits per Pixel\n", __PRETTY_FUNCTION__, xsd->depth);
820 #endif
824 /* Create a dummy X image to get bits per pixel */
825 testimage = XCALL(XGetImage, xsd->display, RootWindow(xsd->display,
826 DefaultScreen(xsd->display)), 0, 0, 1, 1,
827 AllPlanes, ZPixmap);
829 if (NULL != testimage)
831 xsd->bytes_per_pixel = (testimage->bits_per_pixel + 7) >> 3;
832 XDestroyImage(testimage);
834 else
836 D(bug("[X11Gfx] %s: failed to create query image\n", __PRETTY_FUNCTION__));
837 CCALL(raise, SIGSTOP);
840 if (PseudoColor == xsd->vi.class)
842 xsd->clut_mask = (1L << xsd->depth) - 1;
843 xsd->clut_shift = 0;
847 /* Create a dummy window for pixmaps */
848 xsd->dummy_window_for_creating_pixmaps = XCALL(XCreateSimpleWindow, xsd->display,
849 DefaultRootWindow(xsd->display),
850 0, 0, 100, 100,
852 BlackPixel(xsd->display, DefaultScreen(xsd->display)),
853 BlackPixel(xsd->display, DefaultScreen(xsd->display)));
854 if (0 == xsd->dummy_window_for_creating_pixmaps)
856 D(bug("[X11Gfx] %s: failed to create pixmap window\n", __PRETTY_FUNCTION__));
857 ok = FALSE;
860 #if USE_XSHM
862 char *displayname = XCALL(XDisplayName, NULL);
864 if ((strncmp(displayname, ":", 1) == 0) ||
865 (strncmp(displayname, "unix:", 5) == 0))
867 /* Display is local, not remote. XSHM is possible */
869 /* Do we have Xshm support ? */
870 xsd->xshm_info = init_shared_mem(xsd->display);
872 if (NULL == xsd->xshm_info)
874 /* ok = FALSE; */
875 D(bug("INITIALIZATION OF XSHM FAILED !!\n"));
877 else
879 int a, b;
881 InitSemaphore(&xsd->shm_sema);
882 xsd->use_xshm = TRUE;
884 XCALL(XQueryExtension, xsd->display, "MIT-SHM", &xshm_major, &a, &b);
888 #endif
890 UNLOCK_X11
892 ReturnBool("initx11stuff", ok);
896 /****************************************************************************************/
898 static VOID cleanupx11stuff(struct x11_staticdata *xsd)
900 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
902 LOCK_X11
904 /* Do nothing for now */
905 if (0 != xsd->dummy_window_for_creating_pixmaps)
907 XCALL(XDestroyWindow, xsd->display, xsd->dummy_window_for_creating_pixmaps);
910 #if USE_XSHM
911 cleanup_shared_mem(xsd->display, xsd->xshm_info);
912 #endif
914 UNLOCK_X11
917 /****************************************************************************************/
919 //#define xsd (&LIBBASE->xsd)
920 /****************************************************************************************/
922 static int x11gfx_init(LIBBASETYPEPTR LIBBASE)
924 D(bug("[X11Gfx] %s: initialising semaphore @ 0x%p\n", __PRETTY_FUNCTION__, &LIBBASE->xsd.sema));
926 InitSemaphore(&LIBBASE->xsd.sema);
928 return OOP_ObtainAttrBases(attrbases);
931 /****************************************************************************************/
933 static int x11gfx_expunge(LIBBASETYPEPTR LIBBASE)
935 D(bug("[X11Gfx] %s()\n", __PRETTY_FUNCTION__));
937 OOP_ReleaseAttrBases(attrbases);
938 return TRUE;
941 /****************************************************************************************/
943 ADD2INITLIB(x11gfx_init, 0);
944 ADD2EXPUNGELIB(x11gfx_expunge, 0);
946 /****************************************************************************************/