/[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 50 by matthewc, Sat Apr 20 09:41:03 2002 UTC revision 101 by astrand, Mon Aug 26 17:12:43 2002 UTC
# Line 2  Line 2 
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-2001
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 22  Line 22 
22  #include <X11/Xutil.h>  #include <X11/Xutil.h>
23  #include <time.h>  #include <time.h>
24  #include <errno.h>  #include <errno.h>
25    #define XK_MISCELLANY
26    #include <X11/keysymdef.h>
27  #include "rdesktop.h"  #include "rdesktop.h"
28    #include "scancodes.h"
29    
 extern char keymapname[16];  
 extern int keylayout;  
30  extern int width;  extern int width;
31  extern int height;  extern int height;
32  extern BOOL sendmotion;  extern BOOL sendmotion;
33  extern BOOL fullscreen;  extern BOOL fullscreen;
34    extern BOOL grab_keyboard;
35    extern char title[];
36    
37  Display *display;  Display *display = NULL;
38  static int x_socket;  static int x_socket;
39  static Window wnd;  static Window wnd;
40  static GC gc;  static GC gc;
41  static Visual *visual;  static Visual *visual;
42  static int depth;  static int depth;
43  static int bpp;  static int bpp;
44    static int dpy_width;
45    static int dpy_height;
46    
47  /* endianness */  /* endianness */
48  static BOOL host_be;  static BOOL host_be;
# Line 59  static BOOL owncolmap; Line 64  static BOOL owncolmap;
64  static Colormap xcolmap;  static Colormap xcolmap;
65  static uint32 white;  static uint32 white;
66  static uint32 *colmap;  static uint32 *colmap;
67    static XIM IM = NULL;
68    static XIC IC = NULL;
69    
70    /* Compose support */
71    BOOL enable_compose = False;
72    
73    /* toggle fullscreen globals */
74    static XSetWindowAttributes attribs;
75    static unsigned long input_mask;
76    
77  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )
78  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));
# Line 87  static int rop2_map[] = { Line 101  static int rop2_map[] = {
101  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
102    
103  static void  static void
104  translate8(uint8 *data, uint8 *out, uint8 *end)  translate8(uint8 * data, uint8 * out, uint8 * end)
105  {  {
106          while (out < end)          while (out < end)
107                  *(out++) = (uint8)colmap[*(data++)];                  *(out++) = (uint8) colmap[*(data++)];
108  }  }
109    
110  static void  static void
111  translate16(uint8 *data, uint16 *out, uint16 *end)  translate16(uint8 * data, uint16 * out, uint16 * end)
112  {  {
113          while (out < end)          while (out < end)
114                  *(out++) = (uint16)colmap[*(data++)];                  *(out++) = (uint16) colmap[*(data++)];
115  }  }
116    
117  /* little endian - conversion happens when colourmap is built */  /* little endian - conversion happens when colourmap is built */
118  static void  static void
119  translate24(uint8 *data, uint8 *out, uint8 *end)  translate24(uint8 * data, uint8 * out, uint8 * end)
120  {  {
121          uint32 value;          uint32 value;
122    
# Line 116  translate24(uint8 *data, uint8 *out, uin Line 130  translate24(uint8 *data, uint8 *out, uin
130  }  }
131    
132  static void  static void
133  translate32(uint8 *data, uint32 *out, uint32 *end)  translate32(uint8 * data, uint32 * out, uint32 * end)
134  {  {
135          while (out < end)          while (out < end)
136                  *(out++) = colmap[*(data++)];                  *(out++) = colmap[*(data++)];
137  }  }
138    
139  static uint8 *  static uint8 *
140  translate_image(int width, int height, uint8 *data)  translate_image(int width, int height, uint8 * data)
141  {  {
142          int size = width * height * bpp/8;          int size = width * height * bpp / 8;
143          uint8 *out = xmalloc(size);          uint8 *out = xmalloc(size);
144          uint8 *end = out + size;          uint8 *end = out + size;
145    
# Line 136  translate_image(int width, int height, u Line 150  translate_image(int width, int height, u
150                          break;                          break;
151    
152                  case 16:                  case 16:
153                          translate16(data, (uint16 *)out, (uint16 *)end);                          translate16(data, (uint16 *) out, (uint16 *) end);
154                          break;                          break;
155    
156                  case 24:                  case 24:
# Line 144  translate_image(int width, int height, u Line 158  translate_image(int width, int height, u
158                          break;                          break;
159    
160                  case 32:                  case 32:
161                          translate32(data, (uint32 *)out, (uint32 *)end);                          translate32(data, (uint32 *) out, (uint32 *) end);
162                          break;                          break;
163          }          }
164    
# Line 180  translate_colour(uint32 colour) Line 194  translate_colour(uint32 colour)
194          return colour;          return colour;
195  }  }
196    
197    static unsigned long
198    init_inputmethod(void)
199    {
200            unsigned long filtered_events = 0;
201    
202            IM = XOpenIM(display, NULL, NULL, NULL);
203            if (IM == NULL)
204            {
205                    error("Failed to open input method\n");
206            }
207    
208            if (IM != NULL)
209            {
210                    /* Must be done after XCreateWindow */
211                    IC = XCreateIC(IM, XNInputStyle,
212                                   (XIMPreeditNothing | XIMStatusNothing),
213                                   XNClientWindow, wnd, XNFocusWindow, wnd, NULL);
214    
215                    if (IC == NULL)
216                    {
217                            error("Failed to create input context\n");
218                            XCloseIM(IM);
219                            IM = NULL;
220                    }
221            }
222    
223            /* For correct Multi_key/Compose processing, I guess.
224               It seems to work alright anyway, though. */
225            if (IC != NULL)
226            {
227                    if (XGetICValues(IC, XNFilterEvents, &filtered_events, NULL) != NULL)
228                    {
229                            error("Failed to obtain XNFilterEvents value from IC\n");
230                            filtered_events = 0;
231                    }
232            }
233            return filtered_events;
234    }
235    
236    static void
237    close_inputmethod(void)
238    {
239            if (IC != NULL)
240            {
241                    XDestroyIC(IC);
242                    if (IM != NULL)
243                    {
244                            XCloseIM(IM);
245                            IM = NULL;
246                    }
247            }
248    }
249    
250  BOOL  BOOL
251  ui_create_window(char *title)  ui_init()
252  {  {
         XSetWindowAttributes attribs;  
         XClassHint *classhints;  
         XSizeHints *sizehints;  
         unsigned long input_mask;  
         XPixmapFormatValues *pfm;  
253          Screen *screen;          Screen *screen;
         uint16 test;  
         int i;  
   
254          display = XOpenDisplay(NULL);          display = XOpenDisplay(NULL);
255          if (display == NULL)          if (display == NULL)
256          {          {
257                  error("Failed to open display\n");                  error("Failed to open display\n");
258                  return False;                  return False;
259          }          }
260            if (fullscreen)
261            {
262                    screen = DefaultScreenOfDisplay(display);
263                    width = WidthOfScreen(screen);
264                    height = HeightOfScreen(screen);
265            }
266            return True;
267    }
268    
269    BOOL
270    ui_create_window_obj(int xpos, int ypos, int width, int height, int valuemask)
271    {
272            XClassHint *classhints;
273            XSizeHints *sizehints;
274            XEvent xevent;
275            Screen *screen;
276    
277            screen = DefaultScreenOfDisplay(display);
278    
279            wnd = XCreateWindow(display, RootWindowOfScreen(screen), xpos,
280                                ypos, width, height, 0, CopyFromParent,
281                                InputOutput, CopyFromParent, valuemask, &attribs);
282    
283    
284            XStoreName(display, wnd, title);
285    
286            classhints = XAllocClassHint();
287            if (classhints != NULL)
288            {
289                    classhints->res_name = classhints->res_class = "rdesktop";
290                    XSetClassHint(display, wnd, classhints);
291                    XFree(classhints);
292            }
293    
294            sizehints = XAllocSizeHints();
295            if (sizehints)
296            {
297                    sizehints->flags = PMinSize | PMaxSize;
298                    sizehints->min_width = sizehints->max_width = width;
299                    sizehints->min_height = sizehints->max_height = height;
300                    XSetWMNormalHints(display, wnd, sizehints);
301                    XFree(sizehints);
302            }
303    
304            if (enable_compose)
305                    input_mask |= init_inputmethod();
306    
307            XSelectInput(display, wnd, input_mask);
308    
309            gc = XCreateGC(display, wnd, 0, NULL);
310    
311            XMapWindow(display, wnd);
312    
313            /* Wait for VisibilityNotify Event */
314            for (;;)
315            {
316                    XNextEvent(display, &xevent);
317                    if (xevent.type == VisibilityNotify)
318                            break;
319            }
320    
321            if (ownbackstore)
322                    backstore = XCreatePixmap(display, wnd, width, height, depth);
323    
324            /* clear the window so that cached data is not viewed upon start... */
325            XSetBackground(display, gc, 0);
326            XSetForeground(display, gc, 0);
327            FILL_RECTANGLE(0, 0, width, height);
328            /* make sure the window is focused */
329            XSetInputFocus(display, wnd, RevertToPointerRoot, CurrentTime);
330    }
331    
332    BOOL
333    ui_create_window()
334    {
335            XPixmapFormatValues *pfm;
336            Screen *screen;
337            uint16 test;
338            int i;
339    
340          x_socket = ConnectionNumber(display);          x_socket = ConnectionNumber(display);
341          screen = DefaultScreenOfDisplay(display);          screen = DefaultScreenOfDisplay(display);
# Line 211  ui_create_window(char *title) Line 349  ui_create_window(char *title)
349                     desirable, e.g. 24 bits->32 bits. */                     desirable, e.g. 24 bits->32 bits. */
350                  while (i--)                  while (i--)
351                  {                  {
352                          if ((pfm[i].depth == depth)                          if ((pfm[i].depth == depth) && (pfm[i].bits_per_pixel > bpp))
                             && (pfm[i].bits_per_pixel > bpp))  
353                          {                          {
354                                  bpp = pfm[i].bits_per_pixel;                                  bpp = pfm[i].bits_per_pixel;
355                          }                          }
# Line 233  ui_create_window(char *title) Line 370  ui_create_window(char *title)
370                  xcolmap = DefaultColormapOfScreen(screen);                  xcolmap = DefaultColormapOfScreen(screen);
371    
372          test = 1;          test = 1;
373          host_be = !(BOOL)(*(uint8 *)(&test));          host_be = !(BOOL) (*(uint8 *) (&test));
374          xserver_be = (ImageByteOrder(display) == MSBFirst);          xserver_be = (ImageByteOrder(display) == MSBFirst);
375    
376          white = WhitePixelOfScreen(screen);          white = WhitePixelOfScreen(screen);
# Line 243  ui_create_window(char *title) Line 380  ui_create_window(char *title)
380          if (attribs.backing_store == NotUseful)          if (attribs.backing_store == NotUseful)
381                  ownbackstore = True;                  ownbackstore = True;
382    
383            dpy_width = WidthOfScreen(screen);
384            dpy_height = HeightOfScreen(screen);
385    
386          if (fullscreen)          if (fullscreen)
387          {          {
388                  attribs.override_redirect = True;                  attribs.override_redirect = True;
389                  width = WidthOfScreen(screen);                  width = dpy_width;
390                  height = HeightOfScreen(screen);                  height = dpy_height;
391          }          }
392          else          else
393          {          {
394                  attribs.override_redirect = False;                  attribs.override_redirect = False;
395          }          }
396    
397          width = (width + 3) & ~3; /* make width a multiple of 32 bits */          width = (width + 3) & ~3;       /* make width a multiple of 32 bits */
398    
         wnd = XCreateWindow(display, RootWindowOfScreen(screen),  
                             0, 0, width, height, 0, CopyFromParent,  
                             InputOutput, CopyFromParent,  
                             CWBackingStore | CWBackPixel | CWOverrideRedirect,  
                             &attribs);  
399    
400          XStoreName(display, wnd, title);          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
401                    VisibilityChangeMask | FocusChangeMask;
         classhints = XAllocClassHint();  
         if (classhints != NULL)  
         {  
                 classhints->res_name = classhints->res_class = "rdesktop";  
                 XSetClassHint(display, wnd, classhints);  
                 XFree(classhints);  
         }  
   
         sizehints = XAllocSizeHints();  
         if (sizehints)  
         {  
                 sizehints->flags = PMinSize | PMaxSize;  
                 sizehints->min_width = sizehints->max_width = width;  
                 sizehints->min_height = sizehints->max_height = height;  
                 XSetWMNormalHints(display, wnd, sizehints);  
                 XFree(sizehints);  
         }  
   
         xkeymap_init();  
   
         input_mask = KeyPressMask | KeyReleaseMask  
                         | ButtonPressMask | ButtonReleaseMask  
                         | EnterWindowMask | LeaveWindowMask;  
402    
403            if (grab_keyboard)
404                    input_mask |= EnterWindowMask | LeaveWindowMask;
405          if (sendmotion)          if (sendmotion)
406                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
407    
408          if (ownbackstore)          if (ownbackstore)
409                  input_mask |= ExposureMask;                  input_mask |= ExposureMask;
410    
411          XSelectInput(display, wnd, input_mask);          if (fullscreen)
412          gc = XCreateGC(display, wnd, 0, NULL);                  ui_create_window_obj(0, 0, width, height,
413                                         CWBackingStore | CWBackPixel | CWOverrideRedirect);
414            else
415                    ui_create_window_obj(0, 0, width, height, CWBackingStore | CWBackPixel);
416    
417          if (ownbackstore)          xkeymap_init2();
                 backstore = XCreatePixmap(display, wnd, width, height, depth);  
418    
         XMapWindow(display, wnd);  
419          return True;          return True;
420  }  }
421    
# Line 311  ui_destroy_window() Line 426  ui_destroy_window()
426                  XFreePixmap(display, backstore);                  XFreePixmap(display, backstore);
427    
428          XFreeGC(display, gc);          XFreeGC(display, gc);
429    
430            close_inputmethod();
431    
432          XDestroyWindow(display, wnd);          XDestroyWindow(display, wnd);
433          XCloseDisplay(display);          XCloseDisplay(display);
434          display = NULL;          display = NULL;
435  }  }
436    
437    void
438    reset_keys()
439    {
440            /* reset keys */
441            uint32 ev_time;
442            ev_time = time(NULL);
443            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
444            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LALT);
445            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
446            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RCTRL);
447            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
448            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
449    }
450    
451    void
452    toggle_fullscreen()
453    {
454            /* save window contents */
455            Pixmap pixmap;
456            pixmap = XCreatePixmap(display, wnd, width, height, depth);
457            if (ownbackstore)
458                    XCopyArea(display, backstore, pixmap, gc, 0, 0, width, height, 0, 0);
459            else
460                    XCopyArea(display, wnd, pixmap, gc, 0, 0, width, height, 0, 0);
461            fullscreen = fullscreen ? False : True;
462            close_inputmethod();
463            if (ownbackstore)
464                    XFreePixmap(display, backstore);
465            XFreeGC(display, gc);
466            XDestroyWindow(display, wnd);
467            if (fullscreen)
468            {
469                    attribs.override_redirect = True;
470                    ui_create_window_obj(0, 0, dpy_width, dpy_height,
471                                         CWBackingStore | CWBackPixel | CWOverrideRedirect);
472            }
473            else
474            {
475                    attribs.override_redirect = False;
476                    ui_create_window_obj(0, 0, width, height, CWBackingStore | CWBackPixel);
477            }
478            ui_set_cursor(cache_get_cursor(0));
479            ui_move_pointer(width / 2, height / 2);
480            reset_keys();
481            /* restore window contents */
482            if (ownbackstore)
483                    XCopyArea(display, pixmap, backstore, gc, 0, 0, width, height, 0, 0);
484            XCopyArea(display, pixmap, wnd, gc, 0, 0, width, height, 0, 0);
485            XFreePixmap(display, pixmap);
486    }
487    
488  static void  static void
489  xwin_process_events()  xwin_process_events()
490  {  {
491          XEvent event;          XEvent xevent;
492    
493          KeySym keysym;          KeySym keysym;
         uint8 scancode;  
494          uint16 button, flags;          uint16 button, flags;
495          uint32 ev_time;          uint32 ev_time;
496            key_translation tr;
497            char *ksname = NULL;
498            char str[256];
499            Status status;
500    
501          if (display == NULL)          /* Refresh keyboard mapping if it has changed. This is important for
502                  return;             Xvnc, since it allocates keycodes dynamically */
503            if (XCheckTypedEvent(display, MappingNotify, &xevent))
504            {
505                    if (xevent.xmapping.request == MappingKeyboard
506                        || xevent.xmapping.request == MappingModifier)
507                            XRefreshKeyboardMapping(&xevent.xmapping);
508            }
509    
510          while (XCheckMaskEvent(display, ~0, &event))          while (XCheckMaskEvent(display, ~0, &xevent))
511          {          {
512                    if (enable_compose && (XFilterEvent(&xevent, None) == True))
513                    {
514                            DEBUG_KBD(("Filtering event\n"));
515                            continue;
516                    }
517    
518                  ev_time = time(NULL);                  ev_time = time(NULL);
519                  flags = 0;                  flags = 0;
520    
521                  switch (event.type)                  switch (xevent.type)
522                  {                  {
523                            case KeyPress:
524                                    if (IC != NULL)
525                                            /* Multi_key compatible version */
526                                    {
527                                            XmbLookupString(IC,
528                                                            (XKeyPressedEvent *) &
529                                                            xevent, str, sizeof(str), &keysym, &status);
530                                            if (!((status == XLookupKeySym) || (status == XLookupBoth)))
531                                            {
532                                                    error("XmbLookupString failed with status 0x%x\n",
533                                                          status);
534                                                    break;
535                                            }
536                                    }
537                                    else
538                                    {
539                                            /* Plain old XLookupString */
540                                            DEBUG_KBD(("No input context, using XLookupString\n"));
541                                            XLookupString((XKeyEvent *) & xevent,
542                                                          str, sizeof(str), &keysym, NULL);
543                                    }
544    
545                                    /* FIXME needs alt modifier */
546                                    if (keysym == XK_Break) /* toggle full screen */
547                                    {
548                                            toggle_fullscreen();
549                                            break;
550                                    }
551                                    ksname = get_ksname(keysym);
552                                    DEBUG_KBD(("\nKeyPress for (keysym 0x%lx, %s)\n", keysym, ksname));
553    
554                                    if (inhibit_key(keysym))
555                                    {
556                                            DEBUG_KBD(("Inhibiting key\n"));
557                                            break;
558                                    }
559    
560                                    tr = xkeymap_translate_key(keysym,
561                                                               xevent.xkey.keycode, xevent.xkey.state);
562    
563                                    ensure_remote_modifiers(ev_time, tr);
564    
565                                    if (tr.scancode == 0)
566                                            break;
567    
568                                    rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
569                                    break;
570                          case KeyRelease:                          case KeyRelease:
571                                  flags = KBD_FLAG_DOWN | KBD_FLAG_UP;                                  XLookupString((XKeyEvent *) & xevent, str,
572                                  /* fall through */                                                sizeof(str), &keysym, NULL);
573    
574                          case KeyPress:                                  ksname = get_ksname(keysym);
575                                  keysym = XKeycodeToKeysym(display, event.xkey.keycode, 0);                                  DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
576                                  scancode = xkeymap_translate_key(keysym, event.xkey.keycode, &flags);                                             ksname));
577                                  if (scancode == 0)  
578                                    if (inhibit_key(keysym))
579                                            break;
580    
581                                    tr = xkeymap_translate_key(keysym,
582                                                               xevent.xkey.keycode, xevent.xkey.state);
583    
584                                    if (tr.scancode == 0)
585                                          break;                                          break;
586    
587                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, flags, scancode, 0);                                  rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
588                                  break;                                  break;
589    
590                          case ButtonPress:                          case ButtonPress:
# Line 353  xwin_process_events() Line 592  xwin_process_events()
592                                  /* fall through */                                  /* fall through */
593    
594                          case ButtonRelease:                          case ButtonRelease:
595                                  button = xkeymap_translate_button(event.xbutton.button);                                  button = xkeymap_translate_button(xevent.xbutton.button);
596                                  if (button == 0)                                  if (button == 0)
597                                          break;                                          break;
598    
599                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
600                                                 flags | button,                                                 flags | button, xevent.xbutton.x, xevent.xbutton.y);
                                                event.xbutton.x,  
                                                event.xbutton.y);  
601                                  break;                                  break;
602    
603                          case MotionNotify:                          case MotionNotify:
604                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
605                                                 MOUSE_FLAG_MOVE,                                                 MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
                                                event.xmotion.x,  
                                                event.xmotion.y);  
