/[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 64 by astrand, Thu Jul 18 16:38:31 2002 UTC revision 449 by astrand, Wed Aug 27 09:42:55 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 numlock_modifier_mask = 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    
69  #define DShift1Mask   (1<<0)  /* MWM decorations */
70  #define DLockMask     (1<<1)  #define MWM_HINTS_DECORATIONS   (1L << 1)
71  #define DControl1Mask (1<<2)  #define PROP_MOTIF_WM_HINTS_ELEMENTS    5
72  #define DMod1Mask     (1<<3)  typedef struct
73  #define DMod2Mask     (1<<4)  {
74  #define DMod3Mask     (1<<5)          uint32 flags;
75  #define DMod4Mask     (1<<6)          uint32 functions;
76  #define DMod5Mask     (1<<7)          uint32 decorations;
77  #define DShift2Mask   (1<<8)          sint32 inputMode;
78  #define DControl2Mask (1<<9)          uint32 status;
79  #define DNumLockMask  (1<<10)  }
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 73  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 105  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_get_numlock_mask();  static void
135  void xwin_mod_update(uint32 state, uint32 ev_time);  mwm_hide_decorations(void)
136  void xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode);  {
137  void xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode);          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++)];
# Line 126  translate16(uint8 * data, uint16 * out, Line 298  translate16(uint8 * data, uint16 * out,
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 140  translate24(uint8 * data, uint8 * out, u Line 312  translate24(uint8 * data, uint8 * out, u
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 ?? */
322  translate_image(int width, int height, uint8 * data)  
323    static void
324    translate15to16(uint16 * data, uint16 * out, uint16 * end)
325  {  {
326          int size = width * height * bpp / 8;          while (out < end)
327          uint8 *out = xmalloc(size);                  *(out++) = (uint16) make_colour16(split_colour15(*(data++)));
328          uint8 *end = out + size;  }
329    
330          switch (bpp)  static void
331    translate15to24(uint16 * data, uint8 * out, uint8 * end)
332    {
333            uint32 value;
334    
335            while (out < end)
336          {          {
337                  case 8:                  value = make_colour24(split_colour15(*(data++)));
338                          translate8(data, out, end);                  *(out++) = value;
339                          break;                  *(out++) = value >> 8;
340                    *(out++) = value >> 16;
341            }
342    }
343    
344                  case 16:  static void
345                          translate16(data, (uint16 *) out, (uint16 *) end);  translate15to32(uint16 * data, uint32 * out, uint32 * end)
346                          break;  {
347            while (out < end)
348                    *(out++) = make_colour32(split_colour15(*(data++)));
349    }
350    
351                  case 24:  static void
352                          translate24(data, out, end);  translate16to16(uint16 * data, uint16 * out, uint16 * end)
353                          break;  {
354            while (out < end)
355                    *(out++) = (uint16) (*(data++));
356    }
357    
358                  case 32:  
359                          translate32(data, (uint32 *) out, (uint32 *) end);  static void
360                          break;  translate16to24(uint16 * data, uint8 * out, uint8 * end)
361    {
362            uint32 value;
363    
364            while (out < end)
365            {
366                    value = make_colour24(split_colour16(*(data++)));
367                    *(out++) = value;
368                    *(out++) = value >> 8;
369                    *(out++) = value >> 16;
370          }          }
371    }
372    
373          return out;  static void
374    translate16to32(uint16 * data, uint32 * out, uint32 * end)
375    {
376            while (out < end)
377                    *(out++) = make_colour32(split_colour16(*(data++)));
378  }  }
379    
380  #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }  static void
381  #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }  translate24to16(uint8 * data, uint16 * out, uint16 * end)
382  #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \  {
383                          x = (x << 16) | (x >> 16); }          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  static uint32  static void
394  translate_colour(uint32 colour)  translate24to24(uint8 * data, uint8 * out, uint8 * end)
395  {  {
396          switch (bpp)          while (out < end)
397          {          {
398                  case 16:                  *(out++) = (*(data++));
399                          if (host_be != xserver_be)          }
400                                  BSWAP16(colour);  }
                         break;  
401    
402    static void
403    translate24to32(uint8 * data, uint32 * out, uint32 * end)
404    {
405            uint32 pixel = 0;
406            while (out < end)
407            {
408                    pixel = *(data++);
409                    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            switch (g_server_bpp)
423            {
424                  case 24:                  case 24:
425                          if (xserver_be)                          switch (bpp)
426                                  BSWAP24(colour);                          {
427                                    case 32:
428                                            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 16:
439                  case 32:                          switch (bpp)
440                          if (host_be != xserver_be)                          {
441                                  BSWAP32(colour);                                  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;
454                    case 15:
455                            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;
470                    case 8:
471                            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;
         return colour;  
489  }  }
490    
491  BOOL  BOOL
492  ui_create_window(char *title)  get_key_state(unsigned int state, uint32 keysym)
493  {  {
494          XSetWindowAttributes attribs;          int modifierpos, key, keysymMask = 0;
495          XClassHint *classhints;          int offset;
         XSizeHints *sizehints;  
         unsigned long input_mask;  
         XPixmapFormatValues *pfm;  
         Screen *screen;  
         uint16 test;  
         int i;  
496    
497          int xkb_minor, xkb_major;          KeyCode keycode = XKeysymToKeycode(display, keysym);
         int xkb_event, xkb_error, xkb_reason;  
498    
499          /* compare compiletime libs with runtime libs. */          if (keycode == NoSymbol)
         xkb_major = XkbMajorVersion;  
         xkb_minor = XkbMinorVersion;  
         if (XkbLibraryVersion(&xkb_major, &xkb_minor) == False)  
         {  
                 error("please re-compile rdesktop\ncompile time version of xkb is not compatible with\nyour runtime version of the library\n");  
500                  return False;                  return False;
         }  
   
501    
502          display =          for (modifierpos = 0; modifierpos < 8; modifierpos++)
                 XkbOpenDisplay(NULL, &xkb_event, &xkb_error, &xkb_major,  
                                &xkb_minor, &xkb_reason);  
         switch (xkb_reason)  
503          {          {
504                  case XkbOD_BadLibraryVersion:                  offset = mod_map->max_keypermod * modifierpos;
505                          error("XkbOD_BadLibraryVersion: XKB extensions in server and the library rdesktop is linked against aren't compatible with each other.\n");  
506                          break;                  for (key = 0; key < mod_map->max_keypermod; key++)
507                  case XkbOD_ConnectionRefused:                  {
508                          error("XkbOD_ConnectionRefused\n");                          if (mod_map->modifiermap[offset + key] == keycode)
509                          break;                                  keysymMask |= 1 << modifierpos;
510                  case XkbOD_BadServerVersion:                  }
                         error("XkbOD_BadServerVersion\n");  
                         break;  
                 case XkbOD_NonXkbServer:  
                         error("XkbOD_NonXkbServer: XKB extension not present in server\nupdate your X server.\n");  
                         break;  
                 case XkbOD_Success:  
                         DEBUG("XkbOD_Success: Connection established with display\n");  
                         break;  
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 269  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 285  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 334  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;  
         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)  
712          {          {
713                  error("XkbGetKeyboard failed.\n");                  XMaskEvent(display, VisibilityChangeMask, &xevent);
                 exit(0);  
714          }          }
715            while (xevent.type != VisibilityNotify);
716    
717          /* TODO: error texts... make them friendly. */          g_focused = False;
718          if (XkbSelectEvents          g_mouse_in_wnd = False;
             (display, xkb->device_spec, XkbAllEventsMask,  
              XkbAllEventsMask) == False)  
         {  
                 error("XkbSelectEvents failed.\n");  
                 exit(0);  
         }  
719    
720          xwin_get_numlock_mask();          /* 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  xwin_get_numlock_mask()  ui_destroy_window(void)
730  {  {
731          KeyCode numlockcode;          if (IC != NULL)
732          KeyCode *keycode;                  XDestroyIC(IC);
         XModifierKeymap *modmap;  
         int i, j;  
   
         /* Find out if numlock is already defined as a modifier key, and if so where */  
         numlockcode = XKeysymToKeycode(display, 0xFF7F);        /* XF_Num_Lock = 0xFF7F */  
         if (numlockcode)  
         {  
                 modmap = XGetModifierMapping(display);  
                 if (modmap)  
                 {  
                         keycode = modmap->modifiermap;  
                         for (i = 0; i < 8; i++)  
                                 for (j = modmap->max_keypermod; j--;)  
                                 {  
                                         if (*keycode == numlockcode)  
                                         {  
                                                 numlock_modifier_mask =  
                                                         (1 << i);  
                                                 i = 8;  
                                                 break;  
                                         }  
                                         keycode++;  
                                 }  
                         if (!numlock_modifier_mask)  
                         {  
                                 modmap->modifiermap[7 *  
                                                     modmap->max_keypermod] =  
                                         numlockcode;  
                                 if (XSetModifierMapping(display, modmap) ==  
                                     MappingSuccess)  
                                         numlock_modifier_mask = (1 << 7);  
                                 else  
                                         printf("XSetModifierMapping failed!\n");  
                         }  
                         XFreeModifiermap(modmap);  
                 }  
         }  
   
         if (!numlock_modifier_mask)  
                 printf("WARNING: Failed to get a numlock modifier mapping.\n");  
733    
734            XDestroyWindow(display, wnd);
735  }  }
736    
737  void  void
738  ui_destroy_window()  xwin_toggle_fullscreen(void)
739  {  {
740          if (xkb != NULL)          Pixmap contents = 0;
                 XkbFreeKeyboard(xkb, XkbAllControlsMask, True);  
741    
742          if (ownbackstore)          if (!ownbackstore)
743                  XFreePixmap(display, backstore);          {
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          XFreeGC(display, gc);          ui_destroy_window();
750          XDestroyWindow(display, wnd);          g_fullscreen = !g_fullscreen;
751          XCloseDisplay(display);          ui_create_window();
752          display = NULL;  
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  static void  /* Process all events in Xlib queue
763  xwin_process_events()     Returns 0 after user quit, 1 otherwise */
764    static int
765    xwin_process_events(void)
766  {  {
767          XEvent xevent;          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, &xevent))          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 (xevent.type)                  switch (xevent.type)
791                  {                  {
792                          case KeyRelease:                          case ClientMessage:
793                                  flags = KBD_FLAG_DOWN | KBD_FLAG_UP;                                  /* the window manager told us to quit */
794                                  /* fall through */                                  if ((xevent.xclient.message_type == protocol_atom)
795                                        && ((Atom) xevent.xclient.data.l[0] == kill_atom))
796                                            /* Quit */
797                                            return 0;
798                                    break;
799    
800                          case KeyPress:                          case KeyPress:
801                                  if (XkbTranslateKeyCode                                  last_gesturetime = xevent.xkey.time;
802                                      (xkb, xevent.xkey.keycode,                                  if (IC != NULL)
803                                       xevent.xkey.state, &tmpmods,                                          /* Multi_key compatible version */
804                                       &keysym) == False)                                  {
805                                          break;                                          XmbLookupString(IC,
806                                  scancode =                                                          &xevent.xkey, str, sizeof(str), &keysym,
807                                          xkeymap_translate_key(keysym,                                                          &status);
808                                                                xevent.xkey.                                          if (!((status == XLookupKeySym) || (status == XLookupBoth)))
809                                                                keycode,                                          {
810                                                                &flags);                                                  error("XmbLookupString failed with status 0x%x\n",
811                                                          status);
812                                  if (scancode == 0)                                                  break;
813                                          break;                                          }
814                                    }
815                                  /* keep track of the modifiers -- needed for stickykeys... */                                  else
816                                  if (xevent.type == KeyPress)                                  {
817                                          xwin_mod_press(xevent.xkey.state,                                          /* Plain old XLookupString */
818                                                         ev_time, scancode);                                          DEBUG_KBD(("\nNo input context, using XLookupString\n"));
819                                            XLookupString((XKeyEvent *) & xevent,
820                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE,                                                        str, sizeof(str), &keysym, NULL);
821                                                 flags, scancode, 0);                                  }
822    
823                                  if (xevent.type == KeyRelease)                                  DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,
824                                          xwin_mod_release(xevent.xkey.state,                                             get_ksname(keysym)));
825                                                           ev_time, scancode);  
826                                    ev_time = time(NULL);
827                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
828                                            break;
829    
830                                    tr = xkeymap_translate_key(keysym,
831                                                               xevent.xkey.keycode, xevent.xkey.state);
832    
833                                    if (tr.scancode == 0)
834                                            break;
835    
836                                    save_remote_modifiers();
837                                    ensure_remote_modifiers(ev_time, tr);
838                                    rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
839                                    restore_remote_modifiers();
840    
841                                  break;                                  break;
842    
843                            case KeyRelease:
844                                    last_gesturetime = xevent.xkey.time;
845                                    XLookupString((XKeyEvent *) & xevent, str,
846                                                  sizeof(str), &keysym, NULL);
847    
848                                    DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
849                                               get_ksname(keysym)));
850    
851                                    ev_time = time(NULL);
852                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
853                                            break;
854    
855                                    tr = xkeymap_translate_key(keysym,
856                                                               xevent.xkey.keycode, xevent.xkey.state);
857    
858                                    if (tr.scancode == 0)
859                                            break;
860    
861                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
862                                    break;
863    
864                          case ButtonPress:                          case ButtonPress:
865                                  flags = MOUSE_FLAG_DOWN;                                  flags = MOUSE_FLAG_DOWN;
866                                  /* fall through */                                  /* fall through */
867    
868                          case ButtonRelease:                          case ButtonRelease:
869                                  button = xkeymap_translate_button(xevent.                                  last_gesturetime = xevent.xbutton.time;
870                                                                    xbutton.                                  button = xkeymap_translate_button(xevent.xbutton.button);
                                                                   button);  
871                                  if (button == 0)                                  if (button == 0)
872                                          break;                                          break;
873    
874                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  /* If win_button_size is nonzero, enable single app mode */
875                                                 flags | button,                                  if (xevent.xbutton.y < win_button_size)
876                                                 xevent.xbutton.x,                                  {
877                                                 xevent.xbutton.y);                                          /* Stop moving window when button is released, regardless of cursor position */
878                                            if (moving_wnd && (xevent.type == ButtonRelease))
879                                                    moving_wnd = False;
880    
881                                            /*  Check from right to left: */
882    
883                                            if (xevent.xbutton.x >= g_width - win_button_size)
884                                            {
885                                                    /* The close button, continue */
886                                                    ;
887                                            }
888                                            else if (xevent.xbutton.x >= g_width - win_button_size * 2)
889                                            {
890                                                    /* The maximize/restore button. Do not send to
891                                                       server.  It might be a good idea to change the
892                                                       cursor or give some other visible indication
893                                                       that rdesktop inhibited this click */
894                                                    break;
895                                            }
896                                            else if (xevent.xbutton.x >= g_width - win_button_size * 3)
897                                            {
898                                                    /* The minimize button. Iconify window. */
899                                                    XIconifyWindow(display, wnd,
900                                                                   DefaultScreen(display));
901                                                    break;
902                                            }
903                                            else if (xevent.xbutton.x <= win_button_size)
904                                            {
905                                                    /* The system menu. Ignore. */
906                                                    break;
907                                            }
908                                            else
909                                            {
910                                                    /* The title bar. */
911                                                    if ((xevent.type == ButtonPress) && !g_fullscreen
912                                                        && hide_decorations)
913                                                    {
914                                                            moving_wnd = True;
915                                                            move_x_offset = xevent.xbutton.x;
916                                                            move_y_offset = xevent.xbutton.y;
917                                                    }
918                                                    break;
919    
920                                            }
921                                    }
922    
923                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
924                                                   flags | button, xevent.xbutton.x, xevent.xbutton.y);
925                                  break;                                  break;
926    
927                          case MotionNotify:                          case MotionNotify:
928                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  if (moving_wnd)
929                                                 MOUSE_FLAG_MOVE,                                  {
930                                                 xevent.xmotion.x,                                          XMoveWindow(display, wnd,
931                                                 xevent.xmotion.y);                                                      xevent.xmotion.x_root - move_x_offset,
932                                                        xevent.xmotion.y_root - move_y_offset);
933                                            break;
934                                    }
935    
936                                    if (g_fullscreen && !g_focused)
937                                            XSetInputFocus(display, wnd, RevertToPointerRoot,
938                                                           CurrentTime);
939                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
940                                                   MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
941                                  break;                                  break;
942    
943                          case EnterNotify:                          case FocusIn:
944                                  XGrabKeyboard(display, wnd, True,                                  if (xevent.xfocus.mode == NotifyGrab)
945                                                GrabModeAsync, GrabModeAsync,                                          break;
946                                                CurrentTime);                                  g_focused = True;
947                                    XQueryPointer(display, wnd, &wdummy, &wdummy, &dummy, &dummy,
948                                                  &dummy, &dummy, &state);
949                                    reset_modifier_keys(state);
950                                    if (grab_keyboard && g_mouse_in_wnd)
951                                            XGrabKeyboard(display, wnd, True,
952                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
953                                    break;
954    
955                                  xwin_mod_update(xevent.xcrossing.state,                          case FocusOut:
956                                                  ev_time);                                  if (xevent.xfocus.mode == NotifyUngrab)
957                                            break;
958                                    g_focused = False;
959                                    if (xevent.xfocus.mode == NotifyWhileGrabbed)
960                                            XUngrabKeyboard(display, CurrentTime);
961                                    break;
962    
963                            case EnterNotify:
964                                    /* we only register for this event when in fullscreen mode */
965                                    /* or grab_keyboard */
966                                    g_mouse_in_wnd = True;
967                                    if (g_fullscreen)
968                                    {
969                                            XSetInputFocus(display, wnd, RevertToPointerRoot,
970                                                           CurrentTime);
971                                            break;
972                                    }
973                                    if (g_focused)
974                                            XGrabKeyboard(display, wnd, True,
975                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
976                                  break;                                  break;
977    
978                          case LeaveNotify:                          case LeaveNotify:
979                                    /* we only register for this event when grab_keyboard */
980                                    g_mouse_in_wnd = False;
981                                  XUngrabKeyboard(display, CurrentTime);                                  XUngrabKeyboard(display, CurrentTime);
982                                  break;                                  break;
983    
# Line 538  xwin_process_events() Line 988  xwin_process_events()
988                                            xevent.xexpose.height,                                            xevent.xexpose.height,
989                                            xevent.xexpose.x, xevent.xexpose.y);                                            xevent.xexpose.x, xevent.xexpose.y);
990                                  break;                                  break;
                 }  
         }  
 }  
   
 void  
 xwin_mod_update(uint32 state, uint32 ev_time)  
 {  
         xwin_mod_press(state, ev_time, 0);  
         xwin_mod_release(state, ev_time, 0);  
 }  
   
 void  
 xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode)  
 {  
         switch (scancode)  
         {  
                 case 0x2a:  
                         key_down_state &= ~DShift1Mask;  
                         break;  
                 case 0x36:  
                         key_down_state &= ~DShift2Mask;  
                         break;  
                 case 0x1d:  
                         key_down_state &= ~DControl1Mask;  
                         break;  
                 case 0x9d:  
                         key_down_state &= ~DControl2Mask;  
                         break;  
                 case 0x38:  
                         key_down_state &= ~DMod1Mask;  
                         break;  
                 case 0xb8:  
                         key_down_state &= ~DMod2Mask;  
                         break;  
         }  
   
         if (!(numlock_modifier_mask & state)  
             && (key_down_state & DNumLockMask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0);  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,  
                                KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0);  
                 key_down_state &= ~DNumLockMask;  
         }  
   
         if (!(LockMask & state) && (key_down_state & DLockMask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,  
                                KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);  
                 key_down_state &= ~DLockMask;  
   
         }  
   
   
         if (!(ShiftMask & state) && (key_down_state & DShift1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x2a,  
                                0);  
                 key_down_state &= ~DShift1Mask;  
   
         }  
   
         if (!(ControlMask & state) && (key_down_state & DControl1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x1d,  
                                0);  
                 key_down_state &= ~DControl1Mask;  
   
         }  
   
         if (!(Mod1Mask & state) && (key_down_state & DMod1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x38,  
                                0);  
                 key_down_state &= ~DMod1Mask;  
991    
992          }                          case MappingNotify:
993                                    /* Refresh keyboard mapping if it has changed. This is important for
994          if (!(Mod2Mask & state) && (key_down_state & DMod2Mask))                                     Xvnc, since it allocates keycodes dynamically */
995          {                                  if (xevent.xmapping.request == MappingKeyboard
996                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0xb8,                                      || xevent.xmapping.request == MappingModifier)
997                                 0);                                          XRefreshKeyboardMapping(&xevent.xmapping);
                 key_down_state &= ~DMod2Mask;  
         }  
 }  
   
   
 void  
 xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode)  
 {  
998    
999          switch (scancode)                                  if (xevent.xmapping.request == MappingModifier)
1000          {                                  {
1001                  case 0x2a:                                          XFreeModifiermap(mod_map);
1002                          key_down_state |= DShift1Mask;                                          mod_map = XGetModifierMapping(display);
1003                          break;                                  }
1004                  case 0x36:                                  break;
                         key_down_state |= DShift2Mask;  
                         break;  
                 case 0x1d:  
                         key_down_state |= DControl1Mask;  
                         break;  
                 case 0x9d:  
                         key_down_state |= DControl2Mask;  
                         break;  
                 case 0x3a:  
                         key_down_state ^= DLockMask;  
                         break;  
                 case 0x45:  
                         key_down_state ^= DNumLockMask;  
                         break;  
                 case 0x38:  
                         key_down_state |= DMod1Mask;  
                         break;  
                 case 0xb8:  
                         key_down_state |= DMod2Mask;  
                         break;  
         }  
   
         if ((numlock_modifier_mask && state)  
             && !(key_down_state & DNumLockMask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0);  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,  
                                KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0);  
                 key_down_state |= DNumLockMask;  
         }  
   
         if ((LockMask & state) && !(key_down_state & DLockMask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,  
                                KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);  
                 key_down_state |= DLockMask;  
   
         }  
   
   
         if ((ShiftMask & 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 & 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 & state) && !(key_down_state & DMod1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,  
                                0x38, 0);  
                 key_down_state |= DMod1Mask;  
   
         }  
   
         if ((Mod2Mask & state) && !(key_down_state & DMod2Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,  
                                0xb8, 0);  
                 key_down_state |= DMod2Mask;  
1005    
1006                                    /* clipboard stuff */
1007                            case SelectionNotify:
1008                                    xclip_handle_SelectionNotify(&xevent.xselection);
1009                                    break;
1010                            case SelectionRequest:
1011                                    xclip_handle_SelectionRequest(&xevent.xselectionrequest);
1012                                    break;
1013                            case SelectionClear:
1014                                    xclip_handle_SelectionClear();
1015                                    break;
1016                            case PropertyNotify:
1017                                    xclip_handle_PropertyNotify(&xevent.xproperty);
1018                                    break;
1019                    }
1020          }          }
1021            /* Keep going */
1022            return 1;
1023  }  }
1024    
1025  void  /* Returns 0 after user quit, 1 otherwise */
1026    int
1027  ui_select(int rdp_socket)  ui_select(int rdp_socket)
1028  {  {
1029          int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;          int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;
# Line 724  ui_select(int rdp_socket) Line 1033  ui_select(int rdp_socket)
1033    
1034          while (True)          while (True)
1035          {          {
1036                    /* Process any events already waiting */
1037                    if (!xwin_process_events())
1038                            /* User quit */
1039                            return 0;
1040    
1041                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
1042                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
1043                  if (display != NULL)                  FD_SET(x_socket, &rfds);
                 {  
                         FD_SET(x_socket, &rfds);  
                         XFlush(display);  
                 }  
1044    
1045                  switch (select(n, &rfds, NULL, NULL, NULL))                  switch (select(n, &rfds, NULL, NULL, NULL))
1046                  {                  {
# Line 741  ui_select(int rdp_socket) Line 1051  ui_select(int rdp_socket)
1051                                  continue;                                  continue;
1052                  }                  }
1053    
                 if (FD_ISSET(x_socket, &rfds))  
                         xwin_process_events();  
   
1054                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
1055                          return;                          return 1;
1056          }          }
1057  }  }
1058    
# Line 764  ui_create_bitmap(int width, int height, Line 1071  ui_create_bitmap(int width, int height,
1071    
1072          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
1073          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
1074          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1075                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, g_server_bpp == 8 ? 8 : bpp, 0);
1076    
1077          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
1078    
# Line 776  ui_create_bitmap(int width, int height, Line 1083  ui_create_bitmap(int width, int height,
1083  }  }
1084    
1085  void  void
1086  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)  
1087  {  {
1088          XImage *image;          XImage *image;
1089          uint8 *tdata;          uint8 *tdata;
   
1090          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
1091          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1092                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, g_server_bpp == 8 ? 8 : bpp, 0);
1093    
1094          if (ownbackstore)          if (ownbackstore)
1095          {          {
# Line 820  ui_create_glyph(int width, int height, u Line 1125  ui_create_glyph(int width, int height, u
1125          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(display, wnd, width, height, 1);
1126          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(display, bitmap, 0, NULL);
1127    
1128          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(display, visual, 1, ZPixmap, 0, (char *) data,
1129                               data, width, height, 8, scanline);                               width, height, 8, scanline);
1130          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
1131          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
1132          XInitImage(image);          XInitImage(image);
# Line 840  ui_destroy_glyph(HGLYPH glyph) Line 1145  ui_destroy_glyph(HGLYPH glyph)
1145  }  }
1146    
1147  HCURSOR  HCURSOR
1148  ui_create_cursor(unsigned int x, unsigned int y, int width,  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
1149                   int height, uint8 * andmask, uint8 * xormask)                   uint8 * andmask, uint8 * xormask)
1150  {  {
1151          HGLYPH maskglyph, cursorglyph;          HGLYPH maskglyph, cursorglyph;
1152          XColor bg, fg;          XColor bg, fg;
# Line 855  ui_create_cursor(unsigned int x, unsigne Line 1160  ui_create_cursor(unsigned int x, unsigne
1160          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1161          offset = scanline * height;          offset = scanline * height;
1162    
1163          cursor = xmalloc(offset);          cursor = (uint8 *) xmalloc(offset);
1164          memset(cursor, 0, offset);          memset(cursor, 0, offset);
1165    
1166          mask = xmalloc(offset);          mask = (uint8 *) xmalloc(offset);
1167          memset(mask, 0, offset);          memset(mask, 0, offset);
1168    
1169          /* approximate AND and XOR masks with a monochrome X pointer */          /* approximate AND and XOR masks with a monochrome X pointer */
# Line 899  ui_create_cursor(unsigned int x, unsigne Line 1204  ui_create_cursor(unsigned int x, unsigne
1204          cursorglyph = ui_create_glyph(width, height, cursor);          cursorglyph = ui_create_glyph(width, height, cursor);
1205          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
1206    
1207          xcursor = XCreatePixmapCursor(display, (Pixmap) cursorglyph,          xcursor =
1208                                        (Pixmap) maskglyph, &fg, &bg, x, y);                  XCreatePixmapCursor(display, (Pixmap) cursorglyph,
1209                                        (Pixmap) maskglyph, &fg, &bg, x, y);
1210    
1211          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
1212          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
# Line 912  ui_create_cursor(unsigned int x, unsigne Line 1218  ui_create_cursor(unsigned int x, unsigne
1218  void  void
1219  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
1220  {  {
1221          XDefineCursor(display, wnd, (Cursor) cursor);          current_cursor = (Cursor) cursor;
1222            XDefineCursor(display, wnd, current_cursor);
1223  }  }
1224    
1225  void  void
# Line 927  ui_destroy_cursor(HCURSOR cursor) Line 1234  ui_destroy_cursor(HCURSOR cursor)
1234                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
1235                  (xc)->flags = DoRed | DoGreen | DoBlue;                  (xc)->flags = DoRed | DoGreen | DoBlue;
1236    
1237    
1238  HCOLOURMAP  HCOLOURMAP
1239  ui_create_colourmap(COLOURMAP * colours)  ui_create_colourmap(COLOURMAP * colours)
1240  {  {
1241          COLOURENTRY *entry;          COLOURENTRY *entry;
1242          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
1243            if (!owncolmap)
1244            {
1245                    uint32 *map = (uint32 *) xmalloc(sizeof(*colmap) * ncolours);
1246                    XColor xentry;
1247                    XColor xc_cache[256];
1248                    uint32 colour;
1249                    int colLookup = 256;
1250                    for (i = 0; i < ncolours; i++)
1251                    {
1252                            entry = &colours->colours[i];
1253                            MAKE_XCOLOR(&xentry, entry);
1254    
1255                            if (XAllocColor(display, xcolmap, &xentry) == 0)
1256                            {
1257                                    /* Allocation failed, find closest match. */
1258                                    int j = 256;
1259                                    int nMinDist = 3 * 256 * 256;
1260                                    long nDist = nMinDist;
1261    
1262                                    /* only get the colors once */
1263                                    while (colLookup--)
1264                                    {
1265                                            xc_cache[colLookup].pixel = colLookup;
1266                                            xc_cache[colLookup].red = xc_cache[colLookup].green =
1267                                                    xc_cache[colLookup].blue = 0;
1268                                            xc_cache[colLookup].flags = 0;
1269                                            XQueryColor(display,
1270                                                        DefaultColormap(display,
1271                                                                        DefaultScreen(display)),
1272                                                        &xc_cache[colLookup]);
1273                                    }
1274                                    colLookup = 0;
1275    
1276          if (owncolmap)                                  /* approximate the pixel */
1277                                    while (j--)
1278                                    {
1279                                            if (xc_cache[j].flags)
1280                                            {
1281                                                    nDist = ((long) (xc_cache[j].red >> 8) -
1282                                                             (long) (xentry.red >> 8)) *
1283                                                            ((long) (xc_cache[j].red >> 8) -
1284                                                             (long) (xentry.red >> 8)) +
1285                                                            ((long) (xc_cache[j].green >> 8) -
1286                                                             (long) (xentry.green >> 8)) *
1287                                                            ((long) (xc_cache[j].green >> 8) -
1288                                                             (long) (xentry.green >> 8)) +
1289                                                            ((long) (xc_cache[j].blue >> 8) -
1290                                                             (long) (xentry.blue >> 8)) *
1291                                                            ((long) (xc_cache[j].blue >> 8) -
1292                                                             (long) (xentry.blue >> 8));
1293                                            }
1294                                            if (nDist < nMinDist)
1295                                            {
1296                                                    nMinDist = nDist;
1297                                                    xentry.pixel = j;
1298                                            }
1299                                    }
1300                            }
1301                            colour = xentry.pixel;
1302    
1303                            /* update our cache */
1304                            if (xentry.pixel < 256)
1305                            {
1306                                    xc_cache[xentry.pixel].red = xentry.red;
1307                                    xc_cache[xentry.pixel].green = xentry.green;
1308                                    xc_cache[xentry.pixel].blue = xentry.blue;
1309    
1310                            }
1311    
1312    
1313                            /* byte swap here to make translate_image faster */
1314                            map[i] = translate_colour(colour);
1315                    }
1316                    return map;
1317            }
1318            else
1319          {          {
1320                  XColor *xcolours, *xentry;                  XColor *xcolours, *xentry;
1321                  Colormap map;                  Colormap map;
1322    
1323                  xcolours = xmalloc(sizeof(XColor) * ncolours);                  xcolours = (XColor *) xmalloc(sizeof(XColor) * ncolours);
1324                  for (i = 0; i < ncolours; i++)                  for (i = 0; i < ncolours; i++)
1325                  {                  {
1326                          entry = &colours->colours[i];                          entry = &colours->colours[i];
# Line 953  ui_create_colourmap(COLOURMAP * colours) Line 1335  ui_create_colourmap(COLOURMAP * colours)
1335                  xfree(xcolours);                  xfree(xcolours);
1336                  return (HCOLOURMAP) map;                  return (HCOLOURMAP) map;
1337          }          }
         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;  
         }  
1338  }  }
1339    
1340  void  void
1341  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
1342  {  {
1343          if (owncolmap)          if (!owncolmap)
                 XFreeColormap(display, (Colormap) map);  
         else  
1344                  xfree(map);                  xfree(map);
1345            else
1346                    XFreeColormap(display, (Colormap) map);
1347  }  }
1348    
1349  void  void
1350  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
1351  {  {
1352          if (owncolmap)          if (!owncolmap)
1353                  XSetWindowColormap(display, wnd, (Colormap) map);          {
1354                    if (colmap)
1355                            xfree(colmap);
1356    
1357                    colmap = (uint32 *) map;
1358            }
1359          else          else
1360                  colmap = map;                  XSetWindowColormap(display, wnd, (Colormap) map);
1361  }  }
1362    
1363  void  void
# Line 1008  ui_set_clip(int x, int y, int cx, int cy Line 1373  ui_set_clip(int x, int y, int cx, int cy
1373  }  }
1374    
1375  void  void
1376  ui_reset_clip()  ui_reset_clip(void)
1377  {  {
1378          XRectangle rect;          XRectangle rect;
1379    
1380          rect.x = 0;          rect.x = 0;
1381          rect.y = 0;          rect.y = 0;
1382          rect.width = width;          rect.width = g_width;
1383          rect.height = height;          rect.height = g_height;
1384          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
1385  }  }
1386    
1387  void  void
1388  ui_bell()  ui_bell(void)
1389  {  {
1390          XBell(display, 0);          XBell(display, 0);
1391  }  }
# Line 1034  ui_destblt(uint8 opcode, Line 1399  ui_destblt(uint8 opcode,
1399          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1400  }  }
1401    
1402    static uint8 hatch_patterns[] = {
1403            0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0 - bsHorizontal */
1404            0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 1 - bsVertical */
1405            0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, /* 2 - bsFDiagonal */
1406            0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* 3 - bsBDiagonal */
1407            0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, /* 4 - bsCross */
1408            0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81  /* 5 - bsDiagCross */
1409    };
1410    
1411  void  void
1412  ui_patblt(uint8 opcode,  ui_patblt(uint8 opcode,
1413            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
# Line 1051  ui_patblt(uint8 opcode, Line 1425  ui_patblt(uint8 opcode,
1425                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1426                          break;                          break;
1427    
1428                    case 2: /* Hatch */
1429                            fill = (Pixmap) ui_create_glyph(8, 8,
1430                                                            hatch_patterns + brush->pattern[0] * 8);
1431                            SET_FOREGROUND(bgcolour);
1432                            SET_BACKGROUND(fgcolour);
1433                            XSetFillStyle(display, gc, FillOpaqueStippled);
1434                            XSetStipple(display, gc, fill);
1435                            XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
1436                            FILL_RECTANGLE(x, y, cx, cy);
1437                            XSetFillStyle(display, gc, FillSolid);
1438                            XSetTSOrigin(display, gc, 0, 0);
1439                            ui_destroy_glyph((HGLYPH) fill);
1440                            break;
1441    
1442                  case 3: /* Pattern */                  case 3: /* Pattern */
1443                          for (i = 0; i != 8; i++)                          for (i = 0; i != 8; i++)
1444                                  ipattern[7 - i] = brush->pattern[i];                                  ipattern[7 - i] = brush->pattern[i];
# Line 1060  ui_patblt(uint8 opcode, Line 1448  ui_patblt(uint8 opcode,
1448                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
1449                          XSetFillStyle(display, gc, FillOpaqueStippled);                          XSetFillStyle(display, gc, FillOpaqueStippled);
1450                          XSetStipple(display, gc, fill);                          XSetStipple(display, gc, fill);
1451                          XSetTSOrigin(display, gc, brush->xorigin,                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
                                      brush->yorigin);  
1452    
1453                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1454    
1455                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
1456                            XSetTSOrigin(display, gc, 0, 0);
1457                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH) fill);
1458                          break;                          break;
1459    
# Line 1084  ui_screenblt(uint8 opcode, Line 1472  ui_screenblt(uint8 opcode,
1472          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1473          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
1474          if (ownbackstore)          if (ownbackstore)
1475                  XCopyArea(display, backstore, backstore, gc, srcx, srcy,                  XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1476          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1477  }  }
1478    
# Line 1097  ui_memblt(uint8 opcode, Line 1484  ui_memblt(uint8 opcode,
1484          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1485          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
1486          if (ownbackstore)          if (ownbackstore)
1487                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy,                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1488          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1489  }  }
1490    
# Line 1115  ui_triblt(uint8 opcode, Line 1501  ui_triblt(uint8 opcode,
1501          {          {
1502                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
1503                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1504                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1505                          break;                          break;
1506    
1507                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
1508                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1509                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1510                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1511                          break;                          break;
1512    
1513                  case 0xc0:      /* PSa */                  case 0xc0:      /* PSa */
1514                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1515                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
1516                          break;                          break;
1517    
1518                  default:                  default:
# Line 1161  ui_rect( Line 1543  ui_rect(
1543          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
1544  }  }
1545    
1546    /* warning, this function only draws on wnd or backstore, not both */
1547  void  void
1548  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1549                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1550                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1551                int fgcolour)                int bgcolour, int fgcolour)
1552  {  {
1553          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
1554          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
1555    
1556          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)          XSetFillStyle(display, gc,
1557                        ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1558          XSetStipple(display, gc, (Pixmap) glyph);          XSetStipple(display, gc, (Pixmap) glyph);
1559          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(display, gc, x, y);
1560    
1561          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
1562    
1563          XSetFillStyle(display, gc, FillSolid);          XSetFillStyle(display, gc, FillSolid);
1564  }  }
# Line 1189  ui_draw_glyph(int mixmode, Line 1572  ui_draw_glyph(int mixmode,
1572        if ((xyoffset & 0x80))\        if ((xyoffset & 0x80))\
1573          {\          {\
1574            if (flags & TEXT2_VERTICAL) \            if (flags & TEXT2_VERTICAL) \
1575              y += ttext[++idx] | (ttext[++idx] << 8);\              y += ttext[idx+1] | (ttext[idx+2] << 8);\
1576            else\            else\
1577              x += ttext[++idx] | (ttext[++idx] << 8);\              x += ttext[idx+1] | (ttext[idx+2] << 8);\
1578              idx += 2;\
1579          }\          }\
1580        else\        else\
1581          {\          {\
# Line 1203  ui_draw_glyph(int mixmode, Line 1587  ui_draw_glyph(int mixmode,
1587      }\      }\
1588    if (glyph != NULL)\    if (glyph != NULL)\
1589      {\      {\
1590        ui_draw_glyph (mixmode, x + (short) glyph->offset,\        ui_draw_glyph (mixmode, x + glyph->offset,\
1591                       y + (short) glyph->baseline,\                       y + glyph->baseline,\
1592                       glyph->width, glyph->height,\                       glyph->width, glyph->height,\
1593                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\
1594        if (flags & TEXT2_IMPLICIT_X)\        if (flags & TEXT2_IMPLICIT_X)\
# Line 1214  ui_draw_glyph(int mixmode, Line 1598  ui_draw_glyph(int mixmode,
1598    
1599  void  void
1600  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,
1601               int clipx, int clipy, int clipcx, int clipcy, int boxx,               int clipx, int clipy, int clipcx, int clipcy,
1602               int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1603               int fgcolour, uint8 * text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1604  {  {
1605          FONTGLYPH *glyph;          FONTGLYPH *glyph;
# Line 1226  ui_draw_text(uint8 font, uint8 flags, in Line 1610  ui_draw_text(uint8 font, uint8 flags, in
1610    
1611          if (boxcx > 1)          if (boxcx > 1)
1612          {          {
1613                  FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);
1614          }          }
1615          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
1616          {          {
1617                  FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
1618          }          }
1619    
1620          /* Paint text, character by character */          /* Paint text, character by character */
# Line 1240  ui_draw_text(uint8 font, uint8 flags, in Line 1624  ui_draw_text(uint8 font, uint8 flags, in
1624                  {                  {
1625                          case 0xff:                          case 0xff:
1626                                  if (i + 2 < length)                                  if (i + 2 < length)
1627                                          cache_put_text(text[i + 1], text,                                          cache_put_text(text[i + 1], text, text[i + 2]);
                                                        text[i + 2]);  
1628                                  else                                  else
1629                                  {                                  {
1630                                          error("this shouldn't be happening\n");                                          error("this shouldn't be happening\n");
1631                                          break;                                          exit(1);
1632                                  }                                  }
1633                                  /* this will move pointer from start to first character after FF command */                                  /* this will move pointer from start to first character after FF command */
1634                                  length -= i + 3;                                  length -= i + 3;
# Line 1258  ui_draw_text(uint8 font, uint8 flags, in Line 1641  ui_draw_text(uint8 font, uint8 flags, in
1641                                  if (entry != NULL)                                  if (entry != NULL)
1642                                  {                                  {
1643                                          if ((((uint8 *) (entry->data))[1] ==                                          if ((((uint8 *) (entry->data))[1] ==
1644                                               0)                                               0) && (!(flags & TEXT2_IMPLICIT_X)))
                                             && (!(flags & TEXT2_IMPLICIT_X)))  
1645                                          {                                          {
1646                                                  if (flags & TEXT2_VERTICAL)                                                  if (flags & TEXT2_VERTICAL)
1647                                                          y += text[i + 2];                                                          y += text[i + 2];
1648                                                  else                                                  else
1649                                                          x += text[i + 2];                                                          x += text[i + 2];
1650                                          }                                          }
                                         if (i + 2 < length)  
                                                 i += 3;  
                                         else  
                                                 i += 2;  
                                         length -= i;  
                                         /* this will move pointer from start to first character after FE command */  
                                         text = &(text[i]);  
                                         i = 0;  
1651                                          for (j = 0; j < entry->size; j++)                                          for (j = 0; j < entry->size; j++)
1652                                                  DO_GLYPH(((uint8 *) (entry->                                                  DO_GLYPH(((uint8 *) (entry->data)), j);
                                                                      data)),  
                                                          j);  
1653                                  }                                  }
1654                                    if (i + 2 < length)
1655                                            i += 3;
1656                                    else
1657                                            i += 2;
1658                                    length -= i;
1659                                    /* this will move pointer from start to first character after FE command */
1660                                    text = &(text[i]);
1661                                    i = 0;
1662                                  break;                                  break;
1663    
1664                          default:                          default:
# Line 1287  ui_draw_text(uint8 font, uint8 flags, in Line 1667  ui_draw_text(uint8 font, uint8 flags, in
1667                                  break;                                  break;
1668                  }                  }
1669          }          }
1670            if (ownbackstore)
1671            {
1672                    if (boxcx > 1)
1673                            XCopyArea(display, backstore, wnd, gc, boxx,
1674                                      boxy, boxcx, boxcy, boxx, boxy);
1675                    else
1676                            XCopyArea(display, backstore, wnd, gc, clipx,
1677                                      clipy, clipcx, clipcy, clipx, clipy);
1678            }
1679  }  }
1680    
1681  void  void
# Line 1299  ui_desktop_save(uint32 offset, int x, in Line 1686  ui_desktop_save(uint32 offset, int x, in
1686    
1687          if (ownbackstore)          if (ownbackstore)
1688          {          {
1689                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1690          }          }
1691          else          else
1692          {          {
1693                  pix = XCreatePixmap(display, wnd, cx, cy, depth);                  pix = XCreatePixmap(display, wnd, cx, cy, depth);
1694                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
1695                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1696                  XFreePixmap(display, pix);                  XFreePixmap(display, pix);
1697          }          }
1698    
1699          offset *= bpp / 8;          offset *= bpp / 8;
1700          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);  
1701    
1702          XDestroyImage(image);          XDestroyImage(image);
1703  }  }
# Line 1329  ui_desktop_restore(uint32 offset, int x, Line 1713  ui_desktop_restore(uint32 offset, int x,
1713          if (data == NULL)          if (data == NULL)
1714                  return;                  return;
1715    
1716          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1717                               0, data, cx, cy, BitmapPad(display),                               (char *) data, cx, cy, BitmapPad(display), cx * bpp / 8);
                              cx * bpp / 8);  
1718    
1719          if (ownbackstore)          if (ownbackstore)
1720          {          {

Legend:
Removed from v.64  
changed lines
  Added in v.449

  ViewVC Help
Powered by ViewVC 1.1.26