/[rdesktop]/sourceforge.net/branches/seamlessrdp-branch/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/branches/seamlessrdp-branch/rdesktop/xwin.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.35  
changed lines
  Added in v.788

  ViewVC Help
Powered by ViewVC 1.1.26