/[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 697 by astrand, Tue May 11 13:45:57 2004 UTC revision 991 by astrand, Fri Aug 26 07:01:02 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 30  Line 30 
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 47  extern uint32 g_embed_wnd; Line 50  extern uint32 g_embed_wnd;
50  BOOL g_enable_compose = False;  BOOL g_enable_compose = False;
51  BOOL g_Unobscured;              /* used for screenblt */  BOOL g_Unobscured;              /* used for screenblt */
52  static GC g_gc = NULL;  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 74  static Pixmap g_backstore = 0; Line 79  static Pixmap g_backstore = 0;
79  static BOOL g_moving_wnd;  static BOOL g_moving_wnd;
80  static int g_move_x_offset = 0;  static int g_move_x_offset = 0;
81  static int g_move_y_offset = 0;  static int g_move_y_offset = 0;
82    static BOOL g_using_full_workarea = False;
83    
84  #ifdef WITH_RDPSND  #ifdef WITH_RDPSND
85  extern int g_dsp_fd;  extern int g_dsp_fd;
# Line 115  PixelColour; Line 121  PixelColour;
121          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); \
122  }  }
123    
124    #define FILL_POLYGON(p,np)\
125    { \
126            XFillPolygon(g_display, g_wnd, g_gc, p, np, Complex, CoordModePrevious); \
127            if (g_ownbackstore) \
128                    XFillPolygon(g_display, g_backstore, g_gc, p, np, Complex, CoordModePrevious); \
129    }
130    
131    #define DRAW_ELLIPSE(x,y,cx,cy,m)\
132    { \
133            switch (m) \
134            { \
135                    case 0: /* Outline */ \
136                            XDrawArc(g_display, g_wnd, g_gc, x, y, cx, cy, 0, 360*64); \
137                            if (g_ownbackstore) \
138                                    XDrawArc(g_display, g_backstore, g_gc, x, y, cx, cy, 0, 360*64); \
139                            break; \
140                    case 1: /* Filled */ \
141                            XFillArc(g_display, g_ownbackstore ? g_backstore : g_wnd, g_gc, x, y, \
142                                     cx, cy, 0, 360*64); \
143                            if (g_ownbackstore) \
144                                    XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y); \
145                            break; \
146            } \
147    }
148    
149  /* colour maps */  /* colour maps */
150  extern BOOL g_owncolmap;  extern BOOL g_owncolmap;
151  static Colormap g_xcolmap;  static Colormap g_xcolmap;
# Line 168  mwm_hide_decorations(void) Line 199  mwm_hide_decorations(void)
199                          (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);                          (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
200  }  }
201    
202  static PixelColour  #define SPLITCOLOUR15(colour, rv) \
203  split_colour15(uint32 colour)  { \
204  {          rv.red = ((colour >> 7) & 0xf8) | ((colour >> 12) & 0x7); \
205          PixelColour rv;          rv.green = ((colour >> 2) & 0xf8) | ((colour >> 8) & 0x7); \
206          rv.red = (colour & 0x7c00) >> 7;          rv.blue = ((colour << 3) & 0xf8) | ((colour >> 2) & 0x7); \
         rv.green = (colour & 0x03e0) >> 2;  
         rv.blue = (colour & 0x001f) << 3;  
         return rv;  
 }  
   
 static PixelColour  
 split_colour16(uint32 colour)  
 {  
         PixelColour rv;  
         rv.red = (colour & 0xf800) >> 8;  
         rv.green = (colour & 0x07e0) >> 3;  
         rv.blue = (colour & 0x001f) << 3;  
         return rv;  
 }  
   
 static PixelColour  
 split_colour24(uint32 colour)  
 {  
         PixelColour rv;  
         rv.blue = (colour & 0xff0000) >> 16;  
         rv.green = (colour & 0x00ff00) >> 8;  
         rv.red = (colour & 0x0000ff);  
         return rv;  
207  }  }
208    
209  static uint32  #define SPLITCOLOUR16(colour, rv) \
210  make_colour(PixelColour pc)  { \
211  {          rv.red = ((colour >> 8) & 0xf8) | ((colour >> 13) & 0x7); \
212          return (((pc.red >> g_red_shift_r) << g_red_shift_l)          rv.green = ((colour >> 3) & 0xfc) | ((colour >> 9) & 0x3); \
213                  | ((pc.green >> g_green_shift_r) << g_green_shift_l)          rv.blue = ((colour << 3) & 0xf8) | ((colour >> 2) & 0x7); \
214                  | ((pc.blue >> g_blue_shift_r) << g_blue_shift_l));  } \
215    
216    #define SPLITCOLOUR24(colour, rv) \
217    { \
218            rv.blue = (colour & 0xff0000) >> 16; \
219            rv.green = (colour & 0x00ff00) >> 8; \
220            rv.red = (colour & 0x0000ff); \
221  }  }
222    
223    #define MAKECOLOUR(pc) \
224            ((pc.red >> g_red_shift_r) << g_red_shift_l) \
225                    | ((pc.green >> g_green_shift_r) << g_green_shift_l) \
226                    | ((pc.blue >> g_blue_shift_r) << g_blue_shift_l) \
227    
228  #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }  #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
229  #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | (x & 0xff00)); }  #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | (x & 0xff00)); }
230  #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \  #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
231                          x = (x << 16) | (x >> 16); }                          x = (x << 16) | (x >> 16); }
232    
233    #define BOUT16(o, x) { *(o++) = x >> 8; *(o++) = x; }
234    #define BOUT24(o, x) { *(o++) = x >> 16; *(o++) = x >> 8; *(o++) = x; }
235    #define BOUT32(o, x) { *(o++) = x >> 24; *(o++) = x >> 16; *(o++) = x >> 8; *(o++) = x; }
236    #define LOUT16(o, x) { *(o++) = x; *(o++) = x >> 8; }
237    #define LOUT24(o, x) { *(o++) = x; *(o++) = x >> 8; *(o++) = x >> 16; }
238    #define LOUT32(o, x) { *(o++) = x; *(o++) = x >> 8; *(o++) = x >> 16; *(o++) = x >> 24; }
239    
240  static uint32  static uint32
241  translate_colour(uint32 colour)  translate_colour(uint32 colour)
242  {  {
# Line 218  translate_colour(uint32 colour) Line 244  translate_colour(uint32 colour)
244          switch (g_server_bpp)          switch (g_server_bpp)
245          {          {
246                  case 15:                  case 15:
247                          pc = split_colour15(colour);                          SPLITCOLOUR15(colour, pc);
248                          break;                          break;
249                  case 16:                  case 16:
250                          pc = split_colour16(colour);                          SPLITCOLOUR16(colour, pc);
251                          break;                          break;
252                  case 24:                  case 24:
253                          pc = split_colour24(colour);                          SPLITCOLOUR24(colour, pc);
254                          break;                          break;
255          }          }
256          return make_colour(pc);          return MAKECOLOUR(pc);
257  }  }
258    
259    /* indent is confused by UNROLL8 */
260    /* *INDENT-OFF* */
261    
262    /* repeat and unroll, similar to bitmap.c */
263    /* potentialy any of the following translate */
264    /* functions can use repeat but just doing */
265    /* the most common ones */
266    
267  #define UNROLL8(stm) { stm stm stm stm stm stm stm stm }  #define UNROLL8(stm) { stm stm stm stm stm stm stm stm }
268  #define REPEAT(stm) \  /* 2 byte output repeat */
269    #define REPEAT2(stm) \
270    { \
271            while (out <= end - 8 * 2) \
272                    UNROLL8(stm) \
273            while (out < end) \
274                    { stm } \
275    }
276    /* 3 byte output repeat */
277    #define REPEAT3(stm) \
278    { \
279            while (out <= end - 8 * 3) \
280                    UNROLL8(stm) \
281            while (out < end) \
282                    { stm } \
283    }
284    /* 4 byte output repeat */
285    #define REPEAT4(stm) \
286  { \  { \
287          while (out <= end - 8 * 4) \          while (out <= end - 8 * 4) \
288                  UNROLL8(stm) \                  UNROLL8(stm) \
289          while (out < end) \          while (out < end) \
290                  { stm } \                  { stm } \
291  }  }
292    /* *INDENT-ON* */
293    
294  static void  static void
295  translate8to8(uint8 * data, uint8 * out, uint8 * end)  translate8to8(const uint8 * data, uint8 * out, uint8 * end)
296  {  {
297          while (out < end)          while (out < end)
298                  *(out++) = (uint8) g_colmap[*(data++)];                  *(out++) = (uint8) g_colmap[*(data++)];
299  }  }
300    
301  static void  static void
302  translate8to16(uint8 * data, uint8 * out, uint8 * end)  translate8to16(const uint8 * data, uint8 * out, uint8 * end)
303  {  {
304          uint16 value;          uint16 value;
305    
306          if (g_arch_match)          if (g_arch_match)
307                  REPEAT(*((uint16 *) out) = g_colmap[*(data++)]; out += 2;          {
308                    /* *INDENT-OFF* */
309                    REPEAT2
310                    (
311                            *((uint16 *) out) = g_colmap[*(data++)];
312                            out += 2;
313                  )                  )
314          else                  /* *INDENT-ON* */
315  if (g_xserver_be)          }
316  {          else if (g_xserver_be)
         while (out < end)  
317          {          {
318                  value = (uint16) g_colmap[*(data++)];                  while (out < end)
319                  *(out++) = value >> 8;                  {
320                  *(out++) = value;                          value = (uint16) g_colmap[*(data++)];
321                            BOUT16(out, value);
322                    }
323          }          }
324  }          else
 else  
 {  
         while (out < end)  
325          {          {
326                  value = (uint16) g_colmap[*(data++)];                  while (out < end)
327                  *(out++) = value;                  {
328                  *(out++) = value >> 8;                          value = (uint16) g_colmap[*(data++)];
329                            LOUT16(out, value);
330                    }
331          }          }
332  }  }
 }  
