/[rdesktop]/jpeg/rdesktop/trunk/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 /jpeg/rdesktop/trunk/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 34 by matty, Sat Sep 15 13:03:35 2001 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-Windows
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 int width;  extern int width;
# Line 29  extern BOOL sendmotion; Line 30  extern BOOL sendmotion;
30  extern BOOL fullscreen;  extern BOOL fullscreen;
31    
32  static Display *display;  static Display *display;
33    static int x_socket;
34  static Window wnd;  static Window wnd;
35  static GC gc;  static GC gc;
36  static Visual *visual;  static Visual *visual;
37  static int depth;  static int depth;
38  static int bpp;  static int bpp;
 static BOOL backpixmap;  
39    
40    /* endianness */
41    static BOOL host_be;
42    static BOOL xserver_be;
43    
44    /* software backing store */
45    static BOOL ownbackstore;
46    static Pixmap backstore;
47    
48    #define FILL_RECTANGLE(x,y,cx,cy)\
49    { \
50            XFillRectangle(display, wnd, gc, x, y, cx, cy); \
51            if (ownbackstore) \
52                    XFillRectangle(display, backstore, gc, x, y, cx, cy); \
53    }
54    
55    /* colour maps */
56  static BOOL owncolmap;  static BOOL owncolmap;
57  static Colormap xcolmap;  static Colormap xcolmap;
58  static uint32 white;  static uint32 white;
59  static uint32 *colmap;  static uint32 *colmap;
60    
61  #define TRANSLATE(col)          ( owncolmap ? col : colmap[col] )  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )
62  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));
63  #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));  #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));
64    
# Line 81  translate16(uint8 *data, uint16 *out, ui Line 98  translate16(uint8 *data, uint16 *out, ui
98                  *(out++) = (uint16)colmap[*(data++)];                  *(out++) = (uint16)colmap[*(data++)];
99  }  }
100    
101  /* XXX endianness */  /* little endian - conversion happens when colourmap is built */
102  static void  static void
103  translate24(uint8 *data, uint8 *out, uint8 *end)  translate24(uint8 *data, uint8 *out, uint8 *end)
104  {  {
# Line 104  translate32(uint8 *data, uint32 *out, ui Line 121  translate32(uint8 *data, uint32 *out, ui
121  }  }
122    
123  static uint8 *  static uint8 *
124  translate(int width, int height, uint8 *data)  translate_image(int width, int height, uint8 *data)
125  {  {
126          int size = width * height * bpp/8;          int size = width * height * bpp/8;
127          uint8 *out = xmalloc(size);          uint8 *out = xmalloc(size);
# Line 132  translate(int width, int height, uint8 * Line 149  translate(int width, int height, uint8 *
149          return out;          return out;
150  }  }
151    
152  #define L_ENDIAN  #define BSWAP16(x) x = (((x & 0xff) << 8) | (x >> 8));
153  int screen_msbfirst = 0;  #define BSWAP24(x) x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00));
154    #define BSWAP32(x) x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
155                       x = (x << 16) | (x >> 16);
156    
157    static uint32
158    translate_colour(uint32 colour)
159    {
160            switch (bpp)
161            {
162                    case 16:
163                            if (host_be != xserver_be)
164                                    BSWAP16(colour);
165                            break;
166    
167                    case 24:
168                            if (xserver_be)
169                                    BSWAP24(colour);
170                            break;
171    
172                    case 32:
173                            if (host_be != xserver_be)
174                                    BSWAP32(colour);
175                            break;
176            }
177    
178            return colour;
179    }
180    
181  BOOL  BOOL
182  ui_create_window(char *title)  ui_create_window(char *title)
# Line 145  ui_create_window(char *title) Line 187  ui_create_window(char *title)
187          unsigned long input_mask;          unsigned long input_mask;
188          XPixmapFormatValues *pfm;          XPixmapFormatValues *pfm;
189          Screen *screen;          Screen *screen;
190            uint16 test;
191          int i;          int i;
192    
   
