/[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 38 by matthewc, Thu Apr 4 12:04:33 2002 UTC revision 508 by astrand, Wed Oct 22 10:55:11 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)          if (g_owncolmap != True)
709                  owncolmap = True;          {
710          else                  g_xcolmap = DefaultColormapOfScreen(g_screen);
711                  xcolmap = DefaultColormapOfScreen(screen);                  if (g_depth <= 8)
712                            warning("Screen depth is 8 bits or lower: you may want to use -C for a private colourmap\n");
713            }
714    
715          test = 1;          g_gc = XCreateGC(g_display, RootWindowOfScreen(g_screen), 0, NULL);
         host_be = !(BOOL)(*(uint8 *)(&test));  
         xserver_be = (ImageByteOrder(display) == MSBFirst);  
716    
717          white = WhitePixelOfScreen(screen);          if (DoesBackingStore(g_screen) != Always)
718          attribs.background_pixel = BlackPixelOfScreen(screen);                  g_ownbackstore = True;
         attribs.backing_store = DoesBackingStore(screen);  
719    
720          if (attribs.backing_store == NotUseful)          test = 1;
721                  ownbackstore = True;          g_host_be = !(BOOL) (*(uint8 *) (&test));
722            g_xserver_be = (ImageByteOrder(g_display) == MSBFirst);
723    
724          if (fullscreen)          /*
725             * Determine desktop size
726             */
727            if (g_width < 0)
728          {          {
729                  attribs.override_redirect = True;                  /* Percent of screen */
730                  width = WidthOfScreen(screen);                  g_height = HeightOfScreen(g_screen) * (-g_width) / 100;
731                  height = HeightOfScreen(screen);                  g_width = WidthOfScreen(g_screen) * (-g_width) / 100;
732          }          }
733          else          else if (g_width == 0)
734          {          {
735                  attribs.override_redirect = False;                  /* Fetch geometry from _NET_WORKAREA */
736                    uint32 x, y, cx, cy;
737    
738                    if (get_current_workarea(&x, &y, &cx, &cy) == 0)
739                    {
740                            g_width = cx;
741                            g_height = cy;
742                    }
743                    else
744                    {
745                            warning("Failed to get workarea: probably your window manager does not support extended hints\n");
746                            g_width = 800;
747                            g_height = 600;
748                    }
749          }          }
750            else if (g_fullscreen)
751            {
752                    g_width = WidthOfScreen(g_screen);
753                    g_height = HeightOfScreen(g_screen);
754            }
755    
756            /* make sure width is a multiple of 4 */
757            g_width = (g_width + 3) & ~3;
758    
759            if (g_ownbackstore)
760            {
761                    g_backstore =
762                            XCreatePixmap(g_display, RootWindowOfScreen(g_screen), g_width, g_height,
763                                          g_depth);
764    
765                    /* clear to prevent rubbish being exposed at startup */
766                    XSetForeground(g_display, g_gc, BlackPixelOfScreen(g_screen));
767                    XFillRectangle(g_display, g_backstore, g_gc, 0, 0, g_width, g_height);
768            }
769    
770            g_mod_map = XGetModifierMapping(g_display);
771    
772            xkeymap_init();
773    
774            if (g_enable_compose)
775                    g_IM = XOpenIM(g_display, NULL, NULL, NULL);
776    
777            xclip_init();
778    
779            /* todo take this out when high colour is done */
780            printf("server bpp %d client bpp %d depth %d\n", g_server_bpp, g_bpp, g_depth);
781    
782            return True;
783    }
784    
785    void
786    ui_deinit(void)
787    {
788            if (g_IM != NULL)
789                    XCloseIM(g_IM);
790    
791            XFreeModifiermap(g_mod_map);
792    
793            if (g_ownbackstore)
794                    XFreePixmap(g_display, g_backstore);
795    
796            XFreeGC(g_display, g_gc);
797            XCloseDisplay(g_display);
798            g_display = NULL;
799    }
800    
801          width = (width + 3) & ~3; /* make width a multiple of 32 bits */  #define NULL_POINTER_MASK       "\x80"
802    #define NULL_POINTER_DATA       "\x0\x0\x0"
803            
804    BOOL
805    ui_create_window(void)
806    {
807            XSetWindowAttributes attribs;
808            XClassHint *classhints;
809            XSizeHints *sizehints;
810            int wndwidth, wndheight;
811            long input_mask, ic_input_mask;
812            XEvent xevent;
813    
814            wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;
815            wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;
816    
817            attribs.background_pixel = BlackPixelOfScreen(g_screen);
818            attribs.backing_store = g_ownbackstore ? NotUseful : Always;
819            attribs.override_redirect = g_fullscreen;
820    
821          wnd = XCreateWindow(display, RootWindowOfScreen(screen),          g_wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), 0, 0, wndwidth, wndheight,
822                              0, 0, width, height, 0, CopyFromParent,                                0, CopyFromParent, InputOutput, CopyFromParent,
823                              InputOutput, CopyFromParent,                                CWBackPixel | CWBackingStore | CWOverrideRedirect, &attribs);
                             CWBackingStore | CWBackPixel | CWOverrideRedirect,  
                             &attribs);  
824    
825          XStoreName(display, wnd, title);          XStoreName(g_display, g_wnd, g_title);
826    
827            if (g_hide_decorations)
828                    mwm_hide_decorations();
829    
830          classhints = XAllocClassHint();          classhints = XAllocClassHint();
831          if (classhints != NULL)          if (classhints != NULL)
832          {          {
833                  classhints->res_name = classhints->res_class = "rdesktop";                  classhints->res_name = classhints->res_class = "rdesktop";
834                  XSetClassHint(display, wnd, classhints);                  XSetClassHint(g_display, g_wnd, classhints);
835                  XFree(classhints);                  XFree(classhints);
836          }          }
837    
# Line 276  ui_create_window(char *title) Line 839  ui_create_window(char *title)
839          if (sizehints)          if (sizehints)
840          {          {
841                  sizehints->flags = PMinSize | PMaxSize;                  sizehints->flags = PMinSize | PMaxSize;
842                  sizehints->min_width = sizehints->max_width = width;                  sizehints->min_width = sizehints->max_width = g_width;
843                  sizehints->min_height = sizehints->max_height = height;                  sizehints->min_height = sizehints->max_height = g_height;
844                  XSetWMNormalHints(display, wnd, sizehints);                  XSetWMNormalHints(g_display, g_wnd, sizehints);
845                  XFree(sizehints);                  XFree(sizehints);
846          }          }
847    
848          xkeymap_init(display);          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
849                    VisibilityChangeMask | FocusChangeMask;
         input_mask = KeyPressMask | KeyReleaseMask  
                         | ButtonPressMask | ButtonReleaseMask  
                         | EnterWindowMask | LeaveWindowMask;  