333    
334  /* little endian - conversion happens when colourmap is built */  /* little endian - conversion happens when colourmap is built */
335  static void  static void
336  translate8to24(uint8 * data, uint8 * out, uint8 * end)  translate8to24(const uint8 * data, uint8 * out, uint8 * end)
337  {  {
338          uint32 value;          uint32 value;
339    
# Line 286  translate8to24(uint8 * data, uint8 * out Line 342  translate8to24(uint8 * data, uint8 * out
342                  while (out < end)                  while (out < end)
343                  {                  {
344                          value = g_colmap[*(data++)];                          value = g_colmap[*(data++)];
345                          *(out++) = value >> 16;                          BOUT24(out, value);
                         *(out++) = value >> 8;  
                         *(out++) = value;  
346                  }                  }
347          }          }
348          else          else
# Line 296  translate8to24(uint8 * data, uint8 * out Line 350  translate8to24(uint8 * data, uint8 * out
350                  while (out < end)                  while (out < end)
351                  {                  {
352                          value = g_colmap[*(data++)];                          value = g_colmap[*(data++)];
353                          *(out++) = value;                          LOUT24(out, value);
                         *(out++) = value >> 8;  
                         *(out++) = value >> 16;  
354                  }                  }
355          }          }
356  }  }
357    
358  static void  static void
359  translate8to32(uint8 * data, uint8 * out, uint8 * end)  translate8to32(const uint8 * data, uint8 * out, uint8 * end)
360  {  {
361          uint32 value;          uint32 value;
362    
363          if (g_arch_match)          if (g_arch_match)
364                  REPEAT(*((uint32 *) out) = g_colmap[*(data++)]; out += 4;          {
365                    /* *INDENT-OFF* */
366                    REPEAT4
367                    (
368                            *((uint32 *) out) = g_colmap[*(data++)];
369                            out += 4;
370                  )                  )
371          else                  /* *INDENT-ON* */
372  if (g_xserver_be)          }
373  {          else if (g_xserver_be)
         while (out < end)  
374          {          {
375                  value = g_colmap[*(data++)];                  while (out < end)
376                  *(out++) = value >> 24;                  {
377                  *(out++) = value >> 16;                          value = g_colmap[*(data++)];
378                  *(out++) = value >> 8;                          BOUT32(out, value);
379                  *(out++) = value;                  }
380          }          }
381  }          else
 else  
 {  
         while (out < end)  
382          {          {
383                  value = g_colmap[*(data++)];                  while (out < end)
384                  *(out++) = value;                  {
385                  *(out++) = value >> 8;                          value = g_colmap[*(data++)];
386                  *(out++) = value >> 16;                          LOUT32(out, value);
387                  *(out++) = value >> 24;                  }
388          }          }
389  }  }
 }  
