/[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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 52 by n-ki, Fri Apr 26 08:22:39 2002 UTC revision 331 by astrand, Tue Feb 18 13:44:27 2003 UTC
# Line 1  Line 1 
1  /*  /*
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     User interface services - X Window System     User interface services - X Window System
4     Copyright (C) Matthew Chapman 1999-2001     Copyright (C) Matthew Chapman 1999-2002
5    
6     This program is free software; you can redistribute it and/or modify     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     it under the terms of the GNU General Public License as published by
# Line 20  Line 20 
20    
21  #include <X11/Xlib.h>  #include <X11/Xlib.h>
22  #include <X11/Xutil.h>  #include <X11/Xutil.h>
 #include <X11/XKBlib.h>  
23  #include <time.h>  #include <time.h>
24  #include <errno.h>  #include <errno.h>
25  #include "rdesktop.h"  #include "rdesktop.h"
26    
 extern char keymapname[16];  
 extern int keylayout;  
27  extern int width;  extern int width;
28  extern int height;  extern int height;
29  extern BOOL sendmotion;  extern BOOL sendmotion;
30  extern BOOL fullscreen;  extern BOOL fullscreen;
31    extern BOOL grab_keyboard;
32    extern BOOL hide_decorations;
33    extern char title[];
34    extern int server_bpp;
35    extern int win_button_size;
36    BOOL enable_compose = False;
37    BOOL focused;
38    BOOL mouse_in_wnd;
39    
40  Display *display;  Display *display;
 XkbDescPtr xkb;  
41  static int x_socket;  static int x_socket;
42    static Screen *screen;
43  static Window wnd;  static Window wnd;
44  static GC gc;  static GC gc;
45  static Visual *visual;  static Visual *visual;
46  static int depth;  static int depth;
47  static int bpp;  static int bpp;
48    static XIM IM;
49    static XIC IC;
50    static XModifierKeymap *mod_map;
51    static Cursor current_cursor;
52    static Atom protocol_atom, kill_atom;
53    
54  /* endianness */  /* endianness */
55  static BOOL host_be;  static BOOL host_be;
# Line 49  static BOOL xserver_be; Line 59  static BOOL xserver_be;
59  static BOOL ownbackstore;  static BOOL ownbackstore;
60  static Pixmap backstore;  static Pixmap backstore;
61    
62  /* needed to keep track of the modifiers */  /* MWM decorations */
63  static unsigned int key_modifier_state = 0;  #define MWM_HINTS_DECORATIONS   (1L << 1)
64  static unsigned int key_down_state = 0;  #define PROP_MOTIF_WM_HINTS_ELEMENTS    5
65    typedef struct
66  #define DShift1Mask   (1<<0)  {
67  #define DShift2Mask   (1<<1)          uint32 flags;
68  #define DControl1Mask (1<<2)          uint32 functions;
69  #define DControl2Mask (1<<3)          uint32 decorations;
70  #define DMod1Mask     (1<<4)          sint32 inputMode;
71  #define DMod2Mask     (1<<5)          uint32 status;
72    }
73    PropMotifWmHints;
74    
75    typedef struct
76    {
77            uint32 red;
78            uint32 green;
79            uint32 blue;
80    }
81    PixelColour;
82    
83  #define FILL_RECTANGLE(x,y,cx,cy)\  #define FILL_RECTANGLE(x,y,cx,cy)\
84  { \  { \
# Line 67  static unsigned int key_down_state = 0; Line 87  static unsigned int key_down_state = 0;
87                  XFillRectangle(display, backstore, gc, x, y, cx, cy); \                  XFillRectangle(display, backstore, gc, x, y, cx, cy); \
88  }  }
89    
90    #define FILL_RECTANGLE_BACKSTORE(x,y,cx,cy)\
91    { \
92            XFillRectangle(display, ownbackstore ? backstore : wnd, gc, x, y, cx, cy); \
93    }
94    
95  /* colour maps */  /* colour maps */
96  static BOOL owncolmap;  BOOL owncolmap = False;
97  static Colormap xcolmap;  static Colormap xcolmap;
 static uint32 white;  
