/[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 30 by matty, Fri Sep 14 13:51:38 2001 UTC revision 262 by astrand, Mon Nov 18 15:37:20 2002 UTC
# Line 1  Line 1 
1  /*  /*
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     User interface services - X-Windows     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 21  Line 21 
21  #include <X11/Xlib.h>  #include <X11/Xlib.h>
22  #include <X11/Xutil.h>  #include <X11/Xutil.h>
23  #include <time.h>  #include <time.h>
24    #include <errno.h>
25  #include "rdesktop.h"  #include "rdesktop.h"
26    
27  extern int width;  extern int width;
28  extern int height;  extern int height;
29  extern BOOL sendmotion;  extern BOOL sendmotion;
30  extern BOOL fullscreen;  extern BOOL fullscreen;
31    extern BOOL grab_keyboard;
32  static Display *display;  extern BOOL hide_decorations;
33    extern char title[];
34    BOOL enable_compose = False;
35    BOOL focused;
36    BOOL mouse_in_wnd;
37    
38    Display *display;
39    static int x_socket;
40    static Screen *screen;
41  static Window wnd;  static Window wnd;
42  static GC gc;  static GC gc;
43  static Visual *visual;  static Visual *visual;
44  static int depth;  static int depth;
45  static int bpp;  static int bpp;
46  static BOOL backpixmap;  static XIM IM;
47    static XIC IC;
48    static XModifierKeymap *mod_map;
49    static Cursor current_cursor;
50    
51    /* endianness */
52    static BOOL host_be;
53    static BOOL xserver_be;
54    
55    /* software backing store */
56    static BOOL ownbackstore;
57    static Pixmap backstore;
58    
59    /* MWM decorations */
60    #define MWM_HINTS_DECORATIONS   (1L << 1)
61    #define PROP_MOTIF_WM_HINTS_ELEMENTS    5
62    typedef struct
63    {
64            unsigned long flags;
65            unsigned long functions;
66            unsigned long decorations;
67            long inputMode;
68            unsigned long status;
69    }
70    PropMotifWmHints;
71    
72  static BOOL owncolmap;  
73    #define FILL_RECTANGLE(x,y,cx,cy)\
74    { \
75            XFillRectangle(display, wnd, gc, x, y, cx, cy); \
76            if (ownbackstore) \
77                    XFillRectangle(display, backstore, gc, x, y, cx, cy); \
78    }
79    
80    /* colour maps */
81  static Colormap xcolmap;  static Colormap xcolmap;
 static uint32 white;  
82  static uint32 *colmap;  static uint32 *colmap;
83    
84  #define TRANSLATE(col)          ( owncolmap ? col : colmap[col] )  #define SET_FOREGROUND(col)     XSetForeground(display, gc, translate_colour(colmap[col]));
85  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));  #define SET_BACKGROUND(col)     XSetBackground(display, gc, translate_colour(colmap[col]));
 #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));  