390    
391  static void  static void
392  translate15to16(uint16 * data, uint8 * out, uint8 * end)  translate15to16(const uint16 * data, uint8 * out, uint8 * end)
393  {  {
394          uint16 pixel;          uint16 pixel;
395          uint16 value;          uint16 value;
396            PixelColour pc;
397    
398          while (out < end)          if (g_xserver_be)
399          {          {
400                  pixel = *(data++);                  while (out < end)
   
                 if (g_host_be)  
                 {  
                         BSWAP16(pixel);  
                 }  
   
                 value = make_colour(split_colour15(pixel));  
   
                 if (g_xserver_be)  
401                  {                  {
402                          *(out++) = value >> 8;                          pixel = *(data++);
403                          *(out++) = value;                          if (g_host_be)
404                            {
405                                    BSWAP16(pixel);
406                            }
407                            SPLITCOLOUR15(pixel, pc);
408                            value = MAKECOLOUR(pc);
409                            BOUT16(out, value);
410                  }                  }
411                  else          }
412            else
413            {
414                    while (out < end)
415                  {                  {
416                          *(out++) = value;                          pixel = *(data++);
417                          *(out++) = value >> 8;                          if (g_host_be)
418                            {
419                                    BSWAP16(pixel);
420                            }
421                            SPLITCOLOUR15(pixel, pc);
422                            value = MAKECOLOUR(pc);
423                            LOUT16(out, value);
424                  }                  }
425          }          }
426  }  }
427    
428  static void  static void
429  translate15to24(uint16 * data, uint8 * out, uint8 * end)  translate15to24(const uint16 * data, uint8 * out, uint8 * end)
430  {  {
431          uint32 value;          uint32 value;
432          uint16 pixel;          uint16 pixel;
433            PixelColour pc;
434    
435          while (out < end)          if (g_arch_match)
436          {          {
437                  pixel = *(data++);                  /* *INDENT-OFF* */
438                    REPEAT3
439                  if (g_host_be)                  (
440                  {                          pixel = *(data++);
441                          BSWAP16(pixel);                          SPLITCOLOUR15(pixel, pc);
442                  }                          *(out++) = pc.blue;
443                            *(out++) = pc.green;
444                  value = make_colour(split_colour15(pixel));                          *(out++) = pc.red;
445                  if (g_xserver_be)                  )
446                    /* *INDENT-ON* */
447            }
448            else if (g_xserver_be)
449            {
450                    while (out < end)
451                  {                  {
452                          *(out++) = value >> 16;                          pixel = *(data++);
453                          *(out++) = value >> 8;                          if (g_host_be)
454                          *(out++) = value;                          {
455                                    BSWAP16(pixel);
456                            }
457                            SPLITCOLOUR15(pixel, pc);
458                            value = MAKECOLOUR(pc);
459                            BOUT24(out, value);
460                  }                  }
461                  else          }
462            else
463            {
464                    while (out < end)
465                  {                  {
466                          *(out++) = value;                          pixel = *(data++);
467                          *(out++) = value >> 8;                          if (g_host_be)
468                          *(out++) = value >> 16;                          {
469                                    BSWAP16(pixel);
470                            }
471                            SPLITCOLOUR15(pixel, pc);
472                            value = MAKECOLOUR(pc);
473                            LOUT24(out, value);
474                  }                  }
475          }          }
476  }  }
477    
478  static void  static void
479  translate15to32(uint16 * data, uint8 * out, uint8 * end)  translate15to32(const uint16 * data, uint8 * out, uint8 * end)
480  {  {
481          uint16 pixel;          uint16 pixel;
482          uint32 value;          uint32 value;
483            PixelColour pc;
484    
485          while (out < end)          if (g_arch_match)
486          {          {
487                  pixel = *(data++);                  /* *INDENT-OFF* */
488                    REPEAT4
489                  if (g_host_be)                  (
490                  {                          pixel = *(data++);
491                          BSWAP16(pixel);                          SPLITCOLOUR15(pixel, pc);
492                  }                          *(out++) = pc.blue;
493                            *(out++) = pc.green;
494                  value = make_colour(split_colour15(pixel));                          *(out++) = pc.red;
495                            *(out++) = 0;
496                  if (g_xserver_be)                  )
497                    /* *INDENT-ON* */
498            }
499            else if (g_xserver_be)
500            {
501                    while (out < end)
502                  {                  {
503                          *(out++) = value >> 24;                          pixel = *(data++);
504                          *(out++) = value >> 16;                          if (g_host_be)
505                          *(out++) = value >> 8;                          {
506                          *(out++) = value;                                  BSWAP16(pixel);
507                            }
508                            SPLITCOLOUR15(pixel, pc);
509                            value = MAKECOLOUR(pc);
510                            BOUT32(out, value);
511                  }                  }
512                  else          }
513            else
514            {
515                    while (out < end)
516                  {                  {
517                          *(out++) = value;                          pixel = *(data++);
518                          *(out++) = value >> 8;                          if (g_host_be)
519                          *(out++) = value >> 16;                          {
520                          *(out++) = value >> 24;                                  BSWAP16(pixel);
521                            }
522                            SPLITCOLOUR15(pixel, pc);
523                            value = MAKECOLOUR(pc);
524                            LOUT32(out, value);
525                  }                  }
526          }          }
527  }  }
528    
529  static void  static void
530  translate16to16(uint16 * data, uint8 * out, uint8 * end)  translate16to16(const uint16 * data, uint8 * out, uint8 * end)
531  {  {
532          uint16 pixel;          uint16 pixel;
533          uint16 value;          uint16 value;
534            PixelColour pc;
535    
536          while (out < end)          if (g_xserver_be)
537          {          {
                 pixel = *(data++);  
   
538                  if (g_host_be)                  if (g_host_be)
539                  {                  {
540                          BSWAP16(pixel);                          while (out < end)
541                            {
542                                    pixel = *(data++);
543                                    BSWAP16(pixel);
544                                    SPLITCOLOUR16(pixel, pc);
545                                    value = MAKECOLOUR(pc);
546                                    BOUT16(out, value);
547                            }
548                  }                  }
549                    else
550                  value = make_colour(split_colour16(pixel));                  {
551                            while (out < end)
552                  if (g_xserver_be)                          {
553                                    pixel = *(data++);
554                                    SPLITCOLOUR16(pixel, pc);
555                                    value = MAKECOLOUR(pc);
556                                    BOUT16(out, value);
557                            }
558                    }
559            }
560            else
561            {
562                    if (g_host_be)
563                  {                  {
564                          *(out++) = value >> 8;                          while (out < end)
565                          *(out++) = value;                          {
566                                    pixel = *(data++);
567                                    BSWAP16(pixel);
568                                    SPLITCOLOUR16(pixel, pc);
569                                    value = MAKECOLOUR(pc);
570                                    LOUT16(out, value);
571                            }
572                  }                  }
573                  else                  else
574                  {                  {
575                          *(out++) = value;                          while (out < end)
576                          *(out++) = value >> 8;                          {
577                                    pixel = *(data++);
578                                    SPLITCOLOUR16(pixel, pc);
579                                    value = MAKECOLOUR(pc);
580                                    LOUT16(out, value);
581                            }
582                  }                  }
583          }          }
584  }  }
585    
586  static void  static void
587  translate16to24(uint16 * data, uint8 * out, uint8 * end)  translate16to24(const uint16 * data, uint8 * out, uint8 * end)
588  {  {
589          uint32 value;          uint32 value;
590          uint16 pixel;          uint16 pixel;
591            PixelColour pc;
592    
593          while (out < end)          if (g_arch_match)
594            {
595                    /* *INDENT-OFF* */
596                    REPEAT3
597                    (
598                            pixel = *(data++);
599                            SPLITCOLOUR16(pixel, pc);
600                            *(out++) = pc.blue;
601                            *(out++) = pc.green;
602                            *(out++) = pc.red;
603                    )
604                    /* *INDENT-ON* */
605            }
606            else if (g_xserver_be)
607          {          {
                 pixel = *(data++);  
   
608                  if (g_host_be)                  if (g_host_be)
609                  {                  {
610                          BSWAP16(pixel);                          while (out < end)
611                            {
612                                    pixel = *(data++);
613                                    BSWAP16(pixel);
614                                    SPLITCOLOUR16(pixel, pc);
615                                    value = MAKECOLOUR(pc);
616                                    BOUT24(out, value);
617                            }
618                  }                  }
619                    else
620                  value = make_colour(split_colour16(pixel));                  {
621                            while (out < end)
622                  if (g_xserver_be)                          {
623                                    pixel = *(data++);
624                                    SPLITCOLOUR16(pixel, pc);
625                                    value = MAKECOLOUR(pc);
626                                    BOUT24(out, value);
627                            }
628                    }
629            }
630            else
631            {
632                    if (g_host_be)
633                  {                  {
634                          *(out++) = value >> 16;                          while (out < end)
635                          *(out++) = value >> 8;                          {
636                          *(out++) = value;                                  pixel = *(data++);
637                                    BSWAP16(pixel);
638                                    SPLITCOLOUR16(pixel, pc);
639                                    value = MAKECOLOUR(pc);
640                                    LOUT24(out, value);
641                            }
642                  }                  }
643                  else                  else
644                  {                  {
645                          *(out++) = value;                          while (out < end)
646                          *(out++) = value >> 8;                          {
647                          *(out++) = value >> 16;                                  pixel = *(data++);
648                                    SPLITCOLOUR16(pixel, pc);
649                                    value = MAKECOLOUR(pc);
650                                    LOUT24(out, value);
651                            }
652                  }                  }
653          }          }
654  }  }
655    
656  static void  static void
657  translate16to32(uint16 * data, uint8 * out, uint8 * end)  translate16to32(const uint16 * data, uint8 * out, uint8 * end)
658  {  {
659          uint16 pixel;          uint16 pixel;
660          uint32 value;          uint32 value;
661            PixelColour pc;
662    
663          while (out < end)          if (g_arch_match)
664            {
665                    /* *INDENT-OFF* */
666                    REPEAT4
667                    (
668                            pixel = *(data++);
669                            SPLITCOLOUR16(pixel, pc);
670                            *(out++) = pc.blue;
671                            *(out++) = pc.green;
672                            *(out++) = pc.red;
673                            *(out++) = 0;
674                    )
675                    /* *INDENT-ON* */
676            }
677            else if (g_xserver_be)
678          {          {
                 pixel = *(data++);  
   
679                  if (g_host_be)                  if (g_host_be)
680                  {                  {
681                          BSWAP16(pixel);                          while (out < end)
682                            {
683                                    pixel = *(data++);
684                                    BSWAP16(pixel);
685                                    SPLITCOLOUR16(pixel, pc);
686                                    value = MAKECOLOUR(pc);
687                                    BOUT32(out, value);
688                            }
689                  }                  }
690                    else
691                  value = make_colour(split_colour16(pixel));                  {
692                            while (out < end)
693                  if (g_xserver_be)                          {
694                                    pixel = *(data++);
695                                    SPLITCOLOUR16(pixel, pc);
696                                    value = MAKECOLOUR(pc);
697                                    BOUT32(out, value);
698                            }
699                    }
700            }
701            else
702            {
703                    if (g_host_be)
704                  {                  {
705                          *(out++) = value >> 24;                          while (out < end)
706                          *(out++) = value >> 16;                          {
707                          *(out++) = value >> 8;                                  pixel = *(data++);
708                          *(out++) = value;                                  BSWAP16(pixel);
709                                    SPLITCOLOUR16(pixel, pc);
710                                    value = MAKECOLOUR(pc);
711                                    LOUT32(out, value);
712                            }
713                  }                  }
714                  else                  else
715                  {                  {
716                          *(out++) = value;                          while (out < end)
717                          *(out++) = value >> 8;                          {
718                          *(out++) = value >> 16;                                  pixel = *(data++);
719                          *(out++) = value >> 24;                                  SPLITCOLOUR16(pixel, pc);
720                                    value = MAKECOLOUR(pc);
721                                    LOUT32(out, value);
722                            }
723                  }                  }
724          }          }
725  }  }
726    
727  static void  static void
728  translate24to16(uint8 * data, uint8 * out, uint8 * end)  translate24to16(const uint8 * data, uint8 * out, uint8 * end)
729  {  {
730          uint32 pixel = 0;          uint32 pixel = 0;
731          uint16 value;          uint16 value;
732            PixelColour pc;
733    
734          while (out < end)          while (out < end)
735          {          {
736                  pixel = *(data++) << 16;                  pixel = *(data++) << 16;
737                  pixel |= *(data++) << 8;                  pixel |= *(data++) << 8;
738                  pixel |= *(data++);                  pixel |= *(data++);
739                    SPLITCOLOUR24(pixel, pc);
740                  value = (uint16) make_colour(split_colour24(pixel));                  value = MAKECOLOUR(pc);
   
741                  if (g_xserver_be)                  if (g_xserver_be)
742                  {                  {
743                          *(out++) = value >> 8;                          BOUT16(out, value);
                         *(out++) = value;  
744                  }                  }
745                  else                  else
746                  {                  {
747                          *(out++) = value;                          LOUT16(out, value);
                         *(out++) = value >> 8;  
748                  }                  }
749          }          }
750  }  }
751    
752  static void  static void
753  translate24to24(uint8 * data, uint8 * out, uint8 * end)  translate24to24(const uint8 * data, uint8 * out, uint8 * end)
754  {  {
755          uint32 pixel;          uint32 pixel;
756          uint32 value;          uint32 value;
757            PixelColour pc;
758    
759          while (out < end)          if (g_xserver_be)
760          {          {
761                  pixel = *(data++) << 16;                  while (out < end)
                 pixel |= *(data++) << 8;  
                 pixel |= *(data++);  
   
                 value = make_colour(split_colour24(pixel));  
   
                 if (g_xserver_be)  
762                  {                  {
763                          *(out++) = value >> 16;                          pixel = *(data++) << 16;
764                          *(out++) = value >> 8;                          pixel |= *(data++) << 8;
765                          *(out++) = value;                          pixel |= *(data++);
766                            SPLITCOLOUR24(pixel, pc);
767                            value = MAKECOLOUR(pc);
768                            BOUT24(out, value);
769                  }                  }
770                  else          }
771            else
772            {
773                    while (out < end)
774                  {                  {
775                          *(out++) = value;                          pixel = *(data++) << 16;
776                          *(out++) = value >> 8;                          pixel |= *(data++) << 8;
777                          *(out++) = value >> 16;                          pixel |= *(data++);
778                            SPLITCOLOUR24(pixel, pc);
779                            value = MAKECOLOUR(pc);
780                            LOUT24(out, value);
781                  }                  }
782          }          }
783  }  }
784    
785  static void  static void
786  translate24to32(uint8 * data, uint8 * out, uint8 * end)  translate24to32(const uint8 * data, uint8 * out, uint8 * end)
787  {  {
788          uint32 pixel;          uint32 pixel;
789          uint32 value;          uint32 value;
790            PixelColour pc;
791    
792          while (out < end)          if (g_arch_match)
793          {          {
794                  pixel = *(data++) << 16;                  /* *INDENT-OFF* */
795                  pixel |= *(data++) << 8;  #ifdef NEED_ALIGN
796                  pixel |= *(data++);                  REPEAT4
797                    (
798                  value = make_colour(split_colour24(pixel));                          *(out++) = *(data++);
799                            *(out++) = *(data++);
800                  if (g_xserver_be)                          *(out++) = *(data++);
801                            *(out++) = 0;
802                    )
803    #else
804                    REPEAT4
805                    (
806                            *((uint32 *) out) = *((uint32 *) data);
807                            out += 4;
808                            data += 3;
809                    )
810    #endif
811                    /* *INDENT-ON* */
812            }
813            else if (g_xserver_be)
814            {
815                    while (out < end)
816                  {                  {
817                          *(out++) = value >> 24;                          pixel = *(data++) << 16;
818                          *(out++) = value >> 16;                          pixel |= *(data++) << 8;
819                          *(out++) = value >> 8;                          pixel |= *(data++);
820                          *(out++) = value;                          SPLITCOLOUR24(pixel, pc);
821                            value = MAKECOLOUR(pc);
822                            BOUT32(out, value);
823                  }                  }
824                  else          }
825            else
826            {
827                    while (out < end)
828                  {                  {
829                          *(out++) = value;                          pixel = *(data++) << 16;
830                          *(out++) = value >> 8;                          pixel |= *(data++) << 8;
831                          *(out++) = value >> 16;                          pixel |= *(data++);
832                          *(out++) = value >> 24;                          SPLITCOLOUR24(pixel, pc);
833                            value = MAKECOLOUR(pc);
834                            LOUT32(out, value);
835                  }                  }
836          }          }
837  }  }
# Line 629  translate_image(int width, int height, u Line 852  translate_image(int width, int height, u
852                          return data;                          return data;
853                  if (g_depth == 16 && g_server_bpp == 16)                  if (g_depth == 16 && g_server_bpp == 16)
854                          return data;                          return data;
855                    if (g_depth == 24 && g_bpp == 24 && g_server_bpp == 24)
856                            return data;
857          }          }
858    
859          size = width * height * (g_bpp / 8);          size = width * height * (g_bpp / 8);
# Line 802  ui_init(void) Line 1027  ui_init(void)
1027                  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);
1028                  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);
1029    
1030                  /* if RGB video and averything is little endian */                  /* if RGB video and everything is little endian */
1031                  if (vi.red_mask > vi.green_mask && vi.green_mask > vi.blue_mask)                  if ((vi.red_mask > vi.green_mask && vi.green_mask > vi.blue_mask) &&
1032                          if (!g_xserver_be && !g_host_be)                      !g_xserver_be && !g_host_be)
1033                    {
1034                            if (g_depth <= 16 || (g_red_shift_l == 16 && g_green_shift_l == 8 &&
1035                                                  g_blue_shift_l == 0))
1036                            {
1037                                  g_arch_match = True;                                  g_arch_match = True;
1038                            }
1039                    }
1040    
1041                    if (g_arch_match)
1042                    {
1043                            DEBUG(("Architectures match, enabling little endian optimisations.\n"));
1044                    }
1045          }          }
1046    
1047          pfm = XListPixmapFormats(g_display, &i);          pfm = XListPixmapFormats(g_display, &i);
# Line 856  ui_init(void) Line 1092  ui_init(void)
1092          else if (g_width < 0)          else if (g_width < 0)
1093          {          {
1094                  /* Percent of screen */                  /* Percent of screen */
1095                    if (-g_width >= 100)
1096                            g_using_full_workarea = True;
1097                  g_height = HeightOfScreen(g_screen) * (-g_width) / 100;                  g_height = HeightOfScreen(g_screen) * (-g_width) / 100;
1098                  g_width = WidthOfScreen(g_screen) * (-g_width) / 100;                  g_width = WidthOfScreen(g_screen) * (-g_width) / 100;
1099          }          }
# Line 863  ui_init(void) Line 1101  ui_init(void)
1101          {          {
1102                  /* Fetch geometry from _NET_WORKAREA */                  /* Fetch geometry from _NET_WORKAREA */
1103                  uint32 x, y, cx, cy;                  uint32 x, y, cx, cy;
1104                    g_using_full_workarea = True;
1105    
1106                  if (get_current_workarea(&x, &y, &cx, &cy) == 0)                  if (get_current_workarea(&x, &y, &cx, &cy) == 0)
1107                  {                  {
# Line 917  BOOL Line 1156  BOOL
1156  ui_create_window(void)  ui_create_window(void)
1157  {  {
1158          uint8 null_pointer_mask[1] = { 0x80 };          uint8 null_pointer_mask[1] = { 0x80 };
1159          uint8 null_pointer_data[4] = { 0x00, 0x00, 0x00, 0x00 };          uint8 null_pointer_data[24] = { 0x00 };
1160    
1161          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
1162          XClassHint *classhints;          XClassHint *classhints;
1163          XSizeHints *sizehints;          XSizeHints *sizehints;
# Line 928  ui_create_window(void) Line 1168  ui_create_window(void)
1168          wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;          wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;
1169          wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;          wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;
1170    
1171            /* Handle -x-y portion of geometry string */
1172            if (g_xpos < 0 || (g_xpos == 0 && (g_pos & 2)))
1173                    g_xpos = WidthOfScreen(g_screen) + g_xpos - g_width;
1174            if (g_ypos < 0 || (g_ypos == 0 && (g_pos & 4)))
1175                    g_ypos = HeightOfScreen(g_screen) + g_ypos - g_height;
1176    
1177          attribs.background_pixel = BlackPixelOfScreen(g_screen);          attribs.background_pixel = BlackPixelOfScreen(g_screen);
1178          attribs.border_pixel = WhitePixelOfScreen(g_screen);          attribs.border_pixel = WhitePixelOfScreen(g_screen);
1179          attribs.backing_store = g_ownbackstore ? NotUseful : Always;          attribs.backing_store = g_ownbackstore ? NotUseful : Always;
1180          attribs.override_redirect = g_fullscreen;          attribs.override_redirect = g_fullscreen;
1181          attribs.colormap = g_xcolmap;          attribs.colormap = g_xcolmap;
1182    
1183          g_wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), 0, 0, wndwidth, wndheight,          g_wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), g_xpos, g_ypos, wndwidth,
1184                                0, g_depth, InputOutput, g_visual,                                wndheight, 0, g_depth, InputOutput, g_visual,
1185                                CWBackPixel | CWBackingStore | CWOverrideRedirect |                                CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
1186                                CWColormap | CWBorderPixel, &attribs);                                CWBorderPixel, &attribs);
1187    
1188          if (g_gc == NULL)          if (g_gc == NULL)
1189                  g_gc = XCreateGC(g_display, g_wnd, 0, NULL);                  g_gc = XCreateGC(g_display, g_wnd, 0, NULL);
1190    
1191            if (g_create_bitmap_gc == NULL)
1192                    g_create_bitmap_gc = XCreateGC(g_display, g_wnd, 0, NULL);
1193    
1194          if ((g_ownbackstore) && (g_backstore == 0))          if ((g_ownbackstore) && (g_backstore == 0))
1195          {          {
1196                  g_backstore = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);                  g_backstore = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
# Line 968  ui_create_window(void) Line 1217  ui_create_window(void)
1217          if (sizehints)          if (sizehints)
1218          {          {
1219                  sizehints->flags = PMinSize | PMaxSize;                  sizehints->flags = PMinSize | PMaxSize;
1220                    if (g_pos)
1221                            sizehints->flags |= PPosition;
1222                  sizehints->min_width = sizehints->max_width = g_width;                  sizehints->min_width = sizehints->max_width = g_width;
1223                  sizehints->min_height = sizehints->max_height = g_height;                  sizehints->min_height = sizehints->max_height = g_height;
1224                  XSetWMNormalHints(g_display, g_wnd, sizehints);                  XSetWMNormalHints(g_display, g_wnd, sizehints);
# Line 980  ui_create_window(void) Line 1231  ui_create_window(void)
1231          }          }
1232    
1233          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
1234                  VisibilityChangeMask | FocusChangeMask;                  VisibilityChangeMask | FocusChangeMask | StructureNotifyMask;
1235    
1236          if (g_sendmotion)          if (g_sendmotion)
1237                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
# Line 1031  void Line 1282  void
1282  ui_resize_window()  ui_resize_window()
1283  {  {
1284          XSizeHints *sizehints;          XSizeHints *sizehints;
1285            Pixmap bs;
1286    
1287          sizehints = XAllocSizeHints();          sizehints = XAllocSizeHints();
1288          if (sizehints)          if (sizehints)
# Line 1046  ui_resize_window() Line 1298  ui_resize_window()
1298          {          {
1299                  XResizeWindow(g_display, g_wnd, g_width, g_height);                  XResizeWindow(g_display, g_wnd, g_width, g_height);
1300          }          }
1301    
1302            /* create new backstore pixmap */
1303            if (g_backstore != 0)
1304            {
1305                    bs = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
1306                    XSetForeground(g_display, g_gc, BlackPixelOfScreen(g_screen));
1307                    XFillRectangle(g_display, bs, g_gc, 0, 0, g_width, g_height);
1308                    XCopyArea(g_display, g_backstore, bs, g_gc, 0, 0, g_width, g_height, 0, 0);
1309                    XFreePixmap(g_display, g_backstore);
1310                    g_backstore = bs;
1311            }
1312  }  }
1313    
1314  void  void
# Line 1082  xwin_toggle_fullscreen(void) Line 1345  xwin_toggle_fullscreen(void)
1345          }          }
1346  }  }
1347    
1348  /* Process all events in Xlib queue  static void
1349    handle_button_event(XEvent xevent, BOOL down)
1350    {
1351            uint16 button, flags = 0;
1352            g_last_gesturetime = xevent.xbutton.time;
1353            button = xkeymap_translate_button(xevent.xbutton.button);
1354            if (button == 0)
1355                    return;
1356    
1357            if (down)
1358                    flags = MOUSE_FLAG_DOWN;
1359    
1360            /* Stop moving window when button is released, regardless of cursor position */
1361            if (g_moving_wnd && (xevent.type == ButtonRelease))
1362                    g_moving_wnd = False;
1363    
1364            /* If win_button_size is nonzero, enable single app mode */
1365            if (xevent.xbutton.y < g_win_button_size)
1366            {
1367                    /*  Check from right to left: */
1368                    if (xevent.xbutton.x >= g_width - g_win_button_size)
1369                    {
1370                            /* The close button, continue */
1371                            ;
1372                    }
1373                    else if (xevent.xbutton.x >= g_width - g_win_button_size * 2)
1374                    {
1375                            /* The maximize/restore button. Do not send to
1376                               server.  It might be a good idea to change the
1377                               cursor or give some other visible indication
1378                               that rdesktop inhibited this click */
1379                            if (xevent.type == ButtonPress)
1380                                    return;
1381                    }
1382                    else if (xevent.xbutton.x >= g_width - g_win_button_size * 3)
1383                    {
1384                            /* The minimize button. Iconify window. */
1385                            if (xevent.type == ButtonRelease)
1386                            {
1387                                    /* Release the mouse button outside the minimize button, to prevent the
1388                                       actual minimazation to happen */
1389                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE, button, 1, 1);
1390                                    XIconifyWindow(g_display, g_wnd, DefaultScreen(g_display));
1391                                    return;
1392                            }
1393                    }
1394                    else if (xevent.xbutton.x <= g_win_button_size)
1395                    {
1396                            /* The system menu. Ignore. */
1397                            if (xevent.type == ButtonPress)
1398                                    return;
1399                    }
1400                    else
1401                    {
1402                            /* The title bar. */
1403                            if (xevent.type == ButtonPress)
1404                            {
1405                                    if (!g_fullscreen && g_hide_decorations && !g_using_full_workarea)
1406                                    {
1407                                            g_moving_wnd = True;
1408                                            g_move_x_offset = xevent.xbutton.x;
1409                                            g_move_y_offset = xevent.xbutton.y;
1410                                    }
1411                                    return;
1412                            }
1413                    }
1414            }
1415    
1416            rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1417                           flags | button, xevent.xbutton.x, xevent.xbutton.y);
1418    }
1419    
1420    /* Process events in Xlib queue
1421     Returns 0 after user quit, 1 otherwise */     Returns 0 after user quit, 1 otherwise */
1422  static int  static int
1423  xwin_process_events(void)  xwin_process_events(void)
1424  {  {
1425          XEvent xevent;          XEvent xevent;
1426          KeySym keysym;          KeySym keysym;
         uint16 button, flags;  
1427          uint32 ev_time;          uint32 ev_time;
         key_translation tr;  
1428          char str[256];          char str[256];
1429          Status status;          Status status;
1430            int events = 0;
1431    
1432          while (XPending(g_display) > 0)          while ((XPending(g_display) > 0) && events++ < 20)
1433          {          {
1434                  XNextEvent(g_display, &xevent);                  XNextEvent(g_display, &xevent);
1435    
# Line 1105  xwin_process_events(void) Line 1439  xwin_process_events(void)
1439                          continue;                          continue;
1440                  }                  }
1441    
                 flags = 0;  
   
1442                  switch (xevent.type)                  switch (xevent.type)
1443                  {                  {
1444                          case VisibilityNotify:                          case VisibilityNotify:
# Line 1143  xwin_process_events(void) Line 1475  xwin_process_events(void)
1475                                                        str, sizeof(str), &keysym, NULL);                                                        str, sizeof(str), &keysym, NULL);
1476                                  }                                  }
1477    
1478                                  DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,                                  DEBUG_KBD(("KeyPress for keysym (0x%lx, %s)\n", keysym,
1479                                             get_ksname(keysym)));                                             get_ksname(keysym)));
1480    
1481                                  ev_time = time(NULL);                                  ev_time = time(NULL);
1482                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
1483                                          break;                                          break;
1484    
1485                                  tr = xkeymap_translate_key(keysym,                                  xkeymap_send_keys(keysym, xevent.xkey.keycode, xevent.xkey.state,
1486                                                             xevent.xkey.keycode, xevent.xkey.state);                                                    ev_time, True, 0);
   
                                 if (tr.scancode == 0)  
                                         break;  
   
                                 save_remote_modifiers(tr.scancode);  
                                 ensure_remote_modifiers(ev_time, tr);  
                                 rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);  
                                 restore_remote_modifiers(ev_time, tr.scancode);  
   
