/[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 645 by jsorg71, Mon Mar 29 13:59:03 2004 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>
23  #include <X11/XKBlib.h>  #include <unistd.h>
24    #include <sys/time.h>
25  #include <time.h>  #include <time.h>
26  #include <errno.h>  #include <errno.h>
27    #include <strings.h>
28  #include "rdesktop.h"  #include "rdesktop.h"
29    #include "xproto.h"
30    
31  extern char keymapname[16];  extern int g_width;
32  extern int keylayout;  extern int g_height;
33  extern int width;  extern BOOL g_sendmotion;
34  extern int height;  extern BOOL g_fullscreen;
35  extern BOOL sendmotion;  extern BOOL g_grab_keyboard;
36  extern BOOL fullscreen;  extern BOOL g_hide_decorations;
37    extern char g_title[];
38  Display *display;  extern int g_server_bpp;
39  XkbDescPtr xkb;  extern int g_win_button_size;
40  static int x_socket;  
41  static Window wnd;  Display *g_display;
42  static GC gc;  Time g_last_gesturetime;
43  static Visual *visual;  static int g_x_socket;
44  static int depth;  static Screen *g_screen;
45  static int bpp;  Window g_wnd;
46    uint32 g_embed_wnd;
47    BOOL g_enable_compose = False;
48    static GC g_gc = NULL;
49    static Visual *g_visual;
50    static int g_depth;
51    static int g_bpp;
52    static XIM g_IM;
53    static XIC g_IC;
54    static XModifierKeymap *g_mod_map;
55    static Cursor g_current_cursor;
56    static HCURSOR g_null_cursor = NULL;
57    static Atom g_protocol_atom, g_kill_atom;
58    static BOOL g_focused;
59    static BOOL g_mouse_in_wnd;
60    static BOOL g_arch_match = False; /* set to True if RGB XServer and little endian */
61    
62  /* endianness */  /* endianness */
63  static BOOL host_be;  static BOOL g_host_be;
64  static BOOL xserver_be;  static BOOL g_xserver_be;
65    static int g_red_shift_r, g_blue_shift_r, g_green_shift_r;
66    static int g_red_shift_l, g_blue_shift_l, g_green_shift_l;
67    
68  /* software backing store */  /* software backing store */
69  static BOOL ownbackstore;  BOOL g_ownbackstore = True;     /* We can't rely on external BackingStore */
70  static Pixmap backstore;  static Pixmap g_backstore = 0;
71    
72    /* Moving in single app mode */
73    static BOOL g_moving_wnd;
74    static int g_move_x_offset = 0;
75    static int g_move_y_offset = 0;
76    
77    #ifdef WITH_RDPSND
78    extern int g_dsp_fd;
79    extern BOOL g_dsp_busy;
80    extern BOOL g_rdpsnd;
81    #endif
82    
83    /* MWM decorations */
84    #define MWM_HINTS_DECORATIONS   (1L << 1)
85    #define PROP_MOTIF_WM_HINTS_ELEMENTS    5
86    typedef struct
87    {
88            uint32 flags;
89            uint32 functions;
90            uint32 decorations;
91            sint32 inputMode;
92            uint32 status;
93    }
94    PropMotifWmHints;
95    
96    typedef struct
97    {
98            uint32 red;
99            uint32 green;
100            uint32 blue;
101    }
102    PixelColour;
103    
 /* needed to keep track of the modifiers */  
 static unsigned int numlock_modifier_mask = 0;  
 static unsigned int key_down_state = 0;  
   
   
 #define DShift1Mask   (1<<0)  
 #define DLockMask     (1<<1)  
 #define DControl1Mask (1<<2)  
 #define DMod1Mask     (1<<3)  
 #define DMod2Mask     (1<<4)  
 #define DMod3Mask     (1<<5)  
 #define DMod4Mask     (1<<6)  
 #define DMod5Mask     (1<<7)  
 #define DShift2Mask   (1<<8)  
 #define DControl2Mask (1<<9)  
 #define DNumLockMask  (1<<10)  
104    
105  #define FILL_RECTANGLE(x,y,cx,cy)\  #define FILL_RECTANGLE(x,y,cx,cy)\
106  { \  { \
107          XFillRectangle(display, wnd, gc, x, y, cx, cy); \          XFillRectangle(g_display, g_wnd, g_gc, x, y, cx, cy); \
108          if (ownbackstore) \          if (g_ownbackstore) \
109                  XFillRectangle(display, backstore, gc, x, y, cx, cy); \                  XFillRectangle(g_display, g_backstore, g_gc, x, y, cx, cy); \
110    }
111    
112    #define FILL_RECTANGLE_BACKSTORE(x,y,cx,cy)\
113    { \
114            XFillRectangle(g_display, g_ownbackstore ? g_backstore : g_wnd, g_gc, x, y, cx, cy); \
115  }  }
116    
117  /* colour maps */  /* colour maps */
118  static BOOL owncolmap;  BOOL g_owncolmap = False;
119  static Colormap xcolmap;  static Colormap g_xcolmap;
120  static uint32 white;  static uint32 *g_colmap = NULL;
121  static uint32 *colmap;  
122    #define TRANSLATE(col)          ( g_server_bpp != 8 ? translate_colour(col) : g_owncolmap ? col : g_colmap[col] )
123  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )  #define SET_FOREGROUND(col)     XSetForeground(g_display, g_gc, TRANSLATE(col));
124  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));  #define SET_BACKGROUND(col)     XSetBackground(g_display, g_gc, TRANSLATE(col));
 #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));  
