/[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 887 by stargo, Sat Apr 16 11:57:19 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 40  Time g_last_gesturetime; Line 46  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    extern uint32 g_embed_wnd;
50  BOOL g_enable_compose = False;  BOOL g_enable_compose = False;
51  static GC g_gc;  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 49  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;  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;  static BOOL g_focused;
65  static BOOL g_mouse_in_wnd;  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;
# Line 61  static int g_red_shift_r, g_blue_shift_r Line 72  static int g_red_shift_r, g_blue_shift_r
72  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;
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;
# Line 109  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    
# Line 162  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_colour(PixelColour pc)  { \
210  {          rv.red = ((colour >> 8) & 0xf8) | ((colour >> 13) & 0x7); \
211          return (((pc.red >> g_red_shift_r) << g_red_shift_l)          rv.green = ((colour >> 3) & 0xfc) | ((colour >> 9) & 0x3); \
212                  | ((pc.green >> g_green_shift_r) << g_green_shift_l)          rv.blue = ((colour << 3) & 0xf8) | ((colour >> 2) & 0x7); \
213                  | ((pc.blue >> g_blue_shift_r) << g_blue_shift_l));  } \
214    
215    #define SPLITCOLOUR24(colour, rv) \
216    { \
217            rv.blue = (colour & 0xff0000) >> 16; \
218            rv.green = (colour & 0x00ff00) >> 8; \
219            rv.red = (colour & 0x0000ff); \
220  }  }
221    
222    #define MAKECOLOUR(pc) \
223            ((pc.red >> g_red_shift_r) << g_red_shift_l) \
224                    | ((pc.green >> g_green_shift_r) << g_green_shift_l) \
225                    | ((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 & 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  {  {
# Line 218  translate_colour(uint32 colour) Line 243  translate_colour(uint32 colour)
243          switch (g_server_bpp)          switch (g_server_bpp)
244          {          {
245                  case 15:                  case 15:
246                          pc = split_colour15(colour);                          SPLITCOLOUR15(colour, pc);
247                          break;                          break;
248                  case 16:                  case 16:
249                          pc = split_colour16(colour);                          SPLITCOLOUR16(colour, pc);
250                          break;                          break;
251                  case 24:                  case 24:
252                          pc = split_colour24(colour);                          SPLITCOLOUR24(colour, pc);
253                          break;                          break;
254          }          }
255          return make_colour(pc);          return MAKECOLOUR(pc);
256    }
257    
258    /* indent is confused by UNROLL8 */
259    /* *INDENT-OFF* */
260    
261    /* repeat and unroll, similar to bitmap.c */
262    /* potentialy any of the following translate */
263    /* functions can use repeat but just doing */
264    /* the most common ones */
265    
266    #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, uint8 * out, uint8 * end)  translate8to16(const uint8 * data, uint8 * out, uint8 * end)
302  {  {
303          uint16 value;          uint16 value;
304    
305          while (out < end)          if (g_arch_match)
306          {          {
307                  value = (uint16) g_colmap[*(data++)];                  /* *INDENT-OFF* */
308                    REPEAT2
309                  if (g_xserver_be)                  (
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                          *(out++) = value >> 8;                          value = (uint16) g_colmap[*(data++)];
320                          *(out++) = value;                          BOUT16(out, value);
321                  }                  }
322                  else          }
323            else
324            {
325                    while (out < end)
326                  {                  {
327                          *(out++) = value;                          value = (uint16) g_colmap[*(data++)];
328                          *(out++) = value >> 8;                          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                  value = g_colmap[*(data++)];                  while (out < end)
   
                 if (g_xserver_be)  
342                  {                  {
343                          *(out++) = value >> 16;                          value = g_colmap[*(data++)];
344                          *(out++) = value >> 8;                          BOUT24(out, value);
                         *(out++) = value;  
345                  }                  }
346                  else          }
347            else
348            {
349                    while (out < end)
350                  {                  {
351                          *(out++) = value;                          value = g_colmap[*(data++)];
352                          *(out++) = value >> 8;                          LOUT24(out, value);
                         *(out++) = value >> 16;  
353                  }                  }
354          }          }
355  }  }
356    
357  static void  static void
358  translate8to32(uint8 * data, uint8 * out, uint8 * end)  translate8to32(const uint8 * data, uint8 * out, uint8 * end)
359  {  {
360          uint32 value;          uint32 value;
361    
362          while (out < end)          if (g_arch_match)
363          {          {
364                  value = g_colmap[*(data++)];                  /* *INDENT-OFF* */
365                    REPEAT4
366                  if (g_xserver_be)                  (
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                          *(out++) = value >> 24;                          value = g_colmap[*(data++)];
377                          *(out++) = value >> 16;                          BOUT32(out, value);
                         *(out++) = value >> 8;  
                         *(out++) = value;  
378                  }                  }
379                  else          }
380            else
381            {
382                    while (out < end)
383                  {                  {
384                          *(out++) = value;                          value = g_colmap[*(data++)];
385                          *(out++) = value >> 8;                          LOUT32(out, value);
                         *(out++) = value >> 16;  
                         *(out++) = value >> 24;  
386                  }                  }
387          }          }
388  }  }
389    
 /* todo the remaining translate function might need some big endian check ?? */  
   
390  static void  static void
391  translate15to16(uint16 * data, uint8 * out, uint8 * end)  translate15to16(const uint16 * data, uint8 * out, uint8 * end)
392  {  {
393          uint16 pixel;          uint16 pixel;
394          uint16 value;          uint16 value;
395            PixelColour pc;
396    
397          while (out < end)          if (g_xserver_be)
398          {          {
399                  pixel = *(data++);                  while (out < end)
   
                 if (g_host_be)  
400                  {                  {
401                          BSWAP16(pixel);                          pixel = *(data++);
402                  }                          if (g_host_be)
403                            {
404                  value = make_colour(split_colour15(pixel));                                  BSWAP16(pixel);
405                            }
406                  if (g_xserver_be)                          SPLITCOLOUR15(pixel, pc);
407                  {                          value = MAKECOLOUR(pc);
408                          *(out++) = value >> 8;                          BOUT16(out, value);
                         *(out++) = value;  
409                  }                  }
410                  else          }
411            else
412            {
413                    while (out < end)
414                  {                  {
415                          *(out++) = value;                          pixel = *(data++);
416                          *(out++) = value >> 8;                          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;          uint16 pixel;
432            PixelColour pc;
433    
434          while (out < end)          if (g_arch_match)
435          {          {
436                  pixel = *(data++);                  /* *INDENT-OFF* */
437                    REPEAT3
438                  if (g_host_be)                  (
439                  {                          pixel = *(data++);
440                          BSWAP16(pixel);                          SPLITCOLOUR15(pixel, pc);
441                  }                          *(out++) = pc.blue;
442                            *(out++) = pc.green;
443                  value = make_colour(split_colour15(pixel));                          *(out++) = pc.red;
444                  if (g_xserver_be)                  )
445                    /* *INDENT-ON* */
446            }
447            else if (g_xserver_be)
448            {
449                    while (out < end)
450                  {                  {
451                          *(out++) = value >> 16;                          pixel = *(data++);
452                          *(out++) = value >> 8;                          if (g_host_be)
453                          *(out++) = value;                          {
454                                    BSWAP16(pixel);
455                            }
456                            SPLITCOLOUR15(pixel, pc);
457                            value = MAKECOLOUR(pc);
458                            BOUT24(out, value);
459                  }                  }
460                  else          }
461            else
462            {
463                    while (out < end)
464                  {                  {
465                          *(out++) = value;                          pixel = *(data++);
466                          *(out++) = value >> 8;                          if (g_host_be)
467                          *(out++) = value >> 16;                          {
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, uint8 * out, uint8 * end)  translate15to32(const uint16 * data, uint8 * out, uint8 * end)
479  {  {
480          uint16 pixel;          uint16 pixel;
481          uint32 value;          uint32 value;
482            PixelColour pc;
483    
484          while (out < end)          if (g_arch_match)
485          {          {
486                  pixel = *(data++);                  /* *INDENT-OFF* */
487                    REPEAT4
488                  if (g_host_be)                  (
489                  {                          pixel = *(data++);
490                          BSWAP16(pixel);                          SPLITCOLOUR15(pixel, pc);
491                  }                          *(out++) = pc.blue;
492                            *(out++) = pc.green;
493                  value = make_colour(split_colour15(pixel));                          *(out++) = pc.red;
494                            *(out++) = 0;
495                  if (g_xserver_be)                  )
496                    /* *INDENT-ON* */
497            }
498            else if (g_xserver_be)
499            {
500                    while (out < end)
501                  {                  {
502                          *(out++) = value >> 24;                          pixel = *(data++);
503                          *(out++) = value >> 16;                          if (g_host_be)
504                          *(out++) = value >> 8;                          {
505                          *(out++) = value;                                  BSWAP16(pixel);
506                            }
507                            SPLITCOLOUR15(pixel, pc);
508                            value = MAKECOLOUR(pc);
509                            BOUT32(out, value);
510                  }                  }
511                  else          }
512            else
513            {
514                    while (out < end)
515                  {                  {
516                          *(out++) = value;                          pixel = *(data++);
517                          *(out++) = value >> 8;                          if (g_host_be)
518                          *(out++) = value >> 16;                          {
519                          *(out++) = value >> 24;                                  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, uint8 * out, uint8 * end)  translate16to16(const uint16 * data, uint8 * out, uint8 * end)
530  {  {
531          uint16 pixel;          uint16 pixel;
532          uint16 value;          uint16 value;
533            PixelColour pc;
534    
535          while (out < end)          if (g_xserver_be)
536          {          {
                 pixel = *(data++);  
   
537                  if (g_host_be)                  if (g_host_be)
538                  {                  {
539                          BSWAP16(pixel);                          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                  value = make_colour(split_colour16(pixel));          else
560            {
561                  if (g_xserver_be)                  if (g_host_be)
562                  {                  {
563                          *(out++) = value >> 8;                          while (out < end)
564                          *(out++) = value;                          {
565                                    pixel = *(data++);
566                                    BSWAP16(pixel);
567                                    SPLITCOLOUR16(pixel, pc);
568                                    value = MAKECOLOUR(pc);
569                                    LOUT16(out, value);
570                            }
571                  }                  }
572                  else                  else
573                  {                  {
574                          *(out++) = value;                          while (out < end)
575                          *(out++) = value >> 8;                          {
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;          uint16 pixel;
590            PixelColour pc;
591    
592          while (out < end)          if (g_arch_match)
593            {
594                    /* *INDENT-OFF* */
595                    REPEAT3
596                    (
597                            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          {          {
                 pixel = *(data++);  
   
607                  if (g_host_be)                  if (g_host_be)
608                  {                  {
609                          BSWAP16(pixel);                          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
                 value = make_colour(split_colour16(pixel));  
   
                 if (g_xserver_be)  
619                  {                  {
620                          *(out++) = value >> 16;                          while (out < end)
621                          *(out++) = value >> 8;                          {
622                          *(out++) = value;                                  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                  else
643                  {                  {
644                          *(out++) = value;                          while (out < end)
645                          *(out++) = value >> 8;                          {
646                          *(out++) = value >> 16;                                  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, uint8 * out, uint8 * end)  translate16to32(const uint16 * data, uint8 * out, uint8 * end)
657  {  {
658          uint16 pixel;          uint16 pixel;
659          uint32 value;          uint32 value;
660            PixelColour pc;
661    
662          while (out < end)          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          {          {
                 pixel = *(data++);  
   
678                  if (g_host_be)                  if (g_host_be)
679                  {                  {
680                          BSWAP16(pixel);                          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
                 value = make_colour(split_colour16(pixel));  
   
                 if (g_xserver_be)  
690                  {                  {
691                          *(out++) = value >> 24;                          while (out < end)
692                          *(out++) = value >> 16;                          {
693                          *(out++) = value >> 8;                                  pixel = *(data++);
694                          *(out++) = value;                                  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                  else
714                  {                  {
715                          *(out++) = value;                          while (out < end)
716                          *(out++) = value >> 8;                          {
717                          *(out++) = value >> 16;                                  pixel = *(data++);
718                          *(out++) = value >> 24;                                  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, uint8 * out, uint8 * end)  translate24to16(const uint8 * data, uint8 * out, uint8 * end)
728  {  {
729          uint32 pixel = 0;          uint32 pixel = 0;
730          uint16 value;          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                    SPLITCOLOUR24(pixel, pc);
739                  value = (uint16) make_colour(split_colour24(pixel));                  value = MAKECOLOUR(pc);
   
740                  if (g_xserver_be)                  if (g_xserver_be)
741                  {                  {
742                          *(out++) = value >> 8;                          BOUT16(out, value);
                         *(out++) = value;  
743                  }                  }
744                  else                  else
745                  {                  {
746                          *(out++) = value;                          LOUT16(out, value);
                         *(out++) = value >> 8;  
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          uint32 pixel;          uint32 pixel;
755          uint32 value;          uint32 value;
756            PixelColour pc;
757    
758          while (out < end)          if (g_xserver_be)
759          {          {
760                  pixel = *(data++) << 16;                  while (out < end)
                 pixel |= *(data++) << 8;  
                 pixel |= *(data++);  
   
                 value = make_colour(split_colour24(pixel));  
                   
                 if (g_xserver_be)  
761                  {                  {
762                          *(out++) = value >> 16;                          pixel = *(data++) << 16;
763                          *(out++) = value >> 8;                          pixel |= *(data++) << 8;
764                          *(out++) = value;                          pixel |= *(data++);
765                            SPLITCOLOUR24(pixel, pc);
766                            value = MAKECOLOUR(pc);
767                            BOUT24(out, value);
768                  }                  }
769                  else          }
770            else
771            {
772                    while (out < end)
773                  {                  {
774                          *(out++) = value;                          pixel = *(data++) << 16;
775                          *(out++) = value >> 8;                          pixel |= *(data++) << 8;
776                          *(out++) = value >> 16;                          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, uint8 * out, uint8 * end)  translate24to32(const uint8 * data, uint8 * out, uint8 * end)
786  {  {
787          uint32 pixel;          uint32 pixel;
788          uint32 value;          uint32 value;
789            PixelColour pc;
790    
791          while (out < end)          if (g_arch_match)
792          {          {
793                  pixel = *(data++) << 16;                  /* *INDENT-OFF* */
794                  pixel |= *(data++) << 8;  #ifdef NEED_ALIGN
795                  pixel |= *(data++);                  REPEAT4
796                    (
797                  value = make_colour(split_colour24(pixel));                          *(out++) = *(data++);
798                            *(out++) = *(data++);
799                  if (g_xserver_be)                          *(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                          *(out++) = value >> 24;                          pixel = *(data++) << 16;
817                          *(out++) = value >> 16;                          pixel |= *(data++) << 8;
818                          *(out++) = value >> 8;                          pixel |= *(data++);
819                          *(out++) = value;                          SPLITCOLOUR24(pixel, pc);
820                            value = MAKECOLOUR(pc);
821                            BOUT32(out, value);
822                  }                  }
823                  else          }
824            else
825            {
826                    while (out < end)
827                  {                  {
828                          *(out++) = value;                          pixel = *(data++) << 16;
829                          *(out++) = value >> 8;                          pixel |= *(data++) << 8;
830                          *(out++) = value >> 16;                          pixel |= *(data++);
831                          *(out++) = value >> 24;                          SPLITCOLOUR24(pixel, pc);
832                            value = MAKECOLOUR(pc);
833                            LOUT32(out, value);
834                  }                  }
835          }          }
836  }  }
# Line 592  translate24to32(uint8 * data, uint8 * ou Line 838  translate24to32(uint8 * data, uint8 * ou
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 700  ui_init(void) Line 963  ui_init(void)
963          XVisualInfo vi;          XVisualInfo vi;
964          XPixmapFormatValues *pfm;          XPixmapFormatValues *pfm;
965          uint16 test;          uint16 test;
966          int i, screen_num;          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 714  ui_init(void) Line 980  ui_init(void)
980          g_screen = ScreenOfDisplay(g_display, screen_num);          g_screen = ScreenOfDisplay(g_display, screen_num);
981          g_depth = DefaultDepthOfScreen(g_screen);          g_depth = DefaultDepthOfScreen(g_screen);
982    
983          if (g_server_bpp == 8)          /* 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                  /* we use a colourmap, so any visual should do */                  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);                  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          else
1015          {          {
# Line 733  ui_init(void) Line 1025  ui_init(void)
1025                  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);
1026                  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);
1027                  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);
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);
# Line 759  ui_init(void) Line 1067  ui_init(void)
1067    
1068          if (!g_owncolmap)          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            }
         test = 1;  
         g_host_be = !(BOOL) (*(uint8 *) (&test));  
         g_xserver_be = (ImageByteOrder(g_display) == MSBFirst);  
1082    
1083          /*          /*
1084           * Determine desktop size           * Determine desktop size
1085           */           */
1086          if (g_width < 0)          if (g_fullscreen)
1087            {
1088                    g_width = WidthOfScreen(g_screen);
1089                    g_height = HeightOfScreen(g_screen);
1090            }
1091            else if (g_width < 0)
1092          {          {
1093                  /* Percent of screen */                  /* Percent of screen */
1094                  g_height = HeightOfScreen(g_screen) * (-g_width) / 100;                  g_height = HeightOfScreen(g_screen) * (-g_width) / 100;
# Line 799  ui_init(void) Line 1111  ui_init(void)
1111                          g_height = 600;                          g_height = 600;
1112                  }                  }
1113          }          }
         else if (g_fullscreen)  
         {  
                 g_width = WidthOfScreen(g_screen);  
                 g_height = HeightOfScreen(g_screen);  
         }  
1114    
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();          xkeymap_init();
# Line 839  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 853  BOOL Line 1152  BOOL
1152  ui_create_window(void)  ui_create_window(void)
1153  {  {
1154          uint8 null_pointer_mask[1] = { 0x80 };          uint8 null_pointer_mask[1] = { 0x80 };
1155          uint8 null_pointer_data[4] = { 0x00, 0x00, 0x00, 0x00 };          uint8 null_pointer_data[24] = { 0x00 };
1156    
1157          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
1158          XClassHint *classhints;          XClassHint *classhints;
1159          XSizeHints *sizehints;          XSizeHints *sizehints;
# Line 864  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          g_wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), 0, 0, wndwidth, wndheight,          if ((g_ownbackstore) && (g_backstore == 0))
1191                                0, CopyFromParent, InputOutput, CopyFromParent,          {
1192                                CWBackPixel | CWBackingStore | CWOverrideRedirect, &attribs);                  g_backstore = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
1193    
1194                    /* clear to prevent rubbish being exposed at startup */
1195                    XSetForeground(g_display, g_gc, BlackPixelOfScreen(g_screen));
1196                    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 889  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 926  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 936  ui_create_window(void) Line 1268  ui_create_window(void)
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 */          /* create invisible 1x1 cursor to be used as null cursor */
1271          g_null_cursor = ui_create_cursor(0, 0, 1, 1, null_pointer_mask, null_pointer_data);          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_destroy_window(void)  ui_resize_window()
1279  {  {
1280          ui_destroy_cursor(g_null_cursor);          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)
1312    {
1313          if (g_IC != NULL)          if (g_IC != NULL)
1314                  XDestroyIC(g_IC);                  XDestroyIC(g_IC);
1315    
# Line 977  xwin_toggle_fullscreen(void) Line 1341  xwin_toggle_fullscreen(void)
1341          }          }
1342  }  }
1343    
1344  /* Process all events in Xlib queue  /* Process events in Xlib queue
1345     Returns 0 after user quit, 1 otherwise */     Returns 0 after user quit, 1 otherwise */
1346  static int  static int
1347  xwin_process_events(void)  xwin_process_events(void)
# Line 989  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;
1356          unsigned int state;          int events = 0;
         Window wdummy;  
         int dummy;  
1357    
1358          while (XPending(g_display) > 0)          while ((XPending(g_display) > 0) && events++ < 20)
1359          {          {
1360                  XNextEvent(g_display, &xevent);                  XNextEvent(g_display, &xevent);
1361    
# Line 1007  xwin_process_events(void) Line 1369  xwin_process_events(void)
1369    
1370                  switch (xevent.type)                  switch (xevent.type)
1371                  {                  {
1372                            case VisibilityNotify:
1373                                    g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;
1374                                    break;
1375                          case ClientMessage:                          case ClientMessage:
1376                                  /* the window manager told us to quit */                                  /* the window manager told us to quit */
1377                                  if ((xevent.xclient.message_type == g_protocol_atom)                                  if ((xevent.xclient.message_type == g_protocol_atom)
# Line 1164  xwin_process_events(void) Line 1529  xwin_process_events(void)
1529                                  if (xevent.xfocus.mode == NotifyGrab)                                  if (xevent.xfocus.mode == NotifyGrab)
1530                                          break;                                          break;
1531                                  g_focused = True;                                  g_focused = True;
1532                                  XQueryPointer(g_display, g_wnd, &wdummy, &wdummy, &dummy, &dummy,                                  reset_modifier_keys();
                                               &dummy, &dummy, &state);  
                                 reset_modifier_keys(state);  
1533                                  if (g_grab_keyboard && g_mouse_in_wnd)                                  if (g_grab_keyboard && g_mouse_in_wnd)
1534                                          XGrabKeyboard(g_display, g_wnd, True,                                          XGrabKeyboard(g_display, g_wnd, True,
1535                                                        GrabModeAsync, GrabModeAsync, CurrentTime);                                                        GrabModeAsync, GrabModeAsync, CurrentTime);
# Line 1246  xwin_process_events(void) Line 1609  xwin_process_events(void)
1609  int  int
1610  ui_select(int rdp_socket)  ui_select(int rdp_socket)
1611  {  {
1612          int n = (rdp_socket > g_x_socket) ? rdp_socket + 1 : g_x_socket + 1;          int n;
1613          fd_set rfds, wfds;          fd_set rfds, wfds;
1614            struct timeval tv;
1615            BOOL s_timeout = False;
1616    
1617          while (True)          while (True)
1618          {          {
1619                    n = (rdp_socket > g_x_socket) ? rdp_socket : g_x_socket;
1620                  /* Process any events already waiting */                  /* Process any events already waiting */
1621                  if (!xwin_process_events())                  if (!xwin_process_events())
1622                          /* User quit */                          /* User quit */
# Line 1266  ui_select(int rdp_socket) Line 1632  ui_select(int rdp_socket)
1632                  if (g_dsp_busy)                  if (g_dsp_busy)
1633                  {                  {
1634                          FD_SET(g_dsp_fd, &wfds);                          FD_SET(g_dsp_fd, &wfds);
1635                          n = (g_dsp_fd + 1 > n) ? g_dsp_fd + 1 : n;                          n = (g_dsp_fd > n) ? g_dsp_fd : n;
1636                  }                  }
1637  #endif  #endif
1638                    /* default timeout */
1639                    tv.tv_sec = 60;
1640                    tv.tv_usec = 0;
1641    
1642                  switch (select(n, &rfds, &wfds, NULL, NULL))                  /* add redirection handles */
1643                    rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
1644    
1645                    n++;
1646    
1647                    switch (select(n, &rfds, &wfds, NULL, &tv))
1648                  {                  {
1649                          case -1:                          case -1:
1650                                  error("select: %s\n", strerror(errno));                                  error("select: %s\n", strerror(errno));
1651    
1652                          case 0:                          case 0:
1653                                    /* Abort serial read calls */
1654                                    if (s_timeout)
1655                                            rdpdr_check_fds(&rfds, &wfds, (BOOL) True);
1656                                  continue;                                  continue;
1657                  }                  }
1658    
1659                    rdpdr_check_fds(&rfds, &wfds, (BOOL) False);
1660    
1661                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
1662                          return 1;                          return 1;
1663    
# Line 1320  ui_create_bitmap(int width, int height, Line 1699  ui_create_bitmap(int width, int height,
1699          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1700                               (char *) tdata, width, height, bitmap_pad, 0);                               (char *) tdata, width, height, bitmap_pad, 0);
1701    
1702          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);
1703    
1704          XFree(image);          XFree(image);
1705          if (!g_owncolmap)          if (tdata != data)
1706                  xfree(tdata);                  xfree(tdata);
1707          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
1708  }  }
# Line 1362  ui_paint_bitmap(int x, int y, int cx, in Line 1741  ui_paint_bitmap(int x, int y, int cx, in
1741          }          }
1742    
1743          XFree(image);          XFree(image);
1744          if (!g_owncolmap)          if (tdata != data)
1745                  xfree(tdata);                  xfree(tdata);
1746  }  }
1747    
# Line 1378  ui_create_glyph(int width, int height, u Line 1757  ui_create_glyph(int width, int height, u
1757          XImage *image;          XImage *image;
1758          Pixmap bitmap;          Pixmap bitmap;
1759          int scanline;          int scanline;
         GC gc;  
1760    
1761          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1762    
1763          bitmap = XCreatePixmap(g_display, g_wnd, width, height, 1);          bitmap = XCreatePixmap(g_display, g_wnd, width, height, 1);
1764          gc = XCreateGC(g_display, bitmap, 0, NULL);          if (g_create_glyph_gc == 0)
1765                    g_create_glyph_gc = XCreateGC(g_display, bitmap, 0, NULL);
1766    
1767          image = XCreateImage(g_display, g_visual, 1, ZPixmap, 0, (char *) data,          image = XCreateImage(g_display, g_visual, 1, ZPixmap, 0, (char *) data,
1768                               width, height, 8, scanline);                               width, height, 8, scanline);
# Line 1391  ui_create_glyph(int width, int height, u Line 1770  ui_create_glyph(int width, int height, u
1770          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
1771          XInitImage(image);          XInitImage(image);
1772    
1773          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);
1774    
1775          XFree(image);          XFree(image);
         XFreeGC(g_display, gc);  
1776          return (HGLYPH) bitmap;          return (HGLYPH) bitmap;
1777  }  }
1778    
# Line 1686  ui_patblt(uint8 opcode, Line 2064  ui_patblt(uint8 opcode,
2064          {          {
2065                  case 0: /* Solid */                  case 0: /* Solid */
2066                          SET_FOREGROUND(fgcolour);                          SET_FOREGROUND(fgcolour);
2067                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
2068                          break;                          break;
2069    
2070                  case 2: /* Hatch */                  case 2: /* Hatch */
# Line 1697  ui_patblt(uint8 opcode, Line 2075  ui_patblt(uint8 opcode,
2075                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2076                          XSetStipple(g_display, g_gc, fill);                          XSetStipple(g_display, g_gc, fill);
2077                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2078                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
2079                          XSetFillStyle(g_display, g_gc, FillSolid);                          XSetFillStyle(g_display, g_gc, FillSolid);
2080                          XSetTSOrigin(g_display, g_gc, 0, 0);                          XSetTSOrigin(g_display, g_gc, 0, 0);
2081                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH) fill);
# Line 1707  ui_patblt(uint8 opcode, Line 2085  ui_patblt(uint8 opcode,
2085                          for (i = 0; i != 8; i++)                          for (i = 0; i != 8; i++)
2086                                  ipattern[7 - i] = brush->pattern[i];                                  ipattern[7 - i] = brush->pattern[i];
2087                          fill = (Pixmap) ui_create_glyph(8, 8, ipattern);                          fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
   
2088                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(bgcolour);
2089                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
2090                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2091                          XSetStipple(g_display, g_gc, fill);                          XSetStipple(g_display, g_gc, fill);
2092                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2093                            FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
                         FILL_RECTANGLE(x, y, cx, cy);  
   
2094                          XSetFillStyle(g_display, g_gc, FillSolid);                          XSetFillStyle(g_display, g_gc, FillSolid);
2095                          XSetTSOrigin(g_display, g_gc, 0, 0);                          XSetTSOrigin(g_display, g_gc, 0, 0);
2096                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH) fill);
# Line 1726  ui_patblt(uint8 opcode, Line 2101  ui_patblt(uint8 opcode,
2101          }          }
2102    
2103          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
2104    
2105            if (g_ownbackstore)
2106                    XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
2107  }  }
2108    
2109  void  void
# Line 1734  ui_screenblt(uint8 opcode, Line 2112  ui_screenblt(uint8 opcode,
2112               /* src */ int srcx, int srcy)               /* src */ int srcx, int srcy)
2113  {  {
2114          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
         XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);  
2115          if (g_ownbackstore)          if (g_ownbackstore)
2116                  XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x, y);          {
2117                    if (g_Unobscured)
2118                    {
2119                            XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
2120                            XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x,
2121                                      y);
2122                    }
2123                    else
2124                    {
2125                            XCopyArea(g_display, g_backstore, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
2126                            XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x,
2127                                      y);
2128                    }
2129            }
2130            else
2131            {
2132                    XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
2133            }
2134          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
2135  }  }
2136    
# Line 1807  ui_rect( Line 2201  ui_rect(
2201          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
2202  }  }
2203    
2204    void
2205    ui_polygon(uint8 opcode,
2206               /* mode */ uint8 fillmode,
2207               /* dest */ POINT * point, int npoints,
2208               /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2209    {
2210            uint8 style, i, ipattern[8];
2211            Pixmap fill;
2212    
2213            SET_FUNCTION(opcode);
2214    
2215            switch (fillmode)
2216            {
2217                    case ALTERNATE:
2218                            XSetFillRule(g_display, g_gc, EvenOddRule);
2219                            break;
2220                    case WINDING:
2221                            XSetFillRule(g_display, g_gc, WindingRule);
2222                            break;
2223                    default:
2224                            unimpl("fill mode %d\n", fillmode);
2225            }
2226    
2227            if (brush)
2228                    style = brush->style;
2229            else
2230                    style = 0;
2231    
2232            switch (style)
2233            {
2234                    case 0: /* Solid */
2235                            SET_FOREGROUND(fgcolour);
2236                            FILL_POLYGON((XPoint *) point, npoints);
2237                            break;
2238    
2239                    case 2: /* Hatch */
2240                            fill = (Pixmap) ui_create_glyph(8, 8,
2241                                                            hatch_patterns + brush->pattern[0] * 8);
2242                            SET_FOREGROUND(fgcolour);
2243                            SET_BACKGROUND(bgcolour);
2244                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2245                            XSetStipple(g_display, g_gc, fill);
2246                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2247                            FILL_POLYGON((XPoint *) point, npoints);
2248                            XSetFillStyle(g_display, g_gc, FillSolid);
2249                            XSetTSOrigin(g_display, g_gc, 0, 0);
2250                            ui_destroy_glyph((HGLYPH) fill);
2251                            break;
2252    
2253                    case 3: /* Pattern */
2254                            for (i = 0; i != 8; i++)
2255                                    ipattern[7 - i] = brush->pattern[i];
2256                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
2257                            SET_FOREGROUND(bgcolour);
2258                            SET_BACKGROUND(fgcolour);
2259                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2260                            XSetStipple(g_display, g_gc, fill);
2261                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2262                            FILL_POLYGON((XPoint *) point, npoints);
2263                            XSetFillStyle(g_display, g_gc, FillSolid);
2264                            XSetTSOrigin(g_display, g_gc, 0, 0);
2265                            ui_destroy_glyph((HGLYPH) fill);
2266                            break;
2267    
2268                    default:
2269                            unimpl("brush %d\n", brush->style);
2270            }
2271    
2272            RESET_FUNCTION(opcode);
2273    }
2274    
2275    void
2276    ui_polyline(uint8 opcode,
2277                /* dest */ POINT * points, int npoints,
2278                /* pen */ PEN * pen)
2279    {
2280            /* TODO: set join style */
2281            SET_FUNCTION(opcode);
2282            SET_FOREGROUND(pen->colour);
2283            XDrawLines(g_display, g_wnd, g_gc, (XPoint *) points, npoints, CoordModePrevious);
2284            if (g_ownbackstore)
2285                    XDrawLines(g_display, g_backstore, g_gc, (XPoint *) points, npoints,
2286                               CoordModePrevious);
2287            RESET_FUNCTION(opcode);
2288    }
2289    
2290    void
2291    ui_ellipse(uint8 opcode,
2292               /* mode */ uint8 fillmode,
2293               /* dest */ int x, int y, int cx, int cy,
2294               /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2295    {
2296            uint8 style, i, ipattern[8];
2297            Pixmap fill;
2298    
2299            SET_FUNCTION(opcode);
2300    
2301            if (brush)
2302                    style = brush->style;
2303            else
2304                    style = 0;
2305    
2306            switch (style)
2307            {
2308                    case 0: /* Solid */
2309                            SET_FOREGROUND(fgcolour);
2310                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2311                            break;
2312    
2313                    case 2: /* Hatch */
2314                            fill = (Pixmap) ui_create_glyph(8, 8,
2315                                                            hatch_patterns + brush->pattern[0] * 8);
2316                            SET_FOREGROUND(fgcolour);
2317                            SET_BACKGROUND(bgcolour);
2318                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2319                            XSetStipple(g_display, g_gc, fill);
2320                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2321                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2322                            XSetFillStyle(g_display, g_gc, FillSolid);
2323                            XSetTSOrigin(g_display, g_gc, 0, 0);
2324                            ui_destroy_glyph((HGLYPH) fill);
2325                            break;
2326    
2327                    case 3: /* Pattern */
2328                            for (i = 0; i != 8; i++)
2329                                    ipattern[7 - i] = brush->pattern[i];
2330                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
2331                            SET_FOREGROUND(bgcolour);
2332                            SET_BACKGROUND(fgcolour);
2333                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2334                            XSetStipple(g_display, g_gc, fill);
2335                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2336                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2337                            XSetFillStyle(g_display, g_gc, FillSolid);
2338                            XSetTSOrigin(g_display, g_gc, 0, 0);
2339                            ui_destroy_glyph((HGLYPH) fill);
2340                            break;
2341    
2342                    default:
2343                            unimpl("brush %d\n", brush->style);
2344            }
2345    
2346            RESET_FUNCTION(opcode);
2347    }
2348    
2349  /* warning, this function only draws on wnd or backstore, not both */  /* warning, this function only draws on wnd or backstore, not both */
2350  void  void
2351  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
# Line 1831  ui_draw_glyph(int mixmode, Line 2370  ui_draw_glyph(int mixmode,
2370  {\  {\
2371    glyph = cache_get_font (font, ttext[idx]);\    glyph = cache_get_font (font, ttext[idx]);\
2372    if (!(flags & TEXT2_IMPLICIT_X))\    if (!(flags & TEXT2_IMPLICIT_X))\
2373      {\
2374        xyoffset = ttext[++idx];\
2375        if ((xyoffset & 0x80))\
2376      {\      {\
2377        xyoffset = ttext[++idx];\        if (flags & TEXT2_VERTICAL)\
2378        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;\  
         }\  
2379        else\        else\
2380          {\          x += ttext[idx+1] | (ttext[idx+2] << 8);\
2381            if (flags & TEXT2_VERTICAL) \        idx += 2;\
             y += xyoffset;\  
           else\  
             x += xyoffset;\  
         }\  
2382      }\      }\
2383    if (glyph != NULL)\      else\
2384      {\      {\
2385        ui_draw_glyph (mixmode, x + glyph->offset,\        if (flags & TEXT2_VERTICAL)\
2386                       y + glyph->baseline,\          y += xyoffset;\
2387                       glyph->width, glyph->height,\        else\
2388                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\          x += xyoffset;\
       if (flags & TEXT2_IMPLICIT_X)\  
         x += glyph->width;\  
2389      }\      }\
2390      }\
2391      if (glyph != NULL)\
2392      {\
2393        x1 = x + glyph->offset;\
2394        y1 = y + glyph->baseline;\
2395        XSetStipple(g_display, g_gc, (Pixmap) glyph->pixmap);\
2396        XSetTSOrigin(g_display, g_gc, x1, y1);\
2397        FILL_RECTANGLE_BACKSTORE(x1, y1, glyph->width, glyph->height);\
2398        if (flags & TEXT2_IMPLICIT_X)\
2399          x += glyph->width;\
2400      }\
2401  }  }
2402    
2403  void  void
2404  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,
2405               int clipx, int clipy, int clipcx, int clipcy,               int clipx, int clipy, int clipcx, int clipcy,
2406               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, BRUSH * brush,
2407               int fgcolour, uint8 * text, uint8 length)               int bgcolour, int fgcolour, uint8 * text, uint8 length)
2408  {  {
2409            /* TODO: use brush appropriately */
2410    
2411          FONTGLYPH *glyph;          FONTGLYPH *glyph;
2412          int i, j, xyoffset;          int i, j, xyoffset, x1, y1;
2413          DATABLOB *entry;          DATABLOB *entry;
2414    
2415          SET_FOREGROUND(bgcolour);          SET_FOREGROUND(bgcolour);
2416    
2417            /* Sometimes, the boxcx value is something really large, like
2418               32691. This makes XCopyArea fail with Xvnc. The code below
2419               is a quick fix. */
2420            if (boxx + boxcx > g_width)
2421                    boxcx = g_width - boxx;
2422    
2423          if (boxcx > 1)          if (boxcx > 1)
2424          {          {
2425                  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 2429  ui_draw_text(uint8 font, uint8 flags, in
2429                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
2430          }          }
2431    
2432            SET_FOREGROUND(fgcolour);
2433            SET_BACKGROUND(bgcolour);
2434            XSetFillStyle(g_display, g_gc, FillStippled);
2435    
2436          /* Paint text, character by character */          /* Paint text, character by character */
2437          for (i = 0; i < length;)          for (i = 0; i < length;)
2438          {          {
# Line 1931  ui_draw_text(uint8 font, uint8 flags, in Line 2483  ui_draw_text(uint8 font, uint8 flags, in
2483                                  break;                                  break;
2484                  }                  }
2485          }          }
2486    
2487            XSetFillStyle(g_display, g_gc, FillSolid);
2488    
2489          if (g_ownbackstore)          if (g_ownbackstore)
2490          {          {
2491                  if (boxcx > 1)                  if (boxcx > 1)
# Line 1992  ui_desktop_restore(uint32 offset, int x, Line 2547  ui_desktop_restore(uint32 offset, int x,
2547    
2548          XFree(image);          XFree(image);
2549  }  }
2550    
2551    /* these do nothing here but are used in uiports */
2552    void
2553    ui_begin_update(void)
2554    {
2555    }
2556    
2557    void
2558    ui_end_update(void)
2559    {
2560    }

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

  ViewVC Help
Powered by ViewVC 1.1.26