/[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 53 by matthewc, Tue May 28 11:48:55 2002 UTC revision 448 by astrand, Wed Aug 27 08:21:53 2003 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
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    #include "xproto.h"
27    
28  extern char keymapname[16];  extern int g_width;
29  extern int keylayout;  extern int g_height;
30  extern int width;  extern BOOL g_sendmotion;
31  extern int height;  extern BOOL g_fullscreen;
32  extern BOOL sendmotion;  extern BOOL grab_keyboard;
33  extern BOOL fullscreen;  extern BOOL hide_decorations;
34    extern char title[];
35    extern int g_server_bpp;
36    extern int win_button_size;
37    BOOL g_enable_compose = False;
38    BOOL g_focused;
39    BOOL g_mouse_in_wnd;
40    
41  Display *display;  Display *display;
42  XkbDescPtr xkb;  Time last_gesturetime;
43  static int x_socket;  static int x_socket;
44  static Window wnd;  static Screen *screen;
45    Window wnd;
46  static GC gc;  static GC gc;
47  static Visual *visual;  static Visual *visual;
48  static int depth;  static int depth;
49  static int bpp;  static int bpp;
50    static XIM IM;
51    static XIC IC;
52    static XModifierKeymap *mod_map;
53    static Cursor current_cursor;
54    static Atom protocol_atom, kill_atom;
55    
56  /* endianness */  /* endianness */
57  static BOOL host_be;  static BOOL host_be;
# Line 49  static BOOL xserver_be; Line 61  static BOOL xserver_be;
61  static BOOL ownbackstore;  static BOOL ownbackstore;
62  static Pixmap backstore;  static Pixmap backstore;
63    
64  /* needed to keep track of the modifiers */  /* Moving in single app mode */
65  static unsigned int key_modifier_state = 0;  static BOOL moving_wnd;
66  static unsigned int key_down_state = 0;  static int move_x_offset = 0;
67    static int move_y_offset = 0;
68  #define DShift1Mask   (1<<0)  
69  #define DShift2Mask   (1<<1)  /* MWM decorations */
70  #define DControl1Mask (1<<2)  #define MWM_HINTS_DECORATIONS   (1L << 1)
71  #define DControl2Mask (1<<3)  #define PROP_MOTIF_WM_HINTS_ELEMENTS    5
72  #define DMod1Mask     (1<<4)  typedef struct
73  #define DMod2Mask     (1<<5)  {
74            uint32 flags;
75            uint32 functions;
76            uint32 decorations;
77            sint32 inputMode;
78            uint32 status;
79    }
80    PropMotifWmHints;
81    
82    typedef struct
83    {
84            uint32 red;
85            uint32 green;
86            uint32 blue;
87    }
88    PixelColour;
89    
90    
91  #define FILL_RECTANGLE(x,y,cx,cy)\  #define FILL_RECTANGLE(x,y,cx,cy)\
92  { \  { \
# Line 67  static unsigned int key_down_state = 0; Line 95  static unsigned int key_down_state = 0;
95                  XFillRectangle(display, backstore, gc, x, y, cx, cy); \                  XFillRectangle(display, backstore, gc, x, y, cx, cy); \
96  }  }
97    
98    #define FILL_RECTANGLE_BACKSTORE(x,y,cx,cy)\
99    { \
100            XFillRectangle(display, ownbackstore ? backstore : wnd, gc, x, y, cx, cy); \
101    }
102    
103  /* colour maps */  /* colour maps */
104  static BOOL owncolmap;  BOOL owncolmap = False;
105  static Colormap xcolmap;  static Colormap xcolmap;
106  static uint32 white;  static uint32 *colmap = NULL;
 static uint32 *colmap;  
