/[rdesktop]/sourceforge.net/trunk/rdesktop/xwin.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/xwin.c

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

revision 376 by jsorg71, Mon May 19 21:36:33 2003 UTC revision 844 by jdmeijer, Thu Mar 10 22:48:15 2005 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     User interface services - X Window System     User interface services - X Window System
4     Copyright (C) Matthew Chapman 1999-2002     Copyright (C) Matthew Chapman 1999-2005
5    
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 20  Line 20 
20    
21  #include <X11/Xlib.h>  #include <X11/Xlib.h>
22  #include <X11/Xutil.h>  #include <X11/Xutil.h>
23    #include <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 int g_xpos;
34  extern BOOL fullscreen;  extern int g_ypos;
35  extern BOOL grab_keyboard;  extern BOOL g_sendmotion;
36  extern BOOL hide_decorations;  extern BOOL g_fullscreen;
37  extern char title[];  extern BOOL g_grab_keyboard;
38  extern int server_bpp;  extern BOOL g_hide_decorations;
39  extern int win_button_size;  extern char g_title[];
40  BOOL enable_compose = False;  extern int g_server_bpp;
41  BOOL focused;  extern int g_win_button_size;
42  BOOL mouse_in_wnd;  
43    Display *g_display;
44  Display *display;  Time g_last_gesturetime;
45  static int x_socket;  static int g_x_socket;
46  static Screen *screen;  static Screen *g_screen;
47  static Window wnd;  Window g_wnd;
48  static GC gc;  extern uint32 g_embed_wnd;
49  static Visual *visual;  BOOL g_enable_compose = False;
50  static int depth;  BOOL g_Unobscured;              /* used for screenblt */
51  static int bpp;  static GC g_gc = NULL;
52  static XIM IM;  static GC g_create_bitmap_gc = NULL;
53  static XIC IC;  static GC g_create_glyph_gc = NULL;
54  static XModifierKeymap *mod_map;  static Visual *g_visual;
55  static Cursor current_cursor;  static int g_depth;
56  static Atom protocol_atom, kill_atom;  static int g_bpp;
57    static XIM g_IM;
58    static XIC g_IC;
59    static XModifierKeymap *g_mod_map;
60    static Cursor g_current_cursor;
61    static HCURSOR g_null_cursor = NULL;
62    static Atom g_protocol_atom, g_kill_atom;
63    static BOOL g_focused;
64    static BOOL g_mouse_in_wnd;
65    static BOOL g_arch_match = False;       /* set to True if RGB XServer and little endian */
66    
67  /* endianness */  /* endianness */
68  static BOOL host_be;  static BOOL g_host_be;
69  static BOOL xserver_be;  static BOOL g_xserver_be;
70    static int g_red_shift_r, g_blue_shift_r, g_green_shift_r;
71    static int g_red_shift_l, g_blue_shift_l, g_green_shift_l;
72    
73  /* software backing store */  /* software backing store */
74  static BOOL ownbackstore;  extern BOOL g_ownbackstore;
75  static Pixmap backstore;  static Pixmap g_backstore = 0;
76    
77  /* Moving in single app mode */  /* Moving in single app mode */
78  static BOOL moving_wnd;  static BOOL g_moving_wnd;
79  static int move_x_offset = 0;  static int g_move_x_offset = 0;
80  static int move_y_offset = 0;  static int g_move_y_offset = 0;
81    
82    #ifdef WITH_RDPSND
83    extern int g_dsp_fd;
84    extern BOOL g_dsp_busy;
85    extern BOOL g_rdpsnd;
86    #endif
87    
88  /* MWM decorations */  /* MWM decorations */
89  #define MWM_HINTS_DECORATIONS   (1L << 1)  #define MWM_HINTS_DECORATIONS   (1L << 1)
# Line 85  typedef struct Line 106  typedef struct
106  }  }
107  PixelColour;  PixelColour;
108    
109    
110  #define FILL_RECTANGLE(x,y,cx,cy)\  #define FILL_RECTANGLE(x,y,cx,cy)\
111  { \  { \
112          XFillRectangle(display, wnd, gc, x, y, cx, cy); \          XFillRectangle(g_display, g_wnd, g_gc, x, y, cx, cy); \
113          if (ownbackstore) \          if (g_ownbackstore) \
114                  XFillRectangle(display, backstore, gc, x, y, cx, cy); \                  XFillRectangle(g_display, g_backstore, g_gc, x, y, cx, cy); \
115  }  }
116    
117  #define FILL_RECTANGLE_BACKSTORE(x,y,cx,cy)\  #define FILL_RECTANGLE_BACKSTORE(x,y,cx,cy)\
118  { \  { \
119          XFillRectangle(display, ownbackstore ? backstore : wnd, gc, x, y, cx, cy); \          XFillRectangle(g_display, g_ownbackstore ? g_backstore : g_wnd, g_gc, x, y, cx, cy); \
120    }
121    
122    #define FILL_POLYGON(p,np)\
123    { \
124            XFillPolygon(g_display, g_wnd, g_gc, p, np, Complex, CoordModePrevious); \
125            if (g_ownbackstore) \
126                    XFillPolygon(g_display, g_backstore, g_gc, p, np, Complex, CoordModePrevious); \
127    }
128    
129    #define DRAW_ELLIPSE(x,y,cx,cy,m)\
130    { \
131            switch (m) \
132            { \
133                    case 0: /* Outline */ \
134                            XDrawArc(g_display, g_wnd, g_gc, x, y, cx, cy, 0, 360*64); \
135                            if (g_ownbackstore) \
136                                    XDrawArc(g_display, g_backstore, g_gc, x, y, cx, cy, 0, 360*64); \
137                            break; \
138                    case 1: /* Filled */ \
139                            XFillArc(g_display, g_ownbackstore ? g_backstore : g_wnd, g_gc, x, y, \
140                                     cx, cy, 0, 360*64); \
141                            if (g_ownbackstore) \
142                                    XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y); \
143                            break; \
144            } \
145  }  }
146    
147  /* colour maps */  /* colour maps */
148  BOOL owncolmap = False;  extern BOOL g_owncolmap;
149  static Colormap xcolmap;  static Colormap g_xcolmap;
150  static uint32 *colmap;  static uint32 *g_colmap = NULL;
151    
152  #define TRANSLATE(col)          ( server_bpp != 8 ? translate_colour(col) : owncolmap ? col : translate_colour(colmap[col]) )  #define TRANSLATE(col)          ( g_server_bpp != 8 ? translate_colour(col) : g_owncolmap ? col : g_colmap[col] )
153  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));  #define SET_FOREGROUND(col)     XSetForeground(g_display, g_gc, TRANSLATE(col));
154  #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));  #define SET_BACKGROUND(col)     XSetBackground(g_display, g_gc, TRANSLATE(col));
155    
156  static int rop2_map[] = {  static int rop2_map[] = {
157          GXclear,                /* 0 */          GXclear,                /* 0 */
# Line 125  static int rop2_map[] = { Line 172  static int rop2_map[] = {
172          GXset                   /* 1 */          GXset                   /* 1 */
173  };  };
174    
175  #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]); }
176  #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); }
177    
178  static void  static void
179  mwm_hide_decorations(void)  mwm_hide_decorations(void)
# Line 139  mwm_hide_decorations(void) Line 186  mwm_hide_decorations(void)
186          motif_hints.decorations = 0;          motif_hints.decorations = 0;
187    
188          /* get the atom for the property */          /* get the atom for the property */
189          hintsatom = XInternAtom(display, "_MOTIF_WM_HINTS", False);          hintsatom = XInternAtom(g_display, "_MOTIF_WM_HINTS", False);
190          if (!hintsatom)          if (!hintsatom)
191          {          {
192                  warning("Failed to get atom _MOTIF_WM_HINTS: probably your window manager does not support MWM hints\n");                  warning("Failed to get atom _MOTIF_WM_HINTS: probably your window manager does not support MWM hints\n");
193                  return;                  return;
194          }          }
195    
196          XChangeProperty(display, wnd, hintsatom, hintsatom, 32, PropModeReplace,          XChangeProperty(g_display, g_wnd, hintsatom, hintsatom, 32, PropModeReplace,
197                          (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);                          (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
198  }  }
199    
200  static PixelColour  #define SPLITCOLOUR15(colour, rv) \
201  split_colour15(uint32 colour)  { \
202  {          rv.red = ((colour >> 7) & 0xf8) | ((colour >> 12) & 0x7); \
203          PixelColour rv;          rv.green = ((colour >> 2) & 0xf8) | ((colour >> 8) & 0x7); \
204          rv.red = (colour & 0x7c00) >> 10;          rv.blue = ((colour << 3) & 0xf8) | ((colour >> 2) & 0x7); \
         rv.red = (rv.red * 0xff) / 0x1f;  
         rv.green = (colour & 0x03e0) >> 5;  
         rv.green = (rv.green * 0xff) / 0x1f;  
         rv.blue = (colour & 0x1f);  
         rv.blue = (rv.blue * 0xff) / 0x1f;  
         return rv;  
 }  
   
 static PixelColour  
 split_colour16(uint32 colour)  
 {  
         PixelColour rv;  
         rv.red = (colour & 0xf800) >> 11;  
         rv.red = (rv.red * 0xff) / 0x1f;  
         rv.green = (colour & 0x07e0) >> 5;  
         rv.green = (rv.green * 0xff) / 0x3f;  
         rv.blue = (colour & 0x001f);  
         rv.blue = (rv.blue * 0xff) / 0x1f;  
         return rv;  
 }  
   
 static PixelColour  
 split_colour24(uint32 colour)  
 {  
         PixelColour rv;  
         rv.blue = (colour & 0xff0000) >> 16;  
         rv.green = (colour & 0xff00) >> 8;  
         rv.red = (colour & 0xff);  
         return rv;  
205  }  }
206    
207  static uint32  #define SPLITCOLOUR16(colour, rv) \
208  make_colour16(PixelColour pc)  { \
209  {          rv.red = ((colour >> 8) & 0xf8) | ((colour >> 13) & 0x7); \
210          pc.red = (pc.red * 0x1f) / 0xff;          rv.green = ((colour >> 3) & 0xfc) | ((colour >> 9) & 0x3); \
211          pc.green = (pc.green * 0x3f) / 0xff;          rv.blue = ((colour << 3) & 0xf8) | ((colour >> 2) & 0x7); \
212          pc.blue = (pc.blue * 0x1f) / 0xff;  } \
         return (pc.red << 11) | (pc.green << 5) | pc.blue;  
 }  
213    
214  static uint32  #define SPLITCOLOUR24(colour, rv) \
215  make_colour24(PixelColour pc)  { \
216  {          rv.blue = (colour & 0xff0000) >> 16; \
217          return (pc.red << 16) | (pc.green << 8) | pc.blue;          rv.green = (colour & 0x00ff00) >> 8; \
218            rv.red = (colour & 0x0000ff); \
219  }  }
220    
221  static uint32  #define MAKECOLOUR(pc) \
222  make_colour32(PixelColour pc)          ((pc.red >> g_red_shift_r) << g_red_shift_l) \
223  {                  | ((pc.green >> g_green_shift_r) << g_green_shift_l) \
224          return (pc.red << 16) | (pc.green << 8) | pc.blue;                  | ((pc.blue >> g_blue_shift_r) << g_blue_shift_l) \
 }  
225    
226  #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }  #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
227  #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }  #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | (x & 0xff00)); }
228  #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \  #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
229                          x = (x << 16) | (x >> 16); }                          x = (x << 16) | (x >> 16); }
230    
231    #define BOUT16(o, x) { *(o++) = x >> 8; *(o++) = x; }
232    #define BOUT24(o, x) { *(o++) = x >> 16; *(o++) = x >> 8; *(o++) = x; }
233    #define BOUT32(o, x) { *(o++) = x >> 24; *(o++) = x >> 16; *(o++) = x >> 8; *(o++) = x; }
234    #define LOUT16(o, x) { *(o++) = x; *(o++) = x >> 8; }
235    #define LOUT24(o, x) { *(o++) = x; *(o++) = x >> 8; *(o++) = x >> 16; }
236    #define LOUT32(o, x) { *(o++) = x; *(o++) = x >> 8; *(o++) = x >> 16; *(o++) = x >> 24; }
237    
238  static uint32  static uint32
239  translate_colour(uint32 colour)  translate_colour(uint32 colour)
240  {  {
241          switch (server_bpp)          PixelColour pc;
242            switch (g_server_bpp)
243          {          {
244                  case 15:                  case 15:
245                          switch (bpp)                          SPLITCOLOUR15(colour, pc);
                         {  
                                 case 16:  
                                         colour = make_colour16(split_colour15(colour));  
                                         break;  
                                 case 24:  
                                         colour = make_colour24(split_colour15(colour));  
                                         break;  
                                 case 32:  
                                         colour = make_colour32(split_colour15(colour));  
                                         break;  
                         }  
246                          break;                          break;
247                  case 16:                  case 16:
248                          switch (bpp)                          SPLITCOLOUR16(colour, pc);
                         {  
                                 case 16:  
                                         break;  
                                 case 24:  
                                         colour = make_colour24(split_colour16(colour));  
                                         break;  
                                 case 32:  
                                         colour = make_colour32(split_colour16(colour));  
                                         break;  
                         }  
249                          break;                          break;
250                  case 24:                  case 24:
251                          switch (bpp)                          SPLITCOLOUR24(colour, pc);
                         {  
                                 case 16:  
                                         colour = make_colour16(split_colour24(colour));  
                                         break;  
                                 case 24:  
                                         break;  
                                 case 32:  
                                         colour = make_colour32(split_colour24(colour));  
                                         break;  
                         }  
252                          break;                          break;
253          }          }
254          switch (bpp)          return MAKECOLOUR(pc);
255          {  }
                 case 16:  
                         if (host_be != xserver_be)  
                                 BSWAP16(colour);  
                         break;  
256    
257                  case 24:  /* indent is confused by UNROLL8 */
258                          if (xserver_be)  /* *INDENT-OFF* */
                                 BSWAP24(colour);  
                         break;  
259    
260                  case 32:  /* repeat and unroll, similar to bitmap.c */
261                          if (host_be != xserver_be)  /* potentialy any of the following translate */
262                                  BSWAP32(colour);  /* functions can use repeat but just doing */
263                          break;  /* the most common ones */
         }  
264    
265          return colour;  #define UNROLL8(stm) { stm stm stm stm stm stm stm stm }
266    /* 2 byte output repeat */
267    #define REPEAT2(stm) \
268    { \
269            while (out <= end - 8 * 2) \
270                    UNROLL8(stm) \
271            while (out < end) \
272                    { stm } \
273  }  }
274    /* 3 byte output repeat */
275    #define REPEAT3(stm) \
276    { \
277            while (out <= end - 8 * 3) \
278                    UNROLL8(stm) \
279            while (out < end) \
280                    { stm } \
281    }
282    /* 4 byte output repeat */
283    #define REPEAT4(stm) \
284    { \
285            while (out <= end - 8 * 4) \
286                    UNROLL8(stm) \
287            while (out < end) \
288                    { stm } \
289    }
290    /* *INDENT-ON* */
291    
292  static void  static void
293  translate8to8(uint8 * data, uint8 * out, uint8 * end)  translate8to8(const uint8 * data, uint8 * out, uint8 * end)
294  {  {
295          while (out < end)          while (out < end)
296                  *(out++) = (uint8) colmap[*(data++)];                  *(out++) = (uint8) g_colmap[*(data++)];
297  }  }
298    
299  static void  static void
300  translate8to16(uint8 * data, uint16 * out, uint16 * end)  translate8to16(const uint8 * data, uint8 * out, uint8 * end)
301  {  {
302          while (out < end)          uint16 value;
303                  *(out++) = (uint16) colmap[*(data++)];  
304            if (g_arch_match)
305            {
306                    /* *INDENT-OFF* */
307                    REPEAT2
308                    (
309                            *((uint16 *) out) = g_colmap[*(data++)];
310                            out += 2;
311                    )
312                    /* *INDENT-ON* */
313            }
314            else if (g_xserver_be)
315            {
316                    while (out < end)
317                    {
318                            value = (uint16) g_colmap[*(data++)];
319                            BOUT16(out, value);
320                    }
321            }
322            else
323            {
324                    while (out < end)
325                    {
326                            value = (uint16) g_colmap[*(data++)];
327                            LOUT16(out, value);
328                    }
329            }
330  }  }
331    
332  /* little endian - conversion happens when colourmap is built */  /* little endian - conversion happens when colourmap is built */
333  static void  static void
334  translate8to24(uint8 * data, uint8 * out, uint8 * end)  translate8to24(const uint8 * data, uint8 * out, uint8 * end)
335  {  {
336          uint32 value;          uint32 value;
337    
338          while (out < end)          if (g_xserver_be)
339            {
340                    while (out < end)
341                    {
342                            value = g_colmap[*(data++)];
343                            BOUT24(out, value);
344                    }
345            }
346            else
347          {          {
348                  value = colmap[*(data++)];                  while (out < end)
349                  *(out++) = value;                  {
350                  *(out++) = value >> 8;                          value = g_colmap[*(data++)];
351                  *(out++) = value >> 16;                          LOUT24(out, value);
352                    }
353          }          }
354  }  }
355    
356  static void  static void
357  translate8to32(uint8 * data, uint32 * out, uint32 * end)  translate8to32(const uint8 * data, uint8 * out, uint8 * end)
358  {  {
359          while (out < end)          uint32 value;
                 *(out++) = colmap[*(data++)];  
 }  
360    
361  /* todo the remaining translate function might need some big endian check ?? */          if (g_arch_match)
362            {
363                    /* *INDENT-OFF* */
364                    REPEAT4
365                    (
366                            *((uint32 *) out) = g_colmap[*(data++)];
367                            out += 4;
368                    )
369                    /* *INDENT-ON* */
370            }
371            else if (g_xserver_be)
372            {
373                    while (out < end)
374                    {
375                            value = g_colmap[*(data++)];
376                            BOUT32(out, value);
377                    }
378            }
379            else
380            {
381                    while (out < end)
382                    {
383                            value = g_colmap[*(data++)];
384                            LOUT32(out, value);
385                    }
386            }
387    }
388    
389  static void  static void
390  translate15to16(uint16 * data, uint16 * out, uint16 * end)  translate15to16(const uint16 * data, uint8 * out, uint8 * end)
391  {  {
392          while (out < end)          uint16 pixel;
393                  *(out++) = (uint16) make_colour16(split_colour15(*(data++)));          uint16 value;
394            PixelColour pc;
395    
396            if (g_xserver_be)
397            {
398                    while (out < end)
399                    {
400                            pixel = *(data++);
401                            if (g_host_be)
402                            {
403                                    BSWAP16(pixel);
404                            }
405                            SPLITCOLOUR15(pixel, pc);
406                            value = MAKECOLOUR(pc);
407                            BOUT16(out, value);
408                    }
409            }
410            else
411            {
412                    while (out < end)
413                    {
414                            pixel = *(data++);
415                            if (g_host_be)
416                            {
417                                    BSWAP16(pixel);
418                            }
419                            SPLITCOLOUR15(pixel, pc);
420                            value = MAKECOLOUR(pc);
421                            LOUT16(out, value);
422                    }
423            }
424  }  }
425    
426  static void  static void
427  translate15to24(uint16 * data, uint8 * out, uint8 * end)  translate15to24(const uint16 * data, uint8 * out, uint8 * end)
428  {  {
429          uint32 value;          uint32 value;
430            uint16 pixel;
431            PixelColour pc;
432    
433          while (out < end)          if (g_arch_match)
434          {          {
435                  value = make_colour24(split_colour15(*(data++)));                  /* *INDENT-OFF* */
436                  *(out++) = value;                  REPEAT3
437                  *(out++) = value >> 8;                  (
438                  *(out++) = value >> 16;                          pixel = *(data++);
439                            SPLITCOLOUR15(pixel, pc);
440                            *(out++) = pc.blue;
441                            *(out++) = pc.green;
442                            *(out++) = pc.red;
443                    )
444                    /* *INDENT-ON* */
445            }
446            else if (g_xserver_be)
447            {
448                    while (out < end)
449                    {
450                            pixel = *(data++);
451                            if (g_host_be)
452                            {
453                                    BSWAP16(pixel);
454                            }
455                            SPLITCOLOUR15(pixel, pc);
456                            value = MAKECOLOUR(pc);
457                            BOUT24(out, value);
458                    }
459            }
460            else
461            {
462                    while (out < end)
463                    {
464                            pixel = *(data++);
465                            if (g_host_be)
466                            {
467                                    BSWAP16(pixel);
468                            }
469                            SPLITCOLOUR15(pixel, pc);
470                            value = MAKECOLOUR(pc);
471                            LOUT24(out, value);
472                    }
473          }          }
474  }  }
475    
476  static void  static void
477  translate15to32(uint16 * data, uint32 * out, uint32 * end)  translate15to32(const uint16 * data, uint8 * out, uint8 * end)
478  {  {
479          while (out < end)          uint16 pixel;
480                  *(out++) = make_colour32(split_colour15(*(data++)));          uint32 value;
481            PixelColour pc;
482    
483            if (g_arch_match)
484            {
485                    /* *INDENT-OFF* */
486                    REPEAT4
487                    (
488                            pixel = *(data++);
489                            SPLITCOLOUR15(pixel, pc);
490                            *(out++) = pc.blue;
491                            *(out++) = pc.green;
492                            *(out++) = pc.red;
493                            *(out++) = 0;
494                    )
495                    /* *INDENT-ON* */
496            }
497            else if (g_xserver_be)
498            {
499                    while (out < end)
500                    {
501                            pixel = *(data++);
502                            if (g_host_be)
503                            {
504                                    BSWAP16(pixel);
505                            }
506                            SPLITCOLOUR15(pixel, pc);
507                            value = MAKECOLOUR(pc);
508                            BOUT32(out, value);
509                    }
510            }
511            else
512            {
513                    while (out < end)
514                    {
515                            pixel = *(data++);
516                            if (g_host_be)
517                            {
518                                    BSWAP16(pixel);
519                            }
520                            SPLITCOLOUR15(pixel, pc);
521                            value = MAKECOLOUR(pc);
522                            LOUT32(out, value);
523                    }
524            }
525  }  }
526    
527  static void  static void
528  translate16to16(uint16 * data, uint16 * out, uint16 * end)  translate16to16(const uint16 * data, uint8 * out, uint8 * end)
529  {  {
530          while (out < end)          uint16 pixel;
531                  *(out++) = (uint16) (*(data++));          uint16 value;
532  }          PixelColour pc;
533    
534            if (g_xserver_be)
535            {
536                    if (g_host_be)
537                    {
538                            while (out < end)
539                            {
540                                    pixel = *(data++);
541                                    BSWAP16(pixel);
542                                    SPLITCOLOUR16(pixel, pc);
543                                    value = MAKECOLOUR(pc);
544                                    BOUT16(out, value);
545                            }
546                    }
547                    else
548                    {
549                            while (out < end)
550                            {
551                                    pixel = *(data++);
552                                    SPLITCOLOUR16(pixel, pc);
553                                    value = MAKECOLOUR(pc);
554                                    BOUT16(out, value);
555                            }
556                    }
557            }
558            else
559            {
560                    if (g_host_be)
561                    {
562                            while (out < end)
563                            {
564                                    pixel = *(data++);
565                                    BSWAP16(pixel);
566                                    SPLITCOLOUR16(pixel, pc);
567                                    value = MAKECOLOUR(pc);
568                                    LOUT16(out, value);
569                            }
570                    }
571                    else
572                    {
573                            while (out < end)
574                            {
575                                    pixel = *(data++);
576                                    SPLITCOLOUR16(pixel, pc);
577                                    value = MAKECOLOUR(pc);
578                                    LOUT16(out, value);
579                            }
580                    }
581            }
582    }
583    
584  static void  static void
585  translate16to24(uint16 * data, uint8 * out, uint8 * end)  translate16to24(const uint16 * data, uint8 * out, uint8 * end)
586  {  {
587          uint32 value;          uint32 value;
588            uint16 pixel;
589            PixelColour pc;
590    
591          while (out < end)          if (g_arch_match)
592            {
593                    /* *INDENT-OFF* */
594                    REPEAT3
595                    (
596                            pixel = *(data++);
597                            SPLITCOLOUR16(pixel, pc);
598                            *(out++) = pc.blue;
599                            *(out++) = pc.green;
600                            *(out++) = pc.red;
601                    )
602                    /* *INDENT-ON* */
603            }
604            else if (g_xserver_be)
605            {
606                    if (g_host_be)
607                    {
608                            while (out < end)
609                            {
610                                    pixel = *(data++);
611                                    BSWAP16(pixel);
612                                    SPLITCOLOUR16(pixel, pc);
613                                    value = MAKECOLOUR(pc);
614                                    BOUT24(out, value);
615                            }
616                    }
617                    else
618                    {
619                            while (out < end)
620                            {
621                                    pixel = *(data++);
622                                    SPLITCOLOUR16(pixel, pc);
623                                    value = MAKECOLOUR(pc);
624                                    BOUT24(out, value);
625                            }
626                    }
627            }
628            else
629          {          {
630                  value = make_colour24(split_colour16(*(data++)));                  if (g_host_be)
631                  *(out++) = value;                  {
632                  *(out++) = value >> 8;                          while (out < end)
633                  *(out++) = value >> 16;                          {
634                                    pixel = *(data++);
635                                    BSWAP16(pixel);
636                                    SPLITCOLOUR16(pixel, pc);
637                                    value = MAKECOLOUR(pc);
638                                    LOUT24(out, value);
639                            }
640                    }
641                    else
642                    {
643                            while (out < end)
644                            {
645                                    pixel = *(data++);
646                                    SPLITCOLOUR16(pixel, pc);
647                                    value = MAKECOLOUR(pc);
648                                    LOUT24(out, value);
649                            }
650                    }
651          }          }
652  }  }
653    
654  static void  static void
655  translate16to32(uint16 * data, uint32 * out, uint32 * end)  translate16to32(const uint16 * data, uint8 * out, uint8 * end)
656  {  {
657          while (out < end)          uint16 pixel;
658                  *(out++) = make_colour32(split_colour16(*(data++)));          uint32 value;
659            PixelColour pc;
660    
661            if (g_arch_match)
662            {
663                    /* *INDENT-OFF* */
664                    REPEAT4
665                    (
666                            pixel = *(data++);
667                            SPLITCOLOUR16(pixel, pc);
668                            *(out++) = pc.blue;
669                            *(out++) = pc.green;
670                            *(out++) = pc.red;
671                            *(out++) = 0;
672                    )
673                    /* *INDENT-ON* */
674            }
675            else if (g_xserver_be)
676            {
677                    if (g_host_be)
678                    {
679                            while (out < end)
680                            {
681                                    pixel = *(data++);
682                                    BSWAP16(pixel);
683                                    SPLITCOLOUR16(pixel, pc);
684                                    value = MAKECOLOUR(pc);
685                                    BOUT32(out, value);
686                            }
687                    }
688                    else
689                    {
690                            while (out < end)
691                            {
692                                    pixel = *(data++);
693                                    SPLITCOLOUR16(pixel, pc);
694                                    value = MAKECOLOUR(pc);
695                                    BOUT32(out, value);
696                            }
697                    }
698            }
699            else
700            {
701                    if (g_host_be)
702                    {
703                            while (out < end)
704                            {
705                                    pixel = *(data++);
706                                    BSWAP16(pixel);
707                                    SPLITCOLOUR16(pixel, pc);
708                                    value = MAKECOLOUR(pc);
709                                    LOUT32(out, value);
710                            }
711                    }
712                    else
713                    {
714                            while (out < end)
715                            {
716                                    pixel = *(data++);
717                                    SPLITCOLOUR16(pixel, pc);
718                                    value = MAKECOLOUR(pc);
719                                    LOUT32(out, value);
720                            }
721                    }
722            }
723  }  }
724    
725  static void  static void
726  translate24to16(uint8 * data, uint16 * out, uint16 * end)  translate24to16(const uint8 * data, uint8 * out, uint8 * end)
727  {  {
728          uint32 pixel = 0;          uint32 pixel = 0;
729            uint16 value;
730            PixelColour pc;
731    
732          while (out < end)          while (out < end)
733          {          {
734                  pixel = *(data++) << 16;                  pixel = *(data++) << 16;
735                  pixel |= *(data++) << 8;                  pixel |= *(data++) << 8;
736                  pixel |= *(data++);                  pixel |= *(data++);
737                  *(out++) = (uint16) make_colour16(split_colour24(pixel));                  SPLITCOLOUR24(pixel, pc);
738                    value = MAKECOLOUR(pc);
739                    if (g_xserver_be)
740                    {
741                            BOUT16(out, value);
742                    }
743                    else
744                    {
745                            LOUT16(out, value);
746                    }
747          }          }
748  }  }
749    
750  static void  static void
751  translate24to24(uint8 * data, uint8 * out, uint8 * end)  translate24to24(const uint8 * data, uint8 * out, uint8 * end)
752  {  {
753          while (out < end)          uint32 pixel;
754            uint32 value;
755            PixelColour pc;
756    
757            if (g_xserver_be)
758          {          {
759                  *(out++) = (*(data++));                  while (out < end)
760                    {
761                            pixel = *(data++) << 16;
762                            pixel |= *(data++) << 8;
763                            pixel |= *(data++);
764                            SPLITCOLOUR24(pixel, pc);
765                            value = MAKECOLOUR(pc);
766                            BOUT24(out, value);
767                    }
768            }
769            else
770            {
771                    while (out < end)
772                    {
773                            pixel = *(data++) << 16;
774                            pixel |= *(data++) << 8;
775                            pixel |= *(data++);
776                            SPLITCOLOUR24(pixel, pc);
777                            value = MAKECOLOUR(pc);
778                            LOUT24(out, value);
779                    }
780          }          }
781  }  }
782    
783  static void  static void
784  translate24to32(uint8 * data, uint32 * out, uint32 * end)  translate24to32(const uint8 * data, uint8 * out, uint8 * end)
785  {  {
786          uint32 pixel = 0;          uint32 pixel;
787          while (out < end)          uint32 value;
788            PixelColour pc;
789    
790            if (g_arch_match)
791          {          {
792                  pixel = *(data++);                  /* *INDENT-OFF* */
793                  pixel |= *(data++) << 8;  #ifdef NEED_ALIGN
794                  pixel |= *(data++) << 16;                  REPEAT4
795                  *(out++) = pixel;                  (
796                            *(out++) = *(data++);
797                            *(out++) = *(data++);
798                            *(out++) = *(data++);
799                            *(out++) = 0;
800                    )
801    #else
802                    REPEAT4
803                    (
804                            *((uint32 *) out) = *((uint32 *) data);
805                            out += 4;
806                            data += 3;
807                    )
808    #endif
809                    /* *INDENT-ON* */
810            }
811            else if (g_xserver_be)
812            {
813                    while (out < end)
814                    {
815                            pixel = *(data++) << 16;
816                            pixel |= *(data++) << 8;
817                            pixel |= *(data++);
818                            SPLITCOLOUR24(pixel, pc);
819                            value = MAKECOLOUR(pc);
820                            BOUT32(out, value);
821                    }
822            }
823            else
824            {
825                    while (out < end)
826                    {
827                            pixel = *(data++) << 16;
828                            pixel |= *(data++) << 8;
829                            pixel |= *(data++);
830                            SPLITCOLOUR24(pixel, pc);
831                            value = MAKECOLOUR(pc);
832                            LOUT32(out, value);
833                    }
834          }          }
835  }  }
836    
837  static uint8 *  static uint8 *
838  translate_image(int width, int height, uint8 * data)  translate_image(int width, int height, uint8 * data)
839  {  {
840          int size = width * height * bpp / 8;          int size;
841          uint8 *out = (uint8*)xmalloc(size);          uint8 *out;
842          uint8 *end = out + size;          uint8 *end;
843    
844            /* if server and xserver bpp match, */
845            /* and arch(endian) matches, no need to translate */
846            /* just return data */
847            if (g_arch_match)
848            {
849                    if (g_depth == 15 && g_server_bpp == 15)
850                            return data;
851                    if (g_depth == 16 && g_server_bpp == 16)
852                            return data;
853                    if (g_depth == 24 && g_bpp == 24 && g_server_bpp == 24)
854                            return data;
855            }
856    
857            size = width * height * (g_bpp / 8);
858            out = (uint8 *) xmalloc(size);
859            end = out + size;
860    
861          switch (server_bpp)          switch (g_server_bpp)
862          {          {
863                  case 24:                  case 24:
864                          switch (bpp)                          switch (g_bpp)
865                          {                          {
866                                  case 32:                                  case 32:
867                                          translate24to32(data, (uint32 *) out, (uint32 *) end);                                          translate24to32(data, out, end);
868                                          break;                                          break;
869                                  case 24:                                  case 24:
870                                          translate24to24(data, out, end);                                          translate24to24(data, out, end);
871                                          break;                                          break;
872                                  case 16:                                  case 16:
873                                          translate24to16(data, (uint16 *) out, (uint16 *) end);                                          translate24to16(data, out, end);
874                                          break;                                          break;
875                          }                          }
876                          break;                          break;
877                  case 16:                  case 16:
878                          switch (bpp)                          switch (g_bpp)
879                          {                          {
880                                  case 32:                                  case 32:
881                                          translate16to32((uint16 *) data, (uint32 *) out,                                          translate16to32((uint16 *) data, out, end);
                                                         (uint32 *) end);  
882                                          break;                                          break;
883                                  case 24:                                  case 24:
884                                          translate16to24((uint16 *) data, out, end);                                          translate16to24((uint16 *) data, out, end);
885                                          break;                                          break;
886                                  case 16:                                  case 16:
887                                          translate16to16((uint16 *) data, (uint16 *) out,                                          translate16to16((uint16 *) data, out, end);
                                                         (uint16 *) end);  
888                                          break;                                          break;
889                          }                          }
890                          break;                          break;
891                  case 15:                  case 15:
892                          switch (bpp)                          switch (g_bpp)
893                          {                          {
894                                  case 32:                                  case 32:
895                                          translate15to32((uint16 *) data, (uint32 *) out,                                          translate15to32((uint16 *) data, out, end);
                                                         (uint32 *) end);  
896                                          break;                                          break;
897                                  case 24:                                  case 24:
898                                          translate15to24((uint16 *) data, out, end);                                          translate15to24((uint16 *) data, out, end);
899                                          break;                                          break;
900                                  case 16:                                  case 16:
901                                          translate15to16((uint16 *) data, (uint16 *) out,                                          translate15to16((uint16 *) data, out, end);
                                                         (uint16 *) end);  
902                                          break;                                          break;
903                          }                          }
904                          break;                          break;
905                  case 8:                  case 8:
906                          switch (bpp)                          switch (g_bpp)
907                          {                          {
908                                  case 8:                                  case 8:
909                                          translate8to8(data, out, end);                                          translate8to8(data, out, end);
910                                          break;                                          break;
911                                  case 16:                                  case 16:
912                                          translate8to16(data, (uint16 *) out, (uint16 *) end);                                          translate8to16(data, out, end);
913                                          break;                                          break;
914                                  case 24:                                  case 24:
915                                          translate8to24(data, out, end);                                          translate8to24(data, out, end);
916                                          break;                                          break;
917                                  case 32:                                  case 32:
918                                          translate8to32(data, (uint32 *) out, (uint32 *) end);                                          translate8to32(data, out, end);
919                                          break;                                          break;
920                          }                          }
921                          break;                          break;
# Line 491  get_key_state(unsigned int state, uint32 Line 929  get_key_state(unsigned int state, uint32
929          int modifierpos, key, keysymMask = 0;          int modifierpos, key, keysymMask = 0;
930          int offset;          int offset;
931    
932          KeyCode keycode = XKeysymToKeycode(display, keysym);          KeyCode keycode = XKeysymToKeycode(g_display, keysym);
933    
934          if (keycode == NoSymbol)          if (keycode == NoSymbol)
935                  return False;                  return False;
936    
937          for (modifierpos = 0; modifierpos < 8; modifierpos++)          for (modifierpos = 0; modifierpos < 8; modifierpos++)
938          {          {
939                  offset = mod_map->max_keypermod * modifierpos;                  offset = g_mod_map->max_keypermod * modifierpos;
940    
941                  for (key = 0; key < mod_map->max_keypermod; key++)                  for (key = 0; key < g_mod_map->max_keypermod; key++)
942                  {                  {
943                          if (mod_map->modifiermap[offset + key] == keycode)                          if (g_mod_map->modifiermap[offset + key] == keycode)
944                                  keysymMask |= 1 << modifierpos;                                  keysymMask |= 1 << modifierpos;
945                  }                  }
946          }          }
# Line 510  get_key_state(unsigned int state, uint32 Line 948  get_key_state(unsigned int state, uint32
948          return (state & keysymMask) ? True : False;          return (state & keysymMask) ? True : False;
949  }  }
950    
951    static void
952    calculate_shifts(uint32 mask, int *shift_r, int *shift_l)
953    {
954            *shift_l = ffs(mask) - 1;
955            mask >>= *shift_l;
956            *shift_r = 8 - ffs(mask & ~(mask >> 1));
957    }
958    
959  BOOL  BOOL
960  ui_init(void)  ui_init(void)
961  {  {
962            XVisualInfo vi;
963          XPixmapFormatValues *pfm;          XPixmapFormatValues *pfm;
964          uint16 test;          uint16 test;
965          int i;          int i, screen_num, nvisuals;
966            XVisualInfo *vmatches = NULL;
967            XVisualInfo template;
968            Bool TrueColorVisual = False;
969    
970          display = XOpenDisplay(NULL);          g_display = XOpenDisplay(NULL);
971          if (display == NULL)          if (g_display == NULL)
972          {          {
973                  error("Failed to open display: %s\n", XDisplayName(NULL));                  error("Failed to open display: %s\n", XDisplayName(NULL));
974                  return False;                  return False;
975          }          }
976    
977          x_socket = ConnectionNumber(display);          screen_num = DefaultScreen(g_display);
978          screen = DefaultScreenOfDisplay(display);          g_x_socket = ConnectionNumber(g_display);
979          visual = DefaultVisualOfScreen(screen);          g_screen = ScreenOfDisplay(g_display, screen_num);
980          depth = DefaultDepthOfScreen(screen);          g_depth = DefaultDepthOfScreen(g_screen);
981    
982            /* Search for best TrueColor depth */
983            template.class = TrueColor;
984            vmatches = XGetVisualInfo(g_display, VisualClassMask, &template, &nvisuals);
985    
986            nvisuals--;
987            while (nvisuals >= 0)
988            {
989                    if ((vmatches + nvisuals)->depth > g_depth)
990                    {
991                            g_depth = (vmatches + nvisuals)->depth;
992                    }
993                    nvisuals--;
994                    TrueColorVisual = True;
995            }
996    
997            test = 1;
998            g_host_be = !(BOOL) (*(uint8 *) (&test));
999            g_xserver_be = (ImageByteOrder(g_display) == MSBFirst);
1000    
1001            if ((g_server_bpp == 8) && ((!TrueColorVisual) || (g_depth <= 8)))
1002            {
1003                    /* we use a colourmap, so the default visual should do */
1004                    g_visual = DefaultVisualOfScreen(g_screen);
1005                    g_depth = DefaultDepthOfScreen(g_screen);
1006    
1007                    /* Do not allocate colours on a TrueColor visual */
1008                    if (g_visual->class == TrueColor)
1009                    {
1010                            g_owncolmap = False;
1011                    }
1012            }
1013            else
1014            {
1015                    /* need a truecolour visual */
1016                    if (!XMatchVisualInfo(g_display, screen_num, g_depth, TrueColor, &vi))
1017                    {
1018                            error("The display does not support true colour - high colour support unavailable.\n");
1019                            return False;
1020                    }
1021    
1022                    g_visual = vi.visual;
1023                    g_owncolmap = False;
1024                    calculate_shifts(vi.red_mask, &g_red_shift_r, &g_red_shift_l);
1025                    calculate_shifts(vi.blue_mask, &g_blue_shift_r, &g_blue_shift_l);
1026                    calculate_shifts(vi.green_mask, &g_green_shift_r, &g_green_shift_l);
1027    
1028                    /* if RGB video and everything is little endian */
1029                    if ((vi.red_mask > vi.green_mask && vi.green_mask > vi.blue_mask) &&
1030                        !g_xserver_be && !g_host_be)
1031                    {
1032                            if (g_depth <= 16 || (g_red_shift_l == 16 && g_green_shift_l == 8 &&
1033                                                  g_blue_shift_l == 0))
1034                            {
1035                                    g_arch_match = True;
1036                            }
1037                    }
1038    
1039                    if (g_arch_match)
1040                    {
1041                            DEBUG(("Architectures match, enabling little endian optimisations.\n"));
1042                    }
1043            }
1044    
1045          pfm = XListPixmapFormats(display, &i);          pfm = XListPixmapFormats(g_display, &i);
1046          if (pfm != NULL)          if (pfm != NULL)
1047          {          {
1048                  /* Use maximum bpp for this depth - this is generally                  /* Use maximum bpp for this depth - this is generally
1049                     desirable, e.g. 24 bits->32 bits. */                     desirable, e.g. 24 bits->32 bits. */
1050                  while (i--)                  while (i--)
1051                  {                  {
1052                          if ((pfm[i].depth == depth) && (pfm[i].bits_per_pixel > bpp))                          if ((pfm[i].depth == g_depth) && (pfm[i].bits_per_pixel > g_bpp))
1053                          {                          {
1054                                  bpp = pfm[i].bits_per_pixel;                                  g_bpp = pfm[i].bits_per_pixel;
1055                          }                          }
1056                  }                  }
1057                  XFree(pfm);                  XFree(pfm);
1058          }          }
1059    
1060          if (bpp < 8)          if (g_bpp < 8)
1061          {          {
1062                  error("Less than 8 bpp not currently supported.\n");                  error("Less than 8 bpp not currently supported.\n");
1063                  XCloseDisplay(display);                  XCloseDisplay(g_display);
1064                  return False;                  return False;
1065          }          }
1066    
1067          if (owncolmap != True)          if (!g_owncolmap)
1068          {          {
1069                  xcolmap = DefaultColormapOfScreen(screen);                  g_xcolmap =
1070                  if (depth <= 8)                          XCreateColormap(g_display, RootWindowOfScreen(g_screen), g_visual,
1071                                            AllocNone);
1072                    if (g_depth <= 8)
1073                          warning("Screen depth is 8 bits or lower: you may want to use -C for a private colourmap\n");                          warning("Screen depth is 8 bits or lower: you may want to use -C for a private colourmap\n");
1074          }          }
1075    
1076          gc = XCreateGC(display, RootWindowOfScreen(screen), 0, NULL);          if ((!g_ownbackstore) && (DoesBackingStore(g_screen) != Always))
1077            {
1078          if (DoesBackingStore(screen) != Always)                  warning("External BackingStore not available, using internal\n");
1079                  ownbackstore = True;                  g_ownbackstore = True;
1080            }
         test = 1;  
         host_be = !(BOOL) (*(uint8 *) (&test));  
         xserver_be = (ImageByteOrder(display) == MSBFirst);  
1081    
1082          if ((width == 0) || (height == 0))          /*
1083             * Determine desktop size
1084             */
1085            if (g_fullscreen)
1086            {
1087                    g_width = WidthOfScreen(g_screen);
1088                    g_height = HeightOfScreen(g_screen);
1089            }
1090            else if (g_width < 0)
1091            {
1092                    /* Percent of screen */
1093                    g_height = HeightOfScreen(g_screen) * (-g_width) / 100;
1094                    g_width = WidthOfScreen(g_screen) * (-g_width) / 100;
1095            }
1096            else if (g_width == 0)
1097          {          {
1098                  /* Fetch geometry from _NET_WORKAREA */                  /* Fetch geometry from _NET_WORKAREA */
1099                  uint32 x, y, cx, cy;                  uint32 x, y, cx, cy;
1100    
1101                  if (get_current_workarea(&x, &y, &cx, &cy) == 0)                  if (get_current_workarea(&x, &y, &cx, &cy) == 0)
1102                  {                  {
1103                          width = cx;                          g_width = cx;
1104                          height = cy;                          g_height = cy;
1105                  }                  }
1106                  else                  else
1107                  {                  {
1108                          warning("Failed to get workarea: probably your window manager does not support extended hints\n");                          warning("Failed to get workarea: probably your window manager does not support extended hints\n");
1109                          width = 800;                          g_width = 800;
1110                          height = 600;                          g_height = 600;
1111                  }                  }
1112          }          }
1113    
         if (fullscreen)  
         {  
                 width = WidthOfScreen(screen);  
                 height = HeightOfScreen(screen);  
         }  
   
1114          /* make sure width is a multiple of 4 */          /* make sure width is a multiple of 4 */
1115          width = (width + 3) & ~3;          g_width = (g_width + 3) & ~3;
1116    
1117          if (ownbackstore)          g_mod_map = XGetModifierMapping(g_display);
         {  
                 backstore =  
                         XCreatePixmap(display, RootWindowOfScreen(screen), width, height, depth);  
1118    
1119                  /* clear to prevent rubbish being exposed at startup */          xkeymap_init();
                 XSetForeground(display, gc, BlackPixelOfScreen(screen));  
                 XFillRectangle(display, backstore, gc, 0, 0, width, height);  
         }  
   
         mod_map = XGetModifierMapping(display);  
1120    
1121          if (enable_compose)          if (g_enable_compose)
1122                  IM = XOpenIM(display, NULL, NULL, NULL);                  g_IM = XOpenIM(g_display, NULL, NULL, NULL);
1123    
1124          xkeymap_init();          xclip_init();
1125    
1126          /* todo take this out when high colour is done */          DEBUG_RDP5(("server bpp %d client bpp %d depth %d\n", g_server_bpp, g_bpp, g_depth));
         printf("server bpp %d client bpp %d depth %d\n", server_bpp, bpp, depth);  
1127    
1128          return True;          return True;
1129  }  }
# Line 620  ui_init(void) Line 1131  ui_init(void)
1131  void  void
1132  ui_deinit(void)  ui_deinit(void)
1133  {  {
1134          if (IM != NULL)          if (g_IM != NULL)
1135                  XCloseIM(IM);                  XCloseIM(g_IM);
1136    
1137            if (g_null_cursor != NULL)
1138                    ui_destroy_cursor(g_null_cursor);
1139    
1140          XFreeModifiermap(mod_map);          XFreeModifiermap(g_mod_map);
1141    
1142          if (ownbackstore)          if (g_ownbackstore)
1143                  XFreePixmap(display, backstore);                  XFreePixmap(g_display, g_backstore);
1144    
1145          XFreeGC(display, gc);          XFreeGC(g_display, g_gc);
1146          XCloseDisplay(display);          XCloseDisplay(g_display);
1147          display = NULL;          g_display = NULL;
1148  }  }
1149    
1150  BOOL  BOOL
1151  ui_create_window(void)  ui_create_window(void)
1152  {  {
1153            uint8 null_pointer_mask[1] = { 0x80 };
1154            uint8 null_pointer_data[24] = { 0x00 };
1155    
1156          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
1157          XClassHint *classhints;          XClassHint *classhints;
1158          XSizeHints *sizehints;          XSizeHints *sizehints;
# Line 643  ui_create_window(void) Line 1160  ui_create_window(void)
1160          long input_mask, ic_input_mask;          long input_mask, ic_input_mask;
1161          XEvent xevent;          XEvent xevent;
1162    
1163          wndwidth = fullscreen ? WidthOfScreen(screen) : width;          wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;
1164          wndheight = fullscreen ? HeightOfScreen(screen) : height;          wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;
1165    
1166            attribs.background_pixel = BlackPixelOfScreen(g_screen);
1167            attribs.border_pixel = WhitePixelOfScreen(g_screen);
1168            attribs.backing_store = g_ownbackstore ? NotUseful : Always;
1169            attribs.override_redirect = g_fullscreen;
1170            attribs.colormap = g_xcolmap;
1171    
1172            g_wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), g_xpos, g_ypos, wndwidth,
1173                                  wndheight, 0, g_depth, InputOutput, g_visual,
1174                                  CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
1175                                  CWBorderPixel, &attribs);
1176    
1177          attribs.background_pixel = BlackPixelOfScreen(screen);          if (g_gc == NULL)
1178          attribs.backing_store = ownbackstore ? NotUseful : Always;                  g_gc = XCreateGC(g_display, g_wnd, 0, NULL);
         attribs.override_redirect = fullscreen;  
1179    
1180          wnd = XCreateWindow(display, RootWindowOfScreen(screen), 0, 0, wndwidth, wndheight,          if (g_create_bitmap_gc == NULL)
1181                              0, CopyFromParent, InputOutput, CopyFromParent,                  g_create_bitmap_gc = XCreateGC(g_display, g_wnd, 0, NULL);
                             CWBackPixel | CWBackingStore | CWOverrideRedirect, &attribs);  
1182    
1183          XStoreName(display, wnd, title);          if ((g_ownbackstore) && (g_backstore == 0))
1184            {
1185                    g_backstore = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
1186    
1187                    /* clear to prevent rubbish being exposed at startup */
1188                    XSetForeground(g_display, g_gc, BlackPixelOfScreen(g_screen));
1189                    XFillRectangle(g_display, g_backstore, g_gc, 0, 0, g_width, g_height);
1190            }
1191    
1192          if (hide_decorations)          XStoreName(g_display, g_wnd, g_title);
1193    
1194            if (g_hide_decorations)
1195                  mwm_hide_decorations();                  mwm_hide_decorations();
1196    
1197          classhints = XAllocClassHint();          classhints = XAllocClassHint();
1198          if (classhints != NULL)          if (classhints != NULL)
1199          {          {
1200                  classhints->res_name = classhints->res_class = "rdesktop";                  classhints->res_name = classhints->res_class = "rdesktop";
1201                  XSetClassHint(display, wnd, classhints);                  XSetClassHint(g_display, g_wnd, classhints);
1202                  XFree(classhints);                  XFree(classhints);
1203          }          }
1204    
# Line 671  ui_create_window(void) Line 1206  ui_create_window(void)
1206          if (sizehints)          if (sizehints)
1207          {          {
1208                  sizehints->flags = PMinSize | PMaxSize;                  sizehints->flags = PMinSize | PMaxSize;
1209                  sizehints->min_width = sizehints->max_width = width;                  sizehints->min_width = sizehints->max_width = g_width;
1210                  sizehints->min_height = sizehints->max_height = height;                  sizehints->min_height = sizehints->max_height = g_height;
1211                  XSetWMNormalHints(display, wnd, sizehints);                  XSetWMNormalHints(g_display, g_wnd, sizehints);
1212                  XFree(sizehints);                  XFree(sizehints);
1213          }          }
1214    
1215            if (g_embed_wnd)
1216            {
1217                    XReparentWindow(g_display, g_wnd, (Window) g_embed_wnd, 0, 0);
1218            }
1219    
1220          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
1221                  VisibilityChangeMask | FocusChangeMask;                  VisibilityChangeMask | FocusChangeMask;
1222    
1223          if (sendmotion)          if (g_sendmotion)
1224                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
1225          if (ownbackstore)          if (g_ownbackstore)
1226                  input_mask |= ExposureMask;                  input_mask |= ExposureMask;
1227          if (fullscreen || grab_keyboard)          if (g_fullscreen || g_grab_keyboard)
1228                  input_mask |= EnterWindowMask;                  input_mask |= EnterWindowMask;
1229          if (grab_keyboard)          if (g_grab_keyboard)
1230                  input_mask |= LeaveWindowMask;                  input_mask |= LeaveWindowMask;
1231    
1232          if (IM != NULL)          if (g_IM != NULL)
1233          {          {
1234                  IC = XCreateIC(IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),                  g_IC = XCreateIC(g_IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
1235                                 XNClientWindow, wnd, XNFocusWindow, wnd, NULL);                                   XNClientWindow, g_wnd, XNFocusWindow, g_wnd, NULL);
1236    
1237                  if ((IC != NULL)                  if ((g_IC != NULL)
1238                      && (XGetICValues(IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))                      && (XGetICValues(g_IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))
1239                          input_mask |= ic_input_mask;                          input_mask |= ic_input_mask;
1240          }          }
1241    
1242          XSelectInput(display, wnd, input_mask);          XSelectInput(g_display, g_wnd, input_mask);
1243          XMapWindow(display, wnd);          XMapWindow(g_display, g_wnd);
1244    
1245          /* wait for VisibilityNotify */          /* wait for VisibilityNotify */
1246          do          do
1247          {          {
1248                  XMaskEvent(display, VisibilityChangeMask, &xevent);                  XMaskEvent(g_display, VisibilityChangeMask, &xevent);
1249          }          }
1250          while (xevent.type != VisibilityNotify);          while (xevent.type != VisibilityNotify);
1251            g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;
1252    
1253          focused = False;          g_focused = False;
1254          mouse_in_wnd = False;          g_mouse_in_wnd = False;
1255    
1256          /* handle the WM_DELETE_WINDOW protocol */          /* handle the WM_DELETE_WINDOW protocol */
1257          protocol_atom = XInternAtom(display, "WM_PROTOCOLS", True);          g_protocol_atom = XInternAtom(g_display, "WM_PROTOCOLS", True);
1258          kill_atom = XInternAtom(display, "WM_DELETE_WINDOW", True);          g_kill_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", True);
1259          XSetWMProtocols(display, wnd, &kill_atom, 1);          XSetWMProtocols(g_display, g_wnd, &g_kill_atom, 1);
1260    
1261            /* create invisible 1x1 cursor to be used as null cursor */
1262            if (g_null_cursor == NULL)
1263                    g_null_cursor = ui_create_cursor(0, 0, 1, 1, null_pointer_mask, null_pointer_data);
1264    
1265          return True;          return True;
1266  }  }
1267    
1268  void  void
1269    ui_resize_window()
1270    {
1271            XSizeHints *sizehints;
1272            Pixmap bs;
1273    
1274            sizehints = XAllocSizeHints();
1275            if (sizehints)
1276            {
1277                    sizehints->flags = PMinSize | PMaxSize;
1278                    sizehints->min_width = sizehints->max_width = g_width;
1279                    sizehints->min_height = sizehints->max_height = g_height;
1280                    XSetWMNormalHints(g_display, g_wnd, sizehints);
1281                    XFree(sizehints);
1282            }
1283    
1284            if (!(g_fullscreen || g_embed_wnd))
1285            {
1286                    XResizeWindow(g_display, g_wnd, g_width, g_height);
1287            }
1288    
1289            /* create new backstore pixmap */
1290            if (g_backstore != 0)
1291            {
1292                    bs = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
1293                    XSetForeground(g_display, g_gc, BlackPixelOfScreen(g_screen));
1294                    XFillRectangle(g_display, bs, g_gc, 0, 0, g_width, g_height);
1295                    XCopyArea(g_display, g_backstore, bs, g_gc, 0, 0, g_width, g_height, 0, 0);
1296                    XFreePixmap(g_display, g_backstore);
1297                    g_backstore = bs;
1298            }
1299    }
1300    
1301    void
1302  ui_destroy_window(void)  ui_destroy_window(void)
1303  {  {
1304          if (IC != NULL)          if (g_IC != NULL)
1305                  XDestroyIC(IC);                  XDestroyIC(g_IC);
1306    
1307          XDestroyWindow(display, wnd);          XDestroyWindow(g_display, g_wnd);
1308  }  }
1309    
1310  void  void
# Line 734  xwin_toggle_fullscreen(void) Line 1312  xwin_toggle_fullscreen(void)
1312  {  {
1313          Pixmap contents = 0;          Pixmap contents = 0;
1314    
1315          if (!ownbackstore)          if (!g_ownbackstore)
1316          {          {
1317                  /* need to save contents of window */                  /* need to save contents of window */
1318                  contents = XCreatePixmap(display, wnd, width, height, depth);                  contents = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
1319                  XCopyArea(display, wnd, contents, gc, 0, 0, width, height, 0, 0);                  XCopyArea(g_display, g_wnd, contents, g_gc, 0, 0, g_width, g_height, 0, 0);
1320          }          }
1321    
1322          ui_destroy_window();          ui_destroy_window();
1323          fullscreen = !fullscreen;          g_fullscreen = !g_fullscreen;
1324          ui_create_window();          ui_create_window();
1325    
1326          XDefineCursor(display, wnd, current_cursor);          XDefineCursor(g_display, g_wnd, g_current_cursor);
1327    
1328          if (!ownbackstore)          if (!g_ownbackstore)
1329          {          {
1330                  XCopyArea(display, contents, wnd, gc, 0, 0, width, height, 0, 0);                  XCopyArea(g_display, contents, g_wnd, g_gc, 0, 0, g_width, g_height, 0, 0);
1331                  XFreePixmap(display, contents);                  XFreePixmap(g_display, contents);
1332          }          }
1333  }  }
1334    
1335  /* Process all events in Xlib queue  /* Process all events in Xlib queue
1336     Returns 0 after user quit, 1 otherwise */     Returns 0 after user quit, 1 otherwise */
1337  static int  static int
1338  xwin_process_events(void)  xwin_process_events(void)
# Line 766  xwin_process_events(void) Line 1344  xwin_process_events(void)
1344          key_translation tr;          key_translation tr;
1345          char str[256];          char str[256];
1346          Status status;          Status status;
         unsigned int state;  
         Window wdummy;  
         int dummy;  
1347    
1348          while (XPending(display) > 0)          while (XPending(g_display) > 0)
1349          {          {
1350                  XNextEvent(display, &xevent);                  XNextEvent(g_display, &xevent);
1351    
1352                  if ((IC != NULL) && (XFilterEvent(&xevent, None) == True))                  if ((g_IC != NULL) && (XFilterEvent(&xevent, None) == True))
1353                  {                  {
1354                          DEBUG_KBD(("Filtering event\n"));                          DEBUG_KBD(("Filtering event\n"));
1355                          continue;                          continue;
# Line 784  xwin_process_events(void) Line 1359  xwin_process_events(void)
1359    
1360                  switch (xevent.type)                  switch (xevent.type)
1361                  {                  {
1362                            case VisibilityNotify:
1363                                    g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;
1364                                    break;
1365                          case ClientMessage:                          case ClientMessage:
1366                                  /* the window manager told us to quit */                                  /* the window manager told us to quit */
1367                                  if ((xevent.xclient.message_type == protocol_atom)                                  if ((xevent.xclient.message_type == g_protocol_atom)
1368                                      && ((Atom)xevent.xclient.data.l[0] == kill_atom))                                      && ((Atom) xevent.xclient.data.l[0] == g_kill_atom))
1369                                          /* Quit */                                          /* Quit */
1370                                          return 0;                                          return 0;
1371                                  break;                                  break;
1372    
1373                          case KeyPress:                          case KeyPress:
1374                                  if (IC != NULL)                                  g_last_gesturetime = xevent.xkey.time;
1375                                    if (g_IC != NULL)
1376                                          /* Multi_key compatible version */                                          /* Multi_key compatible version */
1377                                  {                                  {
1378                                          XmbLookupString(IC,                                          XmbLookupString(g_IC,
1379                                                          (XKeyPressedEvent *) &                                                          &xevent.xkey, str, sizeof(str), &keysym,
1380                                                          xevent, str, sizeof(str), &keysym, &status);                                                          &status);
1381                                          if (!((status == XLookupKeySym) || (status == XLookupBoth)))                                          if (!((status == XLookupKeySym) || (status == XLookupBoth)))
1382                                          {                                          {
1383                                                  error("XmbLookupString failed with status 0x%x\n",                                                  error("XmbLookupString failed with status 0x%x\n",
# Line 827  xwin_process_events(void) Line 1406  xwin_process_events(void)
1406                                  if (tr.scancode == 0)                                  if (tr.scancode == 0)
1407                                          break;                                          break;
1408    
1409                                    save_remote_modifiers(tr.scancode);
1410                                  ensure_remote_modifiers(ev_time, tr);                                  ensure_remote_modifiers(ev_time, tr);
   
1411                                  rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);                                  rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
1412                                    restore_remote_modifiers(ev_time, tr.scancode);
1413    
1414                                  break;                                  break;
1415    
1416                          case KeyRelease:                          case KeyRelease:
1417                                    g_last_gesturetime = xevent.xkey.time;
1418                                  XLookupString((XKeyEvent *) & xevent, str,                                  XLookupString((XKeyEvent *) & xevent, str,
1419                                                sizeof(str), &keysym, NULL);                                                sizeof(str), &keysym, NULL);
1420    
# Line 857  xwin_process_events(void) Line 1439  xwin_process_events(void)
1439                                  /* fall through */                                  /* fall through */
1440    
1441                          case ButtonRelease:                          case ButtonRelease:
1442                                    g_last_gesturetime = xevent.xbutton.time;
1443                                  button = xkeymap_translate_button(xevent.xbutton.button);                                  button = xkeymap_translate_button(xevent.xbutton.button);
1444                                  if (button == 0)                                  if (button == 0)
1445                                          break;                                          break;
1446    
1447                                  /* If win_button_size is nonzero, enable single app mode */                                  /* If win_button_size is nonzero, enable single app mode */
1448                                  if (xevent.xbutton.y < win_button_size)                                  if (xevent.xbutton.y < g_win_button_size)
1449                                  {                                  {
1450                                          /* Stop moving window when button is released, regardless of cursor position */                                          /* Stop moving window when button is released, regardless of cursor position */
1451                                          if (moving_wnd && (xevent.type == ButtonRelease))                                          if (g_moving_wnd && (xevent.type == ButtonRelease))
1452                                                  moving_wnd = False;                                                  g_moving_wnd = False;
1453    
1454                                          /*  Check from right to left: */                                          /*  Check from right to left: */
1455    
1456                                          if (xevent.xbutton.x >= width - win_button_size)                                          if (xevent.xbutton.x >= g_width - g_win_button_size)
1457                                          {                                          {
1458                                                  /* The close button, continue */                                                  /* The close button, continue */
1459                                                  ;                                                  ;
1460                                          }                                          }
1461                                          else if (xevent.xbutton.x >= width - win_button_size * 2)                                          else if (xevent.xbutton.x >=
1462                                                     g_width - g_win_button_size * 2)
1463                                          {                                          {
1464                                                  /* The maximize/restore button. Do not send to                                                  /* The maximize/restore button. Do not send to
1465                                                     server.  It might be a good idea to change the                                                     server.  It might be a good idea to change the
1466                                                     cursor or give some other visible indication                                                     cursor or give some other visible indication
1467                                                     that rdesktop inhibited this click */                                                     that rdesktop inhibited this click */
1468                                                  break;                                                  break;
1469                                          }                                          }
1470                                          else if (xevent.xbutton.x >= width - win_button_size * 3)                                          else if (xevent.xbutton.x >=
1471                                                     g_width - g_win_button_size * 3)
1472                                          {                                          {
1473                                                  /* The minimize button. Iconify window. */                                                  /* The minimize button. Iconify window. */
1474                                                  XIconifyWindow(display, wnd,                                                  XIconifyWindow(g_display, g_wnd,
1475                                                                 DefaultScreen(display));                                                                 DefaultScreen(g_display));
1476                                                  break;                                                  break;
1477                                          }                                          }
1478                                          else if (xevent.xbutton.x <= win_button_size)                                          else if (xevent.xbutton.x <= g_win_button_size)
1479                                          {                                          {
1480                                                  /* The system menu. Ignore. */                                                  /* The system menu. Ignore. */
1481                                                  break;                                                  break;
# Line 898  xwin_process_events(void) Line 1483  xwin_process_events(void)
1483                                          else                                          else
1484                                          {                                          {
1485                                                  /* The title bar. */                                                  /* The title bar. */
1486                                                  if ((xevent.type == ButtonPress) && !fullscreen                                                  if ((xevent.type == ButtonPress) && !g_fullscreen
1487                                                      && hide_decorations)                                                      && g_hide_decorations)
1488                                                  {                                                  {
1489                                                          moving_wnd = True;                                                          g_moving_wnd = True;
1490                                                          move_x_offset = xevent.xbutton.x;                                                          g_move_x_offset = xevent.xbutton.x;
1491                                                          move_y_offset = xevent.xbutton.y;                                                          g_move_y_offset = xevent.xbutton.y;
1492                                                  }                                                  }
1493                                                  break;                                                  break;
1494    
# Line 915  xwin_process_events(void) Line 1500  xwin_process_events(void)
1500                                  break;                                  break;
1501    
1502                          case MotionNotify:                          case MotionNotify:
1503                                  if (moving_wnd)                                  if (g_moving_wnd)
1504                                  {                                  {
1505                                          XMoveWindow(display, wnd,                                          XMoveWindow(g_display, g_wnd,
1506                                                      xevent.xmotion.x_root - move_x_offset,                                                      xevent.xmotion.x_root - g_move_x_offset,
1507                                                      xevent.xmotion.y_root - move_y_offset);                                                      xevent.xmotion.y_root - g_move_y_offset);
1508                                          break;                                          break;
1509                                  }                                  }
1510    
1511                                  if (fullscreen && !focused)                                  if (g_fullscreen && !g_focused)
1512                                          XSetInputFocus(display, wnd, RevertToPointerRoot,                                          XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,
1513                                                         CurrentTime);                                                         CurrentTime);
1514                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1515                                                 MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);                                                 MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
# Line 933  xwin_process_events(void) Line 1518  xwin_process_events(void)
1518                          case FocusIn:                          case FocusIn:
1519                                  if (xevent.xfocus.mode == NotifyGrab)                                  if (xevent.xfocus.mode == NotifyGrab)
1520                                          break;                                          break;
1521                                  focused = True;                                  g_focused = True;
1522                                  XQueryPointer(display, wnd, &wdummy, &wdummy, &dummy, &dummy,                                  reset_modifier_keys();
1523                                                &dummy, &dummy, &state);                                  if (g_grab_keyboard && g_mouse_in_wnd)
1524                                  reset_modifier_keys(state);                                          XGrabKeyboard(g_display, g_wnd, True,
                                 if (grab_keyboard && mouse_in_wnd)  
                                         XGrabKeyboard(display, wnd, True,  
1525                                                        GrabModeAsync, GrabModeAsync, CurrentTime);                                                        GrabModeAsync, GrabModeAsync, CurrentTime);
1526                                  break;                                  break;
1527    
1528                          case FocusOut:                          case FocusOut:
1529                                  if (xevent.xfocus.mode == NotifyUngrab)                                  if (xevent.xfocus.mode == NotifyUngrab)
1530                                          break;                                          break;
1531                                  focused = False;                                  g_focused = False;
1532                                  if (xevent.xfocus.mode == NotifyWhileGrabbed)                                  if (xevent.xfocus.mode == NotifyWhileGrabbed)
1533                                          XUngrabKeyboard(display, CurrentTime);                                          XUngrabKeyboard(g_display, CurrentTime);
1534                                  break;                                  break;
1535    
1536                          case EnterNotify:                          case EnterNotify:
1537                                  /* we only register for this event when in fullscreen mode */                                  /* we only register for this event when in fullscreen mode */
1538                                  /* or grab_keyboard */                                  /* or grab_keyboard */
1539                                  mouse_in_wnd = True;                                  g_mouse_in_wnd = True;
1540                                  if (fullscreen)                                  if (g_fullscreen)
1541                                  {                                  {
1542                                          XSetInputFocus(display, wnd, RevertToPointerRoot,                                          XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,
1543                                                         CurrentTime);                                                         CurrentTime);
1544                                          break;                                          break;
1545                                  }                                  }
1546                                  if (focused)                                  if (g_focused)
1547                                          XGrabKeyboard(display, wnd, True,                                          XGrabKeyboard(g_display, g_wnd, True,
1548                                                        GrabModeAsync, GrabModeAsync, CurrentTime);                                                        GrabModeAsync, GrabModeAsync, CurrentTime);
1549                                  break;                                  break;
1550    
1551                          case LeaveNotify:                          case LeaveNotify:
1552                                  /* we only register for this event when grab_keyboard */                                  /* we only register for this event when grab_keyboard */
1553                                  mouse_in_wnd = False;                                  g_mouse_in_wnd = False;
1554                                  XUngrabKeyboard(display, CurrentTime);                                  XUngrabKeyboard(g_display, CurrentTime);
1555                                  break;                                  break;
1556    
1557                          case Expose:                          case Expose:
1558                                  XCopyArea(display, backstore, wnd, gc,                                  XCopyArea(g_display, g_backstore, g_wnd, g_gc,
1559                                            xevent.xexpose.x, xevent.xexpose.y,                                            xevent.xexpose.x, xevent.xexpose.y,
1560                                            xevent.xexpose.width,                                            xevent.xexpose.width,
1561                                            xevent.xexpose.height,                                            xevent.xexpose.height,
# Line 988  xwin_process_events(void) Line 1571  xwin_process_events(void)
1571    
1572                                  if (xevent.xmapping.request == MappingModifier)                                  if (xevent.xmapping.request == MappingModifier)
1573                                  {                                  {
1574                                          XFreeModifiermap(mod_map);                                          XFreeModifiermap(g_mod_map);
1575                                          mod_map = XGetModifierMapping(display);                                          g_mod_map = XGetModifierMapping(g_display);
1576                                  }                                  }
1577                                  break;                                  break;
1578    
1579                                    /* clipboard stuff */
1580                            case SelectionNotify:
1581                                    xclip_handle_SelectionNotify(&xevent.xselection);
1582                                    break;
1583                            case SelectionRequest:
1584                                    xclip_handle_SelectionRequest(&xevent.xselectionrequest);
1585                                    break;
1586                            case SelectionClear:
1587                                    xclip_handle_SelectionClear();
1588                                    break;
1589                            case PropertyNotify:
1590                                    xclip_handle_PropertyNotify(&xevent.xproperty);
1591                                    break;
1592                  }                  }
1593          }          }
1594          /* Keep going */          /* Keep going */
# Line 1003  xwin_process_events(void) Line 1599  xwin_process_events(void)
1599  int  int
1600  ui_select(int rdp_socket)  ui_select(int rdp_socket)
1601  {  {
1602          int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;          int n;
1603          fd_set rfds;          fd_set rfds, wfds;
1604            struct timeval tv;
1605          FD_ZERO(&rfds);          BOOL s_timeout = False;
1606    
1607          while (True)          while (True)
1608          {          {
1609                    n = (rdp_socket > g_x_socket) ? rdp_socket : g_x_socket;
1610                  /* Process any events already waiting */                  /* Process any events already waiting */
1611                  if (!xwin_process_events())                  if (!xwin_process_events())
1612                          /* User quit */                          /* User quit */
1613                          return 0;                          return 0;
1614    
1615                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
1616                    FD_ZERO(&wfds);
1617                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
1618                  FD_SET(x_socket, &rfds);                  FD_SET(g_x_socket, &rfds);
1619    
1620                  switch (select(n, &rfds, NULL, NULL, NULL))  #ifdef WITH_RDPSND
1621                    /* FIXME: there should be an API for registering fds */
1622                    if (g_dsp_busy)
1623                    {
1624                            FD_SET(g_dsp_fd, &wfds);
1625                            n = (g_dsp_fd > n) ? g_dsp_fd : n;
1626                    }
1627    #endif
1628                    /* default timeout */
1629                    tv.tv_sec = 60;
1630                    tv.tv_usec = 0;
1631    
1632                    /* add redirection handles */
1633                    rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
1634    
1635                    n++;
1636    
1637                    switch (select(n, &rfds, &wfds, NULL, &tv))
1638                  {                  {
1639                          case -1:                          case -1:
1640                                  error("select: %s\n", strerror(errno));                                  error("select: %s\n", strerror(errno));
1641    
1642                          case 0:                          case 0:
1643                                    /* Abort serial read calls */
1644                                    if (s_timeout)
1645                                            rdpdr_check_fds(&rfds, &wfds, (BOOL) True);
1646                                  continue;                                  continue;
1647                  }                  }
1648    
1649                    rdpdr_check_fds(&rfds, &wfds, (BOOL) False);
1650    
1651                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
1652                          return 1;                          return 1;
1653    
1654    #ifdef WITH_RDPSND
1655                    if (g_dsp_busy && FD_ISSET(g_dsp_fd, &wfds))
1656                            wave_out_play();
1657    #endif
1658          }          }
1659  }  }
1660    
1661  void  void
1662  ui_move_pointer(int x, int y)  ui_move_pointer(int x, int y)
1663  {  {
1664          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);          XWarpPointer(g_display, g_wnd, g_wnd, 0, 0, 0, 0, x, y);
1665  }  }
1666    
1667  HBITMAP  HBITMAP
# Line 1045  ui_create_bitmap(int width, int height, Line 1670  ui_create_bitmap(int width, int height,
1670          XImage *image;          XImage *image;
1671          Pixmap bitmap;          Pixmap bitmap;
1672          uint8 *tdata;          uint8 *tdata;
1673            int bitmap_pad;
1674    
1675            if (g_server_bpp == 8)
1676            {
1677                    bitmap_pad = 8;
1678            }
1679            else
1680            {
1681                    bitmap_pad = g_bpp;
1682    
1683                    if (g_bpp == 24)
1684                            bitmap_pad = 32;
1685            }
1686    
1687          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (g_owncolmap ? data : translate_image(width, height, data));
1688          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(g_display, g_wnd, width, height, g_depth);
1689          image = XCreateImage(display, visual, depth, ZPixmap, 0,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1690                               (char *) tdata, width, height, server_bpp == 8 ? 8 : bpp, 0);                               (char *) tdata, width, height, bitmap_pad, 0);
1691    
1692          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);
1693    
1694          XFree(image);          XFree(image);
1695          if (!owncolmap)          if (tdata != data)
1696                  xfree(tdata);                  xfree(tdata);
1697          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
1698  }  }
# Line 1064  ui_paint_bitmap(int x, int y, int cx, in Line 1702  ui_paint_bitmap(int x, int y, int cx, in
1702  {  {
1703          XImage *image;          XImage *image;
1704          uint8 *tdata;          uint8 *tdata;
1705          tdata = (owncolmap ? data : translate_image(width, height, data));          int bitmap_pad;
         image = XCreateImage(display, visual, depth, ZPixmap, 0,  
                              (char *) tdata, width, height, server_bpp == 8 ? 8 : bpp, 0);  
1706    
1707          if (ownbackstore)          if (g_server_bpp == 8)
1708          {          {
1709                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);                  bitmap_pad = 8;
                 XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);  
1710          }          }
1711          else          else
1712          {          {
1713                  XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);                  bitmap_pad = g_bpp;
1714    
1715                    if (g_bpp == 24)
1716                            bitmap_pad = 32;
1717            }
1718    
1719            tdata = (g_owncolmap ? data : translate_image(width, height, data));
1720            image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1721                                 (char *) tdata, width, height, bitmap_pad, 0);
1722    
1723            if (g_ownbackstore)
1724            {
1725                    XPutImage(g_display, g_backstore, g_gc, image, 0, 0, x, y, cx, cy);
1726                    XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
1727            }
1728            else
1729            {
1730                    XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy);
1731          }          }
1732    
1733          XFree(image);          XFree(image);
1734          if (!owncolmap)          if (tdata != data)
1735                  xfree(tdata);                  xfree(tdata);
1736  }  }
1737    
1738  void  void
1739  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(HBITMAP bmp)
1740  {  {
1741          XFreePixmap(display, (Pixmap) bmp);          XFreePixmap(g_display, (Pixmap) bmp);
1742  }  }
1743    
1744  HGLYPH  HGLYPH
# Line 1095  ui_create_glyph(int width, int height, u Line 1747  ui_create_glyph(int width, int height, u
1747          XImage *image;          XImage *image;
1748          Pixmap bitmap;          Pixmap bitmap;
1749          int scanline;          int scanline;
         GC gc;  
1750    
1751          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1752    
1753          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(g_display, g_wnd, width, height, 1);
1754          gc = XCreateGC(display, bitmap, 0, NULL);          if (g_create_glyph_gc == 0)
1755                    g_create_glyph_gc = XCreateGC(g_display, bitmap, 0, NULL);
1756    
1757          image = XCreateImage(display, visual, 1, ZPixmap, 0, (char *) data,          image = XCreateImage(g_display, g_visual, 1, ZPixmap, 0, (char *) data,
1758                               width, height, 8, scanline);                               width, height, 8, scanline);
1759          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
1760          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
1761          XInitImage(image);          XInitImage(image);
1762    
1763          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);
1764    
1765          XFree(image);          XFree(image);
         XFreeGC(display, gc);  
1766          return (HGLYPH) bitmap;          return (HGLYPH) bitmap;
1767  }  }
1768    
1769  void  void
1770  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
1771  {  {
1772          XFreePixmap(display, (Pixmap) glyph);          XFreePixmap(g_display, (Pixmap) glyph);
1773  }  }
1774    
1775  HCURSOR  HCURSOR
# Line 1137  ui_create_cursor(unsigned int x, unsigne Line 1788  ui_create_cursor(unsigned int x, unsigne
1788          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1789          offset = scanline * height;          offset = scanline * height;
1790    
1791          cursor = (uint8*)xmalloc(offset);          cursor = (uint8 *) xmalloc(offset);
1792          memset(cursor, 0, offset);          memset(cursor, 0, offset);
1793    
1794          mask = (uint8*)xmalloc(offset);          mask = (uint8 *) xmalloc(offset);
1795          memset(mask, 0, offset);          memset(mask, 0, offset);
1796    
1797          /* approximate AND and XOR masks with a monochrome X pointer */          /* approximate AND and XOR masks with a monochrome X pointer */
# Line 1182  ui_create_cursor(unsigned int x, unsigne Line 1833  ui_create_cursor(unsigned int x, unsigne
1833          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
1834    
1835          xcursor =          xcursor =
1836                  XCreatePixmapCursor(display, (Pixmap) cursorglyph,                  XCreatePixmapCursor(g_display, (Pixmap) cursorglyph,
1837                                      (Pixmap) maskglyph, &fg, &bg, x, y);                                      (Pixmap) maskglyph, &fg, &bg, x, y);
1838    
1839          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
# Line 1195  ui_create_cursor(unsigned int x, unsigne Line 1846  ui_create_cursor(unsigned int x, unsigne
1846  void  void
1847  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
1848  {  {
1849          current_cursor = (Cursor) cursor;          g_current_cursor = (Cursor) cursor;
1850          XDefineCursor(display, wnd, current_cursor);          XDefineCursor(g_display, g_wnd, g_current_cursor);
1851  }  }
1852    
1853  void  void
1854  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_cursor(HCURSOR cursor)
1855  {  {
1856          XFreeCursor(display, (Cursor) cursor);          XFreeCursor(g_display, (Cursor) cursor);
1857    }
1858    
1859    void
1860    ui_set_null_cursor(void)
1861    {
1862            ui_set_cursor(g_null_cursor);
1863  }  }
1864    
1865  #define MAKE_XCOLOR(xc,c) \  #define MAKE_XCOLOR(xc,c) \
# Line 1217  ui_create_colourmap(COLOURMAP * colours) Line 1874  ui_create_colourmap(COLOURMAP * colours)
1874  {  {
1875          COLOURENTRY *entry;          COLOURENTRY *entry;
1876          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
1877          if (!owncolmap)          if (!g_owncolmap)
1878          {          {
1879                  uint32 *map = (uint32*)xmalloc(sizeof(*colmap) * ncolours);                  uint32 *map = (uint32 *) xmalloc(sizeof(*g_colmap) * ncolours);
1880                  XColor xentry;                  XColor xentry;
1881                  XColor xc_cache[256];                  XColor xc_cache[256];
1882                  uint32 colour;                  uint32 colour;
# Line 1229  ui_create_colourmap(COLOURMAP * colours) Line 1886  ui_create_colourmap(COLOURMAP * colours)
1886                          entry = &colours->colours[i];                          entry = &colours->colours[i];
1887                          MAKE_XCOLOR(&xentry, entry);                          MAKE_XCOLOR(&xentry, entry);
1888    
1889                          if (XAllocColor(display, xcolmap, &xentry) == 0)                          if (XAllocColor(g_display, g_xcolmap, &xentry) == 0)
1890                          {                          {
1891                                  /* Allocation failed, find closest match. */                                  /* Allocation failed, find closest match. */
1892                                  int j = 256;                                  int j = 256;
# Line 1243  ui_create_colourmap(COLOURMAP * colours) Line 1900  ui_create_colourmap(COLOURMAP * colours)
1900                                          xc_cache[colLookup].red = xc_cache[colLookup].green =                                          xc_cache[colLookup].red = xc_cache[colLookup].green =
1901                                                  xc_cache[colLookup].blue = 0;                                                  xc_cache[colLookup].blue = 0;
1902                                          xc_cache[colLookup].flags = 0;                                          xc_cache[colLookup].flags = 0;
1903                                          XQueryColor(display,                                          XQueryColor(g_display,
1904                                                      DefaultColormap(display,                                                      DefaultColormap(g_display,
1905                                                                      DefaultScreen(display)),                                                                      DefaultScreen(g_display)),
1906                                                      &xc_cache[colLookup]);                                                      &xc_cache[colLookup]);
1907                                  }                                  }
1908                                  colLookup = 0;                                  colLookup = 0;
# Line 1286  ui_create_colourmap(COLOURMAP * colours) Line 1943  ui_create_colourmap(COLOURMAP * colours)
1943    
1944                          }                          }
1945    
1946                            map[i] = colour;
                         /* byte swap here to make translate_image faster */  
                         map[i] = translate_colour(colour);  
1947                  }                  }
1948                  return map;                  return map;
1949          }          }
# Line 1297  ui_create_colourmap(COLOURMAP * colours) Line 1952  ui_create_colourmap(COLOURMAP * colours)
1952                  XColor *xcolours, *xentry;                  XColor *xcolours, *xentry;
1953                  Colormap map;                  Colormap map;
1954    
1955                  xcolours = (XColor*)xmalloc(sizeof(XColor) * ncolours);                  xcolours = (XColor *) xmalloc(sizeof(XColor) * ncolours);
1956                  for (i = 0; i < ncolours; i++)                  for (i = 0; i < ncolours; i++)
1957                  {                  {
1958                          entry = &colours->colours[i];                          entry = &colours->colours[i];
# Line 1306  ui_create_colourmap(COLOURMAP * colours) Line 1961  ui_create_colourmap(COLOURMAP * colours)
1961                          MAKE_XCOLOR(xentry, entry);                          MAKE_XCOLOR(xentry, entry);
1962                  }                  }
1963    
1964                  map = XCreateColormap(display, wnd, visual, AllocAll);                  map = XCreateColormap(g_display, g_wnd, g_visual, AllocAll);
1965                  XStoreColors(display, map, xcolours, ncolours);                  XStoreColors(g_display, map, xcolours, ncolours);
1966    
1967                  xfree(xcolours);                  xfree(xcolours);
1968                  return (HCOLOURMAP) map;                  return (HCOLOURMAP) map;
# Line 1317  ui_create_colourmap(COLOURMAP * colours) Line 1972  ui_create_colourmap(COLOURMAP * colours)
1972  void  void
1973  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
1974  {  {
1975          if (!owncolmap)          if (!g_owncolmap)
1976                  xfree(map);                  xfree(map);
1977          else          else
1978                  XFreeColormap(display, (Colormap) map);                  XFreeColormap(g_display, (Colormap) map);
1979  }  }
1980    
1981  void  void
1982  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
1983  {  {
1984          if (!owncolmap)          if (!g_owncolmap)
1985                  colmap = (uint32*)map;          {
1986                    if (g_colmap)
1987                            xfree(g_colmap);
1988    
1989                    g_colmap = (uint32 *) map;
1990            }
1991          else          else
1992                  XSetWindowColormap(display, wnd, (Colormap) map);                  XSetWindowColormap(g_display, g_wnd, (Colormap) map);
1993  }  }
1994    
1995  void  void
# Line 1341  ui_set_clip(int x, int y, int cx, int cy Line 2001  ui_set_clip(int x, int y, int cx, int cy
2001          rect.y = y;          rect.y = y;
2002          rect.width = cx;          rect.width = cx;
2003          rect.height = cy;          rect.height = cy;
2004          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);
2005  }  }
2006    
2007  void  void
# Line 1351  ui_reset_clip(void) Line 2011  ui_reset_clip(void)
2011    
2012          rect.x = 0;          rect.x = 0;
2013          rect.y = 0;          rect.y = 0;
2014          rect.width = width;          rect.width = g_width;
2015          rect.height = height;          rect.height = g_height;
2016          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);
2017  }  }
2018    
2019  void  void
2020  ui_bell(void)  ui_bell(void)
2021  {  {
2022          XBell(display, 0);          XBell(g_display, 0);
2023  }  }
2024    
2025  void  void
# Line 1372  ui_destblt(uint8 opcode, Line 2032  ui_destblt(uint8 opcode,
2032  }  }
2033    
2034  static uint8 hatch_patterns[] = {  static uint8 hatch_patterns[] = {
2035          0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0 - bsHorizontal */          0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0 - bsHorizontal */
2036          0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 1 - bsVertical */          0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 1 - bsVertical */
2037          0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, /* 2 - bsFDiagonal */          0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, /* 2 - bsFDiagonal */
2038          0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* 3 - bsBDiagonal */          0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* 3 - bsBDiagonal */
2039          0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, /* 4 - bsCross */          0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, /* 4 - bsCross */
2040          0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81  /* 5 - bsDiagCross */          0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81  /* 5 - bsDiagCross */
2041  };  };
2042    
2043  void  void
# Line 1394  ui_patblt(uint8 opcode, Line 2054  ui_patblt(uint8 opcode,
2054          {          {
2055                  case 0: /* Solid */                  case 0: /* Solid */
2056                          SET_FOREGROUND(fgcolour);                          SET_FOREGROUND(fgcolour);
2057                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
2058                          break;                          break;
2059    
2060                  case 2: /* Hatch */                  case 2: /* Hatch */
2061                          fill = (Pixmap) ui_create_glyph(8, 8, hatch_patterns + brush->pattern[0] * 8);                          fill = (Pixmap) ui_create_glyph(8, 8,
2062                          SET_FOREGROUND(bgcolour);                                                          hatch_patterns + brush->pattern[0] * 8);
2063                          SET_BACKGROUND(fgcolour);                          SET_FOREGROUND(fgcolour);
2064                          XSetFillStyle(display, gc, FillOpaqueStippled);                          SET_BACKGROUND(bgcolour);
2065                          XSetStipple(display, gc, fill);                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2066                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);                          XSetStipple(g_display, g_gc, fill);
2067                          FILL_RECTANGLE(x, y, cx, cy);                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2068                          XSetFillStyle(display, gc, FillSolid);                          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
2069                          XSetTSOrigin(display, gc, 0, 0);                          XSetFillStyle(g_display, g_gc, FillSolid);
2070                            XSetTSOrigin(g_display, g_gc, 0, 0);
2071                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH) fill);
2072                          break;                          break;
2073    
# Line 1414  ui_patblt(uint8 opcode, Line 2075  ui_patblt(uint8 opcode,
2075                          for (i = 0; i != 8; i++)                          for (i = 0; i != 8; i++)
2076                                  ipattern[7 - i] = brush->pattern[i];                                  ipattern[7 - i] = brush->pattern[i];
2077                          fill = (Pixmap) ui_create_glyph(8, 8, ipattern);                          fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
   