125    
126  static int rop2_map[] = {  static int rop2_map[] = {
127          GXclear,                /* 0 */          GXclear,                /* 0 */
# Line 102  static int rop2_map[] = { Line 142  static int rop2_map[] = {
142          GXset                   /* 1 */          GXset                   /* 1 */
143  };  };
144    
145  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, rop2_map[rop2]); }
146  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, GXcopy); }
147    
148    static void
149    mwm_hide_decorations(void)
150    {
151            PropMotifWmHints motif_hints;
152            Atom hintsatom;
153    
154            /* setup the property */
155            motif_hints.flags = MWM_HINTS_DECORATIONS;
156            motif_hints.decorations = 0;
157    
158            /* get the atom for the property */
159            hintsatom = XInternAtom(g_display, "_MOTIF_WM_HINTS", False);
160            if (!hintsatom)
161            {
162                    warning("Failed to get atom _MOTIF_WM_HINTS: probably your window manager does not support MWM hints\n");
163                    return;
164            }
165    
166            XChangeProperty(g_display, g_wnd, hintsatom, hintsatom, 32, PropModeReplace,
167                            (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
168    }
169    
170  void xwin_get_numlock_mask();  static PixelColour
171  void xwin_mod_update(uint32 state, uint32 ev_time);  split_colour15(uint32 colour)
172  void xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode);  {
173  void xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode);          PixelColour rv;
174            rv.red = (colour & 0x7c00) >> 7;
175            rv.green = (colour & 0x03e0) >> 2;
176            rv.blue = (colour & 0x001f) << 3;
177            return rv;
178    }
179    
180    static PixelColour
181    split_colour16(uint32 colour)
182    {
183            PixelColour rv;
184            rv.red = (colour & 0xf800) >> 8;
185            rv.green = (colour & 0x07e0) >> 3;
186            rv.blue = (colour & 0x001f) << 3;
187            return rv;
188    }
189    
190    static PixelColour
191    split_colour24(uint32 colour)
192    {
193            PixelColour rv;
194            rv.blue = (colour & 0xff0000) >> 16;
195            rv.green = (colour & 0x00ff00) >> 8;
196            rv.red = (colour & 0x0000ff);
197            return rv;
198    }
199    
200    static uint32
201    make_colour(PixelColour pc)
202    {
203            return (((pc.red >> g_red_shift_r) << g_red_shift_l)
204                    | ((pc.green >> g_green_shift_r) << g_green_shift_l)
205                    | ((pc.blue >> g_blue_shift_r) << g_blue_shift_l));
206    }
207    
208    #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
209    #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | (x & 0xff00)); }
210    #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
211                            x = (x << 16) | (x >> 16); }
212    
213    static uint32
214    translate_colour(uint32 colour)
215    {
216            PixelColour pc;
217            switch (g_server_bpp)
218            {
219                    case 15:
220                            pc = split_colour15(colour);
221                            break;
222                    case 16:
223                            pc = split_colour16(colour);
224                            break;
225                    case 24:
226                            pc = split_colour24(colour);
227                            break;
228            }
229            return make_colour(pc);
230    }
231    
232  static void  static void
233  translate8(uint8 * data, uint8 * out, uint8 * end)  translate8to8(uint8 * data, uint8 * out, uint8 * end)
234  {  {
235          while (out < end)          while (out < end)
236                  *(out++) = (uint8) colmap[*(data++)];                  *(out++) = (uint8) g_colmap[*(data++)];
237  }  }
238    
239  static void  static void
240  translate16(uint8 * data, uint16 * out, uint16 * end)  translate8to16(uint8 * data, uint8 * out, uint8 * end)
241  {  {
242          while (out < end)          uint16 value;
243                  *(out++) = (uint16) colmap[*(data++)];  
244            if (g_xserver_be)
245            {
246                    while (out < end)
247                    {
248                            value = (uint16) g_colmap[*(data++)];
249                            *(out++) = value >> 8;
250                            *(out++) = value;
251                    }
252            }
253            else
254            {
255                    while (out < end)
256                    {
257                            value = (uint16) g_colmap[*(data++)];
258                            *(out++) = value;
259                            *(out++) = value >> 8;
260                    }
261            }
262  }  }
263    
264  /* little endian - conversion happens when colourmap is built */  /* little endian - conversion happens when colourmap is built */
265  static void  static void
266  translate24(uint8 * data, uint8 * out, uint8 * end)  translate8to24(uint8 * data, uint8 * out, uint8 * end)
267  {  {
268          uint32 value;          uint32 value;
269    
270            if (g_xserver_be)
271            {
272                    while (out < end)
273                    {
274                            value = g_colmap[*(data++)];
275                            *(out++) = value >> 16;
276                            *(out++) = value >> 8;
277                            *(out++) = value;
278                    }
279            }
280            else
281            {
282                    while (out < end)
283                    {
284                            value = g_colmap[*(data++)];
285                            *(out++) = value;
286                            *(out++) = value >> 8;
287                            *(out++) = value >> 16;
288                    }
289            }
290    }
291    
292    static void
293    translate8to32(uint8 * data, uint8 * out, uint8 * end)
294    {
295            uint32 value;
296    
297            if (g_xserver_be)
298            {
299                    while (out < end)
300                    {
301                            value = g_colmap[*(data++)];
302                            *(out++) = value >> 24;
303                            *(out++) = value >> 16;
304                            *(out++) = value >> 8;
305                            *(out++) = value;
306                    }
307            }
308            else
309            {
310                    while (out < end)
311                    {
312                            value = g_colmap[*(data++)];
313                            *(out++) = value;
314                            *(out++) = value >> 8;
315                            *(out++) = value >> 16;
316                            *(out++) = value >> 24;
317                    }
318            }
319    }
320    
321    static void
322    translate15to16(uint16 * data, uint8 * out, uint8 * end)
323    {
324            uint16 pixel;
325            uint16 value;
326    
327          while (out < end)          while (out < end)
328          {          {
329                  value = colmap[*(data++)];                  pixel = *(data++);
330                  *(out++) = value;  
331                  *(out++) = value >> 8;                  if (g_host_be)
332                  *(out++) = value >> 16;                  {
333                            BSWAP16(pixel);
334                    }
335    
336                    value = make_colour(split_colour15(pixel));
337    
338                    if (g_xserver_be)
339                    {
340                            *(out++) = value >> 8;
341                            *(out++) = value;
342                    }
343                    else
344                    {
345                            *(out++) = value;
346                            *(out++) = value >> 8;
347                    }
348          }          }
349  }  }
350    
351  static void  static void
352  translate32(uint8 * data, uint32 * out, uint32 * end)  translate15to24(uint16 * data, uint8 * out, uint8 * end)
353  {  {
354            uint32 value;
355            uint16 pixel;
356    
357          while (out < end)          while (out < end)
358                  *(out++) = colmap[*(data++)];          {
359                    pixel = *(data++);
360    
361                    if (g_host_be)
362                    {
363                            BSWAP16(pixel);
364                    }
365    
366                    value = make_colour(split_colour15(pixel));
367                    if (g_xserver_be)
368                    {
369                            *(out++) = value >> 16;
370                            *(out++) = value >> 8;
371                            *(out++) = value;
372                    }
373                    else
374                    {
375                            *(out++) = value;
376                            *(out++) = value >> 8;
377                            *(out++) = value >> 16;
378                    }
379            }
380  }  }
381    
382  static uint8 *  static void
383  translate_image(int width, int height, uint8 * data)  translate15to32(uint16 * data, uint8 * out, uint8 * end)
384  {  {
385          int size = width * height * bpp / 8;          uint16 pixel;
386          uint8 *out = xmalloc(size);          uint32 value;
         uint8 *end = out + size;  
387    
388          switch (bpp)          while (out < end)
389          {          {
390                  case 8:                  pixel = *(data++);
                         translate8(data, out, end);  
                         break;  
391    
392                  case 16:                  if (g_host_be)
393                          translate16(data, (uint16 *) out, (uint16 *) end);                  {
394                          break;                          BSWAP16(pixel);
395                    }
396    
397                  case 24:                  value = make_colour(split_colour15(pixel));
                         translate24(data, out, end);  
                         break;  
398    
399                  case 32:                  if (g_xserver_be)
400                          translate32(data, (uint32 *) out, (uint32 *) end);                  {
401                          break;                          *(out++) = value >> 24;
402                            *(out++) = value >> 16;
403                            *(out++) = value >> 8;
404                            *(out++) = value;
405                    }
406                    else
407                    {
408                            *(out++) = value;
409                            *(out++) = value >> 8;
410                            *(out++) = value >> 16;
411                            *(out++) = value >> 24;
412                    }
413          }          }
414    }
415    
416          return out;  static void
417    translate16to16(uint16 * data, uint8 * out, uint8 * end)
418    {
419            uint16 pixel;
420            uint16 value;
421    
422            while (out < end)
423            {
424                    pixel = *(data++);
425    
426                    if (g_host_be)
427                    {
428                            BSWAP16(pixel);
429                    }
430    
431                    value = make_colour(split_colour16(pixel));
432    
433                    if (g_xserver_be)
434                    {
435                            *(out++) = value >> 8;
436                            *(out++) = value;
437                    }
438                    else
439                    {
440                            *(out++) = value;
441                            *(out++) = value >> 8;
442                    }
443            }
444  }  }
445    
446  #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }  static void
447  #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }  translate16to24(uint16 * data, uint8 * out, uint8 * end)
448  #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \  {
449                          x = (x << 16) | (x >> 16); }          uint32 value;
450            uint16 pixel;
451    
452  static uint32          while (out < end)
453  translate_colour(uint32 colour)          {
454                    pixel = *(data++);
455    
456                    if (g_host_be)
457                    {
458                            BSWAP16(pixel);
459                    }
460    
461                    value = make_colour(split_colour16(pixel));
462    
463                    if (g_xserver_be)
464                    {
465                            *(out++) = value >> 16;
466                            *(out++) = value >> 8;
467                            *(out++) = value;
468                    }
469                    else
470                    {
471                            *(out++) = value;
472                            *(out++) = value >> 8;
473                            *(out++) = value >> 16;
474                    }
475            }
476    }
477    
478    static void
479    translate16to32(uint16 * data, uint8 * out, uint8 * end)
480  {  {
481          switch (bpp)          uint16 pixel;
482            uint32 value;
483    
484            while (out < end)
485          {          {
486                  case 16:                  pixel = *(data++);
                         if (host_be != xserver_be)  
                                 BSWAP16(colour);  
                         break;  
487    
488                  case 24:                  if (g_host_be)
489                          if (xserver_be)                  {
490                                  BSWAP24(colour);                          BSWAP16(pixel);
491                          break;                  }
492    
493                  case 32:                  value = make_colour(split_colour16(pixel));
494                          if (host_be != xserver_be)  
495                                  BSWAP32(colour);                  if (g_xserver_be)
496                          break;                  {
497                            *(out++) = value >> 24;
498                            *(out++) = value >> 16;
499                            *(out++) = value >> 8;
500                            *(out++) = value;
501                    }
502                    else
503                    {
504                            *(out++) = value;
505                            *(out++) = value >> 8;
506                            *(out++) = value >> 16;
507                            *(out++) = value >> 24;
508                    }
509          }          }
510    }
511    
512    static void
513    translate24to16(uint8 * data, uint8 * out, uint8 * end)
514    {
515            uint32 pixel = 0;
516            uint16 value;
517            while (out < end)
518            {
519                    pixel = *(data++) << 16;
520                    pixel |= *(data++) << 8;
521                    pixel |= *(data++);
522    
523                    value = (uint16) make_colour(split_colour24(pixel));
524    
525          return colour;                  if (g_xserver_be)
526                    {
527                            *(out++) = value >> 8;
528                            *(out++) = value;
529                    }
530                    else
531                    {
532                            *(out++) = value;
533                            *(out++) = value >> 8;
534                    }
535            }
536  }  }
537    
538  BOOL  static void
539  ui_create_window(char *title)  translate24to24(uint8 * data, uint8 * out, uint8 * end)
540  {  {
541          XSetWindowAttributes attribs;          uint32 pixel;
542          XClassHint *classhints;          uint32 value;
543          XSizeHints *sizehints;  
544          unsigned long input_mask;          while (out < end)
545          XPixmapFormatValues *pfm;          {
546          Screen *screen;                  pixel = *(data++) << 16;
547          uint16 test;                  pixel |= *(data++) << 8;
548          int i;                  pixel |= *(data++);
549    
550                    value = make_colour(split_colour24(pixel));
551    
552                    if (g_xserver_be)
553                    {
554                            *(out++) = value >> 16;
555                            *(out++) = value >> 8;
556                            *(out++) = value;
557                    }
558                    else
559                    {
560                            *(out++) = value;
561                            *(out++) = value >> 8;
562                            *(out++) = value >> 16;
563                    }
564            }
565    }
566    
567          int xkb_minor, xkb_major;  static void
568          int xkb_event, xkb_error, xkb_reason;  translate24to32(uint8 * data, uint8 * out, uint8 * end)
569    {
570            uint32 pixel;
571            uint32 value;
572    
573          /* compare compiletime libs with runtime libs. */          while (out < end)
         xkb_major = XkbMajorVersion;  
         xkb_minor = XkbMinorVersion;  
         if (XkbLibraryVersion(&xkb_major, &xkb_minor) == False)  
574          {          {
575                  error("please re-compile rdesktop\ncompile time version of xkb is not compatible with\nyour runtime version of the library\n");                  pixel = *(data++) << 16;
576                  return False;                  pixel |= *(data++) << 8;
577                    pixel |= *(data++);
578    
579                    value = make_colour(split_colour24(pixel));
580    
581                    if (g_xserver_be)
582                    {
583                            *(out++) = value >> 24;
584                            *(out++) = value >> 16;
585                            *(out++) = value >> 8;
586                            *(out++) = value;
587                    }
588                    else
589                    {
590                            *(out++) = value;
591                            *(out++) = value >> 8;
592                            *(out++) = value >> 16;
593                            *(out++) = value >> 24;
594                    }
595          }          }
596    }
597    
598    static uint8 *
599    translate_image(int width, int height, uint8 * data)
600    {
601            int size;
602            uint8 *out;
603            uint8 *end;
604    
605            /* if server and xserver bpp match, */
606            /* and arch(endian) matches, no need to translate */
607            /* just return data */
608            if (g_arch_match)
609            {
610                    if (g_depth == 15 && g_server_bpp == 15)
611                            return data;
612                    if (g_depth == 16 && g_server_bpp == 16)
613                            return data;
614            }
615    
616            size = width * height * (g_bpp / 8);
617            out = (uint8 *) xmalloc(size);
618            end = out + size;
619    
620          display =          switch (g_server_bpp)
                 XkbOpenDisplay(NULL, &xkb_event, &xkb_error, &xkb_major,  
                                &xkb_minor, &xkb_reason);  
         switch (xkb_reason)  
621          {          {
622                  case XkbOD_BadLibraryVersion:                  case 24:
623                          error("XkbOD_BadLibraryVersion: XKB extensions in server and the library rdesktop is linked against aren't compatible with each other.\n");                          switch (g_bpp)
624                          break;                          {
625                  case XkbOD_ConnectionRefused:                                  case 32:
626                          error("XkbOD_ConnectionRefused\n");                                          translate24to32(data, out, end);
627                                            break;
628                                    case 24:
629                                            translate24to24(data, out, end);
630                                            break;
631                                    case 16:
632                                            translate24to16(data, out, end);
633                                            break;
634                            }
635                          break;                          break;
636                  case XkbOD_BadServerVersion:                  case 16:
637                          error("XkbOD_BadServerVersion\n");                          switch (g_bpp)
638                            {
639                                    case 32:
640                                            translate16to32((uint16 *) data, out, end);
641                                            break;
642                                    case 24:
643                                            translate16to24((uint16 *) data, out, end);
644                                            break;
645                                    case 16:
646                                            translate16to16((uint16 *) data, out, end);
647                                            break;
648                            }
649                          break;                          break;
650                  case XkbOD_NonXkbServer:                  case 15:
651                          error("XkbOD_NonXkbServer: XKB extension not present in server\nupdate your X server.\n");                          switch (g_bpp)
652                            {
653                                    case 32:
654                                            translate15to32((uint16 *) data, out, end);
655                                            break;
656                                    case 24:
657                                            translate15to24((uint16 *) data, out, end);
658                                            break;
659                                    case 16:
660                                            translate15to16((uint16 *) data, out, end);
661                                            break;
662                            }
663                          break;                          break;
664                  case XkbOD_Success:                  case 8:
665                          DEBUG("XkbOD_Success: Connection established with display\n");                          switch (g_bpp)
666                            {
667                                    case 8:
668                                            translate8to8(data, out, end);
669                                            break;
670                                    case 16:
671                                            translate8to16(data, out, end);
672                                            break;
673                                    case 24:
674                                            translate8to24(data, out, end);
675                                            break;
676                                    case 32:
677                                            translate8to32(data, out, end);
678                                            break;
679                            }
680                          break;                          break;
681          }          }
682            return out;
683    }
684    
685    BOOL
686    get_key_state(unsigned int state, uint32 keysym)
687    {
688            int modifierpos, key, keysymMask = 0;
689            int offset;
690    
691            KeyCode keycode = XKeysymToKeycode(g_display, keysym);
692    
693            if (keycode == NoSymbol)
694                    return False;
695    
696            for (modifierpos = 0; modifierpos < 8; modifierpos++)
697            {
698                    offset = g_mod_map->max_keypermod * modifierpos;
699    
700                    for (key = 0; key < g_mod_map->max_keypermod; key++)
701                    {
702                            if (g_mod_map->modifiermap[offset + key] == keycode)
703                                    keysymMask |= 1 << modifierpos;
704                    }
705            }
706    
707            return (state & keysymMask) ? True : False;
708    }
709    
710    static void
711    calculate_shifts(uint32 mask, int *shift_r, int *shift_l)
712    {
713            *shift_l = ffs(mask) - 1;
714            mask >>= *shift_l;
715            *shift_r = 8 - ffs(mask & ~(mask >> 1));
716    }
717    
718    BOOL
719    ui_init(void)
720    {
721            XVisualInfo vi;
722            XPixmapFormatValues *pfm;
723            uint16 test;
724            int i, screen_num, nvisuals;
725            XVisualInfo *vmatches = NULL;
726            XVisualInfo template;
727            Bool TrueColorVisual = False;
728    
729          if (display == NULL)          g_display = XOpenDisplay(NULL);
730            if (g_display == NULL)
731          {          {
732                  error("Failed to open display\n");                  error("Failed to open display: %s\n", XDisplayName(NULL));
733                  return False;                  return False;
734          }          }
735    
736          x_socket = ConnectionNumber(display);          screen_num = DefaultScreen(g_display);
737          screen = DefaultScreenOfDisplay(display);          g_x_socket = ConnectionNumber(g_display);
738          visual = DefaultVisualOfScreen(screen);          g_screen = ScreenOfDisplay(g_display, screen_num);
739          depth = DefaultDepthOfScreen(screen);          g_depth = DefaultDepthOfScreen(g_screen);
740    
741            /* Search for best TrueColor depth */
742            template.class = TrueColor;
743            vmatches = XGetVisualInfo(g_display, VisualClassMask, &template, &nvisuals);
744    
745          pfm = XListPixmapFormats(display, &i);          nvisuals--;
746            while (nvisuals >= 0)
747            {
748                    if ((vmatches + nvisuals)->depth > g_depth)
749                    {
750                            g_depth = (vmatches + nvisuals)->depth;
751                    }
752                    nvisuals--;
753                    TrueColorVisual = True;
754            }
755    
756            test = 1;
757            g_host_be = !(BOOL) (*(uint8 *) (&test));
758            g_xserver_be = (ImageByteOrder(g_display) == MSBFirst);
759    
760            if ((g_server_bpp == 8) && ((!TrueColorVisual) || (g_depth <= 8)))
761            {
762                    /* we use a colourmap, so the default visual should do */
763                    g_visual = DefaultVisualOfScreen(g_screen);
764                    g_depth = DefaultDepthOfScreen(g_screen);
765    
766                    /* Do not allocate colours on a TrueColor visual */
767                    if (g_visual->class == TrueColor)
768                    {
769                            g_owncolmap = False;
770                    }
771            }
772            else
773            {
774                    /* need a truecolour visual */
775                    if (!XMatchVisualInfo(g_display, screen_num, g_depth, TrueColor, &vi))
776                    {
777                            error("The display does not support true colour - high colour support unavailable.\n");
778                            return False;
779                    }
780    
781                    g_visual = vi.visual;
782                    g_owncolmap = False;
783                    calculate_shifts(vi.red_mask, &g_red_shift_r, &g_red_shift_l);
784                    calculate_shifts(vi.blue_mask, &g_blue_shift_r, &g_blue_shift_l);
785                    calculate_shifts(vi.green_mask, &g_green_shift_r, &g_green_shift_l);
786    
787                    /* if RGB video and averything is little endian */
788                    if (vi.red_mask > vi.green_mask && vi.green_mask > vi.blue_mask)
789                            if (!g_xserver_be && !g_host_be)
790                                    g_arch_match = True;
791            }
792    
793            pfm = XListPixmapFormats(g_display, &i);
794          if (pfm != NULL)          if (pfm != NULL)
795          {          {
796                  /* Use maximum bpp for this depth - this is generally                  /* Use maximum bpp for this depth - this is generally
797                     desirable, e.g. 24 bits->32 bits. */                     desirable, e.g. 24 bits->32 bits. */
798                  while (i--)                  while (i--)
799                  {                  {
800                          if ((pfm[i].depth == depth)                          if ((pfm[i].depth == g_depth) && (pfm[i].bits_per_pixel > g_bpp))
                             && (pfm[i].bits_per_pixel > bpp))  
801                          {                          {
802                                  bpp = pfm[i].bits_per_pixel;                                  g_bpp = pfm[i].bits_per_pixel;
803                          }                          }
804                  }                  }
805                  XFree(pfm);                  XFree(pfm);
806          }          }
807    
808          if (bpp < 8)          if (g_bpp < 8)
809          {          {
810                  error("Less than 8 bpp not currently supported.\n");                  error("Less than 8 bpp not currently supported.\n");
811                  XCloseDisplay(display);                  XCloseDisplay(g_display);
812                  return False;                  return False;
813          }          }
814    
815          if (depth <= 8)          if (!g_owncolmap)
816                  owncolmap = True;          {
817          else                  g_xcolmap =
818                  xcolmap = DefaultColormapOfScreen(screen);                          XCreateColormap(g_display, RootWindowOfScreen(g_screen), g_visual,
819                                            AllocNone);
820          test = 1;                  if (g_depth <= 8)
821          host_be = !(BOOL) (*(uint8 *) (&test));                          warning("Screen depth is 8 bits or lower: you may want to use -C for a private colourmap\n");
822          xserver_be = (ImageByteOrder(display) == MSBFirst);          }
   
         white = WhitePixelOfScreen(screen);  
         attribs.background_pixel = BlackPixelOfScreen(screen);  
         attribs.backing_store = DoesBackingStore(screen);  
823    
824          if (attribs.backing_store == NotUseful)          if ((!g_ownbackstore) && (DoesBackingStore(g_screen) != Always))
825                  ownbackstore = True;          {
826                    warning("External BackingStore not available, using internal\n");
827                    g_ownbackstore = True;
828            }
829    
830          if (fullscreen)          /*
831             * Determine desktop size
832             */
833            if (g_fullscreen)
834          {          {
835                  attribs.override_redirect = True;                  g_width = WidthOfScreen(g_screen);
836                  width = WidthOfScreen(screen);                  g_height = HeightOfScreen(g_screen);
                 height = HeightOfScreen(screen);  
837          }          }
838          else          else if (g_width < 0)
839          {          {
840                  attribs.override_redirect = False;                  /* Percent of screen */
841                    g_height = HeightOfScreen(g_screen) * (-g_width) / 100;
842                    g_width = WidthOfScreen(g_screen) * (-g_width) / 100;
843          }          }
844            else if (g_width == 0)
845            {
846                    /* Fetch geometry from _NET_WORKAREA */
847                    uint32 x, y, cx, cy;
848    
849                    if (get_current_workarea(&x, &y, &cx, &cy) == 0)
850                    {
851                            g_width = cx;
852                            g_height = cy;
853                    }
854                    else
855                    {
856                            warning("Failed to get workarea: probably your window manager does not support extended hints\n");
857                            g_width = 800;
858                            g_height = 600;
859                    }
860            }
861    
862            /* make sure width is a multiple of 4 */
863            g_width = (g_width + 3) & ~3;
864    
865            g_mod_map = XGetModifierMapping(g_display);
866    
867            xkeymap_init();
868    
869          width = (width + 3) & ~3;       /* make width a multiple of 32 bits */          if (g_enable_compose)
870                    g_IM = XOpenIM(g_display, NULL, NULL, NULL);
871    
872          wnd = XCreateWindow(display, RootWindowOfScreen(screen),          xclip_init();
                             0, 0, width, height, 0, CopyFromParent,  
                             InputOutput, CopyFromParent,  
                             CWBackingStore | CWBackPixel | CWOverrideRedirect,  
                             &attribs);  
873    
874          XStoreName(display, wnd, title);          DEBUG_RDP5(("server bpp %d client bpp %d depth %d\n", g_server_bpp, g_bpp, g_depth));
875    
876            return True;
877    }
878    
879    void
880    ui_deinit(void)
881    {
882            if (g_IM != NULL)
883                    XCloseIM(g_IM);
884    
885            if (g_null_cursor != NULL)
886                    ui_destroy_cursor(g_null_cursor);
887    
888            XFreeModifiermap(g_mod_map);
889    
890            if (g_ownbackstore)
891                    XFreePixmap(g_display, g_backstore);
892    
893            XFreeGC(g_display, g_gc);
894            XCloseDisplay(g_display);
895            g_display = NULL;
896    }
897    
898    BOOL
899    ui_create_window(void)
900    {
901            uint8 null_pointer_mask[1] = { 0x80 };
902            uint8 null_pointer_data[4] = { 0x00, 0x00, 0x00, 0x00 };
903            XSetWindowAttributes attribs;
904            XClassHint *classhints;
905            XSizeHints *sizehints;
906            int wndwidth, wndheight;
907            long input_mask, ic_input_mask;
908            XEvent xevent;
909    
910            wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;
911            wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;
912    
913            attribs.background_pixel = BlackPixelOfScreen(g_screen);
914            attribs.border_pixel = WhitePixelOfScreen(g_screen);
915            attribs.backing_store = g_ownbackstore ? NotUseful : Always;
916            attribs.override_redirect = g_fullscreen;
917            attribs.colormap = g_xcolmap;
918    
919            g_wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), 0, 0, wndwidth, wndheight,
920                                  0, g_depth, InputOutput, g_visual,
921                                  CWBackPixel | CWBackingStore | CWOverrideRedirect |
922                                  CWColormap | CWBorderPixel, &attribs);
923    
924            if (g_gc == NULL)
925                    g_gc = XCreateGC(g_display, g_wnd, 0, NULL);
926    
927            if ((g_ownbackstore) && (g_backstore == 0))
928            {
929                    g_backstore = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
930    
931                    /* clear to prevent rubbish being exposed at startup */
932                    XSetForeground(g_display, g_gc, BlackPixelOfScreen(g_screen));
933                    XFillRectangle(g_display, g_backstore, g_gc, 0, 0, g_width, g_height);
934            }
935    
936            XStoreName(g_display, g_wnd, g_title);
937    
938            if (g_hide_decorations)
939                    mwm_hide_decorations();
940    
941          classhints = XAllocClassHint();          classhints = XAllocClassHint();
942          if (classhints != NULL)          if (classhints != NULL)
943          {          {
944                  classhints->res_name = classhints->res_class = "rdesktop";                  classhints->res_name = classhints->res_class = "rdesktop";
945                  XSetClassHint(display, wnd, classhints);                  XSetClassHint(g_display, g_wnd, classhints);
946                  XFree(classhints);                  XFree(classhints);
947          }          }
948    
# Line 334  ui_create_window(char *title) Line 950  ui_create_window(char *title)
950          if (sizehints)          if (sizehints)
951          {          {
952                  sizehints->flags = PMinSize | PMaxSize;                  sizehints->flags = PMinSize | PMaxSize;
953                  sizehints->min_width = sizehints->max_width = width;                  sizehints->min_width = sizehints->max_width = g_width;
954                  sizehints->min_height = sizehints->max_height = height;                  sizehints->min_height = sizehints->max_height = g_height;
955                  XSetWMNormalHints(display, wnd, sizehints);                  XSetWMNormalHints(g_display, g_wnd, sizehints);
956                  XFree(sizehints);                  XFree(sizehints);
957          }          }
958    
959          xkeymap_init();          if ( g_embed_wnd )
960            {
961                    XReparentWindow(g_display, g_wnd, (Window)g_embed_wnd, 0, 0);
962            }
963    
964          input_mask = KeyPressMask | KeyReleaseMask |          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
965                  ButtonPressMask | ButtonReleaseMask |                  VisibilityChangeMask | FocusChangeMask;
                 EnterWindowMask | LeaveWindowMask;  
         if (sendmotion)  
                 input_mask |= PointerMotionMask;  
