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

Diff of /sourceforge.net/branches/seamlessrdp-branch/rdesktop/xwin.c

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

revision 456 by astrand, Sun Aug 31 20:01:12 2003 UTC revision 867 by stargo, Wed Mar 23 12:25:54 2005 UTC
# Line 1  Line 1 
1  /* -*- c-basic-offset: 8 -*-  /* -*- 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"  #include "xproto.h"
30    
31  extern int g_width;  extern int g_width;
32  extern int g_height;  extern int g_height;
33    extern int g_xpos;
34    extern int g_ypos;
35    extern int g_pos;
36  extern BOOL g_sendmotion;  extern BOOL g_sendmotion;
37  extern BOOL g_fullscreen;  extern BOOL g_fullscreen;
38  extern BOOL g_grab_keyboard;  extern BOOL g_grab_keyboard;
# Line 34  extern BOOL g_hide_decorations; Line 40  extern BOOL g_hide_decorations;
40  extern char g_title[];  extern char g_title[];
41  extern int g_server_bpp;  extern int g_server_bpp;
42  extern int g_win_button_size;  extern int g_win_button_size;
 BOOL g_enable_compose = False;  
 BOOL g_focused;  
 BOOL g_mouse_in_wnd;  
43    
44  Display *g_display;  Display *g_display;
45  Time g_last_gesturetime;  Time g_last_gesturetime;
46  static int g_x_socket;  static int g_x_socket;
47  static Screen *g_screen;  static Screen *g_screen;
48  Window g_wnd;  Window g_wnd;
49  static GC g_gc;  extern uint32 g_embed_wnd;
50    BOOL g_enable_compose = False;
51    BOOL g_Unobscured;              /* used for screenblt */
52    static GC g_gc = NULL;
53    static GC g_create_bitmap_gc = NULL;
54    static GC g_create_glyph_gc = NULL;
55  static Visual *g_visual;  static Visual *g_visual;
56  static int g_depth;  static int g_depth;
57  static int g_bpp;  static int g_bpp;
# Line 51  static XIM g_IM; Line 59  static XIM g_IM;
59  static XIC g_IC;  static XIC g_IC;
60  static XModifierKeymap *g_mod_map;  static XModifierKeymap *g_mod_map;
61  static Cursor g_current_cursor;  static Cursor g_current_cursor;
62    static HCURSOR g_null_cursor = NULL;
63  static Atom g_protocol_atom, g_kill_atom;  static Atom g_protocol_atom, g_kill_atom;
64    static BOOL g_focused;
65    static BOOL g_mouse_in_wnd;
66    static BOOL g_arch_match = False;       /* set to True if RGB XServer and little endian */
67    
68  /* endianness */  /* endianness */
69  static BOOL g_host_be;  static BOOL g_host_be;
70  static BOOL g_xserver_be;  static BOOL g_xserver_be;
71    static int g_red_shift_r, g_blue_shift_r, g_green_shift_r;
72    static int g_red_shift_l, g_blue_shift_l, g_green_shift_l;
73    
74  /* software backing store */  /* software backing store */
75  static BOOL g_ownbackstore;  extern BOOL g_ownbackstore;
76  static Pixmap g_backstore;  static Pixmap g_backstore = 0;
77    
78  /* Moving in single app mode */  /* Moving in single app mode */
79  static BOOL g_moving_wnd;  static BOOL g_moving_wnd;
80  static int g_move_x_offset = 0;  static int g_move_x_offset = 0;
81  static int g_move_y_offset = 0;  static int g_move_y_offset = 0;
82    
83    #ifdef WITH_RDPSND
84    extern int g_dsp_fd;
85    extern BOOL g_dsp_busy;
86    extern BOOL g_rdpsnd;
87    #endif
88    
89  /* MWM decorations */  /* MWM decorations */
90  #define MWM_HINTS_DECORATIONS   (1L << 1)  #define MWM_HINTS_DECORATIONS   (1L << 1)
91  #define PROP_MOTIF_WM_HINTS_ELEMENTS    5  #define PROP_MOTIF_WM_HINTS_ELEMENTS    5
# Line 100  PixelColour; Line 120  PixelColour;
120          XFillRectangle(g_display, g_ownbackstore ? g_backstore : g_wnd, g_gc, x, y, cx, cy); \          XFillRectangle(g_display, g_ownbackstore ? g_backstore : g_wnd, g_gc, x, y, cx, cy); \
121  }  }
122    
123    #define FILL_POLYGON(p,np)\
124    { \
125            XFillPolygon(g_display, g_wnd, g_gc, p, np, Complex, CoordModePrevious); \
126            if (g_ownbackstore) \
127                    XFillPolygon(g_display, g_backstore, g_gc, p, np, Complex, CoordModePrevious); \
128    }
129    
130    #define DRAW_ELLIPSE(x,y,cx,cy,m)\
131    { \
132            switch (m) \
133            { \
134                    case 0: /* Outline */ \
135                            XDrawArc(g_display, g_wnd, g_gc, x, y, cx, cy, 0, 360*64); \
136                            if (g_ownbackstore) \
137                                    XDrawArc(g_display, g_backstore, g_gc, x, y, cx, cy, 0, 360*64); \
138                            break; \
139                    case 1: /* Filled */ \
140                            XFillArc(g_display, g_ownbackstore ? g_backstore : g_wnd, g_gc, x, y, \
141                                     cx, cy, 0, 360*64); \
142                            if (g_ownbackstore) \
143                                    XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y); \
144                            break; \
145            } \
146    }
147    
148  /* colour maps */  /* colour maps */
149  BOOL g_owncolmap = False;  extern BOOL g_owncolmap;
150  static Colormap g_xcolmap;  static Colormap g_xcolmap;
151  static uint32 *g_colmap = NULL;  static uint32 *g_colmap = NULL;
152    
153  #define TRANSLATE(col)          ( g_server_bpp != 8 ? translate_colour(col) : g_owncolmap ? col : translate_colour(g_colmap[col]) )  #define TRANSLATE(col)          ( g_server_bpp != 8 ? translate_colour(col) : g_owncolmap ? col : g_colmap[col] )
154  #define SET_FOREGROUND(col)     XSetForeground(g_display, g_gc, TRANSLATE(col));  #define SET_FOREGROUND(col)     XSetForeground(g_display, g_gc, TRANSLATE(col));
155  #define SET_BACKGROUND(col)     XSetBackground(g_display, g_gc, TRANSLATE(col));  #define SET_BACKGROUND(col)     XSetBackground(g_display, g_gc, TRANSLATE(col));
156    
# Line 153  mwm_hide_decorations(void) Line 198  mwm_hide_decorations(void)
198                          (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);                          (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
199  }  }
200    
201  static PixelColour  #define SPLITCOLOUR15(colour, rv) \
202  split_colour15(uint32 colour)  { \
203  {          rv.red = ((colour >> 7) & 0xf8) | ((colour >> 12) & 0x7); \
204          PixelColour rv;          rv.green = ((colour >> 2) & 0xf8) | ((colour >> 8) & 0x7); \
205          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;  
206  }  }
207    
208  static uint32  #define SPLITCOLOUR16(colour, rv) \
209  make_colour16(PixelColour pc)  { \
210  {          rv.red = ((colour >> 8) & 0xf8) | ((colour >> 13) & 0x7); \
211          pc.red = (pc.red * 0x1f) / 0xff;          rv.green = ((colour >> 3) & 0xfc) | ((colour >> 9) & 0x3); \
212          pc.green = (pc.green * 0x3f) / 0xff;          rv.blue = ((colour << 3) & 0xf8) | ((colour >> 2) & 0x7); \
213          pc.blue = (pc.blue * 0x1f) / 0xff;  } \
         return (pc.red << 11) | (pc.green << 5) | pc.blue;  
 }  
214    
215  static uint32  #define SPLITCOLOUR24(colour, rv) \
216  make_colour24(PixelColour pc)  { \
217  {          rv.blue = (colour & 0xff0000) >> 16; \
218          return (pc.red << 16) | (pc.green << 8) | pc.blue;          rv.green = (colour & 0x00ff00) >> 8; \
219            rv.red = (colour & 0x0000ff); \
220  }  }
221    
222  static uint32  #define MAKECOLOUR(pc) \
223  make_colour32(PixelColour pc)          ((pc.red >> g_red_shift_r) << g_red_shift_l) \
224  {                  | ((pc.green >> g_green_shift_r) << g_green_shift_l) \
225          return (pc.red << 16) | (pc.green << 8) | pc.blue;                  | ((pc.blue >> g_blue_shift_r) << g_blue_shift_l) \
 }  
