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

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

  ViewVC Help
Powered by ViewVC 1.1.26