/[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 49 by mmihalik, Fri Apr 19 12:06:08 2002 UTC revision 519 by matthewc, Tue Oct 28 03:40:26 2003 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     User interface services - X Window System     User interface services - X Window System
4     Copyright (C) Matthew Chapman 1999-2001     Copyright (C) Matthew Chapman 1999-2002
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
8     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# Line 23  Line 23 
23  #include <time.h>  #include <time.h>
24  #include <errno.h>  #include <errno.h>
25  #include "rdesktop.h"  #include "rdesktop.h"
26    #include "xproto.h"
27    
28  extern char keymapname[16];  extern int g_width;
29  extern int keylayout;  extern int g_height;
30  extern int width;  extern BOOL g_sendmotion;
31  extern int height;  extern BOOL g_fullscreen;
32  extern BOOL sendmotion;  extern BOOL g_grab_keyboard;
33  extern BOOL fullscreen;  extern BOOL g_hide_decorations;
34    extern char g_title[];
35  static Display *display;  extern int g_server_bpp;
36  static int x_socket;  extern int g_win_button_size;
37  static Window wnd;  
38  static GC gc;  Display *g_display;
39  static Visual *visual;  Time g_last_gesturetime;
40  static int depth;  static int g_x_socket;
41  static int bpp;  static Screen *g_screen;
42    Window g_wnd;
43    BOOL g_enable_compose = False;
44    static GC g_gc;
45    static Visual *g_visual;
46    static int g_depth;
47    static int g_bpp;
48    static XIM g_IM;
49    static XIC g_IC;
50    static XModifierKeymap *g_mod_map;
51    static Cursor g_current_cursor;
52    static HCURSOR g_null_cursor;
53    static Atom g_protocol_atom, g_kill_atom;
54    static BOOL g_focused;
55    static BOOL g_mouse_in_wnd;
56    
57  /* endianness */  /* endianness */
58  static BOOL host_be;  static BOOL g_host_be;
59  static BOOL xserver_be;  static BOOL g_xserver_be;
60    
61  /* software backing store */  /* software backing store */
62  static BOOL ownbackstore;  static BOOL g_ownbackstore;
63  static Pixmap backstore;  static Pixmap g_backstore;
64    
65    /* Moving in single app mode */
66    static BOOL g_moving_wnd;
67    static int g_move_x_offset = 0;
68    static int g_move_y_offset = 0;
69    
70    #ifdef WITH_RDPSND
71    extern int g_dsp_fd;
72    extern BOOL g_dsp_busy;
73    extern BOOL g_rdpsnd;
74    #endif
75    
76    /* MWM decorations */
77    #define MWM_HINTS_DECORATIONS   (1L << 1)
78    #define PROP_MOTIF_WM_HINTS_ELEMENTS    5
79    typedef struct
80    {
81            uint32 flags;
82            uint32 functions;
83            uint32 decorations;
84            sint32 inputMode;
85            uint32 status;
86    }
87    PropMotifWmHints;
88    
89    typedef struct
90    {
91            uint32 red;
92            uint32 green;
93            uint32 blue;
94    }
95    PixelColour;
96    
97    
98  #define FILL_RECTANGLE(x,y,cx,cy)\  #define FILL_RECTANGLE(x,y,cx,cy)\
99  { \  { \
100          XFillRectangle(display, wnd, gc, x, y, cx, cy); \          XFillRectangle(g_display, g_wnd, g_gc, x, y, cx, cy); \
101          if (ownbackstore) \          if (g_ownbackstore) \
102                  XFillRectangle(display, backstore, gc, x, y, cx, cy); \                  XFillRectangle(g_display, g_backstore, g_gc, x, y, cx, cy); \
103    }
104    
105    #define FILL_RECTANGLE_BACKSTORE(x,y,cx,cy)\
106    { \
107            XFillRectangle(g_display, g_ownbackstore ? g_backstore : g_wnd, g_gc, x, y, cx, cy); \
108  }  }
109    
110  /* colour maps */  /* colour maps */
111  static BOOL owncolmap;  BOOL g_owncolmap = False;
112  static Colormap xcolmap;  static Colormap g_xcolmap;
113  static uint32 white;  static uint32 *g_colmap = NULL;
114  static uint32 *colmap;  
115    #define TRANSLATE(col)          ( g_server_bpp != 8 ? translate_colour(col) : g_owncolmap ? col : translate_colour(g_colmap[col]) )
116  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )  #define SET_FOREGROUND(col)     XSetForeground(g_display, g_gc, TRANSLATE(col));
117  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));  #define SET_BACKGROUND(col)     XSetBackground(g_display, g_gc, TRANSLATE(col));
 #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));  
