/[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 29 by matty, Fri Sep 14 03:38:39 2001 UTC revision 50 by matthewc, Sat Apr 20 09:41:03 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-2000     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
# 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 char keymapname[16];
28    extern int keylayout;
29  extern int width;  extern int width;
30  extern int height;  extern int height;
31  extern BOOL sendmotion;  extern BOOL sendmotion;
32  extern BOOL fullscreen;  extern BOOL fullscreen;
33    
34  static Display *display;  Display *display;
35    static int x_socket;
36  static Window wnd;  static Window wnd;
37  static GC gc;  static GC gc;
38  static Visual *visual;  static Visual *visual;
39  static int depth;  static int depth;
40  static int bpp;  static int bpp;
 static BOOL backpixmap;  
41    
42    /* endianness */
43    static BOOL host_be;
44    static BOOL xserver_be;
45    
46    /* software backing store */
47    static BOOL ownbackstore;
48    static Pixmap backstore;
49    
50    #define FILL_RECTANGLE(x,y,cx,cy)\
51    { \
52            XFillRectangle(display, wnd, gc, x, y, cx, cy); \
53            if (ownbackstore) \
54                    XFillRectangle(display, backstore, gc, x, y, cx, cy); \
55    }
56    
57    /* colour maps */
58  static BOOL owncolmap;  static BOOL owncolmap;
59  static Colormap xcolmap;  static Colormap xcolmap;
60  static uint32 white;  static uint32 white;
61  static uint32 *colmap;  static uint32 *colmap;
62    
63  #define TRANSLATE(col)          ( owncolmap ? col : colmap[col] )  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )
64  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));
65  #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));  #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));
66    
# Line 81  translate16(uint8 *data, uint16 *out, ui Line 100  translate16(uint8 *data, uint16 *out, ui
100                  *(out++) = (uint16)colmap[*(data++)];                  *(out++) = (uint16)colmap[*(data++)];
101  }  }
102    
103  /* XXX endianness */  /* little endian - conversion happens when colourmap is built */
104  static void  static void
105  translate24(uint8 *data, uint8 *out, uint8 *end)  translate24(uint8 *data, uint8 *out, uint8 *end)
106  {  {
# Line 104  translate32(uint8 *data, uint32 *out, ui Line 123  translate32(uint8 *data, uint32 *out, ui
123  }  }
124    
125  static uint8 *  static uint8 *
126  translate(int width, int height, uint8 *data)  translate_image(int width, int height, uint8 *data)
127  {  {
128          int size = width * height * bpp/8;          int size = width * height * bpp/8;
129          uint8 *out = xmalloc(size);          uint8 *out = xmalloc(size);
# Line 132  translate(int width, int height, uint8 * Line 151  translate(int width, int height, uint8 *
151          return out;          return out;
152  }  }
153    
154  #define L_ENDIAN  #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
155  int screen_msbfirst = 0;  #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }
156    #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
157                            x = (x << 16) | (x >> 16); }
158    
159    static uint32
160    translate_colour(uint32 colour)
161    {
162            switch (bpp)
163            {
164                    case 16:
165                            if (host_be != xserver_be)
166                                    BSWAP16(colour);
167                            break;
168    
169                    case 24:
170                            if (xserver_be)
171                                    BSWAP24(colour);
172                            break;
173    
174                    case 32:
175                            if (host_be != xserver_be)
176                                    BSWAP32(colour);
177                            break;
178            }
179    
180            return colour;
181    }
182    
183  BOOL  BOOL
184  ui_create_window(char *title)  ui_create_window(char *title)
# Line 145  ui_create_window(char *title) Line 189  ui_create_window(char *title)
189          unsigned long input_mask;          unsigned long input_mask;
190          XPixmapFormatValues *pfm;          XPixmapFormatValues *pfm;
191          Screen *screen;          Screen *screen;
192            uint16 test;
193          int i;          int i;
194    
   