1487                                  break;                                  break;
1488    
1489                          case KeyRelease:                          case KeyRelease:
# Line 1168  xwin_process_events(void) Line 1491  xwin_process_events(void)
1491                                  XLookupString((XKeyEvent *) & xevent, str,                                  XLookupString((XKeyEvent *) & xevent, str,
1492                                                sizeof(str), &keysym, NULL);                                                sizeof(str), &keysym, NULL);
1493    
1494                                  DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,                                  DEBUG_KBD(("\nKeyRelease for keysym (0x%lx, %s)\n", keysym,
1495                                             get_ksname(keysym)));                                             get_ksname(keysym)));
1496    
1497                                  ev_time = time(NULL);                                  ev_time = time(NULL);
1498                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))                                  if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
1499                                          break;                                          break;
1500    
1501                                  tr = xkeymap_translate_key(keysym,                                  xkeymap_send_keys(keysym, xevent.xkey.keycode, xevent.xkey.state,
1502                                                             xevent.xkey.keycode, xevent.xkey.state);                                                    ev_time, False, 0);
   
                                 if (tr.scancode == 0)  
                                         break;  
   
                                 rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);  
1503                                  break;                                  break;
1504    
1505                          case ButtonPress:                          case ButtonPress:
1506                                  flags = MOUSE_FLAG_DOWN;                                  handle_button_event(xevent, True);
1507                                  /* fall through */                                  break;
1508    
1509                          case ButtonRelease:                          case ButtonRelease:
1510                                  g_last_gesturetime = xevent.xbutton.time;                                  handle_button_event(xevent, False);
                                 button = xkeymap_translate_button(xevent.xbutton.button);  
                                 if (button == 0)  
                                         break;  
   
                                 /* If win_button_size is nonzero, enable single app mode */  
                                 if (xevent.xbutton.y < g_win_button_size)  
                                 {  
                                         /* Stop moving window when button is released, regardless of cursor position */  
                                         if (g_moving_wnd && (xevent.type == ButtonRelease))  
                                                 g_moving_wnd = False;  
   
                                         /*  Check from right to left: */  
   
                                         if (xevent.xbutton.x >= g_width - g_win_button_size)  
                                         {  
                                                 /* The close button, continue */  
                                                 ;  
                                         }  
                                         else if (xevent.xbutton.x >=  
                                                  g_width - g_win_button_size * 2)  
                                         {  
                                                 /* The maximize/restore button. Do not send to  
                                                    server.  It might be a good idea to change the  
                                                    cursor or give some other visible indication  
                                                    that rdesktop inhibited this click */  
                                                 break;  
                                         }  
                                         else if (xevent.xbutton.x >=  
                                                  g_width - g_win_button_size * 3)  
                                         {  
                                                 /* The minimize button. Iconify window. */  
                                                 XIconifyWindow(g_display, g_wnd,  
                                                                DefaultScreen(g_display));  
                                                 break;  
                                         }  
                                         else if (xevent.xbutton.x <= g_win_button_size)  
                                         {  
                                                 /* The system menu. Ignore. */  
                                                 break;  
                                         }  
                                         else  
                                         {  
                                                 /* The title bar. */  
                                                 if ((xevent.type == ButtonPress) && !g_fullscreen  
                                                     && g_hide_decorations)  
                                                 {  
                                                         g_moving_wnd = True;  
                                                         g_move_x_offset = xevent.xbutton.x;  
                                                         g_move_y_offset = xevent.xbutton.y;  
                                                 }  
                                                 break;  
   
                                         }  
                                 }  
   
                                 rdp_send_input(time(NULL), RDP_INPUT_MOUSE,  
                                                flags | button, xevent.xbutton.x, xevent.xbutton.y);  