226    
227  #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }  #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
228  #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }  #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | (x & 0xff00)); }
229  #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \  #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
230                          x = (x << 16) | (x >> 16); }                          x = (x << 16) | (x >> 16); }
231    
232    #define BOUT16(o, x) { *(o++) = x >> 8; *(o++) = x; }
233    #define BOUT24(o, x) { *(o++) = x >> 16; *(o++) = x >> 8; *(o++) = x; }
234    #define BOUT32(o, x) { *(o++) = x >> 24; *(o++) = x >> 16; *(o++) = x >> 8; *(o++) = x; }
235    #define LOUT16(o, x) { *(o++) = x; *(o++) = x >> 8; }
236    #define LOUT24(o, x) { *(o++) = x; *(o++) = x >> 8; *(o++) = x >> 16; }
237    #define LOUT32(o, x) { *(o++) = x; *(o++) = x >> 8; *(o++) = x >> 16; *(o++) = x >> 24; }
238    
239  static uint32  static uint32
240  translate_colour(uint32 colour)  translate_colour(uint32 colour)
241  {  {
242            PixelColour pc;
243          switch (g_server_bpp)          switch (g_server_bpp)
244          {          {
245                  case 15:                  case 15:
246                          switch (g_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;  
                         }  
247                          break;                          break;
248                  case 16:                  case 16:
249                          switch (g_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;  
                         }  
250                          break;                          break;
251                  case 24:                  case 24:
252                          switch (g_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;  
                         }  
253                          break;                          break;
254          }          }
255          switch (g_bpp)          return MAKECOLOUR(pc);
256          {  }
                 case 16:  
                         if (g_host_be != g_xserver_be)  
                                 BSWAP16(colour);  
                         break;  
257    
258                  case 24:  /* indent is confused by UNROLL8 */
259                          if (g_xserver_be)  /* *INDENT-OFF* */
                                 BSWAP24(colour);  
                         break;  
260    
261                  case 32:  /* repeat and unroll, similar to bitmap.c */
262                          if (g_host_be != g_xserver_be)  /* potentialy any of the following translate */
263                                  BSWAP32(colour);  /* functions can use repeat but just doing */
264                          break;  /* the most common ones */
         }  
265    
266          return colour;  #define UNROLL8(stm) { stm stm stm stm stm stm stm stm }
267    /* 2 byte output repeat */
268    #define REPEAT2(stm) \
269    { \
270            while (out <= end - 8 * 2) \
271                    UNROLL8(stm) \
272            while (out < end) \
273                    { stm } \
274  }  }
275    /* 3 byte output repeat */
276    #define REPEAT3(stm) \
277    { \
278            while (out <= end - 8 * 3) \
279                    UNROLL8(stm) \
280            while (out < end) \
281                    { stm } \
282    }
283    /* 4 byte output repeat */
284    #define REPEAT4(stm) \
285    { \
286            while (out <= end - 8 * 4) \
287                    UNROLL8(stm) \
288            while (out < end) \
289                    { stm } \
290    }
291    /* *INDENT-ON* */
292    
293  static void  static void
294  translate8to8(uint8 * data, uint8 * out, uint8 * end)  translate8to8(const uint8 * data, uint8 * out, uint8 * end)
295  {  {
296          while (out < end)          while (out < end)
297                  *(out++) = (uint8) g_colmap[*(data++)];                  *(out++) = (uint8) g_colmap[*(data++)];
298  }  }
299    
300  static void  static void
301  translate8to16(uint8 * data, uint16 * out, uint16 * end)  translate8to16(const uint8 * data, uint8 * out, uint8 * end)
302  {  {
303          while (out < end)          uint16 value;
304                  *(out++) = (uint16) g_colmap[*(data++)];  
305            if (g_arch_match)
306            {
307                    /* *INDENT-OFF* */
308                    REPEAT2
309                    (
310                            *((uint16 *) out) = g_colmap[*(data++)];
311                            out += 2;
312                    )
313                    /* *INDENT-ON* */
314            }
315            else if (g_xserver_be)
316            {
317                    while (out < end)
318                    {
319                            value = (uint16) g_colmap[*(data++)];
320                            BOUT16(out, value);
321                    }
322            }
323            else
324            {
325                    while (out < end)
326                    {
327                            value = (uint16) g_colmap[*(data++)];
328                            LOUT16(out, value);
329                    }
330            }
331  }  }
332    
333  /* little endian - conversion happens when colourmap is built */  /* little endian - conversion happens when colourmap is built */
334  static void  static void
335  translate8to24(uint8 * data, uint8 * out, uint8 * end)  translate8to24(const uint8 * data, uint8 * out, uint8 * end)
336  {  {
337          uint32 value;          uint32 value;
338    
339          while (out < end)          if (g_xserver_be)
340            {
341                    while (out < end)
342                    {
343                            value = g_colmap[*(data++)];
344                            BOUT24(out, value);
345                    }
346            }
347            else
348          {          {
349                  value = g_colmap[*(data++)];                  while (out < end)
350                  *(out++) = value;                  {
351                  *(out++) = value >> 8;                          value = g_colmap[*(data++)];
352                  *(out++) = value >> 16;                          LOUT24(out, value);
353                    }
354          }          }
355  }  }
356    
357  static void  static void
358  translate8to32(uint8 * data, uint32 * out, uint32 * end)  translate8to32(const uint8 * data, uint8 * out, uint8 * end)
359  {  {
360          while (out < end)          uint32 value;
                 *(out++) = g_colmap[*(data++)];  
 }  
361    
362  /* todo the remaining translate function might need some big endian check ?? */          if (g_arch_match)
363            {
364                    /* *INDENT-OFF* */
365                    REPEAT4
366                    (
367                            *((uint32 *) out) = g_colmap[*(data++)];
368                            out += 4;
369                    )
370                    /* *INDENT-ON* */
371            }
372            else if (g_xserver_be)
373            {
374                    while (out < end)
375                    {
376                            value = g_colmap[*(data++)];
377                            BOUT32(out, value);
378                    }
379            }
380            else
381            {
382                    while (out < end)
383                    {
384                            value = g_colmap[*(data++)];
385                            LOUT32(out, value);
386                    }
387            }
388    }
389    
390  static void  static void
391  translate15to16(uint16 * data, uint16 * out, uint16 * end)  translate15to16(const uint16 * data, uint8 * out, uint8 * end)
392  {  {
393          while (out < end)          uint16 pixel;
394                  *(out++) = (uint16) make_colour16(split_colour15(*(data++)));          uint16 value;
395            PixelColour pc;
396    
397            if (g_xserver_be)
398            {
399                    while (out < end)
400                    {
401                            pixel = *(data++);
402                            if (g_host_be)
403                            {
404                                    BSWAP16(pixel);
405                            }
406                            SPLITCOLOUR15(pixel, pc);
407                            value = MAKECOLOUR(pc);
408                            BOUT16(out, value);
409                    }
410            }
411            else
412            {
413                    while (out < end)
414                    {
415                            pixel = *(data++);
416                            if (g_host_be)
417                            {
418                                    BSWAP16(pixel);
419                            }
420                            SPLITCOLOUR15(pixel, pc);
421                            value = MAKECOLOUR(pc);
422                            LOUT16(out, value);
423                    }
424            }
425  }  }
426    
427  static void  static void
428  translate15to24(uint16 * data, uint8 * out, uint8 * end)  translate15to24(const uint16 * data, uint8 * out, uint8 * end)
429  {  {
430          uint32 value;          uint32 value;
431            uint16 pixel;
432            PixelColour pc;
433    
434          while (out < end)          if (g_arch_match)
435          {          {
436                  value = make_colour24(split_colour15(*(data++)));                  /* *INDENT-OFF* */
437                  *(out++) = value;                  REPEAT3
438                  *(out++) = value >> 8;                  (
439                  *(out++) = value >> 16;                          pixel = *(data++);
440                            SPLITCOLOUR15(pixel, pc);
441                            *(out++) = pc.blue;
442                            *(out++) = pc.green;
443                            *(out++) = pc.red;
444                    )
445                    /* *INDENT-ON* */
446            }
447            else if (g_xserver_be)
448            {
449                    while (out < end)
450                    {
451                            pixel = *(data++);
452                            if (g_host_be)
453                            {
454                                    BSWAP16(pixel);
455                            }
456                            SPLITCOLOUR15(pixel, pc);
457                            value = MAKECOLOUR(pc);
458                            BOUT24(out, value);
459                    }
460            }
461            else
462            {
463                    while (out < end)
464                    {
465                            pixel = *(data++);
466                            if (g_host_be)
467                            {
468                                    BSWAP16(pixel);
469                            }
470                            SPLITCOLOUR15(pixel, pc);
471                            value = MAKECOLOUR(pc);
472                            LOUT24(out, value);
473                    }
474          }          }
475  }  }
476    
477  static void  static void
478  translate15to32(uint16 * data, uint32 * out, uint32 * end)  translate15to32(const uint16 * data, uint8 * out, uint8 * end)
479  {  {
480          while (out < end)          uint16 pixel;
481                  *(out++) = make_colour32(split_colour15(*(data++)));          uint32 value;
482            PixelColour pc;
483    
484            if (g_arch_match)
485            {
486                    /* *INDENT-OFF* */
487                    REPEAT4
488                    (
489                            pixel = *(data++);
490                            SPLITCOLOUR15(pixel, pc);
491                            *(out++) = pc.blue;
492                            *(out++) = pc.green;
493                            *(out++) = pc.red;
494                            *(out++) = 0;
495                    )
496                    /* *INDENT-ON* */
497            }
498            else if (g_xserver_be)
499            {
500                    while (out < end)
501                    {
502                            pixel = *(data++);
503                            if (g_host_be)
504                            {
505                                    BSWAP16(pixel);
506                            }
507                            SPLITCOLOUR15(pixel, pc);
508                            value = MAKECOLOUR(pc);
509                            BOUT32(out, value);
510                    }
511            }
512            else
513            {
514                    while (out < end)
515                    {
516                            pixel = *(data++);
517                            if (g_host_be)
518                            {
519                                    BSWAP16(pixel);
520                            }
521                            SPLITCOLOUR15(pixel, pc);
522                            value = MAKECOLOUR(pc);
523                            LOUT32(out, value);
524                    }
525            }
526  }  }
527    
528  static void  static void
529  translate16to16(uint16 * data, uint16 * out, uint16 * end)  translate16to16(const uint16 * data, uint8 * out, uint8 * end)
530  {  {
531          while (out < end)          uint16 pixel;
532                  *(out++) = (uint16) (*(data++));          uint16 value;
533  }          PixelColour pc;
534    
535            if (g_xserver_be)
536            {
537                    if (g_host_be)
538                    {
539                            while (out < end)
540                            {
541                                    pixel = *(data++);
542                                    BSWAP16(pixel);
543                                    SPLITCOLOUR16(pixel, pc);
544                                    value = MAKECOLOUR(pc);
545                                    BOUT16(out, value);
546                            }
547                    }
548                    else
549                    {
550                            while (out < end)
551                            {
552                                    pixel = *(data++);
553                                    SPLITCOLOUR16(pixel, pc);
554                                    value = MAKECOLOUR(pc);
555                                    BOUT16(out, value);
556                            }
557                    }
558            }
559            else
560            {
561                    if (g_host_be)
562                    {
563                            while (out < end)
564                            {
565                                    pixel = *(data++);
566                                    BSWAP16(pixel);
567                                    SPLITCOLOUR16(pixel, pc);
568                                    value = MAKECOLOUR(pc);
569                                    LOUT16(out, value);
570                            }
571                    }
572                    else
573                    {
574                            while (out < end)
575                            {
576                                    pixel = *(data++);
577                                    SPLITCOLOUR16(pixel, pc);
578                                    value = MAKECOLOUR(pc);
579                                    LOUT16(out, value);
580                            }
581                    }
582            }
583    }
584    
585  static void  static void
586  translate16to24(uint16 * data, uint8 * out, uint8 * end)  translate16to24(const uint16 * data, uint8 * out, uint8 * end)
587  {  {
588          uint32 value;          uint32 value;
589            uint16 pixel;
590            PixelColour pc;
591    
592          while (out < end)          if (g_arch_match)
593          {          {
594                  value = make_colour24(split_colour16(*(data++)));                  /* *INDENT-OFF* */
595                  *(out++) = value;                  REPEAT3
596                  *(out++) = value >> 8;                  (
597                  *(out++) = value >> 16;                          pixel = *(data++);
598                            SPLITCOLOUR16(pixel, pc);
599                            *(out++) = pc.blue;
600                            *(out++) = pc.green;
601                            *(out++) = pc.red;
602                    )
603                    /* *INDENT-ON* */
604            }
605            else if (g_xserver_be)
606            {
607                    if (g_host_be)
608                    {
609                            while (out < end)
610                            {
611                                    pixel = *(data++);
612                                    BSWAP16(pixel);
613                                    SPLITCOLOUR16(pixel, pc);
614                                    value = MAKECOLOUR(pc);
615                                    BOUT24(out, value);
616                            }
617                    }
618                    else
619                    {
620                            while (out < end)
621                            {
622                                    pixel = *(data++);
623                                    SPLITCOLOUR16(pixel, pc);
624                                    value = MAKECOLOUR(pc);
625                                    BOUT24(out, value);
626                            }
627                    }
628            }
629            else
630            {
631                    if (g_host_be)
632                    {
633                            while (out < end)
634                            {
635                                    pixel = *(data++);
636                                    BSWAP16(pixel);
637                                    SPLITCOLOUR16(pixel, pc);
638                                    value = MAKECOLOUR(pc);
639                                    LOUT24(out, value);
640                            }
641                    }
642                    else
643                    {
644                            while (out < end)
645                            {
646                                    pixel = *(data++);
647                                    SPLITCOLOUR16(pixel, pc);
648                                    value = MAKECOLOUR(pc);
649                                    LOUT24(out, value);
650                            }
651                    }
652          }          }
653  }  }
654    
655  static void  static void
656  translate16to32(uint16 * data, uint32 * out, uint32 * end)  translate16to32(const uint16 * data, uint8 * out, uint8 * end)
657  {  {
658          while (out < end)          uint16 pixel;
659                  *(out++) = make_colour32(split_colour16(*(data++)));          uint32 value;
660            PixelColour pc;
661    
662            if (g_arch_match)
663            {
664                    /* *INDENT-OFF* */
665                    REPEAT4
666                    (
667                            pixel = *(data++);
668                            SPLITCOLOUR16(pixel, pc);
669                            *(out++) = pc.blue;
670                            *(out++) = pc.green;
671                            *(out++) = pc.red;
672                            *(out++) = 0;
673                    )
674                    /* *INDENT-ON* */
675            }
676            else if (g_xserver_be)
677            {
678                    if (g_host_be)
679                    {
680                            while (out < end)
681                            {
682                                    pixel = *(data++);
683                                    BSWAP16(pixel);
684                                    SPLITCOLOUR16(pixel, pc);
685                                    value = MAKECOLOUR(pc);
686                                    BOUT32(out, value);
687                            }
688                    }
689                    else
690                    {
691                            while (out < end)
692                            {
693                                    pixel = *(data++);
694                                    SPLITCOLOUR16(pixel, pc);
695                                    value = MAKECOLOUR(pc);
696                                    BOUT32(out, value);
697                            }
698                    }
699            }
700            else
701            {
702                    if (g_host_be)
703                    {
704                            while (out < end)
705                            {
706                                    pixel = *(data++);
707                                    BSWAP16(pixel);
708                                    SPLITCOLOUR16(pixel, pc);
709                                    value = MAKECOLOUR(pc);
710                                    LOUT32(out, value);
711                            }
712                    }
713                    else
714                    {
715                            while (out < end)
716                            {
717                                    pixel = *(data++);
718                                    SPLITCOLOUR16(pixel, pc);
719                                    value = MAKECOLOUR(pc);
720                                    LOUT32(out, value);
721                            }
722                    }
723            }
724  }  }
725    
726  static void  static void
727  translate24to16(uint8 * data, uint16 * out, uint16 * end)  translate24to16(const uint8 * data, uint8 * out, uint8 * end)
728  {  {
729          uint32 pixel = 0;          uint32 pixel = 0;
730            uint16 value;
731            PixelColour pc;
732    
733          while (out < end)          while (out < end)
734          {          {
735                  pixel = *(data++) << 16;                  pixel = *(data++) << 16;
736                  pixel |= *(data++) << 8;                  pixel |= *(data++) << 8;
737                  pixel |= *(data++);                  pixel |= *(data++);
738                  *(out++) = (uint16) make_colour16(split_colour24(pixel));                  SPLITCOLOUR24(pixel, pc);
739                    value = MAKECOLOUR(pc);
740                    if (g_xserver_be)
741                    {
742                            BOUT16(out, value);
743                    }
744                    else
745                    {
746                            LOUT16(out, value);
747                    }
748          }          }
749  }  }
750    
751  static void  static void
752  translate24to24(uint8 * data, uint8 * out, uint8 * end)  translate24to24(const uint8 * data, uint8 * out, uint8 * end)
753  {  {
754          while (out < end)          uint32 pixel;
755            uint32 value;
756            PixelColour pc;
757    
758            if (g_xserver_be)
759            {
760                    while (out < end)
761                    {
762                            pixel = *(data++) << 16;
763                            pixel |= *(data++) << 8;
764                            pixel |= *(data++);
765                            SPLITCOLOUR24(pixel, pc);
766                            value = MAKECOLOUR(pc);
767                            BOUT24(out, value);
768                    }
769            }
770            else
771          {          {
772                  *(out++) = (*(data++));                  while (out < end)
773                    {
774                            pixel = *(data++) << 16;
775                            pixel |= *(data++) << 8;
776                            pixel |= *(data++);
777                            SPLITCOLOUR24(pixel, pc);
778                            value = MAKECOLOUR(pc);
779                            LOUT24(out, value);
780                    }
781          }          }
782  }  }
783    
784  static void  static void
785  translate24to32(uint8 * data, uint32 * out, uint32 * end)  translate24to32(const uint8 * data, uint8 * out, uint8 * end)
786  {  {
787          uint32 pixel = 0;          uint32 pixel;
788          while (out < end)          uint32 value;
789            PixelColour pc;
790    
791            if (g_arch_match)
792          {          {
793                  pixel = *(data++);                  /* *INDENT-OFF* */
794                  pixel |= *(data++) << 8;  #ifdef NEED_ALIGN
795                  pixel |= *(data++) << 16;                  REPEAT4
796                  *(out++) = pixel;                  (
797                            *(out++) = *(data++);
798                            *(out++) = *(data++);
799                            *(out++) = *(data++);
800                            *(out++) = 0;
801                    )
802    #else
803                    REPEAT4
804                    (
805                            *((uint32 *) out) = *((uint32 *) data);
806                            out += 4;
807                            data += 3;
808                    )
809    #endif
810                    /* *INDENT-ON* */
811            }
812            else if (g_xserver_be)
813            {
814                    while (out < end)
815                    {
816                            pixel = *(data++) << 16;
817                            pixel |= *(data++) << 8;
818                            pixel |= *(data++);
819                            SPLITCOLOUR24(pixel, pc);
820                            value = MAKECOLOUR(pc);
821                            BOUT32(out, value);
822                    }
823            }
824            else
825            {
826                    while (out < end)
827                    {
828                            pixel = *(data++) << 16;
829                            pixel |= *(data++) << 8;
830                            pixel |= *(data++);
831                            SPLITCOLOUR24(pixel, pc);
832                            value = MAKECOLOUR(pc);
833                            LOUT32(out, value);
834                    }
835          }          }
836  }  }
837    
838  static uint8 *  static uint8 *
839  translate_image(int width, int height, uint8 * data)  translate_image(int width, int height, uint8 * data)
840  {  {
841          int size = width * height * g_bpp / 8;          int size;
842          uint8 *out = (uint8 *) xmalloc(size);          uint8 *out;
843          uint8 *end = out + size;          uint8 *end;
844    
845            /* if server and xserver bpp match, */
846            /* and arch(endian) matches, no need to translate */
847            /* just return data */
848            if (g_arch_match)
849            {
850                    if (g_depth == 15 && g_server_bpp == 15)
851                            return data;
852                    if (g_depth == 16 && g_server_bpp == 16)
853                            return data;
854                    if (g_depth == 24 && g_bpp == 24 && g_server_bpp == 24)
855                            return data;
856            }
857    
858            size = width * height * (g_bpp / 8);
859            out = (uint8 *) xmalloc(size);
860            end = out + size;
861    
862          switch (g_server_bpp)          switch (g_server_bpp)
863          {          {
# Line 425  translate_image(int width, int height, u Line 865  translate_image(int width, int height, u
865                          switch (g_bpp)                          switch (g_bpp)
866                          {                          {
867                                  case 32:                                  case 32:
868                                          translate24to32(data, (uint32 *) out, (uint32 *) end);                                          translate24to32(data, out, end);
869                                          break;                                          break;
870                                  case 24:                                  case 24:
871                                          translate24to24(data, out, end);                                          translate24to24(data, out, end);
872                                          break;                                          break;
873                                  case 16:                                  case 16:
874                                          translate24to16(data, (uint16 *) out, (uint16 *) end);                                          translate24to16(data, out, end);
875                                          break;                                          break;
876                          }                          }
877                          break;                          break;
# Line 439  translate_image(int width, int height, u Line 879  translate_image(int width, int height, u
879                          switch (g_bpp)                          switch (g_bpp)
880                          {                          {
881                                  case 32:                                  case 32:
882                                          translate16to32((uint16 *) data, (uint32 *) out,                                          translate16to32((uint16 *) data, out, end);
                                                         (uint32 *) end);  
883                                          break;                                          break;
884                                  case 24:                                  case 24:
885                                          translate16to24((uint16 *) data, out, end);                                          translate16to24((uint16 *) data, out, end);
886                                          break;                                          break;
887                                  case 16:                                  case 16:
888                                          translate16to16((uint16 *) data, (uint16 *) out,                                          translate16to16((uint16 *) data, out, end);
                                                         (uint16 *) end);  
889                                          break;                                          break;
890                          }                          }
891                          break;                          break;
# Line 455  translate_image(int width, int height, u Line 893  translate_image(int width, int height, u
893                          switch (g_bpp)                          switch (g_bpp)
894                          {                          {
895                                  case 32:                                  case 32:
896                                          translate15to32((uint16 *) data, (uint32 *) out,                                          translate15to32((uint16 *) data, out, end);
                                                         (uint32 *) end);  
897                                          break;                                          break;
898                                  case 24:                                  case 24:
899                                          translate15to24((uint16 *) data, out, end);                                          translate15to24((uint16 *) data, out, end);
900                                          break;                                          break;
901                                  case 16:                                  case 16:
902                                          translate15to16((uint16 *) data, (uint16 *) out,                                          translate15to16((uint16 *) data, out, end);
                                                         (uint16 *) end);  
903                                          break;                                          break;
904                          }                          }
905                          break;                          break;
# Line 474  translate_image(int width, int height, u Line 910  translate_image(int width, int height, u
910                                          translate8to8(data, out, end);                                          translate8to8(data, out, end);
911                                          break;                                          break;
912                                  case 16:                                  case 16:
913                                          translate8to16(data, (uint16 *) out, (uint16 *) end);                                          translate8to16(data, out, end);
914                                          break;                                          break;
915                                  case 24:                                  case 24:
916                                          translate8to24(data, out, end);                                          translate8to24(data, out, end);
917                                          break;                                          break;
918                                  case 32:                                  case 32:
919                                          translate8to32(data, (uint32 *) out, (uint32 *) end);                                          translate8to32(data, out, end);
920                                          break;                                          break;
921                          }                          }
922                          break;                          break;
# Line 513  get_key_state(unsigned int state, uint32 Line 949  get_key_state(unsigned int state, uint32
949          return (state & keysymMask) ? True : False;          return (state & keysymMask) ? True : False;
950  }  }
951    
952    static void
953    calculate_shifts(uint32 mask, int *shift_r, int *shift_l)
954    {
955            *shift_l = ffs(mask) - 1;
956            mask >>= *shift_l;
957            *shift_r = 8 - ffs(mask & ~(mask >> 1));
958    }
959    
960  BOOL  BOOL
961  ui_init(void)  ui_init(void)
962  {  {
963            XVisualInfo vi;
964          XPixmapFormatValues *pfm;          XPixmapFormatValues *pfm;
965          uint16 test;          uint16 test;
966          int i;          int i, screen_num, nvisuals;
967            XVisualInfo *vmatches = NULL;
968            XVisualInfo template;
969            Bool TrueColorVisual = False;
970    
971          g_display = XOpenDisplay(NULL);          g_display = XOpenDisplay(NULL);
972          if (g_display == NULL)          if (g_display == NULL)
# Line 527  ui_init(void) Line 975  ui_init(void)
975                  return False;                  return False;
976          }          }
977    
978            screen_num = DefaultScreen(g_display);
979          g_x_socket = ConnectionNumber(g_display);          g_x_socket = ConnectionNumber(g_display);
980          g_screen = DefaultScreenOfDisplay(g_display);          g_screen = ScreenOfDisplay(g_display, screen_num);
         g_visual = DefaultVisualOfScreen(g_screen);  