606                                  break;                                  break;
607    
608                            case FocusIn:
609                                    /* fall through */
610                          case EnterNotify:                          case EnterNotify:
611                                  XGrabKeyboard(display, wnd, True, GrabModeAsync,                                  if (grab_keyboard)
612                                                GrabModeAsync, CurrentTime);                                          XGrabKeyboard(display, wnd, True,
613                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
614                                  break;                                  break;
615    
616                            case FocusOut:
617                                    reset_keys();
618                                    /* fall through */
619                          case LeaveNotify:                          case LeaveNotify:
620                                  XUngrabKeyboard(display, CurrentTime);                                  if (grab_keyboard)
621                                            XUngrabKeyboard(display, CurrentTime);
622                                  break;                                  break;
623    
624                          case Expose:                          case Expose:
625                                  XCopyArea(display, backstore, wnd, gc,                                  XCopyArea(display, backstore, wnd, gc,
626                                            event.xexpose.x, event.xexpose.y,                                            xevent.xexpose.x, xevent.xexpose.y,
627                                            event.xexpose.width, event.xexpose.height,                                            xevent.xexpose.width,
628                                            event.xexpose.x, event.xexpose.y);                                            xevent.xexpose.height,
629                                              xevent.xexpose.x, xevent.xexpose.y);
630                                  break;                                  break;
631                  }                  }
632          }          }
# Line 392  xwin_process_events() Line 635  xwin_process_events()
635  void  void
636  ui_select(int rdp_socket)  ui_select(int rdp_socket)
637  {  {
638          int n = (rdp_socket > x_socket) ? rdp_socket+1 : x_socket+1;          int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;
639          fd_set rfds;          fd_set rfds;
640    
         XFlush(display);  
   
641          FD_ZERO(&rfds);          FD_ZERO(&rfds);
642    
643          while (True)          while (True)
644          {          {
645                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
646                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
647                  FD_SET(x_socket, &rfds);                  if (display != NULL)
648                    {
649                            FD_SET(x_socket, &rfds);
650                            XFlush(display);
651                    }
652    
653                  switch (select(n, &rfds, NULL, NULL, NULL))                  switch (select(n, &rfds, NULL, NULL, NULL))
654                  {                  {
# Line 429  ui_move_pointer(int x, int y) Line 674  ui_move_pointer(int x, int y)
674  }  }
675    
676  HBITMAP  HBITMAP
677  ui_create_bitmap(int width, int height, uint8 *data)  ui_create_bitmap(int width, int height, uint8 * data)
678  {  {
679          XImage *image;          XImage *image;
680          Pixmap bitmap;          Pixmap bitmap;
# Line 437  ui_create_bitmap(int width, int height, Line 682  ui_create_bitmap(int width, int height,
682    
683          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
684          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
685          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
686                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, 8, 0);
687    
688          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
689    
# Line 449  ui_create_bitmap(int width, int height, Line 694  ui_create_bitmap(int width, int height,
694  }  }
695    
696  void  void
697  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)  
698  {  {
699          XImage *image;          XImage *image;
700          uint8 *tdata;          uint8 *tdata;
701    
702          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
703          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
704                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, 8, 0);
705    
706          if (ownbackstore)          if (ownbackstore)
707          {          {
# Line 477  ui_paint_bitmap(int x, int y, int cx, in Line 721  ui_paint_bitmap(int x, int y, int cx, in
721  void  void
722  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(HBITMAP bmp)
723  {  {
724          XFreePixmap(display, (Pixmap)bmp);          XFreePixmap(display, (Pixmap) bmp);
725  }  }
726    
727  HGLYPH  HGLYPH
728  ui_create_glyph(int width, int height, uint8 *data)  ui_create_glyph(int width, int height, uint8 * data)
729  {  {
730          XImage *image;          XImage *image;
731          Pixmap bitmap;          Pixmap bitmap;
# Line 493  ui_create_glyph(int width, int height, u Line 737  ui_create_glyph(int width, int height, u
737          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(display, wnd, width, height, 1);
738          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(display, bitmap, 0, NULL);
739    
740          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(display, visual, 1, ZPixmap, 0, (char *) data,
741                               data, width, height, 8, scanline);                               width, height, 8, scanline);
742          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
743          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
744          XInitImage(image);          XInitImage(image);
# Line 503  ui_create_glyph(int width, int height, u Line 747  ui_create_glyph(int width, int height, u
747    
748          XFree(image);          XFree(image);
749          XFreeGC(display, gc);          XFreeGC(display, gc);
750          return (HGLYPH)bitmap;          return (HGLYPH) bitmap;
751  }  }
752    
753  void  void
754  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
755  {  {
756          XFreePixmap(display, (Pixmap)glyph);          XFreePixmap(display, (Pixmap) glyph);
757  }  }
758    
759  HCURSOR  HCURSOR
760  ui_create_cursor(unsigned int x, unsigned int y, int width,  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
761                   int height, uint8 *andmask, uint8 *xormask)                   uint8 * andmask, uint8 * xormask)
762  {  {
763          HGLYPH maskglyph, cursorglyph;          HGLYPH maskglyph, cursorglyph;
764          XColor bg, fg;          XColor bg, fg;
# Line 571  ui_create_cursor(unsigned int x, unsigne Line 815  ui_create_cursor(unsigned int x, unsigne
815    
816          cursorglyph = ui_create_glyph(width, height, cursor);          cursorglyph = ui_create_glyph(width, height, cursor);
817          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
818            
819          xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,          xcursor =
820                                  (Pixmap)maskglyph, &fg, &bg, x, y);                  XCreatePixmapCursor(display, (Pixmap) cursorglyph,
821                                        (Pixmap) maskglyph, &fg, &bg, x, y);
822    
823          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
824          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
825          xfree(mask);          xfree(mask);
826          xfree(cursor);          xfree(cursor);
827          return (HCURSOR)xcursor;          return (HCURSOR) xcursor;
828  }  }
829    
830  void  void
831  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
832  {  {
833          XDefineCursor(display, wnd, (Cursor)cursor);          XDefineCursor(display, wnd, (Cursor) cursor);
834  }  }
835    
836  void  void
837  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_cursor(HCURSOR cursor)
838  {  {
839          XFreeCursor(display, (Cursor)cursor);          XFreeCursor(display, (Cursor) cursor);
840  }  }
841    
842  #define MAKE_XCOLOR(xc,c) \  #define MAKE_XCOLOR(xc,c) \
# Line 601  ui_destroy_cursor(HCURSOR cursor) Line 846  ui_destroy_cursor(HCURSOR cursor)
846                  (xc)->flags = DoRed | DoGreen | DoBlue;                  (xc)->flags = DoRed | DoGreen | DoBlue;
847    
848  HCOLOURMAP  HCOLOURMAP
849  ui_create_colourmap(COLOURMAP *colours)  ui_create_colourmap(COLOURMAP * colours)
850  {  {
851          COLOURENTRY *entry;          COLOURENTRY *entry;
852          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
# Line 624  ui_create_colourmap(COLOURMAP *colours) Line 869  ui_create_colourmap(COLOURMAP *colours)
869                  XStoreColors(display, map, xcolours, ncolours);                  XStoreColors(display, map, xcolours, ncolours);
870    
871                  xfree(xcolours);                  xfree(xcolours);
872                  return (HCOLOURMAP)map;                  return (HCOLOURMAP) map;
873          }          }
874          else          else
875          {          {
# Line 654  void Line 899  void
899  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
900  {  {
901          if (owncolmap)          if (owncolmap)
902                  XFreeColormap(display, (Colormap)map);                  XFreeColormap(display, (Colormap) map);
903          else          else
904                  xfree(map);                  xfree(map);
905  }  }
# Line 663  void Line 908  void
908  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
909  {  {
910          if (owncolmap)          if (owncolmap)
911                  XSetWindowColormap(display, wnd, (Colormap)map);                  XSetWindowColormap(display, wnd, (Colormap) map);
912          else          else
913                  colmap = map;                  colmap = map;
914  }  }
# Line 710  ui_destblt(uint8 opcode, Line 955  ui_destblt(uint8 opcode,
955  void  void
956  ui_patblt(uint8 opcode,  ui_patblt(uint8 opcode,
957            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
958            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
959  {  {
960          Pixmap fill;          Pixmap fill;
961            uint8 i, ipattern[8];
962    
963          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
964    
# Line 724  ui_patblt(uint8 opcode, Line 970  ui_patblt(uint8 opcode,
970                          break;                          break;
971    
972                  case 3: /* Pattern */                  case 3: /* Pattern */
973                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);                          for (i = 0; i != 8; i++)
974                                    ipattern[7 - i] = brush->pattern[i];
975                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
976    
977                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(bgcolour);
978                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
# Line 735  ui_patblt(uint8 opcode, Line 983  ui_patblt(uint8 opcode,
983                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
984    
985                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
986                          ui_destroy_glyph((HGLYPH)fill);                          XSetTSOrigin(display, gc, 0, 0);
987                            ui_destroy_glyph((HGLYPH) fill);
988                          break;                          break;
989    
990                  default:                  default:
# Line 753  ui_screenblt(uint8 opcode, Line 1002  ui_screenblt(uint8 opcode,
1002          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1003          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
1004          if (ownbackstore)          if (ownbackstore)
1005                  XCopyArea(display, backstore, backstore, gc, srcx, srcy,                  XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1006          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1007  }  }
1008    
# Line 764  ui_memblt(uint8 opcode, Line 1012  ui_memblt(uint8 opcode,
1012            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
1013  {  {
1014          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1015          XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
1016          if (ownbackstore)          if (ownbackstore)
1017                  XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
1018          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
1019  }  }
1020    
# Line 775  void Line 1022  void
1022  ui_triblt(uint8 opcode,  ui_triblt(uint8 opcode,
1023            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1024            /* src */ HBITMAP src, int srcx, int srcy,            /* src */ HBITMAP src, int srcx, int srcy,
1025            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1026  {  {
1027          /* This is potentially difficult to do in general. Until someone          /* This is potentially difficult to do in general. Until someone
1028             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 784  ui_triblt(uint8 opcode, Line 1031  ui_triblt(uint8 opcode,
1031          {          {
1032                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
1033                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1034                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1035                          break;                          break;
1036    
1037                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
1038                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1039                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1040                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1041                          break;                          break;
1042    
1043                  case 0xc0:      /* PSa */                  case 0xc0:      /* PSa */
1044                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1045                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
1046                          break;                          break;
1047    
1048                  default:                  default:
# Line 811  ui_triblt(uint8 opcode, Line 1054  ui_triblt(uint8 opcode,
1054  void  void
1055  ui_line(uint8 opcode,  ui_line(uint8 opcode,
1056          /* dest */ int startx, int starty, int endx, int endy,          /* dest */ int startx, int starty, int endx, int endy,
1057          /* pen */ PEN *pen)          /* pen */ PEN * pen)
1058  {  {
1059          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1060          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
# Line 833  ui_rect( Line 1076  ui_rect(
1076  void  void
1077  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1078                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1079                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1080                int fgcolour)                int bgcolour, int fgcolour)
1081  {  {
1082          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
1083          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
1084    
1085          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)          XSetFillStyle(display, gc,
1086                        ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1087          XSetStipple(display, gc, (Pixmap)glyph);          XSetStipple(display, gc, (Pixmap) glyph);
1088          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(display, gc, x, y);
1089    
1090          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
# Line 858  ui_draw_glyph(int mixmode, Line 1101  ui_draw_glyph(int mixmode,
1101        if ((xyoffset & 0x80))\        if ((xyoffset & 0x80))\
1102          {\          {\
1103            if (flags & TEXT2_VERTICAL) \            if (flags & TEXT2_VERTICAL) \
1104              y += ttext[++idx] | (ttext[++idx] << 8);\              y += ttext[idx+1] | (ttext[idx+2] << 8);\
1105            else\            else\
1106              x += ttext[++idx] | (ttext[++idx] << 8);\              x += ttext[idx+1] | (ttext[idx+2] << 8);\
1107              idx += 2;\
1108          }\          }\
1109        else\        else\
1110          {\          {\
# Line 883  ui_draw_glyph(int mixmode, Line 1127  ui_draw_glyph(int mixmode,
1127    
1128  void  void
1129  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,
1130               int clipx, int clipy, int clipcx, int clipcy, int boxx,               int clipx, int clipy, int clipcx, int clipcy,
1131               int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1132               int fgcolour, uint8 * text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1133  {  {
1134          FONTGLYPH *glyph;          FONTGLYPH *glyph;
# Line 903  ui_draw_text(uint8 font, uint8 flags, in Line 1147  ui_draw_text(uint8 font, uint8 flags, in
1147          }          }
1148    
1149          /* Paint text, character by character */          /* Paint text, character by character */
1150          for (i = 0; i < length;) {          for (i = 0; i < length;)
1151                  switch (text[i]) {          {
1152                  case 0xff:                  switch (text[i])
1153                          if (i + 2 < length)                  {
1154                                  cache_put_text(text[i + 1], text, text[i + 2]);                          case 0xff:
1155                          else {                                  if (i + 2 < length)
1156                                  error("this shouldn't be happening\n");                                          cache_put_text(text[i + 1], text, text[i + 2]);
1157                                    else
1158                                    {
1159                                            error("this shouldn't be happening\n");
1160                                            break;
1161                                    }
1162                                    /* this will move pointer from start to first character after FF command */
1163                                    length -= i + 3;
1164                                    text = &(text[i + 3]);
1165                                    i = 0;
1166                                  break;                                  break;
                         }  
                         /* this will move pointer from start to first character after FF command */  
                         length -= i + 3;  
                         text = &(text[i + 3]);  
                         i = 0;  
                         break;  
1167    
1168                  case 0xfe:                          case 0xfe:
1169                          entry = cache_get_text(text[i + 1]);                                  entry = cache_get_text(text[i + 1]);
1170                          if (entry != NULL) {                                  if (entry != NULL)
1171                                  if ((((uint8 *) (entry->data))[1] == 0)                                  {
1172                                      && (!(flags & TEXT2_IMPLICIT_X))) {                                          if ((((uint8 *) (entry->data))[1] ==
1173                                          if (flags & TEXT2_VERTICAL)                                                     0) && (!(flags & TEXT2_IMPLICIT_X)))
1174                                                  y += text[i + 2];                                          {
1175                                                    if (flags & TEXT2_VERTICAL)
1176                                                            y += text[i + 2];
1177                                                    else
1178                                                            x += text[i + 2];
1179                                            }
1180                                            if (i + 2 < length)
1181                                                    i += 3;
1182                                          else                                          else
1183                                                  x += text[i + 2];                                                  i += 2;
1184                                            length -= i;
1185                                            /* this will move pointer from start to first character after FE command */
1186                                            text = &(text[i]);
1187                                            i = 0;
1188                                            for (j = 0; j < entry->size; j++)
1189                                                    DO_GLYPH(((uint8 *) (entry->data)), j);
1190                                  }                                  }
1191                                  if (i + 2 < length)                                  break;
                                         i += 3;  
                                 else  
                                         i += 2;  
                                 length -= i;    
                                 /* this will move pointer from start to first character after FE command */  
                                 text = &(text[i]);  
                                 i = 0;  
                                 for (j = 0; j < entry->size; j++)  
                                         DO_GLYPH(((uint8 *) (entry->data)), j);  
                         }  
                         break;  
1192    
1193                  default:                          default:
1194                          DO_GLYPH(text, i);                                  DO_GLYPH(text, i);
1195                          i++;                                  i++;
1196                          break;                                  break;
1197                  }                  }
1198          }          }
1199    
# Line 959  ui_desktop_save(uint32 offset, int x, in Line 1208  ui_desktop_save(uint32 offset, int x, in
1208    
1209          if (ownbackstore)          if (ownbackstore)
1210          {          {
1211                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1212          }          }
1213          else          else
1214          {          {
1215                  pix = XCreatePixmap(display, wnd, cx, cy, depth);                  pix = XCreatePixmap(display, wnd, cx, cy, depth);
1216                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
1217                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1218                  XFreePixmap(display, pix);                  XFreePixmap(display, pix);
1219          }          }
1220    
1221          offset *= bpp/8;          offset *= bpp / 8;
1222          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, (uint8 *)image->data);  
1223    
1224          XDestroyImage(image);          XDestroyImage(image);
1225  }  }
# Line 984  ui_desktop_restore(uint32 offset, int x, Line 1230  ui_desktop_restore(uint32 offset, int x,
1230          XImage *image;          XImage *image;
1231          uint8 *data;          uint8 *data;
1232    
1233          offset *= bpp/8;          offset *= bpp / 8;
1234          data = cache_get_desktop(offset, cx, cy, bpp/8);          data = cache_get_desktop(offset, cx, cy, bpp / 8);
1235          if (data == NULL)          if (data == NULL)
1236                  return;                  return;
1237    
1238          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1239                               0, data, cx, cy, BitmapPad(display),                               (char *) data, cx, cy, BitmapPad(display), cx * bpp / 8);
                              cx * bpp/8);  
1240    
1241          if (ownbackstore)          if (ownbackstore)
1242          {          {

Legend:
Removed from v.50  
changed lines
  Added in v.101

  ViewVC Help
Powered by ViewVC 1.1.26