118    
119  static int rop2_map[] = {  static int rop2_map[] = {
120          GXclear,                /* 0 */          GXclear,                /* 0 */
# Line 83  static int rop2_map[] = { Line 135  static int rop2_map[] = {
135          GXset                   /* 1 */          GXset                   /* 1 */
136  };  };
137    
138  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, rop2_map[rop2]); }
139  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, GXcopy); }
140    
141    static void
142    mwm_hide_decorations(void)
143    {
144            PropMotifWmHints motif_hints;
145            Atom hintsatom;
146    
147            /* setup the property */
148            motif_hints.flags = MWM_HINTS_DECORATIONS;
149            motif_hints.decorations = 0;
150    
151            /* get the atom for the property */
152            hintsatom = XInternAtom(g_display, "_MOTIF_WM_HINTS", False);
153            if (!hintsatom)
154            {
155                    warning("Failed to get atom _MOTIF_WM_HINTS: probably your window manager does not support MWM hints\n");
156                    return;
157            }
158    
159            XChangeProperty(g_display, g_wnd, hintsatom, hintsatom, 32, PropModeReplace,
160                            (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
161    }
162    
163    static PixelColour
164    split_colour15(uint32 colour)
165    {
166            PixelColour rv;
167            rv.red = (colour & 0x7c00) >> 10;
168            rv.red = (rv.red * 0xff) / 0x1f;
169            rv.green = (colour & 0x03e0) >> 5;
170            rv.green = (rv.green * 0xff) / 0x1f;
171            rv.blue = (colour & 0x1f);
172            rv.blue = (rv.blue * 0xff) / 0x1f;
173            return rv;
174    }
175    
176    static PixelColour
177    split_colour16(uint32 colour)
178    {
179            PixelColour rv;
180            rv.red = (colour & 0xf800) >> 11;
181            rv.red = (rv.red * 0xff) / 0x1f;
182            rv.green = (colour & 0x07e0) >> 5;
183            rv.green = (rv.green * 0xff) / 0x3f;
184            rv.blue = (colour & 0x001f);
185            rv.blue = (rv.blue * 0xff) / 0x1f;
186            return rv;
187    }
188    
189    static PixelColour
190    split_colour24(uint32 colour)
191    {
192            PixelColour rv;
193            rv.blue = (colour & 0xff0000) >> 16;
194            rv.green = (colour & 0xff00) >> 8;
195            rv.red = (colour & 0xff);
196            return rv;
197    }
198    
199    static uint32
200    make_colour16(PixelColour pc)
201    {
202            pc.red = (pc.red * 0x1f) / 0xff;
203            pc.green = (pc.green * 0x3f) / 0xff;
204            pc.blue = (pc.blue * 0x1f) / 0xff;
205            return (pc.red << 11) | (pc.green << 5) | pc.blue;
206    }
207    
208    static uint32
209    make_colour24(PixelColour pc)
210    {
211            if (g_xserver_be)
212            {
213                    return pc.red | (pc.green << 8) | (pc.blue << 16);
214            }
215            else
216            {
217                    return (pc.red << 16) | (pc.green << 8) | pc.blue;
218            }
219    }
220    
221    static uint32
222    make_colour32(PixelColour pc)
223    {
224            if (g_xserver_be)
225            {
226                    return pc.red | (pc.green << 8) | (pc.blue << 16);
227            }
228            else
229            {
230                    return (pc.red << 16) | (pc.green << 8) | pc.blue;
231            }
232    }
233    
234    #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
235    #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }
236    #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
237                            x = (x << 16) | (x >> 16); }
238    
239    static uint32
240    translate_colour(uint32 colour)
241    {
242            switch (g_server_bpp)
243            {
244                    case 15:
245                            switch (g_bpp)
246                            {
247                                    case 16:
248                                            colour = make_colour16(split_colour15(colour));
249                                            break;
250                                    case 24:
251                                            colour = make_colour24(split_colour15(colour));
252                                            break;
253                                    case 32:
254                                            colour = make_colour32(split_colour15(colour));
255                                            break;
256                            }
257                            break;
258                    case 16:
259                            switch (g_bpp)
260                            {
261                                    case 16:
262                                            break;
263                                    case 24:
264                                            colour = make_colour24(split_colour16(colour));
265                                            break;
266                                    case 32:
267                                            colour = make_colour32(split_colour16(colour));
268                                            break;
269                            }
270                            break;
271                    case 24:
272                            switch (g_bpp)
273                            {
274                                    case 16:
275                                            colour = make_colour16(split_colour24(colour));
276                                            break;
277                                    case 24:
278                                            break;
279                                    case 32:
280                                            colour = make_colour32(split_colour24(colour));
281                                            break;
282                            }
283                            break;
284            }
285            return colour;
286    }
287    
288  static void  static void
289  translate8(uint8 *data, uint8 *out, uint8 *end)  translate8to8(uint8 * data, uint8 * out, uint8 * end)
290  {  {
291          while (out < end)          while (out < end)
292                  *(out++) = (uint8)colmap[*(data++)];                  *(out++) = (uint8) g_colmap[*(data++)];
293  }  }
294    
295  static void  static void
296  translate16(uint8 *data, uint16 *out, uint16 *end)  translate8to16(uint8 * data, uint16 * out, uint16 * end)
297  {  {
298          while (out < end)          while (out < end)
299                  *(out++) = (uint16)colmap[*(data++)];                  *(out++) = (uint16) g_colmap[*(data++)];
300  }  }
301    
302  /* little endian - conversion happens when colourmap is built */  /* little endian - conversion happens when colourmap is built */
303  static void  static void
304  translate24(uint8 *data, uint8 *out, uint8 *end)  translate8to24(uint8 * data, uint8 * out, uint8 * end)
305  {  {
306          uint32 value;          uint32 value;
307    
308          while (out < end)          while (out < end)
309          {          {
310                  value = colmap[*(data++)];                  value = g_colmap[*(data++)];
311                  *(out++) = value;                  *(out++) = value;
312                  *(out++) = value >> 8;                  *(out++) = value >> 8;
313                  *(out++) = value >> 16;                  *(out++) = value >> 16;
# Line 116  translate24(uint8 *data, uint8 *out, uin Line 315  translate24(uint8 *data, uint8 *out, uin
315  }  }
316    
317  static void  static void
318  translate32(uint8 *data, uint32 *out, uint32 *end)  translate8to32(uint8 * data, uint32 * out, uint32 * end)
319  {  {
320          while (out < end)          while (out < end)
321                  *(out++) = colmap[*(data++)];                  *(out++) = g_colmap[*(data++)];
322  }  }
323    
324  static uint8 *  /* todo the remaining translate function might need some big endian check ?? */
325  translate_image(int width, int height, uint8 *data)  
326    static void
327    translate15to16(uint16 * data, uint8 * out, uint8 * end)
328  {  {
329          int size = width * height * bpp/8;          uint16 pixel;
330          uint8 *out = xmalloc(size);          uint16 value;
         uint8 *end = out + size;  
331    
332          switch (bpp)          while (out < end)
333          {          {
334                  case 8:                  pixel = *(data++);
                         translate8(data, out, end);  
                         break;  
335    
336                  case 16:                  if (g_host_be)
337                          translate16(data, (uint16 *)out, (uint16 *)end);                  {
338                          break;                  BSWAP16(pixel)}
339    
340                  case 24:                  value = make_colour16(split_colour15(pixel));
                         translate24(data, out, end);  
                         break;  
341    
342                  case 32:                  if (g_xserver_be)
343                          translate32(data, (uint32 *)out, (uint32 *)end);                  {
344                          break;                          *(out++) = value >> 8;
345                            *(out++) = value;
346                    }
347                    else
348                    {
349                            *(out++) = value;
350                            *(out++) = value >> 8;
351                    }
352          }          }
353    }
354    
355          return out;  static void
356    translate15to24(uint16 * data, uint8 * out, uint8 * end)
357    {
358            uint32 value;
359            uint16 pixel;
360    
361            while (out < end)
362            {
363                    pixel = *(data++);
364    
365                    if (g_host_be)
366                    {
367                    BSWAP16(pixel)}
368    
369                    value = make_colour24(split_colour15(pixel));
370                    if (g_xserver_be)
371                    {
372                            *(out++) = value >> 16;
373                            *(out++) = value >> 8;
374                            *(out++) = value;
375                    }
376                    else
377                    {
378                            *(out++) = value;
379                            *(out++) = value >> 8;
380                            *(out++) = value >> 16;
381                    }
382            }
383  }  }
384    
385  #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }  static void
386  #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }  translate15to32(uint16 * data, uint8 * out, uint8 * end)
387  #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \  {
388                          x = (x << 16) | (x >> 16); }          uint16 pixel;
389            uint32 value;
390    
391  static uint32          while (out < end)
392  translate_colour(uint32 colour)          {
393                    pixel = *(data++);
394    
395                    if (g_host_be)
396                    {
397                            BSWAP16(pixel);
398                    }
399    
400                    value = make_colour32(split_colour15(pixel));
401    
402                    if (g_xserver_be)
403                    {
404                            *(out++) = value >> 24;
405                            *(out++) = value >> 16;
406                            *(out++) = value >> 8;
407                            *(out++) = value;
408                    }
409                    else
410                    {
411                            *(out++) = value;
412                            *(out++) = value >> 8;
413                            *(out++) = value >> 16;
414                            *(out++) = value >> 24;
415                    }
416            }
417    }
418    
419    static void
420    translate16to16(uint16 * data, uint16 * out, uint16 * end)
421  {  {
422          switch (bpp)          uint16 value;
423    
424            if (g_xserver_be)
425          {          {
426                  case 16:                  while (out < end)
427                          if (host_be != xserver_be)                  {
428                                  BSWAP16(colour);                          value = *data;
429                          break;                          BSWAP16(value);
430                            *out = value;
431                            data++;
432                            out++;
433                    }
434    
435            }
436            else
437            {
438                    while (out < end)
439                    {
440                            *out = *data;
441                            out++;
442                            data++;
443                    }
444            }
445    }
446    
447    
448    static void
449    translate16to24(uint16 * data, uint8 * out, uint8 * end)
450    {
451            uint32 value;
452            uint16 pixel;
453    
454            while (out < end)
455            {
456                    pixel = *(data++);
457    
458                    if (g_host_be)
459                    {
460                    BSWAP16(pixel)}
461    
462                    value = make_colour24(split_colour16(pixel));
463    
464                    if (g_xserver_be)
465                    {
466                            *(out++) = value >> 16;
467                            *(out++) = value >> 8;
468                            *(out++) = value;
469                    }
470                    else
471                    {
472                            *(out++) = value;
473                            *(out++) = value >> 8;
474                            *(out++) = value >> 16;
475                    }
476            }
477    }
478    
479    static void
480    translate16to32(uint16 * data, uint8 * out, uint8 * end)
481    {
482            uint16 pixel;
483            uint32 value;
484    
485            while (out < end)
486            {
487                    pixel = *(data++);
488    
489                    if (g_host_be)
490                    {
491                    BSWAP16(pixel)}
492    
493                    value = make_colour32(split_colour16(pixel));
494    
495                    if (g_xserver_be)
496                    {
497                            *(out++) = value >> 24;
498                            *(out++) = value >> 16;
499                            *(out++) = value >> 8;
500                            *(out++) = value;
501                    }
502                    else
503                    {
504                            *(out++) = value;
505                            *(out++) = value >> 8;
506                            *(out++) = value >> 16;
507                            *(out++) = value >> 24;
508                    }
509            }
510    }
511    
512    static void
513    translate24to16(uint8 * data, uint8 * out, uint8 * end)
514    {
515            uint32 pixel = 0;
516            uint16 value;
517            while (out < end)
518            {
519                    pixel = *(data++) << 16;
520                    pixel |= *(data++) << 8;
521                    pixel |= *(data++);
522    
523                    value = (uint16) make_colour16(split_colour24(pixel));
524    
525                    if (g_xserver_be)
526                    {
527                            *(out++) = value >> 8;
528                            *(out++) = value;
529                    }
530                    else
531                    {
532                            *(out++) = value;
533                            *(out++) = value >> 8;
534                    }
535            }
536    }
537    
538    static void
539    translate24to24(uint8 * data, uint8 * out, uint8 * end)
540    {
541            while (out < end)
542            {
543                    *(out++) = (*(data++));
544            }
545    }
546    
547    static void
548    translate24to32(uint8 * data, uint8 * out, uint8 * end)
549    {
550            while (out < end)
551            {
552                    if (g_xserver_be)
553                    {
554                            *(out++) = 0x00;
555                            *(out++) = *(data++);
556                            *(out++) = *(data++);
557                            *(out++) = *(data++);
558                    }
559                    else
560                    {
561                            *(out++) = *(data++);
562                            *(out++) = *(data++);
563                            *(out++) = *(data++);
564                            *(out++) = 0x00;
565                    }
566            }
567    }
568    
569    static uint8 *
570    translate_image(int width, int height, uint8 * data)
571    {
572            int size = width * height * g_bpp / 8;
573            uint8 *out = (uint8 *) xmalloc(size);
574            uint8 *end = out + size;
575    
576            switch (g_server_bpp)
577            {
578                  case 24:                  case 24:
579                          if (xserver_be)                          switch (g_bpp)
580                                  BSWAP24(colour);                          {
581                                    case 32:
582                                            translate24to32(data, out, end);
583                                            break;
584                                    case 24:
585                                            translate24to24(data, out, end);
586                                            break;
587                                    case 16:
588                                            translate24to16(data, out, end);
589                                            break;
590                            }
591                          break;                          break;
592                    case 16:
593                  case 32:                          switch (g_bpp)
594                          if (host_be != xserver_be)                          {
595                                  BSWAP32(colour);                                  case 32:
596                                            translate16to32((uint16 *) data, out, end);
597                                            break;
598                                    case 24:
599                                            translate16to24((uint16 *) data, out, end);
600                                            break;
601                                    case 16:
602                                            translate16to16((uint16 *) data, (uint16 *) out,
603                                                            (uint16 *) end);
604                                            break;
605                            }
606                            break;
607                    case 15:
608                            switch (g_bpp)
609                            {
610                                    case 32:
611                                            translate15to32((uint16 *) data, out, end);
612                                            break;
613                                    case 24:
614                                            translate15to24((uint16 *) data, out, end);
615                                            break;
616                                    case 16:
617                                            translate15to16((uint16 *) data, out, end);
618                                            break;
619                            }
620                            break;
621                    case 8:
622                            switch (g_bpp)
623                            {
624                                    case 8:
625                                            translate8to8(data, out, end);
626                                            break;
627                                    case 16:
628                                            translate8to16(data, (uint16 *) out, (uint16 *) end);
629                                            break;
630                                    case 24:
631                                            translate8to24(data, out, end);
632                                            break;
633                                    case 32:
634                                            translate8to32(data, (uint32 *) out, (uint32 *) end);
635                                            break;
636                            }
637                          break;                          break;
638          }          }
639            return out;
640    }
641    
642          return colour;  BOOL
643    get_key_state(unsigned int state, uint32 keysym)
644    {
645            int modifierpos, key, keysymMask = 0;
646            int offset;
647    
648            KeyCode keycode = XKeysymToKeycode(g_display, keysym);
649    
650            if (keycode == NoSymbol)
651                    return False;
652    
653            for (modifierpos = 0; modifierpos < 8; modifierpos++)
654            {
655                    offset = g_mod_map->max_keypermod * modifierpos;
656    
657                    for (key = 0; key < g_mod_map->max_keypermod; key++)
658                    {
659                            if (g_mod_map->modifiermap[offset + key] == keycode)
660                                    keysymMask |= 1 << modifierpos;
661                    }
662            }
663    
664            return (state & keysymMask) ? True : False;
665  }  }
666    
667  BOOL  BOOL
668  ui_create_window(char *title)  ui_init(void)
669  {  {
         XSetWindowAttributes attribs;  
         XClassHint *classhints;  
         XSizeHints *sizehints;  
         unsigned long input_mask;  
670          XPixmapFormatValues *pfm;          XPixmapFormatValues *pfm;
         Screen *screen;  
671          uint16 test;          uint16 test;
672          int i;          int i;
673    
674          display = XOpenDisplay(NULL);          g_display = XOpenDisplay(NULL);
675          if (display == NULL)          if (g_display == NULL)
676          {          {
677                  error("Failed to open display\n");                  error("Failed to open display: %s\n", XDisplayName(NULL));
678                  return False;                  return False;
679          }          }
680    
681          x_socket = ConnectionNumber(display);          g_x_socket = ConnectionNumber(g_display);
682          screen = DefaultScreenOfDisplay(display);          g_screen = DefaultScreenOfDisplay(g_display);
683          visual = DefaultVisualOfScreen(screen);          g_visual = DefaultVisualOfScreen(g_screen);
684          depth = DefaultDepthOfScreen(screen);          g_depth = DefaultDepthOfScreen(g_screen);
685    
686          pfm = XListPixmapFormats(display, &i);          pfm = XListPixmapFormats(g_display, &i);
687          if (pfm != NULL)          if (pfm != NULL)
688          {          {
689                  /* Use maximum bpp for this depth - this is generally                  /* Use maximum bpp for this depth - this is generally
690                     desirable, e.g. 24 bits->32 bits. */                     desirable, e.g. 24 bits->32 bits. */
691                  while (i--)                  while (i--)
692                  {                  {
693                          if ((pfm[i].depth == depth)                          if ((pfm[i].depth == g_depth) && (pfm[i].bits_per_pixel > g_bpp))
                             && (pfm[i].bits_per_pixel > bpp))  
694                          {                          {
695                                  bpp = pfm[i].bits_per_pixel;                                  g_bpp = pfm[i].bits_per_pixel;
696                          }                          }
697                  }                  }
698                  XFree(pfm);                  XFree(pfm);
699          }          }
700    
701          if (bpp < 8)          if (g_bpp < 8)
702          {          {
703                  error("Less than 8 bpp not currently supported.\n");                  error("Less than 8 bpp not currently supported.\n");
704                  XCloseDisplay(display);                  XCloseDisplay(g_display);
705                  return False;                  return False;
706          }          }
707    
708          if (depth <= 8)          /* private colour map code only works for 8 bpp */
709                  owncolmap = True;          if (g_owncolmap && (g_bpp > 8))
710          else                  g_owncolmap = False;
                 xcolmap = DefaultColormapOfScreen(screen);  
711    
712          test = 1;          if (!g_owncolmap)
713          host_be = !(BOOL)(*(uint8 *)(&test));          {
714          xserver_be = (ImageByteOrder(display) == MSBFirst);                  g_xcolmap = DefaultColormapOfScreen(g_screen);
715                    if (g_depth <= 8)
716                            warning("Screen depth is 8 bits or lower: you may want to use -C for a private colourmap\n");
717            }
718    
719          white = WhitePixelOfScreen(screen);          g_gc = XCreateGC(g_display, RootWindowOfScreen(g_screen), 0, NULL);
         attribs.background_pixel = BlackPixelOfScreen(screen);  
         attribs.backing_store = DoesBackingStore(screen);  
720    
721          if (attribs.backing_store == NotUseful)          if (DoesBackingStore(g_screen) != Always)
722                  ownbackstore = True;                  g_ownbackstore = True;
723    
724          if (fullscreen)          test = 1;
725            g_host_be = !(BOOL) (*(uint8 *) (&test));
726            g_xserver_be = (ImageByteOrder(g_display) == MSBFirst);
727    
728            /*
729             * Determine desktop size
730             */
731            if (g_width < 0)
732          {          {
733                  attribs.override_redirect = True;                  /* Percent of screen */
734                  width = WidthOfScreen(screen);                  g_height = HeightOfScreen(g_screen) * (-g_width) / 100;
735                  height = HeightOfScreen(screen);                  g_width = WidthOfScreen(g_screen) * (-g_width) / 100;
736          }          }
737          else          else if (g_width == 0)
738          {          {
739                  attribs.override_redirect = False;                  /* Fetch geometry from _NET_WORKAREA */
740                    uint32 x, y, cx, cy;
741    
742                    if (get_current_workarea(&x, &y, &cx, &cy) == 0)
743                    {
744                            g_width = cx;
745                            g_height = cy;
746                    }
747                    else
748                    {
749                            warning("Failed to get workarea: probably your window manager does not support extended hints\n");
750                            g_width = 800;
751                            g_height = 600;
752                    }
753            }
754            else if (g_fullscreen)
755            {
756                    g_width = WidthOfScreen(g_screen);
757                    g_height = HeightOfScreen(g_screen);
758          }          }
759    
760          width = (width + 3) & ~3; /* make width a multiple of 32 bits */          /* make sure width is a multiple of 4 */
761            g_width = (g_width + 3) & ~3;
762    
763            if (g_ownbackstore)
764            {
765                    g_backstore =
766                            XCreatePixmap(g_display, RootWindowOfScreen(g_screen), g_width, g_height,
767                                          g_depth);
768    
769                    /* clear to prevent rubbish being exposed at startup */
770                    XSetForeground(g_display, g_gc, BlackPixelOfScreen(g_screen));
771                    XFillRectangle(g_display, g_backstore, g_gc, 0, 0, g_width, g_height);
772            }
773    
774            g_mod_map = XGetModifierMapping(g_display);
775    
776            xkeymap_init();
777    
778            if (g_enable_compose)
779                    g_IM = XOpenIM(g_display, NULL, NULL, NULL);
780    
781            xclip_init();
782    
783            DEBUG_RDP5(("server bpp %d client bpp %d depth %d\n", g_server_bpp, g_bpp, g_depth));
784    
785            return True;
786    }
787    
788    void
789    ui_deinit(void)
790    {
791            if (g_IM != NULL)
792                    XCloseIM(g_IM);
793    
794            XFreeModifiermap(g_mod_map);
795    
796            if (g_ownbackstore)
797                    XFreePixmap(g_display, g_backstore);
798    
799            XFreeGC(g_display, g_gc);
800            XCloseDisplay(g_display);
801            g_display = NULL;
802    }
803    
804    #define NULL_POINTER_MASK       "\x80"
805    #define NULL_POINTER_DATA       "\x0\x0\x0"
806            
807    BOOL
808    ui_create_window(void)
809    {
810            XSetWindowAttributes attribs;
811            XClassHint *classhints;
812            XSizeHints *sizehints;
813            int wndwidth, wndheight;
814            long input_mask, ic_input_mask;
815            XEvent xevent;
816    
817            wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;
818            wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;
819    
820          wnd = XCreateWindow(display, RootWindowOfScreen(screen),          attribs.background_pixel = BlackPixelOfScreen(g_screen);
821                              0, 0, width, height, 0, CopyFromParent,          attribs.backing_store = g_ownbackstore ? NotUseful : Always;
822                              InputOutput, CopyFromParent,          attribs.override_redirect = g_fullscreen;
                             CWBackingStore | CWBackPixel | CWOverrideRedirect,  
                             &attribs);  
823    
824          XStoreName(display, wnd, title);          g_wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), 0, 0, wndwidth, wndheight,
825                                  0, CopyFromParent, InputOutput, CopyFromParent,
826                                  CWBackPixel | CWBackingStore | CWOverrideRedirect, &attribs);
827    
828            XStoreName(g_display, g_wnd, g_title);
829    
830            if (g_hide_decorations)
831                    mwm_hide_decorations();
832    
833          classhints = XAllocClassHint();          classhints = XAllocClassHint();
834          if (classhints != NULL)          if (classhints != NULL)
835          {          {
836                  classhints->res_name = classhints->res_class = "rdesktop";                  classhints->res_name = classhints->res_class = "rdesktop";
837                  XSetClassHint(display, wnd, classhints);                  XSetClassHint(g_display, g_wnd, classhints);
838                  XFree(classhints);                  XFree(classhints);
839          }          }
840    
# Line 276  ui_create_window(char *title) Line 842  ui_create_window(char *title)
842          if (sizehints)          if (sizehints)
843          {          {
844                  sizehints->flags = PMinSize | PMaxSize;                  sizehints->flags = PMinSize | PMaxSize;
845                  sizehints->min_width = sizehints->max_width = width;                  sizehints->min_width = sizehints->max_width = g_width;
846                  sizehints->min_height = sizehints->max_height = height;                  sizehints->min_height = sizehints->max_height = g_height;
847                  XSetWMNormalHints(display, wnd, sizehints);                  XSetWMNormalHints(g_display, g_wnd, sizehints);
848                  XFree(sizehints);                  XFree(sizehints);
849          }          }
850    
851          xkeymap_init(display);          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
852                    VisibilityChangeMask | FocusChangeMask;
853    
854          input_mask = KeyPressMask | KeyReleaseMask          if (g_sendmotion)
                         | ButtonPressMask | ButtonReleaseMask  
                         | EnterWindowMask | LeaveWindowMask;  
   
         if (sendmotion)  
855                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
856            if (g_ownbackstore)
         if (ownbackstore)  
857                  input_mask |= ExposureMask;                  input_mask |= ExposureMask;
858            if (g_fullscreen || g_grab_keyboard)
859                    input_mask |= EnterWindowMask;
860            if (g_grab_keyboard)
861                    input_mask |= LeaveWindowMask;
862    
863            if (g_IM != NULL)
864            {
865                    g_IC = XCreateIC(g_IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
866                                     XNClientWindow, g_wnd, XNFocusWindow, g_wnd, NULL);
867    
868                    if ((g_IC != NULL)
869                        && (XGetICValues(g_IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))
870                            input_mask |= ic_input_mask;
871            }
872    
873            XSelectInput(g_display, g_wnd, input_mask);
874            XMapWindow(g_display, g_wnd);
875    
876            /* wait for VisibilityNotify */
877            do
878            {
879                    XMaskEvent(g_display, VisibilityChangeMask, &xevent);
880            }
881            while (xevent.type != VisibilityNotify);
882    
883            g_focused = False;
884            g_mouse_in_wnd = False;
885    
886          XSelectInput(display, wnd, input_mask);          /* handle the WM_DELETE_WINDOW protocol */
887          gc = XCreateGC(display, wnd, 0, NULL);          g_protocol_atom = XInternAtom(g_display, "WM_PROTOCOLS", True);
888            g_kill_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", True);
889            XSetWMProtocols(g_display, g_wnd, &g_kill_atom, 1);
890    
891          if (ownbackstore)          /* create invisible 1x1 cursor to be used as null cursor */
892                  backstore = XCreatePixmap(display, wnd, width, height, depth);          g_null_cursor = ui_create_cursor(0, 0, 1, 1, NULL_POINTER_MASK, NULL_POINTER_DATA);
893    
         XMapWindow(display, wnd);  
894          return True;          return True;
895  }  }
896    
897  void  void
898  ui_destroy_window()  ui_destroy_window(void)
899  {  {
900          if (ownbackstore)          ui_destroy_cursor(g_null_cursor);
901                  XFreePixmap(display, backstore);          
902            if (g_IC != NULL)
903                    XDestroyIC(g_IC);
904    
905          XFreeGC(display, gc);          XDestroyWindow(g_display, g_wnd);
         XDestroyWindow(display, wnd);  
         XCloseDisplay(display);  
         display = NULL;  
906  }  }
907    
908  static void  void
909  xwin_process_events()  xwin_toggle_fullscreen(void)
910    {
911            Pixmap contents = 0;
912    
913            if (!g_ownbackstore)
914            {
915                    /* need to save contents of window */
916                    contents = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
917                    XCopyArea(g_display, g_wnd, contents, g_gc, 0, 0, g_width, g_height, 0, 0);
918            }
919    
920            ui_destroy_window();
921            g_fullscreen = !g_fullscreen;
922            ui_create_window();
923    
924            XDefineCursor(g_display, g_wnd, g_current_cursor);
925    
926            if (!g_ownbackstore)
927            {
928                    XCopyArea(g_display, contents, g_wnd, g_gc, 0, 0, g_width, g_height, 0, 0);
929                    XFreePixmap(g_display, contents);
930            }
931    }
932    
933    /* Process all events in Xlib queue
934       Returns 0 after user quit, 1 otherwise */
935    static int
936    xwin_process_events(void)
937  {  {
938          XEvent event;          XEvent xevent;
939          KeySym keysym;          KeySym keysym;
940          uint8 scancode;          uint16 button, flags;
         uint16 button;  
941          uint32 ev_time;          uint32 ev_time;
942            key_translation tr;
943            char str[256];
944            Status status;
945            unsigned int state;
946            Window wdummy;
947            int dummy;
948    
949          if (display == NULL)          while (XPending(g_display) > 0)
                 return;  
   
         while (XCheckMaskEvent(display, ~0, &event))  
950          {          {
951                  ev_time = time(NULL);                  XNextEvent(g_display, &xevent);
952    
953                    if ((g_IC != NULL) && (XFilterEvent(&xevent, None) == True))
954                    {
955                            DEBUG_KBD(("Filtering event\n"));
956                            continue;
957                    }
958    
959                  switch (event.type)                  flags = 0;
960    
961                    switch (xevent.type)
962                  {                  {
963                            case ClientMessage:
964                                    /* the window manager told us to quit */
965                                    if ((xevent.xclient.message_type == g_protocol_atom)
966                                        && ((Atom) xevent.xclient.data.l[0] == g_kill_atom))
967                                            /* Quit */
968                                            return 0;
969                                    break;
970    
971                          case KeyPress:                          case KeyPress:
972                                  keysym = XKeycodeToKeysym(display, event.xkey.keycode, 0);                                  g_last_gesturetime = xevent.xkey.time;
973                                  scancode = xkeymap_translate_key(keysym, event.xkey.keycode);                                  if (g_IC != NULL)
974                                  if (scancode == 0)                                          /* Multi_key compatible version */
975                                    {
976                                            XmbLookupString(g_IC,
977                                                            &xevent.xkey, str, sizeof(str), &keysym,
978                                                            &status);
979                                            if (!((status == XLookupKeySym) || (status == XLookupBoth)))
980                                            {
981                                                    error("XmbLookupString failed with status 0x%x\n",
982                                                          status);
983                                                    break;
984                                            }
985                                    }
986                                    else
987                                    {
988                                            /* Plain old XLookupString */
989                                            DEBUG_KBD(("\nNo input context, using XLookupString\n"));
990                                            XLookupString((XKeyEvent *) & xevent,
991                                                          str, sizeof(str), &keysym, NULL);
992                                    }
993    
994                                    DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,
995                                               get_ksname(keysym)));
996    
997                                    ev_time = time(NULL);
998                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
999                                            break;
1000    
1001                                    tr = xkeymap_translate_key(keysym,
1002                                                               xevent.xkey.keycode, xevent.xkey.state);
1003    
1004                                    if (tr.scancode == 0)
1005                                          break;                                          break;
1006    
1007                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,                                  save_remote_modifiers(tr.scancode);
1008                                                 scancode, 0);                                  ensure_remote_modifiers(ev_time, tr);
1009                                    rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
1010                                    restore_remote_modifiers(ev_time, tr.scancode);
1011    
1012                                  break;                                  break;
1013    
1014                          case KeyRelease:                          case KeyRelease:
1015                                  keysym = XKeycodeToKeysym(display, event.xkey.keycode, 0);                                  g_last_gesturetime = xevent.xkey.time;
1016                                  scancode = xkeymap_translate_key(keysym, event.xkey.keycode);                                  XLookupString((XKeyEvent *) & xevent, str,
1017                                  if (scancode == 0)                                                sizeof(str), &keysym, NULL);
1018    
1019                                    DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
1020                                               get_ksname(keysym)));
1021    
1022                                    ev_time = time(NULL);
1023                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
1024                                          break;                                          break;
1025    
1026                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE,                                  tr = xkeymap_translate_key(keysym,
1027                                                 KBD_FLAG_DOWN | KBD_FLAG_UP,                                                             xevent.xkey.keycode, xevent.xkey.state);
                                                scancode, 0);  
                                 break;  