981          g_depth = DefaultDepthOfScreen(g_screen);          g_depth = DefaultDepthOfScreen(g_screen);
982    
983            /* Search for best TrueColor depth */
984            template.class = TrueColor;
985            vmatches = XGetVisualInfo(g_display, VisualClassMask, &template, &nvisuals);
986    
987            nvisuals--;
988            while (nvisuals >= 0)
989            {
990                    if ((vmatches + nvisuals)->depth > g_depth)
991                    {
992                            g_depth = (vmatches + nvisuals)->depth;
993                    }
994                    nvisuals--;
995                    TrueColorVisual = True;
996            }
997    
998            test = 1;
999            g_host_be = !(BOOL) (*(uint8 *) (&test));
1000            g_xserver_be = (ImageByteOrder(g_display) == MSBFirst);
1001    
1002            if ((g_server_bpp == 8) && ((!TrueColorVisual) || (g_depth <= 8)))
1003            {
1004                    /* we use a colourmap, so the default visual should do */
1005                    g_visual = DefaultVisualOfScreen(g_screen);
1006                    g_depth = DefaultDepthOfScreen(g_screen);
1007    
1008                    /* Do not allocate colours on a TrueColor visual */
1009                    if (g_visual->class == TrueColor)
1010                    {
1011                            g_owncolmap = False;
1012                    }
1013            }
1014            else
1015            {
1016                    /* need a truecolour visual */
1017                    if (!XMatchVisualInfo(g_display, screen_num, g_depth, TrueColor, &vi))
1018                    {
1019                            error("The display does not support true colour - high colour support unavailable.\n");
1020                            return False;
1021                    }
1022    
1023                    g_visual = vi.visual;
1024                    g_owncolmap = False;
1025                    calculate_shifts(vi.red_mask, &g_red_shift_r, &g_red_shift_l);
1026                    calculate_shifts(vi.blue_mask, &g_blue_shift_r, &g_blue_shift_l);
1027                    calculate_shifts(vi.green_mask, &g_green_shift_r, &g_green_shift_l);
1028    
1029                    /* if RGB video and everything is little endian */
1030                    if ((vi.red_mask > vi.green_mask && vi.green_mask > vi.blue_mask) &&
1031                        !g_xserver_be && !g_host_be)
1032                    {
1033                            if (g_depth <= 16 || (g_red_shift_l == 16 && g_green_shift_l == 8 &&
1034                                                  g_blue_shift_l == 0))
1035                            {
1036                                    g_arch_match = True;
1037                            }
1038                    }
1039    
1040                    if (g_arch_match)
1041                    {
1042                            DEBUG(("Architectures match, enabling little endian optimisations.\n"));
1043                    }
1044            }
1045    
1046          pfm = XListPixmapFormats(g_display, &i);          pfm = XListPixmapFormats(g_display, &i);
1047          if (pfm != NULL)          if (pfm != NULL)
1048          {          {
# Line 554  ui_init(void) Line 1065  ui_init(void)
1065                  return False;                  return False;
1066          }          }
1067    
1068          if (g_owncolmap != True)          if (!g_owncolmap)
1069          {          {
1070                  g_xcolmap = DefaultColormapOfScreen(g_screen);                  g_xcolmap =
1071                            XCreateColormap(g_display, RootWindowOfScreen(g_screen), g_visual,
1072                                            AllocNone);
1073                  if (g_depth <= 8)                  if (g_depth <= 8)
1074                          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");
1075          }          }
1076    
1077          g_gc = XCreateGC(g_display, RootWindowOfScreen(g_screen), 0, NULL);          if ((!g_ownbackstore) && (DoesBackingStore(g_screen) != Always))
1078            {
1079          if (DoesBackingStore(g_screen) != Always)                  warning("External BackingStore not available, using internal\n");
1080                  g_ownbackstore = True;                  g_ownbackstore = True;
1081            }
1082    
1083          test = 1;          /*
1084          g_host_be = !(BOOL) (*(uint8 *) (&test));           * Determine desktop size
1085          g_xserver_be = (ImageByteOrder(g_display) == MSBFirst);           */
1086            if (g_fullscreen)
1087          if ((g_width == 0) || (g_height == 0))          {
1088                    g_width = WidthOfScreen(g_screen);
1089                    g_height = HeightOfScreen(g_screen);
1090            }
1091            else if (g_width < 0)
1092            {
1093                    /* Percent of screen */
1094                    g_height = HeightOfScreen(g_screen) * (-g_width) / 100;
1095                    g_width = WidthOfScreen(g_screen) * (-g_width) / 100;
1096            }
1097            else if (g_width == 0)
1098          {          {
1099                  /* Fetch geometry from _NET_WORKAREA */                  /* Fetch geometry from _NET_WORKAREA */
1100                  uint32 x, y, cx, cy;                  uint32 x, y, cx, cy;
# Line 588  ui_init(void) Line 1112  ui_init(void)
1112                  }                  }
1113          }          }
1114    
         if (g_fullscreen)  
         {  
                 g_width = WidthOfScreen(g_screen);  
                 g_height = HeightOfScreen(g_screen);  
         }  
   