86    
87  static int rop2_map[] = {  static int rop2_map[] = {
88          GXclear,                /* 0 */          GXclear,                /* 0 */
# Line 67  static int rop2_map[] = { Line 106  static int rop2_map[] = {
106  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }
107  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
108    
109    void
110    mwm_hide_decorations(void)
111    {
112            PropMotifWmHints motif_hints;
113            Atom hintsatom;
114    
115            /* setup the property */
116            motif_hints.flags = MWM_HINTS_DECORATIONS;
117            motif_hints.decorations = 0;
118    
119            /* get the atom for the property */
120            hintsatom = XInternAtom(display, "_MOTIF_WM_HINTS", False);
121            if (!hintsatom)
122            {
123                    error("Failed to get atom _MOTIF_WM_HINTS\n");
124                    return;
125            }
126    
127            XChangeProperty(display, wnd, hintsatom, hintsatom, 32, PropModeReplace,
128                            (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
129    }
130    
131  static void  static void
132  translate8(uint8 *data, uint8 *out, uint8 *end)  translate8(uint8 * data, uint8 * out, uint8 * end)
133  {  {
134          while (out < end)          while (out < end)
135                  *(out++) = (uint8)colmap[*(data++)];                  *(out++) = (uint8) colmap[*(data++)];
136  }  }
137    
138  static void  static void
139  translate16(uint8 *data, uint16 *out, uint16 *end)  translate16(uint8 * data, uint16 * out, uint16 * end)
140  {  {
141          while (out < end)          while (out < end)
142                  *(out++) = (uint16)colmap[*(data++)];                  *(out++) = (uint16) colmap[*(data++)];
143  }  }
144    
145  /* XXX endianness */  /* little endian - conversion happens when colourmap is built */
146  static void  static void
147  translate24(uint8 *data, uint8 *out, uint8 *end)  translate24(uint8 * data, uint8 * out, uint8 * end)
148  {  {
149          uint32 value;          uint32 value;
150    
# Line 97  translate24(uint8 *data, uint8 *out, uin Line 158  translate24(uint8 *data, uint8 *out, uin
158  }  }
159    
160  static void  static void
161  translate32(uint8 *data, uint32 *out, uint32 *end)  translate32(uint8 * data, uint32 * out, uint32 * end)
162  {  {
163          while (out < end)          while (out < end)
164                  *(out++) = colmap[*(data++)];                  *(out++) = colmap[*(data++)];
165  }  }
166    
167  static uint8 *  static uint8 *
168  translate(int width, int height, uint8 *data)  translate_image(int width, int height, uint8 * data)
169  {  {
170          int size = width * height * bpp/8;          int size = width * height * bpp / 8;
171          uint8 *out = xmalloc(size);          uint8 *out = xmalloc(size);
172          uint8 *end = out + size;          uint8 *end = out + size;
173    
# Line 117  translate(int width, int height, uint8 * Line 178  translate(int width, int height, uint8 *
178                          break;                          break;
179    
180                  case 16:                  case 16:
181                          translate16(data, (uint16 *)out, (uint16 *)end);                          translate16(data, (uint16 *) out, (uint16 *) end);
182                          break;                          break;
183    
184                  case 24:                  case 24:
# Line 125  translate(int width, int height, uint8 * Line 186  translate(int width, int height, uint8 *
186                          break;                          break;
187    
188                  case 32:                  case 32:
189                          translate32(data, (uint32 *)out, (uint32 *)end);                          translate32(data, (uint32 *) out, (uint32 *) end);
190                          break;                          break;
191          }          }
192    
193          return out;          return out;
194  }  }
195    
196  #define L_ENDIAN  #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
197  int screen_msbfirst = 0;  #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }
198    #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
199                            x = (x << 16) | (x >> 16); }
200    
201    static uint32
202    translate_colour(uint32 colour)
203    {
204            switch (bpp)
205            {
206                    case 16:
207                            if (host_be != xserver_be)
208                                    BSWAP16(colour);
209                            break;
210    
211                    case 24:
212                            if (xserver_be)
213                                    BSWAP24(colour);
214                            break;
215    
216                    case 32:
217                            if (host_be != xserver_be)
218                                    BSWAP32(colour);
219                            break;
220            }
221    
222            return colour;
223    }
224    
225    BOOL
226    get_key_state(unsigned int state, uint32 keysym)
227    {
228            int modifierpos, key, keysymMask = 0;
229            int offset;
230    
231            KeyCode keycode = XKeysymToKeycode(display, keysym);
232    
233            if (keycode == NoSymbol)
234                    return False;
235    
236            for (modifierpos = 0; modifierpos < 8; modifierpos++)
237            {
238                    offset = mod_map->max_keypermod * modifierpos;
239    
240                    for (key = 0; key < mod_map->max_keypermod; key++)
241                    {
242                            if (mod_map->modifiermap[offset + key] == keycode)
243                                    keysymMask |= 1 << modifierpos;
244                    }
245            }
246    
247            return (state & keysymMask) ? True : False;
248    }
249    
250  BOOL  BOOL
251  ui_create_window(char *title)  ui_init(void)
252  {  {
         XSetWindowAttributes attribs;  
         XClassHint *classhints;  
         XSizeHints *sizehints;  
         unsigned long input_mask;  
253          XPixmapFormatValues *pfm;          XPixmapFormatValues *pfm;
254          Screen *screen;          uint16 test;
255          int i;          int i;
256    
   
257          display = XOpenDisplay(NULL);          display = XOpenDisplay(NULL);
258          if (display == NULL)          if (display == NULL)
259          {          {
260                  error("Failed to open display\n");                  error("Failed to open display: %s\n", XDisplayName(NULL));
261                  return False;                  return False;
262          }          }
263    
264            x_socket = ConnectionNumber(display);
265          screen = DefaultScreenOfDisplay(display);          screen = DefaultScreenOfDisplay(display);
266          visual = DefaultVisualOfScreen(screen);          visual = DefaultVisualOfScreen(screen);
267          depth = DefaultDepthOfScreen(screen);          depth = DefaultDepthOfScreen(screen);
# Line 166  ui_create_window(char *title) Line 273  ui_create_window(char *title)
273                     desirable, e.g. 24 bits->32 bits. */                     desirable, e.g. 24 bits->32 bits. */
274                  while (i--)                  while (i--)
275                  {                  {
276                          if ((pfm[i].depth == depth)                          if ((pfm[i].depth == depth) && (pfm[i].bits_per_pixel > bpp))
                             && (pfm[i].bits_per_pixel > bpp))  
277                          {                          {
278                                  bpp = pfm[i].bits_per_pixel;                                  bpp = pfm[i].bits_per_pixel;
279                          }                          }
# Line 182  ui_create_window(char *title) Line 288  ui_create_window(char *title)
288                  return False;                  return False;
289          }          }
290    
291          if (depth <= 8)          xcolmap = DefaultColormapOfScreen(screen);
292                  owncolmap = True;          gc = XCreateGC(display, RootWindowOfScreen(screen), 0, NULL);
         else  
                 xcolmap = DefaultColormapOfScreen(screen);  
293    
294          white = WhitePixelOfScreen(screen);          if (DoesBackingStore(screen) != Always)
295          attribs.background_pixel = BlackPixelOfScreen(screen);                  ownbackstore = True;
         attribs.backing_store = DoesBackingStore(screen);  
296    
297          if (attribs.backing_store == NotUseful)          test = 1;
298                  backpixmap = True;          host_be = !(BOOL) (*(uint8 *) (&test));
299            xserver_be = (ImageByteOrder(display) == MSBFirst);
300    
301          if (fullscreen)          if (fullscreen)
302          {          {
                 attribs.override_redirect = True;  
303                  width = WidthOfScreen(screen);                  width = WidthOfScreen(screen);
304                  height = HeightOfScreen(screen);                  height = HeightOfScreen(screen);
305          }          }
306          else  
307            /* make sure width is a multiple of 4 */
308            width = (width + 3) & ~3;
309    
310            if (ownbackstore)
311          {          {
312                  attribs.override_redirect = False;                  backstore =
313                            XCreatePixmap(display, RootWindowOfScreen(screen), width, height, depth);
314    
315                    /* clear to prevent rubbish being exposed at startup */
316                    XSetForeground(display, gc, BlackPixelOfScreen(screen));
317                    XFillRectangle(display, backstore, gc, 0, 0, width, height);
318          }          }
319    
320          width = (width + 3) & ~3; /* make width a multiple of 32 bits */          mod_map = XGetModifierMapping(display);
321    
322            if (enable_compose)
323                    IM = XOpenIM(display, NULL, NULL, NULL);
324    
325            xkeymap_init();
326            return True;
327    }
328    
329    void
330    ui_deinit(void)
331    {
332            if (IM != NULL)
333                    XCloseIM(IM);
334    
335            XFreeModifiermap(mod_map);
336    
337            if (ownbackstore)
338                    XFreePixmap(display, backstore);
339    
340            XFreeGC(display, gc);
341            XCloseDisplay(display);
342            display = NULL;
343    }
344    
345    BOOL
346    ui_create_window(void)
347    {
348            XSetWindowAttributes attribs;
349            XClassHint *classhints;
350            XSizeHints *sizehints;
351            int wndwidth, wndheight;
352            long input_mask, ic_input_mask;
353            XEvent xevent;
354    
355            wndwidth = fullscreen ? WidthOfScreen(screen) : width;
356            wndheight = fullscreen ? HeightOfScreen(screen) : height;
357    
358          wnd = XCreateWindow(display, RootWindowOfScreen(screen),          attribs.background_pixel = BlackPixelOfScreen(screen);
359                              0, 0, width, height, 0, CopyFromParent,          attribs.backing_store = ownbackstore ? NotUseful : Always;
360                              InputOutput, CopyFromParent,          attribs.override_redirect = fullscreen;
361                              CWBackingStore | CWBackPixel | CWOverrideRedirect,  
362                              &attribs);          wnd = XCreateWindow(display, RootWindowOfScreen(screen), 0, 0, wndwidth, wndheight,
363                                0, CopyFromParent, InputOutput, CopyFromParent,
364                                CWBackPixel | CWBackingStore | CWOverrideRedirect, &attribs);
365    
366          XStoreName(display, wnd, title);          XStoreName(display, wnd, title);
367    
368            if (hide_decorations)
369                    mwm_hide_decorations();
370    
371          classhints = XAllocClassHint();          classhints = XAllocClassHint();
372          if (classhints != NULL)          if (classhints != NULL)
373          {          {
# Line 233  ui_create_window(char *title) Line 386  ui_create_window(char *title)
386                  XFree(sizehints);                  XFree(sizehints);
387          }          }
388    
389          input_mask = KeyPressMask | KeyReleaseMask          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
390                          | ButtonPressMask | ButtonReleaseMask                  VisibilityChangeMask | FocusChangeMask;
                         | EnterWindowMask | LeaveWindowMask;  
391    
392          if (sendmotion)          if (sendmotion)
393                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
394            if (ownbackstore)
395                    input_mask |= ExposureMask;
396            if (fullscreen || grab_keyboard)
397                    input_mask |= EnterWindowMask;
398            if (grab_keyboard)
399                    input_mask |= LeaveWindowMask;
400    
401          XSelectInput(display, wnd, input_mask);          if (IM != NULL)
402          gc = XCreateGC(display, wnd, 0, NULL);          {
403                    IC = XCreateIC(IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
404                                   XNClientWindow, wnd, XNFocusWindow, wnd, NULL);
405    
406                    if ((IC != NULL)
407                        && (XGetICValues(IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))
408                            input_mask |= ic_input_mask;
409            }
410    
411            XSelectInput(display, wnd, input_mask);
412          XMapWindow(display, wnd);          XMapWindow(display, wnd);
413    
414            /* wait for VisibilityNotify */
415            do
416            {
417                    XMaskEvent(display, VisibilityChangeMask, &xevent);
418            }
419            while (xevent.type != VisibilityNotify);
420    
421            focused = False;
422            mouse_in_wnd = False;
423    
424          return True;          return True;
425  }  }
426    
427  void  void
428  ui_destroy_window()  ui_destroy_window(void)
429  {  {
430          XFreeGC(display, gc);          if (IC != NULL)
431                    XDestroyIC(IC);
432    
433          XDestroyWindow(display, wnd);          XDestroyWindow(display, wnd);
         XCloseDisplay(display);  
         display = NULL;  
434  }  }
435    
436  static uint8  void
437  xwin_translate_key(unsigned long key)  xwin_toggle_fullscreen(void)
438  {  {
439          DEBUG(("KEY(code=0x%lx)\n", key));          Pixmap contents = 0;
440    
441          if ((key > 8) && (key <= 0x60))          if (!ownbackstore)
442                  return (key - 8);          {
443                    /* need to save contents of window */
444                    contents = XCreatePixmap(display, wnd, width, height, depth);
445                    XCopyArea(display, wnd, contents, gc, 0, 0, width, height, 0, 0);
446            }
447    
448          switch (key)          ui_destroy_window();
449          {          fullscreen = !fullscreen;
450                  case 0x61:      /* home */          ui_create_window();
                         return 0x47 | 0x80;  
                 case 0x62:      /* up arrow */  
                         return 0x48 | 0x80;  
                 case 0x63:      /* page up */  
                         return 0x49 | 0x80;  
                 case 0x64:      /* left arrow */  
                         return 0x4b | 0x80;  
                 case 0x66:      /* right arrow */  
                         return 0x4d | 0x80;  
                 case 0x67:      /* end */  
                         return 0x4f | 0x80;  
                 case 0x68:      /* down arrow */  
                         return 0x50 | 0x80;  
                 case 0x69:      /* page down */  
                         return 0x51 | 0x80;  
                 case 0x6a:      /* insert */  
                         return 0x52 | 0x80;  
                 case 0x6b:      /* delete */  
                         return 0x53 | 0x80;  
                 case 0x6c:      /* keypad enter */  
                         return 0x1c | 0x80;  
                 case 0x6d:      /* right ctrl */  
                         return 0x1d | 0x80;  
                 case 0x6f:      /* ctrl - print screen */  
                         return 0x37 | 0x80;  
                 case 0x70:      /* keypad '/' */  
                         return 0x35 | 0x80;  
                 case 0x71:      /* right alt */  
                         return 0x38 | 0x80;  
                 case 0x72:      /* ctrl break */  
                         return 0x46 | 0x80;  
                 case 0x73:      /* left window key */  
                         return 0xff;    /* real scancode is 5b */  
                 case 0x74:      /* right window key */  
                         return 0xff;    /* real scancode is 5c */  
                 case 0x75:      /* menu key */  
                         return 0x5d | 0x80;  
         }  
   
         return 0;  
 }  
   
 static uint16  
 xwin_translate_mouse(unsigned long button)  
 {  
         switch (button)  
         {  
                 case Button1:   /* left */  
                         return MOUSE_FLAG_BUTTON1;  
                 case Button2:   /* middle */  
                         return MOUSE_FLAG_BUTTON3;  
                 case Button3:   /* right */  
                         return MOUSE_FLAG_BUTTON2;  
         }  
   
         return 0;  
 }  
   
 void  
 ui_process_events()  
 {  
         XEvent event;  
         uint8 scancode;  
         uint16 button;  
         uint32 ev_time;  
451    
452          if (display == NULL)          XDefineCursor(display, wnd, current_cursor);
453                  return;  
454            if (!ownbackstore)
455            {
456                    XCopyArea(display, contents, wnd, gc, 0, 0, width, height, 0, 0);
457                    XFreePixmap(display, contents);
458            }
459    }
460    
461    /* Process all events in Xlib queue */
462    static void
463    xwin_process_events(void)
464    {
465            XEvent xevent;
466            KeySym keysym;
467            uint16 button, flags;
468            uint32 ev_time;
469            key_translation tr;
470            char str[256];
471            Status status;
472            unsigned int state;
473            Window wdummy;
474            int dummy;
475    
476          while (XCheckWindowEvent(display, wnd, ~0, &event))          while (XPending(display) > 0)
477          {          {
478                  ev_time = time(NULL);                  XNextEvent(display, &xevent);
479    
480                  switch (event.type)                  if ((IC != NULL) && (XFilterEvent(&xevent, None) == True))
481                    {
482                            DEBUG_KBD(("Filtering event\n"));
483                            continue;
484                    }
485    
486                    flags = 0;
487    
488                    switch (xevent.type)
489                  {                  {
490                          case KeyPress:                          case KeyPress:
491                                  scancode = xwin_translate_key(event.xkey.keycode);                                  if (IC != NULL)
492                                  if (scancode == 0)                                          /* Multi_key compatible version */
493                                    {
494                                            XmbLookupString(IC,
495                                                            (XKeyPressedEvent *) &
496                                                            xevent, str, sizeof(str), &keysym, &status);
497                                            if (!((status == XLookupKeySym) || (status == XLookupBoth)))
498                                            {
499                                                    error("XmbLookupString failed with status 0x%x\n",
500                                                          status);
501                                                    break;
502                                            }
503                                    }
504                                    else
505                                    {
506                                            /* Plain old XLookupString */
507                                            DEBUG_KBD(("\nNo input context, using XLookupString\n"));
508                                            XLookupString((XKeyEvent *) & xevent,
509                                                          str, sizeof(str), &keysym, NULL);
510                                    }
511    
512                                    DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,
513                                               get_ksname(keysym)));
514    
515                                    ev_time = time(NULL);
516                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
517                                            break;
518    
519                                    tr = xkeymap_translate_key(keysym,
520                                                               xevent.xkey.keycode, xevent.xkey.state);
521    
522                                    if (tr.scancode == 0)
523                                          break;                                          break;
524    
525                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,                                  ensure_remote_modifiers(ev_time, tr);
526                                                 scancode, 0);  
527                                    rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
528                                  break;                                  break;
529    
530                          case KeyRelease:                          case KeyRelease:
531                                  scancode = xwin_translate_key(event.xkey.keycode);                                  XLookupString((XKeyEvent *) & xevent, str,
532                                  if (scancode == 0)                                                sizeof(str), &keysym, NULL);
533    
534                                    DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
535                                               get_ksname(keysym)));
536    
537                                    ev_time = time(NULL);
538                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
539                                          break;                                          break;
540    
541                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE,                                  tr = xkeymap_translate_key(keysym,
542                                                 KBD_FLAG_DOWN | KBD_FLAG_UP,                                                             xevent.xkey.keycode, xevent.xkey.state);
                                                scancode, 0);  
                                 break;  
543    
544                          case ButtonPress:                                  if (tr.scancode == 0)
                                 button = xwin_translate_mouse(event.xbutton.button);  
                                 if (button == 0)  
545                                          break;                                          break;
546    
547                                  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);  
548                                  break;                                  break;
549    
550                            case ButtonPress:
551                                    flags = MOUSE_FLAG_DOWN;
552                                    /* fall through */
553    
554                          case ButtonRelease:                          case ButtonRelease:
555                                  button = xwin_translate_mouse(event.xbutton.button);                                  button = xkeymap_translate_button(xevent.xbutton.button);
556                                  if (button == 0)                                  if (button == 0)
557                                          break;                                          break;
558    
559                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
560                                                 button,                                                 flags | button, xevent.xbutton.x, xevent.xbutton.y);
                                                event.xbutton.x,  
                                                event.xbutton.y);  