2078                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(bgcolour);
2079                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
2080                          XSetFillStyle(display, gc, FillOpaqueStippled);                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2081                          XSetStipple(display, gc, fill);                          XSetStipple(g_display, g_gc, fill);
2082                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2083                            FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
2084                          FILL_RECTANGLE(x, y, cx, cy);                          XSetFillStyle(g_display, g_gc, FillSolid);
2085                            XSetTSOrigin(g_display, g_gc, 0, 0);
                         XSetFillStyle(display, gc, FillSolid);  
                         XSetTSOrigin(display, gc, 0, 0);  
2086                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH) fill);
2087                          break;                          break;
2088    
# Line 1433  ui_patblt(uint8 opcode, Line 2091  ui_patblt(uint8 opcode,
2091          }          }
2092    
2093          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
2094    
2095            if (g_ownbackstore)
2096                    XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
2097  }  }
2098    
2099  void  void
# Line 1441  ui_screenblt(uint8 opcode, Line 2102  ui_screenblt(uint8 opcode,
2102               /* src */ int srcx, int srcy)               /* src */ int srcx, int srcy)
2103  {  {
2104          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
2105          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          if (g_ownbackstore)
2106          if (ownbackstore)          {
2107                  XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, cy, x, y);                  if (g_Unobscured)
2108                    {
2109                            XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
2110                            XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x,
2111                                      y);
2112                    }
2113                    else
2114                    {
2115                            XCopyArea(g_display, g_backstore, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
2116                            XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x,
2117                                      y);
2118                    }
2119            }
2120            else
2121            {
2122                    XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
2123            }
2124          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
2125  }  }
2126    
# Line 1453  ui_memblt(uint8 opcode, Line 2130  ui_memblt(uint8 opcode,
2130            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
2131  {  {
2132          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
2133          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);
2134          if (ownbackstore)          if (g_ownbackstore)
2135                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy, cx, cy, x, y);                  XCopyArea(g_display, (Pixmap) src, g_backstore, g_gc, srcx, srcy, cx, cy, x, y);
2136          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
2137  }  }
2138    
# Line 1499  ui_line(uint8 opcode, Line 2176  ui_line(uint8 opcode,
2176  {  {
2177          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
2178          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
2179          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(g_display, g_wnd, g_gc, startx, starty, endx, endy);
2180          if (ownbackstore)          if (g_ownbackstore)
2181                  XDrawLine(display, backstore, gc, startx, starty, endx, endy);                  XDrawLine(g_display, g_backstore, g_gc, startx, starty, endx, endy);
2182          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
2183  }  }
2184    
# Line 1514  ui_rect( Line 2191  ui_rect(
2191          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
2192  }  }
2193    
2194    void
2195    ui_polygon(uint8 opcode,
2196               /* mode */ uint8 fillmode,
2197               /* dest */ POINT * point, int npoints,
2198               /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2199    {
2200            uint8 style, i, ipattern[8];
2201            Pixmap fill;
2202    
2203            SET_FUNCTION(opcode);
2204    
2205            switch (fillmode)
2206            {
2207                    case ALTERNATE:
2208                            XSetFillRule(g_display, g_gc, EvenOddRule);
2209                            break;
2210                    case WINDING:
2211                            XSetFillRule(g_display, g_gc, WindingRule);
2212                            break;
2213                    default:
2214                            unimpl("fill mode %d\n", fillmode);
2215            }
2216    
2217            if (brush)
2218                    style = brush->style;
2219            else
2220                    style = 0;
2221    
2222            switch (style)
2223            {
2224                    case 0: /* Solid */
2225                            SET_FOREGROUND(fgcolour);
2226                            FILL_POLYGON((XPoint *) point, npoints);
2227                            break;
2228    
2229                    case 2: /* Hatch */
2230                            fill = (Pixmap) ui_create_glyph(8, 8,
2231                                                            hatch_patterns + brush->pattern[0] * 8);
2232                            SET_FOREGROUND(fgcolour);
2233                            SET_BACKGROUND(bgcolour);
2234                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2235                            XSetStipple(g_display, g_gc, fill);
2236                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2237                            FILL_POLYGON((XPoint *) point, npoints);
2238                            XSetFillStyle(g_display, g_gc, FillSolid);
2239                            XSetTSOrigin(g_display, g_gc, 0, 0);
2240                            ui_destroy_glyph((HGLYPH) fill);
2241                            break;
2242    
2243                    case 3: /* Pattern */
2244                            for (i = 0; i != 8; i++)
2245                                    ipattern[7 - i] = brush->pattern[i];
2246                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
2247                            SET_FOREGROUND(bgcolour);
2248                            SET_BACKGROUND(fgcolour);
2249                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2250                            XSetStipple(g_display, g_gc, fill);
2251                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2252                            FILL_POLYGON((XPoint *) point, npoints);
2253                            XSetFillStyle(g_display, g_gc, FillSolid);
2254                            XSetTSOrigin(g_display, g_gc, 0, 0);
2255                            ui_destroy_glyph((HGLYPH) fill);
2256                            break;
2257    
2258                    default:
2259                            unimpl("brush %d\n", brush->style);
2260            }
2261    
2262            RESET_FUNCTION(opcode);
2263    }
2264    
2265    void
2266    ui_polyline(uint8 opcode,
2267                /* dest */ POINT * points, int npoints,
2268                /* pen */ PEN * pen)
2269    {
2270            /* TODO: set join style */
2271            SET_FUNCTION(opcode);
2272            SET_FOREGROUND(pen->colour);
2273            XDrawLines(g_display, g_wnd, g_gc, (XPoint *) points, npoints, CoordModePrevious);
2274            if (g_ownbackstore)
2275                    XDrawLines(g_display, g_backstore, g_gc, (XPoint *) points, npoints,
2276                               CoordModePrevious);
2277            RESET_FUNCTION(opcode);
2278    }
2279    
2280    void
2281    ui_ellipse(uint8 opcode,
2282               /* mode */ uint8 fillmode,
2283               /* dest */ int x, int y, int cx, int cy,
2284               /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2285    {
2286            uint8 style, i, ipattern[8];
2287            Pixmap fill;
2288    
2289            SET_FUNCTION(opcode);
2290    
2291            if (brush)
2292                    style = brush->style;
2293            else
2294                    style = 0;
2295    
2296            switch (style)
2297            {
2298                    case 0: /* Solid */
2299                            SET_FOREGROUND(fgcolour);
2300                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2301                            break;
2302    
2303                    case 2: /* Hatch */
2304                            fill = (Pixmap) ui_create_glyph(8, 8,
2305                                                            hatch_patterns + brush->pattern[0] * 8);
2306                            SET_FOREGROUND(fgcolour);
2307                            SET_BACKGROUND(bgcolour);
2308                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2309                            XSetStipple(g_display, g_gc, fill);
2310                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2311                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2312                            XSetFillStyle(g_display, g_gc, FillSolid);
2313                            XSetTSOrigin(g_display, g_gc, 0, 0);
2314                            ui_destroy_glyph((HGLYPH) fill);
2315                            break;
2316    
2317                    case 3: /* Pattern */
2318                            for (i = 0; i != 8; i++)
2319                                    ipattern[7 - i] = brush->pattern[i];
2320                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
2321                            SET_FOREGROUND(bgcolour);
2322                            SET_BACKGROUND(fgcolour);
2323                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2324                            XSetStipple(g_display, g_gc, fill);
2325                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2326                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2327                            XSetFillStyle(g_display, g_gc, FillSolid);
2328                            XSetTSOrigin(g_display, g_gc, 0, 0);
2329                            ui_destroy_glyph((HGLYPH) fill);
2330                            break;
2331    
2332                    default:
2333                            unimpl("brush %d\n", brush->style);
2334            }
2335    
2336            RESET_FUNCTION(opcode);
2337    }
2338    
2339  /* warning, this function only draws on wnd or backstore, not both */  /* warning, this function only draws on wnd or backstore, not both */
2340  void  void
2341  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
# Line 1524  ui_draw_glyph(int mixmode, Line 2346  ui_draw_glyph(int mixmode,
2346          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
2347          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
2348    
2349          XSetFillStyle(display, gc,          XSetFillStyle(g_display, g_gc,
2350                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
2351          XSetStipple(display, gc, (Pixmap) glyph);          XSetStipple(g_display, g_gc, (Pixmap) glyph);
2352          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(g_display, g_gc, x, y);
2353    
2354          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
2355    
2356          XSetFillStyle(display, gc, FillSolid);          XSetFillStyle(g_display, g_gc, FillSolid);
2357  }  }
2358    
2359  #define DO_GLYPH(ttext,idx) \  #define DO_GLYPH(ttext,idx) \
2360  {\  {\
2361    glyph = cache_get_font (font, ttext[idx]);\    glyph = cache_get_font (font, ttext[idx]);\
2362    if (!(flags & TEXT2_IMPLICIT_X))\    if (!(flags & TEXT2_IMPLICIT_X))\
2363      {\
2364        xyoffset = ttext[++idx];\
2365        if ((xyoffset & 0x80))\
2366      {\      {\
2367        xyoffset = ttext[++idx];\        if (flags & TEXT2_VERTICAL)\
2368        if ((xyoffset & 0x80))\          y += ttext[idx+1] | (ttext[idx+2] << 8);\
         {\  
           if (flags & TEXT2_VERTICAL) \  
             y += ttext[idx+1] | (ttext[idx+2] << 8);\  
           else\  
             x += ttext[idx+1] | (ttext[idx+2] << 8);\  
           idx += 2;\  
         }\  
2369        else\        else\
2370          {\          x += ttext[idx+1] | (ttext[idx+2] << 8);\
2371            if (flags & TEXT2_VERTICAL) \        idx += 2;\
             y += xyoffset;\  
           else\  
             x += xyoffset;\  
         }\  
2372      }\      }\
2373    if (glyph != NULL)\      else\
2374      {\      {\
2375        ui_draw_glyph (mixmode, x + glyph->offset,\        if (flags & TEXT2_VERTICAL)\
2376                       y + glyph->baseline,\          y += xyoffset;\
2377                       glyph->width, glyph->height,\        else\
2378                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\          x += xyoffset;\
       if (flags & TEXT2_IMPLICIT_X)\  
         x += glyph->width;\  
2379      }\      }\
2380      }\
2381      if (glyph != NULL)\
2382      {\
2383        x1 = x + glyph->offset;\
2384        y1 = y + glyph->baseline;\
2385        XSetStipple(g_display, g_gc, (Pixmap) glyph->pixmap);\
2386        XSetTSOrigin(g_display, g_gc, x1, y1);\
2387        FILL_RECTANGLE_BACKSTORE(x1, y1, glyph->width, glyph->height);\
2388        if (flags & TEXT2_IMPLICIT_X)\
2389          x += glyph->width;\
2390      }\
2391  }  }
2392    
2393  void  void
2394  ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,  ui_draw_text(uint8 font, uint8 flags, uint8 opcode, int mixmode, int x, int y,
2395               int clipx, int clipy, int clipcx, int clipcy,               int clipx, int clipy, int clipcx, int clipcy,
2396               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, BRUSH * brush,
2397               int fgcolour, uint8 * text, uint8 length)               int bgcolour, int fgcolour, uint8 * text, uint8 length)
2398  {  {
2399            /* TODO: use brush appropriately */
2400    
2401          FONTGLYPH *glyph;          FONTGLYPH *glyph;
2402          int i, j, xyoffset;          int i, j, xyoffset, x1, y1;
2403          DATABLOB *entry;          DATABLOB *entry;
2404    
2405          SET_FOREGROUND(bgcolour);          SET_FOREGROUND(bgcolour);
2406    
2407            /* Sometimes, the boxcx value is something really large, like
2408               32691. This makes XCopyArea fail with Xvnc. The code below
2409               is a quick fix. */
2410            if (boxx + boxcx > g_width)
2411                    boxcx = g_width - boxx;
2412    
2413          if (boxcx > 1)          if (boxcx > 1)
2414          {          {
2415                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);
# Line 1588  ui_draw_text(uint8 font, uint8 flags, in Line 2419  ui_draw_text(uint8 font, uint8 flags, in
2419                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
2420          }          }
2421    
2422            SET_FOREGROUND(fgcolour);
2423            SET_BACKGROUND(bgcolour);
2424            XSetFillStyle(g_display, g_gc, FillStippled);
2425    
2426          /* Paint text, character by character */          /* Paint text, character by character */
2427          for (i = 0; i < length;)          for (i = 0; i < length;)
2428          {          {
# Line 1638  ui_draw_text(uint8 font, uint8 flags, in Line 2473  ui_draw_text(uint8 font, uint8 flags, in
2473                                  break;                                  break;
2474                  }                  }
2475          }          }
2476          if (ownbackstore)  
2477            XSetFillStyle(g_display, g_gc, FillSolid);
2478    
2479            if (g_ownbackstore)
2480          {          {
2481                  if (boxcx > 1)                  if (boxcx > 1)
2482                          XCopyArea(display, backstore, wnd, gc, boxx,                          XCopyArea(g_display, g_backstore, g_wnd, g_gc, boxx,
2483                                    boxy, boxcx, boxcy, boxx, boxy);                                    boxy, boxcx, boxcy, boxx, boxy);
2484                  else                  else
2485                          XCopyArea(display, backstore, wnd, gc, clipx,                          XCopyArea(g_display, g_backstore, g_wnd, g_gc, clipx,
2486                                    clipy, clipcx, clipcy, clipx, clipy);                                    clipy, clipcx, clipcy, clipx, clipy);
2487          }          }
2488  }  }
# Line 1655  ui_desktop_save(uint32 offset, int x, in Line 2493  ui_desktop_save(uint32 offset, int x, in
2493          Pixmap pix;          Pixmap pix;
2494          XImage *image;          XImage *image;
2495    
2496          if (ownbackstore)          if (g_ownbackstore)
2497          {          {
2498                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes, ZPixmap);                  image = XGetImage(g_display, g_backstore, x, y, cx, cy, AllPlanes, ZPixmap);
2499          }          }
2500          else          else
2501          {          {
2502                  pix = XCreatePixmap(display, wnd, cx, cy, depth);                  pix = XCreatePixmap(g_display, g_wnd, cx, cy, g_depth);
2503                  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);
2504                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);                  image = XGetImage(g_display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
2505                  XFreePixmap(display, pix);                  XFreePixmap(g_display, pix);
2506          }          }
2507    
2508          offset *= bpp / 8;          offset *= g_bpp / 8;
2509          cache_put_desktop(offset, cx, cy, image->bytes_per_line, bpp / 8, (uint8 *) image->data);          cache_put_desktop(offset, cx, cy, image->bytes_per_line, g_bpp / 8, (uint8 *) image->data);
2510    
2511          XDestroyImage(image);          XDestroyImage(image);
2512  }  }
# Line 1679  ui_desktop_restore(uint32 offset, int x, Line 2517  ui_desktop_restore(uint32 offset, int x,
2517          XImage *image;          XImage *image;
2518          uint8 *data;          uint8 *data;
2519    
2520          offset *= bpp / 8;          offset *= g_bpp / 8;
2521          data = cache_get_desktop(offset, cx, cy, bpp / 8);          data = cache_get_desktop(offset, cx, cy, g_bpp / 8);
2522          if (data == NULL)          if (data == NULL)
2523                  return;                  return;
2524    
2525          image = XCreateImage(display, visual, depth, ZPixmap, 0,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
2526                               (char *) data, cx, cy, BitmapPad(display), cx * bpp / 8);                               (char *) data, cx, cy, BitmapPad(g_display), cx * g_bpp / 8);
2527    
2528          if (ownbackstore)          if (g_ownbackstore)
2529          {          {
2530                  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);
2531                  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);
2532          }          }
2533          else          else
2534          {          {
2535                  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);
2536          }          }
2537    
2538          XFree(image);          XFree(image);
2539  }  }
2540    
2541    /* these do nothing here but are used in uiports */
2542    void
2543    ui_begin_update(void)
2544    {
2545    }
2546    
2547    void
2548    ui_end_update(void)
2549    {
2550    }

Legend:
Removed from v.376  
changed lines
  Added in v.844

  ViewVC Help
Powered by ViewVC 1.1.26