1511                                  break;                                  break;
1512    
1513                          case MotionNotify:                          case MotionNotify:
# Line 1339  xwin_process_events(void) Line 1600  xwin_process_events(void)
1600                          case PropertyNotify:                          case PropertyNotify:
1601                                  xclip_handle_PropertyNotify(&xevent.xproperty);                                  xclip_handle_PropertyNotify(&xevent.xproperty);
1602                                  break;                                  break;
1603                            case MapNotify:
1604                                    rdp_send_client_window_status(1);
1605                                    break;
1606                            case UnmapNotify:
1607                                    rdp_send_client_window_status(0);
1608                                    break;
1609                  }                  }
1610          }          }
1611          /* Keep going */          /* Keep going */
# Line 1390  ui_select(int rdp_socket) Line 1657  ui_select(int rdp_socket)
1657                                  error("select: %s\n", strerror(errno));                                  error("select: %s\n", strerror(errno));
1658    
1659                          case 0:                          case 0:
1660                                  /* TODO: if tv.tv_sec just times out                                  /* Abort serial read calls */
1661                                   * we will segfault.                                  if (s_timeout)
1662                                   * FIXME:                                          rdpdr_check_fds(&rfds, &wfds, (BOOL) True);
                                  */  
                                 //s_timeout = True;  
                                 //rdpdr_check_fds(&rfds, &wfds, (BOOL) True);  