1028    
1029                          case ButtonPress:                                  if (tr.scancode == 0)
                                 button = xkeymap_translate_button(event.xbutton.button);  
                                 if (button == 0)  
1030                                          break;                                          break;
1031    
1032                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
                                                button | MOUSE_FLAG_DOWN,  
                                                event.xbutton.x,  
                                                event.xbutton.y);  
1033                                  break;                                  break;
1034    
1035                            case ButtonPress:
1036                                    flags = MOUSE_FLAG_DOWN;
1037                                    /* fall through */
1038    
1039                          case ButtonRelease:                          case ButtonRelease:
1040                                  button = xkeymap_translate_button(event.xbutton.button);                                  g_last_gesturetime = xevent.xbutton.time;
1041                                    button = xkeymap_translate_button(xevent.xbutton.button);
1042                                  if (button == 0)                                  if (button == 0)
1043                                          break;                                          break;
1044    
1045                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  /* If win_button_size is nonzero, enable single app mode */
1046                                                 button,                                  if (xevent.xbutton.y < g_win_button_size)
1047                                                 event.xbutton.x,                                  {
1048                                                 event.xbutton.y);                                          /* Stop moving window when button is released, regardless of cursor position */
1049                                            if (g_moving_wnd && (xevent.type == ButtonRelease))
1050                                                    g_moving_wnd = False;
1051    
1052                                            /*  Check from right to left: */
1053    
1054                                            if (xevent.xbutton.x >= g_width - g_win_button_size)
1055                                            {
1056                                                    /* The close button, continue */
1057                                                    ;
1058                                            }
1059                                            else if (xevent.xbutton.x >=
1060                                                     g_width - g_win_button_size * 2)
1061                                            {
1062                                                    /* The maximize/restore button. Do not send to
1063                                                       server.  It might be a good idea to change the
1064                                                       cursor or give some other visible indication
1065                                                       that rdesktop inhibited this click */
1066                                                    break;
1067                                            }
1068                                            else if (xevent.xbutton.x >=
1069                                                     g_width - g_win_button_size * 3)
1070                                            {
1071                                                    /* The minimize button. Iconify window. */
1072                                                    XIconifyWindow(g_display, g_wnd,
1073                                                                   DefaultScreen(g_display));
1074                                                    break;
1075                                            }
1076                                            else if (xevent.xbutton.x <= g_win_button_size)
1077                                            {
1078                                                    /* The system menu. Ignore. */
1079                                                    break;
1080                                            }
1081                                            else
1082                                            {
1083                                                    /* The title bar. */
1084                                                    if ((xevent.type == ButtonPress) && !g_fullscreen
1085                                                        && g_hide_decorations)
1086                                                    {
1087                                                            g_moving_wnd = True;
1088                                                            g_move_x_offset = xevent.xbutton.x;
1089                                                            g_move_y_offset = xevent.xbutton.y;
1090                                                    }
1091                                                    break;
1092    
1093                                            }
1094                                    }
1095    
1096                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1097                                                   flags | button, xevent.xbutton.x, xevent.xbutton.y);
1098                                  break;                                  break;
1099    
1100                          case MotionNotify:                          case MotionNotify:
1101                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  if (g_moving_wnd)
1102                                                 MOUSE_FLAG_MOVE,                                  {
1103                                                 event.xmotion.x,                                          XMoveWindow(g_display, g_wnd,
1104                                                 event.xmotion.y);                                                      xevent.xmotion.x_root - g_move_x_offset,
1105                                                        xevent.xmotion.y_root - g_move_y_offset);
1106                                            break;
1107                                    }
1108    
1109                                    if (g_fullscreen && !g_focused)
1110                                            XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,
1111                                                           CurrentTime);
1112                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1113                                                   MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
1114                                    break;
1115    
1116                            case FocusIn:
1117                                    if (xevent.xfocus.mode == NotifyGrab)
1118                                            break;
1119                                    g_focused = True;
1120                                    XQueryPointer(g_display, g_wnd, &wdummy, &wdummy, &dummy, &dummy,
1121                                                  &dummy, &dummy, &state);
1122                                    reset_modifier_keys(state);
1123                                    if (g_grab_keyboard && g_mouse_in_wnd)
1124                                            XGrabKeyboard(g_display, g_wnd, True,
1125                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
1126                                    break;
1127    
1128                            case FocusOut:
1129                                    if (xevent.xfocus.mode == NotifyUngrab)
1130                                            break;
1131                                    g_focused = False;
1132                                    if (xevent.xfocus.mode == NotifyWhileGrabbed)
1133                                            XUngrabKeyboard(g_display, CurrentTime);
1134                                  break;                                  break;
1135    
1136                          case EnterNotify:                          case EnterNotify:
1137                                  XGrabKeyboard(display, wnd, True, GrabModeAsync,                                  /* we only register for this event when in fullscreen mode */
1138                                                GrabModeAsync, CurrentTime);                                  /* or grab_keyboard */
1139                                    g_mouse_in_wnd = True;
1140                                    if (g_fullscreen)
1141                                    {
1142                                            XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,
1143                                                           CurrentTime);
1144                                            break;
1145                                    }
1146                                    if (g_focused)
1147                                            XGrabKeyboard(g_display, g_wnd, True,
1148                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
1149                                  break;                                  break;
1150    
1151                          case LeaveNotify:                          case LeaveNotify:
1152                                  XUngrabKeyboard(display, CurrentTime);                                  /* we only register for this event when grab_keyboard */
1153                                    g_mouse_in_wnd = False;
1154                                    XUngrabKeyboard(g_display, CurrentTime);
1155                                  break;                                  break;
1156    
1157                          case Expose:                          case Expose:
1158                                  XCopyArea(display, backstore, wnd, gc,                                  XCopyArea(g_display, g_backstore, g_wnd, g_gc,
1159                                            event.xexpose.x, event.xexpose.y,                                            xevent.xexpose.x, xevent.xexpose.y,
1160                                            event.xexpose.width, event.xexpose.height,                                            xevent.xexpose.width,
1161                                            event.xexpose.x, event.xexpose.y);                                            xevent.xexpose.height,
1162                                              xevent.xexpose.x, xevent.xexpose.y);
1163                                    break;
1164    
1165                            case MappingNotify:
1166                                    /* Refresh keyboard mapping if it has changed. This is important for
1167                                       Xvnc, since it allocates keycodes dynamically */
1168                                    if (xevent.xmapping.request == MappingKeyboard
1169                                        || xevent.xmapping.request == MappingModifier)
1170                                            XRefreshKeyboardMapping(&xevent.xmapping);
1171    
1172                                    if (xevent.xmapping.request == MappingModifier)
1173                                    {
1174                                            XFreeModifiermap(g_mod_map);
1175                                            g_mod_map = XGetModifierMapping(g_display);
1176                                    }
1177                                    break;
1178    
1179                                    /* clipboard stuff */
1180                            case SelectionNotify:
1181                                    xclip_handle_SelectionNotify(&xevent.xselection);
1182                                    break;
1183                            case SelectionRequest:
1184                                    xclip_handle_SelectionRequest(&xevent.xselectionrequest);
1185                                    break;
1186                            case SelectionClear:
1187                                    xclip_handle_SelectionClear();
1188                                    break;
1189                            case PropertyNotify:
1190                                    xclip_handle_PropertyNotify(&xevent.xproperty);
1191                                  break;                                  break;
1192                  }                  }
1193          }          }
1194            /* Keep going */
1195            return 1;
1196  }  }
1197    
1198  void  /* Returns 0 after user quit, 1 otherwise */
1199    int
1200  ui_select(int rdp_socket)  ui_select(int rdp_socket)
1201  {  {
1202          int n = (rdp_socket > x_socket) ? rdp_socket+1 : x_socket+1;          int n = (rdp_socket > g_x_socket) ? rdp_socket + 1 : g_x_socket + 1;
1203          fd_set rfds;          fd_set rfds, wfds;
   
         XFlush(display);  
   
         FD_ZERO(&rfds);  
1204    
1205          while (True)          while (True)
1206          {          {
1207                    /* Process any events already waiting */
1208                    if (!xwin_process_events())
1209                            /* User quit */
1210                            return 0;
1211    
1212                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
1213                    FD_ZERO(&wfds);
1214                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
1215                  FD_SET(x_socket, &rfds);                  FD_SET(g_x_socket, &rfds);
1216    
1217    #ifdef WITH_RDPSND
1218                    /* FIXME: there should be an API for registering fds */
1219                    if (g_dsp_busy)
1220                    {
1221                            FD_SET(g_dsp_fd, &wfds);
1222                            n = (g_dsp_fd + 1 > n) ? g_dsp_fd + 1 : n;
1223                    }
1224    #endif
1225    
1226                  switch (select(n, &rfds, NULL, NULL, NULL))                  switch (select(n, &rfds, &wfds, NULL, NULL))
1227                  {                  {
1228                          case -1:                          case -1:
1229                                  error("select: %s\n", strerror(errno));                                  error("select: %s\n", strerror(errno));
# Line 428  ui_select(int rdp_socket) Line 1232  ui_select(int rdp_socket)
1232                                  continue;                                  continue;
1233                  }                  }
1234    
                 if (FD_ISSET(x_socket, &rfds))  
                         xwin_process_events();  
   
1235                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
1236                          return;                          return 1;
1237    
1238    #ifdef WITH_RDPSND
1239                    if (g_dsp_busy && FD_ISSET(g_dsp_fd, &wfds))
1240                            wave_out_play();
1241    #endif
1242          }          }
1243  }  }
1244    
1245  void  void
1246  ui_move_pointer(int x, int y)  ui_move_pointer(int x, int y)
1247  {  {
1248          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);          XWarpPointer(g_display, g_wnd, g_wnd, 0, 0, 0, 0, x, y);
1249  }  }
1250    
1251  HBITMAP  HBITMAP
1252  ui_create_bitmap(int width, int height, uint8 *data)  ui_create_bitmap(int width, int height, uint8 * data)
1253  {  {
1254          XImage *image;          XImage *image;
1255          Pixmap bitmap;          Pixmap bitmap;
1256          uint8 *tdata;          uint8 *tdata;
1257    
1258          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (g_owncolmap ? data : translate_image(width, height, data));
1259          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(g_display, g_wnd, width, height, g_depth);
1260          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1261                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, g_server_bpp == 8 ? 8 : g_bpp, 0);
1262    
1263          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(g_display, bitmap, g_gc, image, 0, 0, 0, 0, width, height);
1264    
1265          XFree(image);          XFree(image);
1266          if (!owncolmap)          if (!g_owncolmap)
1267                  xfree(tdata);                  xfree(tdata);
1268          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
1269  }  }
1270    
1271  void  void
1272  ui_paint_bitmap(int x, int y, int cx, int cy,  ui_paint_bitmap(int x, int y, int cx, int cy, int width, int height, uint8 * data)
                 int width, int height, uint8 *data)  
