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

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

  ViewVC Help
Powered by ViewVC 1.1.26