561                                  break;                                  break;
562    
563                          case MotionNotify:                          case MotionNotify:
564                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
565                                                 MOUSE_FLAG_MOVE,                                                 MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
566                                                 event.xmotion.x,                                  break;
567                                                 event.xmotion.y);  
568                            case FocusIn:
569                                    if (xevent.xfocus.mode == NotifyGrab)
570                                            break;
571                                    focused = True;
572                                    XQueryPointer(display, wnd, &wdummy, &wdummy, &dummy, &dummy,
573                                                  &dummy, &dummy, &state);
574                                    reset_modifier_keys(state);
575                                    if (grab_keyboard && mouse_in_wnd)
576                                            XGrabKeyboard(display, wnd, True,
577                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
578                                    break;
579    
580                            case FocusOut:
581                                    if (xevent.xfocus.mode == NotifyUngrab)
582                                            break;
583                                    focused = False;
584                                    if (xevent.xfocus.mode == NotifyWhileGrabbed)
585                                            XUngrabKeyboard(display, CurrentTime);
586                                  break;                                  break;
587    
588                          case EnterNotify:                          case EnterNotify:
589                                  XGrabKeyboard(display, wnd, True, GrabModeAsync,                                  /* we only register for this event when in fullscreen mode */
590                                                GrabModeAsync, CurrentTime);                                  /* or grab_keyboard */
591                                    mouse_in_wnd = True;
592                                    if (fullscreen)
593                                    {
594                                            XSetInputFocus(display, wnd, RevertToPointerRoot,
595                                                           CurrentTime);
596                                            break;
597                                    }
598                                    if (focused)
599                                            XGrabKeyboard(display, wnd, True,
600                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
601                                  break;                                  break;
602    
603                          case LeaveNotify:                          case LeaveNotify:
604                                    /* we only register for this event when grab_keyboard */
605                                    mouse_in_wnd = False;
606                                  XUngrabKeyboard(display, CurrentTime);                                  XUngrabKeyboard(display, CurrentTime);
607                                  break;                                  break;
608    
609                            case Expose:
610                                    XCopyArea(display, backstore, wnd, gc,
611                                              xevent.xexpose.x, xevent.xexpose.y,
612                                              xevent.xexpose.width,
613                                              xevent.xexpose.height,
614                                              xevent.xexpose.x, xevent.xexpose.y);
615                                    break;
616    
617                            case MappingNotify:
618                                    /* Refresh keyboard mapping if it has changed. This is important for
619                                       Xvnc, since it allocates keycodes dynamically */
620                                    if (xevent.xmapping.request == MappingKeyboard
621                                        || xevent.xmapping.request == MappingModifier)
622                                            XRefreshKeyboardMapping(&xevent.xmapping);
623    
624                                    if (xevent.xmapping.request == MappingModifier)
625                                    {
626                                            XFreeModifiermap(mod_map);
627                                            mod_map = XGetModifierMapping(display);
628                                    }
629                                    break;
630    
631                  }                  }
632          }          }
633  }  }
634    
635  void  void
636    ui_select(int rdp_socket)
637    {
638            int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;
639            fd_set rfds;
640    
641            FD_ZERO(&rfds);
642    
643            while (True)
644            {
645                    /* Process any events already waiting */
646                    xwin_process_events();
647    
648                    FD_ZERO(&rfds);
649                    FD_SET(rdp_socket, &rfds);
650                    FD_SET(x_socket, &rfds);
651    
652                    switch (select(n, &rfds, NULL, NULL, NULL))
653                    {
654                            case -1:
655                                    error("select: %s\n", strerror(errno));
656    
657                            case 0:
658                                    continue;
659                    }
660    
661                    if (FD_ISSET(rdp_socket, &rfds))
662                            return;
663            }
664    }
665    
666    void
667  ui_move_pointer(int x, int y)  ui_move_pointer(int x, int y)
668  {  {
669          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
670  }  }
671    
672  HBITMAP  HBITMAP
673  ui_create_bitmap(int width, int height, uint8 *data)  ui_create_bitmap(int width, int height, uint8 * data)
674  {  {
675          XImage *image;          XImage *image;
676          Pixmap bitmap;          Pixmap bitmap;
677          uint8 *tdata;          uint8 *tdata;
678    
679          tdata = (owncolmap ? data : translate(width, height, data));          tdata = translate_image(width, height, data);
680          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
681          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
682                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, 8, 0);
683    
684          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
685    
686          XFree(image);          XFree(image);
687          if (!owncolmap)          xfree(tdata);
                 xfree(tdata);  
688          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
689  }  }
690    
691  void  void
692  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)  
693  {  {
694          XImage *image;          XImage *image;
695          uint8 *tdata;          uint8 *tdata;
696    
697          tdata = (owncolmap ? data : translate(width, height, data));          tdata = translate_image(width, height, data);
698          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
699                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, 8, 0);
700    
701          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);          if (ownbackstore)
702            {
703                    XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
704                    XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
705            }
706            else
707            {
708                    XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
709            }
710    
711          XFree(image);          XFree(image);
712          if (!owncolmap)          xfree(tdata);
                 xfree(tdata);  