1115          /* make sure width is a multiple of 4 */          /* make sure width is a multiple of 4 */
1116          g_width = (g_width + 3) & ~3;          g_width = (g_width + 3) & ~3;
1117    
         if (g_ownbackstore)  
         {  
                 g_backstore =  
                         XCreatePixmap(g_display, RootWindowOfScreen(g_screen), g_width, g_height,  
                                       g_depth);  
   
                 /* clear to prevent rubbish being exposed at startup */  
                 XSetForeground(g_display, g_gc, BlackPixelOfScreen(g_screen));  
                 XFillRectangle(g_display, g_backstore, g_gc, 0, 0, g_width, g_height);  
         }  
   
1118          g_mod_map = XGetModifierMapping(g_display);          g_mod_map = XGetModifierMapping(g_display);
1119    
1120            xkeymap_init();
1121    
1122          if (g_enable_compose)          if (g_enable_compose)
1123                  g_IM = XOpenIM(g_display, NULL, NULL, NULL);                  g_IM = XOpenIM(g_display, NULL, NULL, NULL);
1124    
         xkeymap_init();  
1125          xclip_init();          xclip_init();
1126    
1127          /* 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", g_server_bpp, g_bpp, g_depth);  
1128    
1129          return True;          return True;
1130  }  }
# Line 628  ui_deinit(void) Line 1135  ui_deinit(void)
1135          if (g_IM != NULL)          if (g_IM != NULL)
1136                  XCloseIM(g_IM);                  XCloseIM(g_IM);
1137    
1138            if (g_null_cursor != NULL)
1139                    ui_destroy_cursor(g_null_cursor);
1140    
1141          XFreeModifiermap(g_mod_map);          XFreeModifiermap(g_mod_map);
1142    
1143          if (g_ownbackstore)          if (g_ownbackstore)
# Line 641  ui_deinit(void) Line 1151  ui_deinit(void)
1151  BOOL  BOOL
1152  ui_create_window(void)  ui_create_window(void)
1153  {  {
1154            uint8 null_pointer_mask[1] = { 0x80 };
1155            uint8 null_pointer_data[24] = { 0x00 };
1156    
1157          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
1158          XClassHint *classhints;          XClassHint *classhints;
1159          XSizeHints *sizehints;          XSizeHints *sizehints;
# Line 651  ui_create_window(void) Line 1164  ui_create_window(void)
1164          wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;          wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;
1165          wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;          wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;
1166    
1167            /* Handle -x-y portion of geometry string */
1168            if (g_xpos < 0 || (g_xpos == 0 && (g_pos & 2)))
1169                    g_xpos = WidthOfScreen(g_screen) + g_xpos - g_width;
1170            if (g_ypos < 0 || (g_ypos == 0 && (g_pos & 4)))
1171                    g_ypos = HeightOfScreen(g_screen) + g_ypos - g_height;
1172    
1173          attribs.background_pixel = BlackPixelOfScreen(g_screen);          attribs.background_pixel = BlackPixelOfScreen(g_screen);
1174            attribs.border_pixel = WhitePixelOfScreen(g_screen);
1175          attribs.backing_store = g_ownbackstore ? NotUseful : Always;          attribs.backing_store = g_ownbackstore ? NotUseful : Always;
1176          attribs.override_redirect = g_fullscreen;          attribs.override_redirect = g_fullscreen;
1177            attribs.colormap = g_xcolmap;
1178    
1179            g_wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), g_xpos, g_ypos, wndwidth,
1180                                  wndheight, 0, g_depth, InputOutput, g_visual,
1181                                  CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
1182                                  CWBorderPixel, &attribs);
1183    
1184            if (g_gc == NULL)
1185                    g_gc = XCreateGC(g_display, g_wnd, 0, NULL);
1186    
1187            if (g_create_bitmap_gc == NULL)
1188                    g_create_bitmap_gc = XCreateGC(g_display, g_wnd, 0, NULL);
1189    
1190            if ((g_ownbackstore) && (g_backstore == 0))
1191            {
1192                    g_backstore = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
1193    
1194          g_wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), 0, 0, wndwidth, wndheight,                  /* clear to prevent rubbish being exposed at startup */
1195                                0, CopyFromParent, InputOutput, CopyFromParent,                  XSetForeground(g_display, g_gc, BlackPixelOfScreen(g_screen));
1196                                CWBackPixel | CWBackingStore | CWOverrideRedirect, &attribs);                  XFillRectangle(g_display, g_backstore, g_gc, 0, 0, g_width, g_height);
1197            }
1198    
1199          XStoreName(g_display, g_wnd, g_title);          XStoreName(g_display, g_wnd, g_title);
1200    
# Line 676  ui_create_window(void) Line 1213  ui_create_window(void)
1213          if (sizehints)          if (sizehints)
1214          {          {
1215                  sizehints->flags = PMinSize | PMaxSize;                  sizehints->flags = PMinSize | PMaxSize;
1216                    if (g_pos)
1217                            sizehints->flags |= PPosition;
1218                  sizehints->min_width = sizehints->max_width = g_width;                  sizehints->min_width = sizehints->max_width = g_width;
1219                  sizehints->min_height = sizehints->max_height = g_height;                  sizehints->min_height = sizehints->max_height = g_height;
1220                  XSetWMNormalHints(g_display, g_wnd, sizehints);                  XSetWMNormalHints(g_display, g_wnd, sizehints);
1221                  XFree(sizehints);                  XFree(sizehints);
1222          }          }
1223    
1224            if (g_embed_wnd)
1225            {
1226                    XReparentWindow(g_display, g_wnd, (Window) g_embed_wnd, 0, 0);
1227            }
1228    
1229          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
1230                  VisibilityChangeMask | FocusChangeMask;                  VisibilityChangeMask | FocusChangeMask;
1231    
# Line 713  ui_create_window(void) Line 1257  ui_create_window(void)
1257                  XMaskEvent(g_display, VisibilityChangeMask, &xevent);                  XMaskEvent(g_display, VisibilityChangeMask, &xevent);
1258          }          }
1259          while (xevent.type != VisibilityNotify);          while (xevent.type != VisibilityNotify);
1260            g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;
1261    
1262          g_focused = False;          g_focused = False;
1263          g_mouse_in_wnd = False;          g_mouse_in_wnd = False;
# Line 722  ui_create_window(void) Line 1267  ui_create_window(void)
1267          g_kill_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", True);          g_kill_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", True);
1268          XSetWMProtocols(g_display, g_wnd, &g_kill_atom, 1);          XSetWMProtocols(g_display, g_wnd, &g_kill_atom, 1);
1269    
1270            /* create invisible 1x1 cursor to be used as null cursor */
1271            if (g_null_cursor == NULL)
1272                    g_null_cursor = ui_create_cursor(0, 0, 1, 1, null_pointer_mask, null_pointer_data);
1273    
1274          return True;          return True;
1275  }  }
1276    
1277  void  void
1278    ui_resize_window()
1279    {
1280            XSizeHints *sizehints;
1281            Pixmap bs;
1282    
1283            sizehints = XAllocSizeHints();
1284            if (sizehints)
1285            {
1286                    sizehints->flags = PMinSize | PMaxSize;
1287                    sizehints->min_width = sizehints->max_width = g_width;
1288                    sizehints->min_height = sizehints->max_height = g_height;
1289                    XSetWMNormalHints(g_display, g_wnd, sizehints);
1290                    XFree(sizehints);
1291            }
1292    
1293            if (!(g_fullscreen || g_embed_wnd))
1294            {
1295                    XResizeWindow(g_display, g_wnd, g_width, g_height);
1296            }
1297    
1298            /* create new backstore pixmap */
1299            if (g_backstore != 0)
1300            {
1301                    bs = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
1302                    XSetForeground(g_display, g_gc, BlackPixelOfScreen(g_screen));
1303                    XFillRectangle(g_display, bs, g_gc, 0, 0, g_width, g_height);
1304                    XCopyArea(g_display, g_backstore, bs, g_gc, 0, 0, g_width, g_height, 0, 0);
1305                    XFreePixmap(g_display, g_backstore);
1306                    g_backstore = bs;
1307            }
1308    }
1309    
1310    void
1311  ui_destroy_window(void)  ui_destroy_window(void)
1312  {  {
1313          if (g_IC != NULL)          if (g_IC != NULL)
# Line 771  xwin_process_events(void) Line 1353  xwin_process_events(void)
1353          key_translation tr;          key_translation tr;
1354          char str[256];          char str[256];
1355          Status status;          Status status;
         unsigned int state;  
         Window wdummy;  
         int dummy;  
1356    
1357          while (XPending(g_display) > 0)          while (XPending(g_display) > 0)
1358          {          {
# Line 789  xwin_process_events(void) Line 1368  xwin_process_events(void)
1368    
1369                  switch (xevent.type)                  switch (xevent.type)
1370                  {                  {
1371                            case VisibilityNotify:
1372                                    g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;
1373                                    break;
1374                          case ClientMessage:                          case ClientMessage:
1375                                  /* the window manager told us to quit */                                  /* the window manager told us to quit */
1376                                  if ((xevent.xclient.message_type == g_protocol_atom)                                  if ((xevent.xclient.message_type == g_protocol_atom)
# Line 833  xwin_process_events(void) Line 1415  xwin_process_events(void)
1415                                  if (tr.scancode == 0)                                  if (tr.scancode == 0)
1416                                          break;                                          break;
1417    
1418                                  save_remote_modifiers();                                  save_remote_modifiers(tr.scancode);
1419                                  ensure_remote_modifiers(ev_time, tr);                                  ensure_remote_modifiers(ev_time, tr);
1420                                  rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);                                  rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
1421                                  restore_remote_modifiers();                                  restore_remote_modifiers(ev_time, tr.scancode);
1422    
1423                                  break;                                  break;
1424    
# Line 946  xwin_process_events(void) Line 1528  xwin_process_events(void)
1528                                  if (xevent.xfocus.mode == NotifyGrab)                                  if (xevent.xfocus.mode == NotifyGrab)
1529                                          break;                                          break;
1530                                  g_focused = True;                                  g_focused = True;
1531                                  XQueryPointer(g_display, g_wnd, &wdummy, &wdummy, &dummy, &dummy,                                  reset_modifier_keys();
                                               &dummy, &dummy, &state);  
                                 reset_modifier_keys(state);  
1532                                  if (g_grab_keyboard && g_mouse_in_wnd)                                  if (g_grab_keyboard && g_mouse_in_wnd)
1533                                          XGrabKeyboard(g_display, g_wnd, True,                                          XGrabKeyboard(g_display, g_wnd, True,
1534                                                        GrabModeAsync, GrabModeAsync, CurrentTime);                                                        GrabModeAsync, GrabModeAsync, CurrentTime);
# Line 1028  xwin_process_events(void) Line 1608  xwin_process_events(void)
1608  int  int
1609  ui_select(int rdp_socket)  ui_select(int rdp_socket)
1610  {  {
1611          int n = (rdp_socket > g_x_socket) ? rdp_socket + 1 : g_x_socket + 1;          int n;
1612          fd_set rfds;          fd_set rfds, wfds;
1613            struct timeval tv;
1614          FD_ZERO(&rfds);          BOOL s_timeout = False;
1615    
1616          while (True)          while (True)
1617          {          {
1618                    n = (rdp_socket > g_x_socket) ? rdp_socket : g_x_socket;
1619                  /* Process any events already waiting */                  /* Process any events already waiting */
1620                  if (!xwin_process_events())                  if (!xwin_process_events())
1621                          /* User quit */                          /* User quit */
1622                          return 0;                          return 0;
1623    
1624                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
1625                    FD_ZERO(&wfds);
1626                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
1627                  FD_SET(g_x_socket, &rfds);                  FD_SET(g_x_socket, &rfds);
1628    
1629                  switch (select(n, &rfds, NULL, NULL, NULL))  #ifdef WITH_RDPSND
1630                    /* FIXME: there should be an API for registering fds */
1631                    if (g_dsp_busy)
1632                    {
1633                            FD_SET(g_dsp_fd, &wfds);
1634                            n = (g_dsp_fd > n) ? g_dsp_fd : n;
1635                    }
1636    #endif
1637                    /* default timeout */
1638                    tv.tv_sec = 60;
1639                    tv.tv_usec = 0;
1640    
1641                    /* add redirection handles */
1642                    rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
1643    
1644                    n++;
1645    
1646                    switch (select(n, &rfds, &wfds, NULL, &tv))
1647                  {                  {
1648                          case -1:                          case -1:
1649                                  error("select: %s\n", strerror(errno));                                  error("select: %s\n", strerror(errno));
1650    
1651                          case 0:                          case 0:
1652                                    /* Abort serial read calls */
1653                                    if (s_timeout)
1654                                            rdpdr_check_fds(&rfds, &wfds, (BOOL) True);
1655                                  continue;                                  continue;
1656                  }                  }
1657    
1658                    rdpdr_check_fds(&rfds, &wfds, (BOOL) False);
1659    
1660                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
1661                          return 1;                          return 1;
1662    
1663    #ifdef WITH_RDPSND
1664                    if (g_dsp_busy && FD_ISSET(g_dsp_fd, &wfds))
1665                            wave_out_play();
1666    #endif
1667          }          }
1668  }  }
1669    
# Line 1070  ui_create_bitmap(int width, int height, Line 1679  ui_create_bitmap(int width, int height,
1679          XImage *image;          XImage *image;
1680          Pixmap bitmap;          Pixmap bitmap;
1681          uint8 *tdata;          uint8 *tdata;
1682            int bitmap_pad;
1683    
1684            if (g_server_bpp == 8)
1685            {
1686                    bitmap_pad = 8;
1687            }
1688            else
1689            {
1690                    bitmap_pad = g_bpp;
1691    
1692                    if (g_bpp == 24)
1693                            bitmap_pad = 32;
1694            }
1695    
1696          tdata = (g_owncolmap ? data : translate_image(width, height, data));          tdata = (g_owncolmap ? data : translate_image(width, height, data));
1697          bitmap = XCreatePixmap(g_display, g_wnd, width, height, g_depth);          bitmap = XCreatePixmap(g_display, g_wnd, width, height, g_depth);
1698          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1699                               (char *) tdata, width, height, g_server_bpp == 8 ? 8 : g_bpp, 0);                               (char *) tdata, width, height, bitmap_pad, 0);
1700    
1701          XPutImage(g_display, bitmap, g_gc, image, 0, 0, 0, 0, width, height);          XPutImage(g_display, bitmap, g_create_bitmap_gc, image, 0, 0, 0, 0, width, height);
1702    
1703          XFree(image);          XFree(image);
1704          if (!g_owncolmap)          if (tdata != data)
1705                  xfree(tdata);                  xfree(tdata);
1706          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
1707  }  }
# Line 1089  ui_paint_bitmap(int x, int y, int cx, in Line 1711  ui_paint_bitmap(int x, int y, int cx, in
1711  {  {
1712          XImage *image;          XImage *image;
1713          uint8 *tdata;          uint8 *tdata;
1714            int bitmap_pad;
1715    
1716            if (g_server_bpp == 8)
1717            {
1718                    bitmap_pad = 8;
1719            }
1720            else
1721            {
1722                    bitmap_pad = g_bpp;
1723    
1724                    if (g_bpp == 24)
1725                            bitmap_pad = 32;
1726            }
1727    
1728          tdata = (g_owncolmap ? data : translate_image(width, height, data));          tdata = (g_owncolmap ? data : translate_image(width, height, data));
1729          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1730                               (char *) tdata, width, height, g_server_bpp == 8 ? 8 : g_bpp, 0);                               (char *) tdata, width, height, bitmap_pad, 0);
1731    
1732          if (g_ownbackstore)          if (g_ownbackstore)
1733          {          {
# Line 1104  ui_paint_bitmap(int x, int y, int cx, in Line 1740  ui_paint_bitmap(int x, int y, int cx, in
1740          }          }
1741    
1742          XFree(image);          XFree(image);
1743          if (!g_owncolmap)          if (tdata != data)
1744                  xfree(tdata);                  xfree(tdata);
1745  }  }
1746    
# Line 1120  ui_create_glyph(int width, int height, u Line 1756  ui_create_glyph(int width, int height, u
1756          XImage *image;          XImage *image;
1757          Pixmap bitmap;          Pixmap bitmap;
1758          int scanline;          int scanline;
         GC gc;  
1759    
1760          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1761    
1762          bitmap = XCreatePixmap(g_display, g_wnd, width, height, 1);          bitmap = XCreatePixmap(g_display, g_wnd, width, height, 1);
1763          gc = XCreateGC(g_display, bitmap, 0, NULL);          if (g_create_glyph_gc == 0)
1764                    g_create_glyph_gc = XCreateGC(g_display, bitmap, 0, NULL);
1765    
1766          image = XCreateImage(g_display, g_visual, 1, ZPixmap, 0, (char *) data,          image = XCreateImage(g_display, g_visual, 1, ZPixmap, 0, (char *) data,
1767                               width, height, 8, scanline);                               width, height, 8, scanline);
# Line 1133  ui_create_glyph(int width, int height, u Line 1769  ui_create_glyph(int width, int height, u
1769          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
1770          XInitImage(image);          XInitImage(image);
1771    
1772          XPutImage(g_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);
1773    
1774          XFree(image);          XFree(image);
         XFreeGC(g_display, gc);  
1775          return (HGLYPH) bitmap;          return (HGLYPH) bitmap;
1776  }  }
1777    
# Line 1230  ui_destroy_cursor(HCURSOR cursor) Line 1865  ui_destroy_cursor(HCURSOR cursor)
1865          XFreeCursor(g_display, (Cursor) cursor);          XFreeCursor(g_display, (Cursor) cursor);
1866  }  }
1867    
1868    void
1869    ui_set_null_cursor(void)
1870    {
1871            ui_set_cursor(g_null_cursor);
1872    }
1873    
1874  #define MAKE_XCOLOR(xc,c) \  #define MAKE_XCOLOR(xc,c) \
1875                  (xc)->red   = ((c)->red   << 8) | (c)->red; \                  (xc)->red   = ((c)->red   << 8) | (c)->red; \
1876                  (xc)->green = ((c)->green << 8) | (c)->green; \                  (xc)->green = ((c)->green << 8) | (c)->green; \
# Line 1311  ui_create_colourmap(COLOURMAP * colours) Line 1952  ui_create_colourmap(COLOURMAP * colours)
1952    
1953                          }                          }
1954    
1955                            map[i] = colour;
                         /* byte swap here to make translate_image faster */  
                         map[i] = translate_colour(colour);  
