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

Legend:
Removed from v.52  
changed lines
  Added in v.643

  ViewVC Help
Powered by ViewVC 1.1.26