195          display = XOpenDisplay(NULL);          display = XOpenDisplay(NULL);
196          if (display == NULL)          if (display == NULL)
197          {          {
198                  ERROR("Failed to open display\n");                  error("Failed to open display\n");
199                  return False;                  return False;
200          }          }
201    
202            x_socket = ConnectionNumber(display);
203          screen = DefaultScreenOfDisplay(display);          screen = DefaultScreenOfDisplay(display);
204          visual = DefaultVisualOfScreen(screen);          visual = DefaultVisualOfScreen(screen);
205          depth = DefaultDepthOfScreen(screen);          depth = DefaultDepthOfScreen(screen);
# Line 177  ui_create_window(char *title) Line 222  ui_create_window(char *title)
222    
223          if (bpp < 8)          if (bpp < 8)
224          {          {
225                  ERROR("Less than 8 bpp not currently supported.\n");                  error("Less than 8 bpp not currently supported.\n");
226                  XCloseDisplay(display);                  XCloseDisplay(display);
227                  return False;                  return False;
228          }          }
# Line 187  ui_create_window(char *title) Line 232  ui_create_window(char *title)
232          else          else
233                  xcolmap = DefaultColormapOfScreen(screen);                  xcolmap = DefaultColormapOfScreen(screen);
234    
235            test = 1;
236            host_be = !(BOOL)(*(uint8 *)(&test));
237            xserver_be = (ImageByteOrder(display) == MSBFirst);
238    
239          white = WhitePixelOfScreen(screen);          white = WhitePixelOfScreen(screen);
240          attribs.background_pixel = BlackPixelOfScreen(screen);          attribs.background_pixel = BlackPixelOfScreen(screen);
241          attribs.backing_store = DoesBackingStore(screen);          attribs.backing_store = DoesBackingStore(screen);
242    
243          if (attribs.backing_store == NotUseful)          if (attribs.backing_store == NotUseful)
244                  backpixmap = True;                  ownbackstore = True;
245    
246          if (fullscreen)          if (fullscreen)
247          {          {
# Line 205  ui_create_window(char *title) Line 254  ui_create_window(char *title)
254                  attribs.override_redirect = False;                  attribs.override_redirect = False;
255          }          }
256    
257          width &= ~3; /* make width a multiple of 32 bits */          width = (width + 3) & ~3; /* make width a multiple of 32 bits */
258    
259          wnd = XCreateWindow(display, RootWindowOfScreen(screen),          wnd = XCreateWindow(display, RootWindowOfScreen(screen),
260                              0, 0, width, height, 0, CopyFromParent,                              0, 0, width, height, 0, CopyFromParent,
# Line 233  ui_create_window(char *title) Line 282  ui_create_window(char *title)
282                  XFree(sizehints);                  XFree(sizehints);
283          }          }
284    
285            xkeymap_init();
286    
287          input_mask = KeyPressMask | KeyReleaseMask          input_mask = KeyPressMask | KeyReleaseMask
288                          | ButtonPressMask | ButtonReleaseMask                          | ButtonPressMask | ButtonReleaseMask
289                          | EnterWindowMask | LeaveWindowMask;                          | EnterWindowMask | LeaveWindowMask;
# Line 240  ui_create_window(char *title) Line 291  ui_create_window(char *title)
291          if (sendmotion)          if (sendmotion)
292                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
293    
294            if (ownbackstore)
295                    input_mask |= ExposureMask;
296    
297          XSelectInput(display, wnd, input_mask);          XSelectInput(display, wnd, input_mask);
298          gc = XCreateGC(display, wnd, 0, NULL);          gc = XCreateGC(display, wnd, 0, NULL);
299    
300            if (ownbackstore)
301                    backstore = XCreatePixmap(display, wnd, width, height, depth);
302    
303          XMapWindow(display, wnd);          XMapWindow(display, wnd);
304          return True;          return True;
305  }  }
# Line 250  ui_create_window(char *title) Line 307  ui_create_window(char *title)
307  void  void
308  ui_destroy_window()  ui_destroy_window()
309  {  {
310            if (ownbackstore)
311                    XFreePixmap(display, backstore);
312    
313          XFreeGC(display, gc);          XFreeGC(display, gc);
314          XDestroyWindow(display, wnd);          XDestroyWindow(display, wnd);
315          XCloseDisplay(display);          XCloseDisplay(display);
316          display = NULL;          display = NULL;
317  }  }
318    
319  static uint8  static void
320  xwin_translate_key(unsigned long key)  xwin_process_events()
 {  
         DEBUG("KEY(code=0x%lx)\n", key);  
   
         if ((key > 8) && (key <= 0x60))  
                 return (key - 8);  
   
         switch (key)  
         {  
                 case 0x61:      /* home */  
                         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()  
321  {  {
322          XEvent event;          XEvent event;
323            KeySym keysym;
324          uint8 scancode;          uint8 scancode;
325          uint16 button;          uint16 button, flags;
326          uint32 ev_time;          uint32 ev_time;
327    
328          if (display == NULL)          if (display == NULL)
329                  return;                  return;
330    
331          while (XCheckWindowEvent(display, wnd, ~0, &event))          while (XCheckMaskEvent(display, ~0, &event))
332          {          {
333                  ev_time = time(NULL);                  ev_time = time(NULL);
334                    flags = 0;
335    
336                  switch (event.type)                  switch (event.type)
337                  {                  {
                         case KeyPress:  
                                 scancode = xwin_translate_key(event.xkey.keycode);  
                                 if (scancode == 0)  
                                         break;  
   
                                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,  
                                                scancode, 0);  
                                 break;  
   
338                          case KeyRelease:                          case KeyRelease:
339                                  scancode = xwin_translate_key(event.xkey.keycode);                                  flags = KBD_FLAG_DOWN | KBD_FLAG_UP;
340                                    /* fall through */
341    
342                            case KeyPress:
343                                    keysym = XKeycodeToKeysym(display, event.xkey.keycode, 0);
344                                    scancode = xkeymap_translate_key(keysym, event.xkey.keycode, &flags);
345                                  if (scancode == 0)                                  if (scancode == 0)
346                                          break;                                          break;
347    
348                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE,                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, flags, scancode, 0);
                                                KBD_FLAG_DOWN | KBD_FLAG_UP,  
                                                scancode, 0);  
349                                  break;                                  break;
350    
351                          case ButtonPress:                          case ButtonPress:
352                                  button = xwin_translate_mouse(event.xbutton.button);                                  flags = MOUSE_FLAG_DOWN;
353                                  if (button == 0)                                  /* fall through */
                                         break;  
   
                                 rdp_send_input(ev_time, RDP_INPUT_MOUSE,  
                                                button | MOUSE_FLAG_DOWN,  
                                                event.xbutton.x,  
                                                event.xbutton.y);  
                                 break;  
354    
355                          case ButtonRelease:                          case ButtonRelease:
356                                  button = xwin_translate_mouse(event.xbutton.button);                                  button = xkeymap_translate_button(event.xbutton.button);
357                                  if (button == 0)                                  if (button == 0)
358                                          break;                                          break;
359    
360                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
361                                                 button,                                                 flags | button,
362                                                 event.xbutton.x,                                                 event.xbutton.x,
363                                                 event.xbutton.y);                                                 event.xbutton.y);
364                                  break;                                  break;
# Line 398  ui_process_events() Line 378  ui_process_events()
378                          case LeaveNotify:                          case LeaveNotify:
379                                  XUngrabKeyboard(display, CurrentTime);                                  XUngrabKeyboard(display, CurrentTime);
380                                  break;                                  break;
381    
382                            case Expose:
383                                    XCopyArea(display, backstore, wnd, gc,
384                                              event.xexpose.x, event.xexpose.y,
385                                              event.xexpose.width, event.xexpose.height,
386                                              event.xexpose.x, event.xexpose.y);
387                                    break;
388                    }
389            }
390    }
391    
392    void
393    ui_select(int rdp_socket)
394    {
395            int n = (rdp_socket > x_socket) ? rdp_socket+1 : x_socket+1;
396            fd_set rfds;
397    
398            XFlush(display);
399    
400            FD_ZERO(&rfds);
401    
402            while (True)
403            {
404                    FD_ZERO(&rfds);
405                    FD_SET(rdp_socket, &rfds);
406                    FD_SET(x_socket, &rfds);
407    
408                    switch (select(n, &rfds, NULL, NULL, NULL))
409                    {
410                            case -1:
411                                    error("select: %s\n", strerror(errno));
412    
413                            case 0:
414                                    continue;
415                  }                  }
416    
417                    if (FD_ISSET(x_socket, &rfds))
418                            xwin_process_events();
419    
420                    if (FD_ISSET(rdp_socket, &rfds))
421                            return;
422          }          }
423  }  }
424    
# Line 415  ui_create_bitmap(int width, int height, Line 435  ui_create_bitmap(int width, int height,
435          Pixmap bitmap;          Pixmap bitmap;
436          uint8 *tdata;          uint8 *tdata;
437    
438          tdata = (owncolmap ? data : translate(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
439          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
440          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap,
441                               0, tdata, width, height, 8, 0);                               0, tdata, width, height, 8, 0);
# Line 435  ui_paint_bitmap(int x, int y, int cx, in Line 455  ui_paint_bitmap(int x, int y, int cx, in
455          XImage *image;          XImage *image;
456          uint8 *tdata;          uint8 *tdata;
457    
458          tdata = (owncolmap ? data : translate(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
459          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap,
460                               0, tdata, width, height, 8, 0);                               0, tdata, width, height, 8, 0);
461    
462          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);          if (ownbackstore)
463            {
464                    XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
465                    XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
466            }
467            else
468            {
469                    XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
470            }
471    
472          XFree(image);          XFree(image);
473          if (!owncolmap)          if (!owncolmap)
# Line 602  ui_create_colourmap(COLOURMAP *colours) Line 630  ui_create_colourmap(COLOURMAP *colours)
630          {          {
631                  uint32 *map = xmalloc(sizeof(*colmap) * ncolours);                  uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
632                  XColor xentry;                  XColor xentry;
633                    uint32 colour;
634    
635                  for (i = 0; i < ncolours; i++)                  for (i = 0; i < ncolours; i++)
636                  {                  {
# Line 609  ui_create_colourmap(COLOURMAP *colours) Line 638  ui_create_colourmap(COLOURMAP *colours)
638                          MAKE_XCOLOR(&xentry, entry);                          MAKE_XCOLOR(&xentry, entry);
639    
640                          if (XAllocColor(display, xcolmap, &xentry) != 0)                          if (XAllocColor(display, xcolmap, &xentry) != 0)
641                                  map[i] = xentry.pixel;                                  colour = xentry.pixel;
642                          else                          else
643                                  map[i] = white;                                  colour = white;
644    
645                            /* byte swap here to make translate_image faster */
646                            map[i] = translate_colour(colour);
647                  }                  }
648    
649                  return map;                  return map;
# Line 671  ui_destblt(uint8 opcode, Line 703  ui_destblt(uint8 opcode,
703             /* dest */ int x, int y, int cx, int cy)             /* dest */ int x, int y, int cx, int cy)
704  {  {
705          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
706          XFillRectangle(display, wnd, gc, x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
707          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
708  }  }
709    
# Line 688  ui_patblt(uint8 opcode, Line 720  ui_patblt(uint8 opcode,
720          {          {
721                  case 0: /* Solid */                  case 0: /* Solid */
722                          SET_FOREGROUND(fgcolour);                          SET_FOREGROUND(fgcolour);
723                          XFillRectangle(display, wnd, gc, x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
724                          break;                          break;
725    
726                  case 3: /* Pattern */                  case 3: /* Pattern */
# Line 700  ui_patblt(uint8 opcode, Line 732  ui_patblt(uint8 opcode,
732                          XSetStipple(display, gc, fill);                          XSetStipple(display, gc, fill);
733                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
734    
735                          XFillRectangle(display, wnd, gc, x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
736    
737                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
738                          ui_destroy_glyph((HGLYPH)fill);                          ui_destroy_glyph((HGLYPH)fill);
739                          break;                          break;
740    
741                  default:                  default:
742                          NOTIMP("brush %d\n", brush->style);                          unimpl("brush %d\n", brush->style);
743          }          }
744    
745          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
# Line 720  ui_screenblt(uint8 opcode, Line 752  ui_screenblt(uint8 opcode,
752  {  {
753          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
754          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
755            if (ownbackstore)
756                    XCopyArea(display, backstore, backstore, gc, srcx, srcy,
757                              cx, cy, x, y);
758          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
759  }  }
760    
# Line 730  ui_memblt(uint8 opcode, Line 765  ui_memblt(uint8 opcode,
765  {  {
766          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
767          XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);
768            if (ownbackstore)
769                    XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,
770                              cx, cy, x, y);
771          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
772  }  }
773    
# Line 765  ui_triblt(uint8 opcode, Line 803  ui_triblt(uint8 opcode,
803                          break;                          break;
804    
805                  default:                  default:
806                          NOTIMP("triblt 0x%x\n", opcode);                          unimpl("triblt 0x%x\n", opcode);
807                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
808          }          }
809  }  }
# Line 778  ui_line(uint8 opcode, Line 816  ui_line(uint8 opcode,
816          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
817          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
818          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(display, wnd, gc, startx, starty, endx, endy);
819            if (ownbackstore)
820                    XDrawLine(display, backstore, gc, startx, starty, endx, endy);
821          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
822  }  }
823    
# Line 787  ui_rect( Line 827  ui_rect(
827                 /* brush */ int colour)                 /* brush */ int colour)
828  {  {
829          SET_FOREGROUND(colour);          SET_FOREGROUND(colour);
830          XFillRectangle(display, wnd, gc, x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
831  }  }
832    
833  void  void
# Line 804  ui_draw_glyph(int mixmode, Line 844  ui_draw_glyph(int mixmode,
844          XSetStipple(display, gc, (Pixmap)glyph);          XSetStipple(display, gc, (Pixmap)glyph);
845          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(display, gc, x, y);
846    
847          XFillRectangle(display, wnd, gc, x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
848    
849          XSetFillStyle(display, gc, FillSolid);          XSetFillStyle(display, gc, FillSolid);
850  }  }
851    
852    #define DO_GLYPH(ttext,idx) \
853    {\
854      glyph = cache_get_font (font, ttext[idx]);\
855      if (!(flags & TEXT2_IMPLICIT_X))\
856        {\
857          xyoffset = ttext[++idx];\
858          if ((xyoffset & 0x80))\
859            {\
860              if (flags & TEXT2_VERTICAL) \
861                y += ttext[++idx] | (ttext[++idx] << 8);\
862              else\
863                x += ttext[++idx] | (ttext[++idx] << 8);\
864            }\
865          else\
866            {\
867              if (flags & TEXT2_VERTICAL) \
868                y += xyoffset;\
869              else\
870                x += xyoffset;\
871            }\
872        }\
873      if (glyph != NULL)\
874        {\
875          ui_draw_glyph (mixmode, x + (short) glyph->offset,\
876                         y + (short) glyph->baseline,\
877                         glyph->width, glyph->height,\
878                         glyph->pixmap, 0, 0, bgcolour, fgcolour);\
879          if (flags & TEXT2_IMPLICIT_X)\
880            x += glyph->width;\
881        }\
882    }
883    
884  void  void
885  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,
886               int clipx, int clipy, int clipcx, int clipcy,               int clipx, int clipy, int clipcx, int clipcy, int boxx,
887               int boxx, int boxy, int boxcx, int boxcy,               int boxy, int boxcx, int boxcy, int bgcolour,
888               int bgcolour, int fgcolour, uint8 *text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
889  {  {
890          FONTGLYPH *glyph;          FONTGLYPH *glyph;
891          int i, offset;          int i, j, xyoffset;
892            DATABLOB *entry;
893    
894          SET_FOREGROUND(bgcolour);          SET_FOREGROUND(bgcolour);
895    
896          if (boxcx > 1)          if (boxcx > 1)
897                  XFillRectangle(display, wnd, gc, boxx, boxy, boxcx, boxcy);          {
898                    FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);
899            }
900          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
901                  XFillRectangle(display, wnd, gc, clipx, clipy, clipcx, clipcy);          {
902                    FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);
903            }
904    
905          /* Paint text, character by character */          /* Paint text, character by character */
906          for (i = 0; i < length; i++)          for (i = 0; i < length;) {
907          {                  switch (text[i]) {
908                  glyph = cache_get_font(font, text[i]);                  case 0xff:
909                            if (i + 2 < length)
910                                    cache_put_text(text[i + 1], text, text[i + 2]);
911                            else {
912                                    error("this shouldn't be happening\n");
913                                    break;
914                            }
915                            /* this will move pointer from start to first character after FF command */
916                            length -= i + 3;
917                            text = &(text[i + 3]);
918                            i = 0;
919                            break;
920    
921                  if (!(flags & TEXT2_IMPLICIT_X))                  case 0xfe:
922                  {                          entry = cache_get_text(text[i + 1]);
923                          offset = text[++i];                          if (entry != NULL) {
924                          if (offset & 0x80)                                  if ((((uint8 *) (entry->data))[1] == 0)
925                                  offset = ((offset & 0x7f) << 8) | text[++i];                                      && (!(flags & TEXT2_IMPLICIT_X))) {
926                                            if (flags & TEXT2_VERTICAL)      
927                                                    y += text[i + 2];
928                                            else
929                                                    x += text[i + 2];
930                                    }
931                                    if (i + 2 < length)
932                                            i += 3;
933                                    else
934                                            i += 2;
935                                    length -= i;  
936                                    /* this will move pointer from start to first character after FE command */
937                                    text = &(text[i]);
938                                    i = 0;
939                                    for (j = 0; j < entry->size; j++)
940                                            DO_GLYPH(((uint8 *) (entry->data)), j);
941                            }
942                            break;
943    
944                          if (flags & TEXT2_VERTICAL)                  default:
945                                  y += offset;                          DO_GLYPH(text, i);
946                          else                          i++;
947                                  x += offset;                          break;
948                  }                  }
949            }
950    
                 if (glyph != NULL)  
                 {  
                         ui_draw_glyph(mixmode, x + (short) glyph->offset,  
                                       y + (short) glyph->baseline,  
                                       glyph->width, glyph->height,  
                                       glyph->pixmap, 0, 0,  
                                       bgcolour, fgcolour);  
951    
                         if (flags & TEXT2_IMPLICIT_X)  
                                 x += glyph->width;  
                 }  
         }  