1956                  }                  }
1957                  return map;                  return map;
1958          }          }
# Line 1424  ui_patblt(uint8 opcode, Line 2063  ui_patblt(uint8 opcode,
2063          {          {
2064                  case 0: /* Solid */                  case 0: /* Solid */
2065                          SET_FOREGROUND(fgcolour);                          SET_FOREGROUND(fgcolour);
2066                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
2067                          break;                          break;
2068    
2069                  case 2: /* Hatch */                  case 2: /* Hatch */
2070                          fill = (Pixmap) ui_create_glyph(8, 8,                          fill = (Pixmap) ui_create_glyph(8, 8,
2071                                                          hatch_patterns + brush->pattern[0] * 8);                                                          hatch_patterns + brush->pattern[0] * 8);
2072                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(fgcolour);
2073                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(bgcolour);
2074                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2075                          XSetStipple(g_display, g_gc, fill);                          XSetStipple(g_display, g_gc, fill);
2076                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2077                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
2078                          XSetFillStyle(g_display, g_gc, FillSolid);                          XSetFillStyle(g_display, g_gc, FillSolid);
2079                          XSetTSOrigin(g_display, g_gc, 0, 0);                          XSetTSOrigin(g_display, g_gc, 0, 0);
2080                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH) fill);
# Line 1445  ui_patblt(uint8 opcode, Line 2084  ui_patblt(uint8 opcode,
2084                          for (i = 0; i != 8; i++)                          for (i = 0; i != 8; i++)
2085                                  ipattern[7 - i] = brush->pattern[i];                                  ipattern[7 - i] = brush->pattern[i];
2086                          fill = (Pixmap) ui_create_glyph(8, 8, ipattern);                          fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
   