107    
108  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )  #define TRANSLATE(col)          ( g_server_bpp != 8 ? translate_colour(col) : owncolmap ? col : translate_colour(colmap[col]) )
109  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));
110  #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));  #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));
111    
# Line 99  static int rop2_map[] = { Line 131  static int rop2_map[] = {
131  #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]); }
132  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
133    
134  void xwin_release_modifiers(XKeyEvent* ev, uint32 ev_time, uint32 scancode);  static void
135  void xwin_press_modifiers(XKeyEvent* ev, uint32 ev_time, uint32 scancode);  mwm_hide_decorations(void)
136    {
137            PropMotifWmHints motif_hints;
138            Atom hintsatom;
139    
140            /* setup the property */
141            motif_hints.flags = MWM_HINTS_DECORATIONS;
142            motif_hints.decorations = 0;
143    
144            /* get the atom for the property */
145            hintsatom = XInternAtom(display, "_MOTIF_WM_HINTS", False);
146            if (!hintsatom)
147            {
148                    warning("Failed to get atom _MOTIF_WM_HINTS: probably your window manager does not support MWM hints\n");
149                    return;
150            }
151    
152            XChangeProperty(display, wnd, hintsatom, hintsatom, 32, PropModeReplace,
153                            (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
154    }
155    
156    static PixelColour
157    split_colour15(uint32 colour)
158    {
159            PixelColour rv;
160            rv.red = (colour & 0x7c00) >> 10;
161            rv.red = (rv.red * 0xff) / 0x1f;
162            rv.green = (colour & 0x03e0) >> 5;
163            rv.green = (rv.green * 0xff) / 0x1f;
164            rv.blue = (colour & 0x1f);
165            rv.blue = (rv.blue * 0xff) / 0x1f;
166            return rv;
167    }
168    
169    static PixelColour
170    split_colour16(uint32 colour)
171    {
172            PixelColour rv;
173            rv.red = (colour & 0xf800) >> 11;
174            rv.red = (rv.red * 0xff) / 0x1f;
175            rv.green = (colour & 0x07e0) >> 5;
176            rv.green = (rv.green * 0xff) / 0x3f;
177            rv.blue = (colour & 0x001f);
178            rv.blue = (rv.blue * 0xff) / 0x1f;
179            return rv;
180    }
181    
182    static PixelColour
183    split_colour24(uint32 colour)
184    {
185            PixelColour rv;
186            rv.blue = (colour & 0xff0000) >> 16;
187            rv.green = (colour & 0xff00) >> 8;
188            rv.red = (colour & 0xff);
189            return rv;
190    }
191    
192    static uint32
193    make_colour16(PixelColour pc)
194    {
195            pc.red = (pc.red * 0x1f) / 0xff;
196            pc.green = (pc.green * 0x3f) / 0xff;
197            pc.blue = (pc.blue * 0x1f) / 0xff;
198            return (pc.red << 11) | (pc.green << 5) | pc.blue;
199    }
200    
201    static uint32
202    make_colour24(PixelColour pc)
203    {
204            return (pc.red << 16) | (pc.green << 8) | pc.blue;
205    }
206    
207    static uint32
208    make_colour32(PixelColour pc)
209    {
210            return (pc.red << 16) | (pc.green << 8) | pc.blue;
211    }
212    
213    #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
214    #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }
215    #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
216                            x = (x << 16) | (x >> 16); }
217    
218    static uint32
219    translate_colour(uint32 colour)
220    {
221            switch (g_server_bpp)
222            {
223                    case 15:
224                            switch (bpp)
225                            {
226                                    case 16:
227                                            colour = make_colour16(split_colour15(colour));
228                                            break;
229                                    case 24:
230                                            colour = make_colour24(split_colour15(colour));
231                                            break;
232                                    case 32:
233                                            colour = make_colour32(split_colour15(colour));
234                                            break;
235                            }
236                            break;
237                    case 16:
238                            switch (bpp)
239                            {
240                                    case 16:
241                                            break;
242                                    case 24:
243                                            colour = make_colour24(split_colour16(colour));
244                                            break;
245                                    case 32:
246                                            colour = make_colour32(split_colour16(colour));
247                                            break;
248                            }
249                            break;
250                    case 24:
251                            switch (bpp)
252                            {
253                                    case 16:
254                                            colour = make_colour16(split_colour24(colour));
255                                            break;
256                                    case 24:
257                                            break;
258                                    case 32:
259                                            colour = make_colour32(split_colour24(colour));
260                                            break;
261                            }
262                            break;
263            }
264            switch (bpp)
265            {
266                    case 16:
267                            if (host_be != xserver_be)
268                                    BSWAP16(colour);
269                            break;
270    
271                    case 24:
272                            if (xserver_be)
273                                    BSWAP24(colour);
274                            break;
275    
276                    case 32:
277                            if (host_be != xserver_be)
278                                    BSWAP32(colour);
279                            break;
280            }
281    
282            return colour;
283    }
284    
285  static void  static void
286  translate8(uint8 *data, uint8 *out, uint8 *end)  translate8to8(uint8 * data, uint8 * out, uint8 * end)
287  {  {
288          while (out < end)          while (out < end)
289                  *(out++) = (uint8)colmap[*(data++)];                  *(out++) = (uint8) colmap[*(data++)];
290  }  }
291    
292  static void  static void
293  translate16(uint8 *data, uint16 *out, uint16 *end)  translate8to16(uint8 * data, uint16 * out, uint16 * end)
294  {  {
295          while (out < end)          while (out < end)
296                  *(out++) = (uint16)colmap[*(data++)];                  *(out++) = (uint16) colmap[*(data++)];
297  }  }
298    
299  /* little endian - conversion happens when colourmap is built */  /* little endian - conversion happens when colourmap is built */
300  static void  static void
301  translate24(uint8 *data, uint8 *out, uint8 *end)  translate8to24(uint8 * data, uint8 * out, uint8 * end)
302  {  {
303          uint32 value;          uint32 value;
304    
# Line 132  translate24(uint8 *data, uint8 *out, uin Line 312  translate24(uint8 *data, uint8 *out, uin
312  }  }
313    
314  static void  static void
315  translate32(uint8 *data, uint32 *out, uint32 *end)  translate8to32(uint8 * data, uint32 * out, uint32 * end)
316  {  {
317          while (out < end)          while (out < end)
318                  *(out++) = colmap[*(data++)];                  *(out++) = colmap[*(data++)];
319  }  }
320    
321  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;  
322    
323          switch (bpp)  static void
324          {  translate15to16(uint16 * data, uint16 * out, uint16 * end)
325                  case 8:  {
326                          translate8(data, out, end);          while (out < end)
327                          break;                  *(out++) = (uint16) make_colour16(split_colour15(*(data++)));
328    }
                 case 16:  
                         translate16(data, (uint16 *)out, (uint16 *)end);  
                         break;  
329    
330                  case 24:  static void
331                          translate24(data, out, end);  translate15to24(uint16 * data, uint8 * out, uint8 * end)
332                          break;  {
333            uint32 value;
334    
335                  case 32:          while (out < end)
336                          translate32(data, (uint32 *)out, (uint32 *)end);          {
337                          break;                  value = make_colour24(split_colour15(*(data++)));
338                    *(out++) = value;
339                    *(out++) = value >> 8;
340                    *(out++) = value >> 16;
341          }          }
342    }
343    
344          return out;  static void
345    translate15to32(uint16 * data, uint32 * out, uint32 * end)
346    {
347            while (out < end)
348                    *(out++) = make_colour32(split_colour15(*(data++)));
349  }  }
350    
351  #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }  static void
352  #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }  translate16to16(uint16 * data, uint16 * out, uint16 * end)
353  #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \  {
354                          x = (x << 16) | (x >> 16); }          while (out < end)
355                    *(out++) = (uint16) (*(data++));
356    }
357    
358  static uint32  
359  translate_colour(uint32 colour)  static void
360    translate16to24(uint16 * data, uint8 * out, uint8 * end)
361  {  {
362          switch (bpp)          uint32 value;
363    
364            while (out < end)
365          {          {
366                  case 16:                  value = make_colour24(split_colour16(*(data++)));
367                          if (host_be != xserver_be)                  *(out++) = value;
368                                  BSWAP16(colour);                  *(out++) = value >> 8;
369                          break;                  *(out++) = value >> 16;
370            }
371    }
372    
373                  case 24:  static void
374                          if (xserver_be)  translate16to32(uint16 * data, uint32 * out, uint32 * end)
375                                  BSWAP24(colour);  {
376                          break;          while (out < end)
377                    *(out++) = make_colour32(split_colour16(*(data++)));
378    }
379    
380                  case 32:  static void
381                          if (host_be != xserver_be)  translate24to16(uint8 * data, uint16 * out, uint16 * end)
382                                  BSWAP32(colour);  {
383                          break;          uint32 pixel = 0;
384            while (out < end)
385            {
386                    pixel = *(data++) << 16;
387                    pixel |= *(data++) << 8;
388                    pixel |= *(data++);
389                    *(out++) = (uint16) make_colour16(split_colour24(pixel));
390          }          }
391    }
392    
393          return colour;  static void
394    translate24to24(uint8 * data, uint8 * out, uint8 * end)
395    {
396            while (out < end)
397            {
398                    *(out++) = (*(data++));
399            }
400  }  }
401    
402  BOOL  static void
403  ui_create_window(char *title)  translate24to32(uint8 * data, uint32 * out, uint32 * end)
404  {  {
405          XSetWindowAttributes attribs;          uint32 pixel = 0;
406          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 )  
407          {          {
408                  error("please re-compile rdesktop\ncompile time version of xkb is not compatible with\nyour runtime version of the library\n");                  pixel = *(data++);
409                  return False;                  pixel |= *(data++) << 8;
410                    pixel |= *(data++) << 16;
411                    *(out++) = pixel;
412          }          }
413    }
414    
415    static uint8 *
416    translate_image(int width, int height, uint8 * data)
417    {
418            int size = width * height * bpp / 8;
419            uint8 *out = (uint8 *) xmalloc(size);
420            uint8 *end = out + size;
421    
422          /* 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 (g_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)  
423          {          {
424                  case XkbOD_BadLibraryVersion:                  case 24:
425                          error("XkbOD_BadLibraryVersion: XKB extensions in server and the library rdesktop is linked against aren't compatible with each other.\n");                          switch (bpp)
426                          break;                          {
427                  case XkbOD_ConnectionRefused:                                  case 32:
428                          error("XkbOD_ConnectionRefused\n");                                          translate24to32(data, (uint32 *) out, (uint32 *) end);
429                                            break;
430                                    case 24:
431                                            translate24to24(data, out, end);
432                                            break;
433                                    case 16:
434                                            translate24to16(data, (uint16 *) out, (uint16 *) end);
435                                            break;
436                            }
437                          break;                          break;
438                  case XkbOD_BadServerVersion:                  case 16:
439                          error("XkbOD_BadServerVersion\n");                          switch (bpp)
440                            {
441                                    case 32:
442                                            translate16to32((uint16 *) data, (uint32 *) out,
443                                                            (uint32 *) end);
444                                            break;
445                                    case 24:
446                                            translate16to24((uint16 *) data, out, end);
447                                            break;
448                                    case 16:
449                                            translate16to16((uint16 *) data, (uint16 *) out,
450                                                            (uint16 *) end);
451                                            break;
452                            }
453                          break;                          break;
454                  case XkbOD_NonXkbServer:                  case 15:
455                          error("XkbOD_NonXkbServer: XKB extension not present in server\nupdate your X server.\n");                          switch (bpp)
456                            {
457                                    case 32:
458                                            translate15to32((uint16 *) data, (uint32 *) out,
459                                                            (uint32 *) end);
460                                            break;
461                                    case 24:
462                                            translate15to24((uint16 *) data, out, end);
463                                            break;
464                                    case 16:
465                                            translate15to16((uint16 *) data, (uint16 *) out,
466                                                            (uint16 *) end);
467                                            break;
468                            }
469                          break;                          break;
470                  case XkbOD_Success:                  case 8:
471                          DEBUG("XkbOD_Success: Connection established with display\n");                          switch (bpp)
472                            {
473                                    case 8:
474                                            translate8to8(data, out, end);
475                                            break;
476                                    case 16:
477                                            translate8to16(data, (uint16 *) out, (uint16 *) end);
478                                            break;
479                                    case 24:
480                                            translate8to24(data, out, end);
481                                            break;
482                                    case 32:
483                                            translate8to32(data, (uint32 *) out, (uint32 *) end);
484                                            break;
485                            }
486                          break;                          break;
487          }          }
488            return out;
489    }
490    
491    BOOL
492    get_key_state(unsigned int state, uint32 keysym)
493    {
494            int modifierpos, key, keysymMask = 0;
495            int offset;
496    
497            KeyCode keycode = XKeysymToKeycode(display, keysym);
498    
499            if (keycode == NoSymbol)
500                    return False;
501    
502            for (modifierpos = 0; modifierpos < 8; modifierpos++)
503            {
504                    offset = mod_map->max_keypermod * modifierpos;
505    
506                    for (key = 0; key < mod_map->max_keypermod; key++)
507                    {
508                            if (mod_map->modifiermap[offset + key] == keycode)
509                                    keysymMask |= 1 << modifierpos;
510                    }
511            }
512    
513            return (state & keysymMask) ? True : False;
514    }
515    
516    BOOL
517    ui_init(void)
518    {
519            XPixmapFormatValues *pfm;
520            uint16 test;
521            int i;
522    
523            display = XOpenDisplay(NULL);
524          if (display == NULL)          if (display == NULL)
525          {          {
526                  error("Failed to open display\n");                  error("Failed to open display: %s\n", XDisplayName(NULL));
527                  return False;                  return False;
528          }          }
529    
# Line 255  ui_create_window(char *title) Line 531  ui_create_window(char *title)
531          screen = DefaultScreenOfDisplay(display);          screen = DefaultScreenOfDisplay(display);
532          visual = DefaultVisualOfScreen(screen);          visual = DefaultVisualOfScreen(screen);
533          depth = DefaultDepthOfScreen(screen);          depth = DefaultDepthOfScreen(screen);
534            
535          pfm = XListPixmapFormats(display, &i);          pfm = XListPixmapFormats(display, &i);
536          if (pfm != NULL)          if (pfm != NULL)
537          {          {
# Line 263  ui_create_window(char *title) Line 539  ui_create_window(char *title)
539                     desirable, e.g. 24 bits->32 bits. */                     desirable, e.g. 24 bits->32 bits. */
540                  while (i--)                  while (i--)
541                  {                  {
542                          if ((pfm[i].depth == depth)                          if ((pfm[i].depth == depth) && (pfm[i].bits_per_pixel > bpp))
                             && (pfm[i].bits_per_pixel > bpp))  
543                          {                          {
544                                  bpp = pfm[i].bits_per_pixel;                                  bpp = pfm[i].bits_per_pixel;
545                          }                          }
# Line 279  ui_create_window(char *title) Line 554  ui_create_window(char *title)
554                  return False;                  return False;
555          }          }
556    
557          if (depth <= 8)          if (owncolmap != True)
558                  owncolmap = True;          {
         else  
559                  xcolmap = DefaultColormapOfScreen(screen);                  xcolmap = DefaultColormapOfScreen(screen);
560                    if (depth <= 8)
561                            warning("Screen depth is 8 bits or lower: you may want to use -C for a private colourmap\n");
562            }
563    
564            gc = XCreateGC(display, RootWindowOfScreen(screen), 0, NULL);
565    
566            if (DoesBackingStore(screen) != Always)
567                    ownbackstore = True;
568    
569          test = 1;          test = 1;
570          host_be = !(BOOL)(*(uint8 *)(&test));          host_be = !(BOOL) (*(uint8 *) (&test));
571          xserver_be = (ImageByteOrder(display) == MSBFirst);          xserver_be = (ImageByteOrder(display) == MSBFirst);
572    
573          white = WhitePixelOfScreen(screen);          if ((g_width == 0) || (g_height == 0))
574          attribs.background_pixel = BlackPixelOfScreen(screen);          {
575          attribs.backing_store = DoesBackingStore(screen);                  /* Fetch geometry from _NET_WORKAREA */
576                    uint32 x, y, cx, cy;
577    
578          if (attribs.backing_store == NotUseful)                  if (get_current_workarea(&x, &y, &cx, &cy) == 0)
579                  ownbackstore = True;                  {
580                            g_width = cx;
581                            g_height = cy;
582                    }
583                    else
584                    {
585                            warning("Failed to get workarea: probably your window manager does not support extended hints\n");
586                            g_width = 800;
587                            g_height = 600;
588                    }
589            }
590    
591          if (fullscreen)          if (g_fullscreen)
592          {          {
593                  attribs.override_redirect = True;                  g_width = WidthOfScreen(screen);
594                  width = WidthOfScreen(screen);                  g_height = HeightOfScreen(screen);
                 height = HeightOfScreen(screen);  
595          }          }
596          else  
597            /* make sure width is a multiple of 4 */
598            g_width = (g_width + 3) & ~3;
599    
600            if (ownbackstore)
601          {          {
602                  attribs.override_redirect = False;                  backstore =
603                            XCreatePixmap(display, RootWindowOfScreen(screen), g_width, g_height,
604                                          depth);
605    
606                    /* clear to prevent rubbish being exposed at startup */
607                    XSetForeground(display, gc, BlackPixelOfScreen(screen));
608                    XFillRectangle(display, backstore, gc, 0, 0, g_width, g_height);
609          }          }
610    
611          width = (width + 3) & ~3; /* make width a multiple of 32 bits */          mod_map = XGetModifierMapping(display);
612    
613          wnd = XCreateWindow(display, RootWindowOfScreen(screen),          if (g_enable_compose)
614                              0, 0, width, height, 0, CopyFromParent,                  IM = XOpenIM(display, NULL, NULL, NULL);
615                              InputOutput, CopyFromParent,  
616                              CWBackingStore | CWBackPixel | CWOverrideRedirect,          xkeymap_init();
617                              &attribs);          xclip_init();
618    
619            /* todo take this out when high colour is done */
620            printf("server bpp %d client bpp %d depth %d\n", g_server_bpp, bpp, depth);
621    
622            return True;
623    }
624    
625    void
626    ui_deinit(void)
627    {
628            if (IM != NULL)
629                    XCloseIM(IM);
630    
631            XFreeModifiermap(mod_map);
632    
633            if (ownbackstore)
634                    XFreePixmap(display, backstore);
635    
636            XFreeGC(display, gc);
637            XCloseDisplay(display);
638            display = NULL;
639    }
640    
641    BOOL
642    ui_create_window(void)
643    {
644            XSetWindowAttributes attribs;
645            XClassHint *classhints;
646            XSizeHints *sizehints;
647            int wndwidth, wndheight;
648            long input_mask, ic_input_mask;
649            XEvent xevent;
650    
651            wndwidth = g_fullscreen ? WidthOfScreen(screen) : g_width;
652            wndheight = g_fullscreen ? HeightOfScreen(screen) : g_height;
653    
654            attribs.background_pixel = BlackPixelOfScreen(screen);
655            attribs.backing_store = ownbackstore ? NotUseful : Always;
656            attribs.override_redirect = g_fullscreen;
657    
658            wnd = XCreateWindow(display, RootWindowOfScreen(screen), 0, 0, wndwidth, wndheight,
659                                0, CopyFromParent, InputOutput, CopyFromParent,
660                                CWBackPixel | CWBackingStore | CWOverrideRedirect, &attribs);
661    
662          XStoreName(display, wnd, title);          XStoreName(display, wnd, title);
663    
664            if (hide_decorations)
665                    mwm_hide_decorations();
666    
667          classhints = XAllocClassHint();          classhints = XAllocClassHint();
668          if (classhints != NULL)          if (classhints != NULL)
669          {          {
# Line 328  ui_create_window(char *title) Line 676  ui_create_window(char *title)
676          if (sizehints)          if (sizehints)
677          {          {
678                  sizehints->flags = PMinSize | PMaxSize;                  sizehints->flags = PMinSize | PMaxSize;
679                  sizehints->min_width = sizehints->max_width = width;                  sizehints->min_width = sizehints->max_width = g_width;
680                  sizehints->min_height = sizehints->max_height = height;                  sizehints->min_height = sizehints->max_height = g_height;
681                  XSetWMNormalHints(display, wnd, sizehints);                  XSetWMNormalHints(display, wnd, sizehints);
682                  XFree(sizehints);                  XFree(sizehints);
683          }          }
684    
685          xkeymap_init();          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
686                    VisibilityChangeMask | FocusChangeMask;
687    
688          input_mask = KeyPressMask | KeyReleaseMask |          if (g_sendmotion)
                          ButtonPressMask | ButtonReleaseMask |  
                          EnterWindowMask | LeaveWindowMask | KeymapStateMask;  
         if (sendmotion)  
689                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
   
690          if (ownbackstore)          if (ownbackstore)
691                  input_mask |= ExposureMask;                  input_mask |= ExposureMask;
692            if (g_fullscreen || grab_keyboard)
693                    input_mask |= EnterWindowMask;
694            if (grab_keyboard)
695                    input_mask |= LeaveWindowMask;
696    
697            if (IM != NULL)
698            {
699                    IC = XCreateIC(IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
700                                   XNClientWindow, wnd, XNFocusWindow, wnd, NULL);
701    
702                    if ((IC != NULL)
703                        && (XGetICValues(IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))
704                            input_mask |= ic_input_mask;
705            }
706    
707          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);  
   
708          XMapWindow(display, wnd);          XMapWindow(display, wnd);
709    
710          /* TODO: error texts... make them friendly. */          /* wait for VisibilityNotify */
711          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 )  
712          {          {
713                          error( "XkbSelectEvents failed.\n");                  XMaskEvent(display, VisibilityChangeMask, &xevent);
                         exit(0);  
714          }          }
715            while (xevent.type != VisibilityNotify);
716    
717            g_focused = False;
718            g_mouse_in_wnd = False;
719    
720            /* handle the WM_DELETE_WINDOW protocol */
721            protocol_atom = XInternAtom(display, "WM_PROTOCOLS", True);
722            kill_atom = XInternAtom(display, "WM_DELETE_WINDOW", True);
723            XSetWMProtocols(display, wnd, &kill_atom, 1);
724    
725          return True;          return True;
726  }  }
727    
728  void  void
729  ui_destroy_window()  ui_destroy_window(void)
730  {  {
731          if( xkb != NULL )          if (IC != NULL)
732                  XkbFreeKeyboard(xkb, XkbAllControlsMask, True);                  XDestroyIC(IC);
733    
         if (ownbackstore)  
                 XFreePixmap(display, backstore);  
   
         XFreeGC(display, gc);  
734          XDestroyWindow(display, wnd);          XDestroyWindow(display, wnd);
         XCloseDisplay(display);  
         display = NULL;  
735  }  }
736    
737  static void  void
738  xwin_process_events()  xwin_toggle_fullscreen(void)
739  {  {
740          XkbEvent xkbevent;          Pixmap contents = 0;
741            
742            if (!ownbackstore)
743            {
744                    /* need to save contents of window */
745                    contents = XCreatePixmap(display, wnd, g_width, g_height, depth);
746                    XCopyArea(display, wnd, contents, gc, 0, 0, g_width, g_height, 0, 0);
747            }
748    
749            ui_destroy_window();
750            g_fullscreen = !g_fullscreen;
751            ui_create_window();
752    
753            XDefineCursor(display, wnd, current_cursor);
754    
755            if (!ownbackstore)
756            {
757                    XCopyArea(display, contents, wnd, gc, 0, 0, g_width, g_height, 0, 0);
758                    XFreePixmap(display, contents);
759            }
760    }
761    
762    /* Process all events in Xlib queue
763       Returns 0 after user quit, 1 otherwise */
764    static int
765    xwin_process_events(void)
766    {
767            XEvent xevent;
768          KeySym keysym;          KeySym keysym;
         uint8 scancode;  
769          uint16 button, flags;          uint16 button, flags;
770          uint32 ev_time;          uint32 ev_time;
771          uint32 tmpmods;          key_translation tr;
772            char str[256];
773            Status status;
774            unsigned int state;
775            Window wdummy;
776            int dummy;
777    
778          while (XCheckMaskEvent(display, ~0, &xkbevent.core))          while (XPending(display) > 0)
779          {          {
780                  ev_time = time(NULL);                  XNextEvent(display, &xevent);
781    
782                    if ((IC != NULL) && (XFilterEvent(&xevent, None) == True))
783                    {
784                            DEBUG_KBD(("Filtering event\n"));
785                            continue;
786                    }
787    
788                  flags = 0;                  flags = 0;
789    
790                  switch (xkbevent.type)                  switch (xevent.type)
791                  {                  {
792                          case KeymapNotify:                          case ClientMessage:
793                                  /* TODO:                                  /* the window manager told us to quit */
794                                   * read modifier status at focus in, and update the local masks, and the other end as well..                                  if ((xevent.xclient.message_type == protocol_atom)
795                                   * if not, we may get out of sync.                                      && ((Atom) xevent.xclient.data.l[0] == kill_atom))
796                                   * xkbevent.core.xkeymap.key_vector                                          /* Quit */
797                                   * char key_vector[32];                                          return 0;
                                  */  
798                                  break;                                  break;
799    
                         case KeyRelease:  
                                 flags = KBD_FLAG_DOWN | KBD_FLAG_UP;  
                                 /* fall through */  
   
800                          case KeyPress:                          case KeyPress:
801                                  if( XkbTranslateKeyCode(xkb, xkbevent.core.xkey.keycode, xkbevent.core.xkey.state, &tmpmods, &keysym) == False )                                  last_gesturetime = xevent.xkey.time;
802                                    if (IC != NULL)
803                                            /* Multi_key compatible version */
804                                    {
805                                            XmbLookupString(IC,
806                                                            &xevent.xkey, str, sizeof(str), &keysym,
807                                                            &status);
808                                            if (!((status == XLookupKeySym) || (status == XLookupBoth)))
809                                            {
810                                                    error("XmbLookupString failed with status 0x%x\n",
811                                                          status);
812                                                    break;
813                                            }
814                                    }
815                                    else
816                                    {
817                                            /* Plain old XLookupString */
818                                            DEBUG_KBD(("\nNo input context, using XLookupString\n"));
819                                            XLookupString((XKeyEvent *) & xevent,
820                                                          str, sizeof(str), &keysym, NULL);
821                                    }
822    
823                                    DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,
824                                               get_ksname(keysym)));
825    
826                                    ev_time = time(NULL);
827                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
828                                          break;                                          break;
                                 scancode = xkeymap_translate_key(keysym, xkbevent.core.xkey.keycode, &flags);  
829    
830                                  if (scancode == 0 )                                  tr = xkeymap_translate_key(keysym,
831                                                               xevent.xkey.keycode, xevent.xkey.state);
832    
833                                    if (tr.scancode == 0)
834                                          break;                                          break;
835    
836                                  /* keep track of the modifiers -- needed for stickykeys... */                                  ensure_remote_modifiers(ev_time, tr);
837                                  if( xkbevent.type == KeyPress )  
838                                          xwin_press_modifiers( &xkbevent.core.xkey, ev_time, scancode );                                  rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
839                                    break;
840    
841                            case KeyRelease:
842                                    last_gesturetime = xevent.xkey.time;
843                                    XLookupString((XKeyEvent *) & xevent, str,
844                                                  sizeof(str), &keysym, NULL);
845    
846                                    DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
847                                               get_ksname(keysym)));
848    
849                                    ev_time = time(NULL);
850                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
851                                            break;
852    
853                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, flags, scancode, 0);                                  tr = xkeymap_translate_key(keysym,
854                                                               xevent.xkey.keycode, xevent.xkey.state);
855    
856                                  if( xkbevent.type == KeyRelease )                                  if (tr.scancode == 0)
857                                          xwin_release_modifiers( &xkbevent.core.xkey, ev_time, scancode );                                          break;
858    
859                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
860                                  break;                                  break;
861    
862                          case ButtonPress:                          case ButtonPress:
# Line 441  xwin_process_events() Line 864  xwin_process_events()
864                                  /* fall through */                                  /* fall through */
865    
866                          case ButtonRelease:                          case ButtonRelease:
867                                  button = xkeymap_translate_button(xkbevent.core.xbutton.button);                                  last_gesturetime = xevent.xbutton.time;
868                                    button = xkeymap_translate_button(xevent.xbutton.button);
869                                  if (button == 0)                                  if (button == 0)
870                                          break;                                          break;
871    
872                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  /* If win_button_size is nonzero, enable single app mode */
873                                                 flags | button,                                  if (xevent.xbutton.y < win_button_size)
874                                                 xkbevent.core.xbutton.x,                                  {
875                                                 xkbevent.core.xbutton.y);                                          /* Stop moving window when button is released, regardless of cursor position */
876                                            if (moving_wnd && (xevent.type == ButtonRelease))
877                                                    moving_wnd = False;
878    
879                                            /*  Check from right to left: */
880    
881                                            if (xevent.xbutton.x >= g_width - win_button_size)
882                                            {
883                                                    /* The close button, continue */
884                                                    ;
885                                            }
886                                            else if (xevent.xbutton.x >= g_width - win_button_size * 2)
887                                            {
888                                                    /* The maximize/restore button. Do not send to
889                                                       server.  It might be a good idea to change the
890                                                       cursor or give some other visible indication
891                                                       that rdesktop inhibited this click */
892                                                    break;
893                                            }
894                                            else if (xevent.xbutton.x >= g_width - win_button_size * 3)
895                                            {
896                                                    /* The minimize button. Iconify window. */
897                                                    XIconifyWindow(display, wnd,
898                                                                   DefaultScreen(display));
899                                                    break;
900                                            }
901                                            else if (xevent.xbutton.x <= win_button_size)
902                                            {
903                                                    /* The system menu. Ignore. */
904                                                    break;
905                                            }
906                                            else
907                                            {
908                                                    /* The title bar. */
909                                                    if ((xevent.type == ButtonPress) && !g_fullscreen
910                                                        && hide_decorations)
911                                                    {
912                                                            moving_wnd = True;
913                                                            move_x_offset = xevent.xbutton.x;
914                                                            move_y_offset = xevent.xbutton.y;
915                                                    }
916                                                    break;
917    
918                                            }
919                                    }
920    
921                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
922                                                   flags | button, xevent.xbutton.x, xevent.xbutton.y);
923                                  break;                                  break;
924    
925                          case MotionNotify:                          case MotionNotify:
926                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  if (moving_wnd)
927                                                 MOUSE_FLAG_MOVE,                                  {
928                                                 xkbevent.core.xmotion.x,                                          XMoveWindow(display, wnd,
929                                                 xkbevent.core.xmotion.y);                                                      xevent.xmotion.x_root - move_x_offset,
930                                                        xevent.xmotion.y_root - move_y_offset);
931                                            break;
932                                    }
933    
934                                    if (g_fullscreen && !g_focused)
935                                            XSetInputFocus(display, wnd, RevertToPointerRoot,
936                                                           CurrentTime);
937                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
938                                                   MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
939                                    break;
940    
941                            case FocusIn:
942                                    if (xevent.xfocus.mode == NotifyGrab)
943                                            break;
944                                    g_focused = True;
945                                    XQueryPointer(display, wnd, &wdummy, &wdummy, &dummy, &dummy,
946                                                  &dummy, &dummy, &state);
947                                    reset_modifier_keys(state);
948                                    if (grab_keyboard && g_mouse_in_wnd)
949                                            XGrabKeyboard(display, wnd, True,
950                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
951                                    break;
952    
953                            case FocusOut:
954                                    if (xevent.xfocus.mode == NotifyUngrab)
955                                            break;
956                                    g_focused = False;
957                                    if (xevent.xfocus.mode == NotifyWhileGrabbed)
958                                            XUngrabKeyboard(display, CurrentTime);
959                                  break;                                  break;
960    
961                          case EnterNotify:                          case EnterNotify:
962                                  XGrabKeyboard(display, wnd, True, GrabModeAsync,                                  /* we only register for this event when in fullscreen mode */
963                                                GrabModeAsync, CurrentTime);                                  /* or grab_keyboard */
964                                    g_mouse_in_wnd = True;
965                                    if (g_fullscreen)
966                                    {
967                                            XSetInputFocus(display, wnd, RevertToPointerRoot,
968                                                           CurrentTime);
969                                            break;
970                                    }
971                                    if (g_focused)
972                                            XGrabKeyboard(display, wnd, True,
973                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
974                                  break;                                  break;
975    
976                          case LeaveNotify:                          case LeaveNotify:
977                                    /* we only register for this event when grab_keyboard */
978                                    g_mouse_in_wnd = False;
979                                  XUngrabKeyboard(display, CurrentTime);                                  XUngrabKeyboard(display, CurrentTime);
980                                  break;                                  break;
981    
982                          case Expose:                          case Expose:
983                                  XCopyArea(display, backstore, wnd, gc,                                  XCopyArea(display, backstore, wnd, gc,
984                                            xkbevent.core.xexpose.x, xkbevent.core.xexpose.y,                                            xevent.xexpose.x, xevent.xexpose.y,
985                                            xkbevent.core.xexpose.width, xkbevent.core.xexpose.height,                                            xevent.xexpose.width,
986                                            xkbevent.core.xexpose.x, xkbevent.core.xexpose.y);                                            xevent.xexpose.height,
987                                              xevent.xexpose.x, xevent.xexpose.y);
988                                  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;  
         }  
989    
990          if( !(ShiftMask & ev->state) && (key_down_state & DShift1Mask))                          case MappingNotify:
991          {                                  /* Refresh keyboard mapping if it has changed. This is important for
992                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x2a, 0);                                     Xvnc, since it allocates keycodes dynamically */
993                  key_down_state &= ~DShift1Mask;                                  if (xevent.xmapping.request == MappingKeyboard
994                                        || xevent.xmapping.request == MappingModifier)
995          }                                          XRefreshKeyboardMapping(&xevent.xmapping);
   
         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;  
   
         }  
           
         if( !(Mod1Mask & ev->state) && (key_down_state & DMod1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x38, 0);  
                 key_down_state &= ~DMod1Mask;  
996    
997          }                                  if (xevent.xmapping.request == MappingModifier)
998                                            {
999          if( !(Mod2Mask & ev->state) && (key_down_state & DMod2Mask))                                          XFreeModifiermap(mod_map);
1000          {                                          mod_map = XGetModifierMapping(display);
1001                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0xb8, 0);                                  }
1002                  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;  
1003    
1004                                    /* clipboard stuff */
1005                            case SelectionNotify:
1006                                    xclip_handle_SelectionNotify(&xevent.xselection);
1007                                    break;
1008                            case SelectionRequest:
1009                                    xclip_handle_SelectionRequest(&xevent.xselectionrequest);
1010                                    break;
1011                            case SelectionClear:
1012                                    xclip_handle_SelectionClear();
1013                                    break;
1014                            case PropertyNotify:
1015                                    xclip_handle_PropertyNotify(&xevent.xproperty);
1016                                    break;
1017                    }
1018          }          }
1019            /* Keep going */
1020            return 1;
1021  }  }
1022    
1023  void  /* Returns 0 after user quit, 1 otherwise */
1024    int
1025  ui_select(int rdp_socket)  ui_select(int rdp_socket)
1026  {  {
1027          int n = (rdp_socket > x_socket) ? rdp_socket+1 : x_socket+1;          int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;
1028          fd_set rfds;          fd_set rfds;
1029    
1030          FD_ZERO(&rfds);          FD_ZERO(&rfds);
1031    
1032          while (True)          while (True)
1033          {          {
1034                    /* Process any events already waiting */
1035                    if (!xwin_process_events())
1036                            /* User quit */
1037                            return 0;
1038    
1039                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
1040                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
1041                  if (display != NULL)                  FD_SET(x_socket, &rfds);
                 {  
                         FD_SET(x_socket, &rfds);  
                         XFlush(display);  
                 }  
1042    
1043                  switch (select(n, &rfds, NULL, NULL, NULL))                  switch (select(n, &rfds, NULL, NULL, NULL))
1044                  {                  {
# Line 612  ui_select(int rdp_socket) Line 1049  ui_select(int rdp_socket)
1049                                  continue;                                  continue;
1050                  }                  }
1051    
                 if (FD_ISSET(x_socket, &rfds))  
                         xwin_process_events();  
   
1052                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
1053                          return;                          return 1;
1054          }          }
1055  }  }
1056    
# Line 627  ui_move_pointer(int x, int y) Line 1061  ui_move_pointer(int x, int y)
1061  }  }
1062    
1063  HBITMAP  HBITMAP
1064  ui_create_bitmap(int width, int height, uint8 *data)  ui_create_bitmap(int width, int height, uint8 * data)
1065  {  {
1066          XImage *image;          XImage *image;
1067          Pixmap bitmap;          Pixmap bitmap;
# Line 635  ui_create_bitmap(int width, int height, Line 1069  ui_create_bitmap(int width, int height,
1069    
1070          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
1071          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
1072          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1073                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, g_server_bpp == 8 ? 8 : bpp, 0);
1074    
1075          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
1076    
# Line 647  ui_create_bitmap(int width, int height, Line 1081  ui_create_bitmap(int width, int height,
1081  }  }
1082    
1083  void  void
1084  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)  
1085  {  {
1086          XImage *image;          XImage *image;
1087          uint8 *tdata;          uint8 *tdata;
   
1088          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
1089          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1090                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, g_server_bpp == 8 ? 8 : bpp, 0);
1091    
1092          if (ownbackstore)          if (ownbackstore)
1093          {          {
# Line 675  ui_paint_bitmap(int x, int y, int cx, in Line 1107  ui_paint_bitmap(int x, int y, int cx, in
1107  void  void
1108  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(HBITMAP bmp)
1109  {  {
1110          XFreePixmap(display, (Pixmap)bmp);          XFreePixmap(display, (Pixmap) bmp);
1111  }  }
1112    
1113  HGLYPH  HGLYPH
1114  ui_create_glyph(int width, int height, uint8 *data)  ui_create_glyph(int width, int height, uint8 * data)
1115  {  {
1116          XImage *image;          XImage *image;
1117          Pixmap bitmap;          Pixmap bitmap;
# Line 691  ui_create_glyph(int width, int height, u Line 1123  ui_create_glyph(int width, int height, u
1123          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(display, wnd, width, height, 1);
1124          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(display, bitmap, 0, NULL);
1125    
1126          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(display, visual, 1, ZPixmap, 0, (char *) data,
1127                               data, width, height, 8, scanline);                               width, height, 8, scanline);
1128          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
1129          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
1130          XInitImage(image);          XInitImage(image);
# Line 701  ui_create_glyph(int width, int height, u Line 1133  ui_create_glyph(int width, int height, u
1133    
1134          XFree(image);          XFree(image);
1135          XFreeGC(display, gc);          XFreeGC(display, gc);
1136          return (HGLYPH)bitmap;          return (HGLYPH) bitmap;
1137  }  }
1138    
1139  void  void
1140  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
1141  {  {
1142          XFreePixmap(display, (Pixmap)glyph);          XFreePixmap(display, (Pixmap) glyph);
1143  }  }
1144    
1145  HCURSOR  HCURSOR
1146  ui_create_cursor(unsigned int x, unsigned int y, int width,  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
1147                   int height, uint8 *andmask, uint8 *xormask)                   uint8 * andmask, uint8 * xormask)
1148  {  {
1149          HGLYPH maskglyph, cursorglyph;          HGLYPH maskglyph, cursorglyph;
1150          XColor bg, fg;          XColor bg, fg;
# Line 726  ui_create_cursor(unsigned int x, unsigne Line 1158  ui_create_cursor(unsigned int x, unsigne
1158          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1159          offset = scanline * height;          offset = scanline * height;
1160    
1161          cursor = xmalloc(offset);          cursor = (uint8 *) xmalloc(offset);
1162          memset(cursor, 0, offset);          memset(cursor, 0, offset);
1163    
1164          mask = xmalloc(offset);          mask = (uint8 *) xmalloc(offset);
1165          memset(mask, 0, offset);          memset(mask, 0, offset);
1166    
1167          /* approximate AND and XOR masks with a monochrome X pointer */          /* approximate AND and XOR masks with a monochrome X pointer */
# Line 769  ui_create_cursor(unsigned int x, unsigne Line 1201  ui_create_cursor(unsigned int x, unsigne
1201    
1202          cursorglyph = ui_create_glyph(width, height, cursor);          cursorglyph = ui_create_glyph(width, height, cursor);
1203          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
1204            
1205          xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,          xcursor =
1206                                  (Pixmap)maskglyph, &fg, &bg, x, y);                  XCreatePixmapCursor(display, (Pixmap) cursorglyph,
1207                                        (Pixmap) maskglyph, &fg, &bg, x, y);
1208    
1209          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
1210          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
1211          xfree(mask);          xfree(mask);
1212          xfree(cursor);          xfree(cursor);
1213          return (HCURSOR)xcursor;          return (HCURSOR) xcursor;
1214  }  }
1215    
1216  void  void
1217  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
1218  {  {
1219          XDefineCursor(display, wnd, (Cursor)cursor);          current_cursor = (Cursor) cursor;
1220            XDefineCursor(display, wnd, current_cursor);
1221  }  }
1222    
1223  void  void
1224  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_cursor(HCURSOR cursor)
1225  {  {
1226          XFreeCursor(display, (Cursor)cursor);          XFreeCursor(display, (Cursor) cursor);
1227  }  }
1228    
1229  #define MAKE_XCOLOR(xc,c) \  #define MAKE_XCOLOR(xc,c) \
# Line 798  ui_destroy_cursor(HCURSOR cursor) Line 1232  ui_destroy_cursor(HCURSOR cursor)
1232                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
1233                  (xc)->flags = DoRed | DoGreen | DoBlue;                  (xc)->flags = DoRed | DoGreen | DoBlue;
1234    
1235    
1236  HCOLOURMAP  HCOLOURMAP
1237  ui_create_colourmap(COLOURMAP *colours)  ui_create_colourmap(COLOURMAP * colours)
1238  {  {
1239          COLOURENTRY *entry;          COLOURENTRY *entry;
1240          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
1241            if (!owncolmap)
1242            {
1243                    uint32 *map = (uint32 *) xmalloc(sizeof(*colmap) * ncolours);
1244                    XColor xentry;
1245                    XColor xc_cache[256];
1246                    uint32 colour;
1247                    int colLookup = 256;
1248                    for (i = 0; i < ncolours; i++)
1249                    {
1250                            entry = &colours->colours[i];
1251                            MAKE_XCOLOR(&xentry, entry);
1252    
1253                            if (XAllocColor(display, xcolmap, &xentry) == 0)
1254                            {
1255                                    /* Allocation failed, find closest match. */
1256                                    int j = 256;
1257                                    int nMinDist = 3 * 256 * 256;
1258                                    long nDist = nMinDist;
1259    
1260                                    /* only get the colors once */
1261                                    while (colLookup--)
1262                                    {
1263                                            xc_cache[colLookup].pixel = colLookup;
1264                                            xc_cache[colLookup].red = xc_cache[colLookup].green =
1265                                                    xc_cache[colLookup].blue = 0;
1266                                            xc_cache[colLookup].flags = 0;
1267                                            XQueryColor(display,
1268                                                        DefaultColormap(display,
1269                                                                        DefaultScreen(display)),
1270                                                        &xc_cache[colLookup]);
1271                                    }
1272                                    colLookup = 0;
1273    
1274                                    /* approximate the pixel */
1275                                    while (j--)
1276                                    {
1277                                            if (xc_cache[j].flags)
1278                                            {
1279                                                    nDist = ((long) (xc_cache[j].red >> 8) -
1280                                                             (long) (xentry.red >> 8)) *
1281                                                            ((long) (xc_cache[j].red >> 8) -
1282                                                             (long) (xentry.red >> 8)) +
1283                                                            ((long) (xc_cache[j].green >> 8) -
1284                                                             (long) (xentry.green >> 8)) *
1285                                                            ((long) (xc_cache[j].green >> 8) -
1286                                                             (long) (xentry.green >> 8)) +
1287                                                            ((long) (xc_cache[j].blue >> 8) -
1288                                                             (long) (xentry.blue >> 8)) *
1289                                                            ((long) (xc_cache[j].blue >> 8) -
1290                                                             (long) (xentry.blue >> 8));
1291                                            }
1292                                            if (nDist < nMinDist)
1293                                            {
1294                                                    nMinDist = nDist;
1295                                                    xentry.pixel = j;
1296                                            }
1297                                    }
1298                            }
1299                            colour = xentry.pixel;
1300    
1301                            /* update our cache */
1302                            if (xentry.pixel < 256)
1303                            {
1304                                    xc_cache[xentry.pixel].red = xentry.red;
1305                                    xc_cache[xentry.pixel].green = xentry.green;
1306                                    xc_cache[xentry.pixel].blue = xentry.blue;
1307    
1308          if (owncolmap)                          }
1309    
1310    
1311                            /* byte swap here to make translate_image faster */
1312                            map[i] = translate_colour(colour);
1313                    }
1314                    return map;
1315            }
1316            else
1317          {          {
1318                  XColor *xcolours, *xentry;                  XColor *xcolours, *xentry;
1319                  Colormap map;                  Colormap map;
1320    
1321                  xcolours = xmalloc(sizeof(XColor) * ncolours);                  xcolours = (XColor *) xmalloc(sizeof(XColor) * ncolours);
1322                  for (i = 0; i < ncolours; i++)                  for (i = 0; i < ncolours; i++)
1323                  {                  {
1324                          entry = &colours->colours[i];                          entry = &colours->colours[i];
# Line 822  ui_create_colourmap(COLOURMAP *colours) Line 1331  ui_create_colourmap(COLOURMAP *colours)
1331                  XStoreColors(display, map, xcolours, ncolours);                  XStoreColors(display, map, xcolours, ncolours);
1332    
1333                  xfree(xcolours);                  xfree(xcolours);
1334                  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;  
1335          }          }
1336  }  }
1337    
1338  void  void
1339  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
1340  {  {
1341          if (owncolmap)          if (!owncolmap)
                 XFreeColormap(display, (Colormap)map);  
         else  
1342                  xfree(map);                  xfree(map);
1343            else
1344                    XFreeColormap(display, (Colormap) map);
1345  }  }
1346    
1347  void  void
1348  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
1349  {  {
1350          if (owncolmap)          if (!owncolmap)
1351                  XSetWindowColormap(display, wnd, (Colormap)map);          {
1352                    if (colmap)
1353                            xfree(colmap);
1354    
1355                    colmap = (uint32 *) map;
1356            }
1357          else          else
1358                  colmap = map;                  XSetWindowColormap(display, wnd, (Colormap) map);
1359  }  }
1360    
1361  void  void
# Line 879  ui_set_clip(int x, int y, int cx, int cy Line 1371  ui_set_clip(int x, int y, int cx, int cy
1371  }  }
1372    
1373  void  void
1374  ui_reset_clip()  ui_reset_clip(void)
1375  {  {
1376          XRectangle rect;          XRectangle rect;
1377    
1378          rect.x = 0;          rect.x = 0;
1379          rect.y = 0;          rect.y = 0;
1380          rect.width = width;          rect.width = g_width;
1381          rect.height = height;          rect.height = g_height;
1382          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
1383  }  }
1384    
1385  void  void
1386  ui_bell()  ui_bell(void)
1387  {  {
1388          XBell(display, 0);          XBell(display, 0);
1389  }  }
# Line 905  ui_destblt(uint8 opcode, Line 1397  ui_destblt(uint8 opcode,
1397          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1398  }  }
1399    
1400    static uint8 hatch_patterns[] = {
1401            0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0 - bsHorizontal */
1402            0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 1 - bsVertical */
1403            0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, /* 2 - bsFDiagonal */
1404            0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* 3 - bsBDiagonal */
1405            0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, /* 4 - bsCross */
1406            0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81  /* 5 - bsDiagCross */
1407    };
1408    
1409  void  void
1410  ui_patblt(uint8 opcode,  ui_patblt(uint8 opcode,
1411            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1412            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1413  {  {
1414          Pixmap fill;          Pixmap fill;
1415            uint8 i, ipattern[8];
1416    
1417          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1418    
# Line 921  ui_patblt(uint8 opcode, Line 1423  ui_patblt(uint8 opcode,
1423                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1424                          break;                          break;
1425    
1426                    case 2: /* Hatch */
1427                            fill = (Pixmap) ui_create_glyph(8, 8,
1428                                                            hatch_patterns + brush->pattern[0] * 8);
1429                            SET_FOREGROUND(bgcolour);
1430                            SET_BACKGROUND(fgcolour);
1431                            XSetFillStyle(display, gc, FillOpaqueStippled);
1432                            XSetStipple(display, gc, fill);
1433                            XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
1434                            FILL_RECTANGLE(x, y, cx, cy);
1435                            XSetFillStyle(display, gc, FillSolid);
1436                            XSetTSOrigin(display, gc, 0, 0);
1437                            ui_destroy_glyph((HGLYPH) fill);
1438                            break;
1439    
1440                  case 3: /* Pattern */                  case 3: /* Pattern */
1441                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);                          for (i = 0; i != 8; i++)
1442                                    ipattern[7 - i] = brush->pattern[i];
1443                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
1444    
1445                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(bgcolour);
1446                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
# Line 933  ui_patblt(uint8 opcode, Line 1451  ui_patblt(uint8 opcode,
1451                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1452    
1453                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
1454                          ui_destroy_glyph((HGLYPH)fill);                          XSetTSOrigin(display, gc, 0, 0);
1455                            ui_destroy_glyph((HGLYPH) fill);
1456                          break;                          break;
1457    
1458                  default:                  default:
# Line 951  ui_screenblt(uint8 opcode, Line 1470  ui_screenblt(uint8 opcode,
1470          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1471          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
1472          if (ownbackstore)          if (ownbackstore)
1473                  XCopyArea(display, backstore, backstore, gc, srcx, srcy,                  XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1474          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1475  }  }
1476    
# Line 962  ui_memblt(uint8 opcode, Line 1480  ui_memblt(uint8 opcode,
1480            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
1481  {  {
1482          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1483          XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
1484          if (ownbackstore)          if (ownbackstore)
1485                  XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1486          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1487  }  }
1488    
# Line 973  void Line 1490  void
1490  ui_triblt(uint8 opcode,  ui_triblt(uint8 opcode,
1491            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1492            /* src */ HBITMAP src, int srcx, int srcy,            /* src */ HBITMAP src, int srcx, int srcy,
1493            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1494  {  {
1495          /* This is potentially difficult to do in general. Until someone          /* This is potentially difficult to do in general. Until someone
1496             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 982  ui_triblt(uint8 opcode, Line 1499  ui_triblt(uint8 opcode,
1499          {          {
1500                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
1501                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1502                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1503                          break;                          break;
1504    
1505                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
1506                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1507                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1508                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1509                          break;                          break;
1510    
1511                  case 0xc0:      /* PSa */                  case 0xc0:      /* PSa */
1512                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1513                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
1514                          break;                          break;
1515    
1516                  default:                  default:
# Line 1009  ui_triblt(uint8 opcode, Line 1522  ui_triblt(uint8 opcode,
1522  void  void
1523  ui_line(uint8 opcode,  ui_line(uint8 opcode,
1524          /* dest */ int startx, int starty, int endx, int endy,          /* dest */ int startx, int starty, int endx, int endy,
1525          /* pen */ PEN *pen)          /* pen */ PEN * pen)
1526  {  {
1527          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1528          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
# Line 1028  ui_rect( Line 1541  ui_rect(
1541          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
1542  }  }
1543    
1544    /* warning, this function only draws on wnd or backstore, not both */
1545  void  void
1546  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1547                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1548                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1549                int fgcolour)                int bgcolour, int fgcolour)
1550  {  {
1551          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
1552          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
1553    
1554          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)          XSetFillStyle(display, gc,
1555                        ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1556          XSetStipple(display, gc, (Pixmap)glyph);          XSetStipple(display, gc, (Pixmap) glyph);
1557          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(display, gc, x, y);
1558    
1559          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
1560    
1561          XSetFillStyle(display, gc, FillSolid);          XSetFillStyle(display, gc, FillSolid);
1562  }  }
# Line 1056  ui_draw_glyph(int mixmode, Line 1570  ui_draw_glyph(int mixmode,
1570        if ((xyoffset & 0x80))\        if ((xyoffset & 0x80))\
1571          {\          {\
1572            if (flags & TEXT2_VERTICAL) \            if (flags & TEXT2_VERTICAL) \
1573              y += ttext[++idx] | (ttext[++idx] << 8);\              y += ttext[idx+1] | (ttext[idx+2] << 8);\
1574            else\            else\
1575              x += ttext[++idx] | (ttext[++idx] << 8);\              x += ttext[idx+1] | (ttext[idx+2] << 8);\
1576              idx += 2;\
1577          }\          }\
1578        else\        else\
1579          {\          {\
# Line 1070  ui_draw_glyph(int mixmode, Line 1585  ui_draw_glyph(int mixmode,
1585      }\      }\
1586    if (glyph != NULL)\    if (glyph != NULL)\
1587      {\      {\
1588        ui_draw_glyph (mixmode, x + (short) glyph->offset,\        ui_draw_glyph (mixmode, x + glyph->offset,\
1589                       y + (short) glyph->baseline,\                       y + glyph->baseline,\
1590                       glyph->width, glyph->height,\                       glyph->width, glyph->height,\
1591                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\
1592        if (flags & TEXT2_IMPLICIT_X)\        if (flags & TEXT2_IMPLICIT_X)\
# Line 1081  ui_draw_glyph(int mixmode, Line 1596  ui_draw_glyph(int mixmode,
1596    
1597  void  void
1598  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,
1599               int clipx, int clipy, int clipcx, int clipcy, int boxx,               int clipx, int clipy, int clipcx, int clipcy,
1600               int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1601               int fgcolour, uint8 * text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1602  {  {
1603          FONTGLYPH *glyph;          FONTGLYPH *glyph;
# Line 1093  ui_draw_text(uint8 font, uint8 flags, in Line 1608  ui_draw_text(uint8 font, uint8 flags, in
1608    
1609          if (boxcx > 1)          if (boxcx > 1)
1610          {          {
1611                  FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);
1612          }          }
1613          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
1614          {          {
1615                  FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
1616          }          }
1617    
1618          /* Paint text, character by character */          /* Paint text, character by character */
1619          for (i = 0; i < length;) {          for (i = 0; i < length;)
1620                  switch (text[i]) {          {
1621                  case 0xff:                  switch (text[i])
1622                          if (i + 2 < length)                  {
1623                                  cache_put_text(text[i + 1], text, text[i + 2]);                          case 0xff:
1624                          else {                                  if (i + 2 < length)
1625                                  error("this shouldn't be happening\n");                                          cache_put_text(text[i + 1], text, text[i + 2]);
1626                                    else
1627                                    {
1628                                            error("this shouldn't be happening\n");
1629                                            exit(1);
1630                                    }
1631                                    /* this will move pointer from start to first character after FF command */
1632                                    length -= i + 3;
1633                                    text = &(text[i + 3]);
1634                                    i = 0;
1635                                  break;                                  break;
                         }  
                         /* this will move pointer from start to first character after FF command */  
                         length -= i + 3;  
                         text = &(text[i + 3]);  
                         i = 0;  
                         break;  
1636    
1637                  case 0xfe:                          case 0xfe:
1638                          entry = cache_get_text(text[i + 1]);                                  entry = cache_get_text(text[i + 1]);
1639                          if (entry != NULL) {                                  if (entry != NULL)
1640                                  if ((((uint8 *) (entry->data))[1] == 0)                                  {
1641                                      && (!(flags & TEXT2_IMPLICIT_X))) {                                          if ((((uint8 *) (entry->data))[1] ==
1642                                          if (flags & TEXT2_VERTICAL)                                               0) && (!(flags & TEXT2_IMPLICIT_X)))
1643                                                  y += text[i + 2];                                          {
1644                                          else                                                  if (flags & TEXT2_VERTICAL)
1645                                                  x += text[i + 2];                                                          y += text[i + 2];
1646                                                    else
1647                                                            x += text[i + 2];
1648                                            }
1649                                            for (j = 0; j < entry->size; j++)
1650                                                    DO_GLYPH(((uint8 *) (entry->data)), j);
1651                                  }                                  }
1652                                  if (i + 2 < length)                                  if (i + 2 < length)
1653                                          i += 3;                                          i += 3;
1654                                  else                                  else
1655                                          i += 2;                                          i += 2;
1656                                  length -= i;                                  length -= i;
1657                                  /* this will move pointer from start to first character after FE command */                                  /* this will move pointer from start to first character after FE command */
1658                                  text = &(text[i]);                                  text = &(text[i]);
1659                                  i = 0;                                  i = 0;
1660                                  for (j = 0; j < entry->size; j++)                                  break;
                                         DO_GLYPH(((uint8 *) (entry->data)), j);  
                         }  
                         break;  
1661    
1662                  default:                          default:
1663                          DO_GLYPH(text, i);                                  DO_GLYPH(text, i);
1664                          i++;                                  i++;
1665                          break;                                  break;
1666                  }                  }
1667          }          }
1668            if (ownbackstore)
1669            {
1670                    if (boxcx > 1)
1671                            XCopyArea(display, backstore, wnd, gc, boxx,
1672                                      boxy, boxcx, boxcy, boxx, boxy);
1673                    else
1674                            XCopyArea(display, backstore, wnd, gc, clipx,
1675                                      clipy, clipcx, clipcy, clipx, clipy);
1676            }
1677  }  }
1678    
1679  void  void
# Line 1157  ui_desktop_save(uint32 offset, int x, in Line 1684  ui_desktop_save(uint32 offset, int x, in
1684    
1685          if (ownbackstore)          if (ownbackstore)
1686          {          {
1687                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1688          }          }
1689          else          else
1690          {          {
1691                  pix = XCreatePixmap(display, wnd, cx, cy, depth);                  pix = XCreatePixmap(display, wnd, cx, cy, depth);
1692                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
1693                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1694                  XFreePixmap(display, pix);                  XFreePixmap(display, pix);
1695          }          }
1696    
1697          offset *= bpp/8;          offset *= bpp / 8;
1698          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);  
1699    
1700          XDestroyImage(image);          XDestroyImage(image);
1701  }  }
# Line 1182  ui_desktop_restore(uint32 offset, int x, Line 1706  ui_desktop_restore(uint32 offset, int x,
1706          XImage *image;          XImage *image;
1707          uint8 *data;          uint8 *data;
1708    
1709          offset *= bpp/8;          offset *= bpp / 8;
1710          data = cache_get_desktop(offset, cx, cy, bpp/8);          data = cache_get_desktop(offset, cx, cy, bpp / 8);
1711          if (data == NULL)          if (data == NULL)
1712                  return;                  return;
1713    
1714          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1715                               0, data, cx, cy, BitmapPad(display),                               (char *) data, cx, cy, BitmapPad(display), cx * bpp / 8);
                              cx * bpp/8);  
1716    
1717          if (ownbackstore)          if (ownbackstore)
1718          {          {

Legend:
Removed from v.53  
changed lines
  Added in v.448

  ViewVC Help
Powered by ViewVC 1.1.26