713  }  }
714    
715  void  void
716  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(HBITMAP bmp)
717  {  {
718          XFreePixmap(display, (Pixmap)bmp);          XFreePixmap(display, (Pixmap) bmp);
719  }  }
720    
721  HGLYPH  HGLYPH
722  ui_create_glyph(int width, int height, uint8 *data)  ui_create_glyph(int width, int height, uint8 * data)
723  {  {
724          XImage *image;          XImage *image;
725          Pixmap bitmap;          Pixmap bitmap;
# Line 465  ui_create_glyph(int width, int height, u Line 731  ui_create_glyph(int width, int height, u
731          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(display, wnd, width, height, 1);
732          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(display, bitmap, 0, NULL);
733    
734          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(display, visual, 1, ZPixmap, 0, (char *) data,
735                               data, width, height, 8, scanline);                               width, height, 8, scanline);
736          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
737          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
738          XInitImage(image);          XInitImage(image);
# Line 475  ui_create_glyph(int width, int height, u Line 741  ui_create_glyph(int width, int height, u
741    
742          XFree(image);          XFree(image);
743          XFreeGC(display, gc);          XFreeGC(display, gc);
744          return (HGLYPH)bitmap;          return (HGLYPH) bitmap;
745  }  }
746    
747  void  void
748  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
749  {  {
750          XFreePixmap(display, (Pixmap)glyph);          XFreePixmap(display, (Pixmap) glyph);
751  }  }
752    
753  HCURSOR  HCURSOR
754  ui_create_cursor(unsigned int x, unsigned int y, int width,  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
755                   int height, uint8 *andmask, uint8 *xormask)                   uint8 * andmask, uint8 * xormask)
756  {  {
757          HGLYPH maskglyph, cursorglyph;          HGLYPH maskglyph, cursorglyph;
758          XColor bg, fg;          XColor bg, fg;
# Line 543  ui_create_cursor(unsigned int x, unsigne Line 809  ui_create_cursor(unsigned int x, unsigne
809    
810          cursorglyph = ui_create_glyph(width, height, cursor);          cursorglyph = ui_create_glyph(width, height, cursor);
811          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
812            
813          xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,          xcursor =
814                                  (Pixmap)maskglyph, &fg, &bg, x, y);                  XCreatePixmapCursor(display, (Pixmap) cursorglyph,
815                                        (Pixmap) maskglyph, &fg, &bg, x, y);
816    
817          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
818          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
819          xfree(mask);          xfree(mask);
820          xfree(cursor);          xfree(cursor);
821          return (HCURSOR)xcursor;          return (HCURSOR) xcursor;
822  }  }
823    
824  void  void
825  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
826  {  {
827          XDefineCursor(display, wnd, (Cursor)cursor);          current_cursor = (Cursor) cursor;
828            XDefineCursor(display, wnd, current_cursor);
829  }  }
830    
831  void  void
832  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_cursor(HCURSOR cursor)
833  {  {
834          XFreeCursor(display, (Cursor)cursor);          XFreeCursor(display, (Cursor) cursor);
835  }  }
836    
837  #define MAKE_XCOLOR(xc,c) \  #define MAKE_XCOLOR(xc,c) \
# Line 573  ui_destroy_cursor(HCURSOR cursor) Line 841  ui_destroy_cursor(HCURSOR cursor)
841                  (xc)->flags = DoRed | DoGreen | DoBlue;                  (xc)->flags = DoRed | DoGreen | DoBlue;
842    
843  HCOLOURMAP  HCOLOURMAP
844  ui_create_colourmap(COLOURMAP *colours)  ui_create_colourmap(COLOURMAP * colours)
845  {  {
846          COLOURENTRY *entry;          COLOURENTRY *entry;
847          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
848            uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
849          if (owncolmap)          XColor xentry;
850            XColor xc_cache[256];
851            uint32 colour;
852            int colLookup = 256;
853            for (i = 0; i < ncolours; i++)
854          {          {
855                  XColor *xcolours, *xentry;                  entry = &colours->colours[i];
856                  Colormap map;                  MAKE_XCOLOR(&xentry, entry);
857    
858                  xcolours = xmalloc(sizeof(XColor) * ncolours);                  if (XAllocColor(display, xcolmap, &xentry) == 0)
                 for (i = 0; i < ncolours; i++)  
859                  {                  {
860                          entry = &colours->colours[i];                          /* Allocation failed, find closest match. */
861                          xentry = &xcolours[i];                          int j = 256;
862                          xentry->pixel = i;                          int nMinDist = 3 * 256 * 256;
863                          MAKE_XCOLOR(xentry, entry);                          long nDist = nMinDist;
                 }  
864    
865                  map = XCreateColormap(display, wnd, visual, AllocAll);                          /* only get the colors once */
866                  XStoreColors(display, map, xcolours, ncolours);                          while (colLookup--)
867                            {
868                                    xc_cache[colLookup].pixel = colLookup;
869                                    xc_cache[colLookup].red = xc_cache[colLookup].green =
870                                            xc_cache[colLookup].blue = 0;
871                                    xc_cache[colLookup].flags = 0;
872                                    XQueryColor(display,
873                                                DefaultColormap(display, DefaultScreen(display)),
874                                                &xc_cache[colLookup]);
875                            }
876                            colLookup = 0;
877    
878                  xfree(xcolours);                          /* approximate the pixel */
879                  return (HCOLOURMAP)map;                          while (j--)
880          }                          {
881          else                                  if (xc_cache[j].flags)
882          {                                  {
883                  uint32 *map = xmalloc(sizeof(*colmap) * ncolours);                                          nDist = ((long) (xc_cache[j].red >> 8) -
884                  XColor xentry;                                                   (long) (xentry.red >> 8)) *
885                                                    ((long) (xc_cache[j].red >> 8) -
886                                                     (long) (xentry.red >> 8)) +
887                                                    ((long) (xc_cache[j].green >> 8) -
888                                                     (long) (xentry.green >> 8)) *
889                                                    ((long) (xc_cache[j].green >> 8) -
890                                                     (long) (xentry.green >> 8)) +
891                                                    ((long) (xc_cache[j].blue >> 8) -
892                                                     (long) (xentry.blue >> 8)) *
893                                                    ((long) (xc_cache[j].blue >> 8) -
894                                                     (long) (xentry.blue >> 8));
895                                    }
896                                    if (nDist < nMinDist)
897                                    {
898                                            nMinDist = nDist;
899                                            xentry.pixel = j;
900                                    }
901                            }
902                    }
903                    colour = xentry.pixel;
904    
905                  for (i = 0; i < ncolours; i++)                  /* update our cache */
906                    if (xentry.pixel < 256)
907                  {                  {
908                          entry = &colours->colours[i];                          xc_cache[xentry.pixel].red = xentry.red;
909                          MAKE_XCOLOR(&xentry, entry);                          xc_cache[xentry.pixel].green = xentry.green;
910                            xc_cache[xentry.pixel].blue = xentry.blue;
911    
                         if (XAllocColor(display, xcolmap, &xentry) != 0)  
                                 map[i] = xentry.pixel;  
                         else  
                                 map[i] = white;  
912                  }                  }
913    
914                  return map;  
915                    /* byte swap here to make translate_image faster */
916                    map[i] = translate_colour(colour);
917          }          }
918    
919            return map;
920  }  }
921    
922  void  void
923  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
924  {  {
925          if (owncolmap)          xfree(map);
                 XFreeColormap(display, (Colormap)map);  
         else  
                 xfree(map);  
926  }  }
927    
928  void  void
929  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
930  {  {
931          if (owncolmap)          colmap = map;
                 XSetWindowColormap(display, wnd, (Colormap)map);  
         else  
                 colmap = map;  
932  }  }
933    
934  void  void
# Line 649  ui_set_clip(int x, int y, int cx, int cy Line 944  ui_set_clip(int x, int y, int cx, int cy
944  }  }
945    
946  void  void
947  ui_reset_clip()  ui_reset_clip(void)
948  {  {
949          XRectangle rect;          XRectangle rect;
950    
# Line 661  ui_reset_clip() Line 956  ui_reset_clip()
956  }  }
957    
958  void  void
959  ui_bell()  ui_bell(void)
960  {  {
961          XBell(display, 0);          XBell(display, 0);
962  }  }
# Line 671  ui_destblt(uint8 opcode, Line 966  ui_destblt(uint8 opcode,
966             /* dest */ int x, int y, int cx, int cy)             /* dest */ int x, int y, int cx, int cy)
967  {  {
968          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
969          XFillRectangle(display, wnd, gc, x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
970          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
971  }  }
972    
973  void  void
974  ui_patblt(uint8 opcode,  ui_patblt(uint8 opcode,
975            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
976            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
977  {  {
978          Pixmap fill;          Pixmap fill;
979            uint8 i, ipattern[8];
980    
981          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
982    
# Line 688  ui_patblt(uint8 opcode, Line 984  ui_patblt(uint8 opcode,
984          {          {
985                  case 0: /* Solid */                  case 0: /* Solid */
986                          SET_FOREGROUND(fgcolour);                          SET_FOREGROUND(fgcolour);
987                          XFillRectangle(display, wnd, gc, x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
988                          break;                          break;
989    
990                  case 3: /* Pattern */                  case 3: /* Pattern */
991                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);                          for (i = 0; i != 8; i++)
992                                    ipattern[7 - i] = brush->pattern[i];
993                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
994    
995                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(bgcolour);
996                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
# Line 700  ui_patblt(uint8 opcode, Line 998  ui_patblt(uint8 opcode,
998                          XSetStipple(display, gc, fill);                          XSetStipple(display, gc, fill);
999                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
1000    
1001                          XFillRectangle(display, wnd, gc, x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1002    
1003                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
1004                          ui_destroy_glyph((HGLYPH)fill);                          XSetTSOrigin(display, gc, 0, 0);
1005                            ui_destroy_glyph((HGLYPH) fill);
1006                          break;                          break;
1007    
1008                  default:                  default:
# Line 720  ui_screenblt(uint8 opcode, Line 1019  ui_screenblt(uint8 opcode,
1019  {  {
1020          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1021          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
1022            if (ownbackstore)
1023                    XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, cy, x, y);
1024          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1025  }  }
1026    
# Line 729  ui_memblt(uint8 opcode, Line 1030  ui_memblt(uint8 opcode,
1030            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
1031  {  {
1032          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1033          XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
1034            if (ownbackstore)
1035                    XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy, cx, cy, x, y);
1036          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1037  }  }
1038    
# Line 737  void Line 1040  void
1040  ui_triblt(uint8 opcode,  ui_triblt(uint8 opcode,
1041            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1042            /* src */ HBITMAP src, int srcx, int srcy,            /* src */ HBITMAP src, int srcx, int srcy,
1043            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1044  {  {
1045          /* This is potentially difficult to do in general. Until someone          /* This is potentially difficult to do in general. Until someone
1046             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 746  ui_triblt(uint8 opcode, Line 1049  ui_triblt(uint8 opcode,
1049          {          {
1050                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
1051                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1052                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1053                          break;                          break;
1054    
1055                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
1056                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1057                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1058                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1059                          break;                          break;
1060    
1061                  case 0xc0:      /* PSa */                  case 0xc0:      /* PSa */
1062                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1063                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
1064                          break;                          break;
1065    
1066                  default:                  default:
# Line 773  ui_triblt(uint8 opcode, Line 1072  ui_triblt(uint8 opcode,
1072  void  void
1073  ui_line(uint8 opcode,  ui_line(uint8 opcode,
1074          /* dest */ int startx, int starty, int endx, int endy,          /* dest */ int startx, int starty, int endx, int endy,
1075          /* pen */ PEN *pen)          /* pen */ PEN * pen)
1076  {  {
1077          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1078          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
1079          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(display, wnd, gc, startx, starty, endx, endy);
1080            if (ownbackstore)
1081                    XDrawLine(display, backstore, gc, startx, starty, endx, endy);
1082          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1083  }  }
1084    
# Line 787  ui_rect( Line 1088  ui_rect(
1088                 /* brush */ int colour)                 /* brush */ int colour)
1089  {  {
1090          SET_FOREGROUND(colour);          SET_FOREGROUND(colour);
1091          XFillRectangle(display, wnd, gc, x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
1092  }  }
1093    
1094  void  void
1095  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1096                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1097                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1098                int fgcolour)                int bgcolour, int fgcolour)
1099  {  {
1100          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
1101          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
1102    
1103          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)          XSetFillStyle(display, gc,
1104                        ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1105          XSetStipple(display, gc, (Pixmap)glyph);          XSetStipple(display, gc, (Pixmap) glyph);
1106          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(display, gc, x, y);
1107    
1108          XFillRectangle(display, wnd, gc, x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
1109    
1110          XSetFillStyle(display, gc, FillSolid);          XSetFillStyle(display, gc, FillSolid);
1111  }  }
1112    
1113    #define DO_GLYPH(ttext,idx) \
1114    {\
1115      glyph = cache_get_font (font, ttext[idx]);\
1116      if (!(flags & TEXT2_IMPLICIT_X))\
1117        {\
1118          xyoffset = ttext[++idx];\
1119          if ((xyoffset & 0x80))\
1120            {\
1121              if (flags & TEXT2_VERTICAL) \
1122                y += ttext[idx+1] | (ttext[idx+2] << 8);\
1123              else\
1124                x += ttext[idx+1] | (ttext[idx+2] << 8);\
1125              idx += 2;\
1126            }\
1127          else\
1128            {\
1129              if (flags & TEXT2_VERTICAL) \
1130                y += xyoffset;\
1131              else\
1132                x += xyoffset;\
1133            }\
1134        }\
1135      if (glyph != NULL)\
1136        {\
1137          ui_draw_glyph (mixmode, x + (short) glyph->offset,\
1138                         y + (short) glyph->baseline,\
1139                         glyph->width, glyph->height,\
1140                         glyph->pixmap, 0, 0, bgcolour, fgcolour);\
1141          if (flags & TEXT2_IMPLICIT_X)\
1142            x += glyph->width;\
1143        }\
1144    }
1145    
1146  void  void
1147  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,
1148               int clipx, int clipy, int clipcx, int clipcy,               int clipx, int clipy, int clipcx, int clipcy,
1149               int boxx, int boxy, int boxcx, int boxcy,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1150               int bgcolour, int fgcolour, uint8 *text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1151  {  {
1152          FONTGLYPH *glyph;          FONTGLYPH *glyph;
1153          int i, offset;          int i, j, xyoffset;
1154            DATABLOB *entry;
1155    
1156          SET_FOREGROUND(bgcolour);          SET_FOREGROUND(bgcolour);
1157    
1158          if (boxcx > 1)          if (boxcx > 1)
1159                  XFillRectangle(display, wnd, gc, boxx, boxy, boxcx, boxcy);          {
1160                    FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);
1161            }
1162          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
1163                  XFillRectangle(display, wnd, gc, clipx, clipy, clipcx, clipcy);          {
1164                    FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);
1165            }
1166    
1167          /* Paint text, character by character */          /* Paint text, character by character */
1168          for (i = 0; i < length; i++)          for (i = 0; i < length;)
1169          {          {
1170                  glyph = cache_get_font(font, text[i]);                  switch (text[i])
   
                 if (!(flags & TEXT2_IMPLICIT_X))  
1171                  {                  {
1172                          offset = text[++i];                          case 0xff:
1173                          if (offset & 0x80)                                  if (i + 2 < length)
1174                                  offset = ((offset & 0x7f) << 8) | text[++i];                                          cache_put_text(text[i + 1], text, text[i + 2]);
1175                                    else
1176                          if (flags & TEXT2_VERTICAL)                                  {
1177                                  y += offset;                                          error("this shouldn't be happening\n");
1178                          else                                          break;
1179                                  x += offset;                                  }
1180                  }                                  /* this will move pointer from start to first character after FF command */
1181                                    length -= i + 3;
1182                                    text = &(text[i + 3]);
1183                                    i = 0;
1184                                    break;
1185    
1186                  if (glyph != NULL)                          case 0xfe:
1187                  {                                  entry = cache_get_text(text[i + 1]);
1188                          ui_draw_glyph(mixmode, x + (short) glyph->offset,                                  if (entry != NULL)
1189                                        y + (short) glyph->baseline,                                  {
1190                                        glyph->width, glyph->height,                                          if ((((uint8 *) (entry->data))[1] ==
1191                                        glyph->pixmap, 0, 0,                                               0) && (!(flags & TEXT2_IMPLICIT_X)))
1192                                        bgcolour, fgcolour);                                          {
1193                                                    if (flags & TEXT2_VERTICAL)
1194                                                            y += text[i + 2];
1195                                                    else
1196                                                            x += text[i + 2];
1197                                            }
1198                                            if (i + 2 < length)
1199                                                    i += 3;
1200                                            else
1201                                                    i += 2;
1202                                            length -= i;
1203                                            /* this will move pointer from start to first character after FE command */
1204                                            text = &(text[i]);
1205                                            i = 0;
1206                                            for (j = 0; j < entry->size; j++)
1207                                                    DO_GLYPH(((uint8 *) (entry->data)), j);
1208                                    }
1209                                    break;
1210    
1211                          if (flags & TEXT2_IMPLICIT_X)                          default:
1212                                  x += glyph->width;                                  DO_GLYPH(text, i);
1213                                    i++;
1214                                    break;
1215                  }                  }
1216          }          }
1217    
1218    
1219  }  }
1220    
1221  void  void
# Line 862  ui_desktop_save(uint32 offset, int x, in Line 1224  ui_desktop_save(uint32 offset, int x, in
1224          Pixmap pix;          Pixmap pix;
1225          XImage *image;          XImage *image;
1226    
1227          pix = XCreatePixmap(display, wnd, cx, cy, depth);          if (ownbackstore)
1228          XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);          {
1229                    image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes, ZPixmap);
1230          image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);          }
1231            else
1232            {
1233                    pix = XCreatePixmap(display, wnd, cx, cy, depth);
1234                    XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
1235                    image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
1236                    XFreePixmap(display, pix);
1237            }
1238    
1239          offset *= bpp/8;          offset *= bpp / 8;
1240          cache_put_desktop(offset, cx, cy, image->bytes_per_line,          cache_put_desktop(offset, cx, cy, image->bytes_per_line, bpp / 8, (uint8 *) image->data);
                           bpp/8, image->data);  
1241    
1242          XDestroyImage(image);          XDestroyImage(image);
         XFreePixmap(display, pix);  
1243  }  }
1244    
1245  void  void
# Line 881  ui_desktop_restore(uint32 offset, int x, Line 1248  ui_desktop_restore(uint32 offset, int x,
1248          XImage *image;          XImage *image;
1249          uint8 *data;          uint8 *data;
1250    
1251          offset *= bpp/8;          offset *= bpp / 8;
1252          data = cache_get_desktop(offset, cx, cy, bpp/8);          data = cache_get_desktop(offset, cx, cy, bpp / 8);
1253          if (data == NULL)          if (data == NULL)
1254                  return;                  return;
1255    
1256          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1257                               0, data, cx, cy, BitmapPad(display),                               (char *) data, cx, cy, BitmapPad(display), cx * bpp / 8);
1258                               cx * bpp/8);  
1259            if (ownbackstore)
1260            {
1261                    XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
1262                    XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
1263            }
1264            else
1265            {
1266                    XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
1267            }
1268    
         XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);  
1269          XFree(image);          XFree(image);
1270  }  }
   

Legend:
Removed from v.30  
changed lines
  Added in v.262

  ViewVC Help
Powered by ViewVC 1.1.26