2087                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(bgcolour);
2088                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
2089                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2090                          XSetStipple(g_display, g_gc, fill);                          XSetStipple(g_display, g_gc, fill);
2091                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2092                            FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
                         FILL_RECTANGLE(x, y, cx, cy);  
   
2093                          XSetFillStyle(g_display, g_gc, FillSolid);                          XSetFillStyle(g_display, g_gc, FillSolid);
2094                          XSetTSOrigin(g_display, g_gc, 0, 0);                          XSetTSOrigin(g_display, g_gc, 0, 0);
2095                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH) fill);
# Line 1464  ui_patblt(uint8 opcode, Line 2100  ui_patblt(uint8 opcode,
2100          }          }
2101    
2102          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
2103    
2104            if (g_ownbackstore)
2105                    XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
2106  }  }
2107    
2108  void  void
# Line 1472  ui_screenblt(uint8 opcode, Line 2111  ui_screenblt(uint8 opcode,
2111               /* src */ int srcx, int srcy)               /* src */ int srcx, int srcy)
2112  {  {
2113          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
         XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);  
2114          if (g_ownbackstore)          if (g_ownbackstore)
2115                  XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x, y);          {
2116                    if (g_Unobscured)
2117                    {
2118                            XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
2119                            XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x,
2120                                      y);
2121                    }
2122                    else
2123                    {
2124                            XCopyArea(g_display, g_backstore, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
2125                            XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x,
2126                                      y);
2127                    }
2128            }
2129            else
2130            {
2131                    XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
2132            }
2133          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
2134  }  }
2135    
# Line 1545  ui_rect( Line 2200  ui_rect(
2200          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
2201  }  }
2202    
2203    void
2204    ui_polygon(uint8 opcode,
2205               /* mode */ uint8 fillmode,
2206               /* dest */ POINT * point, int npoints,
2207               /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2208    {
2209            uint8 style, i, ipattern[8];
2210            Pixmap fill;
2211    
2212            SET_FUNCTION(opcode);
2213    
2214            switch (fillmode)
2215            {
2216                    case ALTERNATE:
2217                            XSetFillRule(g_display, g_gc, EvenOddRule);
2218                            break;
2219                    case WINDING:
2220                            XSetFillRule(g_display, g_gc, WindingRule);
2221                            break;
2222                    default:
2223                            unimpl("fill mode %d\n", fillmode);
2224            }
2225    
2226            if (brush)
2227                    style = brush->style;
2228            else
2229                    style = 0;
2230    
2231            switch (style)
2232            {
2233                    case 0: /* Solid */
2234                            SET_FOREGROUND(fgcolour);
2235                            FILL_POLYGON((XPoint *) point, npoints);
2236                            break;
2237    
2238                    case 2: /* Hatch */
2239                            fill = (Pixmap) ui_create_glyph(8, 8,
2240                                                            hatch_patterns + brush->pattern[0] * 8);
2241                            SET_FOREGROUND(fgcolour);
2242                            SET_BACKGROUND(bgcolour);
2243                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2244                            XSetStipple(g_display, g_gc, fill);
2245                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2246                            FILL_POLYGON((XPoint *) point, npoints);
2247                            XSetFillStyle(g_display, g_gc, FillSolid);
2248                            XSetTSOrigin(g_display, g_gc, 0, 0);
2249                            ui_destroy_glyph((HGLYPH) fill);
2250                            break;
2251    
2252                    case 3: /* Pattern */
2253                            for (i = 0; i != 8; i++)
2254                                    ipattern[7 - i] = brush->pattern[i];
2255                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
2256                            SET_FOREGROUND(bgcolour);
2257                            SET_BACKGROUND(fgcolour);
2258                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2259                            XSetStipple(g_display, g_gc, fill);
2260                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2261                            FILL_POLYGON((XPoint *) point, npoints);
2262                            XSetFillStyle(g_display, g_gc, FillSolid);
2263                            XSetTSOrigin(g_display, g_gc, 0, 0);
2264                            ui_destroy_glyph((HGLYPH) fill);
2265                            break;
2266    
2267                    default:
2268                            unimpl("brush %d\n", brush->style);
2269            }
2270    
2271            RESET_FUNCTION(opcode);
2272    }
2273    
2274    void
2275    ui_polyline(uint8 opcode,
2276                /* dest */ POINT * points, int npoints,
2277                /* pen */ PEN * pen)
2278    {
2279            /* TODO: set join style */
2280            SET_FUNCTION(opcode);
2281            SET_FOREGROUND(pen->colour);
2282            XDrawLines(g_display, g_wnd, g_gc, (XPoint *) points, npoints, CoordModePrevious);
2283            if (g_ownbackstore)
2284                    XDrawLines(g_display, g_backstore, g_gc, (XPoint *) points, npoints,
2285                               CoordModePrevious);
2286            RESET_FUNCTION(opcode);
2287    }
2288    
2289    void
2290    ui_ellipse(uint8 opcode,
2291               /* mode */ uint8 fillmode,
2292               /* dest */ int x, int y, int cx, int cy,
2293               /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2294    {
2295            uint8 style, i, ipattern[8];
2296            Pixmap fill;
2297    
2298            SET_FUNCTION(opcode);
2299    
2300            if (brush)
2301                    style = brush->style;
2302            else
2303                    style = 0;
2304    
2305            switch (style)
2306            {
2307                    case 0: /* Solid */
2308                            SET_FOREGROUND(fgcolour);
2309                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2310                            break;
2311    
2312                    case 2: /* Hatch */
2313                            fill = (Pixmap) ui_create_glyph(8, 8,
2314                                                            hatch_patterns + brush->pattern[0] * 8);
2315                            SET_FOREGROUND(fgcolour);
2316                            SET_BACKGROUND(bgcolour);
2317                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2318                            XSetStipple(g_display, g_gc, fill);
2319                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2320                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2321                            XSetFillStyle(g_display, g_gc, FillSolid);
2322                            XSetTSOrigin(g_display, g_gc, 0, 0);
2323                            ui_destroy_glyph((HGLYPH) fill);
2324                            break;
2325    
2326                    case 3: /* Pattern */
2327                            for (i = 0; i != 8; i++)
2328                                    ipattern[7 - i] = brush->pattern[i];
2329                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
2330                            SET_FOREGROUND(bgcolour);
2331                            SET_BACKGROUND(fgcolour);
2332                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2333                            XSetStipple(g_display, g_gc, fill);
2334                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2335                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2336                            XSetFillStyle(g_display, g_gc, FillSolid);
2337                            XSetTSOrigin(g_display, g_gc, 0, 0);
2338                            ui_destroy_glyph((HGLYPH) fill);
2339                            break;
2340    
2341                    default:
2342                            unimpl("brush %d\n", brush->style);
2343            }
2344    
2345            RESET_FUNCTION(opcode);
2346    }
2347    
2348  /* warning, this function only draws on wnd or backstore, not both */  /* warning, this function only draws on wnd or backstore, not both */
2349  void  void
2350  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
# Line 1569  ui_draw_glyph(int mixmode, Line 2369  ui_draw_glyph(int mixmode,
2369  {\  {\
2370    glyph = cache_get_font (font, ttext[idx]);\    glyph = cache_get_font (font, ttext[idx]);\
2371    if (!(flags & TEXT2_IMPLICIT_X))\    if (!(flags & TEXT2_IMPLICIT_X))\
2372      {\
2373        xyoffset = ttext[++idx];\
2374        if ((xyoffset & 0x80))\
2375      {\      {\
2376        xyoffset = ttext[++idx];\        if (flags & TEXT2_VERTICAL)\
2377        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;\  
         }\  
2378        else\        else\
2379          {\          x += ttext[idx+1] | (ttext[idx+2] << 8);\
2380            if (flags & TEXT2_VERTICAL) \        idx += 2;\
             y += xyoffset;\  
           else\  
             x += xyoffset;\  
         }\  
2381      }\      }\
2382    if (glyph != NULL)\      else\
2383      {\      {\
2384        ui_draw_glyph (mixmode, x + glyph->offset,\        if (flags & TEXT2_VERTICAL)\
2385                       y + glyph->baseline,\          y += xyoffset;\
2386                       glyph->width, glyph->height,\        else\
2387                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\          x += xyoffset;\
       if (flags & TEXT2_IMPLICIT_X)\  
         x += glyph->width;\  
2388      }\      }\
2389      }\
2390      if (glyph != NULL)\
2391      {\
2392        x1 = x + glyph->offset;\
2393        y1 = y + glyph->baseline;\
2394        XSetStipple(g_display, g_gc, (Pixmap) glyph->pixmap);\
2395        XSetTSOrigin(g_display, g_gc, x1, y1);\
2396        FILL_RECTANGLE_BACKSTORE(x1, y1, glyph->width, glyph->height);\
2397        if (flags & TEXT2_IMPLICIT_X)\
2398          x += glyph->width;\
2399      }\
2400  }  }
2401    
2402  void  void
2403  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,
2404               int clipx, int clipy, int clipcx, int clipcy,               int clipx, int clipy, int clipcx, int clipcy,
2405               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, BRUSH * brush,
2406               int fgcolour, uint8 * text, uint8 length)               int bgcolour, int fgcolour, uint8 * text, uint8 length)
2407  {  {
2408            /* TODO: use brush appropriately */
2409    
2410          FONTGLYPH *glyph;          FONTGLYPH *glyph;
2411          int i, j, xyoffset;          int i, j, xyoffset, x1, y1;
2412          DATABLOB *entry;          DATABLOB *entry;
2413    
2414          SET_FOREGROUND(bgcolour);          SET_FOREGROUND(bgcolour);
2415    
2416            /* Sometimes, the boxcx value is something really large, like
2417               32691. This makes XCopyArea fail with Xvnc. The code below
2418               is a quick fix. */
2419            if (boxx + boxcx > g_width)
2420                    boxcx = g_width - boxx;
2421    
2422          if (boxcx > 1)          if (boxcx > 1)
2423          {          {
2424                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);
# Line 1619  ui_draw_text(uint8 font, uint8 flags, in Line 2428  ui_draw_text(uint8 font, uint8 flags, in
2428                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
2429          }          }
2430    
2431            SET_FOREGROUND(fgcolour);
2432            SET_BACKGROUND(bgcolour);
2433            XSetFillStyle(g_display, g_gc, FillStippled);
2434    
2435          /* Paint text, character by character */          /* Paint text, character by character */
2436          for (i = 0; i < length;)          for (i = 0; i < length;)
2437          {          {
# Line 1669  ui_draw_text(uint8 font, uint8 flags, in Line 2482  ui_draw_text(uint8 font, uint8 flags, in
2482                                  break;                                  break;
2483                  }                  }
2484          }          }
2485    
2486            XSetFillStyle(g_display, g_gc, FillSolid);
2487    
2488          if (g_ownbackstore)          if (g_ownbackstore)
2489          {          {
2490                  if (boxcx > 1)                  if (boxcx > 1)
# Line 1730  ui_desktop_restore(uint32 offset, int x, Line 2546  ui_desktop_restore(uint32 offset, int x,
2546    
2547          XFree(image);          XFree(image);
2548  }  }
2549    
2550    /* these do nothing here but are used in uiports */
2551    void
2552    ui_begin_update(void)
2553    {
2554    }
2555    
2556    void
2557    ui_end_update(void)
2558    {
2559    }

Legend:
Removed from v.456  
changed lines
  Added in v.867

  ViewVC Help
Powered by ViewVC 1.1.26