/[rdesktop]/sourceforge.net/trunk/rdesktop/xwin.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /sourceforge.net/trunk/rdesktop/xwin.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 80 - (hide annotations)
Tue Jul 30 00:56:48 2002 UTC (21 years, 9 months ago) by jsorg71
File MIME type: text/plain
File size: 25099 byte(s)
patblt reset orgin from up19-7-4

1 matty 6 /*
2     rdesktop: A Remote Desktop Protocol client.
3 matthewc 38 User interface services - X Window System
4 matty 30 Copyright (C) Matthew Chapman 1999-2001
5 n-ki 52
6 matty 6 This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 n-ki 52
11 matty 6 This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     GNU General Public License for more details.
15 n-ki 52
16 matty 6 You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20    
21 matty 10 #include <X11/Xlib.h>
22 matty 28 #include <X11/Xutil.h>
23 matty 10 #include <time.h>
24 matty 33 #include <errno.h>
25 astrand 66 #define XK_MISCELLANY
26     #include <X11/keysymdef.h>
27 matty 10 #include "rdesktop.h"
28 astrand 76 #include "scancodes.h"
29 matty 6
30 matty 10 extern int width;
31     extern int height;
32 matty 29 extern BOOL sendmotion;
33 matty 28 extern BOOL fullscreen;
34 astrand 76 extern BOOL grab_keyboard;
35 matty 10
36 astrand 66 Display *display = NULL;
37 matty 33 static int x_socket;
38 matty 10 static Window wnd;
39     static GC gc;
40     static Visual *visual;
41 matty 29 static int depth;
42     static int bpp;
43    
44 matty 33 /* endianness */
45     static BOOL host_be;
46     static BOOL xserver_be;
47    
48     /* software backing store */
49 matty 31 static BOOL ownbackstore;
50     static Pixmap backstore;
51    
52     #define FILL_RECTANGLE(x,y,cx,cy)\
53     { \
54     XFillRectangle(display, wnd, gc, x, y, cx, cy); \
55     if (ownbackstore) \
56     XFillRectangle(display, backstore, gc, x, y, cx, cy); \
57     }
58    
59 matty 33 /* colour maps */
60 matty 29 static BOOL owncolmap;
61     static Colormap xcolmap;
62     static uint32 white;
63 matty 28 static uint32 *colmap;
64 astrand 66 static XIM IM = NULL;
65     static XIC IC = NULL;
66 matty 10
67 astrand 70 /* Compose support */
68     BOOL enable_compose = False;
69    
70 matty 33 #define TRANSLATE(col) ( owncolmap ? col : translate_colour(colmap[col]) )
71 matty 29 #define SET_FOREGROUND(col) XSetForeground(display, gc, TRANSLATE(col));
72     #define SET_BACKGROUND(col) XSetBackground(display, gc, TRANSLATE(col));
73 matty 28
74     static int rop2_map[] = {
75     GXclear, /* 0 */
76     GXnor, /* DPon */
77     GXandInverted, /* DPna */
78     GXcopyInverted, /* Pn */
79     GXandReverse, /* PDna */
80     GXinvert, /* Dn */
81     GXxor, /* DPx */
82     GXnand, /* DPan */
83     GXand, /* DPa */
84     GXequiv, /* DPxn */
85     GXnoop, /* D */
86     GXorInverted, /* DPno */
87     GXcopy, /* P */
88     GXorReverse, /* PDno */
89     GXor, /* DPo */
90     GXset /* 1 */
91     };
92    
93 matty 29 #define SET_FUNCTION(rop2) { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }
94     #define RESET_FUNCTION(rop2) { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
95    
96 matty 28 static void
97 astrand 64 translate8(uint8 * data, uint8 * out, uint8 * end)
98 matty 28 {
99 matty 29 while (out < end)
100 astrand 64 *(out++) = (uint8) colmap[*(data++)];
101 matty 29 }
102 matty 28
103 matty 29 static void
104 astrand 64 translate16(uint8 * data, uint16 * out, uint16 * end)
105 matty 29 {
106     while (out < end)
107 astrand 64 *(out++) = (uint16) colmap[*(data++)];
108 matty 29 }
109    
110 matty 33 /* little endian - conversion happens when colourmap is built */
111 matty 29 static void
112 astrand 64 translate24(uint8 * data, uint8 * out, uint8 * end)
113 matty 29 {
114     uint32 value;
115    
116     while (out < end)
117 matty 28 {
118 matty 29 value = colmap[*(data++)];
119     *(out++) = value;
120     *(out++) = value >> 8;
121     *(out++) = value >> 16;
122 matty 28 }
123     }
124    
125     static void
126 astrand 64 translate32(uint8 * data, uint32 * out, uint32 * end)
127 matty 28 {
128 matty 29 while (out < end)
129     *(out++) = colmap[*(data++)];
130 matty 28 }
131    
132 matty 29 static uint8 *
133 astrand 64 translate_image(int width, int height, uint8 * data)
134 matty 28 {
135 astrand 64 int size = width * height * bpp / 8;
136 matty 29 uint8 *out = xmalloc(size);
137     uint8 *end = out + size;
138    
139     switch (bpp)
140     {
141     case 8:
142     translate8(data, out, end);
143     break;
144    
145     case 16:
146 astrand 64 translate16(data, (uint16 *) out, (uint16 *) end);
147 matty 29 break;
148    
149     case 24:
150     translate24(data, out, end);
151     break;
152    
153     case 32:
154 astrand 64 translate32(data, (uint32 *) out, (uint32 *) end);
155 matty 29 break;
156     }
157    
158     return out;
159 matty 28 }
160    
161 matty 35 #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
162     #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }
163     #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
164     x = (x << 16) | (x >> 16); }
165 matty 29
166 matty 33 static uint32
167     translate_colour(uint32 colour)
168     {
169     switch (bpp)
170     {
171     case 16:
172     if (host_be != xserver_be)
173     BSWAP16(colour);
174     break;
175 matty 29
176 matty 33 case 24:
177     if (xserver_be)
178     BSWAP24(colour);
179     break;
180    
181     case 32:
182     if (host_be != xserver_be)
183     BSWAP32(colour);
184     break;
185     }
186    
187     return colour;
188     }
189    
190 astrand 66 static unsigned long
191     init_inputmethod(void)
192     {
193 astrand 70 unsigned long filtered_events = 0;
194 astrand 66
195     IM = XOpenIM(display, NULL, NULL, NULL);
196     if (IM == NULL)
197     {
198     error("Failed to open input method\n");
199     }
200    
201     if (IM != NULL)
202     {
203     /* Must be done after XCreateWindow */
204     IC = XCreateIC(IM, XNInputStyle,
205     (XIMPreeditNothing | XIMStatusNothing),
206     XNClientWindow, wnd, XNFocusWindow, wnd, NULL);
207    
208     if (IC == NULL)
209     {
210     error("Failed to create input context\n");
211     XCloseIM(IM);
212     IM = NULL;
213     }
214     }
215    
216     /* For correct Multi_key/Compose processing, I guess.
217     It seems to work alright anyway, though. */
218     if (IC != NULL)
219     {
220     if (XGetICValues(IC, XNFilterEvents, &filtered_events, NULL)
221     != NULL)
222     {
223     error("Failed to obtain XNFilterEvents value from IC\n");
224     filtered_events = 0;
225     }
226     }
227     return filtered_events;
228     }
229    
230     static void
231     close_inputmethod(void)
232     {
233     if (IC != NULL)
234     {
235     XDestroyIC(IC);
236     if (IM != NULL)
237     {
238     XCloseIM(IM);
239     IM = NULL;
240     }
241     }
242     }
243    
244    
245 matty 25 BOOL
246     ui_create_window(char *title)
247 matty 6 {
248 matty 9 XSetWindowAttributes attribs;
249 matty 28 XClassHint *classhints;
250     XSizeHints *sizehints;
251 matty 10 unsigned long input_mask;
252 matty 28 XPixmapFormatValues *pfm;
253 matty 29 Screen *screen;
254 matty 33 uint16 test;
255 matty 29 int i;
256 astrand 64
257 astrand 66 display = XOpenDisplay(NULL);
258 matty 6
259     if (display == NULL)
260 matty 21 {
261 matty 30 error("Failed to open display\n");
262 matty 10 return False;
263 matty 21 }
264 matty 6
265 matty 33 x_socket = ConnectionNumber(display);
266 matty 29 screen = DefaultScreenOfDisplay(display);
267     visual = DefaultVisualOfScreen(screen);
268     depth = DefaultDepthOfScreen(screen);
269 astrand 64
270 matty 29 pfm = XListPixmapFormats(display, &i);
271 matty 28 if (pfm != NULL)
272     {
273 matty 29 /* Use maximum bpp for this depth - this is generally
274     desirable, e.g. 24 bits->32 bits. */
275     while (i--)
276 matty 28 {
277 matty 29 if ((pfm[i].depth == depth)
278     && (pfm[i].bits_per_pixel > bpp))
279 matty 28 {
280 matty 29 bpp = pfm[i].bits_per_pixel;
281 matty 28 }
282     }
283     XFree(pfm);
284     }
285 matty 10
286 matty 28 if (bpp < 8)
287 matty 10 {
288 matty 30 error("Less than 8 bpp not currently supported.\n");
289 matty 10 XCloseDisplay(display);
290     return False;
291     }
292    
293 matty 29 if (depth <= 8)
294     owncolmap = True;
295     else
296     xcolmap = DefaultColormapOfScreen(screen);
297 matty 6
298 matty 33 test = 1;
299 astrand 64 host_be = !(BOOL) (*(uint8 *) (&test));
300 matty 33 xserver_be = (ImageByteOrder(display) == MSBFirst);
301    
302 matty 29 white = WhitePixelOfScreen(screen);
303     attribs.background_pixel = BlackPixelOfScreen(screen);
304     attribs.backing_store = DoesBackingStore(screen);
305 matty 28
306 matty 29 if (attribs.backing_store == NotUseful)
307 matty 31 ownbackstore = True;
308 matty 29
309 matty 28 if (fullscreen)
310     {
311     attribs.override_redirect = True;
312 matty 29 width = WidthOfScreen(screen);
313     height = HeightOfScreen(screen);
314 matty 28 }
315     else
316     {
317     attribs.override_redirect = False;
318     }
319    
320 astrand 64 width = (width + 3) & ~3; /* make width a multiple of 32 bits */
321 matty 29
322     wnd = XCreateWindow(display, RootWindowOfScreen(screen),
323 matty 28 0, 0, width, height, 0, CopyFromParent,
324     InputOutput, CopyFromParent,
325     CWBackingStore | CWBackPixel | CWOverrideRedirect,
326     &attribs);
327 matty 9
328 matty 10 XStoreName(display, wnd, title);
329 matty 6
330 matty 28 classhints = XAllocClassHint();
331     if (classhints != NULL)
332     {
333 matty 29 classhints->res_name = classhints->res_class = "rdesktop";
334 matty 28 XSetClassHint(display, wnd, classhints);
335     XFree(classhints);
336     }
337    
338     sizehints = XAllocSizeHints();
339     if (sizehints)
340     {
341 matty 29 sizehints->flags = PMinSize | PMaxSize;
342     sizehints->min_width = sizehints->max_width = width;
343     sizehints->min_height = sizehints->max_height = height;
344 matty 28 XSetWMNormalHints(display, wnd, sizehints);
345     XFree(sizehints);
346     }
347    
348 astrand 66 xkeymap_init2();
349 matthewc 38
350 astrand 66 input_mask =
351     KeyPressMask | KeyReleaseMask | ButtonPressMask |
352 astrand 76 ButtonReleaseMask;
353     if (grab_keyboard)
354     input_mask |= EnterWindowMask | LeaveWindowMask;
355 matty 29 if (sendmotion)
356 matty 10 input_mask |= PointerMotionMask;
357 matty 6
358 matty 31 if (ownbackstore)
359     input_mask |= ExposureMask;
360    
361 astrand 70 if (enable_compose)
362     input_mask |= init_inputmethod();
363 astrand 66
364 astrand 70 XSelectInput(display, wnd, input_mask);
365 astrand 66
366 matty 10 gc = XCreateGC(display, wnd, 0, NULL);
367 matty 7
368 matty 31 if (ownbackstore)
369     backstore = XCreatePixmap(display, wnd, width, height, depth);
370    
371 matty 28 XMapWindow(display, wnd);
372 n-ki 52
373 matty 10 return True;
374 matty 6 }
375    
376 matty 25 void
377     ui_destroy_window()
378 matty 6 {
379 matty 31 if (ownbackstore)
380     XFreePixmap(display, backstore);
381    
382 matty 10 XFreeGC(display, gc);
383 astrand 66
384     close_inputmethod();
385    
386 matty 10 XDestroyWindow(display, wnd);
387     XCloseDisplay(display);
388 matty 28 display = NULL;
389 matty 6 }
390    
391 matty 33 static void
392     xwin_process_events()
393 matty 9 {
394 n-ki 54 XEvent xevent;
395    
396 matthewc 38 KeySym keysym;
397 matthewc 50 uint16 button, flags;
398 matty 10 uint32 ev_time;
399 astrand 66 key_translation tr;
400     char *ksname = NULL;
401     char str[256];
402     Status status;
403 matty 9
404 astrand 66 /* Refresh keyboard mapping if it has changed. This is important for
405     Xvnc, since it allocates keycodes dynamically */
406     if (XCheckTypedEvent(display, MappingNotify, &xevent))
407     {
408     if (xevent.xmapping.request == MappingKeyboard
409     || xevent.xmapping.request == MappingModifier)
410     XRefreshKeyboardMapping(&xevent.xmapping);
411     }
412    
413 n-ki 54 while (XCheckMaskEvent(display, ~0, &xevent))
414 matty 9 {
415 astrand 70 if (enable_compose && (XFilterEvent(&xevent, None) == True))
416 astrand 66 {
417     DEBUG_KBD("Filtering event\n");
418     continue;
419     }
420    
421 matty 10 ev_time = time(NULL);
422 matthewc 50 flags = 0;
423 matty 10
424 n-ki 54 switch (xevent.type)
425 matty 9 {
426     case KeyPress:
427 astrand 66 if (IC != NULL)
428     /* Multi_key compatible version */
429     {
430     XmbLookupString(IC,
431     (XKeyPressedEvent *) &
432     xevent, str,
433     sizeof(str), &keysym,
434     &status);
435     if (!
436     ((status == XLookupKeySym)
437     || (status == XLookupBoth)))
438     {
439     error("XmbLookupString failed with status 0x%x\n", status);
440     break;
441     }
442     }
443     else
444     {
445     /* Plain old XLookupString */
446     DEBUG_KBD
447     ("No input context, using XLookupString\n");
448     XLookupString((XKeyEvent *) & xevent,
449     str, sizeof(str),
450     &keysym, NULL);
451     }
452    
453     ksname = get_ksname(keysym);
454     DEBUG_KBD
455     ("\nKeyPress for (keysym 0x%lx, %s)\n",
456     keysym, ksname);
457    
458     if (inhibit_key(keysym))
459     {
460     DEBUG_KBD("Inhibiting key\n");
461 matty 9 break;
462 astrand 66 }
463 matty 9
464 astrand 66 tr = xkeymap_translate_key(keysym,
465     xevent.xkey.
466 astrand 69 keycode,
467     xevent.xkey.state);
468    
469 astrand 66 ensure_remote_modifiers(ev_time, tr);
470    
471     if (tr.scancode == 0)
472 n-ki 52 break;
473    
474 astrand 66 rdp_send_scancode(ev_time, RDP_KEYPRESS,
475     tr.scancode);
476     break;
477     case KeyRelease:
478     XLookupString((XKeyEvent *) & xevent, str,
479     sizeof(str), &keysym, NULL);
480 n-ki 52
481 astrand 66 ksname = get_ksname(keysym);
482     DEBUG_KBD
483     ("\nKeyRelease for (keysym 0x%lx, %s)\n",
484     keysym, ksname);
485 n-ki 52
486 astrand 66 if (inhibit_key(keysym))
487     break;
488 n-ki 52
489 astrand 66 tr = xkeymap_translate_key(keysym,
490     xevent.xkey.
491 astrand 69 keycode,
492     xevent.xkey.state);
493 astrand 66
494     if (tr.scancode == 0)
495     break;
496    
497     rdp_send_scancode(ev_time, RDP_KEYRELEASE,
498     tr.scancode);
499 matty 9 break;
500    
501     case ButtonPress:
502 matthewc 50 flags = MOUSE_FLAG_DOWN;
503     /* fall through */
504 matty 9
505     case ButtonRelease:
506 astrand 64 button = xkeymap_translate_button(xevent.
507     xbutton.
508     button);
509 matty 9 if (button == 0)
510     break;
511    
512 matty 10 rdp_send_input(ev_time, RDP_INPUT_MOUSE,
513 matthewc 50 flags | button,
514 n-ki 54 xevent.xbutton.x,
515     xevent.xbutton.y);
516 matty 10 break;
517    
518     case MotionNotify:
519     rdp_send_input(ev_time, RDP_INPUT_MOUSE,
520 matty 24 MOUSE_FLAG_MOVE,
521 n-ki 54 xevent.xmotion.x,
522     xevent.xmotion.y);
523 matty 28 break;
524    
525 astrand 76 case FocusIn:
526     /* fall through */
527 matty 28 case EnterNotify:
528 astrand 76 if (grab_keyboard)
529     XGrabKeyboard(display, wnd, True,
530 astrand 77 GrabModeAsync,
531     GrabModeAsync,
532 astrand 76 CurrentTime);
533 matty 28 break;
534    
535 astrand 76 case FocusOut:
536     /* reset keys */
537     rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
538     KBD_FLAG_DOWN | KBD_FLAG_UP,
539     SCANCODE_CHAR_LCTRL, 0);
540     rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
541     KBD_FLAG_DOWN | KBD_FLAG_UP,
542     SCANCODE_CHAR_LALT, 0);
543     /* fall through */
544 matty 28 case LeaveNotify:
545 astrand 76 if (grab_keyboard)
546     XUngrabKeyboard(display, CurrentTime);
547 matty 28 break;
548 matty 31
549     case Expose:
550     XCopyArea(display, backstore, wnd, gc,
551 n-ki 54 xevent.xexpose.x, xevent.xexpose.y,
552 astrand 64 xevent.xexpose.width,
553     xevent.xexpose.height,
554 n-ki 54 xevent.xexpose.x, xevent.xexpose.y);
555 matty 31 break;
556 matty 9 }
557     }
558     }
559    
560 matty 25 void
561 matty 33 ui_select(int rdp_socket)
562     {
563 astrand 64 int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;
564 matty 33 fd_set rfds;
565    
566     FD_ZERO(&rfds);
567    
568     while (True)
569     {
570     FD_ZERO(&rfds);
571     FD_SET(rdp_socket, &rfds);
572 matthewc 53 if (display != NULL)
573     {
574     FD_SET(x_socket, &rfds);
575     XFlush(display);
576     }
577 matty 33
578     switch (select(n, &rfds, NULL, NULL, NULL))
579     {
580     case -1:
581     error("select: %s\n", strerror(errno));
582    
583     case 0:
584     continue;
585     }
586    
587     if (FD_ISSET(x_socket, &rfds))
588     xwin_process_events();
589    
590     if (FD_ISSET(rdp_socket, &rfds))
591     return;
592     }
593     }
594    
595     void
596 matty 25 ui_move_pointer(int x, int y)
597 matty 9 {
598 matty 10 XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
599 matty 9 }
600    
601 matty 25 HBITMAP
602 astrand 64 ui_create_bitmap(int width, int height, uint8 * data)
603 matty 6 {
604     XImage *image;
605 matty 9 Pixmap bitmap;
606 matty 28 uint8 *tdata;
607 matty 29
608 matty 33 tdata = (owncolmap ? data : translate_image(width, height, data));
609 matty 28 bitmap = XCreatePixmap(display, wnd, width, height, depth);
610 astrand 77 image = XCreateImage(display, visual, depth, ZPixmap, 0,
611     (char *) tdata, width, height, 8, 0);
612 matty 6
613 matty 28 XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
614 matty 9
615     XFree(image);
616 matty 29 if (!owncolmap)
617 matty 28 xfree(tdata);
618 matty 24 return (HBITMAP) bitmap;
619 matty 6 }
620    
621 matty 25 void
622 astrand 66 ui_paint_bitmap(int x, int y, int cx, int cy, int width, int height,
623     uint8 * data)
624 matty 6 {
625 matty 10 XImage *image;
626 matty 29 uint8 *tdata;
627 matty 10
628 matty 33 tdata = (owncolmap ? data : translate_image(width, height, data));
629 astrand 77 image = XCreateImage(display, visual, depth, ZPixmap, 0,
630     (char *) tdata, width, height, 8, 0);
631 matty 28
632 matty 31 if (ownbackstore)
633     {
634     XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
635     XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
636     }
637     else
638     {
639     XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
640     }
641 matty 29
642 matty 24 XFree(image);
643 matty 29 if (!owncolmap)
644 matty 28 xfree(tdata);
645 matty 6 }
646    
647 matty 25 void
648     ui_destroy_bitmap(HBITMAP bmp)
649 matty 6 {
650 astrand 64 XFreePixmap(display, (Pixmap) bmp);
651 matty 10 }
652    
653 matty 25 HGLYPH
654 astrand 64 ui_create_glyph(int width, int height, uint8 * data)
655 matty 10 {
656 matty 9 XImage *image;
657     Pixmap bitmap;
658     int scanline;
659     GC gc;
660 matty 6
661 matty 9 scanline = (width + 7) / 8;
662 matty 6
663 matty 10 bitmap = XCreatePixmap(display, wnd, width, height, 1);
664     gc = XCreateGC(display, bitmap, 0, NULL);
665 matty 9
666 astrand 77 image = XCreateImage(display, visual, 1, ZPixmap, 0, (char *) data,
667 astrand 73 width, height, 8, scanline);
668 matty 23 image->byte_order = MSBFirst;
669     image->bitmap_bit_order = MSBFirst;
670     XInitImage(image);
671    
672 matty 10 XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
673 matty 29
674 matty 9 XFree(image);
675 matty 10 XFreeGC(display, gc);
676 astrand 64 return (HGLYPH) bitmap;
677 matty 6 }
678 matty 7
679 matty 25 void
680     ui_destroy_glyph(HGLYPH glyph)
681 matty 7 {
682 astrand 64 XFreePixmap(display, (Pixmap) glyph);
683 matty 9 }
684    
685 matty 29 HCURSOR
686 astrand 66 ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
687     uint8 * andmask, uint8 * xormask)
688 matty 9 {
689 matty 29 HGLYPH maskglyph, cursorglyph;
690     XColor bg, fg;
691     Cursor xcursor;
692     uint8 *cursor, *pcursor;
693     uint8 *mask, *pmask;
694     uint8 nextbit;
695     int scanline, offset;
696     int i, j;
697    
698     scanline = (width + 7) / 8;
699     offset = scanline * height;
700    
701     cursor = xmalloc(offset);
702     memset(cursor, 0, offset);
703    
704     mask = xmalloc(offset);
705     memset(mask, 0, offset);
706    
707     /* approximate AND and XOR masks with a monochrome X pointer */
708     for (i = 0; i < height; i++)
709 matty 7 {
710 matty 29 offset -= scanline;
711     pcursor = &cursor[offset];
712     pmask = &mask[offset];
713    
714     for (j = 0; j < scanline; j++)
715 matty 28 {
716 matty 29 for (nextbit = 0x80; nextbit != 0; nextbit >>= 1)
717     {
718     if (xormask[0] || xormask[1] || xormask[2])
719     {
720     *pcursor |= (~(*andmask) & nextbit);
721     *pmask |= nextbit;
722     }
723     else
724     {
725     *pcursor |= ((*andmask) & nextbit);
726     *pmask |= (~(*andmask) & nextbit);
727     }
728    
729     xormask += 3;
730     }
731    
732     andmask++;
733     pcursor++;
734     pmask++;
735 matty 28 }
736 matty 7 }
737 matty 29
738     fg.red = fg.blue = fg.green = 0xffff;
739     bg.red = bg.blue = bg.green = 0x0000;
740     fg.flags = bg.flags = DoRed | DoBlue | DoGreen;
741    
742     cursorglyph = ui_create_glyph(width, height, cursor);
743     maskglyph = ui_create_glyph(width, height, mask);
744    
745 astrand 66 xcursor =
746     XCreatePixmapCursor(display, (Pixmap) cursorglyph,
747     (Pixmap) maskglyph, &fg, &bg, x, y);
748 astrand 64
749 matty 29 ui_destroy_glyph(maskglyph);
750     ui_destroy_glyph(cursorglyph);
751     xfree(mask);
752     xfree(cursor);
753 astrand 64 return (HCURSOR) xcursor;
754 matty 29 }
755    
756     void
757     ui_set_cursor(HCURSOR cursor)
758     {
759 astrand 64 XDefineCursor(display, wnd, (Cursor) cursor);
760 matty 29 }
761    
762     void
763     ui_destroy_cursor(HCURSOR cursor)
764     {
765 astrand 64 XFreeCursor(display, (Cursor) cursor);
766 matty 29 }
767    
768     #define MAKE_XCOLOR(xc,c) \
769     (xc)->red = ((c)->red << 8) | (c)->red; \
770     (xc)->green = ((c)->green << 8) | (c)->green; \
771     (xc)->blue = ((c)->blue << 8) | (c)->blue; \
772     (xc)->flags = DoRed | DoGreen | DoBlue;
773    
774     HCOLOURMAP
775 astrand 64 ui_create_colourmap(COLOURMAP * colours)
776 matty 29 {
777     COLOURENTRY *entry;
778     int i, ncolours = colours->ncolours;
779    
780     if (owncolmap)
781 matty 28 {
782     XColor *xcolours, *xentry;
783     Colormap map;
784 matty 29
785 matty 28 xcolours = xmalloc(sizeof(XColor) * ncolours);
786     for (i = 0; i < ncolours; i++)
787     {
788     entry = &colours->colours[i];
789     xentry = &xcolours[i];
790     xentry->pixel = i;
791 matty 29 MAKE_XCOLOR(xentry, entry);
792 matty 28 }
793 matty 7
794 matty 28 map = XCreateColormap(display, wnd, visual, AllocAll);
795     XStoreColors(display, map, xcolours, ncolours);
796    
797     xfree(xcolours);
798 astrand 64 return (HCOLOURMAP) map;
799 matty 28 }
800 matty 29 else
801     {
802     uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
803     XColor xentry;
804 matty 33 uint32 colour;
805 matty 29
806     for (i = 0; i < ncolours; i++)
807     {
808     entry = &colours->colours[i];
809     MAKE_XCOLOR(&xentry, entry);
810    
811     if (XAllocColor(display, xcolmap, &xentry) != 0)
812 matty 34 colour = xentry.pixel;
813 matty 29 else
814 matty 34 colour = white;
815 matty 33
816     /* byte swap here to make translate_image faster */
817     map[i] = translate_colour(colour);
818 matty 29 }
819    
820     return map;
821     }
822 matty 7 }
823    
824 matty 25 void
825     ui_destroy_colourmap(HCOLOURMAP map)
826 matty 7 {
827 matty 29 if (owncolmap)
828 astrand 64 XFreeColormap(display, (Colormap) map);
829 matty 29 else
830     xfree(map);
831 matty 7 }
832    
833 matty 25 void
834     ui_set_colourmap(HCOLOURMAP map)
835 matty 7 {
836 matty 29 if (owncolmap)
837 astrand 64 XSetWindowColormap(display, wnd, (Colormap) map);
838 matty 29 else
839 matty 28 colmap = map;
840 matty 7 }
841    
842 matty 25 void
843     ui_set_clip(int x, int y, int cx, int cy)
844 matty 7 {
845 matty 9 XRectangle rect;
846 matty 7
847 matty 9 rect.x = x;
848     rect.y = y;
849     rect.width = cx;
850     rect.height = cy;
851 matty 10 XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
852 matty 9 }
853 matty 7
854 matty 25 void
855     ui_reset_clip()
856 matty 9 {
857     XRectangle rect;
858    
859     rect.x = 0;
860     rect.y = 0;
861 matty 10 rect.width = width;
862     rect.height = height;
863     XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
864 matty 7 }
865    
866 matty 25 void
867     ui_bell()
868 matty 10 {
869     XBell(display, 0);
870     }
871    
872 matty 25 void
873     ui_destblt(uint8 opcode,
874     /* dest */ int x, int y, int cx, int cy)
875 matty 9 {
876 matty 29 SET_FUNCTION(opcode);
877 matty 31 FILL_RECTANGLE(x, y, cx, cy);
878 matty 29 RESET_FUNCTION(opcode);
879 matty 9 }
880    
881 matty 25 void
882     ui_patblt(uint8 opcode,
883     /* dest */ int x, int y, int cx, int cy,
884 astrand 64 /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
885 matty 9 {
886     Pixmap fill;
887 jsorg71 59 uint8 i, ipattern[8];
888 matty 9
889 matty 29 SET_FUNCTION(opcode);
890 matty 9
891     switch (brush->style)
892     {
893 matty 24 case 0: /* Solid */
894 matty 29 SET_FOREGROUND(fgcolour);
895 matty 31 FILL_RECTANGLE(x, y, cx, cy);
896 matty 9 break;
897    
898 matty 24 case 3: /* Pattern */
899 jsorg71 59 for (i = 0; i != 8; i++)
900     ipattern[7 - i] = brush->pattern[i];
901     fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
902 matty 9
903 matty 29 SET_FOREGROUND(bgcolour);
904     SET_BACKGROUND(fgcolour);
905     XSetFillStyle(display, gc, FillOpaqueStippled);
906     XSetStipple(display, gc, fill);
907 astrand 64 XSetTSOrigin(display, gc, brush->xorigin,
908     brush->yorigin);
909 matty 9
910 matty 31 FILL_RECTANGLE(x, y, cx, cy);
911 matty 9
912 matty 29 XSetFillStyle(display, gc, FillSolid);
913 jsorg71 80 XSetTSOrigin(display, gc, 0, 0);
914 astrand 64 ui_destroy_glyph((HGLYPH) fill);
915 matty 9 break;
916    
917     default:
918 matty 30 unimpl("brush %d\n", brush->style);
919 matty 9 }
920 matty 29
921     RESET_FUNCTION(opcode);
922 matty 9 }
923    
924 matty 25 void
925     ui_screenblt(uint8 opcode,
926     /* dest */ int x, int y, int cx, int cy,
927     /* src */ int srcx, int srcy)
928 matty 9 {
929 matty 29 SET_FUNCTION(opcode);
930 matty 24 XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
931 matty 31 if (ownbackstore)
932 astrand 66 XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx,
933     cy, x, y);
934 matty 29 RESET_FUNCTION(opcode);
935 matty 9 }
936    
937 matty 25 void
938     ui_memblt(uint8 opcode,
939     /* dest */ int x, int y, int cx, int cy,
940     /* src */ HBITMAP src, int srcx, int srcy)
941 matty 9 {
942 matty 29 SET_FUNCTION(opcode);
943 astrand 64 XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
944 matty 31 if (ownbackstore)
945 astrand 64 XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy,
946 matty 31 cx, cy, x, y);
947 matty 29 RESET_FUNCTION(opcode);
948 matty 9 }
949    
950 matty 25 void
951     ui_triblt(uint8 opcode,
952     /* dest */ int x, int y, int cx, int cy,
953     /* src */ HBITMAP src, int srcx, int srcy,
954 astrand 64 /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
955 matty 9 {
956     /* This is potentially difficult to do in general. Until someone
957 matty 10 comes up with a more efficient way of doing it I am using cases. */
958 matty 9
959     switch (opcode)
960     {
961 matty 24 case 0x69: /* PDSxxn */
962 matty 16 ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
963 astrand 66 ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour,
964     fgcolour);
965 matty 16 break;
966    
967 matty 24 case 0xb8: /* PSDPxax */
968 astrand 66 ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour,
969     fgcolour);
970 matty 16 ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
971 astrand 66 ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour,
972     fgcolour);
973 matty 9 break;
974    
975 matty 29 case 0xc0: /* PSa */
976 matty 28 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
977     ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,
978     fgcolour);
979     break;
980    
981 matty 9 default:
982 matty 30 unimpl("triblt 0x%x\n", opcode);
983 matty 16 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
984 matty 9 }
985     }
986    
987 matty 25 void
988     ui_line(uint8 opcode,
989     /* dest */ int startx, int starty, int endx, int endy,
990 astrand 64 /* pen */ PEN * pen)
991 matty 9 {
992 matty 29 SET_FUNCTION(opcode);
993     SET_FOREGROUND(pen->colour);
994 matty 10 XDrawLine(display, wnd, gc, startx, starty, endx, endy);
995 matty 31 if (ownbackstore)
996     XDrawLine(display, backstore, gc, startx, starty, endx, endy);
997 matty 29 RESET_FUNCTION(opcode);
998 matty 9 }
999    
1000 matty 25 void
1001     ui_rect(
1002     /* dest */ int x, int y, int cx, int cy,
1003     /* brush */ int colour)
1004 matty 9 {
1005 matty 29 SET_FOREGROUND(colour);
1006 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1007 matty 9 }
1008    
1009 matty 25 void
1010     ui_draw_glyph(int mixmode,
1011     /* dest */ int x, int y, int cx, int cy,
1012 astrand 66 /* src */ HGLYPH glyph, int srcx, int srcy,
1013     int bgcolour, int fgcolour)
1014 matty 9 {
1015 matty 29 SET_FOREGROUND(fgcolour);
1016     SET_BACKGROUND(bgcolour);
1017 matty 9
1018 astrand 66 XSetFillStyle(display, gc,
1019     (mixmode ==
1020     MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1021 astrand 64 XSetStipple(display, gc, (Pixmap) glyph);
1022 matty 29 XSetTSOrigin(display, gc, x, y);
1023 matty 9
1024 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1025 matty 9
1026 matty 29 XSetFillStyle(display, gc, FillSolid);
1027 matty 9 }
1028    
1029 mmihalik 49 #define DO_GLYPH(ttext,idx) \
1030     {\
1031     glyph = cache_get_font (font, ttext[idx]);\
1032     if (!(flags & TEXT2_IMPLICIT_X))\
1033     {\
1034     xyoffset = ttext[++idx];\
1035     if ((xyoffset & 0x80))\
1036     {\
1037     if (flags & TEXT2_VERTICAL) \
1038 astrand 72 y += ttext[idx+1] | (ttext[idx+2] << 8);\
1039 mmihalik 49 else\
1040 astrand 72 x += ttext[idx+1] | (ttext[idx+2] << 8);\
1041     idx += 2;\
1042 mmihalik 49 }\
1043     else\
1044     {\
1045     if (flags & TEXT2_VERTICAL) \
1046     y += xyoffset;\
1047     else\
1048     x += xyoffset;\
1049     }\
1050     }\
1051     if (glyph != NULL)\
1052     {\
1053     ui_draw_glyph (mixmode, x + (short) glyph->offset,\
1054     y + (short) glyph->baseline,\
1055     glyph->width, glyph->height,\
1056     glyph->pixmap, 0, 0, bgcolour, fgcolour);\
1057     if (flags & TEXT2_IMPLICIT_X)\
1058     x += glyph->width;\
1059     }\
1060     }
1061    
1062 matty 25 void
1063     ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
1064 astrand 66 int clipx, int clipy, int clipcx, int clipcy,
1065     int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1066 mmihalik 49 int fgcolour, uint8 * text, uint8 length)
1067 matty 9 {
1068 matty 10 FONTGLYPH *glyph;
1069 mmihalik 49 int i, j, xyoffset;
1070     DATABLOB *entry;
1071 matty 9
1072 matty 29 SET_FOREGROUND(bgcolour);
1073 matty 28
1074 matty 9 if (boxcx > 1)
1075 matty 31 {
1076     FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);
1077     }
1078 matty 17 else if (mixmode == MIX_OPAQUE)
1079 matty 31 {
1080     FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);
1081     }
1082 matty 9
1083     /* Paint text, character by character */
1084 astrand 64 for (i = 0; i < length;)
1085     {
1086     switch (text[i])
1087     {
1088     case 0xff:
1089     if (i + 2 < length)
1090     cache_put_text(text[i + 1], text,
1091     text[i + 2]);
1092     else
1093     {
1094     error("this shouldn't be happening\n");
1095     break;
1096     }
1097     /* this will move pointer from start to first character after FF command */
1098     length -= i + 3;
1099     text = &(text[i + 3]);
1100     i = 0;
1101 mmihalik 49 break;
1102 matty 9
1103 astrand 64 case 0xfe:
1104     entry = cache_get_text(text[i + 1]);
1105     if (entry != NULL)
1106     {
1107     if ((((uint8 *) (entry->data))[1] ==
1108     0)
1109     && (!(flags & TEXT2_IMPLICIT_X)))
1110     {
1111     if (flags & TEXT2_VERTICAL)
1112     y += text[i + 2];
1113     else
1114     x += text[i + 2];
1115     }
1116     if (i + 2 < length)
1117     i += 3;
1118 mmihalik 49 else
1119 astrand 64 i += 2;
1120     length -= i;
1121     /* this will move pointer from start to first character after FE command */
1122     text = &(text[i]);
1123     i = 0;
1124     for (j = 0; j < entry->size; j++)
1125     DO_GLYPH(((uint8 *) (entry->
1126     data)),
1127     j);
1128 matthewc 44 }
1129 astrand 64 break;
1130 matty 17
1131 astrand 64 default:
1132     DO_GLYPH(text, i);
1133     i++;
1134     break;
1135 matty 29 }
1136 mmihalik 49 }
1137 matty 28
1138 matty 9
1139     }
1140    
1141 matty 25 void
1142     ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
1143 matty 9 {
1144 matty 28 Pixmap pix;
1145 matty 9 XImage *image;
1146    
1147 matty 31 if (ownbackstore)
1148     {
1149     image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,
1150     ZPixmap);
1151     }
1152     else
1153     {
1154     pix = XCreatePixmap(display, wnd, cx, cy, depth);
1155     XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
1156     image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,
1157     ZPixmap);
1158     XFreePixmap(display, pix);
1159     }
1160 matty 28
1161 astrand 64 offset *= bpp / 8;
1162 astrand 66 cache_put_desktop(offset, cx, cy, image->bytes_per_line, bpp / 8,
1163     (uint8 *) image->data);
1164 matty 28
1165     XDestroyImage(image);
1166 matty 9 }
1167    
1168 matty 25 void
1169     ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
1170 matty 9 {
1171     XImage *image;
1172 matty 10 uint8 *data;
1173 matty 9
1174 astrand 64 offset *= bpp / 8;
1175     data = cache_get_desktop(offset, cx, cy, bpp / 8);
1176 matty 10 if (data == NULL)
1177     return;
1178 matty 29
1179 astrand 77 image = XCreateImage(display, visual, depth, ZPixmap, 0,
1180     (char *) data, cx, cy, BitmapPad(display),
1181     cx * bpp / 8);
1182 matty 29
1183 matty 31 if (ownbackstore)
1184     {
1185     XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
1186     XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
1187     }
1188     else
1189     {
1190     XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
1191     }
1192    
1193 matty 9 XFree(image);
1194     }

  ViewVC Help
Powered by ViewVC 1.1.26