/[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 281 - (hide annotations)
Mon Dec 2 22:57:47 2002 UTC (21 years, 5 months ago) by jsorg71
File MIME type: text/plain
File size: 30499 byte(s)
minor draw_text optimize

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

  ViewVC Help
Powered by ViewVC 1.1.26