966    
967          if (ownbackstore)          if (g_sendmotion)
968                    input_mask |= PointerMotionMask;
969            if (g_ownbackstore)
970                  input_mask |= ExposureMask;                  input_mask |= ExposureMask;
971            if (g_fullscreen || g_grab_keyboard)
972                    input_mask |= EnterWindowMask;
973            if (g_grab_keyboard)
974                    input_mask |= LeaveWindowMask;
975    
976          XSelectInput(display, wnd, input_mask);          if (g_IM != NULL)
977          gc = XCreateGC(display, wnd, 0, NULL);          {
978                    g_IC = XCreateIC(g_IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
979                                     XNClientWindow, g_wnd, XNFocusWindow, g_wnd, NULL);
980    
981          if (ownbackstore)                  if ((g_IC != NULL)
982                  backstore = XCreatePixmap(display, wnd, width, height, depth);                      && (XGetICValues(g_IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))
983                            input_mask |= ic_input_mask;
984            }
985    
986          XMapWindow(display, wnd);          XSelectInput(g_display, g_wnd, input_mask);
987            XMapWindow(g_display, g_wnd);
988    
989          /* TODO: error texts... make them friendly. */          /* wait for VisibilityNotify */
990          xkb = XkbGetKeyboard(display, XkbAllComponentsMask, XkbUseCoreKbd);          do
         if ((int) xkb == BadAlloc || xkb == NULL)  
991          {          {
992                  error("XkbGetKeyboard failed.\n");                  XMaskEvent(g_display, VisibilityChangeMask, &xevent);
                 exit(0);  
993          }          }
994            while (xevent.type != VisibilityNotify);
995    
996          /* TODO: error texts... make them friendly. */          g_focused = False;
997          if (XkbSelectEvents          g_mouse_in_wnd = False;
             (display, xkb->device_spec, XkbAllEventsMask,  
              XkbAllEventsMask) == False)  
         {  
                 error("XkbSelectEvents failed.\n");  
                 exit(0);  
         }  
998    
999          xwin_get_numlock_mask();          /* handle the WM_DELETE_WINDOW protocol */
1000            g_protocol_atom = XInternAtom(g_display, "WM_PROTOCOLS", True);
1001            g_kill_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", True);
1002            XSetWMProtocols(g_display, g_wnd, &g_kill_atom, 1);
1003    
1004            /* create invisible 1x1 cursor to be used as null cursor */
1005            if (g_null_cursor == NULL)
1006                    g_null_cursor = ui_create_cursor(0, 0, 1, 1, null_pointer_mask, null_pointer_data);
1007    
1008          return True;          return True;
1009  }  }
1010    
1011  void  void
1012  xwin_get_numlock_mask()  ui_destroy_window(void)
1013  {  {
1014          KeyCode numlockcode;          if (g_IC != NULL)
1015          KeyCode *keycode;                  XDestroyIC(g_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");  
1016    
1017            XDestroyWindow(g_display, g_wnd);
1018  }  }
1019    
1020  void  void
1021  ui_destroy_window()  xwin_toggle_fullscreen(void)
1022  {  {
1023          if (xkb != NULL)          Pixmap contents = 0;
                 XkbFreeKeyboard(xkb, XkbAllControlsMask, True);  
1024    
1025          if (ownbackstore)          if (!g_ownbackstore)
1026                  XFreePixmap(display, backstore);          {
1027                    /* need to save contents of window */
1028                    contents = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
1029                    XCopyArea(g_display, g_wnd, contents, g_gc, 0, 0, g_width, g_height, 0, 0);
1030            }
1031    
1032            ui_destroy_window();
1033            g_fullscreen = !g_fullscreen;
1034            ui_create_window();
1035    
1036          XFreeGC(display, gc);          XDefineCursor(g_display, g_wnd, g_current_cursor);
1037          XDestroyWindow(display, wnd);  
1038          XCloseDisplay(display);          if (!g_ownbackstore)
1039          display = NULL;          {
1040                    XCopyArea(g_display, contents, g_wnd, g_gc, 0, 0, g_width, g_height, 0, 0);
1041                    XFreePixmap(g_display, contents);
1042            }
1043  }  }
1044    
1045  static void  /* Process all events in Xlib queue
1046  xwin_process_events()     Returns 0 after user quit, 1 otherwise */
1047    static int
1048    xwin_process_events(void)
1049  {  {
1050          XEvent xevent;          XEvent xevent;
   
1051          KeySym keysym;          KeySym keysym;
         uint8 scancode;  
1052          uint16 button, flags;          uint16 button, flags;
1053          uint32 ev_time;          uint32 ev_time;
1054          uint32 tmpmods;          key_translation tr;
1055            char str[256];
1056            Status status;
1057    
1058          while (XCheckMaskEvent(display, ~0, &xevent))          while (XPending(g_display) > 0)
1059          {          {
1060                  ev_time = time(NULL);                  XNextEvent(g_display, &xevent);
1061    
1062                    if ((g_IC != NULL) && (XFilterEvent(&xevent, None) == True))
1063                    {
1064                            DEBUG_KBD(("Filtering event\n"));
1065                            continue;
1066                    }
1067    
1068                  flags = 0;                  flags = 0;
1069    
1070                  switch (xevent.type)                  switch (xevent.type)
1071                  {                  {
1072                          case KeyRelease:                          case ClientMessage:
1073                                  flags = KBD_FLAG_DOWN | KBD_FLAG_UP;                                  /* the window manager told us to quit */
1074                                  /* fall through */                                  if ((xevent.xclient.message_type == g_protocol_atom)
1075                          case KeyPress:                                      && ((Atom) xevent.xclient.data.l[0] == g_kill_atom))
1076                                  if (XkbTranslateKeyCode                                          /* Quit */
1077                                      (xkb, xevent.xkey.keycode,                                          return 0;
                                      xevent.xkey.state, &tmpmods,  
                                      &keysym) == False)  
                                         break;  
                                 scancode =  
                                         xkeymap_translate_key(keysym,  
                                                               xevent.xkey.  
                                                               keycode,  
                                                               &flags);  
   
                                 if (scancode == 0)  
                                         break;  
   
                                 /* keep track of the modifiers -- needed for stickykeys... */  
                                 if (xevent.type == KeyPress)  
                                         xwin_mod_press(xevent.xkey.state,  
                                                        ev_time, scancode);  
   
                                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,  
                                                flags, scancode, 0);  
   
                                 if (xevent.type == KeyRelease)  
                                         xwin_mod_release(xevent.xkey.state,  
                                                          ev_time, scancode);  
   
1078                                  break;                                  break;
1079    
1080                          case ButtonPress:                          case KeyPress:
1081                                  flags = MOUSE_FLAG_DOWN;                                  g_last_gesturetime = xevent.xkey.time;
1082                                  /* fall through */                                  if (g_IC != NULL)
1083                                            /* Multi_key compatible version */
1084                          case ButtonRelease:                                  {
1085                                  button = xkeymap_translate_button(xevent.                                          XmbLookupString(g_IC,
1086                                                                    xbutton.                                                          &xevent.xkey, str, sizeof(str), &keysym,
1087                                                                    button);                                                          &status);
1088                                  if (button == 0)                                          if (!((status == XLookupKeySym) || (status == XLookupBoth)))
1089                                          break;                                          {
1090                                                    error("XmbLookupString failed with status 0x%x\n",
1091                                                          status);
1092                                                    break;
1093                                            }
1094                                    }
1095                                    else
1096                                    {
1097                                            /* Plain old XLookupString */
1098                                            DEBUG_KBD(("\nNo input context, using XLookupString\n"));
1099                                            XLookupString((XKeyEvent *) & xevent,
1100                                                          str, sizeof(str), &keysym, NULL);
1101                                    }
1102    
1103                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,
1104                                                 flags | button,                                             get_ksname(keysym)));
                                                xevent.xbutton.x,  
                                                xevent.xbutton.y);  
                                 break;  
1105    
1106                          case MotionNotify:                                  ev_time = time(NULL);
1107                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
1108                                                 MOUSE_FLAG_MOVE,                                          break;
                                                xevent.xmotion.x,  
                                                xevent.xmotion.y);  
                                 break;  
1109    
1110                          case EnterNotify:                                  tr = xkeymap_translate_key(keysym,
1111                                  XGrabKeyboard(display, wnd, True,                                                             xevent.xkey.keycode, xevent.xkey.state);
                                               GrabModeAsync, GrabModeAsync,  
                                               CurrentTime);  
1112    
1113                                  xwin_mod_update(xevent.xcrossing.state,                                  if (tr.scancode == 0)
1114                                                  ev_time);                                          break;
                                 break;  
1115    
1116                          case LeaveNotify:                                  save_remote_modifiers(tr.scancode);
1117                                  XUngrabKeyboard(display, CurrentTime);                                  ensure_remote_modifiers(ev_time, tr);
1118                                  break;                                  rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
1119                                    restore_remote_modifiers(ev_time, tr.scancode);
1120    
                         case Expose:  
                                 XCopyArea(display, backstore, wnd, gc,  
                                           xevent.xexpose.x, xevent.xexpose.y,  
                                           xevent.xexpose.width,  
                                           xevent.xexpose.height,  
                                           xevent.xexpose.x, xevent.xexpose.y);  
1121                                  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;  
   
         }  
1122    
1123                            case KeyRelease:
1124                                    g_last_gesturetime = xevent.xkey.time;
1125                                    XLookupString((XKeyEvent *) & xevent, str,
1126                                                  sizeof(str), &keysym, NULL);
1127    
1128          if (!(ShiftMask & state) && (key_down_state & DShift1Mask))                                  DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
1129          {                                             get_ksname(keysym)));
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x2a,  
                                0);  
                 key_down_state &= ~DShift1Mask;  