1663                                  continue;                                  continue;
1664                  }                  }
1665    
# Line 1442  ui_create_bitmap(int width, int height, Line 1706  ui_create_bitmap(int width, int height,
1706          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1707                               (char *) tdata, width, height, bitmap_pad, 0);                               (char *) tdata, width, height, bitmap_pad, 0);
1708    
1709          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);
1710    
1711          XFree(image);          XFree(image);
1712          if (tdata != data)          if (tdata != data)
# Line 1500  ui_create_glyph(int width, int height, u Line 1764  ui_create_glyph(int width, int height, u
1764          XImage *image;          XImage *image;
1765          Pixmap bitmap;          Pixmap bitmap;
1766          int scanline;          int scanline;
         GC gc;  
1767    
1768          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1769    
1770          bitmap = XCreatePixmap(g_display, g_wnd, width, height, 1);          bitmap = XCreatePixmap(g_display, g_wnd, width, height, 1);
1771          gc = XCreateGC(g_display, bitmap, 0, NULL);          if (g_create_glyph_gc == 0)
1772                    g_create_glyph_gc = XCreateGC(g_display, bitmap, 0, NULL);
1773    
1774          image = XCreateImage(g_display, g_visual, 1, ZPixmap, 0, (char *) data,          image = XCreateImage(g_display, g_visual, 1, ZPixmap, 0, (char *) data,
1775                               width, height, 8, scanline);                               width, height, 8, scanline);
# Line 1513  ui_create_glyph(int width, int height, u Line 1777  ui_create_glyph(int width, int height, u
1777          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
1778          XInitImage(image);          XInitImage(image);
1779    
1780          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);
1781    
1782          XFree(image);          XFree(image);
         XFreeGC(g_display, gc);  