952  }  }
953    
954  void  void
# Line 862  ui_desktop_save(uint32 offset, int x, in Line 957  ui_desktop_save(uint32 offset, int x, in
957          Pixmap pix;          Pixmap pix;
958          XImage *image;          XImage *image;
959    
960          pix = XCreatePixmap(display, wnd, cx, cy, depth);          if (ownbackstore)
961          XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);          {
962                    image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,
963          image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);                                    ZPixmap);
964            }
965            else
966            {
967                    pix = XCreatePixmap(display, wnd, cx, cy, depth);
968                    XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
969                    image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,
970                                      ZPixmap);
971                    XFreePixmap(display, pix);
972            }
973    
974          offset *= bpp/8;          offset *= bpp/8;
975          cache_put_desktop(offset, cx, cy, image->bytes_per_line,          cache_put_desktop(offset, cx, cy, image->bytes_per_line,
976                            bpp/8, image->data);                            bpp/8, (uint8 *)image->data);
977    
978          XDestroyImage(image);          XDestroyImage(image);
         XFreePixmap(display, pix);  
979  }  }
980    
981  void  void
# Line 890  ui_desktop_restore(uint32 offset, int x, Line 993  ui_desktop_restore(uint32 offset, int x,
993                               0, data, cx, cy, BitmapPad(display),                               0, data, cx, cy, BitmapPad(display),
994                               cx * bpp/8);                               cx * bpp/8);
995    
996          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);          if (ownbackstore)
997            {
998                    XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
999                    XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
1000            }
1001            else
1002            {
1003                    XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
1004            }
1005    
1006          XFree(image);          XFree(image);
1007  }  }
   

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

  ViewVC Help
Powered by ViewVC 1.1.26