1130    
1131          }                                  ev_time = time(NULL);
1132                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
1133                                            break;
1134    
1135          if (!(ControlMask & state) && (key_down_state & DControl1Mask))                                  tr = xkeymap_translate_key(keysym,
1136          {                                                             xevent.xkey.keycode, xevent.xkey.state);
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x1d,  
                                0);  
                 key_down_state &= ~DControl1Mask;  
1137    
1138          }                                  if (tr.scancode == 0)
1139                                            break;
1140    
1141          if (!(Mod1Mask & state) && (key_down_state & DMod1Mask))                                  rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
1142          {                                  break;
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x38,  
                                0);  
                 key_down_state &= ~DMod1Mask;  
1143    
1144          }                          case ButtonPress:
1145                                    flags = MOUSE_FLAG_DOWN;
1146                                    /* fall through */
1147    
1148          if (!(Mod2Mask & state) && (key_down_state & DMod2Mask))                          case ButtonRelease:
1149          {                                  g_last_gesturetime = xevent.xbutton.time;
1150                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0xb8,                                  button = xkeymap_translate_button(xevent.xbutton.button);
1151                                 0);                                  if (button == 0)
1152                  key_down_state &= ~DMod2Mask;                                          break;
         }  
 }  
1153    
1154                                    /* If win_button_size is nonzero, enable single app mode */
1155                                    if (xevent.xbutton.y < g_win_button_size)
1156                                    {
1157                                            /* Stop moving window when button is released, regardless of cursor position */
1158                                            if (g_moving_wnd && (xevent.type == ButtonRelease))
1159                                                    g_moving_wnd = False;
1160    
1161  void                                          /*  Check from right to left: */
 xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode)  
 {  
1162    
1163          switch (scancode)                                          if (xevent.xbutton.x >= g_width - g_win_button_size)
1164          {                                          {
1165                  case 0x2a:                                                  /* The close button, continue */
1166                          key_down_state |= DShift1Mask;                                                  ;
1167                          break;                                          }
1168                  case 0x36:                                          else if (xevent.xbutton.x >=
1169                          key_down_state |= DShift2Mask;                                                   g_width - g_win_button_size * 2)
1170                          break;                                          {
1171                  case 0x1d:                                                  /* The maximize/restore button. Do not send to
1172                          key_down_state |= DControl1Mask;                                                     server.  It might be a good idea to change the
1173                          break;                                                     cursor or give some other visible indication
1174                  case 0x9d:                                                     that rdesktop inhibited this click */
1175                          key_down_state |= DControl2Mask;                                                  break;
1176                          break;                                          }
1177                  case 0x3a:                                          else if (xevent.xbutton.x >=
1178                          key_down_state ^= DLockMask;                                                   g_width - g_win_button_size * 3)
1179                          break;                                          {
1180                  case 0x45:                                                  /* The minimize button. Iconify window. */
1181                          key_down_state ^= DNumLockMask;                                                  XIconifyWindow(g_display, g_wnd,
1182                          break;                                                                 DefaultScreen(g_display));
1183                  case 0x38:                                                  break;
1184                          key_down_state |= DMod1Mask;                                          }
1185                          break;                                          else if (xevent.xbutton.x <= g_win_button_size)
1186                  case 0xb8:                                          {
1187                          key_down_state |= DMod2Mask;                                                  /* The system menu. Ignore. */
1188                          break;                                                  break;
1189          }                                          }
1190                                            else
1191                                            {
1192                                                    /* The title bar. */
1193                                                    if ((xevent.type == ButtonPress) && !g_fullscreen
1194                                                        && g_hide_decorations)
1195                                                    {
1196                                                            g_moving_wnd = True;
1197                                                            g_move_x_offset = xevent.xbutton.x;
1198                                                            g_move_y_offset = xevent.xbutton.y;
1199                                                    }
1200                                                    break;
1201    
1202          if ((numlock_modifier_mask && state)                                          }
1203              && !(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;  
         }  
1204    
1205          if ((LockMask & state) && !(key_down_state & DLockMask))                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1206          {                                                 flags | button, xevent.xbutton.x, xevent.xbutton.y);
1207                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);                                  break;
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,  
                                KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);  
                 key_down_state |= DLockMask;  