1783          return (HGLYPH) bitmap;          return (HGLYPH) bitmap;
1784  }  }
1785    
# Line 1945  ui_rect( Line 2208  ui_rect(
2208          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
2209  }  }
2210    
2211    void
2212    ui_polygon(uint8 opcode,
2213               /* mode */ uint8 fillmode,
2214               /* dest */ POINT * point, int npoints,
2215               /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2216    {
2217            uint8 style, i, ipattern[8];
2218            Pixmap fill;
2219    
2220            SET_FUNCTION(opcode);
2221    
2222            switch (fillmode)
2223            {
2224                    case ALTERNATE:
2225                            XSetFillRule(g_display, g_gc, EvenOddRule);
2226                            break;
2227                    case WINDING:
2228                            XSetFillRule(g_display, g_gc, WindingRule);
2229                            break;
2230                    default:
2231                            unimpl("fill mode %d\n", fillmode);
2232            }
2233    
2234            if (brush)
2235                    style = brush->style;
2236            else
2237                    style = 0;
2238    
2239            switch (style)
2240            {
2241                    case 0: /* Solid */
2242                            SET_FOREGROUND(fgcolour);
2243                            FILL_POLYGON((XPoint *) point, npoints);
2244                            break;
2245    
2246                    case 2: /* Hatch */
2247                            fill = (Pixmap) ui_create_glyph(8, 8,
2248                                                            hatch_patterns + brush->pattern[0] * 8);
2249                            SET_FOREGROUND(fgcolour);
2250                            SET_BACKGROUND(bgcolour);
2251                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2252                            XSetStipple(g_display, g_gc, fill);
2253                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2254                            FILL_POLYGON((XPoint *) point, npoints);
2255                            XSetFillStyle(g_display, g_gc, FillSolid);
2256                            XSetTSOrigin(g_display, g_gc, 0, 0);
2257                            ui_destroy_glyph((HGLYPH) fill);
2258                            break;
2259    
2260                    case 3: /* Pattern */
2261                            for (i = 0; i != 8; i++)
2262                                    ipattern[7 - i] = brush->pattern[i];
2263                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
2264                            SET_FOREGROUND(bgcolour);
2265                            SET_BACKGROUND(fgcolour);
2266                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2267                            XSetStipple(g_display, g_gc, fill);
2268                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2269                            FILL_POLYGON((XPoint *) point, npoints);
2270                            XSetFillStyle(g_display, g_gc, FillSolid);
2271                            XSetTSOrigin(g_display, g_gc, 0, 0);
2272                            ui_destroy_glyph((HGLYPH) fill);
2273                            break;
2274    
2275                    default:
2276                            unimpl("brush %d\n", brush->style);
2277            }
2278    
2279            RESET_FUNCTION(opcode);
2280    }
2281    
2282    void
2283    ui_polyline(uint8 opcode,
2284                /* dest */ POINT * points, int npoints,
2285                /* pen */ PEN * pen)
2286    {
2287            /* TODO: set join style */
2288            SET_FUNCTION(opcode);
2289            SET_FOREGROUND(pen->colour);
2290            XDrawLines(g_display, g_wnd, g_gc, (XPoint *) points, npoints, CoordModePrevious);
2291            if (g_ownbackstore)
2292                    XDrawLines(g_display, g_backstore, g_gc, (XPoint *) points, npoints,
2293                               CoordModePrevious);
2294            RESET_FUNCTION(opcode);
2295    }
2296    
2297    void
2298    ui_ellipse(uint8 opcode,
2299               /* mode */ uint8 fillmode,
2300               /* dest */ int x, int y, int cx, int cy,
2301               /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2302    {
2303            uint8 style, i, ipattern[8];
2304            Pixmap fill;
2305    
2306            SET_FUNCTION(opcode);
2307    
2308            if (brush)
2309                    style = brush->style;
2310            else
2311                    style = 0;
2312    
2313            switch (style)
2314            {
2315                    case 0: /* Solid */
2316                            SET_FOREGROUND(fgcolour);
2317                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2318                            break;
2319    
2320                    case 2: /* Hatch */
2321                            fill = (Pixmap) ui_create_glyph(8, 8,
2322                                                            hatch_patterns + brush->pattern[0] * 8);
2323                            SET_FOREGROUND(fgcolour);
2324                            SET_BACKGROUND(bgcolour);
2325                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2326                            XSetStipple(g_display, g_gc, fill);
2327                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2328                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2329                            XSetFillStyle(g_display, g_gc, FillSolid);
2330                            XSetTSOrigin(g_display, g_gc, 0, 0);
2331                            ui_destroy_glyph((HGLYPH) fill);
2332                            break;
2333    
2334                    case 3: /* Pattern */
2335                            for (i = 0; i != 8; i++)
2336                                    ipattern[7 - i] = brush->pattern[i];
2337                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
2338                            SET_FOREGROUND(bgcolour);
2339                            SET_BACKGROUND(fgcolour);
2340                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
2341                            XSetStipple(g_display, g_gc, fill);
2342                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
2343                            DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2344                            XSetFillStyle(g_display, g_gc, FillSolid);
2345                            XSetTSOrigin(g_display, g_gc, 0, 0);
2346                            ui_destroy_glyph((HGLYPH) fill);
2347                            break;
2348    
2349                    default:
2350                            unimpl("brush %d\n", brush->style);
2351            }
2352    
2353            RESET_FUNCTION(opcode);
2354    }
2355    
2356  /* warning, this function only draws on wnd or backstore, not both */  /* warning, this function only draws on wnd or backstore, not both */
2357  void  void
2358  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
# Line 2000  ui_draw_glyph(int mixmode, Line 2408  ui_draw_glyph(int mixmode,
2408  }  }
2409    
2410  void  void
2411  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,
2412               int clipx, int clipy, int clipcx, int clipcy,               int clipx, int clipy, int clipcx, int clipcy,
2413               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, BRUSH * brush,
2414               int fgcolour, uint8 * text, uint8 length)               int bgcolour, int fgcolour, uint8 * text, uint8 length)
2415  {  {
2416            /* TODO: use brush appropriately */
2417    
2418          FONTGLYPH *glyph;          FONTGLYPH *glyph;
2419          int i, j, xyoffset, x1, y1;          int i, j, xyoffset, x1, y1;
2420          DATABLOB *entry;          DATABLOB *entry;
# Line 2144  ui_desktop_restore(uint32 offset, int x, Line 2554  ui_desktop_restore(uint32 offset, int x,
2554    
2555          XFree(image);          XFree(image);
2556  }  }
2557    
2558    /* these do nothing here but are used in uiports */
2559    void
2560    ui_begin_update(void)
2561    {
2562    }
2563    
2564    void
2565    ui_end_update(void)
2566    {
2567    }

Legend:
Removed from v.697  
changed lines
  Added in v.991

  ViewVC Help
Powered by ViewVC 1.1.26