850    
851          if (sendmotion)          if (g_sendmotion)
852                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
853            if (g_ownbackstore)
         if (ownbackstore)  
854                  input_mask |= ExposureMask;                  input_mask |= ExposureMask;
855            if (g_fullscreen || g_grab_keyboard)
856                    input_mask |= EnterWindowMask;
857            if (g_grab_keyboard)
858                    input_mask |= LeaveWindowMask;
859    
860            if (g_IM != NULL)
861            {
862                    g_IC = XCreateIC(g_IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
863                                     XNClientWindow, g_wnd, XNFocusWindow, g_wnd, NULL);
864    
865                    if ((g_IC != NULL)
866                        && (XGetICValues(g_IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))
867                            input_mask |= ic_input_mask;
868            }
869    
870          XSelectInput(display, wnd, input_mask);          XSelectInput(g_display, g_wnd, input_mask);
871          gc = XCreateGC(display, wnd, 0, NULL);          XMapWindow(g_display, g_wnd);
872    
873          if (ownbackstore)          /* wait for VisibilityNotify */
874                  backstore = XCreatePixmap(display, wnd, width, height, depth);          do
875            {
876                    XMaskEvent(g_display, VisibilityChangeMask, &xevent);
877            }
878            while (xevent.type != VisibilityNotify);
879    
880            g_focused = False;
881            g_mouse_in_wnd = False;
882    
883            /* handle the WM_DELETE_WINDOW protocol */
884            g_protocol_atom = XInternAtom(g_display, "WM_PROTOCOLS", True);
885            g_kill_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", True);
886            XSetWMProtocols(g_display, g_wnd, &g_kill_atom, 1);
887    
888            /* create invisible 1x1 cursor to be used as null cursor */
889            g_null_cursor = ui_create_cursor(0, 0, 1, 1, NULL_POINTER_MASK, NULL_POINTER_DATA);
890    
         XMapWindow(display, wnd);  
891          return True;          return True;
892  }  }
893    
894  void  void
895  ui_destroy_window()  ui_destroy_window(void)
896  {  {
897          if (ownbackstore)          ui_destroy_cursor(g_null_cursor);
898                  XFreePixmap(display, backstore);          
899            if (g_IC != NULL)
900                    XDestroyIC(g_IC);
901    
902          XFreeGC(display, gc);          XDestroyWindow(g_display, g_wnd);
         XDestroyWindow(display, wnd);  
         XCloseDisplay(display);  
         display = NULL;  
903  }  }
904    
905  static void  void
906  xwin_process_events()  xwin_toggle_fullscreen(void)
907  {  {
908          XEvent event;          Pixmap contents = 0;
909    
910            if (!g_ownbackstore)
911            {
912                    /* need to save contents of window */
913                    contents = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
914                    XCopyArea(g_display, g_wnd, contents, g_gc, 0, 0, g_width, g_height, 0, 0);
915            }
916    
917            ui_destroy_window();
918            g_fullscreen = !g_fullscreen;
919            ui_create_window();
920    
921            XDefineCursor(g_display, g_wnd, g_current_cursor);
922    
923            if (!g_ownbackstore)
924            {
925                    XCopyArea(g_display, contents, g_wnd, g_gc, 0, 0, g_width, g_height, 0, 0);
926                    XFreePixmap(g_display, contents);
927            }
928    }
929    
930    /* Process all events in Xlib queue
931       Returns 0 after user quit, 1 otherwise */
932    static int
933    xwin_process_events(void)
934    {
935            XEvent xevent;
936          KeySym keysym;          KeySym keysym;
937          uint8 scancode;          uint16 button, flags;
         uint16 button;  
938          uint32 ev_time;          uint32 ev_time;
939            key_translation tr;
940            char str[256];
941            Status status;
942            unsigned int state;
943            Window wdummy;
944            int dummy;
945    
946          if (display == NULL)          while (XPending(g_display) > 0)
                 return;  
   
         while (XCheckWindowEvent(display, wnd, ~0, &event))  
947          {          {
948                  ev_time = time(NULL);                  XNextEvent(g_display, &xevent);
949    
950                  switch (event.type)                  if ((g_IC != NULL) && (XFilterEvent(&xevent, None) == True))
951                  {                  {
952                            DEBUG_KBD(("Filtering event\n"));
953                            continue;
954                    }
955    
956                    flags = 0;
957    
958                    switch (xevent.type)
959                    {
960                            case ClientMessage:
961                                    /* the window manager told us to quit */
962                                    if ((xevent.xclient.message_type == g_protocol_atom)
963                                        && ((Atom) xevent.xclient.data.l[0] == g_kill_atom))
964                                            /* Quit */
965                                            return 0;
966                                    break;
967    
968                          case KeyPress:                          case KeyPress:
969                                  keysym = XKeycodeToKeysym(display, event.xkey.keycode, 0);                                  g_last_gesturetime = xevent.xkey.time;
970                                  scancode = xkeymap_translate_key(keysym, event.xkey.keycode);                                  if (g_IC != NULL)
971                                  if (scancode == 0)                                          /* Multi_key compatible version */
972                                    {
973                                            XmbLookupString(g_IC,
974                                                            &xevent.xkey, str, sizeof(str), &keysym,
975                                                            &status);
976                                            if (!((status == XLookupKeySym) || (status == XLookupBoth)))
977                                            {
978                                                    error("XmbLookupString failed with status 0x%x\n",
979                                                          status);
980                                                    break;
981                                            }
982                                    }
983                                    else
984                                    {
985                                            /* Plain old XLookupString */
986                                            DEBUG_KBD(("\nNo input context, using XLookupString\n"));
987                                            XLookupString((XKeyEvent *) & xevent,
988                                                          str, sizeof(str), &keysym, NULL);
989                                    }
990    
991                                    DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,
992                                               get_ksname(keysym)));
993    
994                                    ev_time = time(NULL);
995                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
996                                            break;
997    
998                                    tr = xkeymap_translate_key(keysym,
999                                                               xevent.xkey.keycode, xevent.xkey.state);
1000    
1001                                    if (tr.scancode == 0)
1002                                          break;                                          break;
1003    
1004                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,                                  save_remote_modifiers(tr.scancode);
1005                                                 scancode, 0);                                  ensure_remote_modifiers(ev_time, tr);
1006                                    rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
1007                                    restore_remote_modifiers(ev_time, tr.scancode);
1008    
1009                                  break;                                  break;
1010    
1011                          case KeyRelease:                          case KeyRelease:
1012                                  keysym = XKeycodeToKeysym(display, event.xkey.keycode, 0);                                  g_last_gesturetime = xevent.xkey.time;
1013                                  scancode = xkeymap_translate_key(keysym, event.xkey.keycode);                                  XLookupString((XKeyEvent *) & xevent, str,
1014                                  if (scancode == 0)                                                sizeof(str), &keysym, NULL);
1015    
1016                                    DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
1017                                               get_ksname(keysym)));
1018    
1019                                    ev_time = time(NULL);
1020                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
1021                                          break;                                          break;
1022    
1023                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE,                                  tr = xkeymap_translate_key(keysym,
1024                                                 KBD_FLAG_DOWN | KBD_FLAG_UP,                                                             xevent.xkey.keycode, xevent.xkey.state);
                                                scancode, 0);  
                                 break;  