193          display = XOpenDisplay(NULL);          display = XOpenDisplay(NULL);
194          if (display == NULL)          if (display == NULL)
195          {          {
196                  ERROR("Failed to open display\n");                  error("Failed to open display\n");
197                  return False;                  return False;
198          }          }
199    
200            x_socket = ConnectionNumber(display);
201          screen = DefaultScreenOfDisplay(display);          screen = DefaultScreenOfDisplay(display);
202          visual = DefaultVisualOfScreen(screen);          visual = DefaultVisualOfScreen(screen);
203          depth = DefaultDepthOfScreen(screen);          depth = DefaultDepthOfScreen(screen);
# Line 177  ui_create_window(char *title) Line 220  ui_create_window(char *title)
220    
221          if (bpp < 8)          if (bpp < 8)
222          {          {
223                  ERROR("Less than 8 bpp not currently supported.\n");                  error("Less than 8 bpp not currently supported.\n");
224                  XCloseDisplay(display);                  XCloseDisplay(display);
225                  return False;                  return False;
226          }          }
# Line 187  ui_create_window(char *title) Line 230  ui_create_window(char *title)
230          else          else
231                  xcolmap = DefaultColormapOfScreen(screen);                  xcolmap = DefaultColormapOfScreen(screen);
232    
233            test = 1;
234            host_be = !(BOOL)(*(uint8 *)(&test));
235            xserver_be = (ImageByteOrder(display) == MSBFirst);
236    
237          white = WhitePixelOfScreen(screen);          white = WhitePixelOfScreen(screen);
238          attribs.background_pixel = BlackPixelOfScreen(screen);          attribs.background_pixel = BlackPixelOfScreen(screen);
239          attribs.backing_store = DoesBackingStore(screen);          attribs.backing_store = DoesBackingStore(screen);
240    
241          if (attribs.backing_store == NotUseful)          if (attribs.backing_store == NotUseful)
242                  backpixmap = True;                  ownbackstore = True;
243    
244          if (fullscreen)          if (fullscreen)
245          {          {
# Line 205  ui_create_window(char *title) Line 252  ui_create_window(char *title)
252                  attribs.override_redirect = False;                  attribs.override_redirect = False;
253          }          }
254    
255          width &= ~3; /* make width a multiple of 32 bits */          width = (width + 3) & ~3; /* make width a multiple of 32 bits */
256    
257          wnd = XCreateWindow(display, RootWindowOfScreen(screen),          wnd = XCreateWindow(display, RootWindowOfScreen(screen),
258                              0, 0, width, height, 0, CopyFromParent,                              0, 0, width, height, 0, CopyFromParent,
# Line 240  ui_create_window(char *title) Line 287  ui_create_window(char *title)
287          if (sendmotion)          if (sendmotion)
288                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
289    
290            if (ownbackstore)
291                    input_mask |= ExposureMask;
292    
293          XSelectInput(display, wnd, input_mask);          XSelectInput(display, wnd, input_mask);
294          gc = XCreateGC(display, wnd, 0, NULL);          gc = XCreateGC(display, wnd, 0, NULL);
295    
296            if (ownbackstore)
297                    backstore = XCreatePixmap(display, wnd, width, height, depth);
298    
299          XMapWindow(display, wnd);          XMapWindow(display, wnd);
300          return True;          return True;
301  }  }
# Line 250  ui_create_window(char *title) Line 303  ui_create_window(char *title)
303  void  void
304  ui_destroy_window()  ui_destroy_window()
305  {  {
306            if (ownbackstore)
307                    XFreePixmap(display, backstore);
308    
309          XFreeGC(display, gc);          XFreeGC(display, gc);
310          XDestroyWindow(display, wnd);          XDestroyWindow(display, wnd);
311          XCloseDisplay(display);          XCloseDisplay(display);
# Line 259  ui_destroy_window() Line 315  ui_destroy_window()
315  static uint8  static uint8
316  xwin_translate_key(unsigned long key)  xwin_translate_key(unsigned long key)
317  {  {
318          DEBUG("KEY(code=0x%lx)\n", key);          DEBUG(("KEY(code=0x%lx)\n", key));
319    
320          if ((key > 8) && (key <= 0x60))          if ((key > 8) && (key <= 0x60))
321                  return (key - 8);                  return (key - 8);
# Line 325  xwin_translate_mouse(unsigned long butto Line 381  xwin_translate_mouse(unsigned long butto
381          return 0;          return 0;
382  }  }
383    
384  void  static void
385  ui_process_events()  xwin_process_events()
386  {  {
387          XEvent event;          XEvent event;
388          uint8 scancode;          uint8 scancode;
# Line 398  ui_process_events() Line 454  ui_process_events()
454                          case LeaveNotify:                          case LeaveNotify:
455                                  XUngrabKeyboard(display, CurrentTime);                                  XUngrabKeyboard(display, CurrentTime);
456                                  break;                                  break;
457    
458                            case Expose:
459                                    XCopyArea(display, backstore, wnd, gc,
460                                              event.xexpose.x, event.xexpose.y,
461                                              event.xexpose.width, event.xexpose.height,
462                                              event.xexpose.x, event.xexpose.y);
463                                    break;
464                  }                  }
465          }          }
466  }  }
467    
468  void  void
469    ui_select(int rdp_socket)
470    {
471            int n = (rdp_socket > x_socket) ? rdp_socket+1 : x_socket+1;
472            fd_set rfds;
473    
474            XFlush(display);
475    
476            FD_ZERO(&rfds);
477    
478            while (True)
479            {
480                    FD_ZERO(&rfds);
481                    FD_SET(rdp_socket, &rfds);
482                    FD_SET(x_socket, &rfds);
483    
484                    switch (select(n, &rfds, NULL, NULL, NULL))
485                    {
486                            case -1:
487                                    error("select: %s\n", strerror(errno));
488    
489                            case 0:
490                                    continue;
491                    }
492    
493                    if (FD_ISSET(x_socket, &rfds))
494                            xwin_process_events();
495    
496                    if (FD_ISSET(rdp_socket, &rfds))
497                            return;
498            }
499    }
500    
501    void
502  ui_move_pointer(int x, int y)  ui_move_pointer(int x, int y)
503  {  {
504          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
# Line 415  ui_create_bitmap(int width, int height, Line 511  ui_create_bitmap(int width, int height,
511          Pixmap bitmap;          Pixmap bitmap;
512          uint8 *tdata;          uint8 *tdata;
513    
514          tdata = (owncolmap ? data : translate(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
515          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
516          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap,
517                               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 531  ui_paint_bitmap(int x, int y, int cx, in
531          XImage *image;          XImage *image;
532          uint8 *tdata;          uint8 *tdata;
533    
534          tdata = (owncolmap ? data : translate(width, height, data));          tdata = (owncolmap ? data : translate_image(width, height, data));
535          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap,
536                               0, tdata, width, height, 8, 0);                               0, tdata, width, height, 8, 0);
537    
538          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);          if (ownbackstore)
539            {
540                    XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
541                    XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
542            }
543            else
544            {
545                    XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
546            }
547    
548          XFree(image);          XFree(image);
549          if (!owncolmap)          if (!owncolmap)
# Line 602  ui_create_colourmap(COLOURMAP *colours) Line 706  ui_create_colourmap(COLOURMAP *colours)
706          {          {
707                  uint32 *map = xmalloc(sizeof(*colmap) * ncolours);                  uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
708                  XColor xentry;                  XColor xentry;
709                    uint32 colour;
710    
711                  for (i = 0; i < ncolours; i++)                  for (i = 0; i < ncolours; i++)
712                  {                  {
# Line 609  ui_create_colourmap(COLOURMAP *colours) Line 714  ui_create_colourmap(COLOURMAP *colours)
714                          MAKE_XCOLOR(&xentry, entry);                          MAKE_XCOLOR(&xentry, entry);
715    
716                          if (XAllocColor(display, xcolmap, &xentry) != 0)                          if (XAllocColor(display, xcolmap, &xentry) != 0)
717                                  map[i] = xentry.pixel;                                  colour = xentry.pixel;
718                          else                          else
719                                  map[i] = white;                                  colour = white;
720    
721                            /* byte swap here to make translate_image faster */
722                            map[i] = translate_colour(colour);
723                  }                  }
724    
725                  return map;                  return map;
# Line 671  ui_destblt(uint8 opcode, Line 779  ui_destblt(uint8 opcode,
779             /* dest */ int x, int y, int cx, int cy)             /* dest */ int x, int y, int cx, int cy)
780  {  {
781          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
782          XFillRectangle(display, wnd, gc, x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
783          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
784  }  }
785    
# Line 688  ui_patblt(uint8 opcode, Line 796  ui_patblt(uint8 opcode,
796          {          {
797                  case 0: /* Solid */                  case 0: /* Solid */
798                          SET_FOREGROUND(fgcolour);                          SET_FOREGROUND(fgcolour);
799                          XFillRectangle(display, wnd, gc, x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
800                          break;                          break;
801    
802                  case 3: /* Pattern */                  case 3: /* Pattern */
# Line 700  ui_patblt(uint8 opcode, Line 808  ui_patblt(uint8 opcode,
808                          XSetStipple(display, gc, fill);                          XSetStipple(display, gc, fill);
809                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
810    
811                          XFillRectangle(display, wnd, gc, x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
812    
813                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
814                          ui_destroy_glyph((HGLYPH)fill);                          ui_destroy_glyph((HGLYPH)fill);
815                          break;                          break;
816    
817                  default:                  default:
818                          NOTIMP("brush %d\n", brush->style);                          unimpl("brush %d\n", brush->style);
819          }          }
820    
821          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
# Line 720  ui_screenblt(uint8 opcode, Line 828  ui_screenblt(uint8 opcode,
828  {  {
829          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
830          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
831            if (ownbackstore)
832                    XCopyArea(display, backstore, backstore, gc, srcx, srcy,
833                              cx, cy, x, y);
834          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
835  }  }
836    
# Line 730  ui_memblt(uint8 opcode, Line 841  ui_memblt(uint8 opcode,
841  {  {
842          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
843          XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);
844            if (ownbackstore)
845                    XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,
846                              cx, cy, x, y);
847          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
848  }  }
849    
# Line 765  ui_triblt(uint8 opcode, Line 879  ui_triblt(uint8 opcode,
879                          break;                          break;
880    
881                  default:                  default:
882                          NOTIMP("triblt 0x%x\n", opcode);                          unimpl("triblt 0x%x\n", opcode);
883                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
884          }          }
885  }  }
# Line 778  ui_line(uint8 opcode, Line 892  ui_line(uint8 opcode,
892          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
893          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
894          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(display, wnd, gc, startx, starty, endx, endy);
895            if (ownbackstore)
896                    XDrawLine(display, backstore, gc, startx, starty, endx, endy);
897          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
898  }  }
899    
# Line 787  ui_rect( Line 903  ui_rect(
903                 /* brush */ int colour)                 /* brush */ int colour)
904  {  {
905          SET_FOREGROUND(colour);          SET_FOREGROUND(colour);
906          XFillRectangle(display, wnd, gc, x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
907  }  }
908    
909  void  void
# Line 804  ui_draw_glyph(int mixmode, Line 920  ui_draw_glyph(int mixmode,
920          XSetStipple(display, gc, (Pixmap)glyph);          XSetStipple(display, gc, (Pixmap)glyph);
921          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(display, gc, x, y);
922    
923          XFillRectangle(display, wnd, gc, x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
924    
925          XSetFillStyle(display, gc, FillSolid);          XSetFillStyle(display, gc, FillSolid);
926  }  }
# Line 821  ui_draw_text(uint8 font, uint8 flags, in Line 937  ui_draw_text(uint8 font, uint8 flags, in
937          SET_FOREGROUND(bgcolour);          SET_FOREGROUND(bgcolour);
938    
939          if (boxcx > 1)          if (boxcx > 1)
940                  XFillRectangle(display, wnd, gc, boxx, boxy, boxcx, boxcy);          {
941                    FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);
942            }
943          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
944                  XFillRectangle(display, wnd, gc, clipx, clipy, clipcx, clipcy);          {
945                    FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);
946            }
947    
948          /* Paint text, character by character */          /* Paint text, character by character */
949          for (i = 0; i < length; i++)          for (i = 0; i < length; i++)
# Line 862  ui_desktop_save(uint32 offset, int x, in Line 982  ui_desktop_save(uint32 offset, int x, in
982          Pixmap pix;          Pixmap pix;
983          XImage *image;          XImage *image;
984    
985          pix = XCreatePixmap(display, wnd, cx, cy, depth);          if (ownbackstore)
986          XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);          {
987                    image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,
988          image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);                                    ZPixmap);
989            }
990            else
991            {
992                    pix = XCreatePixmap(display, wnd, cx, cy, depth);
993                    XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
994                    image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,
995                                      ZPixmap);
996                    XFreePixmap(display, pix);
997            }
998    
999          offset *= bpp/8;          offset *= bpp/8;
1000          cache_put_desktop(offset, cx, cy, image->bytes_per_line,          cache_put_desktop(offset, cx, cy, image->bytes_per_line,
1001                            bpp/8, image->data);                            bpp/8, image->data);
1002    
1003          XDestroyImage(image);          XDestroyImage(image);
         XFreePixmap(display, pix);  
1004  }  }
1005    
1006  void  void
# Line 890  ui_desktop_restore(uint32 offset, int x, Line 1018  ui_desktop_restore(uint32 offset, int x,
1018                               0, data, cx, cy, BitmapPad(display),                               0, data, cx, cy, BitmapPad(display),
1019                               cx * bpp/8);                               cx * bpp/8);
1020    
1021          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);          if (ownbackstore)
1022            {
1023                    XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
1024                    XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
1025            }
1026            else
1027            {
1028                    XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
1029            }
1030    
1031          XFree(image);          XFree(image);
1032  }  }
   

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

  ViewVC Help
Powered by ViewVC 1.1.26