1208    
1209          }                          case MotionNotify:
1210                                    if (g_moving_wnd)
1211                                    {
1212                                            XMoveWindow(g_display, g_wnd,
1213                                                        xevent.xmotion.x_root - g_move_x_offset,
1214                                                        xevent.xmotion.y_root - g_move_y_offset);
1215                                            break;
1216                                    }
1217    
1218                                    if (g_fullscreen && !g_focused)
1219                                            XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,
1220                                                           CurrentTime);
1221                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1222                                                   MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
1223                                    break;
1224    
1225          if ((ShiftMask & state)                          case FocusIn:
1226              && !((key_down_state & DShift1Mask)                                  if (xevent.xfocus.mode == NotifyGrab)
1227                   || (key_down_state & DShift2Mask)))                                          break;
1228          {                                  g_focused = True;
1229                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,                                  reset_modifier_keys();
1230                                 0x2a, 0);                                  if (g_grab_keyboard && g_mouse_in_wnd)
1231                  key_down_state |= DShift1Mask;                                          XGrabKeyboard(g_display, g_wnd, True,
1232                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
1233                                    break;
1234    
1235          }                          case FocusOut:
1236                                    if (xevent.xfocus.mode == NotifyUngrab)
1237                                            break;
1238                                    g_focused = False;
1239                                    if (xevent.xfocus.mode == NotifyWhileGrabbed)
1240                                            XUngrabKeyboard(g_display, CurrentTime);
1241                                    break;
1242    
1243          if ((ControlMask & state)                          case EnterNotify:
1244              && !((key_down_state & DControl1Mask)                                  /* we only register for this event when in fullscreen mode */
1245                   || (key_down_state & DControl2Mask)))                                  /* or grab_keyboard */
1246          {                                  g_mouse_in_wnd = True;
1247                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,                                  if (g_fullscreen)
1248                                 0x1d, 0);                                  {
1249                  key_down_state |= DControl1Mask;                                          XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,
1250                                                           CurrentTime);
1251                                            break;
1252                                    }
1253                                    if (g_focused)
1254                                            XGrabKeyboard(g_display, g_wnd, True,
1255                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
1256                                    break;
1257    
1258          }                          case LeaveNotify:
1259                                    /* we only register for this event when grab_keyboard */
1260                                    g_mouse_in_wnd = False;
1261                                    XUngrabKeyboard(g_display, CurrentTime);
1262                                    break;
1263    
1264          if ((Mod1Mask & state) && !(key_down_state & DMod1Mask))                          case Expose:
1265          {                                  XCopyArea(g_display, g_backstore, g_wnd, g_gc,
1266                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,                                            xevent.xexpose.x, xevent.xexpose.y,
1267                                 0x38, 0);                                            xevent.xexpose.width,
1268                  key_down_state |= DMod1Mask;                                            xevent.xexpose.height,
1269                                              xevent.xexpose.x, xevent.xexpose.y);
1270                                    break;
1271    
1272          }                          case MappingNotify:
1273                                    /* Refresh keyboard mapping if it has changed. This is important for
1274                                       Xvnc, since it allocates keycodes dynamically */
1275                                    if (xevent.xmapping.request == MappingKeyboard
1276                                        || xevent.xmapping.request == MappingModifier)
1277                                            XRefreshKeyboardMapping(&xevent.xmapping);
1278    
1279          if ((Mod2Mask & state) && !(key_down_state & DMod2Mask))                                  if (xevent.xmapping.request == MappingModifier)
1280          {                                  {
1281                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN,                                          XFreeModifiermap(g_mod_map);
1282                                 0xb8, 0);                                          g_mod_map = XGetModifierMapping(g_display);
1283                  key_down_state |= DMod2Mask;                                  }
1284                                    break;
1285    
1286                                    /* clipboard stuff */
1287                            case SelectionNotify:
1288                                    xclip_handle_SelectionNotify(&xevent.xselection);
1289                                    break;
1290                            case SelectionRequest:
1291                                    xclip_handle_SelectionRequest(&xevent.xselectionrequest);
1292                                    break;
1293                            case SelectionClear:
1294                                    xclip_handle_SelectionClear();
1295                                    break;
1296                            case PropertyNotify:
1297                                    xclip_handle_PropertyNotify(&xevent.xproperty);
1298                                    break;
1299                    }
1300          }          }
1301            /* Keep going */
1302            return 1;
1303  }  }
1304    
1305  void  /* Returns 0 after user quit, 1 otherwise */
1306    int
1307  ui_select(int rdp_socket)  ui_select(int rdp_socket)
1308  {  {
1309          int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;          int n;
1310          fd_set rfds;          fd_set rfds, wfds;
1311            struct timeval tv;
1312          FD_ZERO(&rfds);          BOOL s_timeout = False;
1313    
1314          while (True)          while (True)
1315          {          {
1316                    n = (rdp_socket > g_x_socket) ? rdp_socket : g_x_socket;
1317                    /* Process any events already waiting */
1318                    if (!xwin_process_events())
1319                            /* User quit */
1320                            return 0;
1321    
1322                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
1323                    FD_ZERO(&wfds);
1324                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
1325                  if (display != NULL)                  FD_SET(g_x_socket, &rfds);
1326    
1327    #ifdef WITH_RDPSND
1328                    /* FIXME: there should be an API for registering fds */
1329                    if (g_dsp_busy)
1330                  {                  {
1331                          FD_SET(x_socket, &rfds);                          FD_SET(g_dsp_fd, &wfds);
1332                          XFlush(display);                          n = (g_dsp_fd > n) ? g_dsp_fd : n;
1333                  }                  }
1334    #endif
1335                    /* default timeout */
1336                    tv.tv_sec = 60;
1337                    tv.tv_usec = 0;
1338    
1339                    /* add redirection handles */
1340                    rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
1341    
1342                  switch (select(n, &rfds, NULL, NULL, NULL))                  n++;
1343    
1344                    switch (select(n, &rfds, &wfds, NULL, &tv))
1345                  {                  {
1346                          case -1:                          case -1:
1347                                  error("select: %s\n", strerror(errno));                                  error("select: %s\n", strerror(errno));
1348    
1349                          case 0:                          case 0:
1350                                    /* TODO: if tv.tv_sec just times out
1351                                     * we will segfault.
1352                                     * FIXME:
1353                                     */
1354                                    //s_timeout = True;
1355                                    //rdpdr_check_fds(&rfds, &wfds, (BOOL) True);
1356                                  continue;                                  continue;
1357                  }                  }
1358    
1359                  if (FD_ISSET(x_socket, &rfds))                  rdpdr_check_fds(&rfds, &wfds, (BOOL) False);
                         xwin_process_events();  
1360    
1361                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
1362                          return;                          return 1;
1363    
1364    #ifdef WITH_RDPSND
1365                    if (g_dsp_busy && FD_ISSET(g_dsp_fd, &wfds))
1366                            wave_out_play();
1367    #endif
1368          }          }
1369  }  }
1370    
1371  void  void
1372  ui_move_pointer(int x, int y)  ui_move_pointer(int x, int y)
1373  {  {
1374          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);          XWarpPointer(g_display, g_wnd, g_wnd, 0, 0, 0, 0, x, y);
1375  }  }
1376    
1377  HBITMAP  HBITMAP
# Line 761  ui_create_bitmap(int width, int height, Line 1380  ui_create_bitmap(int width, int height,
1380          XImage *image;          XImage *image;
1381          Pixmap bitmap;          Pixmap bitmap;
1382          uint8 *tdata;          uint8 *tdata;
1383            int bitmap_pad;
1384    
1385            if (g_server_bpp == 8)
1386            {
1387                    bitmap_pad = 8;
1388            }
1389            else
1390            {
1391                    bitmap_pad = g_bpp;
1392    
1393          tdata = (owncolmap ? data : translate_image(width, height, data));                  if (g_bpp == 24)
1394          bitmap = XCreatePixmap(display, wnd, width, height, depth);                          bitmap_pad = 32;
1395          image = XCreateImage(display, visual, depth, ZPixmap,          }
                              0, tdata, width, height, 8, 0);  
