/[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 536 by matthewc, Fri Oct 31 04:29:57 2003 UTC revision 843 by jdmeijer, Thu Mar 10 22:40:20 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 BOOL g_sendmotion;  extern BOOL g_sendmotion;
36  extern BOOL g_fullscreen;  extern BOOL g_fullscreen;
37  extern BOOL g_grab_keyboard;  extern BOOL g_grab_keyboard;
# Line 40  Time g_last_gesturetime; Line 45  Time g_last_gesturetime;
45  static int g_x_socket;  static int g_x_socket;
46  static Screen *g_screen;  static Screen *g_screen;
47  Window g_wnd;  Window g_wnd;
48    extern uint32 g_embed_wnd;
49  BOOL g_enable_compose = False;  BOOL g_enable_compose = False;
50  static GC g_gc;  BOOL g_Unobscured;              /* used for screenblt */
51    static GC g_gc = NULL;
52    static GC g_create_bitmap_gc = NULL;
53    static GC g_create_glyph_gc = NULL;
54  static Visual *g_visual;  static Visual *g_visual;
55  static int g_depth;  static int g_depth;
56  static int g_bpp;  static int g_bpp;
# Line 49  static XIM g_IM; Line 58  static XIM g_IM;
58  static XIC g_IC;  static XIC g_IC;
59  static XModifierKeymap *g_mod_map;  static XModifierKeymap *g_mod_map;
60  static Cursor g_current_cursor;  static Cursor g_current_cursor;
61  static HCURSOR g_null_cursor;  static HCURSOR g_null_cursor = NULL;
62  static Atom g_protocol_atom, g_kill_atom;  static Atom g_protocol_atom, g_kill_atom;
63  static BOOL g_focused;  static BOOL g_focused;
64  static BOOL g_mouse_in_wnd;  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 g_host_be;  static BOOL g_host_be;
# Line 61  static int g_red_shift_r, g_blue_shift_r Line 71  static int g_red_shift_r, g_blue_shift_r
71  static int g_red_shift_l, g_blue_shift_l, g_green_shift_l;  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 g_ownbackstore;  extern BOOL g_ownbackstore;
75  static Pixmap g_backstore;  static Pixmap g_backstore = 0;
76    
77  /* Moving in single app mode */  /* Moving in single app mode */
78  static BOOL g_moving_wnd;  static BOOL g_moving_wnd;
# Line 109  PixelColour; Line 119  PixelColour;
119          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); \
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 g_owncolmap = False;  extern BOOL g_owncolmap;
149  static Colormap g_xcolmap;  static Colormap g_xcolmap;
150  static uint32 *g_colmap = NULL;  static uint32 *g_colmap = NULL;
151    
# Line 162  mwm_hide_decorations(void) Line 197  mwm_hide_decorations(void)
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_colour(PixelColour pc)  { \
209  {          rv.red = ((colour >> 8) & 0xf8) | ((colour >> 13) & 0x7); \
210          return (((pc.red >> g_red_shift_r) << g_red_shift_l)          rv.green = ((colour >> 3) & 0xfc) | ((colour >> 9) & 0x3); \
211                  | ((pc.green >> g_green_shift_r) << g_green_shift_l)          rv.blue = ((colour << 3) & 0xf8) | ((colour >> 2) & 0x7); \
212                  | ((pc.blue >> g_blue_shift_r) << g_blue_shift_l));  } \
213    
214    #define SPLITCOLOUR24(colour, rv) \
215    { \
216            rv.blue = (colour & 0xff0000) >> 16; \
217            rv.green = (colour & 0x00ff00) >> 8; \
218            rv.red = (colour & 0x0000ff); \
219  }  }
220    
221    #define MAKECOLOUR(pc) \
222            ((pc.red >> g_red_shift_r) << g_red_shift_l) \
223                    | ((pc.green >> g_green_shift_r) << g_green_shift_l) \
224                    | ((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 & 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  {  {
# Line 218  translate_colour(uint32 colour) Line 242  translate_colour(uint32 colour)
242          switch (g_server_bpp)          switch (g_server_bpp)
243          {          {
244                  case 15:                  case 15:
245                          pc = split_colour15(colour);                          SPLITCOLOUR15(colour, pc);
246                          break;                          break;
247                  case 16:                  case 16:
248                          pc = split_colour16(colour);                          SPLITCOLOUR16(colour, pc);
249                          break;                          break;
250                  case 24:                  case 24:
251                          pc = split_colour24(colour);                          SPLITCOLOUR24(colour, pc);
252                          break;                          break;
253          }          }
254          return make_colour(pc);          return MAKECOLOUR(pc);
255  }  }
256    
257    /* indent is confused by UNROLL8 */
258    /* *INDENT-OFF* */
259    
260    /* repeat and unroll, similar to bitmap.c */
261    /* potentialy any of the following translate */
262    /* functions can use repeat but just doing */
263    /* the most common ones */
264    
265    #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) g_colmap[*(data++)];                  *(out++) = (uint8) g_colmap[*(data++)];
297  }  }
298    
299  static void  static void
300  translate8to16(uint8 * data, uint8 * out, uint8 * end)  translate8to16(const uint8 * data, uint8 * out, uint8 * end)
301  {  {
302          uint16 value;          uint16 value;
303    
304          while (out < end)          if (g_arch_match)
305          {          {
306                  value = (uint16) g_colmap[*(data++)];                  /* *INDENT-OFF* */
307                    REPEAT2
308                  if (g_xserver_be)                  (
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                          *(out++) = value >> 8;                          value = (uint16) g_colmap[*(data++)];
319                          *(out++) = value;                          BOUT16(out, value);
320                  }                  }
321                  else          }
322            else
323            {
324                    while (out < end)
325                  {                  {
326                          *(out++) = value;                          value = (uint16) g_colmap[*(data++)];
327                          *(out++) = value >> 8;                          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                  value = g_colmap[*(data++)];                  while (out < end)
   
                 if (g_xserver_be)  
341                  {                  {
342                          *(out++) = value >> 16;                          value = g_colmap[*(data++)];
343                          *(out++) = value >> 8;                          BOUT24(out, value);
                         *(out++) = value;  
344                  }                  }
345                  else          }
346            else
347            {
348                    while (out < end)
349                  {                  {
350                          *(out++) = value;                          value = g_colmap[*(data++)];
351                          *(out++) = value >> 8;                          LOUT24(out, value);
                         *(out++) = value >> 16;  
352                  }                  }
353          }          }
354  }  }
355    
356  static void  static void
357  translate8to32(uint8 * data, uint8 * out, uint8 * end)  translate8to32(const uint8 * data, uint8 * out, uint8 * end)
358  {  {
359          uint32 value;          uint32 value;
360    
361          while (out < end)          if (g_arch_match)
362          {          {
363                  value = g_colmap[*(data++)];                  /* *INDENT-OFF* */
364                    REPEAT4
365                  if (g_xserver_be)                  (
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                          *(out++) = value >> 24;                          value = g_colmap[*(data++)];
376                          *(out++) = value >> 16;                          BOUT32(out, value);
                         *(out++) = value >> 8;  
                         *(out++) = value;  
377                  }                  }
378                  else          }
379            else
380            {
381                    while (out < end)
382                  {                  {
383                          *(out++) = value;                          value = g_colmap[*(data++)];
384                          *(out++) = value >> 8;                          LOUT32(out, value);
                         *(out++) = value >> 16;  
                         *(out++) = value >> 24;  
385                  }                  }
386          }          }
387  }  }
388    
 /* todo the remaining translate function might need some big endian check ?? */  
   