98  static uint32 *colmap;  static uint32 *colmap;
99    
100  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )  #define TRANSLATE(col)          ( server_bpp != 8 ? translate_colour(col) : owncolmap ? col : translate_colour(colmap[col]) )
101  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));
102  #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));  #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));
103    
# Line 99  static int rop2_map[] = { Line 123  static int rop2_map[] = {
123  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }
124  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
125    
126  void xwin_release_modifiers(XKeyEvent* ev, uint32 ev_time, uint32 scancode);  static void
127  void xwin_press_modifiers(XKeyEvent* ev, uint32 ev_time, uint32 scancode);  mwm_hide_decorations(void)
128    {
129            PropMotifWmHints motif_hints;
130            Atom hintsatom;
131    
132            /* setup the property */
133            motif_hints.flags = MWM_HINTS_DECORATIONS;
134            motif_hints.decorations = 0;
135    
136            /* get the atom for the property */
137            hintsatom = XInternAtom(display, "_MOTIF_WM_HINTS", False);
138            if (!hintsatom)
139            {
140                    warning("Failed to get atom _MOTIF_WM_HINTS: probably your window manager does not support MWM hints\n");
141                    return;
142            }
143    
144            XChangeProperty(display, wnd, hintsatom, hintsatom, 32, PropModeReplace,
145                            (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
146    }
147    
148    static PixelColour
149    split_colour15(uint32 colour)
150    {
151            PixelColour rv;
152            rv.red = (colour & 0x7c00) >> 10;
153            rv.red = (rv.red * 0xff) / 0x1f;
154            rv.green = (colour & 0x03e0) >> 5;
155            rv.green = (rv.green * 0xff) / 0x1f;
156            rv.blue = (colour & 0x1f);
157            rv.blue = (rv.blue * 0xff) / 0x1f;
158            return rv;
159    }
160    
161    static PixelColour
162    split_colour16(uint32 colour)
163    {
164            PixelColour rv;
165            rv.red = (colour & 0xf800) >> 11;
166            rv.red = (rv.red * 0xff) / 0x1f;
167            rv.green = (colour & 0x07e0) >> 5;
168            rv.green = (rv.green * 0xff) / 0x3f;
169            rv.blue = (colour & 0x001f);
170            rv.blue = (rv.blue * 0xff) / 0x1f;
171            return rv;
172    }
173    
174    static PixelColour
175    split_colour24(uint32 colour)
176    {
177            PixelColour rv;
178            rv.blue = (colour & 0xff0000) >> 16;
179            rv.green = (colour & 0xff00) >> 8;
180            rv.red = (colour & 0xff);
181            return rv;
182    }
183    
184    static uint32
185    make_colour16(PixelColour pc)
186    {
187            pc.red = (pc.red * 0x1f) / 0xff;
188            pc.green = (pc.green * 0x3f) / 0xff;
189            pc.blue = (pc.blue * 0x1f) / 0xff;
190            return (pc.red << 11) | (pc.green << 5) | pc.blue;
191    }
192    
193    static uint32
194    make_colour24(PixelColour pc)
195    {
196            return (pc.red << 16) | (pc.green << 8) | pc.blue;
197    }
198    
199    static uint32
200    make_colour32(PixelColour pc)
201    {
202            return (pc.red << 16) | (pc.green << 8) | pc.blue;
203    }
204    
205    #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    
210    static uint32
211    translate_colour(uint32 colour)
212    {
213            switch (server_bpp)
214            {
215                    case 15:
216                            switch (bpp)
217                            {
218                                    case 16:
219                                            colour = make_colour16(split_colour15(colour));
220                                            break;
221                                    case 24:
222                                            colour = make_colour24(split_colour15(colour));
223                                            break;
224                                    case 32:
225                                            colour = make_colour32(split_colour15(colour));
226                                            break;
227                            }
228                            break;
229                    case 16:
230                            switch (bpp)
231                            {
232                                    case 16:
233                                            break;
234                                    case 24:
235                                            colour = make_colour24(split_colour16(colour));
236                                            break;
237                                    case 32:
238                                            colour = make_colour32(split_colour16(colour));
239                                            break;
240                            }
241                            break;
242                    case 24:
243                            switch (bpp)
244                            {
245                                    case 16:
246                                            colour = make_colour16(split_colour24(colour));
247                                            break;
248                                    case 24:
249                                            break;
250                                    case 32:
251                                            colour = make_colour32(split_colour24(colour));
252                                            break;
253                            }
254                            break;
255            }
256            switch (bpp)
257            {
258                    case 16:
259                            if (host_be != xserver_be)
260                                    BSWAP16(colour);
261                            break;
262    
263                    case 24:
264                            if (xserver_be)
265                                    BSWAP24(colour);
266                            break;
267    
268                    case 32:
269                            if (host_be != xserver_be)
270                                    BSWAP32(colour);
271                            break;
272            }
273    
274            return colour;
275    }
276    
277  static void  static void
278  translate8(uint8 *data, uint8 *out, uint8 *end)  translate8to8(uint8 * data, uint8 * out, uint8 * end)
279  {  {
280          while (out < end)          while (out < end)
281                  *(out++) = (uint8)colmap[*(data++)];                  *(out++) = (uint8) colmap[*(data++)];
282  }  }
283    
284  static void  static void
285  translate16(uint8 *data, uint16 *out, uint16 *end)  translate8to16(uint8 * data, uint16 * out, uint16 * end)
286  {  {
287          while (out < end)          while (out < end)
288                  *(out++) = (uint16)colmap[*(data++)];                  *(out++) = (uint16) colmap[*(data++)];
289  }  }
290    
291  /* little endian - conversion happens when colourmap is built */  /* little endian - conversion happens when colourmap is built */
292  static void  static void
293  translate24(uint8 *data, uint8 *out, uint8 *end)  translate8to24(uint8 * data, uint8 * out, uint8 * end)
294  {  {
295          uint32 value;          uint32 value;
296    
# Line 132  translate24(uint8 *data, uint8 *out, uin Line 304  translate24(uint8 *data, uint8 *out, uin
304  }  }
305    
306  static void  static void
307  translate32(uint8 *data, uint32 *out, uint32 *end)  translate8to32(uint8 * data, uint32 * out, uint32 * end)
308  {  {
309          while (out < end)          while (out < end)
310                  *(out++) = colmap[*(data++)];                  *(out++) = colmap[*(data++)];
311  }  }
312    
313  static uint8 *  /* todo the remaining translate function might need some big endian check ?? */
 translate_image(int width, int height, uint8 *data)  
 {  
         int size = width * height * bpp/8;  
         uint8 *out = xmalloc(size);  
         uint8 *end = out + size;  
   
         switch (bpp)  
         {  
                 case 8:  
                         translate8(data, out, end);  
                         break;  
314    
315                  case 16:  static void
316                          translate16(data, (uint16 *)out, (uint16 *)end);  translate15to16(uint16 * data, uint16 * out, uint16 * end)
317                          break;  {
318            while (out < end)
319                    *(out++) = (uint16) make_colour16(split_colour15(*(data++)));
320    }
321    
322                  case 24:  static void
323                          translate24(data, out, end);  translate15to24(uint16 * data, uint8 * out, uint8 * end)
324                          break;  {
325            uint32 value;
326    
327                  case 32:          while (out < end)
328                          translate32(data, (uint32 *)out, (uint32 *)end);          {
329                          break;                  value = make_colour24(split_colour15(*(data++)));
330                    *(out++) = value;
331                    *(out++) = value >> 8;
332                    *(out++) = value >> 16;
333          }          }
334    }
335    
336          return out;  static void
337    translate15to32(uint16 * data, uint32 * out, uint32 * end)
338    {
339            while (out < end)
340                    *(out++) = make_colour32(split_colour15(*(data++)));
341  }  }
342    
343  #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }  static void
344  #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }  translate16to16(uint16 * data, uint16 * out, uint16 * end)
345  #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \  {
346                          x = (x << 16) | (x >> 16); }          while (out < end)
347                    *(out++) = (uint16) (*(data++));
348    }
349    
350  static uint32  
351  translate_colour(uint32 colour)  static void
352    translate16to24(uint16 * data, uint8 * out, uint8 * end)
353  {  {
354          switch (bpp)          uint32 value;
355    
356            while (out < end)
357          {          {
358                  case 16:                  value = make_colour24(split_colour16(*(data++)));
359                          if (host_be != xserver_be)                  *(out++) = value;
360                                  BSWAP16(colour);                  *(out++) = value >> 8;
361                          break;                  *(out++) = value >> 16;
362            }
363    }
364    
365                  case 24:  static void
366                          if (xserver_be)  translate16to32(uint16 * data, uint32 * out, uint32 * end)
367                                  BSWAP24(colour);  {
368                          break;          while (out < end)
369                    *(out++) = make_colour32(split_colour16(*(data++)));
370    }
371    
372                  case 32:  static void
373                          if (host_be != xserver_be)  translate24to16(uint8 * data, uint16 * out, uint16 * end)
374                                  BSWAP32(colour);  {
375                          break;          uint32 pixel = 0;
376            while (out < end)
377            {
378                    pixel = *(data++) << 16;
379                    pixel |= *(data++) << 8;
380                    pixel |= *(data++);
381                    *(out++) = (uint16) make_colour16(split_colour24(pixel));
382          }          }
383    }
384    
385          return colour;  static void
386    translate24to24(uint8 * data, uint8 * out, uint8 * end)
387    {
388            while (out < end)
389            {
390                    *(out++) = (*(data++));
391            }
392  }  }
393    
394  BOOL  static void
395  ui_create_window(char *title)  translate24to32(uint8 * data, uint32 * out, uint32 * end)
396  {  {
397          XSetWindowAttributes attribs;          uint32 pixel = 0;
398          XClassHint *classhints;          while (out < end)
         XSizeHints *sizehints;  
         unsigned long input_mask;  
         XPixmapFormatValues *pfm;  
         Screen *screen;  
         uint16 test;  
         int i;  
           
         int xkb_minor, xkb_major;  
         int xkb_event, xkb_error, xkb_reason;  
   
         /* compare compiletime libs with runtime libs. */  
         xkb_major = XkbMajorVersion;  
         xkb_minor = XkbMinorVersion;  
         if( XkbLibraryVersion( &xkb_major, &xkb_minor ) == False )  
399          {          {
400                  error("please re-compile rdesktop\ncompile time version of xkb is not compatible with\nyour runtime version of the library\n");                  memcpy(&pixel, data, 3);
401                  return False;                  data += 3;
402                    *(out++) = pixel;
403          }          }
404    }
405    
406    static uint8 *
407    translate_image(int width, int height, uint8 * data)
408    {
409            int size = width * height * bpp / 8;
410            uint8 *out = xmalloc(size);
411            uint8 *end = out + size;
412    
413          /* XKB is the 'new' keyboard handler in x.. ( the xkb code in Xfree86 originates from SGI, years 1993 and 1995 from what I could tell. )          switch (server_bpp)
          * it makes it possible for people with disabilities to use rdesktop, stickykeys, bouncekeys etc. VERY MUCH useful.  
          * XFree86 has had support for it since it's earliest incarnation. I believe it is a reasonable dependency.  
          */  
         display = XkbOpenDisplay( NULL, &xkb_event, &xkb_error, &xkb_major, &xkb_minor, &xkb_reason );  
         switch(xkb_reason)  
414          {          {
415                  case XkbOD_BadLibraryVersion:                  case 24:
416                          error("XkbOD_BadLibraryVersion: XKB extensions in server and the library rdesktop is linked against aren't compatible with each other.\n");                          switch (bpp)
417                          break;                          {
418                  case XkbOD_ConnectionRefused:                                  case 32:
419                          error("XkbOD_ConnectionRefused\n");                                          translate24to32(data, (uint32 *) out, (uint32 *) end);
420                                            break;
421                                    case 24:
422                                            translate24to24(data, out, end);
423                                            break;
424                                    case 16:
425                                            translate24to16(data, (uint16 *) out, (uint16 *) end);
426                                            break;
427                            }
428                          break;                          break;
429                  case XkbOD_BadServerVersion:                  case 16:
430                          error("XkbOD_BadServerVersion\n");                          switch (bpp)
431                            {
432                                    case 32:
433                                            translate16to32((uint16 *) data, (uint32 *) out,
434                                                            (uint32 *) end);
435                                            break;
436                                    case 24:
437                                            translate16to24((uint16 *) data, out, end);
438                                            break;
439                                    case 16:
440                                            translate16to16((uint16 *) data, (uint16 *) out,
441                                                            (uint16 *) end);
442                                            break;
443                            }
444                          break;                          break;
445                  case XkbOD_NonXkbServer:                  case 15:
446                          error("XkbOD_NonXkbServer: XKB extension not present in server\nupdate your X server.\n");                          switch (bpp)
447                            {
448                                    case 32:
449                                            translate15to32((uint16 *) data, (uint32 *) out,
450                                                            (uint32 *) end);
451                                            break;
452                                    case 24:
453                                            translate15to24((uint16 *) data, out, end);
454                                            break;
455                                    case 16:
456                                            translate15to16((uint16 *) data, (uint16 *) out,
457                                                            (uint16 *) end);
458                                            break;
459                            }
460                          break;                          break;
461                  case XkbOD_Success:                  case 8:
462                          DEBUG("XkbOD_Success: Connection established with display\n");                          switch (bpp)
463                            {
464                                    case 8:
465                                            translate8to8(data, out, end);
466                                            break;
467                                    case 16:
468                                            translate8to16(data, (uint16 *) out, (uint16 *) end);
469                                            break;
470                                    case 24:
471                                            translate8to24(data, out, end);
472                                            break;
473                                    case 32:
474                                            translate8to32(data, (uint32 *) out, (uint32 *) end);
475                                            break;
476                            }
477                          break;                          break;
478          }          }
479            return out;
480    }
481    
482    BOOL
483    get_key_state(unsigned int state, uint32 keysym)
484    {
485            int modifierpos, key, keysymMask = 0;
486            int offset;
487    
488            KeyCode keycode = XKeysymToKeycode(display, keysym);
489    
490            if (keycode == NoSymbol)
491                    return False;
492    
493            for (modifierpos = 0; modifierpos < 8; modifierpos++)
494            {
495                    offset = mod_map->max_keypermod * modifierpos;
496    
497                    for (key = 0; key < mod_map->max_keypermod; key++)
498                    {
499                            if (mod_map->modifiermap[offset + key] == keycode)
500                                    keysymMask |= 1 << modifierpos;
501                    }
502            }
503    
504            return (state & keysymMask) ? True : False;
505    }
506    
507    BOOL
508    ui_init(void)
509    {
510            XPixmapFormatValues *pfm;
511            uint16 test;
512            int i;
513    
514            display = XOpenDisplay(NULL);
515          if (display == NULL)          if (display == NULL)
516          {          {
517                  error("Failed to open display\n");                  error("Failed to open display: %s\n", XDisplayName(NULL));
518                  return False;                  return False;
519          }          }
520    
# Line 255  ui_create_window(char *title) Line 522  ui_create_window(char *title)
522          screen = DefaultScreenOfDisplay(display);          screen = DefaultScreenOfDisplay(display);
523          visual = DefaultVisualOfScreen(screen);          visual = DefaultVisualOfScreen(screen);
524          depth = DefaultDepthOfScreen(screen);          depth = DefaultDepthOfScreen(screen);
525            
526          pfm = XListPixmapFormats(display, &i);          pfm = XListPixmapFormats(display, &i);
527          if (pfm != NULL)          if (pfm != NULL)
528          {          {
# Line 263  ui_create_window(char *title) Line 530  ui_create_window(char *title)
530                     desirable, e.g. 24 bits->32 bits. */                     desirable, e.g. 24 bits->32 bits. */
531                  while (i--)                  while (i--)
532                  {                  {
533                          if ((pfm[i].depth == depth)                          if ((pfm[i].depth == depth) && (pfm[i].bits_per_pixel > bpp))
                             && (pfm[i].bits_per_pixel > bpp))  
534                          {                          {
535                                  bpp = pfm[i].bits_per_pixel;                                  bpp = pfm[i].bits_per_pixel;
536                          }                          }
# Line 279  ui_create_window(char *title) Line 545  ui_create_window(char *title)
545                  return False;                  return False;
546          }          }
547    
548          if (depth <= 8)          if (owncolmap != True)
549                  owncolmap = True;          {
         else  
550                  xcolmap = DefaultColormapOfScreen(screen);                  xcolmap = DefaultColormapOfScreen(screen);
551                    if (depth <= 8)
552                            warning("Screen depth is 8 bits or lower: you may want to use -C for a private colourmap\n");
553            }
554    
555            gc = XCreateGC(display, RootWindowOfScreen(screen), 0, NULL);
556    
557            if (DoesBackingStore(screen) != Always)
558                    ownbackstore = True;
559    
560          test = 1;          test = 1;
561          host_be = !(BOOL)(*(uint8 *)(&test));          host_be = !(BOOL) (*(uint8 *) (&test));
562          xserver_be = (ImageByteOrder(display) == MSBFirst);          xserver_be = (ImageByteOrder(display) == MSBFirst);
563    
564          white = WhitePixelOfScreen(screen);          if ((width == 0) || (height == 0))
565          attribs.background_pixel = BlackPixelOfScreen(screen);          {
566          attribs.backing_store = DoesBackingStore(screen);                  /* Fetch geometry from _NET_WORKAREA */
567                    uint32 x, y, cx, cy;
568    
569          if (attribs.backing_store == NotUseful)                  if (get_current_workarea(&x, &y, &cx, &cy) == 0)
570                  ownbackstore = True;                  {
571                            width = cx;
572                            height = cy;
573                    }
574                    else
575                    {
576                            warning("Failed to get workarea: probably your window manager does not support extended hints\n");
577                            width = 800;
578                            height = 600;
579                    }
580            }
581    
582          if (fullscreen)          if (fullscreen)
583          {          {
                 attribs.override_redirect = True;  
584                  width = WidthOfScreen(screen);                  width = WidthOfScreen(screen);
585                  height = HeightOfScreen(screen);                  height = HeightOfScreen(screen);
586          }          }
587          else  
588            /* make sure width is a multiple of 4 */
589            width = (width + 3) & ~3;
590    
591            if (ownbackstore)
592          {          {
593                  attribs.override_redirect = False;                  backstore =
594                            XCreatePixmap(display, RootWindowOfScreen(screen), width, height, depth);
595    
596                    /* clear to prevent rubbish being exposed at startup */
597                    XSetForeground(display, gc, BlackPixelOfScreen(screen));
598                    XFillRectangle(display, backstore, gc, 0, 0, width, height);
599          }          }
600    
601          width = (width + 3) & ~3; /* make width a multiple of 32 bits */          mod_map = XGetModifierMapping(display);
602    
603            if (enable_compose)
604                    IM = XOpenIM(display, NULL, NULL, NULL);
605    
606            xkeymap_init();
607    
608            /* todo take this out when high colour is done */
609            printf("server bpp %d client bpp %d depth %d\n", server_bpp, bpp, depth);
610    
611            return True;
612    }
613    
614    void
615    ui_deinit(void)
616    {
617            if (IM != NULL)
618                    XCloseIM(IM);
619    
620            XFreeModifiermap(mod_map);
621    
622            if (ownbackstore)
623                    XFreePixmap(display, backstore);
624    
625            XFreeGC(display, gc);
626            XCloseDisplay(display);
627            display = NULL;
628    }
629    
630    BOOL
631    ui_create_window(void)
632    {
633            XSetWindowAttributes attribs;
634            XClassHint *classhints;
635            XSizeHints *sizehints;
636            int wndwidth, wndheight;
637            long input_mask, ic_input_mask;
638            XEvent xevent;
639    
640            wndwidth = fullscreen ? WidthOfScreen(screen) : width;
641            wndheight = fullscreen ? HeightOfScreen(screen) : height;
642    
643          wnd = XCreateWindow(display, RootWindowOfScreen(screen),          attribs.background_pixel = BlackPixelOfScreen(screen);
644                              0, 0, width, height, 0, CopyFromParent,          attribs.backing_store = ownbackstore ? NotUseful : Always;
645                              InputOutput, CopyFromParent,          attribs.override_redirect = fullscreen;
646                              CWBackingStore | CWBackPixel | CWOverrideRedirect,  
647                              &attribs);          wnd = XCreateWindow(display, RootWindowOfScreen(screen), 0, 0, wndwidth, wndheight,
648                                0, CopyFromParent, InputOutput, CopyFromParent,
649                                CWBackPixel | CWBackingStore | CWOverrideRedirect, &attribs);
650    
651          XStoreName(display, wnd, title);          XStoreName(display, wnd, title);
652    
653            if (hide_decorations)
654                    mwm_hide_decorations();
655    
656          classhints = XAllocClassHint();          classhints = XAllocClassHint();
657          if (classhints != NULL)          if (classhints != NULL)
658          {          {
# Line 334  ui_create_window(char *title) Line 671  ui_create_window(char *title)
671                  XFree(sizehints);                  XFree(sizehints);
672          }          }
673    
674          xkeymap_init();          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
675                    VisibilityChangeMask | FocusChangeMask;
676    
         input_mask = KeyPressMask | KeyReleaseMask |  
                          ButtonPressMask | ButtonReleaseMask |  
                          EnterWindowMask | LeaveWindowMask | KeymapStateMask;  
677          if (sendmotion)          if (sendmotion)
678                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
   
679          if (ownbackstore)          if (ownbackstore)
680                  input_mask |= ExposureMask;                  input_mask |= ExposureMask;
681            if (fullscreen || grab_keyboard)
682                    input_mask |= EnterWindowMask;
683            if (grab_keyboard)
684                    input_mask |= LeaveWindowMask;
685    
686            if (IM != NULL)
687            {
688                    IC = XCreateIC(IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
689                                   XNClientWindow, wnd, XNFocusWindow, wnd, NULL);
690    
691                    if ((IC != NULL)
692                        && (XGetICValues(IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))
693                            input_mask |= ic_input_mask;
694            }
695    
696          XSelectInput(display, wnd, input_mask);          XSelectInput(display, wnd, input_mask);
         gc = XCreateGC(display, wnd, 0, NULL);  
   
         if (ownbackstore)  
                 backstore = XCreatePixmap(display, wnd, width, height, depth);  
   
697          XMapWindow(display, wnd);          XMapWindow(display, wnd);
698    
699          /* TODO: error texts... make them friendly. */          /* wait for VisibilityNotify */
700          xkb = XkbGetKeyboard(display, XkbAllComponentsMask, XkbUseCoreKbd);          do
         if ((int)xkb == BadAlloc || xkb == NULL)  
         {  
                         error( "XkbGetKeyboard failed.\n");  
                         exit(0);  
         }  
   
         /* TODO: error texts... make them friendly. */  
         if( XkbSelectEvents(display, xkb->device_spec, XkbAllEventsMask, XkbAllEventsMask) == False )  
701          {          {
702                          error( "XkbSelectEvents failed.\n");                  XMaskEvent(display, VisibilityChangeMask, &xevent);
                         exit(0);  
703          }          }
704            while (xevent.type != VisibilityNotify);
705    
706            focused = False;
707            mouse_in_wnd = False;
708    
709            /* handle the WM_DELETE_WINDOW protocol */
710            protocol_atom = XInternAtom(display, "WM_PROTOCOLS", True);
711            kill_atom = XInternAtom(display, "WM_DELETE_WINDOW", True);
712            XSetWMProtocols(display, wnd, &kill_atom, 1);
713    
714          return True;          return True;
715  }  }
716    
717  void  void
718  ui_destroy_window()  ui_destroy_window(void)
719  {  {
720          if( xkb != NULL )          if (IC != NULL)
721                  XkbFreeKeyboard(xkb, XkbAllControlsMask, True);                  XDestroyIC(IC);
   
         if (ownbackstore)  
                 XFreePixmap(display, backstore);  
722    
         XFreeGC(display, gc);  
723          XDestroyWindow(display, wnd);          XDestroyWindow(display, wnd);
         XCloseDisplay(display);  
         display = NULL;  
724  }  }
725    
726  static void  void
727  xwin_process_events()  xwin_toggle_fullscreen(void)
728  {  {
729          XkbEvent xkbevent;          Pixmap contents = 0;
730            
731            if (!ownbackstore)
732            {
733                    /* need to save contents of window */
734                    contents = XCreatePixmap(display, wnd, width, height, depth);
735                    XCopyArea(display, wnd, contents, gc, 0, 0, width, height, 0, 0);
736            }
737    
738            ui_destroy_window();
739            fullscreen = !fullscreen;
740            ui_create_window();
741    
742            XDefineCursor(display, wnd, current_cursor);
743    
744            if (!ownbackstore)
745            {
746                    XCopyArea(display, contents, wnd, gc, 0, 0, width, height, 0, 0);
747                    XFreePixmap(display, contents);
748            }
749    }
750    
751    /* Process all events in Xlib queue
752       Returns 0 after user quit, 1 otherwise */
753    static int
754    xwin_process_events(void)
755    {
756            XEvent xevent;
757          KeySym keysym;          KeySym keysym;
         uint8 scancode;  
758          uint16 button, flags;          uint16 button, flags;
759          uint32 ev_time;          uint32 ev_time;
760          uint32 tmpmods;          key_translation tr;
761            char str[256];
762          if (display == NULL)          Status status;
763                  return;          unsigned int state;
764            Window wdummy;
765            int dummy;
766    
767          while (XCheckMaskEvent(display, ~0, &xkbevent.core))          while (XPending(display) > 0)
768          {          {
769                  ev_time = time(NULL);                  XNextEvent(display, &xevent);
770    
771                    if ((IC != NULL) && (XFilterEvent(&xevent, None) == True))
772                    {
773                            DEBUG_KBD(("Filtering event\n"));
774                            continue;
775                    }
776    
777                  flags = 0;                  flags = 0;
778    
779                  switch (xkbevent.type)                  switch (xevent.type)
780                  {                  {
781                          case KeymapNotify:                          case ClientMessage:
782                                  /* TODO:                                  /* the window manager told us to quit */
783                                   * read modifier status at focus in, and update the local masks, and the other end as well..                                  if ((xevent.xclient.message_type == protocol_atom)
784                                   * if not, we may get out of sync.                                      && (xevent.xclient.data.l[0] == kill_atom))
785                                   * xkbevent.core.xkeymap.key_vector                                          /* Quit */
786                                   * char key_vector[32];                                          return 0;
                                  */  
787                                  break;                                  break;
788    
                         case KeyRelease:  
                                 flags = KBD_FLAG_DOWN | KBD_FLAG_UP;  
                                 /* fall through */  
   
789                          case KeyPress:                          case KeyPress:
790                                  if( XkbTranslateKeyCode(xkb, xkbevent.core.xkey.keycode, xkbevent.core.xkey.state, &tmpmods, &keysym) == False )                                  if (IC != NULL)
791                                            /* Multi_key compatible version */
792                                    {
793                                            XmbLookupString(IC,
794                                                            (XKeyPressedEvent *) &
795                                                            xevent, str, sizeof(str), &keysym, &status);
796                                            if (!((status == XLookupKeySym) || (status == XLookupBoth)))
797                                            {
798                                                    error("XmbLookupString failed with status 0x%x\n",
799                                                          status);
800                                                    break;
801                                            }
802                                    }
803                                    else
804                                    {
805                                            /* Plain old XLookupString */
806                                            DEBUG_KBD(("\nNo input context, using XLookupString\n"));
807                                            XLookupString((XKeyEvent *) & xevent,
808                                                          str, sizeof(str), &keysym, NULL);
809                                    }
810    
811                                    DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,
812                                               get_ksname(keysym)));
813    
814                                    ev_time = time(NULL);
815                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
816                                          break;                                          break;
                                 scancode = xkeymap_translate_key(keysym, xkbevent.core.xkey.keycode, &flags);  
817    
818                                  if (scancode == 0 )                                  tr = xkeymap_translate_key(keysym,
819                                                               xevent.xkey.keycode, xevent.xkey.state);
820    
821                                    if (tr.scancode == 0)
822                                          break;                                          break;
823    
824                                  /* keep track of the modifiers -- needed for stickykeys... */                                  ensure_remote_modifiers(ev_time, tr);
                                 if( xkbevent.type == KeyPress )  
                                         xwin_press_modifiers( &xkbevent.core.xkey, ev_time, scancode );  
825    
826                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, flags, scancode, 0);                                  rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
827                                    break;
828    
829                                  if( xkbevent.type == KeyRelease )                          case KeyRelease:
830                                          xwin_release_modifiers( &xkbevent.core.xkey, ev_time, scancode );                                  XLookupString((XKeyEvent *) & xevent, str,
831                                                  sizeof(str), &keysym, NULL);
832    
833                                    DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
834                                               get_ksname(keysym)));
835    
836                                    ev_time = time(NULL);
837                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
838                                            break;
839    
840                                    tr = xkeymap_translate_key(keysym,
841                                                               xevent.xkey.keycode, xevent.xkey.state);
842    
843                                    if (tr.scancode == 0)
844                                            break;
845    
846                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
847                                  break;                                  break;
848    
849                          case ButtonPress:                          case ButtonPress:
# Line 444  xwin_process_events() Line 851  xwin_process_events()
851                                  /* fall through */                                  /* fall through */
852    
853                          case ButtonRelease:                          case ButtonRelease:
854                                  button = xkeymap_translate_button(xkbevent.core.xbutton.button);                                  button = xkeymap_translate_button(xevent.xbutton.button);
855                                  if (button == 0)                                  if (button == 0)
856                                          break;                                          break;
857    
858                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  /* If win_button_size is nonzero, enable single app mode */
859                                                 flags | button,                                  if (xevent.xbutton.y < win_button_size)
860                                                 xkbevent.core.xbutton.x,                                  {
861                                                 xkbevent.core.xbutton.y);                                          if (xevent.xbutton.x < win_button_size)
862                                            {
863                                                    /* The system menu, do not send to server */
864                                                    break;
865                                            }
866                                            else if (xevent.xbutton.x >= width - win_button_size)
867                                            {
868                                                    /* The close button, continue */
869                                                    ;
870                                            }
871                                            else if (xevent.xbutton.x >= width - win_button_size * 2)
872                                            {
873                                                    /* The maximize/restore button. Do not send to
874                                                       server.  It might be a good idea to change the
875                                                       cursor or give some other visible indication
876                                                       that rdesktop inhibited this click */
877                                                    break;
878                                            }
879                                            else if (xevent.xbutton.x >= width - win_button_size * 3)
880                                            {
881                                                    /* The minimize button. Iconify window. */
882                                                    XIconifyWindow(display, wnd,
883                                                                   DefaultScreen(display));
884                                                    break;
885                                            }
886                                    }
887    
888                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
889                                                   flags | button, xevent.xbutton.x, xevent.xbutton.y);
890                                  break;                                  break;
891    
892                          case MotionNotify:                          case MotionNotify:
893                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  if (fullscreen && !focused)
894                                                 MOUSE_FLAG_MOVE,                                          XSetInputFocus(display, wnd, RevertToPointerRoot,
895                                                 xkbevent.core.xmotion.x,                                                         CurrentTime);
896                                                 xkbevent.core.xmotion.y);                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
897                                                   MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
898                                    break;
899    
900                            case FocusIn:
901                                    if (xevent.xfocus.mode == NotifyGrab)
902                                            break;
903                                    focused = True;
904                                    XQueryPointer(display, wnd, &wdummy, &wdummy, &dummy, &dummy,
905                                                  &dummy, &dummy, &state);
906                                    reset_modifier_keys(state);
907                                    if (grab_keyboard && mouse_in_wnd)
908                                            XGrabKeyboard(display, wnd, True,
909                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
910                                    break;
911    
912                            case FocusOut:
913                                    if (xevent.xfocus.mode == NotifyUngrab)
914                                            break;
915                                    focused = False;
916                                    if (xevent.xfocus.mode == NotifyWhileGrabbed)
917                                            XUngrabKeyboard(display, CurrentTime);
918                                  break;                                  break;
919    
920                          case EnterNotify:                          case EnterNotify:
921                                  XGrabKeyboard(display, wnd, True, GrabModeAsync,                                  /* we only register for this event when in fullscreen mode */
922                                                GrabModeAsync, CurrentTime);                                  /* or grab_keyboard */
923                                    mouse_in_wnd = True;
924                                    if (fullscreen)
925                                    {
926                                            XSetInputFocus(display, wnd, RevertToPointerRoot,
927                                                           CurrentTime);
928                                            break;
929                                    }
930                                    if (focused)
931                                            XGrabKeyboard(display, wnd, True,
932                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
933                                  break;                                  break;
934    
935                          case LeaveNotify:                          case LeaveNotify:
936                                    /* we only register for this event when grab_keyboard */
937                                    mouse_in_wnd = False;
938                                  XUngrabKeyboard(display, CurrentTime);                                  XUngrabKeyboard(display, CurrentTime);
939                                  break;                                  break;
940    
941                          case Expose:                          case Expose:
942                                  XCopyArea(display, backstore, wnd, gc,                                  XCopyArea(display, backstore, wnd, gc,
943                                            xkbevent.core.xexpose.x, xkbevent.core.xexpose.y,                                            xevent.xexpose.x, xevent.xexpose.y,
944                                            xkbevent.core.xexpose.width, xkbevent.core.xexpose.height,                                            xevent.xexpose.width,
945                                            xkbevent.core.xexpose.x, xkbevent.core.xexpose.y);                                            xevent.xexpose.height,
946                                              xevent.xexpose.x, xevent.xexpose.y);
947                                  break;                                  break;
                 }  
         }  
 }  
   
 void  
 xwin_release_modifiers(XKeyEvent* ev, uint32 ev_time, uint32 scancode)  
 {  
         switch (scancode) {  
         case 0x2a:  
                 key_down_state &= ~DShift1Mask;  
                 break;  
         case 0x36:  
                 key_down_state &= ~DShift2Mask;  
                 break;  
         case 0x1d:  
                 key_down_state &= ~DControl1Mask;  
                 break;  
         case 0x9d:  
                 key_down_state &= ~DControl2Mask;  
                 break;  
         case 0x38:  
                 key_down_state &= ~DMod1Mask;  
                 break;  
         case 0xb8:  
                 key_down_state &= ~DMod2Mask;  
                 break;  
         }  
   
         if( !(ShiftMask & ev->state) && (key_down_state & DShift1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x2a, 0);  
                 key_down_state &= ~DShift1Mask;  
   
         }  
   
         if( !(ControlMask & ev->state) && (key_down_state & DControl1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x1d, 0);  
                 key_down_state &= ~DControl1Mask;  
948    
949          }                          case MappingNotify:
950                                            /* Refresh keyboard mapping if it has changed. This is important for
951          if( !(Mod1Mask & ev->state) && (key_down_state & DMod1Mask))                                     Xvnc, since it allocates keycodes dynamically */
952          {                                  if (xevent.xmapping.request == MappingKeyboard
953                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x38, 0);                                      || xevent.xmapping.request == MappingModifier)
954                  key_down_state &= ~DMod1Mask;                                          XRefreshKeyboardMapping(&xevent.xmapping);
955    
956          }                                  if (xevent.xmapping.request == MappingModifier)
957                                            {
958          if( !(Mod2Mask & ev->state) && (key_down_state & DMod2Mask))                                          XFreeModifiermap(mod_map);
959          {                                          mod_map = XGetModifierMapping(display);
960                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0xb8, 0);                                  }
961                  key_down_state &= ~DMod2Mask;                                  break;
         }  
 }  
   
   
 void  
 xwin_press_modifiers(XKeyEvent* ev, uint32 ev_time, uint32 scancode)  
 {  
         key_modifier_state = ev->state;  
   
         switch (scancode) {  
         case 0x2a:  
                 key_down_state |= DShift1Mask;  
                 break;  
         case 0x36:  
                 key_down_state |= DShift2Mask;  
                 break;  
         case 0x1d:  
                 key_down_state |= DControl1Mask;  
                 break;  
         case 0x9d:  
                 key_down_state |= DControl2Mask;  
                 break;  
         case 0x38:  
                 key_down_state |= DMod1Mask;  
                 break;  
         case 0xb8:  
                 key_down_state |= DMod2Mask;  
                 break;  
         }  
   
         if( (ShiftMask & ev->state) && !((key_down_state & DShift1Mask) || (key_down_state & DShift2Mask)))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x2a, 0);  
                 key_down_state |= DShift1Mask;  
   
         }  
   
         if( (ControlMask & ev->state) && !((key_down_state & DControl1Mask) || (key_down_state & DControl2Mask)))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x1d, 0);  
                 key_down_state |= DControl1Mask;  
   
         }  
   
         if( (Mod1Mask & ev->state) && !(key_down_state & DMod1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x38, 0);  
                 key_down_state |= DMod1Mask;  
   
         }  
   
         if( (Mod2Mask & ev->state) && !(key_down_state & DMod2Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0xb8, 0);  
                 key_down_state |= DMod2Mask;  
962    
963                    }
964          }          }
965            /* Keep going */
966            return 1;
967  }  }
968    
969  void  /* Returns 0 after user quit, 1 otherwise */
970    int
971  ui_select(int rdp_socket)  ui_select(int rdp_socket)
972  {  {
973          int n = (rdp_socket > x_socket) ? rdp_socket+1 : x_socket+1;          int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;
974          fd_set rfds;          fd_set rfds;
975    
         XFlush(display);  
   
976          FD_ZERO(&rfds);          FD_ZERO(&rfds);
977    
978          while (True)          while (True)
979          {          {
980                    /* Process any events already waiting */
981                    if (!xwin_process_events())
982                            /* User quit */
983                            return 0;
984    
985                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
986                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
987                  FD_SET(x_socket, &rfds);                  FD_SET(x_socket, &rfds);
# Line 613  ui_select(int rdp_socket) Line 995  ui_select(int rdp_socket)
995                                  continue;                                  continue;
996                  }                  }
997    
                 if (FD_ISSET(x_socket, &rfds))  
                         xwin_process_events();  
   
998                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
999                          return;                          return 1;
1000          }          }
1001  }  }
1002    
# Line 628  ui_move_pointer(int x, int y) Line 1007  ui_move_pointer(int x, int y)
1007  }  }
1008    
1009  HBITMAP  HBITMAP
1010  ui_create_bitmap(int width, int height, uint8 *data)  ui_create_bitmap(int width, int height, uint8 * data)
1011  {  {
1012          XImage *image;          XImage *image;
1013          Pixmap bitmap;          Pixmap bitmap;
# Line 636  ui_create_bitmap(int width, int height, Line 1015  ui_create_bitmap(int width, int height,
1015    
1016          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
1017          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
1018          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1019                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, server_bpp == 8 ? 8 : bpp, 0);
1020    
1021          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
1022    
# Line 648  ui_create_bitmap(int width, int height, Line 1027  ui_create_bitmap(int width, int height,
1027  }  }
1028    
1029  void  void
1030  ui_paint_bitmap(int x, int y, int cx, int cy,  ui_paint_bitmap(int x, int y, int cx, int cy, int width, int height, uint8 * data)
                 int width, int height, uint8 *data)  
