Fixed a few warnings.
[tangerine.git] / arch / all-hosted / hidd / x11 / x11gfx.c
blobc0f56eba22521baa8bc26df176cfa28f0716ab22
1 /*
2 Copyright © 1995-2009, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: X11 gfx HIDD for AROS.
6 Lang: English.
7 */
9 #define __OOP_NOATTRBASES__
11 #include <stddef.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <unistd.h>
16 #include <X11/Xlib.h>
17 #include <X11/cursorfont.h>
18 #include <X11/Xutil.h>
20 #include <signal.h>
21 #include <string.h>
23 #include <exec/libraries.h>
24 #include <exec/types.h>
25 #include <exec/resident.h>
26 #include <exec/memory.h>
27 #include <aros/libcall.h>
28 #include <proto/exec.h>
29 #include <proto/oop.h>
30 #include <proto/utility.h>
31 #include <oop/oop.h>
33 #include <hidd/hidd.h>
34 #include <hidd/graphics.h>
36 #include <aros/symbolsets.h>
38 #include "x11gfx_intern.h"
39 #include "x11.h"
40 #include "bitmap.h"
42 #include LC_LIBDEFS_FILE
44 #define SDEBUG 0
45 #define DEBUG 0
46 #include <aros/debug.h>
48 #define XFLUSH(x) XCALL(XFlush, x)
49 //#define XFLUSH(x)
51 /****************************************************************************************/
53 #define IS_X11GFX_ATTR(attr, idx) ( ( (idx) = (attr) - HiddX11GfxAB) < num_Hidd_X11Gfx_Attrs)
56 /* Some attrbases needed as global vars.
57 These are write-once read-many */
59 static OOP_AttrBase HiddBitMapAttrBase;
60 static OOP_AttrBase HiddX11GfxAB;
61 static OOP_AttrBase HiddX11BitMapAB;
62 static OOP_AttrBase HiddSyncAttrBase;
63 static OOP_AttrBase HiddPixFmtAttrBase;
64 static OOP_AttrBase HiddGfxAttrBase;
66 static struct OOP_ABDescr attrbases[] =
68 { IID_Hidd_BitMap , &HiddBitMapAttrBase },
69 { IID_Hidd_X11Gfx , &HiddX11GfxAB },
70 { IID_Hidd_X11BitMap, &HiddX11BitMapAB },
71 { IID_Hidd_Sync , &HiddSyncAttrBase },
72 { IID_Hidd_PixFmt , &HiddPixFmtAttrBase },
73 { IID_Hidd_Gfx , &HiddGfxAttrBase },
74 { NULL , NULL }
78 static VOID cleanupx11stuff(struct x11_staticdata *xsd);
79 static BOOL initx11stuff(struct x11_staticdata *xsd);
81 /****************************************************************************************/
83 OOP_Object *X11Cl__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
85 struct TagItem pftags[] =
87 { aHidd_PixFmt_RedShift , 0 }, /* 0 */
88 { aHidd_PixFmt_GreenShift , 0 }, /* 1 */
89 { aHidd_PixFmt_BlueShift , 0 }, /* 2 */
90 { aHidd_PixFmt_AlphaShift , 0 }, /* 3 */
91 { aHidd_PixFmt_RedMask , 0 }, /* 4 */
92 { aHidd_PixFmt_GreenMask , 0 }, /* 5 */
93 { aHidd_PixFmt_BlueMask , 0 }, /* 6 */
94 { aHidd_PixFmt_AlphaMask , 0 }, /* 7 */
95 { aHidd_PixFmt_ColorModel , 0 }, /* 8 */
96 { aHidd_PixFmt_Depth , 0 }, /* 9 */
97 { aHidd_PixFmt_BytesPerPixel, 0 }, /* 10 */
98 { aHidd_PixFmt_BitsPerPixel , 0 }, /* 11 */
99 { aHidd_PixFmt_StdPixFmt , 0 }, /* 12 */
100 { aHidd_PixFmt_CLUTShift , 0 }, /* 13 */
101 { aHidd_PixFmt_CLUTMask , 0 }, /* 14 */
102 { aHidd_PixFmt_BitMapType , 0 }, /* 15 */
103 { TAG_DONE , 0UL }
106 struct TagItem tags_160_160[] =
108 { aHidd_Sync_HDisp , 160 },
109 { aHidd_Sync_VDisp , 160 },
110 { aHidd_Sync_Description, (IPTR)"X11:160x160" },
111 { TAG_DONE , 0UL }
114 struct TagItem tags_240_320[] =
116 { aHidd_Sync_HDisp , 240 },
117 { aHidd_Sync_VDisp , 320 },
118 { aHidd_Sync_Description, (IPTR)"X11:240x320" },
119 { TAG_DONE , 0UL }
122 struct TagItem tags_320_240[] =
124 { aHidd_Sync_HDisp , 320 },
125 { aHidd_Sync_VDisp , 240 },
126 { aHidd_Sync_Description, (IPTR)"X11:320x240" },
127 { TAG_DONE , 0UL }
130 struct TagItem tags_512_384[] =
132 { aHidd_Sync_HDisp , 512 },
133 { aHidd_Sync_VDisp , 384 },
134 { aHidd_Sync_Description, (IPTR)"X11:512x384" },
135 { TAG_DONE , 0UL }
138 struct TagItem tags_640_480[] =
140 { aHidd_Sync_HDisp , 640 },
141 { aHidd_Sync_VDisp , 480 },
142 { aHidd_Sync_Description, (IPTR)"X11:640x480" },
143 { TAG_DONE , 0UL }
146 struct TagItem tags_800_600[] =
148 { aHidd_Sync_HDisp , 800 },
149 { aHidd_Sync_VDisp , 600 },
150 { aHidd_Sync_Description, (IPTR)"X11:800x600" },
151 { TAG_DONE , 0UL }
154 struct TagItem tags_1024_768[] =
156 { aHidd_Sync_HDisp , 1024 },
157 { aHidd_Sync_VDisp , 768 },
158 { aHidd_Sync_Description, (IPTR)"X11:1024x768" },
159 { TAG_DONE , 0UL }
162 struct TagItem tags_1152_864[] =
164 { aHidd_Sync_HDisp , 1152 },
165 { aHidd_Sync_VDisp , 864 },
166 { aHidd_Sync_Description, (IPTR)"X11:1152x864" },
167 { TAG_DONE , 0UL }
170 struct TagItem tags_1280_800[] =
172 { aHidd_Sync_HDisp , 1280 },
173 { aHidd_Sync_VDisp , 800 },
174 { aHidd_Sync_Description, (IPTR)"X11:1280x800" },
175 { TAG_DONE , 0UL }
178 struct TagItem tags_1280_960[] =
180 { aHidd_Sync_HDisp , 1280 },
181 { aHidd_Sync_VDisp , 960 },
182 { aHidd_Sync_Description, (IPTR)"X11:1280x960" },
183 { TAG_DONE , 0UL }
186 struct TagItem tags_1280_1024[] =
188 { aHidd_Sync_HDisp , 1280 },
189 { aHidd_Sync_VDisp , 1024 },
190 { aHidd_Sync_Description, (IPTR)"X11:1280x1024" },
191 { TAG_DONE , 0UL }
194 struct TagItem tags_1600_1200[] =
196 { aHidd_Sync_HDisp , 1600 },
197 { aHidd_Sync_VDisp , 1200 },
198 { aHidd_Sync_Description, (IPTR)"X11:1600x1200" },
199 { TAG_DONE , 0UL }
202 struct TagItem tags_1680_1050[] =
204 { aHidd_Sync_HDisp , 1680 },
205 { aHidd_Sync_VDisp , 1050 },
206 { aHidd_Sync_Description, (IPTR)"X11:1680x1050" },
207 { TAG_DONE , 0UL }
210 struct TagItem tags_1920_1200[] =
212 { aHidd_Sync_HDisp , 1920 },
213 { aHidd_Sync_VDisp , 1200 },
214 { aHidd_Sync_Description, (IPTR)"X11:1920x1200" },
215 { TAG_DONE , 0UL }
218 struct TagItem mode_tags[] =
220 { aHidd_Gfx_PixFmtTags , (IPTR)pftags },
222 /* Default values for the sync attributes */
223 { aHidd_Sync_PixelClock , 100000000 }, /* Oh boy, this X11 pixelclock is fast ;-) */
224 { aHidd_Sync_LeftMargin , 0 },
225 { aHidd_Sync_RightMargin, 0 },
226 { aHidd_Sync_HSyncLength, 0 },
227 { aHidd_Sync_UpperMargin, 0 },
228 { aHidd_Sync_LowerMargin, 0 },
229 { aHidd_Sync_VSyncLength, 0 },
231 /* The different syncmodes. The default attribute values above
232 will be applied to each of these. Note that
233 you can alter the defaults between the tags bewlow
235 { aHidd_Gfx_SyncTags , (IPTR)tags_160_160 },
236 { aHidd_Gfx_SyncTags , (IPTR)tags_240_320 },
237 { aHidd_Gfx_SyncTags , (IPTR)tags_320_240 },
238 { aHidd_Gfx_SyncTags , (IPTR)tags_512_384 },
239 { aHidd_Gfx_SyncTags , (IPTR)tags_640_480 },
240 { aHidd_Gfx_SyncTags , (IPTR)tags_800_600 },
241 { aHidd_Gfx_SyncTags , (IPTR)tags_1024_768 },
242 { aHidd_Gfx_SyncTags , (IPTR)tags_1152_864 },
243 { aHidd_Gfx_SyncTags , (IPTR)tags_1280_800 },
244 { aHidd_Gfx_SyncTags , (IPTR)tags_1280_960 },
245 { aHidd_Gfx_SyncTags , (IPTR)tags_1280_1024 },
246 { aHidd_Gfx_SyncTags , (IPTR)tags_1600_1200 },
247 { aHidd_Gfx_SyncTags , (IPTR)tags_1680_1050 },
248 { aHidd_Gfx_SyncTags , (IPTR)tags_1920_1200 },
249 { TAG_DONE , 0UL }
252 struct TagItem mytags[] =
254 { aHidd_Gfx_ModeTags , (IPTR)mode_tags },
255 { TAG_MORE , (IPTR)msg->attrList }
257 struct pRoot_New mymsg = { msg->mID, mytags };
259 EnterFunc(bug("X11Gfx::New()\n"));
261 /* Do GfxHidd initalization here */
262 if (!initx11stuff(XSD(cl)))
264 kprintf("!!! initx11stuff() FAILED IN X11Gfx::New() !!!\n");
265 ReturnPtr("X11Gfx::New()", OOP_Object *, NULL);
268 /* Register gfxmodes */
269 pftags[0].ti_Data = XSD(cl)->red_shift;
270 pftags[1].ti_Data = XSD(cl)->green_shift;
271 pftags[2].ti_Data = XSD(cl)->blue_shift;
272 pftags[3].ti_Data = 0;
274 pftags[4].ti_Data = XSD(cl)->vi.red_mask;
275 pftags[5].ti_Data = XSD(cl)->vi.green_mask;
276 pftags[6].ti_Data = XSD(cl)->vi.blue_mask;
277 pftags[7].ti_Data = 0x00000000;
279 if (XSD(cl)->vi.class == TrueColor)
281 pftags[8].ti_Data = vHidd_ColorModel_TrueColor;
283 else if (XSD(cl)->vi.class == PseudoColor)
285 pftags[8].ti_Data = vHidd_ColorModel_Palette;
286 pftags[13].ti_Data = XSD(cl)->clut_shift;
287 pftags[14].ti_Data = XSD(cl)->clut_mask;
289 else
291 kprintf("!!! UNHANDLED COLOR MODEL IN X11Gfx:New(): %d !!!\n", XSD(cl)->vi.class);
292 cleanupx11stuff(XSD(cl));
293 ReturnPtr("X11Gfx::New", OOP_Object *, NULL);
296 pftags[9].ti_Data = XSD(cl)->depth;
297 pftags[10].ti_Data = XSD(cl)->bytes_per_pixel;
298 pftags[11].ti_Data = XSD(cl)->depth;
299 pftags[12].ti_Data = vHidd_StdPixFmt_Native;
301 #warning Do better than this
303 /* We assume chunky */
304 pftags[15].ti_Data = vHidd_BitMapType_Chunky;
306 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)&mymsg);
307 if (NULL != o)
309 XColor bg, fg;
310 struct gfx_data *data = OOP_INST_DATA(cl, o);
312 LOCK_X11
313 data->display = XSD(cl)->display;
314 data->screen = DefaultScreen( data->display );
315 data->depth = DisplayPlanes( data->display, data->screen );
316 data->colmap = DefaultColormap( data->display, data->screen );
317 /* Create cursor */
318 data->cursor = XCALL(XCreateFontCursor, data->display, XC_top_left_arrow);
320 fg.pixel = BlackPixel(data->display, data->screen);
321 fg.red = 0x0000; fg.green = 0x0000; fg.blue = 0x0000;
322 fg.flags = (DoRed | DoGreen | DoBlue);
323 bg.pixel = WhitePixel(data->display, data->screen);
324 bg.red = 0xFFFF; bg.green = 0xFFFF; bg.blue = 0xFFFF;
325 bg.flags = (DoRed | DoGreen | DoBlue);
327 XCALL(XRecolorCursor, data->display, data->cursor, &fg, &bg);
329 switch(DoesBackingStore(ScreenOfDisplay(data->display, data->screen)))
331 case WhenMapped:
332 case Always:
333 break;
335 case NotUseful:
336 bug("\n"
337 "+----------------------------------------------------------|\n"
338 "| Your X Server seems to have backing store disabled! |\n"
339 "| =================================================== |\n"
340 "| |\n"
341 "| If possible you should try to switch it on, otherwise |\n"
342 "| AROS will have problems with it's display. When AROS |\n"
343 "| X window is hidden by other X windows, or is dragged |\n"
344 "| off screen, then the gfx in those parts will get lost, |\n"
345 "| unless backing store support is enabled. |\n"
346 "| |\n"
347 "| In case your X11 Server is XFree 4.x then switching on |\n"
348 "| backingstore support can be done by starting the X11 |\n"
349 "| server with something like \"startx -- +bs\". Depending |\n"
350 "| on what gfxcard driver you use it might also be possible |\n"
351 "| to turn it on by adding |\n"
352 "| |\n"
353 "| Option \"Backingstore\" |\n"
354 "| |\n"
355 "| to the Device Section of your X Window config file, |\n"
356 "| which usually is \"/etc/X11/xorg.conf\" |\n"
357 "| or \"/etc/X11/XFree86Config\" |\n"
358 "+----------------------------------------------------------+\n"
359 "\n");
360 break;
364 UNLOCK_X11
366 D(bug("X11Gfx::New(): Got object from super\n"));
368 data->display = XSD(cl)->display;
371 ReturnPtr("X11Gfx::New", OOP_Object *, o);
374 /********** GfxHidd::Dispose() ******************************/
375 VOID X11Cl__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
377 struct gfx_data *data;
379 EnterFunc(bug("X11Gfx::Dispose(o=%p)\n", o));
381 data = OOP_INST_DATA(cl, o);
382 cleanupx11stuff(XSD(cl));
384 D(bug("X11Gfx::Dispose: calling super\n"));
385 OOP_DoSuperMethod(cl, o, msg);
387 ReturnVoid("X11Gfx::Dispose");
390 /****************************************************************************************/
392 OOP_Object *X11Cl__Hidd_Gfx__NewBitMap(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_NewBitMap *msg)
394 BOOL displayable, framebuffer;
395 struct pHidd_Gfx_NewBitMap p;
396 OOP_Object *newbm;
397 IPTR drawable;
399 struct gfx_data *data;
400 struct TagItem tags[] =
402 { aHidd_X11Gfx_SysDisplay , (IPTR) NULL }, /* 0 */
403 { aHidd_X11Gfx_SysScreen , 0UL }, /* 1 */
404 { aHidd_X11Gfx_SysCursor , 0UL }, /* 2 */
405 { aHidd_X11Gfx_ColorMap , 0UL }, /* 3 */
406 { aHidd_X11Gfx_VisualClass , 0UL }, /* 4 */
407 { TAG_IGNORE , 0UL }, /* 5 */
408 { TAG_MORE , (IPTR) NULL } /* 6 */
411 EnterFunc(bug("X11Gfx::NewBitMap()\n"));
413 data = OOP_INST_DATA(cl, o);
415 tags[0].ti_Data = (IPTR)data->display;
416 tags[1].ti_Data = data->screen;
417 tags[2].ti_Data = (IPTR)data->cursor;
418 tags[3].ti_Data = data->colmap;
419 tags[4].ti_Data = XSD(cl)->vi.class;
420 tags[6].ti_Data = (IPTR)msg->attrList;
422 /* Displayable bitmap ? */
423 displayable = GetTagData(aHidd_BitMap_Displayable, FALSE, msg->attrList);
424 framebuffer = GetTagData(aHidd_BitMap_FrameBuffer, FALSE, msg->attrList);
426 if (framebuffer)
428 tags[5].ti_Tag = aHidd_BitMap_ClassPtr;
429 tags[5].ti_Data = (IPTR)XSD(cl)->onbmclass;
431 else if (displayable)
433 tags[5].ti_Tag = aHidd_BitMap_ClassPtr;
434 tags[5].ti_Data = (IPTR)XSD(cl)->offbmclass;
436 else
438 /* When do we create an x11 offscreen bitmap ?
439 - For 1-plane bitmaps.
440 - Bitmaps that have a friend that is an X11 bitmap
441 and there is no standard pixfmt supplied
442 - If the user supplied a modeid.
444 OOP_Object *friend;
445 BOOL usex11 = FALSE;
446 HIDDT_StdPixFmt stdpf;
448 friend = (OOP_Object *)GetTagData(aHidd_BitMap_Friend, 0, msg->attrList);
449 stdpf = (HIDDT_StdPixFmt)GetTagData(aHidd_BitMap_StdPixFmt, vHidd_StdPixFmt_Unknown, msg->attrList);
451 if (NULL != friend)
453 if (vHidd_StdPixFmt_Unknown == stdpf)
455 Drawable d;
457 /* Is the friend ann X11 bitmap ? */
458 d = (Drawable)OOP_GetAttr(friend, aHidd_X11BitMap_Drawable, (IPTR *)&d);
459 if (0 != d)
461 usex11 = TRUE;
466 if (!usex11)
468 if (vHidd_StdPixFmt_Plane == stdpf)
470 usex11 = TRUE;
472 else
474 HIDDT_ModeID modeid;
476 modeid = (HIDDT_ModeID)GetTagData(aHidd_BitMap_ModeID, vHidd_ModeID_Invalid, msg->attrList);
478 if (vHidd_ModeID_Invalid != modeid)
480 usex11 = TRUE;
485 if (usex11)
487 tags[5].ti_Tag = aHidd_BitMap_ClassPtr;
488 tags[5].ti_Data = (IPTR)XSD(cl)->offbmclass;
491 D(else kprintf("x11 hidd: Could not create offscreen bitmap for supplied attrs! Superclass hopefully can.\n");)
494 /* !!! IMPORTANT !!! */
496 p.mID = msg->mID;
497 p.attrList = tags;
499 newbm = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)&p);
501 if (NULL != newbm && framebuffer)
503 OOP_GetAttr(newbm, aHidd_X11BitMap_Drawable, &drawable);
504 data->fbwin = (Window)drawable;
505 #if ADJUST_XWIN_SIZE
506 OOP_GetAttr(newbm, aHidd_X11BitMap_MasterWindow, &drawable);
507 data->masterwin = (Window)drawable;
508 #endif
511 ReturnPtr("X11Gfx::NewBitMap", OOP_Object *, newbm);
514 /****************************************************************************************/
516 VOID X11Cl__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
518 struct gfx_data *data = OOP_INST_DATA(cl, o);
519 ULONG idx;
521 if (IS_X11GFX_ATTR(msg->attrID, idx))
523 switch (idx)
525 case aoHidd_X11Gfx_SysDisplay:
526 *msg->storage = (IPTR)data->display;
527 break;
529 case aoHidd_X11Gfx_SysScreen:
530 *msg->storage = (IPTR)data->screen;
531 break;
533 default:
534 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
535 break;
538 else if (IS_GFX_ATTR(msg->attrID, idx))
540 switch (idx)
542 case aoHidd_Gfx_IsWindowed:
543 *msg->storage = (IPTR)TRUE;
544 break;
546 case aoHidd_Gfx_SupportsHWCursor:
547 #if X11SOFTMOUSE
548 *msg->storage = (IPTR)FALSE;
549 #else
550 *msg->storage = (IPTR)TRUE;
551 #endif
552 break;
554 default:
555 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
556 break;
559 else
561 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
564 return;
567 /****************************************************************************************/
569 OOP_Object *X11Cl__Hidd_Gfx__Show(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_Show *msg)
571 OOP_Object *fb = 0;
572 IPTR width, height, modeid;
573 OOP_Object *pf, *sync;
574 struct gfx_data *data;
576 data = OOP_INST_DATA(cl, o);
578 if (!msg->bitMap)
580 return (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
583 OOP_GetAttr(msg->bitMap, aHidd_BitMap_ModeID, &modeid);
584 if ( HIDD_Gfx_GetMode(o, (HIDDT_ModeID)modeid, &sync, &pf))
586 struct MsgPort *port;
588 #if 1
589 OOP_GetAttr(msg->bitMap, aHidd_BitMap_Width, &width);
590 OOP_GetAttr(msg->bitMap, aHidd_BitMap_Height, &height);
591 #else
592 OOP_GetAttr(sync, aHidd_Sync_HDisp, &width);
593 OOP_GetAttr(sync, aHidd_Sync_VDisp, &height);
594 #endif
596 #if ADJUST_XWIN_SIZE
597 /* Send resize message to the x11 task */
598 port = CreateMsgPort();
599 if (NULL != port)
601 struct notify_msg *nmsg;
603 nmsg = AllocMem(sizeof (*nmsg), MEMF_PUBLIC);
604 if (NULL != nmsg)
606 nmsg->notify_type = NOTY_RESIZEWINDOW;
607 nmsg->xdisplay = data->display;
608 nmsg->xwindow = data->fbwin;
609 nmsg->masterxwindow = data->masterwin;
610 nmsg->width = width;
611 nmsg->height = height;
612 nmsg->execmsg.mn_ReplyPort = port;
614 PutMsg(XSD(cl)->x11task_notify_port, (struct Message *)nmsg);
616 WaitPort(port);
617 FreeMem(nmsg, sizeof (*nmsg));
618 #endif
620 fb = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
621 #if ADJUST_XWIN_SIZE
623 DeleteMsgPort(port);
626 #endif
629 return fb;
632 /****************************************************************************************/
634 VOID X11Cl__Hidd_Gfx__CopyBox(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CopyBox *msg)
636 ULONG mode;
637 Drawable src = 0, dest = 0;
638 struct gfx_data *data;
639 struct bitmap_data *bmdata;
641 data = OOP_INST_DATA(cl, o);
643 mode = GC_DRMD(msg->gc);
645 OOP_GetAttr(msg->src, aHidd_X11BitMap_Drawable, (IPTR *)&src);
646 OOP_GetAttr(msg->dest, aHidd_X11BitMap_Drawable, (IPTR *)&dest);
648 if (0 == dest || 0 == src)
650 /* The destination object is no X11 bitmap, onscreen nor offscreen.
651 Let the superclass do the copying in a more general way
653 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
655 return;
658 LOCK_X11
660 /* This may seem ugly, but we know nobody has subclassed
661 the x11 class, since it's private
663 bmdata = OOP_INST_DATA(XSD(cl)->onbmclass, msg->src);
665 XCALL(XSetFunction, data->display, bmdata->gc, mode);
667 XCALL(XCopyArea, data->display
668 , src /* src */
669 , dest /* dest */
670 , bmdata->gc
671 , msg->srcX
672 , msg->srcY
673 , msg->width
674 , msg->height
675 , msg->destX
676 , msg->destY
679 XFLUSH(data->display);
681 UNLOCK_X11
685 /****************************************************************************************/
687 BOOL X11Cl__Hidd_Gfx__SetCursorShape(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
689 /* Dummy implementation */
690 return TRUE;
693 /****************************************************************************************/
695 BOOL X11Cl__Hidd_Gfx__SetCursorPos(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
697 /* Dummy implementation */
698 return TRUE;
701 /****************************************************************************************/
703 VOID X11Cl__Hidd_Gfx__SetCursorVisible(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
705 /* Dummy implementation */
706 return;
709 /****************************************************************************************/
711 static ULONG mask_to_shift(ULONG mask)
713 ULONG i;
715 for (i = 32; mask; i --)
717 mask >>= 1;
720 if (mask == 32)
722 i = 0;
725 return i;
728 /****************************************************************************************/
730 #undef XSD
731 #define XSD(cl) xsd
734 Inits sysdisplay, sysscreen, colormap, etc.. */
735 static BOOL initx11stuff(struct x11_staticdata *xsd)
737 /* XColor fg, bg; */
738 BOOL ok = TRUE;
739 XVisualInfo template;
740 XVisualInfo *visinfo;
741 int template_mask;
742 int numvisuals;
743 XImage *testimage;
746 EnterFunc(bug("initx11stuff()\n"));
748 LOCK_X11
750 /* Get some info on the display */
751 template.visualid = XCALL(XVisualIDFromVisual, DefaultVisual(xsd->display, DefaultScreen(xsd->display)));
752 template_mask = VisualIDMask;
754 visinfo = XCALL(XGetVisualInfo, xsd->display, template_mask, &template, &numvisuals);
756 if (numvisuals > 1)
758 kprintf("!!! GOT MORE THAN ONE VISUAL FROM X !!!\n");
759 // CCALL(raise, SIGSTOP);
762 if (NULL == visinfo)
764 kprintf("!!! COULD NOT GET X VISUAL INFO !!!\n");
765 CCALL(raise, SIGSTOP);
767 ok = FALSE;
769 else
771 /* Store the visual info structure */
773 memcpy(&xsd->vi, visinfo, sizeof (XVisualInfo));
775 XCALL(XFree, visinfo);
777 visinfo = &xsd->vi;
779 /* We only support TrueColor for now */
781 switch (visinfo->class)
783 case TrueColor:
784 /* Get the pixel masks */
785 xsd->red_shift = mask_to_shift(xsd->vi.red_mask);
786 xsd->green_shift = mask_to_shift(xsd->vi.green_mask);
787 xsd->blue_shift = mask_to_shift(xsd->vi.blue_mask);
788 break;
790 case PseudoColor:
791 /* stegerg */
792 xsd->vi.red_mask = ((1 << xsd->vi.bits_per_rgb) - 1) << (xsd->vi.bits_per_rgb * 2);
793 xsd->vi.green_mask = ((1 << xsd->vi.bits_per_rgb) - 1) << (xsd->vi.bits_per_rgb * 1);
794 xsd->vi.blue_mask = ((1 << xsd->vi.bits_per_rgb) - 1);
795 xsd->red_shift = mask_to_shift(xsd->vi.red_mask);
796 xsd->green_shift = mask_to_shift(xsd->vi.green_mask);
797 xsd->blue_shift = mask_to_shift(xsd->vi.blue_mask);
798 /* end stegerg */
799 break;
801 default:
802 kprintf("!!! GFX HIDD only supports truecolor and pseudocolor diplays for now !!!\n");
803 CCALL(raise, SIGSTOP);
806 xsd->depth = 0;
808 /* stegerg: based on xwininfo source */
811 XWindowAttributes win_attributes;
813 if (!XCALL(XGetWindowAttributes, xsd->display,
814 RootWindow(xsd->display, DefaultScreen(xsd->display)),
815 &win_attributes))
817 kprintf("!!! X11gfx could not get bits per pixel\n");
818 CCALL(raise, SIGSTOP);
820 xsd->depth = win_attributes.depth;
821 kprintf("\n");
822 kprintf("DisplayPlanes = %d\n", DisplayPlanes(xsd->display, DefaultScreen(xsd->display)));
823 kprintf("DefaultDepth = %d\n", DefaultDepth(xsd->display, DefaultScreen(xsd->display)));
825 kprintf("\n\n BITS PER PIXEL = %d \n\n\n", xsd->depth);
828 /* Create a dummy X image to get bits per pixel */
829 testimage = XCALL(XGetImage, xsd->display, RootWindow(xsd->display,
830 DefaultScreen(xsd->display)), 0, 0, 1, 1,
831 AllPlanes, ZPixmap);
833 if (NULL != testimage)
835 xsd->bytes_per_pixel = (testimage->bits_per_pixel + 7) >> 3;
836 XDestroyImage(testimage);
838 else
840 kprintf("!!! X11gfx could not get bits per pixel\n");
841 CCALL(raise, SIGSTOP);
844 if (PseudoColor == xsd->vi.class)
846 xsd->clut_mask = (1L << xsd->depth) - 1;
847 xsd->clut_shift = 0;
851 /* Create a dummy window for pixmaps */
853 xsd->dummy_window_for_creating_pixmaps = XCALL(XCreateSimpleWindow, xsd->display,
854 DefaultRootWindow(xsd->display),
855 0, 0, 100, 100,
857 BlackPixel(xsd->display, DefaultScreen(xsd->display)),
858 BlackPixel(xsd->display, DefaultScreen(xsd->display)));
859 if (0 == xsd->dummy_window_for_creating_pixmaps)
861 ok = FALSE;
864 #if USE_XSHM
866 char *displayname = XCALL(XDisplayName, xsd->display);
868 if ((strncmp(displayname, ":", 1) == 0) ||
869 (strncmp(displayname, "unix:", 5) == 0))
871 /* Display is local, not remote. XSHM is possible */
873 /* Do we have Xshm support ? */
874 xsd->xshm_info = init_shared_mem(xsd->display);
876 if (NULL == xsd->xshm_info)
878 /* ok = FALSE; */
879 kprintf("INITIALIZATION OF XSHM FAILED !!\n");
881 else
883 InitSemaphore(&xsd->shm_sema);
884 xsd->use_xshm = TRUE;
888 #endif
891 UNLOCK_X11
893 ReturnBool("initx11stuff", ok);
897 /****************************************************************************************/
899 static VOID cleanupx11stuff(struct x11_staticdata *xsd)
901 LOCK_X11
903 /* Do nothing for now */
904 if (0 != xsd->dummy_window_for_creating_pixmaps)
906 XCALL(XDestroyWindow, xsd->display, xsd->dummy_window_for_creating_pixmaps);
909 #if USE_XSHM
910 cleanup_shared_mem(xsd->display, xsd->xshm_info);
911 #endif
913 UNLOCK_X11
916 /****************************************************************************************/
918 #define xsd (&LIBBASE->xsd)
920 /****************************************************************************************/
922 static int x11gfx_init(LIBBASETYPEPTR LIBBASE)
924 return OOP_ObtainAttrBases(attrbases);
927 /****************************************************************************************/
929 static int x11gfx_expunge(LIBBASETYPEPTR LIBBASE)
931 OOP_ReleaseAttrBases(attrbases);
932 return TRUE;
935 /****************************************************************************************/
937 ADD2INITLIB(x11gfx_init, 0);
938 ADD2EXPUNGELIB(x11gfx_expunge, 0);
940 /****************************************************************************************/