revert between 56095 -> 55830 in arch
[AROS.git] / arch / all-hosted / hidd / x11 / x11gfx_onbitmap.c
blob185b1cf2b7abca682e8b8603557a2038c1bca369
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Bitmap class for X11 hidd.
6 Lang: English.
7 */
9 #include "x11_debug.h"
11 #include <hidd/gfx.h>
12 #include <proto/utility.h>
14 #include "x11_types.h"
15 #include "x11.h"
16 #include "x11_hostlib.h"
17 #include "x11gfx_bitmap.h"
19 /****************************************************************************************/
21 #if ADJUST_XWIN_SIZE
22 #define MASTERWIN(data) (data)->masterxwindow
23 #define ROOTWIN(data) (data)->masterxwindow
24 #else
25 #define MASTERWIN WINDRAWABLE
26 #define ROOTWIN(data) rootwin
27 #endif
29 /****************************************************************************************/
31 static Pixmap init_icon(Display *d, Window w, Colormap cm, LONG depth,
32 struct x11_staticdata *xsd);
34 /****************************************************************************************/
36 BOOL X11BM_InitFB(OOP_Class *cl, OOP_Object *o, struct TagItem *attrList)
38 Window rootwin;
39 OOP_Object *sync, *pixfmt;
40 HIDDT_ModeID modeid;
41 IPTR depth;
42 XSetWindowAttributes winattr;
43 int visualclass;
44 unsigned long valuemask;
45 struct bitmap_data *data = OOP_INST_DATA(cl, o);
46 struct x11_staticdata *xsd = XSD(cl);
48 D(bug("[X11OnBm] %s()\n", __PRETTY_FUNCTION__));
50 /* stegerg */
51 visualclass = GetTagData(aHidd_BitMap_X11_VisualClass, TrueColor, attrList);
52 if (visualclass == PseudoColor)
54 Colormap cm;
56 HostLib_Lock();
57 cm = XCALL(XCreateColormap, GetSysDisplay(), RootWindow(GetSysDisplay(), GetSysScreen()),
58 xsd->vi->visual, AllocAll);
59 HostLib_Unlock();
61 if (cm)
63 data->colmap = cm;
64 data->flags |= BMDF_COLORMAP_ALLOCED;
67 /* end stegerg */
70 * Get window size from our ModeID.
71 * We can't support scrolling in framebuffer mode.
73 OOP_GetAttr(o, aHidd_BitMap_ModeID, &modeid);
74 OOP_GetAttr(o, aHidd_BitMap_GfxHidd, (IPTR *) &data->gfxhidd);
75 D(bug("[X11OnBm] ModeID 0x%08X, driver @ 0x%p\n", modeid, data->gfxhidd));
77 HIDD_Gfx_GetMode(data->gfxhidd, modeid, &sync, &pixfmt);
79 OOP_GetAttr(sync, aHidd_Sync_HDisp, &data->width);
80 OOP_GetAttr(sync, aHidd_Sync_VDisp, &data->height);
81 depth = DefaultDepth(GetSysDisplay(), GetSysScreen());
83 /* Open an X window to be used for viewing */
84 D(bug("[X11OnBm] Framebuffer window size %ldx%ldx%d\n", data->width, data->height, depth));
86 /* Listen for all sorts of events */
87 winattr.event_mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask
88 | KeyPressMask | KeyReleaseMask | StructureNotifyMask
89 | SubstructureNotifyMask | FocusChangeMask | ExposureMask;
91 if (XSD(cl)->options & OPTION_BACKINGSTORE)
93 /* Framebuffer needs backing store. (Uses lots of mem) */
94 winattr.backing_store = Always;
95 winattr.save_under = True;
98 winattr.cursor = GetSysCursor();
99 winattr.background_pixel = BlackPixel(GetSysDisplay(), GetSysScreen());
101 rootwin = DefaultRootWindow(GetSysDisplay());
102 D(bug("Creating XWindow: root win=%p\n", rootwin));
104 valuemask = CWCursor | CWEventMask | CWBackPixel;
106 if (XSD(cl)->options & OPTION_BACKINGSTORE)
107 valuemask |= CWBackingStore | CWSaveUnder;
109 if (data->flags & BMDF_COLORMAP_ALLOCED)
111 winattr.colormap = data->colmap;
112 valuemask |= CWColormap;
115 HostLib_Lock();
117 #if ADJUST_XWIN_SIZE
119 XSetWindowAttributes rootattr;
120 unsigned long rootmask = 0;
122 rootattr.event_mask = FocusChangeMask;
123 rootmask |= CWEventMask;
125 if (XSD(cl)->options & OPTION_FULLSCREEN)
127 rootattr.override_redirect = True;
128 rootmask |= CWOverrideRedirect;
131 if (data->flags & BMDF_COLORMAP_ALLOCED)
133 rootattr.colormap = data->colmap;
134 rootmask |= CWColormap;
137 MASTERWIN(data) = XCALL(XCreateWindow, GetSysDisplay(), rootwin,
138 0, /* leftedge */
139 0, /* topedge */
140 data->width,
141 data->height,
142 0, /* BorderWidth */
143 depth,
144 InputOutput,
145 DefaultVisual(GetSysDisplay(), GetSysScreen()),
146 rootmask,
147 &rootattr);
150 if (MASTERWIN(data))
151 #endif
153 WINDRAWABLE(data) = XCALL(XCreateWindow, GetSysDisplay(),
154 ROOTWIN(data),
155 0, /* leftedge */
156 0, /* topedge */
157 data->width,
158 data->height,
159 0, /* BorderWidth */
160 depth,
161 InputOutput,
162 DefaultVisual(GetSysDisplay(), GetSysScreen()),
163 valuemask,
164 &winattr);
166 HostLib_Unlock();
168 D(bug("[X11OnBm] X Window @ 0x%p\n", WINDRAWABLE(data)));
170 if (WINDRAWABLE(data))
172 Pixmap icon;
173 #if !ADJUST_XWIN_SIZE
174 XSizeHints sizehint;
175 #endif
176 XClassHint *classhint;
178 HostLib_Lock();
180 classhint = XCALL(XAllocClassHint);
181 classhint->res_name = "AROS";
182 classhint->res_class = "AROS";
183 XCALL(XSetClassHint, GetSysDisplay(), MASTERWIN(data), classhint);
185 XCALL(XStoreName, GetSysDisplay(), MASTERWIN(data), "AROS");
186 XCALL(XSetIconName, GetSysDisplay(), MASTERWIN(data), "AROS Screen");
188 #if !ADJUST_XWIN_SIZE
189 sizehint.flags = PMinSize | PMaxSize;
190 sizehint.min_width = data->width;
191 sizehint.min_height = data->height;
192 sizehint.max_width = data->width;
193 sizehint.max_height = data->height;
195 XCALL(XSetWMNormalHints, GetSysDisplay(), MASTERWIN(data), &sizehint);
196 #endif
198 XCALL(XSetWMProtocols,
199 GetSysDisplay(), MASTERWIN(data), &XSD(cl)->delete_win_atom, 1);
201 icon = init_icon(GetSysDisplay(), MASTERWIN(data),
202 DefaultColormap(GetSysDisplay(), GetSysScreen()), depth, xsd);
204 if (icon)
206 XWMHints hints;
208 hints.icon_pixmap = icon;
209 hints.flags = IconPixmapHint;
211 XCALL(XSetWMHints, GetSysDisplay(), MASTERWIN(data), &hints);
214 if (XSD(cl)->options & OPTION_BACKINGSTORE)
216 DRAWABLE(data) = WINDRAWABLE(data);
217 data->flags |= BMDF_BACKINGSTORE;
219 else
221 DRAWABLE(data) = XCALL(XCreatePixmap, data->display, WINDRAWABLE(data), data->width, data->height, depth);
225 * stegerg: XMapRaised is now called inside the X11 task when getting
226 * the NOTY_MAPWINDOW message, otherwise the X11 task can
227 * get a "dead" MapNotify event:
229 * XCreateWindow is called here on the app task context.
230 * If we also call XMapRaised here then the X11 task might
231 * get the MapNotify event before he got the NOTY_WINCREATE
232 * message sent from here (see below). So the X11 task
233 * would not know about our window and therefore ignore
234 * the MapNotify event from X.
236 * This caused the freezes which sometimes happened during
237 * startup when the Workbench screen was opened.
239 * XCALL(XMapRaised, GetSysDisplay(), DRAWABLE(data));
242 HostLib_Unlock();
244 return TRUE;
245 } /* if WINDRAWABLE(data) */
247 return FALSE;
250 /****************************************************************************************/
252 BOOL X11BM_NotifyFB(OOP_Class *cl, OOP_Object *o)
254 struct bitmap_data *data = OOP_INST_DATA(cl, o);
255 struct x11_staticdata *xsd = XSD(cl);
256 struct MsgPort *port;
258 D(bug("[X11OnBm] %s()\n", __PRETTY_FUNCTION__));
261 * Now we need to get some message from the X11 task about when
262 * the window has been mapped (i.e. MapWindow event).
263 * This is because we cannot render into the window until
264 * it has been mapped.
267 port = CreateMsgPort();
269 if (NULL != port)
271 /* Send a message to the x11 task that the window has been created */
272 struct notify_msg msg;
274 msg.notify_type = NOTY_WINCREATE;
275 msg.xdisplay = GetSysDisplay();
276 msg.xwindow = WINDRAWABLE(data);
277 msg.masterxwindow = MASTERWIN(data);
278 msg.bmobj = o;
279 msg.execmsg.mn_ReplyPort = port;
281 HostLib_Lock();
282 XCALL(XSync, GetSysDisplay(), FALSE);
283 HostLib_Unlock();
285 D(bug("[X11] %s: notifying port @ 0x%p\n", __PRETTY_FUNCTION__,
286 xsd->x11task_notify_port));
287 X11DoNotify(xsd, &msg);
289 if (!(XSD(cl)->options & OPTION_DELAYXWINMAPPING))
291 D(bug("[X11OnBm] %s: notifying x11 task to map window...\n",
292 __PRETTY_FUNCTION__));
294 * Send a message to the X11 task to ask when the window has
295 * been mapped. We change only notify_type; other fields are
296 * already set.
298 msg.notify_type = NOTY_MAPWINDOW;
300 HostLib_Lock();
301 XCALL(XSync, GetSysDisplay(), FALSE);
302 HostLib_Unlock();
304 D(bug("[X11] %s: notifying port @ 0x%p\n", __PRETTY_FUNCTION__,
305 xsd->x11task_notify_port));
306 X11DoNotify(xsd, &msg);
309 DeleteMsgPort(port);
311 return TRUE;
314 return FALSE;
317 /****************************************************************************************/
319 VOID X11BM_DisposeFB(struct bitmap_data *data, struct x11_staticdata *xsd)
321 D(bug("[X11OnBm] %s()\n", __PRETTY_FUNCTION__));
323 if (WINDRAWABLE(data))
325 struct MsgPort *port;
326 struct notify_msg msg;
328 port = CreateMsgPort();
330 if (NULL == port)
332 D(bug("[X11OnBm] %s: failed to create notification message port!\n", __PRETTY_FUNCTION__));
334 return;
337 msg.notify_type = NOTY_WINDISPOSE;
338 msg.xdisplay = GetSysDisplay();
339 msg.xwindow = WINDRAWABLE(data);
340 msg.masterxwindow = MASTERWIN(data);
341 msg.execmsg.mn_ReplyPort = port;
343 D(bug("[X11] %s: notifying port @ 0x%p\n", __PRETTY_FUNCTION__, xsd->x11task_notify_port));
344 X11DoNotify(xsd, &msg);
345 DeleteMsgPort(port);
348 /* Dispose everything */
349 HostLib_Lock();
351 if (WINDRAWABLE(data))
352 XCALL(XDestroyWindow, GetSysDisplay(), WINDRAWABLE(data));
354 #if ADJUST_XWIN_SIZE
355 if (MASTERWIN(data))
356 XCALL(XDestroyWindow, GetSysDisplay(), MASTERWIN(data));
357 #endif
359 if (data->flags & BMDF_COLORMAP_ALLOCED)
360 XCALL(XFreeColormap, GetSysDisplay(), data->colmap);
362 if (!(data->flags & BMDF_BACKINGSTORE))
363 XCALL(XFreePixmap, GetSysDisplay(), DRAWABLE(data));
365 XCALL(XFlush, GetSysDisplay());
367 HostLib_Unlock();
370 /****************************************************************************************/
372 #if ADJUST_XWIN_SIZE
374 BOOL X11BM_SetMode(struct bitmap_data *data, HIDDT_ModeID modeid,
375 struct x11_staticdata *xsd)
377 OOP_Object *sync, *pf;
379 D(bug("[X11OnBm] %s()\n", __PRETTY_FUNCTION__));
381 if (HIDD_Gfx_GetMode(data->gfxhidd, (HIDDT_ModeID) modeid, &sync, &pf))
383 struct MsgPort *port;
384 IPTR new_width, new_height;
386 D(bug("[X11OnBm] %s: got mode info\n", __PRETTY_FUNCTION__));
388 OOP_GetAttr(sync, aHidd_Sync_HDisp, &new_width);
389 OOP_GetAttr(sync, aHidd_Sync_VDisp, &new_height);
392 * Don't do anything if the size actually won't change.
393 * Prevents badly looking flashing, at least on Darwin.
395 if (!(xsd->options & OPTION_DELAYXWINMAPPING) && (new_width == data->width) && (new_height == data->height))
397 D(bug("[X11OnBm] %s: no change ..\n", __PRETTY_FUNCTION__));
398 return TRUE;
401 port = CreateMsgPort();
402 if (port)
404 struct notify_msg nmsg;
406 /* Send resize message to the x11 task */
407 nmsg.notify_type = NOTY_RESIZEWINDOW;
408 nmsg.xdisplay = data->display;
409 nmsg.xwindow = WINDRAWABLE(data);
410 nmsg.masterxwindow = data->masterxwindow;
411 nmsg.width = new_width;
412 nmsg.height = new_height;
413 nmsg.execmsg.mn_ReplyPort = port;
415 D(bug("[X11] %s: notifying port @ 0x%p\n", __PRETTY_FUNCTION__, xsd->x11task_notify_port));
416 X11DoNotify(xsd, &nmsg);
417 DeleteMsgPort(port);
419 /* Update cached size */
420 data->width = new_width;
421 data->height = new_height;
423 return TRUE;
426 return FALSE;
429 #endif
431 /****************************************************************************************/
433 VOID X11BM_ClearFB(struct bitmap_data *data, HIDDT_Pixel bg)
435 XSetWindowAttributes winattr;
437 D(bug("[X11OnBm] %s()\n", __PRETTY_FUNCTION__));
439 winattr.background_pixel = bg;
441 XCALL(XChangeWindowAttributes, data->display, WINDRAWABLE(data), CWBackPixel, &winattr);
442 XCALL(XClearArea, data->display, DRAWABLE(data), 0, 0, data->width, data->height, FALSE);
443 X11BM_ExposeFB(data, 0, 0, data->width, data->height);
446 /****************************************************************************************/
448 VOID X11BM_ExposeFB(struct bitmap_data *data, WORD x, WORD y, WORD width, WORD height)
450 D(bug("[X11OnBm] %s(%d, %d, %d, %d)\n", __PRETTY_FUNCTION__,
451 x, y, width, height));
453 if (!(data->flags & BMDF_BACKINGSTORE))
455 XCALL(XSetFunction, data->display, data->gc, GXcopy);
456 XCALL(XCopyArea, data->display, DRAWABLE(data), WINDRAWABLE(data), data->gc,
457 x, y, width, height, x, y);
461 /****************************************************************************************/
463 #if X11SOFTMOUSE
465 //void init_empty_cursor(Window w, GC gc, struct x11_staticdata *xsd)
466 VOID X11BM_InitEmptyCursor(struct bitmap_data *data)
468 Pixmap p, mask;
469 int width, height;
471 D(bug("[X11OnBm] %s()\n", __PRETTY_FUNCTION__));
473 width = height = 1;
475 LOCK_X11
476 p = XCALL(XCreatePixmap, data->display, WINDRAWABLE(data), width, height, 1);
477 UNLOCK_X11
479 if (0 != p)
481 LOCK_X11
482 mask = XCALL(XCreatePixmap, data->display, WINDRAWABLE(data), width, height, 1);
483 XCALL(XFlush, data->display);
484 UNLOCK_X11
486 if (0 != mask)
488 /* Define cursor for window */
489 XColor fg, bg;
490 Cursor c;
491 GC gc;
493 LOCK_X11
494 gc = XCALL(XCreateGC, data->display, WINDRAWABLE(data), 0, 0);
495 XCALL(XSetForeground, data->display, gc, 0);
496 XCALL(XSetFunction, data->display, gc, GXcopy);
497 #if 0
498 XCALL(XFillRectangle, data->display, p, gc, 1, 1, 1, 1);
499 for (y = 0; y < height; y ++)
501 for (x = 0; x < width; x ++)
503 XCALL(XDrawPoint, data->display, mask, gc, x, y);
506 #endif
507 UNLOCK_X11
509 fg.pixel = BlackPixel(data->display, DefaultScreen(data->display));
510 fg.red = 0x0000;
511 fg.green = 0x0000;
512 fg.blue = 0x0000;
513 fg.flags = DoRed | DoGreen | DoBlue;
515 bg.pixel = WhitePixel(data->display, DefaultScreen(data->display));
516 bg.red = 0xFFFF;
517 bg.green = 0xFFFF;
518 bg.blue = 0xFFFF;
519 bg.flags = DoRed | DoGreen | DoBlue;
521 LOCK_X11
522 c = XCALL(XCreatePixmapCursor, data->display, p, mask, &fg, &bg, 0, 0);
523 UNLOCK_X11
525 if (0 != c)
527 LOCK_X11
528 XCALL(XDefineCursor, data->display, WINDRAWABLE(data), c);
529 UNLOCK_X11
532 LOCK_X11
533 XCALL(XFreePixmap, data->display, mask);
534 XCALL(XFreeGC, data->display, gc);
535 UNLOCK_X11
538 LOCK_X11
539 XCALL(XFreePixmap, data->display, p);
540 UNLOCK_X11
545 #endif
547 /****************************************************************************************/
549 static Pixmap init_icon(Display *d, Window w, Colormap cm, LONG depth,
550 struct x11_staticdata *xsd)
552 #include "icon.h"
554 #define SHIFT_PIX(pix, shift) \
555 (( (shift) < 0) ? (pix) >> (-shift) : (pix) << (shift) )
557 Pixmap icon = XCALL(XCreatePixmap, d, w, width, height, depth);
558 char *data = header_data;
559 LONG red_shift, green_shift, blue_shift;
560 GC gc;
562 D(bug("[X11OnBm] %s()\n", __PRETTY_FUNCTION__));
564 red_shift = 24 - xsd->red_shift;
565 green_shift = 24 - xsd->green_shift;
566 blue_shift = 24 - xsd->blue_shift;
568 if (icon)
570 gc = XCALL(XCreateGC, d, icon, 0, 0);
572 if (gc)
574 WORD x, y;
576 for (y = 0; y < height; y++)
578 for (x = 0; x < width; x++)
580 ULONG rgb[3];
581 ULONG pixel = 0;
583 HEADER_PIXEL(data, rgb);
585 if (xsd->vi->class == TrueColor)
587 pixel = (SHIFT_PIX(rgb[0] & 0xFF, red_shift)
588 & xsd->vi->red_mask)
589 | (SHIFT_PIX(rgb[1] & 0xFF, green_shift)
590 & xsd->vi->green_mask)
591 | (SHIFT_PIX(rgb[2] & 0xFF, blue_shift)
592 & xsd->vi->blue_mask);
594 else if (xsd->vi->class == PseudoColor)
596 XColor xcol;
598 xcol.red = (rgb[0] << 8) + rgb[0];
599 xcol.green = (rgb[1] << 8) + rgb[1];
600 xcol.blue = (rgb[2] << 8) + rgb[2];
601 xcol.flags = DoRed | DoGreen | DoBlue;
603 if (XCALL(XAllocColor, d, cm, &xcol))
605 pixel = xcol.pixel;
609 XCALL(XSetForeground, d, gc, pixel);
610 XCALL(XDrawPoint, d, icon, gc, x, y);
614 XCALL(XFreeGC, d, gc);
616 } /* if (gc) */
618 } /* if (icon) */
620 return icon;