1031  {  {
1032          XImage *image;          XImage *image;
1033          uint8 *tdata;          uint8 *tdata;
   
1034          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
1035          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1036                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, server_bpp == 8 ? 8 : bpp, 0);
1037    
1038          if (ownbackstore)          if (ownbackstore)
1039          {          {
# Line 676  ui_paint_bitmap(int x, int y, int cx, in Line 1053  ui_paint_bitmap(int x, int y, int cx, in
1053  void  void
1054  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(HBITMAP bmp)
1055  {  {
1056          XFreePixmap(display, (Pixmap)bmp);          XFreePixmap(display, (Pixmap) bmp);
1057  }  }
1058    
1059  HGLYPH  HGLYPH
1060  ui_create_glyph(int width, int height, uint8 *data)  ui_create_glyph(int width, int height, uint8 * data)
1061  {  {
1062          XImage *image;          XImage *image;
1063          Pixmap bitmap;          Pixmap bitmap;
# Line 692  ui_create_glyph(int width, int height, u Line 1069  ui_create_glyph(int width, int height, u
1069          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(display, wnd, width, height, 1);
1070          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(display, bitmap, 0, NULL);
1071    
1072          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(display, visual, 1, ZPixmap, 0, (char *) data,
1073                               data, width, height, 8, scanline);                               width, height, 8, scanline);
1074          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
1075          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
1076          XInitImage(image);          XInitImage(image);
# Line 702  ui_create_glyph(int width, int height, u Line 1079  ui_create_glyph(int width, int height, u
1079    
1080          XFree(image);          XFree(image);
1081          XFreeGC(display, gc);          XFreeGC(display, gc);
1082          return (HGLYPH)bitmap;          return (HGLYPH) bitmap;
1083  }  }
1084    
1085  void  void
1086  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
1087  {  {
1088          XFreePixmap(display, (Pixmap)glyph);          XFreePixmap(display, (Pixmap) glyph);
1089  }  }
1090    
1091  HCURSOR  HCURSOR
1092  ui_create_cursor(unsigned int x, unsigned int y, int width,  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
1093                   int height, uint8 *andmask, uint8 *xormask)                   uint8 * andmask, uint8 * xormask)
1094  {  {
1095          HGLYPH maskglyph, cursorglyph;          HGLYPH maskglyph, cursorglyph;
1096          XColor bg, fg;          XColor bg, fg;
# Line 770  ui_create_cursor(unsigned int x, unsigne Line 1147  ui_create_cursor(unsigned int x, unsigne
1147    
1148          cursorglyph = ui_create_glyph(width, height, cursor);          cursorglyph = ui_create_glyph(width, height, cursor);
1149          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
1150            
1151          xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,          xcursor =
1152                                  (Pixmap)maskglyph, &fg, &bg, x, y);                  XCreatePixmapCursor(display, (Pixmap) cursorglyph,
1153                                        (Pixmap) maskglyph, &fg, &bg, x, y);
1154    
1155          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
1156          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
1157          xfree(mask);          xfree(mask);
1158          xfree(cursor);          xfree(cursor);
1159          return (HCURSOR)xcursor;          return (HCURSOR) xcursor;
1160  }  }
1161    
1162  void  void
1163  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
1164  {  {
1165          XDefineCursor(display, wnd, (Cursor)cursor);          current_cursor = (Cursor) cursor;
1166            XDefineCursor(display, wnd, current_cursor);
1167  }  }
1168    
1169  void  void
1170  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_cursor(HCURSOR cursor)
1171  {  {
1172          XFreeCursor(display, (Cursor)cursor);          XFreeCursor(display, (Cursor) cursor);
1173  }  }
1174    
1175  #define MAKE_XCOLOR(xc,c) \  #define MAKE_XCOLOR(xc,c) \
# Line 799  ui_destroy_cursor(HCURSOR cursor) Line 1178  ui_destroy_cursor(HCURSOR cursor)
1178                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
1179                  (xc)->flags = DoRed | DoGreen | DoBlue;                  (xc)->flags = DoRed | DoGreen | DoBlue;
1180    
1181    
1182  HCOLOURMAP  HCOLOURMAP
1183  ui_create_colourmap(COLOURMAP *colours)  ui_create_colourmap(COLOURMAP * colours)
1184  {  {
1185          COLOURENTRY *entry;          COLOURENTRY *entry;
1186          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
1187            if (!owncolmap)
1188            {
1189                    uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
1190                    XColor xentry;
1191                    XColor xc_cache[256];
1192                    uint32 colour;
1193                    int colLookup = 256;
1194                    for (i = 0; i < ncolours; i++)
1195                    {
1196                            entry = &colours->colours[i];
1197                            MAKE_XCOLOR(&xentry, entry);
1198    
1199                            if (XAllocColor(display, xcolmap, &xentry) == 0)
1200                            {
1201                                    /* Allocation failed, find closest match. */
1202                                    int j = 256;
1203                                    int nMinDist = 3 * 256 * 256;
1204                                    long nDist = nMinDist;
1205    
1206                                    /* only get the colors once */
1207                                    while (colLookup--)
1208                                    {
1209                                            xc_cache[colLookup].pixel = colLookup;
1210                                            xc_cache[colLookup].red = xc_cache[colLookup].green =
1211                                                    xc_cache[colLookup].blue = 0;
1212                                            xc_cache[colLookup].flags = 0;
1213                                            XQueryColor(display,
1214                                                        DefaultColormap(display,
1215                                                                        DefaultScreen(display)),
1216                                                        &xc_cache[colLookup]);
1217                                    }
1218                                    colLookup = 0;
1219    
1220                                    /* approximate the pixel */
1221                                    while (j--)
1222                                    {
1223                                            if (xc_cache[j].flags)
1224                                            {
1225                                                    nDist = ((long) (xc_cache[j].red >> 8) -
1226                                                             (long) (xentry.red >> 8)) *
1227                                                            ((long) (xc_cache[j].red >> 8) -
1228                                                             (long) (xentry.red >> 8)) +
1229                                                            ((long) (xc_cache[j].green >> 8) -
1230                                                             (long) (xentry.green >> 8)) *
1231                                                            ((long) (xc_cache[j].green >> 8) -
1232                                                             (long) (xentry.green >> 8)) +
1233                                                            ((long) (xc_cache[j].blue >> 8) -
1234                                                             (long) (xentry.blue >> 8)) *
1235                                                            ((long) (xc_cache[j].blue >> 8) -
1236                                                             (long) (xentry.blue >> 8));
1237                                            }
1238                                            if (nDist < nMinDist)
1239                                            {
1240                                                    nMinDist = nDist;
1241                                                    xentry.pixel = j;
1242                                            }
1243                                    }
1244                            }
1245                            colour = xentry.pixel;
1246    
1247          if (owncolmap)                          /* update our cache */
1248                            if (xentry.pixel < 256)
1249                            {
1250                                    xc_cache[xentry.pixel].red = xentry.red;
1251                                    xc_cache[xentry.pixel].green = xentry.green;
1252                                    xc_cache[xentry.pixel].blue = xentry.blue;
1253    
1254                            }
1255    
1256    
1257                            /* byte swap here to make translate_image faster */
1258                            map[i] = translate_colour(colour);
1259                    }
1260                    return map;
1261            }
1262            else
1263          {          {
1264                  XColor *xcolours, *xentry;                  XColor *xcolours, *xentry;
1265                  Colormap map;                  Colormap map;
# Line 823  ui_create_colourmap(COLOURMAP *colours) Line 1277  ui_create_colourmap(COLOURMAP *colours)
1277                  XStoreColors(display, map, xcolours, ncolours);                  XStoreColors(display, map, xcolours, ncolours);
1278    
1279                  xfree(xcolours);                  xfree(xcolours);
1280                  return (HCOLOURMAP)map;                  return (HCOLOURMAP) map;
         }  
         else  
         {  
                 uint32 *map = xmalloc(sizeof(*colmap) * ncolours);  
                 XColor xentry;  
                 uint32 colour;  
   
                 for (i = 0; i < ncolours; i++)  
                 {  
                         entry = &colours->colours[i];  
                         MAKE_XCOLOR(&xentry, entry);  
   
                         if (XAllocColor(display, xcolmap, &xentry) != 0)  
                                 colour = xentry.pixel;  
                         else  
                                 colour = white;  
   
                         /* byte swap here to make translate_image faster */  
                         map[i] = translate_colour(colour);  
                 }  
   
                 return map;  
1281          }          }
1282  }  }
1283    
1284  void  void
1285  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
1286  {  {
1287          if (owncolmap)          if (!owncolmap)
                 XFreeColormap(display, (Colormap)map);  
         else  
1288                  xfree(map);                  xfree(map);
1289            else
1290                    XFreeColormap(display, (Colormap) map);
1291  }  }
1292    
1293  void  void
1294  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
1295  {  {
1296          if (owncolmap)          if (!owncolmap)
                 XSetWindowColormap(display, wnd, (Colormap)map);  
         else  
1297                  colmap = map;                  colmap = map;
1298            else
1299                    XSetWindowColormap(display, wnd, (Colormap) map);
1300  }  }
1301    
1302  void  void
# Line 880  ui_set_clip(int x, int y, int cx, int cy Line 1312  ui_set_clip(int x, int y, int cx, int cy
1312  }  }
1313    
1314  void  void
1315  ui_reset_clip()  ui_reset_clip(void)
1316  {  {
1317          XRectangle rect;          XRectangle rect;
1318    
# Line 892  ui_reset_clip() Line 1324  ui_reset_clip()
1324  }  }
1325    
1326  void  void
1327  ui_bell()  ui_bell(void)
1328  {  {
1329          XBell(display, 0);          XBell(display, 0);
1330  }  }
# Line 909  ui_destblt(uint8 opcode, Line 1341  ui_destblt(uint8 opcode,
1341  void  void
1342  ui_patblt(uint8 opcode,  ui_patblt(uint8 opcode,
1343            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1344            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1345  {  {
1346          Pixmap fill;          Pixmap fill;
1347            uint8 i, ipattern[8];
1348    
1349          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1350    
# Line 923  ui_patblt(uint8 opcode, Line 1356  ui_patblt(uint8 opcode,
1356                          break;                          break;
1357    
1358                  case 3: /* Pattern */                  case 3: /* Pattern */
1359                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);                          for (i = 0; i != 8; i++)
1360                                    ipattern[7 - i] = brush->pattern[i];
1361                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
1362    
1363                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(bgcolour);
1364                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
# Line 934  ui_patblt(uint8 opcode, Line 1369  ui_patblt(uint8 opcode,
1369                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1370    
1371                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
1372                          ui_destroy_glyph((HGLYPH)fill);                          XSetTSOrigin(display, gc, 0, 0);
1373                            ui_destroy_glyph((HGLYPH) fill);
1374                          break;                          break;
1375    
1376                  default:                  default:
# Line 952  ui_screenblt(uint8 opcode, Line 1388  ui_screenblt(uint8 opcode,
1388          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1389          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
1390          if (ownbackstore)          if (ownbackstore)
1391                  XCopyArea(display, backstore, backstore, gc, srcx, srcy,                  XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1392          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1393  }  }
1394    
# Line 963  ui_memblt(uint8 opcode, Line 1398  ui_memblt(uint8 opcode,
1398            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
1399  {  {
1400          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1401          XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
1402          if (ownbackstore)          if (ownbackstore)
1403                  XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1404          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1405  }  }
1406    
# Line 974  void Line 1408  void
1408  ui_triblt(uint8 opcode,  ui_triblt(uint8 opcode,
1409            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1410            /* src */ HBITMAP src, int srcx, int srcy,            /* src */ HBITMAP src, int srcx, int srcy,
1411            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1412  {  {
1413          /* This is potentially difficult to do in general. Until someone          /* This is potentially difficult to do in general. Until someone
1414             comes up with a more efficient way of doing it I am using cases. */             comes up with a more efficient way of doing it I am using cases. */
# Line 983  ui_triblt(uint8 opcode, Line 1417  ui_triblt(uint8 opcode,
1417          {          {
1418                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
1419                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1420                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1421                          break;                          break;
1422    
1423                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
1424                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1425                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1426                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1427                          break;                          break;
1428    
1429                  case 0xc0:      /* PSa */                  case 0xc0:      /* PSa */
1430                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1431                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
1432                          break;                          break;
1433    
1434                  default:                  default:
# Line 1010  ui_triblt(uint8 opcode, Line 1440  ui_triblt(uint8 opcode,
1440  void  void
1441  ui_line(uint8 opcode,  ui_line(uint8 opcode,
1442          /* dest */ int startx, int starty, int endx, int endy,          /* dest */ int startx, int starty, int endx, int endy,
1443          /* pen */ PEN *pen)          /* pen */ PEN * pen)
1444  {  {
1445          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1446          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
# Line 1029  ui_rect( Line 1459  ui_rect(
1459          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
1460  }  }
1461    
1462    /* warning, this function only draws on wnd or backstore, not both */
1463  void  void
1464  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1465                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1466                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1467                int fgcolour)                int bgcolour, int fgcolour)
1468  {  {
1469          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
1470          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
1471    
1472          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)          XSetFillStyle(display, gc,
1473                        ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1474          XSetStipple(display, gc, (Pixmap)glyph);          XSetStipple(display, gc, (Pixmap) glyph);
1475          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(display, gc, x, y);
1476    
1477          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
1478    
1479          XSetFillStyle(display, gc, FillSolid);          XSetFillStyle(display, gc, FillSolid);
1480  }  }
# Line 1057  ui_draw_glyph(int mixmode, Line 1488  ui_draw_glyph(int mixmode,
1488        if ((xyoffset & 0x80))\        if ((xyoffset & 0x80))\
1489          {\          {\
1490            if (flags & TEXT2_VERTICAL) \            if (flags & TEXT2_VERTICAL) \
1491              y += ttext[++idx] | (ttext[++idx] << 8);\              y += ttext[idx+1] | (ttext[idx+2] << 8);\
1492            else\            else\
1493              x += ttext[++idx] | (ttext[++idx] << 8);\              x += ttext[idx+1] | (ttext[idx+2] << 8);\
1494              idx += 2;\
1495          }\          }\
1496        else\        else\
1497          {\          {\
# Line 1071  ui_draw_glyph(int mixmode, Line 1503  ui_draw_glyph(int mixmode,
1503      }\      }\
1504    if (glyph != NULL)\    if (glyph != NULL)\
1505      {\      {\
1506        ui_draw_glyph (mixmode, x + (short) glyph->offset,\        ui_draw_glyph (mixmode, x + glyph->offset,\
1507                       y + (short) glyph->baseline,\                       y + glyph->baseline,\
1508                       glyph->width, glyph->height,\                       glyph->width, glyph->height,\
1509                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\
1510        if (flags & TEXT2_IMPLICIT_X)\        if (flags & TEXT2_IMPLICIT_X)\
# Line 1082  ui_draw_glyph(int mixmode, Line 1514  ui_draw_glyph(int mixmode,
1514    
1515  void  void
1516  ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,  ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
1517               int clipx, int clipy, int clipcx, int clipcy, int boxx,               int clipx, int clipy, int clipcx, int clipcy,
1518               int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1519               int fgcolour, uint8 * text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1520  {  {
1521          FONTGLYPH *glyph;          FONTGLYPH *glyph;
# Line 1094  ui_draw_text(uint8 font, uint8 flags, in Line 1526  ui_draw_text(uint8 font, uint8 flags, in
1526    
1527          if (boxcx > 1)          if (boxcx > 1)
1528          {          {
1529                  FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);
1530          }          }
1531          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
1532          {          {
1533                  FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
1534          }          }
1535    
1536          /* Paint text, character by character */          /* Paint text, character by character */
1537          for (i = 0; i < length;) {          for (i = 0; i < length;)
1538                  switch (text[i]) {          {
1539                  case 0xff:                  switch (text[i])
1540                          if (i + 2 < length)                  {
1541                                  cache_put_text(text[i + 1], text, text[i + 2]);                          case 0xff:
1542                          else {                                  if (i + 2 < length)
1543                                  error("this shouldn't be happening\n");                                          cache_put_text(text[i + 1], text, text[i + 2]);
1544                                    else
1545                                    {
1546                                            error("this shouldn't be happening\n");
1547                                            exit(1);
1548                                    }
1549                                    /* this will move pointer from start to first character after FF command */
1550                                    length -= i + 3;
1551                                    text = &(text[i + 3]);
1552                                    i = 0;
1553                                  break;                                  break;
                         }  
                         /* this will move pointer from start to first character after FF command */  
                         length -= i + 3;  
                         text = &(text[i + 3]);  
                         i = 0;  
                         break;  
1554    
1555                  case 0xfe:                          case 0xfe:
1556                          entry = cache_get_text(text[i + 1]);                                  entry = cache_get_text(text[i + 1]);
1557                          if (entry != NULL) {                                  if (entry != NULL)
1558                                  if ((((uint8 *) (entry->data))[1] == 0)                                  {
1559                                      && (!(flags & TEXT2_IMPLICIT_X))) {                                          if ((((uint8 *) (entry->data))[1] ==
1560                                          if (flags & TEXT2_VERTICAL)                                               0) && (!(flags & TEXT2_IMPLICIT_X)))
1561                                                  y += text[i + 2];                                          {
1562                                          else                                                  if (flags & TEXT2_VERTICAL)
1563                                                  x += text[i + 2];                                                          y += text[i + 2];
1564                                                    else
1565                                                            x += text[i + 2];
1566                                            }
1567                                            for (j = 0; j < entry->size; j++)
1568                                                    DO_GLYPH(((uint8 *) (entry->data)), j);
1569                                  }                                  }
1570                                  if (i + 2 < length)                                  if (i + 2 < length)
1571                                          i += 3;                                          i += 3;
1572                                  else                                  else
1573                                          i += 2;                                          i += 2;
1574                                  length -= i;                                  length -= i;
1575                                  /* this will move pointer from start to first character after FE command */                                  /* this will move pointer from start to first character after FE command */
1576                                  text = &(text[i]);                                  text = &(text[i]);
1577                                  i = 0;                                  i = 0;
1578                                  for (j = 0; j < entry->size; j++)                                  break;
                                         DO_GLYPH(((uint8 *) (entry->data)), j);  
                         }  
                         break;  
1579    
1580                  default:                          default:
1581                          DO_GLYPH(text, i);                                  DO_GLYPH(text, i);
1582                          i++;                                  i++;
1583                          break;                                  break;
1584                  }                  }
1585          }          }
1586            if (ownbackstore)
1587            {
1588                    if (boxcx > 1)
1589                            XCopyArea(display, backstore, wnd, gc, boxx,
1590                                      boxy, boxcx, boxcy, boxx, boxy);
1591                    else
1592                            XCopyArea(display, backstore, wnd, gc, clipx,
1593                                      clipy, clipcx, clipcy, clipx, clipy);
1594            }
1595  }  }
1596    
1597  void  void
# Line 1158  ui_desktop_save(uint32 offset, int x, in Line 1602  ui_desktop_save(uint32 offset, int x, in
1602    
1603          if (ownbackstore)          if (ownbackstore)
1604          {          {
1605                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1606          }          }
1607          else          else
1608          {          {
1609                  pix = XCreatePixmap(display, wnd, cx, cy, depth);                  pix = XCreatePixmap(display, wnd, cx, cy, depth);
1610                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
1611                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1612                  XFreePixmap(display, pix);                  XFreePixmap(display, pix);
1613          }          }
1614    
1615          offset *= bpp/8;          offset *= bpp / 8;
1616          cache_put_desktop(offset, cx, cy, image->bytes_per_line,          cache_put_desktop(offset, cx, cy, image->bytes_per_line, bpp / 8, (uint8 *) image->data);
                           bpp/8, (uint8 *)image->data);  
1617    
1618          XDestroyImage(image);          XDestroyImage(image);
1619  }  }
# Line 1183  ui_desktop_restore(uint32 offset, int x, Line 1624  ui_desktop_restore(uint32 offset, int x,
1624          XImage *image;          XImage *image;
1625          uint8 *data;          uint8 *data;
1626    
1627          offset *= bpp/8;          offset *= bpp / 8;
1628          data = cache_get_desktop(offset, cx, cy, bpp/8);          data = cache_get_desktop(offset, cx, cy, bpp / 8);
1629          if (data == NULL)          if (data == NULL)
1630                  return;                  return;
1631    
1632          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1633                               0, data, cx, cy, BitmapPad(display),                               (char *) data, cx, cy, BitmapPad(display), cx * bpp / 8);
                              cx * bpp/8);  
1634    
1635          if (ownbackstore)          if (ownbackstore)
1636          {          {

Legend:
Removed from v.52  
changed lines
  Added in v.331

  ViewVC Help
Powered by ViewVC 1.1.26