389  static void  static void
390  translate15to16(uint16 * data, uint8 * out, uint8 * end)  translate15to16(const uint16 * data, uint8 * out, uint8 * end)
391  {  {
392          uint16 pixel;          uint16 pixel;
393          uint16 value;          uint16 value;
394            PixelColour pc;
395    
396          while (out < end)          if (g_xserver_be)
397          {          {
398                  pixel = *(data++);                  while (out < end)
   
                 if (g_host_be)  
399                  {                  {
400                          BSWAP16(pixel);                          pixel = *(data++);
401                  }                          if (g_host_be)
402                            {
403                  value = make_colour(split_colour15(pixel));                                  BSWAP16(pixel);
404                            }
405                  if (g_xserver_be)                          SPLITCOLOUR15(pixel, pc);
406                  {                          value = MAKECOLOUR(pc);
407                          *(out++) = value >> 8;                          BOUT16(out, value);
                         *(out++) = value;  
408                  }                  }
409                  else          }
410            else
411            {
412                    while (out < end)
413                  {                  {
414                          *(out++) = value;                          pixel = *(data++);
415                          *(out++) = value >> 8;                          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;          uint16 pixel;
431            PixelColour pc;
432    
433          while (out < end)          if (g_arch_match)
434          {          {
435                  pixel = *(data++);                  /* *INDENT-OFF* */
436                    REPEAT3
437                  if (g_host_be)                  (
438                  {                          pixel = *(data++);
439                          BSWAP16(pixel);                          SPLITCOLOUR15(pixel, pc);
440                  }                          *(out++) = pc.blue;
441                            *(out++) = pc.green;
442                  value = make_colour(split_colour15(pixel));                          *(out++) = pc.red;
443                  if (g_xserver_be)                  )
444                    /* *INDENT-ON* */
445            }
446            else if (g_xserver_be)
447            {
448                    while (out < end)
449                  {                  {
450                          *(out++) = value >> 16;                          pixel = *(data++);
451                          *(out++) = value >> 8;                          if (g_host_be)
452                          *(out++) = value;                          {
453                                    BSWAP16(pixel);
454                            }
455                            SPLITCOLOUR15(pixel, pc);
456                            value = MAKECOLOUR(pc);
457                            BOUT24(out, value);
458                  }                  }
459                  else          }
460            else
461            {
462                    while (out < end)
463                  {                  {
464                          *(out++) = value;                          pixel = *(data++);
465                          *(out++) = value >> 8;                          if (g_host_be)
466                          *(out++) = value >> 16;                          {
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, uint8 * out, uint8 * end)  translate15to32(const uint16 * data, uint8 * out, uint8 * end)
478  {  {
479          uint16 pixel;          uint16 pixel;
480          uint32 value;          uint32 value;
481            PixelColour pc;
482    
483          while (out < end)          if (g_arch_match)
484          {          {
485                  pixel = *(data++);                  /* *INDENT-OFF* */
486                    REPEAT4
487                  if (g_host_be)                  (
488                  {                          pixel = *(data++);
489                          BSWAP16(pixel);                          SPLITCOLOUR15(pixel, pc);
490                  }                          *(out++) = pc.blue;
491                            *(out++) = pc.green;
492                  value = make_colour(split_colour15(pixel));                          *(out++) = pc.red;
493                            *(out++) = 0;
494                  if (g_xserver_be)                  )
495                    /* *INDENT-ON* */
496            }
497            else if (g_xserver_be)
498            {
499                    while (out < end)
500                  {                  {
501                          *(out++) = value >> 24;                          pixel = *(data++);
502                          *(out++) = value >> 16;                          if (g_host_be)
503                          *(out++) = value >> 8;                          {
504                          *(out++) = value;                                  BSWAP16(pixel);
505                            }
506                            SPLITCOLOUR15(pixel, pc);
507                            value = MAKECOLOUR(pc);
508                            BOUT32(out, value);
509                  }                  }
510                  else          }
511            else
512            {
513                    while (out < end)
514                  {                  {
515                          *(out++) = value;                          pixel = *(data++);
516                          *(out++) = value >> 8;                          if (g_host_be)
517                          *(out++) = value >> 16;                          {
518                          *(out++) = value >> 24;                                  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, uint8 * out, uint8 * end)  translate16to16(const uint16 * data, uint8 * out, uint8 * end)
529  {  {
530          uint16 pixel;          uint16 pixel;
531          uint16 value;          uint16 value;
532            PixelColour pc;
533    
534          while (out < end)          if (g_xserver_be)
535          {          {
                 pixel = *(data++);  
   
536                  if (g_host_be)                  if (g_host_be)
537                  {                  {
538                          BSWAP16(pixel);                          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
                 value = make_colour(split_colour16(pixel));  
   
                 if (g_xserver_be)  
548                  {                  {
549                          *(out++) = value >> 8;                          while (out < end)
550                          *(out++) = value;                          {
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                  else
572                  {                  {
573                          *(out++) = value;                          while (out < end)
574                          *(out++) = value >> 8;                          {
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;          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          {          {
                 pixel = *(data++);  
   
606                  if (g_host_be)                  if (g_host_be)
607                  {                  {
608                          BSWAP16(pixel);                          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
                 value = make_colour(split_colour16(pixel));  
   
                 if (g_xserver_be)  
618                  {                  {
619                          *(out++) = value >> 16;                          while (out < end)
620                          *(out++) = value >> 8;                          {
621                          *(out++) = value;                                  pixel = *(data++);
622                                    SPLITCOLOUR16(pixel, pc);
623                                    value = MAKECOLOUR(pc);
624                                    BOUT24(out, value);
625                            }
626                    }
627            }
628            else
629            {
630                    if (g_host_be)
631                    {
632                            while (out < end)
633                            {
634                                    pixel = *(data++);
635                                    BSWAP16(pixel);
636                                    SPLITCOLOUR16(pixel, pc);
637                                    value = MAKECOLOUR(pc);
638                                    LOUT24(out, value);
639                            }
640                  }                  }
641                  else                  else
642                  {                  {
643                          *(out++) = value;                          while (out < end)
644                          *(out++) = value >> 8;                          {
645                          *(out++) = value >> 16;                                  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, uint8 * out, uint8 * end)  translate16to32(const uint16 * data, uint8 * out, uint8 * end)
656  {  {
657          uint16 pixel;          uint16 pixel;
658          uint32 value;          uint32 value;
659            PixelColour pc;
660    
661          while (out < end)          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          {          {
                 pixel = *(data++);  
   
677                  if (g_host_be)                  if (g_host_be)
678                  {                  {
679                          BSWAP16(pixel);                          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
                 value = make_colour(split_colour16(pixel));  
   
                 if (g_xserver_be)  
689                  {                  {
690                          *(out++) = value >> 24;                          while (out < end)
691                          *(out++) = value >> 16;                          {
692                          *(out++) = value >> 8;                                  pixel = *(data++);
693                          *(out++) = value;                                  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                  else
713                  {                  {
714                          *(out++) = value;                          while (out < end)
715                          *(out++) = value >> 8;                          {
716                          *(out++) = value >> 16;                                  pixel = *(data++);
717                          *(out++) = value >> 24;                                  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, uint8 * out, uint8 * end)  translate24to16(const uint8 * data, uint8 * out, uint8 * end)
727  {  {
728          uint32 pixel = 0;          uint32 pixel = 0;
729          uint16 value;          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                    SPLITCOLOUR24(pixel, pc);
738                  value = (uint16) make_colour(split_colour24(pixel));                  value = MAKECOLOUR(pc);
   
739                  if (g_xserver_be)                  if (g_xserver_be)
740                  {                  {
741                          *(out++) = value >> 8;                          BOUT16(out, value);
                         *(out++) = value;  
742                  }                  }
743                  else                  else
744                  {                  {
745                          *(out++) = value;                          LOUT16(out, value);
                         *(out++) = value >> 8;  
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          uint32 pixel;          uint32 pixel;
754          uint32 value;          uint32 value;
755            PixelColour pc;
756    
757          while (out < end)          if (g_xserver_be)
758          {          {
759                  pixel = *(data++) << 16;                  while (out < end)
                 pixel |= *(data++) << 8;  
                 pixel |= *(data++);  
   
                 value = make_colour(split_colour24(pixel));  
                   
                 if (g_xserver_be)  
760                  {                  {
761                          *(out++) = value >> 16;                          pixel = *(data++) << 16;
762                          *(out++) = value >> 8;                          pixel |= *(data++) << 8;
763                          *(out++) = value;                          pixel |= *(data++);
764                            SPLITCOLOUR24(pixel, pc);
765                            value = MAKECOLOUR(pc);
766                            BOUT24(out, value);
767                  }                  }
768                  else          }
769            else
770            {
771                    while (out < end)
772                  {                  {
773                          *(out++) = value;                          pixel = *(data++) << 16;
774                          *(out++) = value >> 8;                          pixel |= *(data++) << 8;
775                          *(out++) = value >> 16;                          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, uint8 * out, uint8 * end)  translate24to32(const uint8 * data, uint8 * out, uint8 * end)
785  {  {
786          uint32 pixel;          uint32 pixel;
787          uint32 value;          uint32 value;
788            PixelColour pc;
789    
790          while (out < end)          if (g_arch_match)
791          {          {
792                  pixel = *(data++) << 16;                  /* *INDENT-OFF* */
793                  pixel |= *(data++) << 8;  #ifdef NEED_ALIGN
794                  pixel |= *(data++);                  REPEAT4
795                    (
796                  value = make_colour(split_colour24(pixel));                          *(out++) = *(data++);
797                            *(out++) = *(data++);
798                  if (g_xserver_be)                          *(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                          *(out++) = value >> 24;                          pixel = *(data++) << 16;
816                          *(out++) = value >> 16;                          pixel |= *(data++) << 8;
817                          *(out++) = value >> 8;                          pixel |= *(data++);
818                          *(out++) = value;                          SPLITCOLOUR24(pixel, pc);
819                            value = MAKECOLOUR(pc);
820                            BOUT32(out, value);
821                  }                  }
822                  else          }
823            else
824            {
825                    while (out < end)
826                  {                  {
827                          *(out++) = value;                          pixel = *(data++) << 16;
828                          *(out++) = value >> 8;                          pixel |= *(data++) << 8;
829                          *(out++) = value >> 16;                          pixel |= *(data++);
830                          *(out++) = value >> 24;                          SPLITCOLOUR24(pixel, pc);
831                            value = MAKECOLOUR(pc);
832                            LOUT32(out, value);
833                  }                  }
834          }          }
835  }  }
# Line 592  translate24to32(uint8 * data, uint8 * ou Line 837  translate24to32(uint8 * data, uint8 * ou
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 * g_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 (g_server_bpp)          switch (g_server_bpp)
862          {          {
# Line 700  ui_init(void) Line 962  ui_init(void)
962          XVisualInfo vi;          XVisualInfo vi;
963          XPixmapFormatValues *pfm;          XPixmapFormatValues *pfm;
964          uint16 test;          uint16 test;
965          int i, screen_num;          int i, screen_num, nvisuals;
966            XVisualInfo *vmatches = NULL;
967            XVisualInfo template;
968            Bool TrueColorVisual = False;
969    
970          g_display = XOpenDisplay(NULL);          g_display = XOpenDisplay(NULL);
971          if (g_display == NULL)          if (g_display == NULL)
# Line 714  ui_init(void) Line 979  ui_init(void)
979          g_screen = ScreenOfDisplay(g_display, screen_num);          g_screen = ScreenOfDisplay(g_display, screen_num);
980          g_depth = DefaultDepthOfScreen(g_screen);          g_depth = DefaultDepthOfScreen(g_screen);
981    
982          if (g_server_bpp == 8)          /* 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 any visual should do */                  /* we use a colourmap, so the default visual should do */
1004                  g_visual = DefaultVisualOfScreen(g_screen);                  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          else
1014          {          {
# Line 733  ui_init(void) Line 1024  ui_init(void)
1024                  calculate_shifts(vi.red_mask, &g_red_shift_r, &g_red_shift_l);                  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);                  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);                  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(g_display, &i);          pfm = XListPixmapFormats(g_display, &i);
# Line 759  ui_init(void) Line 1066  ui_init(void)
1066    
1067          if (!g_owncolmap)          if (!g_owncolmap)
1068          {          {
1069                  g_xcolmap = DefaultColormapOfScreen(g_screen);                  g_xcolmap =
1070                            XCreateColormap(g_display, RootWindowOfScreen(g_screen), g_visual,
1071                                            AllocNone);
1072                  if (g_depth <= 8)                  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          g_gc = XCreateGC(g_display, RootWindowOfScreen(g_screen), 0, NULL);          if ((!g_ownbackstore) && (DoesBackingStore(g_screen) != Always))
1077            {
1078          if (DoesBackingStore(g_screen) != Always)                  warning("External BackingStore not available, using internal\n");
1079                  g_ownbackstore = True;                  g_ownbackstore = True;
1080            }
         test = 1;  
         g_host_be = !(BOOL) (*(uint8 *) (&test));  
         g_xserver_be = (ImageByteOrder(g_display) == MSBFirst);  
1081    
1082          /*          /*
1083           * Determine desktop size           * Determine desktop size
1084           */           */
1085          if (g_width < 0)          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 */                  /* Percent of screen */
1093                  g_height = HeightOfScreen(g_screen) * (-g_width) / 100;                  g_height = HeightOfScreen(g_screen) * (-g_width) / 100;
# Line 799  ui_init(void) Line 1110  ui_init(void)
1110                          g_height = 600;                          g_height = 600;
1111                  }                  }
1112          }          }
         else if (g_fullscreen)  
         {  
                 g_width = WidthOfScreen(g_screen);  
                 g_height = HeightOfScreen(g_screen);  
         }  
1113    
1114          /* make sure width is a multiple of 4 */          /* make sure width is a multiple of 4 */
1115          g_width = (g_width + 3) & ~3;          g_width = (g_width + 3) & ~3;
1116    
         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);  
         }  
   
1117          g_mod_map = XGetModifierMapping(g_display);          g_mod_map = XGetModifierMapping(g_display);
1118    
1119          xkeymap_init();          xkeymap_init();
# Line 839  ui_deinit(void) Line 1134  ui_deinit(void)
1134          if (g_IM != NULL)          if (g_IM != NULL)
1135                  XCloseIM(g_IM);                  XCloseIM(g_IM);
1136    
1137            if (g_null_cursor != NULL)
1138                    ui_destroy_cursor(g_null_cursor);
1139    
1140          XFreeModifiermap(g_mod_map);          XFreeModifiermap(g_mod_map);
1141    
1142          if (g_ownbackstore)          if (g_ownbackstore)
# Line 853  BOOL Line 1151  BOOL
1151  ui_create_window(void)  ui_create_window(void)
1152  {  {
1153          uint8 null_pointer_mask[1] = { 0x80 };          uint8 null_pointer_mask[1] = { 0x80 };
1154          uint8 null_pointer_data[4] = { 0x00, 0x00, 0x00, 0x00 };          uint8 null_pointer_data[24] = { 0x00 };
1155    
1156          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
1157          XClassHint *classhints;          XClassHint *classhints;
1158          XSizeHints *sizehints;          XSizeHints *sizehints;
# Line 865  ui_create_window(void) Line 1164  ui_create_window(void)
1164          wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;          wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;
1165    
1166          attribs.background_pixel = BlackPixelOfScreen(g_screen);          attribs.background_pixel = BlackPixelOfScreen(g_screen);
1167            attribs.border_pixel = WhitePixelOfScreen(g_screen);
1168          attribs.backing_store = g_ownbackstore ? NotUseful : Always;          attribs.backing_store = g_ownbackstore ? NotUseful : Always;
1169          attribs.override_redirect = g_fullscreen;          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            if (g_gc == NULL)
1178                    g_gc = XCreateGC(g_display, g_wnd, 0, NULL);
1179    
1180          g_wnd = XCreateWindow(g_display, RootWindowOfScreen(g_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);
1182                                CWBackPixel | CWBackingStore | CWOverrideRedirect, &attribs);  
1183            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          XStoreName(g_display, g_wnd, g_title);          XStoreName(g_display, g_wnd, g_title);
1193    
# Line 895  ui_create_window(void) Line 1212  ui_create_window(void)
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    
# Line 926  ui_create_window(void) Line 1248  ui_create_window(void)
1248                  XMaskEvent(g_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          g_focused = False;          g_focused = False;
1254          g_mouse_in_wnd = False;          g_mouse_in_wnd = False;
# Line 936  ui_create_window(void) Line 1259  ui_create_window(void)
1259          XSetWMProtocols(g_display, g_wnd, &g_kill_atom, 1);          XSetWMProtocols(g_display, g_wnd, &g_kill_atom, 1);
1260    
1261          /* create invisible 1x1 cursor to be used as null cursor */          /* create invisible 1x1 cursor to be used as null cursor */
1262          g_null_cursor = ui_create_cursor(0, 0, 1, 1, null_pointer_mask, null_pointer_data);          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_destroy_window(void)  ui_resize_window()
1270  {  {
1271          ui_destroy_cursor(g_null_cursor);          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)
1303    {
1304          if (g_IC != NULL)          if (g_IC != NULL)
1305                  XDestroyIC(g_IC);                  XDestroyIC(g_IC);
1306    
# Line 989  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(g_display) > 0)          while (XPending(g_display) > 0)
1349          {          {
# Line 1007  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 == g_protocol_atom)                                  if ((xevent.xclient.message_type == g_protocol_atom)
# Line 1164  xwin_process_events(void) Line 1519  xwin_process_events(void)
1519                                  if (xevent.xfocus.mode == NotifyGrab)                                  if (xevent.xfocus.mode == NotifyGrab)
1520                                          break;                                          break;
1521                                  g_focused = True;                                  g_focused = True;
1522                                  XQueryPointer(g_display, g_wnd, &wdummy, &wdummy, &dummy, &dummy,                                  reset_modifier_keys();
                                               &dummy, &dummy, &state);  
                                 reset_modifier_keys(state);  
1523                                  if (g_grab_keyboard && g_mouse_in_wnd)                                  if (g_grab_keyboard && g_mouse_in_wnd)
1524                                          XGrabKeyboard(g_display, g_wnd, True,                                          XGrabKeyboard(g_display, g_wnd, True,
1525                                                        GrabModeAsync, GrabModeAsync, CurrentTime);                                                        GrabModeAsync, GrabModeAsync, CurrentTime);
# Line 1246  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 > g_x_socket) ? rdp_socket + 1 : g_x_socket + 1;          int n;
1603          fd_set rfds, wfds;          fd_set rfds, wfds;
1604            struct timeval tv;
1605            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 */
# Line 1266  ui_select(int rdp_socket) Line 1622  ui_select(int rdp_socket)
1622                  if (g_dsp_busy)                  if (g_dsp_busy)
1623                  {                  {
1624                          FD_SET(g_dsp_fd, &wfds);                          FD_SET(g_dsp_fd, &wfds);
1625                          n = (g_dsp_fd + 1 > n) ? g_dsp_fd + 1 : n;                          n = (g_dsp_fd > n) ? g_dsp_fd : n;
1626                  }                  }
1627  #endif  #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, NULL))                  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    
# Line 1320  ui_create_bitmap(int width, int height, Line 1689  ui_create_bitmap(int width, int height,
1689          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1690                               (char *) tdata, width, height, bitmap_pad, 0);                               (char *) tdata, width, height, bitmap_pad, 0);
1691    
1692          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);
1693    
1694          XFree(image);          XFree(image);
1695          if (!g_owncolmap)          if (tdata != data)
1696                  xfree(tdata);                  xfree(tdata);
1697          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
1698  }  }
# Line 1362  ui_paint_bitmap(int x, int y, int cx, in Line 1731  ui_paint_bitmap(int x, int y, int cx, in
1731          }          }
1732    
1733          XFree(image);          XFree(image);
1734          if (!g_owncolmap)          if (tdata != data)
1735                  xfree(tdata);                  xfree(tdata);
1736  }  }
1737    
# Line 1378  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(g_display, g_wnd, width, height, 1);          bitmap = XCreatePixmap(g_display, g_wnd, width, height, 1);
1754          gc = XCreateGC(g_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(g_display, g_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);
# Line 1391  ui_create_glyph(int width, int height, u Line 1760  ui_create_glyph(int width, int height, u
1760          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
1761          XInitImage(image);          XInitImage(image);
1762    
1763          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);
1764    
1765          XFree(image);          XFree(image);
         XFreeGC(g_display, gc);  
1766          return (HGLYPH) bitmap;          return (HGLYPH) bitmap;
1767  }  }
1768    
# Line 1686  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 */
# Line 1697  ui_patblt(uint8 opcode, Line 2065  ui_patblt(uint8 opcode,
2065                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2066                          XSetStipple(g_display, g_gc, fill);                          XSetStipple(g_display, g_gc, fill);
2067                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2068                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
2069                          XSetFillStyle(g_display, g_gc, FillSolid);                          XSetFillStyle(g_display, g_gc, FillSolid);
2070                          XSetTSOrigin(g_display, g_gc, 0, 0);                          XSetTSOrigin(g_display, g_gc, 0, 0);
2071                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH) fill);
# Line 1707  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(g_display, g_gc, FillOpaqueStippled);                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2081                          XSetStipple(g_display, g_gc, fill);                          XSetStipple(g_display, g_gc, fill);
2082                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2083                            FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
                         FILL_RECTANGLE(x, y, cx, cy);  
   
2084                          XSetFillStyle(g_display, g_gc, FillSolid);                          XSetFillStyle(g_display, g_gc, FillSolid);
2085                          XSetTSOrigin(g_display, g_gc, 0, 0);                          XSetTSOrigin(g_display, g_gc, 0, 0);
2086                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH) fill);
# Line 1726  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 1734  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);
         XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);  
2105          if (g_ownbackstore)          if (g_ownbackstore)
2106                  XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x, y);          {
2107                    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 1807  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_ellipse(uint8 opcode,
2267               /* mode */ uint8 fillmode,
2268               /* dest */ int x, int y, int cx, int cy,
2269               /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2270    {
2271            uint8 style, i, ipattern[8];
2272            Pixmap fill;
2273    
2274            SET_FUNCTION(opcode);
2275    
2276            if (brush)
2277                    style = brush->style;
2278            else
2279                    style = 0;
2280    
2281            switch (style)
2282            {
2283                    case 0: /* Solid */
2284                            SET_FOREGROUND(fgcolour);
2285                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2286                            break;
2287    
2288                    case 2: /* Hatch */
2289                            fill = (Pixmap) ui_create_glyph(8, 8,
2290                                                            hatch_patterns + brush->pattern[0] * 8);
2291                            SET_FOREGROUND(fgcolour);
2292                            SET_BACKGROUND(bgcolour);
2293                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2294                            XSetStipple(g_display, g_gc, fill);
2295                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2296                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2297                            XSetFillStyle(g_display, g_gc, FillSolid);
2298                            XSetTSOrigin(g_display, g_gc, 0, 0);
2299                            ui_destroy_glyph((HGLYPH) fill);
2300                            break;
2301    
2302                    case 3: /* Pattern */
2303                            for (i = 0; i != 8; i++)
2304                                    ipattern[7 - i] = brush->pattern[i];
2305                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
2306                            SET_FOREGROUND(bgcolour);
2307                            SET_BACKGROUND(fgcolour);
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                    default:
2318                            unimpl("brush %d\n", brush->style);
2319            }
2320    
2321            RESET_FUNCTION(opcode);
2322    }
2323    
2324  /* warning, this function only draws on wnd or backstore, not both */  /* warning, this function only draws on wnd or backstore, not both */
2325  void  void
2326  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
# Line 1831  ui_draw_glyph(int mixmode, Line 2345  ui_draw_glyph(int mixmode,
2345  {\  {\
2346    glyph = cache_get_font (font, ttext[idx]);\    glyph = cache_get_font (font, ttext[idx]);\
2347    if (!(flags & TEXT2_IMPLICIT_X))\    if (!(flags & TEXT2_IMPLICIT_X))\
2348      {\
2349        xyoffset = ttext[++idx];\
2350        if ((xyoffset & 0x80))\
2351      {\      {\
2352        xyoffset = ttext[++idx];\        if (flags & TEXT2_VERTICAL)\
2353        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;\  
         }\  
2354        else\        else\
2355          {\          x += ttext[idx+1] | (ttext[idx+2] << 8);\
2356            if (flags & TEXT2_VERTICAL) \        idx += 2;\
             y += xyoffset;\  
           else\  
             x += xyoffset;\  
         }\  
2357      }\      }\
2358    if (glyph != NULL)\      else\
2359      {\      {\
2360        ui_draw_glyph (mixmode, x + glyph->offset,\        if (flags & TEXT2_VERTICAL)\
2361                       y + glyph->baseline,\          y += xyoffset;\
2362                       glyph->width, glyph->height,\        else\
2363                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\          x += xyoffset;\
       if (flags & TEXT2_IMPLICIT_X)\  
         x += glyph->width;\  
2364      }\      }\
2365      }\
2366      if (glyph != NULL)\
2367      {\
2368        x1 = x + glyph->offset;\
2369        y1 = y + glyph->baseline;\
2370        XSetStipple(g_display, g_gc, (Pixmap) glyph->pixmap);\
2371        XSetTSOrigin(g_display, g_gc, x1, y1);\
2372        FILL_RECTANGLE_BACKSTORE(x1, y1, glyph->width, glyph->height);\
2373        if (flags & TEXT2_IMPLICIT_X)\
2374          x += glyph->width;\
2375      }\
2376  }  }
2377    
2378  void  void
2379  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,
2380               int clipx, int clipy, int clipcx, int clipcy,               int clipx, int clipy, int clipcx, int clipcy,
2381               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, BRUSH * brush,
2382               int fgcolour, uint8 * text, uint8 length)               int bgcolour, int fgcolour, uint8 * text, uint8 length)
2383  {  {
2384            /* TODO: use brush appropriately */
2385    
2386          FONTGLYPH *glyph;          FONTGLYPH *glyph;
2387          int i, j, xyoffset;          int i, j, xyoffset, x1, y1;
2388          DATABLOB *entry;          DATABLOB *entry;
2389    
2390          SET_FOREGROUND(bgcolour);          SET_FOREGROUND(bgcolour);
2391    
2392            /* Sometimes, the boxcx value is something really large, like
2393               32691. This makes XCopyArea fail with Xvnc. The code below
2394               is a quick fix. */
2395            if (boxx + boxcx > g_width)
2396                    boxcx = g_width - boxx;
2397    
2398          if (boxcx > 1)          if (boxcx > 1)
2399          {          {
2400                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);
# Line 1881  ui_draw_text(uint8 font, uint8 flags, in Line 2404  ui_draw_text(uint8 font, uint8 flags, in
2404                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
2405          }          }
2406    
2407            SET_FOREGROUND(fgcolour);
2408            SET_BACKGROUND(bgcolour);
2409            XSetFillStyle(g_display, g_gc, FillStippled);
2410    
2411          /* Paint text, character by character */          /* Paint text, character by character */
2412          for (i = 0; i < length;)          for (i = 0; i < length;)
2413          {          {
# Line 1931  ui_draw_text(uint8 font, uint8 flags, in Line 2458  ui_draw_text(uint8 font, uint8 flags, in
2458                                  break;                                  break;
2459                  }                  }
2460          }          }
2461    
2462            XSetFillStyle(g_display, g_gc, FillSolid);
2463    
2464          if (g_ownbackstore)          if (g_ownbackstore)
2465          {          {
2466                  if (boxcx > 1)                  if (boxcx > 1)
# Line 1992  ui_desktop_restore(uint32 offset, int x, Line 2522  ui_desktop_restore(uint32 offset, int x,
2522    
2523          XFree(image);          XFree(image);
2524  }  }
2525    
2526    /* these do nothing here but are used in uiports */
2527    void
2528    ui_begin_update(void)
2529    {
2530    }
2531    
2532    void
2533    ui_end_update(void)
2534    {
2535    }

Legend:
Removed from v.536  
changed lines
  Added in v.843

  ViewVC Help
Powered by ViewVC 1.1.26