1025    
1026                          case ButtonPress:                                  if (tr.scancode == 0)
                                 button = xkeymap_translate_button(event.xbutton.button);  
                                 if (button == 0)  
1027                                          break;                                          break;
1028    
1029                                  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);  
1030                                  break;                                  break;
1031    
1032                            case ButtonPress:
1033                                    flags = MOUSE_FLAG_DOWN;
1034                                    /* fall through */
1035    
1036                          case ButtonRelease:                          case ButtonRelease:
1037                                  button = xkeymap_translate_button(event.xbutton.button);                                  g_last_gesturetime = xevent.xbutton.time;
1038                                    button = xkeymap_translate_button(xevent.xbutton.button);
1039                                  if (button == 0)                                  if (button == 0)
1040                                          break;                                          break;
1041    
1042                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  /* If win_button_size is nonzero, enable single app mode */
1043                                                 button,                                  if (xevent.xbutton.y < g_win_button_size)
1044                                                 event.xbutton.x,                                  {
1045                                                 event.xbutton.y);                                          /* Stop moving window when button is released, regardless of cursor position */
1046                                            if (g_moving_wnd && (xevent.type == ButtonRelease))
1047                                                    g_moving_wnd = False;
1048    
1049                                            /*  Check from right to left: */
1050    
1051                                            if (xevent.xbutton.x >= g_width - g_win_button_size)
1052                                            {
1053                                                    /* The close button, continue */
1054                                                    ;
1055                                            }
1056                                            else if (xevent.xbutton.x >=
1057                                                     g_width - g_win_button_size * 2)
1058                                            {
1059                                                    /* The maximize/restore button. Do not send to
1060                                                       server.  It might be a good idea to change the
1061                                                       cursor or give some other visible indication
1062                                                       that rdesktop inhibited this click */
1063                                                    break;
1064                                            }
1065                                            else if (xevent.xbutton.x >=
1066                                                     g_width - g_win_button_size * 3)
1067                                            {
1068                                                    /* The minimize button. Iconify window. */
1069                                                    XIconifyWindow(g_display, g_wnd,
1070                                                                   DefaultScreen(g_display));
1071                                                    break;
1072                                            }
1073                                            else if (xevent.xbutton.x <= g_win_button_size)
1074                                            {
1075                                                    /* The system menu. Ignore. */
1076                                                    break;
1077                                            }
1078                                            else
1079                                            {
1080                                                    /* The title bar. */
1081                                                    if ((xevent.type == ButtonPress) && !g_fullscreen
1082                                                        && g_hide_decorations)
1083                                                    {
1084                                                            g_moving_wnd = True;
1085                                                            g_move_x_offset = xevent.xbutton.x;
1086                                                            g_move_y_offset = xevent.xbutton.y;
1087                                                    }
1088                                                    break;
1089    
1090                                            }
1091                                    }
1092    
1093                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1094                                                   flags | button, xevent.xbutton.x, xevent.xbutton.y);
1095                                  break;                                  break;
1096    
1097                          case MotionNotify:                          case MotionNotify:
1098                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  if (g_moving_wnd)
1099                                                 MOUSE_FLAG_MOVE,                                  {
1100                                                 event.xmotion.x,                                          XMoveWindow(g_display, g_wnd,
1101                                                 event.xmotion.y);                                                      xevent.xmotion.x_root - g_move_x_offset,
1102                                                        xevent.xmotion.y_root - g_move_y_offset);
1103                                            break;
1104                                    }
1105    
1106                                    if (g_fullscreen && !g_focused)
1107                                            XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,
1108                                                           CurrentTime);
1109                                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1110                                                   MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
1111                                    break;
1112    
1113                            case FocusIn:
1114                                    if (xevent.xfocus.mode == NotifyGrab)
1115                                            break;
1116                                    g_focused = True;
1117                                    XQueryPointer(g_display, g_wnd, &wdummy, &wdummy, &dummy, &dummy,
1118                                                  &dummy, &dummy, &state);
1119                                    reset_modifier_keys(state);
1120                                    if (g_grab_keyboard && g_mouse_in_wnd)
1121                                            XGrabKeyboard(g_display, g_wnd, True,
1122                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
1123                                    break;
1124    
1125                            case FocusOut:
1126                                    if (xevent.xfocus.mode == NotifyUngrab)
1127                                            break;
1128                                    g_focused = False;
1129                                    if (xevent.xfocus.mode == NotifyWhileGrabbed)
1130                                            XUngrabKeyboard(g_display, CurrentTime);
1131                                  break;                                  break;
1132    
1133                          case EnterNotify:                          case EnterNotify:
1134                                  XGrabKeyboard(display, wnd, True, GrabModeAsync,                                  /* we only register for this event when in fullscreen mode */
1135                                                GrabModeAsync, CurrentTime);                                  /* or grab_keyboard */
1136                                    g_mouse_in_wnd = True;
1137                                    if (g_fullscreen)
1138                                    {
1139                                            XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,
1140                                                           CurrentTime);
1141                                            break;
1142                                    }
1143                                    if (g_focused)
1144                                            XGrabKeyboard(g_display, g_wnd, True,
1145                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
1146                                  break;                                  break;
1147    
1148                          case LeaveNotify:                          case LeaveNotify:
1149                                  XUngrabKeyboard(display, CurrentTime);                                  /* we only register for this event when grab_keyboard */
1150                                    g_mouse_in_wnd = False;
1151                                    XUngrabKeyboard(g_display, CurrentTime);
1152                                  break;                                  break;
1153    
1154                          case Expose:                          case Expose:
1155                                  XCopyArea(display, backstore, wnd, gc,                                  XCopyArea(g_display, g_backstore, g_wnd, g_gc,
1156                                            event.xexpose.x, event.xexpose.y,                                            xevent.xexpose.x, xevent.xexpose.y,
1157                                            event.xexpose.width, event.xexpose.height,                                            xevent.xexpose.width,
1158                                            event.xexpose.x, event.xexpose.y);                                            xevent.xexpose.height,
1159                                              xevent.xexpose.x, xevent.xexpose.y);
1160                                    break;
1161    
1162                            case MappingNotify:
1163                                    /* Refresh keyboard mapping if it has changed. This is important for
1164                                       Xvnc, since it allocates keycodes dynamically */
1165                                    if (xevent.xmapping.request == MappingKeyboard
1166                                        || xevent.xmapping.request == MappingModifier)
1167                                            XRefreshKeyboardMapping(&xevent.xmapping);
1168    
1169                                    if (xevent.xmapping.request == MappingModifier)
1170                                    {
1171                                            XFreeModifiermap(g_mod_map);
1172                                            g_mod_map = XGetModifierMapping(g_display);
1173                                    }
1174                                    break;
1175    
1176                                    /* clipboard stuff */
1177                            case SelectionNotify:
1178                                    xclip_handle_SelectionNotify(&xevent.xselection);
1179                                    break;
1180                            case SelectionRequest:
1181                                    xclip_handle_SelectionRequest(&xevent.xselectionrequest);
1182                                    break;
1183                            case SelectionClear:
1184                                    xclip_handle_SelectionClear();
1185                                    break;
1186                            case PropertyNotify:
1187                                    xclip_handle_PropertyNotify(&xevent.xproperty);
1188                                  break;                                  break;
1189                  }                  }
1190          }          }
1191            /* Keep going */
1192            return 1;
1193  }  }
1194    
1195  void  /* Returns 0 after user quit, 1 otherwise */
1196    int
1197  ui_select(int rdp_socket)  ui_select(int rdp_socket)
1198  {  {
1199          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;
1200          fd_set rfds;          fd_set rfds, wfds;
   
         XFlush(display);  
   
         FD_ZERO(&rfds);  
1201    
1202          while (True)          while (True)
1203          {          {
1204                    /* Process any events already waiting */
1205                    if (!xwin_process_events())
1206                            /* User quit */
1207                            return 0;
1208    
1209                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
1210                    FD_ZERO(&wfds);
1211                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
1212                  FD_SET(x_socket, &rfds);                  FD_SET(g_x_socket, &rfds);
1213    
1214    #ifdef WITH_RDPSND
1215                    /* FIXME: there should be an API for registering fds */
1216                    if (g_dsp_busy)
1217                    {
1218                            FD_SET(g_dsp_fd, &wfds);
1219                            n = (g_dsp_fd + 1 > n) ? g_dsp_fd + 1 : n;
1220                    }
1221    #endif
1222    
1223                  switch (select(n, &rfds, NULL, NULL, NULL))                  switch (select(n, &rfds, &wfds, NULL, NULL))
1224                  {                  {
1225                          case -1:                          case -1:
1226                                  error("select: %s\n", strerror(errno));                                  error("select: %s\n", strerror(errno));
# Line 428  ui_select(int rdp_socket) Line 1229  ui_select(int rdp_socket)
1229                                  continue;                                  continue;
1230                  }                  }
1231    
                 if (FD_ISSET(x_socket, &rfds))  
                         xwin_process_events();  
   
1232                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
1233                          return;                          return 1;
1234    
1235    #ifdef WITH_RDPSND
1236                    if (g_dsp_busy && FD_ISSET(g_dsp_fd, &wfds))
1237                            wave_out_play();
1238    #endif
1239          }          }
1240  }  }
1241    
1242  void  void
1243  ui_move_pointer(int x, int y)  ui_move_pointer(int x, int y)
1244  {  {
1245          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);          XWarpPointer(g_display, g_wnd, g_wnd, 0, 0, 0, 0, x, y);
1246  }  }
1247    
1248  HBITMAP  HBITMAP
1249  ui_create_bitmap(int width, int height, uint8 *data)  ui_create_bitmap(int width, int height, uint8 * data)
1250  {  {
1251          XImage *image;          XImage *image;
1252          Pixmap bitmap;          Pixmap bitmap;
1253          uint8 *tdata;          uint8 *tdata;
1254    
1255          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (g_owncolmap ? data : translate_image(width, height, data));
1256          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(g_display, g_wnd, width, height, g_depth);
1257          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1258                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, g_server_bpp == 8 ? 8 : g_bpp, 0);
1259    
1260          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(g_display, bitmap, g_gc, image, 0, 0, 0, 0, width, height);
1261    
1262          XFree(image);          XFree(image);
1263          if (!owncolmap)          if (!g_owncolmap)
1264                  xfree(tdata);                  xfree(tdata);
1265          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
1266  }  }
1267    
1268  void  void
1269  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)  
1270  {  {
1271          XImage *image;          XImage *image;
1272          uint8 *tdata;          uint8 *tdata;
1273            tdata = (g_owncolmap ? data : translate_image(width, height, data));
1274            image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1275                                 (char *) tdata, width, height, g_server_bpp == 8 ? 8 : g_bpp, 0);
1276    
1277          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)  
1278          {          {
1279                  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);
1280                  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);
1281          }          }
1282          else          else
1283          {          {
1284                  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);
1285          }          }
1286    
1287          XFree(image);          XFree(image);
1288          if (!owncolmap)          if (!g_owncolmap)
1289                  xfree(tdata);                  xfree(tdata);
1290  }  }
1291    
1292  void  void
1293  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(HBITMAP bmp)
1294  {  {
1295          XFreePixmap(display, (Pixmap)bmp);          XFreePixmap(g_display, (Pixmap) bmp);
1296  }  }
1297    
1298  HGLYPH  HGLYPH
1299  ui_create_glyph(int width, int height, uint8 *data)  ui_create_glyph(int width, int height, uint8 * data)
1300  {  {
1301          XImage *image;          XImage *image;
1302          Pixmap bitmap;          Pixmap bitmap;
# Line 504  ui_create_glyph(int width, int height, u Line 1305  ui_create_glyph(int width, int height, u
1305    
1306          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1307    
1308          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(g_display, g_wnd, width, height, 1);
1309          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(g_display, bitmap, 0, NULL);
1310    
1311          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(g_display, g_visual, 1, ZPixmap, 0, (char *) data,
1312                               data, width, height, 8, scanline);                               width, height, 8, scanline);
1313          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
1314          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
1315          XInitImage(image);          XInitImage(image);
1316    
1317          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(g_display, bitmap, gc, image, 0, 0, 0, 0, width, height);
1318    
1319          XFree(image);          XFree(image);
1320          XFreeGC(display, gc);          XFreeGC(g_display, gc);
1321          return (HGLYPH)bitmap;          return (HGLYPH) bitmap;
1322  }  }
1323    
1324  void  void
1325  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
1326  {  {
1327          XFreePixmap(display, (Pixmap)glyph);          XFreePixmap(g_display, (Pixmap) glyph);
1328  }  }
1329    
1330  HCURSOR  HCURSOR
1331  ui_create_cursor(unsigned int x, unsigned int y, int width,  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
1332                   int height, uint8 *andmask, uint8 *xormask)                   uint8 * andmask, uint8 * xormask)
1333  {  {
1334          HGLYPH maskglyph, cursorglyph;          HGLYPH maskglyph, cursorglyph;
1335          XColor bg, fg;          XColor bg, fg;
# Line 542  ui_create_cursor(unsigned int x, unsigne Line 1343  ui_create_cursor(unsigned int x, unsigne
1343          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
1344          offset = scanline * height;          offset = scanline * height;
1345    
1346          cursor = xmalloc(offset);          cursor = (uint8 *) xmalloc(offset);
1347          memset(cursor, 0, offset);          memset(cursor, 0, offset);
1348    
1349          mask = xmalloc(offset);          mask = (uint8 *) xmalloc(offset);
1350          memset(mask, 0, offset);          memset(mask, 0, offset);
1351    
1352          /* 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 1386  ui_create_cursor(unsigned int x, unsigne
1386    
1387          cursorglyph = ui_create_glyph(width, height, cursor);          cursorglyph = ui_create_glyph(width, height, cursor);
1388          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
1389            
1390          xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,          xcursor =
1391                                  (Pixmap)maskglyph, &fg, &bg, x, y);                  XCreatePixmapCursor(g_display, (Pixmap) cursorglyph,
1392                                        (Pixmap) maskglyph, &fg, &bg, x, y);
1393    
1394          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
1395          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
1396          xfree(mask);          xfree(mask);
1397          xfree(cursor);          xfree(cursor);
1398          return (HCURSOR)xcursor;          return (HCURSOR) xcursor;
1399  }  }
1400    
1401  void  void
1402  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
1403  {  {
1404          XDefineCursor(display, wnd, (Cursor)cursor);          g_current_cursor = (Cursor) cursor;
1405            XDefineCursor(g_display, g_wnd, g_current_cursor);
1406  }  }
1407    
1408  void  void
1409  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_cursor(HCURSOR cursor)
1410  {  {
1411          XFreeCursor(display, (Cursor)cursor);          XFreeCursor(g_display, (Cursor) cursor);
1412    }
1413    
1414    void
1415    ui_set_null_cursor(void)
1416    {
1417            ui_set_cursor(g_null_cursor);
1418  }  }
1419    
1420  #define MAKE_XCOLOR(xc,c) \  #define MAKE_XCOLOR(xc,c) \
# Line 614  ui_destroy_cursor(HCURSOR cursor) Line 1423  ui_destroy_cursor(HCURSOR cursor)
1423                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \                  (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
1424                  (xc)->flags = DoRed | DoGreen | DoBlue;                  (xc)->flags = DoRed | DoGreen | DoBlue;
1425    
1426    
1427  HCOLOURMAP  HCOLOURMAP
1428  ui_create_colourmap(COLOURMAP *colours)  ui_create_colourmap(COLOURMAP * colours)
1429  {  {
1430          COLOURENTRY *entry;          COLOURENTRY *entry;
1431          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
1432            if (!g_owncolmap)
         if (owncolmap)  
1433          {          {
1434                  XColor *xcolours, *xentry;                  uint32 *map = (uint32 *) xmalloc(sizeof(*g_colmap) * ncolours);
1435                  Colormap map;                  XColor xentry;
1436                    XColor xc_cache[256];
1437                  xcolours = xmalloc(sizeof(XColor) * ncolours);                  uint32 colour;
1438                    int colLookup = 256;
1439                  for (i = 0; i < ncolours; i++)                  for (i = 0; i < ncolours; i++)
1440                  {                  {
1441                          entry = &colours->colours[i];                          entry = &colours->colours[i];
1442                          xentry = &xcolours[i];                          MAKE_XCOLOR(&xentry, entry);
                         xentry->pixel = i;  
                         MAKE_XCOLOR(xentry, entry);  
                 }  
1443    
1444                  map = XCreateColormap(display, wnd, visual, AllocAll);                          if (XAllocColor(g_display, g_xcolmap, &xentry) == 0)
1445                  XStoreColors(display, map, xcolours, ncolours);                          {
1446                                    /* Allocation failed, find closest match. */
1447                                    int j = 256;
1448                                    int nMinDist = 3 * 256 * 256;
1449                                    long nDist = nMinDist;
1450    
1451                  xfree(xcolours);                                  /* only get the colors once */
1452                  return (HCOLOURMAP)map;                                  while (colLookup--)
1453                                    {
1454                                            xc_cache[colLookup].pixel = colLookup;
1455                                            xc_cache[colLookup].red = xc_cache[colLookup].green =
1456                                                    xc_cache[colLookup].blue = 0;
1457                                            xc_cache[colLookup].flags = 0;
1458                                            XQueryColor(g_display,
1459                                                        DefaultColormap(g_display,
1460                                                                        DefaultScreen(g_display)),
1461                                                        &xc_cache[colLookup]);
1462                                    }
1463                                    colLookup = 0;
1464    
1465                                    /* approximate the pixel */
1466                                    while (j--)
1467                                    {
1468                                            if (xc_cache[j].flags)
1469                                            {
1470                                                    nDist = ((long) (xc_cache[j].red >> 8) -
1471                                                             (long) (xentry.red >> 8)) *
1472                                                            ((long) (xc_cache[j].red >> 8) -
1473                                                             (long) (xentry.red >> 8)) +
1474                                                            ((long) (xc_cache[j].green >> 8) -
1475                                                             (long) (xentry.green >> 8)) *
1476                                                            ((long) (xc_cache[j].green >> 8) -
1477                                                             (long) (xentry.green >> 8)) +
1478                                                            ((long) (xc_cache[j].blue >> 8) -
1479                                                             (long) (xentry.blue >> 8)) *
1480                                                            ((long) (xc_cache[j].blue >> 8) -
1481                                                             (long) (xentry.blue >> 8));
1482                                            }
1483                                            if (nDist < nMinDist)
1484                                            {
1485                                                    nMinDist = nDist;
1486                                                    xentry.pixel = j;
1487                                            }
1488                                    }
1489                            }
1490                            colour = xentry.pixel;
1491    
1492                            /* update our cache */
1493                            if (xentry.pixel < 256)
1494                            {
1495                                    xc_cache[xentry.pixel].red = xentry.red;
1496                                    xc_cache[xentry.pixel].green = xentry.green;
1497                                    xc_cache[xentry.pixel].blue = xentry.blue;
1498    
1499                            }
1500    
1501    
1502                            /* byte swap here to make translate_image faster */
1503                            map[i] = translate_colour(colour);
1504                    }
1505                    return map;
1506          }          }
1507          else          else
1508          {          {
1509                  uint32 *map = xmalloc(sizeof(*colmap) * ncolours);                  XColor *xcolours, *xentry;
1510                  XColor xentry;                  Colormap map;
                 uint32 colour;  
1511    
1512                    xcolours = (XColor *) xmalloc(sizeof(XColor) * ncolours);
1513                  for (i = 0; i < ncolours; i++)                  for (i = 0; i < ncolours; i++)
1514                  {                  {
1515                          entry = &colours->colours[i];                          entry = &colours->colours[i];
1516                          MAKE_XCOLOR(&xentry, entry);                          xentry = &xcolours[i];
1517                            xentry->pixel = i;
1518                          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);  
1519                  }                  }
1520    
1521                  return map;                  map = XCreateColormap(g_display, g_wnd, g_visual, AllocAll);
1522                    XStoreColors(g_display, map, xcolours, ncolours);
1523    
1524                    xfree(xcolours);
1525                    return (HCOLOURMAP) map;
1526          }          }
1527  }  }
1528    
1529  void  void
1530  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
1531  {  {
1532          if (owncolmap)          if (!g_owncolmap)
                 XFreeColormap(display, (Colormap)map);  
         else  
1533                  xfree(map);                  xfree(map);
1534            else
1535                    XFreeColormap(g_display, (Colormap) map);
1536  }  }
1537    
1538  void  void
1539  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
1540  {  {
1541          if (owncolmap)          if (!g_owncolmap)
1542                  XSetWindowColormap(display, wnd, (Colormap)map);          {
1543                    if (g_colmap)
1544                            xfree(g_colmap);
1545    
1546                    g_colmap = (uint32 *) map;
1547            }
1548          else          else
1549                  colmap = map;                  XSetWindowColormap(g_display, g_wnd, (Colormap) map);
1550  }  }
1551    
1552  void  void
# Line 691  ui_set_clip(int x, int y, int cx, int cy Line 1558  ui_set_clip(int x, int y, int cx, int cy
1558          rect.y = y;          rect.y = y;
1559          rect.width = cx;          rect.width = cx;
1560          rect.height = cy;          rect.height = cy;
1561          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);
1562  }  }
1563    
1564  void  void
1565  ui_reset_clip()  ui_reset_clip(void)
1566  {  {
1567          XRectangle rect;          XRectangle rect;
1568    
1569          rect.x = 0;          rect.x = 0;
1570          rect.y = 0;          rect.y = 0;
1571          rect.width = width;          rect.width = g_width;
1572          rect.height = height;          rect.height = g_height;
1573          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);
1574  }  }
1575    
1576  void  void
1577  ui_bell()  ui_bell(void)
1578  {  {
1579          XBell(display, 0);          XBell(g_display, 0);
1580  }  }
1581    
1582  void  void
# Line 721  ui_destblt(uint8 opcode, Line 1588  ui_destblt(uint8 opcode,
1588          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1589  }  }
1590    
1591    static uint8 hatch_patterns[] = {
1592            0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0 - bsHorizontal */
1593            0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 1 - bsVertical */
1594            0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, /* 2 - bsFDiagonal */
1595            0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* 3 - bsBDiagonal */
1596            0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, /* 4 - bsCross */
1597            0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81  /* 5 - bsDiagCross */
1598    };
1599    
1600  void  void
1601  ui_patblt(uint8 opcode,  ui_patblt(uint8 opcode,
1602            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1603            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1604  {  {
1605          Pixmap fill;          Pixmap fill;
1606            uint8 i, ipattern[8];
1607    
1608          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1609    
# Line 737  ui_patblt(uint8 opcode, Line 1614  ui_patblt(uint8 opcode,
1614                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1615                          break;                          break;
1616    
1617                    case 2: /* Hatch */
1618                            fill = (Pixmap) ui_create_glyph(8, 8,
1619                                                            hatch_patterns + brush->pattern[0] * 8);
1620                            SET_FOREGROUND(fgcolour);
1621                            SET_BACKGROUND(bgcolour);
1622                            XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
1623                            XSetStipple(g_display, g_gc, fill);
1624                            XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
1625                            FILL_RECTANGLE(x, y, cx, cy);
1626                            XSetFillStyle(g_display, g_gc, FillSolid);
1627                            XSetTSOrigin(g_display, g_gc, 0, 0);
1628                            ui_destroy_glyph((HGLYPH) fill);
1629                            break;
1630    
1631                  case 3: /* Pattern */                  case 3: /* Pattern */
1632                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);                          for (i = 0; i != 8; i++)
1633                                    ipattern[7 - i] = brush->pattern[i];
1634                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
1635    
1636                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(bgcolour);
1637                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
1638                          XSetFillStyle(display, gc, FillOpaqueStippled);                          XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
1639                          XSetStipple(display, gc, fill);                          XSetStipple(g_display, g_gc, fill);
1640                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);                          XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
1641    
1642                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1643    
1644                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(g_display, g_gc, FillSolid);
1645                          ui_destroy_glyph((HGLYPH)fill);                          XSetTSOrigin(g_display, g_gc, 0, 0);
1646                            ui_destroy_glyph((HGLYPH) fill);
1647                          break;                          break;
1648    
1649                  default:                  default:
# Line 765  ui_screenblt(uint8 opcode, Line 1659  ui_screenblt(uint8 opcode,
1659               /* src */ int srcx, int srcy)               /* src */ int srcx, int srcy)
1660  {  {
1661          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1662          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);
1663          if (ownbackstore)          if (g_ownbackstore)
1664                  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);  
1665          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1666  }  }
1667    
# Line 778  ui_memblt(uint8 opcode, Line 1671  ui_memblt(uint8 opcode,
1671            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
1672  {  {
1673          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1674          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);
1675          if (ownbackstore)          if (g_ownbackstore)
1676                  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);  
1677          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1678  }  }
1679    
# Line 789  void Line 1681  void
1681  ui_triblt(uint8 opcode,  ui_triblt(uint8 opcode,
1682            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1683            /* src */ HBITMAP src, int srcx, int srcy,            /* src */ HBITMAP src, int srcx, int srcy,
1684            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1685  {  {
1686          /* This is potentially difficult to do in general. Until someone          /* This is potentially difficult to do in general. Until someone
1687             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 1690  ui_triblt(uint8 opcode,
1690          {          {
1691                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
1692                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1693                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1694                          break;                          break;
1695    
1696                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
1697                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1698                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1699                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1700                          break;                          break;
1701    
1702                  case 0xc0:      /* PSa */                  case 0xc0:      /* PSa */
1703                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1704                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
1705                          break;                          break;
1706    
1707                  default:                  default:
# Line 825  ui_triblt(uint8 opcode, Line 1713  ui_triblt(uint8 opcode,
1713  void  void
1714  ui_line(uint8 opcode,  ui_line(uint8 opcode,
1715          /* dest */ int startx, int starty, int endx, int endy,          /* dest */ int startx, int starty, int endx, int endy,
1716          /* pen */ PEN *pen)          /* pen */ PEN * pen)
1717  {  {
1718          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1719          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
1720          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(g_display, g_wnd, g_gc, startx, starty, endx, endy);
1721          if (ownbackstore)          if (g_ownbackstore)
1722                  XDrawLine(display, backstore, gc, startx, starty, endx, endy);                  XDrawLine(g_display, g_backstore, g_gc, startx, starty, endx, endy);
1723          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1724  }  }
1725    
# Line 844  ui_rect( Line 1732  ui_rect(
1732          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
1733  }  }
1734    
1735    /* warning, this function only draws on wnd or backstore, not both */
1736  void  void
1737  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1738                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1739                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1740                int fgcolour)                int bgcolour, int fgcolour)
1741  {  {
1742          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
1743          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
1744    
1745          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)          XSetFillStyle(g_display, g_gc,
1746                        ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1747          XSetStipple(display, gc, (Pixmap)glyph);          XSetStipple(g_display, g_gc, (Pixmap) glyph);
1748          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(g_display, g_gc, x, y);
1749    
1750          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
1751    
1752          XSetFillStyle(display, gc, FillSolid);          XSetFillStyle(g_display, g_gc, FillSolid);
1753    }
1754    
1755    #define DO_GLYPH(ttext,idx) \
1756    {\
1757      glyph = cache_get_font (font, ttext[idx]);\
1758      if (!(flags & TEXT2_IMPLICIT_X))\
1759        {\
1760          xyoffset = ttext[++idx];\
1761          if ((xyoffset & 0x80))\
1762            {\
1763              if (flags & TEXT2_VERTICAL) \
1764                y += ttext[idx+1] | (ttext[idx+2] << 8);\
1765              else\
1766                x += ttext[idx+1] | (ttext[idx+2] << 8);\
1767              idx += 2;\
1768            }\
1769          else\
1770            {\
1771              if (flags & TEXT2_VERTICAL) \
1772                y += xyoffset;\
1773              else\
1774                x += xyoffset;\
1775            }\
1776        }\
1777      if (glyph != NULL)\
1778        {\
1779          ui_draw_glyph (mixmode, x + glyph->offset,\
1780                         y + glyph->baseline,\
1781                         glyph->width, glyph->height,\
1782                         glyph->pixmap, 0, 0, bgcolour, fgcolour);\
1783          if (flags & TEXT2_IMPLICIT_X)\
1784            x += glyph->width;\
1785        }\
1786  }  }
1787    
1788  void  void
1789  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,
1790               int clipx, int clipy, int clipcx, int clipcy,               int clipx, int clipy, int clipcx, int clipcy,
1791               int boxx, int boxy, int boxcx, int boxcy,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1792               int bgcolour, int fgcolour, uint8 *text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1793  {  {
1794          FONTGLYPH *glyph;          FONTGLYPH *glyph;
1795          int i, offset;          int i, j, xyoffset;
1796            DATABLOB *entry;
1797    
1798          SET_FOREGROUND(bgcolour);          SET_FOREGROUND(bgcolour);
1799    
1800          if (boxcx > 1)          if (boxcx > 1)
1801          {          {
1802                  FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);                  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);
1803          }          }
1804          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
1805          {          {
1806                  FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);                  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
1807          }          }
1808    
1809          /* Paint text, character by character */          /* Paint text, character by character */
1810          for (i = 0; i < length; i++)          for (i = 0; i < length;)
1811          {          {
1812                  glyph = cache_get_font(font, text[i]);                  switch (text[i])
   
                 if (!(flags & TEXT2_IMPLICIT_X))  
1813                  {                  {
1814                          offset = text[++i];                          case 0xff:
1815                          if (offset & 0x80)                                  if (i + 2 < length)
1816                                  offset = ((offset & 0x7f) << 8) | text[++i];                                          cache_put_text(text[i + 1], text, text[i + 2]);
1817                                    else
1818                          if (flags & TEXT2_VERTICAL)                                  {
1819                                  y += offset;                                          error("this shouldn't be happening\n");
1820                          else                                          exit(1);
1821                                  x += offset;                                  }
1822                  }                                  /* this will move pointer from start to first character after FF command */
1823                                    length -= i + 3;
1824                                    text = &(text[i + 3]);
1825                                    i = 0;
1826                                    break;
1827    
1828                  if (glyph != NULL)                          case 0xfe:
1829                  {                                  entry = cache_get_text(text[i + 1]);
1830                          ui_draw_glyph(mixmode, x + (short) glyph->offset,                                  if (entry != NULL)
1831                                        y + (short) glyph->baseline,                                  {
1832                                        glyph->width, glyph->height,                                          if ((((uint8 *) (entry->data))[1] ==
1833                                        glyph->pixmap, 0, 0,                                               0) && (!(flags & TEXT2_IMPLICIT_X)))
1834                                        bgcolour, fgcolour);                                          {
1835                                                    if (flags & TEXT2_VERTICAL)
1836                                                            y += text[i + 2];
1837                                                    else
1838                                                            x += text[i + 2];
1839                                            }
1840                                            for (j = 0; j < entry->size; j++)
1841                                                    DO_GLYPH(((uint8 *) (entry->data)), j);
1842                                    }
1843                                    if (i + 2 < length)
1844                                            i += 3;
1845                                    else
1846                                            i += 2;
1847                                    length -= i;
1848                                    /* this will move pointer from start to first character after FE command */
1849                                    text = &(text[i]);
1850                                    i = 0;
1851                                    break;
1852    
1853                          if (flags & TEXT2_IMPLICIT_X)                          default:
1854                                  x += glyph->width;                                  DO_GLYPH(text, i);
1855                                    i++;
1856                                    break;
1857                  }                  }
1858          }          }
1859            if (g_ownbackstore)
1860            {
1861                    if (boxcx > 1)
1862                            XCopyArea(g_display, g_backstore, g_wnd, g_gc, boxx,
1863                                      boxy, boxcx, boxcy, boxx, boxy);
1864                    else
1865                            XCopyArea(g_display, g_backstore, g_wnd, g_gc, clipx,
1866                                      clipy, clipcx, clipcy, clipx, clipy);
1867            }
1868  }  }
1869    
1870  void  void
# Line 920  ui_desktop_save(uint32 offset, int x, in Line 1873  ui_desktop_save(uint32 offset, int x, in
1873          Pixmap pix;          Pixmap pix;
1874          XImage *image;          XImage *image;
1875    
1876          if (ownbackstore)          if (g_ownbackstore)
1877          {          {
1878                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,                  image = XGetImage(g_display, g_backstore, x, y, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1879          }          }
1880          else          else
1881          {          {
1882                  pix = XCreatePixmap(display, wnd, cx, cy, depth);                  pix = XCreatePixmap(g_display, g_wnd, cx, cy, g_depth);
1883                  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);
1884                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,                  image = XGetImage(g_display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
1885                                    ZPixmap);                  XFreePixmap(g_display, pix);
                 XFreePixmap(display, pix);  
1886          }          }
1887    
1888          offset *= bpp/8;          offset *= g_bpp / 8;
1889          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);  
1890    
1891          XDestroyImage(image);          XDestroyImage(image);
1892  }  }
# Line 947  ui_desktop_restore(uint32 offset, int x, Line 1897  ui_desktop_restore(uint32 offset, int x,
1897          XImage *image;          XImage *image;
1898          uint8 *data;          uint8 *data;
1899    
1900          offset *= bpp/8;          offset *= g_bpp / 8;
1901          data = cache_get_desktop(offset, cx, cy, bpp/8);          data = cache_get_desktop(offset, cx, cy, g_bpp / 8);
1902          if (data == NULL)          if (data == NULL)
1903                  return;                  return;
1904    
1905          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1906                               0, data, cx, cy, BitmapPad(display),                               (char *) data, cx, cy, BitmapPad(g_display), cx * g_bpp / 8);
                              cx * bpp/8);  
1907    
1908          if (ownbackstore)          if (g_ownbackstore)
1909          {          {
1910                  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);
1911                  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);
1912          }          }
1913          else          else
1914          {          {
1915                  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);
1916          }          }
1917    
1918          XFree(image);          XFree(image);

Legend:
Removed from v.38  
changed lines
  Added in v.508

  ViewVC Help
Powered by ViewVC 1.1.26