1396    
1397          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          tdata = (g_owncolmap ? data : translate_image(width, height, data));
1398            bitmap = XCreatePixmap(g_display, g_wnd, width, height, g_depth);
1399            image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1400                                 (char *) tdata, width, height, bitmap_pad, 0);
1401    
1402            XPutImage(g_display, bitmap, g_gc, image, 0, 0, 0, 0, width, height);
1403    
1404          XFree(image);          XFree(image);
1405          if (!owncolmap)          if (tdata != data)
1406                  xfree(tdata);                  xfree(tdata);
1407          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
1408  }  }
1409    
1410  void  void
1411  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)  
1412  {  {
1413          XImage *image;          XImage *image;
1414          uint8 *tdata;          uint8 *tdata;
1415            int bitmap_pad;
1416    
1417          tdata = (owncolmap ? data : translate_image(width, height, data));          if (g_server_bpp == 8)
1418          image = XCreateImage(display, visual, depth, ZPixmap,          {
1419                               0, tdata, width, height, 8, 0);                  bitmap_pad = 8;
1420            }
1421            else
1422            {
1423                    bitmap_pad = g_bpp;
1424    
1425                    if (g_bpp == 24)
1426                            bitmap_pad = 32;
1427            }
1428    
1429          if (ownbackstore)          tdata = (g_owncolmap ? data : translate_image(width, height, data));
1430            image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1431                                 (char *) tdata, width, height, bitmap_pad, 0);
1432    
1433            if (g_ownbackstore)
1434          {          {
1435                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_backstore, g_gc, image, 0, 0, x, y, cx, cy);
1436                  XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);                  XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
1437          }          }
1438          else          else
1439          {          {
1440                  XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy);
1441          }          }
1442    
1443          XFree(image);          XFree(image);
1444          if (!owncolmap)          if (tdata != data)
1445                  xfree(tdata);                  xfree(tdata);
1446  }  }
1447    
1448  void  void
1449  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(HBITMAP bmp)
1450  {  {
1451          XFreePixmap(display, (Pixmap) bmp);          XFreePixmap(g_display, (Pixmap) bmp);
1452  }  }
1453    
1454  HGLYPH  HGLYPH
# Line 817  ui_create_glyph(int width, int height, u Line 1461  ui_create_glyph(int width, int height, u
1461    
1462          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1463    
1464          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(g_display, g_wnd, width, height, 1);
1465          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(g_display, bitmap, 0, NULL);
1466    
1467          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(g_display, g_visual, 1, ZPixmap, 0, (char *) data,
1468                               data, width, height, 8, scanline);                               width, height, 8, scanline);
1469          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
1470          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
1471          XInitImage(image);          XInitImage(image);
1472    
1473          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(g_display, bitmap, gc, image, 0, 0, 0, 0, width, height);
1474    
1475          XFree(image);          XFree(image);
1476          XFreeGC(display, gc);          XFreeGC(g_display, gc);
1477          return (HGLYPH) bitmap;          return (HGLYPH) bitmap;
1478  }  }
1479    
1480  void  void
1481  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
1482  {  {
1483          XFreePixmap(display, (Pixmap) glyph);          XFreePixmap(g_display, (Pixmap) glyph);
1484  }  }
1485    
1486  HCURSOR  HCURSOR
1487  ui_create_cursor(unsigned int x, unsigned int y, int width,  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
1488                   int height, uint8 * andmask, uint8 * xormask)                   uint8 * andmask, uint8 * xormask)
1489  {  {
1490          HGLYPH maskglyph, cursorglyph;          HGLYPH maskglyph, cursorglyph;
1491          XColor bg, fg;          XColor bg, fg;
# Line 855  ui_create_cursor(unsigned int x, unsigne Line 1499  ui_create_cursor(unsigned int x, unsigne
1499          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1500          offset = scanline * height;          offset = scanline * height;
1501    
1502          cursor = xmalloc(offset);          cursor = (uint8 *) xmalloc(offset);
1503          memset(cursor, 0, offset);          memset(cursor, 0, offset);
1504    
1505          mask = xmalloc(offset);          mask = (uint8 *) xmalloc(offset);
1506          memset(mask, 0, offset);          memset(mask, 0, offset);
1507    
1508          /* 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 1543  ui_create_cursor(unsigned int x, unsigne
1543          cursorglyph = ui_create_glyph(width, height, cursor);          cursorglyph = ui_create_glyph(width, height, cursor);
1544          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
1545    
1546          xcursor = XCreatePixmapCursor(display, (Pixmap) cursorglyph,          xcursor =
1547                                        (Pixmap) maskglyph, &fg, &bg, x, y);                  XCreatePixmapCursor(g_display, (Pixmap) cursorglyph,
1548                                        (Pixmap) maskglyph, &fg, &bg, x, y);
1549    
1550          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
1551          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
# Line 912  ui_create_cursor(unsigned int x, unsigne Line 1557  ui_create_cursor(unsigned int x, unsigne
1557  void  void
1558  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
1559  {  {
1560          XDefineCursor(display, wnd, (Cursor) cursor);          g_current_cursor = (Cursor) cursor;
1561            XDefineCursor(g_display, g_wnd, g_current_cursor);
1562  }  }
1563    
1564  void  void
1565  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_cursor(HCURSOR cursor)
1566  {  {
1567          XFreeCursor(display, (Cursor) cursor);          XFreeCursor(g_display, (Cursor) cursor);
1568    }
1569    
1570    void
1571    ui_set_null_cursor(void)
1572    {
1573            ui_set_cursor(g_null_cursor);
1574  }  }
1575    
1576  #define MAKE_XCOLOR(xc,c) \  #define MAKE_XCOLOR(xc,c) \
# Line 927  ui_destroy_cursor(HCURSOR cursor) Line 1579  ui_destroy_cursor(HCURSOR cursor)
1579                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
1580                  (xc)->flags = DoRed | DoGreen | DoBlue;                  (xc)->flags = DoRed | DoGreen | DoBlue;
1581    
1582    
1583  HCOLOURMAP  HCOLOURMAP
1584  ui_create_colourmap(COLOURMAP * colours)  ui_create_colourmap(COLOURMAP * colours)
1585  {  {
1586          COLOURENTRY *entry;          COLOURENTRY *entry;
1587          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
1588            if (!g_owncolmap)
1589            {
1590                    uint32 *map = (uint32 *) xmalloc(sizeof(*g_colmap) * ncolours);
1591                    XColor xentry;
1592                    XColor xc_cache[256];
1593                    uint32 colour;
1594                    int colLookup = 256;
1595                    for (i = 0; i < ncolours; i++)
1596                    {
1597                            entry = &colours->colours[i];
1598                            MAKE_XCOLOR(&xentry, entry);
1599    
1600                            if (XAllocColor(g_display, g_xcolmap, &xentry) == 0)
1601                            {
1602                                    /* Allocation failed, find closest match. */
1603                                    int j = 256;
1604                                    int nMinDist = 3 * 256 * 256;
1605                                    long nDist = nMinDist;
1606    
1607          if (owncolmap)                                  /* only get the colors once */
1608                                    while (colLookup--)
1609                                    {
1610                                            xc_cache[colLookup].pixel = colLookup;
1611                                            xc_cache[colLookup].red = xc_cache[colLookup].green =
1612                                                    xc_cache[colLookup].blue = 0;
1613                                            xc_cache[colLookup].flags = 0;
1614                                            XQueryColor(g_display,
1615                                                        DefaultColormap(g_display,
1616                                                                        DefaultScreen(g_display)),
1617                                                        &xc_cache[colLookup]);
1618                                    }
1619                                    colLookup = 0;
1620    
1621                                    /* approximate the pixel */
1622                                    while (j--)
1623                                    {
1624                                            if (xc_cache[j].flags)
1625                                            {
1626                                                    nDist = ((long) (xc_cache[j].red >> 8) -
1627                                                             (long) (xentry.red >> 8)) *
1628                                                            ((long) (xc_cache[j].red >> 8) -
1629                                                             (long) (xentry.red >> 8)) +
1630                                                            ((long) (xc_cache[j].green >> 8) -
1631                                                             (long) (xentry.green >> 8)) *
1632                                                            ((long) (xc_cache[j].green >> 8) -
1633                                                             (long) (xentry.green >> 8)) +
1634                                                            ((long) (xc_cache[j].blue >> 8) -
1635                                                             (long) (xentry.blue >> 8)) *
1636                                                            ((long) (xc_cache[j].blue >> 8) -
1637                                                             (long) (xentry.blue >> 8));
1638                                            }
1639                                            if (nDist < nMinDist)
1640                                            {
1641                                                    nMinDist = nDist;
1642                                                    xentry.pixel = j;
1643                                            }
1644                                    }
1645                            }
1646                            colour = xentry.pixel;
1647    
1648                            /* update our cache */
1649                            if (xentry.pixel < 256)
1650                            {
1651                                    xc_cache[xentry.pixel].red = xentry.red;
1652                                    xc_cache[xentry.pixel].green = xentry.green;
1653                                    xc_cache[xentry.pixel].blue = xentry.blue;
1654    
1655                            }
1656    
1657                            map[i] = colour;
1658                    }
1659                    return map;
1660            }
1661            else
1662          {          {
1663                  XColor *xcolours, *xentry;                  XColor *xcolours, *xentry;
1664                  Colormap map;                  Colormap map;
1665    
1666                  xcolours = xmalloc(sizeof(XColor) * ncolours);                  xcolours = (XColor *) xmalloc(sizeof(XColor) * ncolours);
1667                  for (i = 0; i < ncolours; i++)                  for (i = 0; i < ncolours; i++)
1668                  {                  {
1669                          entry = &colours->colours[i];                          entry = &colours->colours[i];
# Line 947  ui_create_colourmap(COLOURMAP * colours) Line 1672  ui_create_colourmap(COLOURMAP * colours)
1672                          MAKE_XCOLOR(xentry, entry);                          MAKE_XCOLOR(xentry, entry);
1673                  }                  }
1674    
1675                  map = XCreateColormap(display, wnd, visual, AllocAll);                  map = XCreateColormap(g_display, g_wnd, g_visual, AllocAll);
1676                  XStoreColors(display, map, xcolours, ncolours);                  XStoreColors(g_display, map, xcolours, ncolours);
1677    
1678                  xfree(xcolours);                  xfree(xcolours);
1679                  return (HCOLOURMAP) map;                  return (HCOLOURMAP) map;
1680          }          }
         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;  
         }  
