/[rdesktop]/sourceforge.net/branches/seamlessrdp-branch/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/branches/seamlessrdp-branch/rdesktop/xwin.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 309 - (hide annotations)
Tue Feb 4 05:32:13 2003 UTC (21 years, 3 months ago) by jsorg71
Original Path: sourceforge.net/trunk/rdesktop/xwin.c
File MIME type: text/plain
File size: 31034 byte(s)
16bit

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

  ViewVC Help
Powered by ViewVC 1.1.26