1273  {  {
1274          XImage *image;          XImage *image;
1275          uint8 *tdata;          uint8 *tdata;
1276            tdata = (g_owncolmap ? data : translate_image(width, height, data));
1277            image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1278                                 (char *) tdata, width, height, g_server_bpp == 8 ? 8 : g_bpp, 0);
1279    
1280          tdata = (owncolmap ? data : translate_image(width, height, data));          if (g_ownbackstore)
         image = XCreateImage(display, visual, depth, ZPixmap,  
                              0, tdata, width, height, 8, 0);  
   
         if (ownbackstore)  
1281          {          {
1282                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_backstore, g_gc, image, 0, 0, x, y, cx, cy);
1283                  XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);                  XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
1284          }          }
1285          else          else
1286          {          {
1287                  XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy);
1288          }          }
1289    
1290          XFree(image);          XFree(image);
1291          if (!owncolmap)          if (!g_owncolmap)
1292                  xfree(tdata);                  xfree(tdata);
1293  }  }
1294    
1295  void  void
1296  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(HBITMAP bmp)
1297  {  {
1298          XFreePixmap(display, (Pixmap)bmp);          XFreePixmap(g_display, (Pixmap) bmp);
1299  }  }
1300    
1301  HGLYPH  HGLYPH
1302  ui_create_glyph(int width, int height, uint8 *data)  ui_create_glyph(int width, int height, uint8 * data)
1303  {  {
1304          XImage *image;          XImage *image;
1305          Pixmap bitmap;          Pixmap bitmap;
# Line 504  ui_create_glyph(int width, int height, u Line 1308  ui_create_glyph(int width, int height, u
1308    
1309          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1310    
1311          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(g_display, g_wnd, width, height, 1);
1312          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(g_display, bitmap, 0, NULL);
1313    
1314          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(g_display, g_visual, 1, ZPixmap, 0, (char *) data,
1315                               data, width, height, 8, scanline);                               width, height, 8, scanline);
1316          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
1317          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
1318          XInitImage(image);          XInitImage(image);
1319    
1320          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(g_display, bitmap, gc, image, 0, 0, 0, 0, width, height);
1321    
1322          XFree(image);          XFree(image);
1323          XFreeGC(display, gc);          XFreeGC(g_display, gc);
1324          return (HGLYPH)bitmap;          return (HGLYPH) bitmap;
1325  }  }
1326    
1327  void  void
1328  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
1329  {  {
1330          XFreePixmap(display, (Pixmap)glyph);          XFreePixmap(g_display, (Pixmap) glyph);
1331  }  }
1332    
1333  HCURSOR  HCURSOR
1334  ui_create_cursor(unsigned int x, unsigned int y, int width,  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
1335                   int height, uint8 *andmask, uint8 *xormask)                   uint8 * andmask, uint8 * xormask)
1336  {  {
1337          HGLYPH maskglyph, cursorglyph;          HGLYPH maskglyph, cursorglyph;
1338          XColor bg, fg;          XColor bg, fg;
# Line 542  ui_create_cursor(unsigned int x, unsigne Line 1346  ui_create_cursor(unsigned int x, unsigne
1346          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1347          offset = scanline * height;          offset = scanline * height;
1348    
1349          cursor = xmalloc(offset);          cursor = (uint8 *) xmalloc(offset);
1350          memset(cursor, 0, offset);          memset(cursor, 0, offset);
1351    
1352          mask = xmalloc(offset);          mask = (uint8 *) xmalloc(offset);
1353          memset(mask, 0, offset);          memset(mask, 0, offset);
1354    
1355          /* approximate AND and XOR masks with a monochrome X pointer */          /* approximate AND and XOR masks with a monochrome X pointer */
# Line 585  ui_create_cursor(unsigned int x, unsigne Line 1389  ui_create_cursor(unsigned int x, unsigne
1389    
1390          cursorglyph = ui_create_glyph(width, height, cursor);          cursorglyph = ui_create_glyph(width, height, cursor);
1391          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
1392            
1393          xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,          xcursor =
1394                                  (Pixmap)maskglyph, &fg, &bg, x, y);                  XCreatePixmapCursor(g_display, (Pixmap) cursorglyph,
1395                                        (Pixmap) maskglyph, &fg, &bg, x, y);
1396    
1397          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
1398          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
1399          xfree(mask);          xfree(mask);
1400          xfree(cursor);          xfree(cursor);
1401          return (HCURSOR)xcursor;          return (HCURSOR) xcursor;
1402  }  }
1403    
1404  void  void
1405  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
1406  {  {
1407          XDefineCursor(display, wnd, (Cursor)cursor);          g_current_cursor = (Cursor) cursor;
1408            XDefineCursor(g_display, g_wnd, g_current_cursor);
1409  }  }
1410    
1411  void  void
1412  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_cursor(HCURSOR cursor)
1413  {  {
1414          XFreeCursor(display, (Cursor)cursor);          XFreeCursor(g_display, (Cursor) cursor);
1415    }
1416    
1417    void
1418    ui_set_null_cursor(void)
1419    {
1420            ui_set_cursor(g_null_cursor);
1421  }  }
1422    
1423  #define MAKE_XCOLOR(xc,c) \  #define MAKE_XCOLOR(xc,c) \
# Line 614  ui_destroy_cursor(HCURSOR cursor) Line 1426  ui_destroy_cursor(HCURSOR cursor)
1426                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
1427                  (xc)->flags = DoRed | DoGreen | DoBlue;                  (xc)->flags = DoRed | DoGreen | DoBlue;
1428    
1429    
1430  HCOLOURMAP  HCOLOURMAP
1431  ui_create_colourmap(COLOURMAP *colours)  ui_create_colourmap(COLOURMAP * colours)
1432  {  {
1433          COLOURENTRY *entry;          COLOURENTRY *entry;
1434          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
1435            if (!g_owncolmap)
         if (owncolmap)  
1436          {          {
1437                  XColor *xcolours, *xentry;                  uint32 *map = (uint32 *) xmalloc(sizeof(*g_colmap) * ncolours);
1438                  Colormap map;                  XColor xentry;
1439                    XColor xc_cache[256];
1440                  xcolours = xmalloc(sizeof(XColor) * ncolours);                  uint32 colour;
1441                    int colLookup = 256;
1442                  for (i = 0; i < ncolours; i++)                  for (i = 0; i < ncolours; i++)
1443                  {                  {
1444                          entry = &colours->colours[i];                          entry = &colours->colours[i];
1445                          xentry = &xcolours[i];                          MAKE_XCOLOR(&xentry, entry);
                         xentry->pixel = i;  
                         MAKE_XCOLOR(xentry, entry);  
                 }  
1446    
1447                  map = XCreateColormap(display, wnd, visual, AllocAll);                          if (XAllocColor(g_display, g_xcolmap, &xentry) == 0)
1448                  XStoreColors(display, map, xcolours, ncolours);                          {
1449                                    /* Allocation failed, find closest match. */
1450                                    int j = 256;
1451                                    int nMinDist = 3 * 256 * 256;
1452                                    long nDist = nMinDist;
1453    
1454                  xfree(xcolours);                                  /* only get the colors once */
1455                  return (HCOLOURMAP)map;                                  while (colLookup--)
1456                                    {
1457                                            xc_cache[colLookup].pixel = colLookup;
1458                                            xc_cache[colLookup].red = xc_cache[colLookup].green =
1459                                                    xc_cache[colLookup].blue = 0;
1460                                            xc_cache[colLookup].flags = 0;
1461                                            XQueryColor(g_display,
1462                                                        DefaultColormap(g_display,
1463                                                                        DefaultScreen(g_display)),
1464                                                        &xc_cache[colLookup]);
1465                                    }
1466                                    colLookup = 0;
1467    
1468                                    /* approximate the pixel */
1469                                    while (j--)
1470                                    {
1471                                            if (xc_cache[j].flags)
1472                                            {
1473                                                    nDist = ((long) (xc_cache[j].red >> 8) -
1474                                                             (long) (xentry.red >> 8)) *
1475                                                            ((long) (xc_cache[j].red >> 8) -
1476                                                             (long) (xentry.red >> 8)) +
1477                                                            ((long) (xc_cache[j].green >> 8) -
1478                                                             (long) (xentry.green >> 8)) *
1479                                                            ((long) (xc_cache[j].green >> 8) -
1480                                                             (long) (xentry.green >> 8)) +
1481                                                            ((long) (xc_cache[j].blue >> 8) -
1482                                                             (long) (xentry.blue >> 8)) *
1483                                                            ((long) (xc_cache[j].blue >> 8) -
1484                                                             (long) (xentry.blue >> 8));
1485                                            }
1486                                            if (nDist < nMinDist)
1487                                            {
1488                                                    nMinDist = nDist;
1489                                                    xentry.pixel = j;
1490                                            }
1491                                    }
1492                            }
1493                            colour = xentry.pixel;
1494    
1495                            /* update our cache */
1496                            if (xentry.pixel < 256)
1497                            {
1498                                    xc_cache[xentry.pixel].red = xentry.red;
1499                                    xc_cache[xentry.pixel].green = xentry.green;
1500                                    xc_cache[xentry.pixel].blue = xentry.blue;
1501    
1502                            }
1503    
1504    
1505                            /* byte swap here to make translate_image faster */
1506                            map[i] = translate_colour(colour);
1507                    }
1508                    return map;
1509          }          }
1510          else          else
1511          {          {
1512                  uint32 *map = xmalloc(sizeof(*colmap) * ncolours);                  XColor *xcolours, *xentry;
1513                  XColor xentry;                  Colormap map;
                 uint32 colour;  
1514    
1515                    xcolours = (XColor *) xmalloc(sizeof(XColor) * ncolours);
1516                  for (i = 0; i < ncolours; i++)                  for (i = 0; i < ncolours; i++)
1517                  {                  {
1518                          entry = &colours->colours[i];                          entry = &colours->colours[i];
1519                          MAKE_XCOLOR(&xentry, entry);                          xentry = &xcolours[i];
1520                            xentry->pixel = i;
1521                          if (XAllocColor(display, xcolmap, &xentry) != 0)                          MAKE_XCOLOR(xentry, entry);
                                 colour = xentry.pixel;  
                         else  
                                 colour = white;  
   
                         /* byte swap here to make translate_image faster */  
                         map[i] = translate_colour(colour);  
1522                  }                  }
1523    
1524                  return map;                  map = XCreateColormap(g_display, g_wnd, g_visual, AllocAll);
1525                    XStoreColors(g_display, map, xcolours, ncolours);
1526    
1527                    xfree(xcolours);
1528                    return (HCOLOURMAP) map;
1529          }          }
1530  }  }
1531    
1532  void  void
1533  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
1534  {  {
1535          if (owncolmap)          if (!g_owncolmap)
                 XFreeColormap(display, (Colormap)map);  
         else  
1536                  xfree(map);                  xfree(map);
1537            else
1538                    XFreeColormap(g_display, (Colormap) map);
1539  }  }
1540    
1541  void  void
1542  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
1543  {  {
1544          if (owncolmap)          if (!g_owncolmap)
1545                  XSetWindowColormap(display, wnd, (Colormap)map);          {
1546                    if (g_colmap)
1547                            xfree(g_colmap);
1548    
1549                    g_colmap = (uint32 *) map;
1550            }
1551          else          else
1552                  colmap = map;                  XSetWindowColormap(g_display, g_wnd, (Colormap) map);
1553  }  }
1554    
1555  void  void
# Line 691  ui_set_clip(int x, int y, int cx, int cy Line 1561  ui_set_clip(int x, int y, int cx, int cy
1561          rect.y = y;          rect.y = y;
1562          rect.width = cx;          rect.width = cx;
1563          rect.height = cy;          rect.height = cy;
1564          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);
1565  }  }
1566    
1567  void  void
1568  ui_reset_clip()  ui_reset_clip(void)
1569  {  {
1570          XRectangle rect;          XRectangle rect;
1571    
1572          rect.x = 0;          rect.x = 0;
1573          rect.y = 0;          rect.y = 0;
1574          rect.width = width;          rect.width = g_width;
1575          rect.height = height;          rect.height = g_height;
1576          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);
1577  }  }
1578    
1579  void  void
1580  ui_bell()  ui_bell(void)
1581  {  {
1582          XBell(display, 0);          XBell(g_display, 0);
1583  }  }
1584    
1585  void  void
# Line 721  ui_destblt(uint8 opcode, Line 1591  ui_destblt(uint8 opcode,
1591          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1592  }  }
1593    
1594    static uint8 hatch_patterns[] = {
1595            0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0 - bsHorizontal */
1596            0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 1 - bsVertical */
1597            0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, /* 2 - bsFDiagonal */
1598            0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* 3 - bsBDiagonal */
1599            0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, /* 4 - bsCross */
1600            0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81  /* 5 - bsDiagCross */
1601    };
1602    
1603  void  void
1604  ui_patblt(uint8 opcode,  ui_patblt(uint8 opcode,
1605            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1606            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1607  {  {
1608          Pixmap fill;          Pixmap fill;
1609            uint8 i, ipattern[8];
1610    
1611          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1612    
# Line 737  ui_patblt(uint8 opcode, Line 1617  ui_patblt(uint8 opcode,
1617                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1618                          break;                          break;
1619    
1620                    case 2: /* Hatch */
1621                            fill = (Pixmap) ui_create_glyph(8, 8,
1622                                                            hatch_patterns + brush->pattern[0] * 8);
1623                            SET_FOREGROUND(fgcolour);
1624                            SET_BACKGROUND(bgcolour);
1625                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
1626                            XSetStipple(g_display, g_gc, fill);
1627                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
1628                            FILL_RECTANGLE(x, y, cx, cy);
1629                            XSetFillStyle(g_display, g_gc, FillSolid);
1630                            XSetTSOrigin(g_display, g_gc, 0, 0);
1631                            ui_destroy_glyph((HGLYPH) fill);
1632                            break;
1633    
1634                  case 3: /* Pattern */                  case 3: /* Pattern */
1635                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);                          for (i = 0; i != 8; i++)
1636                                    ipattern[7 - i] = brush->pattern[i];
1637                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
1638    
1639                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(bgcolour);
1640                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
1641                          XSetFillStyle(display, gc, FillOpaqueStippled);                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
1642                          XSetStipple(display, gc, fill);                          XSetStipple(g_display, g_gc, fill);
1643                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
1644    
1645                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1646    
1647                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(g_display, g_gc, FillSolid);
1648                          ui_destroy_glyph((HGLYPH)fill);                          XSetTSOrigin(g_display, g_gc, 0, 0);
1649                            ui_destroy_glyph((HGLYPH) fill);
1650                          break;                          break;
1651    
1652                  default:                  default:
# Line 765  ui_screenblt(uint8 opcode, Line 1662  ui_screenblt(uint8 opcode,
1662               /* src */ int srcx, int srcy)               /* src */ int srcx, int srcy)
1663  {  {
1664          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1665          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
1666          if (ownbackstore)          if (g_ownbackstore)
1667                  XCopyArea(display, backstore, backstore, gc, srcx, srcy,                  XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1668          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1669  }  }
1670    
# Line 778  ui_memblt(uint8 opcode, Line 1674  ui_memblt(uint8 opcode,
1674            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
1675  {  {
1676          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1677          XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(g_display, (Pixmap) src, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
1678          if (ownbackstore)          if (g_ownbackstore)
1679                  XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,                  XCopyArea(g_display, (Pixmap) src, g_backstore, g_gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1680          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1681  }  }
1682    
# Line 789  void Line 1684  void
1684  ui_triblt(uint8 opcode,  ui_triblt(uint8 opcode,
1685            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1686            /* src */ HBITMAP src, int srcx, int srcy,            /* src */ HBITMAP src, int srcx, int srcy,
1687            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1688  {  {
1689          /* This is potentially difficult to do in general. Until someone          /* This is potentially difficult to do in general. Until someone
1690             comes up with a more efficient way of doing it I am using cases. */             comes up with a more efficient way of doing it I am using cases. */
# Line 798  ui_triblt(uint8 opcode, Line 1693  ui_triblt(uint8 opcode,
1693          {          {
1694                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
1695                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1696                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1697                          break;                          break;
1698    
1699                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
1700                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1701                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1702                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1703                          break;                          break;
1704    
1705                  case 0xc0:      /* PSa */                  case 0xc0:      /* PSa */
1706                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1707                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
1708                          break;                          break;
1709    
1710                  default:                  default:
# Line 825  ui_triblt(uint8 opcode, Line 1716  ui_triblt(uint8 opcode,
1716  void  void
1717  ui_line(uint8 opcode,  ui_line(uint8 opcode,
1718          /* dest */ int startx, int starty, int endx, int endy,          /* dest */ int startx, int starty, int endx, int endy,
1719          /* pen */ PEN *pen)          /* pen */ PEN * pen)
1720  {  {
1721          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1722          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
1723          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(g_display, g_wnd, g_gc, startx, starty, endx, endy);
1724          if (ownbackstore)          if (g_ownbackstore)
1725                  XDrawLine(display, backstore, gc, startx, starty, endx, endy);                  XDrawLine(g_display, g_backstore, g_gc, startx, starty, endx, endy);
1726          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1727  }  }
1728    
# Line 844  ui_rect( Line 1735  ui_rect(
1735          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
1736  }  }
1737    
1738    /* warning, this function only draws on wnd or backstore, not both */
1739  void  void
1740  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1741                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1742                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1743                int fgcolour)                int bgcolour, int fgcolour)
1744  {  {
1745          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
1746          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
1747    
1748          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)          XSetFillStyle(g_display, g_gc,
1749                        ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1750          XSetStipple(display, gc, (Pixmap)glyph);          XSetStipple(g_display, g_gc, (Pixmap) glyph);
1751          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(g_display, g_gc, x, y);
1752    
1753          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
1754    
1755          XSetFillStyle(display, gc, FillSolid);          XSetFillStyle(g_display, g_gc, FillSolid);
1756  }  }
1757    
1758  #define DO_GLYPH(ttext,idx) \  #define DO_GLYPH(ttext,idx) \
# Line 872  ui_draw_glyph(int mixmode, Line 1764  ui_draw_glyph(int mixmode,
1764        if ((xyoffset & 0x80))\        if ((xyoffset & 0x80))\
1765          {\          {\
1766            if (flags & TEXT2_VERTICAL) \            if (flags & TEXT2_VERTICAL) \
1767              y += ttext[++idx] | (ttext[++idx] << 8);\              y += ttext[idx+1] | (ttext[idx+2] << 8);\
1768            else\            else\
1769              x += ttext[++idx] | (ttext[++idx] << 8);\              x += ttext[idx+1] | (ttext[idx+2] << 8);\
1770              idx += 2;\
1771          }\          }\
1772        else\        else\
1773          {\          {\
# Line 886  ui_draw_glyph(int mixmode, Line 1779  ui_draw_glyph(int mixmode,
1779      }\      }\
1780    if (glyph != NULL)\    if (glyph != NULL)\
1781      {\      {\
1782        ui_draw_glyph (mixmode, x + (short) glyph->offset,\        ui_draw_glyph (mixmode, x + glyph->offset,\
1783                       y + (short) glyph->baseline,\                       y + glyph->baseline,\
1784                       glyph->width, glyph->height,\                       glyph->width, glyph->height,\
1785                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\                       glyph->pixmap, 0, 0, bgcolour, fgcolour);\
1786        if (flags & TEXT2_IMPLICIT_X)\        if (flags & TEXT2_IMPLICIT_X)\
# Line 897  ui_draw_glyph(int mixmode, Line 1790  ui_draw_glyph(int mixmode,
1790    
1791  void  void
1792  ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,  ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
1793               int clipx, int clipy, int clipcx, int clipcy, int boxx,               int clipx, int clipy, int clipcx, int clipcy,
1794               int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1795               int fgcolour, uint8 * text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1796  {  {
1797          FONTGLYPH *glyph;          FONTGLYPH *glyph;
# Line 909  ui_draw_text(uint8 font, uint8 flags, in Line 1802  ui_draw_text(uint8 font, uint8 flags, in
1802    
1803          if (boxcx > 1)          if (boxcx > 1)
1804          {          {
1805                  FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);
1806          }          }
1807          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
1808          {          {
1809                  FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
1810          }          }
1811    
1812          /* Paint text, character by character */          /* Paint text, character by character */
1813          for (i = 0; i < length;) {          for (i = 0; i < length;)
1814                  switch (text[i]) {          {
1815                  case 0xff:                  switch (text[i])
1816                          if (i + 2 < length)                  {
1817                                  cache_put_text(text[i + 1], text, text[i + 2]);                          case 0xff:
1818                          else {                                  if (i + 2 < length)
1819                                  error("this shouldn't be happening\n");                                          cache_put_text(text[i + 1], text, text[i + 2]);
1820                                  break;                                  else
1821                          }                                  {
1822                          /* this will move pointer from start to first character after FF command */                                          error("this shouldn't be happening\n");
1823                          length -= i + 3;                                          exit(1);
1824                          text = &(text[i + 3]);                                  }
1825                          i = 0;                                  /* this will move pointer from start to first character after FF command */
1826                          break;                                  length -= i + 3;
1827                                    text = &(text[i + 3]);
1828                  case 0xfe:                                  i = 0;
1829                          entry = cache_get_text(text[i + 1]);                                  break;
1830                          if (entry != NULL) {  
1831                                  if ((((uint8 *) (entry->data))[1] == 0)                          case 0xfe:
1832                                      && (!(flags & TEXT2_IMPLICIT_X))) {                                  entry = cache_get_text(text[i + 1]);
1833                                          if (flags & TEXT2_VERTICAL)                                        if (entry != NULL)
1834                                                  y += text[i + 2];                                  {
1835                                          else                                          if ((((uint8 *) (entry->data))[1] ==
1836                                                  x += text[i + 2];                                               0) && (!(flags & TEXT2_IMPLICIT_X)))
1837                                            {
1838                                                    if (flags & TEXT2_VERTICAL)
1839                                                            y += text[i + 2];
1840                                                    else
1841                                                            x += text[i + 2];
1842                                            }
1843                                            for (j = 0; j < entry->size; j++)
1844                                                    DO_GLYPH(((uint8 *) (entry->data)), j);
1845                                  }                                  }
1846                                  if (i + 2 < length)                                  if (i + 2 < length)
1847                                          i += 3;                                          i += 3;
1848                                  else                                  else
1849                                          i += 2;                                          i += 2;
1850                                  length -= i;                                    length -= i;
1851                                  /* this will move pointer from start to first character after FE command */                                  /* this will move pointer from start to first character after FE command */
1852                                  text = &(text[i]);                                  text = &(text[i]);
1853                                  i = 0;                                  i = 0;
1854                                  for (j = 0; j < entry->size; j++)                                  break;
                                         DO_GLYPH(((uint8 *) (entry->data)), j);  
                         }  
                         break;  
1855    
1856                  default:                          default:
1857                          DO_GLYPH(text, i);                                  DO_GLYPH(text, i);
1858                          i++;                                  i++;
1859                          break;                                  break;
1860                  }                  }
1861          }          }
1862            if (g_ownbackstore)
1863            {
1864                    if (boxcx > 1)
1865                            XCopyArea(g_display, g_backstore, g_wnd, g_gc, boxx,
1866                                      boxy, boxcx, boxcy, boxx, boxy);
1867                    else
1868                            XCopyArea(g_display, g_backstore, g_wnd, g_gc, clipx,
1869                                      clipy, clipcx, clipcy, clipx, clipy);
1870            }
1871  }  }
1872    
1873  void  void
# Line 971  ui_desktop_save(uint32 offset, int x, in Line 1876  ui_desktop_save(uint32 offset, int x, in
1876          Pixmap pix;          Pixmap pix;
1877          XImage *image;          XImage *image;
1878    
1879          if (ownbackstore)          if (g_ownbackstore)
1880          {          {
1881                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,                  image = XGetImage(g_display, g_backstore, x, y, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1882          }          }
1883          else          else
1884          {          {
1885                  pix = XCreatePixmap(display, wnd, cx, cy, depth);                  pix = XCreatePixmap(g_display, g_wnd, cx, cy, g_depth);
1886                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);                  XCopyArea(g_display, g_wnd, pix, g_gc, x, y, cx, cy, 0, 0);
1887                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,                  image = XGetImage(g_display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
1888                                    ZPixmap);                  XFreePixmap(g_display, pix);
                 XFreePixmap(display, pix);  
1889          }          }
1890    
1891          offset *= bpp/8;          offset *= g_bpp / 8;
1892          cache_put_desktop(offset, cx, cy, image->bytes_per_line,          cache_put_desktop(offset, cx, cy, image->bytes_per_line, g_bpp / 8, (uint8 *) image->data);
                           bpp/8, (uint8 *)image->data);  
1893    
1894          XDestroyImage(image);          XDestroyImage(image);
1895  }  }
# Line 998  ui_desktop_restore(uint32 offset, int x, Line 1900  ui_desktop_restore(uint32 offset, int x,
1900          XImage *image;          XImage *image;
1901          uint8 *data;          uint8 *data;
1902    
1903          offset *= bpp/8;          offset *= g_bpp / 8;
1904          data = cache_get_desktop(offset, cx, cy, bpp/8);          data = cache_get_desktop(offset, cx, cy, g_bpp / 8);
1905          if (data == NULL)          if (data == NULL)
1906                  return;                  return;
1907    
1908          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1909                               0, data, cx, cy, BitmapPad(display),                               (char *) data, cx, cy, BitmapPad(g_display), cx * g_bpp / 8);
                              cx * bpp/8);  
1910    
1911          if (ownbackstore)          if (g_ownbackstore)
1912          {          {
1913                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_backstore, g_gc, image, 0, 0, x, y, cx, cy);
1914                  XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);                  XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
1915          }          }
1916          else          else
1917          {          {
1918                  XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy);
1919          }          }
1920    
1921          XFree(image);          XFree(image);

Legend:
Removed from v.49  
changed lines
  Added in v.519

  ViewVC Help
Powered by ViewVC 1.1.26