1681  }  }
1682    
1683  void  void
1684  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
1685  {  {
1686          if (owncolmap)          if (!g_owncolmap)
                 XFreeColormap(display, (Colormap) map);  
         else  
1687                  xfree(map);                  xfree(map);
1688            else
1689                    XFreeColormap(g_display, (Colormap) map);
1690  }  }
1691    
1692  void  void
1693  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
1694  {  {
1695          if (owncolmap)          if (!g_owncolmap)
1696                  XSetWindowColormap(display, wnd, (Colormap) map);          {
1697                    if (g_colmap)
1698                            xfree(g_colmap);
1699    
1700                    g_colmap = (uint32 *) map;
1701            }
1702          else          else
1703                  colmap = map;                  XSetWindowColormap(g_display, g_wnd, (Colormap) map);
1704  }  }
1705    
1706  void  void
# Line 1004  ui_set_clip(int x, int y, int cx, int cy Line 1712  ui_set_clip(int x, int y, int cx, int cy
1712          rect.y = y;          rect.y = y;
1713          rect.width = cx;          rect.width = cx;
1714          rect.height = cy;          rect.height = cy;
1715          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);
1716  }  }
1717    
1718  void  void
1719  ui_reset_clip()  ui_reset_clip(void)
1720  {  {
1721          XRectangle rect;          XRectangle rect;
1722    
1723          rect.x = 0;          rect.x = 0;
1724          rect.y = 0;          rect.y = 0;
1725          rect.width = width;          rect.width = g_width;
1726          rect.height = height;          rect.height = g_height;
1727          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);
1728  }  }
1729    
1730  void  void
1731  ui_bell()  ui_bell(void)
1732  {  {
1733          XBell(display, 0);          XBell(g_display, 0);
1734  }  }
1735    
1736  void  void
# Line 1034  ui_destblt(uint8 opcode, Line 1742  ui_destblt(uint8 opcode,
1742          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1743  }  }
1744    
1745    static uint8 hatch_patterns[] = {
1746            0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0 - bsHorizontal */
1747            0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 1 - bsVertical */
1748            0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, /* 2 - bsFDiagonal */
1749            0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* 3 - bsBDiagonal */
1750            0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, /* 4 - bsCross */
1751            0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81  /* 5 - bsDiagCross */
1752    };
1753    
1754  void  void
1755  ui_patblt(uint8 opcode,  ui_patblt(uint8 opcode,
1756            /* 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 1768  ui_patblt(uint8 opcode,
1768                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1769                          break;                          break;
1770    
1771                    case 2: /* Hatch */
1772                            fill = (Pixmap) ui_create_glyph(8, 8,
1773                                                            hatch_patterns + brush->pattern[0] * 8);
1774                            SET_FOREGROUND(fgcolour);
1775                            SET_BACKGROUND(bgcolour);
1776                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
1777                            XSetStipple(g_display, g_gc, fill);
1778                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
1779                            FILL_RECTANGLE(x, y, cx, cy);
1780                            XSetFillStyle(g_display, g_gc, FillSolid);
1781                            XSetTSOrigin(g_display, g_gc, 0, 0);
1782                            ui_destroy_glyph((HGLYPH) fill);
1783                            break;
1784    
1785                  case 3: /* Pattern */                  case 3: /* Pattern */
1786                          for (i = 0; i != 8; i++)                          for (i = 0; i != 8; i++)
1787                                  ipattern[7 - i] = brush->pattern[i];                                  ipattern[7 - i] = brush->pattern[i];
# Line 1058  ui_patblt(uint8 opcode, Line 1789  ui_patblt(uint8 opcode,
1789    
1790                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(bgcolour);
1791                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
1792                          XSetFillStyle(display, gc, FillOpaqueStippled);                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
1793                          XSetStipple(display, gc, fill);                          XSetStipple(g_display, g_gc, fill);
1794                          XSetTSOrigin(display, gc, brush->xorigin,                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
                                      brush->yorigin);  
1795    
1796                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1797    
1798                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(g_display, g_gc, FillSolid);
1799                            XSetTSOrigin(g_display, g_gc, 0, 0);
1800                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH) fill);
1801                          break;                          break;
1802    
# Line 1082  ui_screenblt(uint8 opcode, Line 1813  ui_screenblt(uint8 opcode,
1813               /* src */ int srcx, int srcy)               /* src */ int srcx, int srcy)
1814  {  {
1815          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1816          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          if (g_ownbackstore)
1817          if (ownbackstore)          {
1818                  XCopyArea(display, backstore, backstore, gc, srcx, srcy,                  XCopyArea(g_display, g_backstore, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
1819                            cx, cy, x, y);                  XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x, y);
1820            }
1821            else
1822            {
1823                    XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
1824            }
1825          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1826  }  }
1827    
# Line 1095  ui_memblt(uint8 opcode, Line 1831  ui_memblt(uint8 opcode,
1831            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
1832  {  {
1833          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1834          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(g_display, (Pixmap) src, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
1835          if (ownbackstore)          if (g_ownbackstore)
1836                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy,                  XCopyArea(g_display, (Pixmap) src, g_backstore, g_gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1837          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1838  }  }
1839    
# Line 1115  ui_triblt(uint8 opcode, Line 1850  ui_triblt(uint8 opcode,
1850          {          {
1851                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
1852                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1853                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1854                          break;                          break;
1855    
1856                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
1857                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1858                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1859                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1860                          break;                          break;
1861    
1862                  case 0xc0:      /* PSa */                  case 0xc0:      /* PSa */
1863                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1864                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
1865                          break;                          break;
1866    
1867                  default:                  default:
# Line 1146  ui_line(uint8 opcode, Line 1877  ui_line(uint8 opcode,
1877  {  {
1878          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1879          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
1880          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(g_display, g_wnd, g_gc, startx, starty, endx, endy);
1881          if (ownbackstore)          if (g_ownbackstore)
1882                  XDrawLine(display, backstore, gc, startx, starty, endx, endy);                  XDrawLine(g_display, g_backstore, g_gc, startx, starty, endx, endy);
1883          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1884  }  }
1885    
# Line 1161  ui_rect( Line 1892  ui_rect(
1892          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
1893  }  }
1894    
1895    /* warning, this function only draws on wnd or backstore, not both */
1896  void  void
1897  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1898                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1899                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1900                int fgcolour)                int bgcolour, int fgcolour)
1901  {  {
1902          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
1903          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
1904    
1905          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)          XSetFillStyle(g_display, g_gc,
1906                        ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1907          XSetStipple(display, gc, (Pixmap) glyph);          XSetStipple(g_display, g_gc, (Pixmap) glyph);
1908          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(g_display, g_gc, x, y);
1909    
1910          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
1911    
1912          XSetFillStyle(display, gc, FillSolid);          XSetFillStyle(g_display, g_gc, FillSolid);
1913  }  }
1914    
1915  #define DO_GLYPH(ttext,idx) \  #define DO_GLYPH(ttext,idx) \
1916  {\  {\
1917    glyph = cache_get_font (font, ttext[idx]);\    glyph = cache_get_font (font, ttext[idx]);\
1918    if (!(flags & TEXT2_IMPLICIT_X))\    if (!(flags & TEXT2_IMPLICIT_X))\
1919      {\
1920        xyoffset = ttext[++idx];\
1921        if ((xyoffset & 0x80))\
1922      {\      {\
1923        xyoffset = ttext[++idx];\        if (flags & TEXT2_VERTICAL)\
1924        if ((xyoffset & 0x80))\          y += ttext[idx+1] | (ttext[idx+2] << 8);\
         {\  
           if (flags & TEXT2_VERTICAL) \  
             y += ttext[++idx] | (ttext[++idx] << 8);\  
           else\  
             x += ttext[++idx] | (ttext[++idx] << 8);\  
         }\  
1925        else\        else\
1926          {\          x += ttext[idx+1] | (ttext[idx+2] << 8);\
1927            if (flags & TEXT2_VERTICAL) \        idx += 2;\
             y += xyoffset;\  
           else\  
             x += xyoffset;\  
         }\  
1928      }\      }\
1929    if (glyph != NULL)\      else\
1930      {\      {\
1931        ui_draw_glyph (mixmode, x + (short) glyph->offset,\        if (flags & TEXT2_VERTICAL)\
1932                       y + (short) glyph->baseline,\          y += xyoffset;\
1933                       glyph->width, glyph->height,\        else\
1934                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\          x += xyoffset;\
       if (flags & TEXT2_IMPLICIT_X)\  
         x += glyph->width;\  
1935      }\      }\
1936      }\
1937      if (glyph != NULL)\
1938      {\
1939        x1 = x + glyph->offset;\
1940        y1 = y + glyph->baseline;\
1941        XSetStipple(g_display, g_gc, (Pixmap) glyph->pixmap);\
1942        XSetTSOrigin(g_display, g_gc, x1, y1);\
1943        FILL_RECTANGLE_BACKSTORE(x1, y1, glyph->width, glyph->height);\
1944        if (flags & TEXT2_IMPLICIT_X)\
1945          x += glyph->width;\
1946      }\
1947  }  }
1948    
1949  void  void
1950  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,
1951               int clipx, int clipy, int clipcx, int clipcy, int boxx,               int clipx, int clipy, int clipcx, int clipcy,
1952               int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1953               int fgcolour, uint8 * text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1954  {  {
1955          FONTGLYPH *glyph;          FONTGLYPH *glyph;
1956          int i, j, xyoffset;          int i, j, xyoffset, x1, y1;
1957          DATABLOB *entry;          DATABLOB *entry;
1958    
1959          SET_FOREGROUND(bgcolour);          SET_FOREGROUND(bgcolour);
1960    
1961            /* Sometimes, the boxcx value is something really large, like
1962               32691. This makes XCopyArea fail with Xvnc. The code below
1963               is a quick fix. */
1964            if (boxx + boxcx > g_width)
1965                    boxcx = g_width - boxx;
1966    
1967          if (boxcx > 1)          if (boxcx > 1)
1968          {          {
1969                  FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);
1970          }          }
1971          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
1972          {          {
1973                  FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
1974          }          }
1975    
1976            SET_FOREGROUND(fgcolour);
1977            SET_BACKGROUND(bgcolour);
1978            XSetFillStyle(g_display, g_gc, FillStippled);
1979    
1980          /* Paint text, character by character */          /* Paint text, character by character */
1981          for (i = 0; i < length;)          for (i = 0; i < length;)
1982          {          {
# Line 1240  ui_draw_text(uint8 font, uint8 flags, in Line 1984  ui_draw_text(uint8 font, uint8 flags, in
1984                  {                  {
1985                          case 0xff:                          case 0xff:
1986                                  if (i + 2 < length)                                  if (i + 2 < length)
1987                                          cache_put_text(text[i + 1], text,                                          cache_put_text(text[i + 1], text, text[i + 2]);
                                                        text[i + 2]);  
1988                                  else                                  else
1989                                  {                                  {
1990                                          error("this shouldn't be happening\n");                                          error("this shouldn't be happening\n");
1991                                          break;                                          exit(1);
1992                                  }                                  }
1993                                  /* this will move pointer from start to first character after FF command */                                  /* this will move pointer from start to first character after FF command */
1994                                  length -= i + 3;                                  length -= i + 3;
# Line 1258  ui_draw_text(uint8 font, uint8 flags, in Line 2001  ui_draw_text(uint8 font, uint8 flags, in
2001                                  if (entry != NULL)                                  if (entry != NULL)
2002                                  {                                  {
2003                                          if ((((uint8 *) (entry->data))[1] ==                                          if ((((uint8 *) (entry->data))[1] ==
2004                                               0)                                               0) && (!(flags & TEXT2_IMPLICIT_X)))
                                             && (!(flags & TEXT2_IMPLICIT_X)))  
2005                                          {                                          {
2006                                                  if (flags & TEXT2_VERTICAL)                                                  if (flags & TEXT2_VERTICAL)
2007                                                          y += text[i + 2];                                                          y += text[i + 2];
2008                                                  else                                                  else
2009                                                          x += text[i + 2];                                                          x += text[i + 2];
2010                                          }                                          }
                                         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;  
2011                                          for (j = 0; j < entry->size; j++)                                          for (j = 0; j < entry->size; j++)
2012                                                  DO_GLYPH(((uint8 *) (entry->                                                  DO_GLYPH(((uint8 *) (entry->data)), j);
                                                                      data)),  
                                                          j);  
2013                                  }                                  }
2014                                    if (i + 2 < length)
2015                                            i += 3;
2016                                    else
2017                                            i += 2;
2018                                    length -= i;
2019                                    /* this will move pointer from start to first character after FE command */
2020                                    text = &(text[i]);
2021                                    i = 0;
2022                                  break;                                  break;
2023    
2024                          default:                          default:
# Line 1288  ui_draw_text(uint8 font, uint8 flags, in Line 2028  ui_draw_text(uint8 font, uint8 flags, in
2028                  }                  }
2029          }          }
2030    
2031            XSetFillStyle(g_display, g_gc, FillSolid);
2032    
2033            if (g_ownbackstore)
2034            {
2035                    if (boxcx > 1)
2036                            XCopyArea(g_display, g_backstore, g_wnd, g_gc, boxx,
2037                                      boxy, boxcx, boxcy, boxx, boxy);
2038                    else
2039                            XCopyArea(g_display, g_backstore, g_wnd, g_gc, clipx,
2040                                      clipy, clipcx, clipcy, clipx, clipy);
2041            }
2042  }  }
2043    
2044  void  void
# Line 1297  ui_desktop_save(uint32 offset, int x, in Line 2047  ui_desktop_save(uint32 offset, int x, in
2047          Pixmap pix;          Pixmap pix;
2048          XImage *image;          XImage *image;
2049    
2050          if (ownbackstore)          if (g_ownbackstore)
2051          {          {
2052                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,                  image = XGetImage(g_display, g_backstore, x, y, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
2053          }          }
2054          else          else
2055          {          {
2056                  pix = XCreatePixmap(display, wnd, cx, cy, depth);                  pix = XCreatePixmap(g_display, g_wnd, cx, cy, g_depth);
2057                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);                  XCopyArea(g_display, g_wnd, pix, g_gc, x, y, cx, cy, 0, 0);
2058                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,                  image = XGetImage(g_display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
2059                                    ZPixmap);                  XFreePixmap(g_display, pix);
                 XFreePixmap(display, pix);  
2060          }          }
2061    
2062          offset *= bpp / 8;          offset *= g_bpp / 8;
2063          cache_put_desktop(offset, cx, cy, image->bytes_per_line,          cache_put_desktop(offset, cx, cy, image->bytes_per_line, g_bpp / 8, (uint8 *) image->data);
                           bpp / 8, (uint8 *) image->data);  
2064    
2065          XDestroyImage(image);          XDestroyImage(image);
2066  }  }
# Line 1324  ui_desktop_restore(uint32 offset, int x, Line 2071  ui_desktop_restore(uint32 offset, int x,
2071          XImage *image;          XImage *image;
2072          uint8 *data;          uint8 *data;
2073    
2074          offset *= bpp / 8;          offset *= g_bpp / 8;
2075          data = cache_get_desktop(offset, cx, cy, bpp / 8);          data = cache_get_desktop(offset, cx, cy, g_bpp / 8);
2076          if (data == NULL)          if (data == NULL)
2077                  return;                  return;
2078    
2079          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
2080                               0, data, cx, cy, BitmapPad(display),                               (char *) data, cx, cy, BitmapPad(g_display), cx * g_bpp / 8);
                              cx * bpp / 8);  
2081    
2082          if (ownbackstore)          if (g_ownbackstore)
2083          {          {
2084                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_backstore, g_gc, image, 0, 0, x, y, cx, cy);
2085                  XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);                  XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
2086          }          }
2087          else          else
2088          {          {
2089                  XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy);
2090          }          }
2091    
2092          XFree(image);          XFree(image);

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

  ViewVC Help
Powered by ViewVC 1.1.26