/[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 25 by matty, Sat Jan 6 03:47:04 2001 UTC revision 28 by matty, Wed Jun 20 13:54:48 2001 UTC
# Line 19  Line 19 
19  */  */
20    
21  #include <X11/Xlib.h>  #include <X11/Xlib.h>
22    #include <X11/Xutil.h>
23  #include <time.h>  #include <time.h>
24  #include "rdesktop.h"  #include "rdesktop.h"
25    
26  extern int width;  extern int width;
27  extern int height;  extern int height;
28  extern BOOL motion;  extern BOOL motion;
29    extern BOOL grab_keyboard;
30    extern BOOL fullscreen;
31    extern int private_colormap;
32    
33    static int bpp;
34    static int depth;
35  static Display *display;  static Display *display;
36  static Window wnd;  static Window wnd;
37  static GC gc;  static GC gc;
38  static Visual *visual;  static Visual *visual;
39  static XIM IM;  static uint32 *colmap;
40    
41    #define Ctrans(col) ( private_colormap ? col : colmap[col])
42    
43    #define L_ENDIAN
44    int screen_msbfirst = 0;
45    
46    static uint8 *translate(int width, int height, uint8 *data);
47    
48    static int rop2_map[] = {
49            GXclear,                /* 0 */
50            GXnor,                  /* DPon */
51            GXandInverted,          /* DPna */
52            GXcopyInverted,         /* Pn */
53            GXandReverse,           /* PDna */
54            GXinvert,               /* Dn */
55            GXxor,                  /* DPx */
56            GXnand,                 /* DPan */
57            GXand,                  /* DPa */
58            GXequiv,                /* DPxn */
59            GXnoop,                 /* D */
60            GXorInverted,           /* DPno */
61            GXcopy,                 /* P */
62            GXorReverse,            /* PDno */
63            GXor,                   /* DPo */
64            GXset                   /* 1 */
65    };
66    
67    static void
68    xwin_set_function(uint8 rop2)
69    {
70            static uint8 last_rop2 = ROP2_COPY;
71    
72            if (last_rop2 != rop2)
73            {
74                    XSetFunction(display, gc, rop2_map[rop2]);
75                    last_rop2 = rop2;
76            }
77    }
78    
79    static void
80    xwin_grab_keyboard()
81    {
82            XGrabKeyboard(display, wnd, True, GrabModeAsync, GrabModeAsync,
83                          CurrentTime);
84    }
85    
86    static void
87    xwin_ungrab_keyboard()
88    {
89            XUngrabKeyboard(display, CurrentTime);
90    }
91    
92  BOOL  BOOL
93  ui_create_window(char *title)  ui_create_window(char *title)
94  {  {
         Screen *screen;  
95          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
96            XClassHint *classhints;
97            XSizeHints *sizehints;
98          unsigned long input_mask;          unsigned long input_mask;
99          int i;          XPixmapFormatValues *pfm;
100            int count;
101    
102          display = XOpenDisplay(NULL);          display = XOpenDisplay(NULL);
103          if (display == NULL)          if (display == NULL)
# Line 47  ui_create_window(char *title) Line 106  ui_create_window(char *title)
106                  return False;                  return False;
107          }          }
108    
109          /* Check the screen supports 8-bit depth. */          visual = DefaultVisual(display, DefaultScreen(display));
110          screen = DefaultScreenOfDisplay(display);          depth = DefaultDepth(display, DefaultScreen(display));
111          for (i = 0; i < screen->ndepths; i++)          pfm = XListPixmapFormats(display, &count);
112                  if (screen->depths[i].depth == 8)          if (pfm != NULL)
113                          break;          {
114                    while (count--)
115                    {
116                            if ((pfm + count)->depth == depth
117                                && (pfm + count)->bits_per_pixel > bpp)
118                            {
119                                    bpp = (pfm + count)->bits_per_pixel;
120                            }
121                    }
122                    XFree(pfm);
123            }
124    
125          if (i >= screen->ndepths)          if (bpp < 8)
126          {          {
127                  ERROR("8-bit depth required (in this version).\n");                  ERROR("Less than 8 bpp not currently supported.\n");
128                  XCloseDisplay(display);                  XCloseDisplay(display);
129                  return False;                  return False;
130          }          }
131    
132          visual = DefaultVisual(display, DefaultScreen(display));          width &= ~3; /* make width nicely divisible */
133    
134          attribs.background_pixel =          attribs.background_pixel = BlackPixel(display, DefaultScreen(display));
                 BlackPixel(display, DefaultScreen(display));  
135          attribs.backing_store = Always;          attribs.backing_store = Always;
136    
137            if (fullscreen)
138            {
139                    attribs.override_redirect = True;
140                    width = WidthOfScreen(DefaultScreenOfDisplay(display));
141                    height = HeightOfScreen(DefaultScreenOfDisplay(display));
142                    XSetInputFocus(display, PointerRoot, RevertToPointerRoot,
143                                   CurrentTime);
144            }
145            else
146            {
147                    attribs.override_redirect = False;
148            }
149    
150          wnd = XCreateWindow(display, DefaultRootWindow(display),          wnd = XCreateWindow(display, DefaultRootWindow(display),
151                              0, 0, width, height, 0, 8, InputOutput, visual,                              0, 0, width, height, 0, CopyFromParent,
152                              CWBackingStore | CWBackPixel, &attribs);                              InputOutput, CopyFromParent,
153                                CWBackingStore | CWBackPixel | CWOverrideRedirect,
154                                &attribs);
155    
156          XStoreName(display, wnd, title);          XStoreName(display, wnd, title);
157          XMapWindow(display, wnd);  
158            classhints = XAllocClassHint();
159            if (classhints != NULL)
160    
161            {
162                    classhints->res_name = "rdesktop";
163                    classhints->res_class = "rdesktop";
164                    XSetClassHint(display, wnd, classhints);
165                    XFree(classhints);
166            }
167    
168            sizehints = XAllocSizeHints();
169            if (sizehints)
170            {
171                    sizehints->flags =
172                            PPosition | PSize | PMinSize | PMaxSize | PBaseSize;
173                    sizehints->min_width = width;
174                    sizehints->max_width = width;
175                    sizehints->min_height = height;
176                    sizehints->max_height = height;
177                    sizehints->base_width = width;
178                    sizehints->base_height = height;
179                    XSetWMNormalHints(display, wnd, sizehints);
180                    XFree(sizehints);
181            }
182    
183          input_mask = KeyPressMask | KeyReleaseMask;          input_mask = KeyPressMask | KeyReleaseMask;
184          input_mask |= ButtonPressMask | ButtonReleaseMask;          input_mask |= ButtonPressMask | ButtonReleaseMask;
185          if (motion)          if (motion)
186                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
187            if (grab_keyboard)
188                    input_mask |= EnterWindowMask | LeaveWindowMask;
189    
190          XSelectInput(display, wnd, input_mask);          XSelectInput(display, wnd, input_mask);
191          gc = XCreateGC(display, wnd, 0, NULL);          gc = XCreateGC(display, wnd, 0, NULL);
192    
193          IM = XOpenIM(display, NULL, NULL, NULL);          XMapWindow(display, wnd);
194          return True;          return True;
195  }  }
196    
197  void  void
198  ui_destroy_window()  ui_destroy_window()
199  {  {
         XCloseIM(IM);  
200          XFreeGC(display, gc);          XFreeGC(display, gc);
201          XDestroyWindow(display, wnd);          XDestroyWindow(display, wnd);
202          XCloseDisplay(display);          XCloseDisplay(display);
203            display = NULL;
204  }  }
205    
206  static uint8  static uint8
# Line 103  xwin_translate_key(unsigned long key) Line 213  xwin_translate_key(unsigned long key)
213    
214          switch (key)          switch (key)
215          {          {
216                  case 0x62:      /* left arrow */                  case 0x61:      /* home */
217                          return 0x48;                          return 0x47 | 0x80;
218                  case 0x64:      /* up arrow */                  case 0x62:      /* up arrow */
219                          return 0x4b;                          return 0x48 | 0x80;
220                  case 0x66:      /* down arrow */                  case 0x63:      /* page up */
221                          return 0x4d;                          return 0x49 | 0x80;
222                  case 0x68:      /* right arrow */                  case 0x64:      /* left arrow */
223                          return 0x50;                          return 0x4b | 0x80;
224                  case 0x73:      /* Windows key */                  case 0x66:      /* right arrow */
225                          DEBUG("CHECKPOINT\n");                          return 0x4d | 0x80;
226                    case 0x67:      /* end */
227                            return 0x4f | 0x80;
228                    case 0x68:      /* down arrow */
229                            return 0x50 | 0x80;
230                    case 0x69:      /* page down */
231                            return 0x51 | 0x80;
232                    case 0x6a:      /* insert */
233                            return 0x52 | 0x80;
234                    case 0x6b:      /* delete */
235                            return 0x53 | 0x80;
236                    case 0x6c:      /* keypad enter */
237                            return 0x1c | 0x80;
238                    case 0x6d:      /* right ctrl */
239                            return 0x1d | 0x80;
240                    case 0x6f:      /* ctrl - print screen */
241                            return 0x37 | 0x80;
242                    case 0x70:      /* keypad '/' */
243                            return 0x35 | 0x80;
244                    case 0x71:      /* right alt */
245                            return 0x38 | 0x80;
246                    case 0x72:      /* ctrl break */
247                            return 0x46 | 0x80;
248                    case 0x73:      /* left window key */
249                            return 0xff;    /* real scancode is 5b */
250                    case 0x74:      /* right window key */
251                            return 0xff;    /* real scancode is 5c */
252                    case 0x75:      /* menu key */
253                            return 0x5d | 0x80;
254          }          }
255    
256          return 0;          return 0;
# Line 145  ui_process_events() Line 283  ui_process_events()
283          if (display == NULL)          if (display == NULL)
284                  return;                  return;
285    
286          while (XCheckWindowEvent(display, wnd, 0xffffffff, &event))          while (XCheckWindowEvent(display, wnd, ~0, &event))
287          {          {
288                  ev_time = time(NULL);                  ev_time = time(NULL);
289    
290                  switch (event.type)                  switch (event.type)
291                  {                  {
292                          case KeyPress:                          case KeyPress:
293                                  scancode =                                  scancode = xwin_translate_key(event.xkey.keycode);
                                         xwin_translate_key(event.  
                                                            xkey.keycode);  
294                                  if (scancode == 0)                                  if (scancode == 0)
295                                          break;                                          break;
296    
# Line 163  ui_process_events() Line 299  ui_process_events()
299                                  break;                                  break;
300    
301                          case KeyRelease:                          case KeyRelease:
302                                  scancode =                                  scancode = xwin_translate_key(event.xkey.keycode);
                                         xwin_translate_key(event.  
                                                            xkey.keycode);  
303                                  if (scancode == 0)                                  if (scancode == 0)
304                                          break;                                          break;
305    
# Line 175  ui_process_events() Line 309  ui_process_events()
309                                  break;                                  break;
310    
311                          case ButtonPress:                          case ButtonPress:
312                                  button =                                  button = xwin_translate_mouse(event.xbutton.button);
                                         xwin_translate_mouse(event.  
                                                              xbutton.button);  
   
313                                  if (button == 0)                                  if (button == 0)
314                                          break;                                          break;
315    
# Line 189  ui_process_events() Line 320  ui_process_events()
320                                  break;                                  break;
321    
322                          case ButtonRelease:                          case ButtonRelease:
323                                  button =                                  button = xwin_translate_mouse(event.xbutton.button);
                                         xwin_translate_mouse(event.  
                                                              xbutton.button);  
324                                  if (button == 0)                                  if (button == 0)
325                                          break;                                          break;
326    
# Line 206  ui_process_events() Line 335  ui_process_events()
335                                                 MOUSE_FLAG_MOVE,                                                 MOUSE_FLAG_MOVE,
336                                                 event.xmotion.x,                                                 event.xmotion.x,
337                                                 event.xmotion.y);                                                 event.xmotion.y);
338                                    break;
339    
340                            case EnterNotify:
341                                    if (grab_keyboard)
342                                            xwin_grab_keyboard();
343                                    break;
344    
345                            case LeaveNotify:
346                                    if (grab_keyboard)
347                                            xwin_ungrab_keyboard();
348                                    break;
349                  }                  }
350          }          }
351  }  }
# Line 221  ui_create_bitmap(int width, int height, Line 361  ui_create_bitmap(int width, int height,
361  {  {
362          XImage *image;          XImage *image;
363          Pixmap bitmap;          Pixmap bitmap;
364            uint8 *tdata;
365            tdata = (private_colormap ? data : translate(width, height, data));
366            bitmap = XCreatePixmap(display, wnd, width, height, depth);
367            image =
368                    XCreateImage(display, visual,
369                                 depth, ZPixmap,
370                                 0, tdata, width, height, BitmapPad(display), 0);
371    
372          bitmap = XCreatePixmap(display, wnd, width, height, 8);          xwin_set_function(ROP2_COPY);
   
         image = XCreateImage(display, visual, 8, ZPixmap, 0,  
                              data, width, height, 8, width);  
         XSetFunction(display, gc, GXcopy);  
373          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
         XFree(image);  
374    
375            XFree(image);
376            if (!private_colormap)
377                    xfree(tdata);
378          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
379  }  }
380    
# Line 238  ui_paint_bitmap(int x, int y, int cx, in Line 383  ui_paint_bitmap(int x, int y, int cx, in
383                  int width, int height, uint8 *data)                  int width, int height, uint8 *data)
384  {  {
385          XImage *image;          XImage *image;
386            uint8 *tdata =
387                    (private_colormap ? data : translate(width, height, data));
388            image =
389                    XCreateImage(display, visual, depth, ZPixmap, 0, tdata, width,
390                                 height, BitmapPad(display), 0);
391    
392          image = XCreateImage(display, visual, 8, ZPixmap, 0,          xwin_set_function(ROP2_COPY);
393                               data, width, height, 8, width);  
394          XSetFunction(display, gc, GXcopy);          /* Window */
395          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
396          XFree(image);          XFree(image);
397            if (!private_colormap)
398                    xfree(tdata);
399  }  }
400    
401  void  void
# Line 252  ui_destroy_bitmap(HBITMAP bmp) Line 404  ui_destroy_bitmap(HBITMAP bmp)
404          XFreePixmap(display, (Pixmap) bmp);          XFreePixmap(display, (Pixmap) bmp);
405  }  }
406    
407    HCURSOR
408    ui_create_cursor(unsigned int x, unsigned int y, int width,
409                     int height, uint8 *mask, uint8 *data)
410    {
411            XImage *imagecursor;
412            XImage *imagemask;
413            Pixmap maskbitmap, cursorbitmap;
414            Cursor cursor;
415            XColor bg, fg;
416            GC lgc;
417            int i, x1, y1, scanlinelen;
418            uint8 *cdata, *cmask;
419            uint8 c;
420            cdata = (uint8 *) malloc(sizeof(uint8) * width * height);
421            if (!cdata)
422                    return NULL;
423            scanlinelen = (width + 7) >> 3;
424            cmask = (uint8 *) malloc(sizeof(uint8) * scanlinelen * height);
425            if (!cmask)
426            {
427                    free(cdata);
428                    return NULL;
429            }
430            i = (height - 1) * scanlinelen;
431    
432            if (!screen_msbfirst)
433            {
434                    while (i >= 0)
435                    {
436                            for (x1 = 0; x1 < scanlinelen; x1++)
437                            {
438                                    c = *(mask++);
439                                    cmask[i + x1] =
440                                            ((c & 0x1) << 7) | ((c & 0x2) << 5) |
441                                            ((c & 0x4) << 3) | ((c & 0x8) << 1) |
442                                            ((c & 0x10) >> 1) | ((c & 0x20) >> 3)
443                                            | ((c & 0x40) >> 5) | ((c & 0x80) >>
444                                                                   7);
445                            }
446                            i -= scanlinelen;
447                    }
448            }
449            else
450            {
451                    while (i >= 0)
452                    {
453                            for (x1 = 0; x1 < scanlinelen; x1++)
454                            {
455                                    cmask[i + x1] = *(mask++);
456                            }
457                            i -= scanlinelen;
458                    }
459            }
460    
461    
462            fg.red = 0;
463            fg.blue = 0;
464            fg.green = 0;
465            fg.flags = DoRed | DoBlue | DoGreen;
466            bg.red = 65535;
467            bg.blue = 65535;
468            bg.green = 65535;
469            bg.flags = DoRed | DoBlue | DoGreen;
470            maskbitmap = XCreatePixmap(display, wnd, width, height, 1);
471            cursorbitmap = XCreatePixmap(display, wnd, width, height, 1);
472            lgc = XCreateGC(display, maskbitmap, 0, NULL);
473            XSetFunction(display, lgc, GXcopy);
474            imagemask =
475                    XCreateImage(display, visual, 1, XYBitmap, 0, cmask, width,
476                                 height, 8, 0);
477            imagecursor =
478                    XCreateImage(display, visual, 1, XYBitmap, 0, cdata, width,
479                                 height, 8, 0);
480            for (y1 = height - 1; y1 >= 0; y1--)
481                    for (x1 = 0; x1 < width; x1++)
482                    {
483                            if (data[0] >= 0x80 || data[1] >= 0x80
484                                || data[2] >= 0x80)
485                                    if (XGetPixel(imagemask, x1, y1))
486    
487                                    {
488                                            XPutPixel(imagecursor, x1, y1, 0);
489                                            XPutPixel(imagemask, x1, y1, 0);        /* mask is blank for text cursor! */
490                                    }
491    
492                                    else
493                                            XPutPixel(imagecursor, x1, y1, 1);
494    
495                            else
496                                    XPutPixel(imagecursor, x1, y1,
497                                              XGetPixel(imagemask, x1, y1));
498                            data += 3;
499                    }
500            XPutImage(display, maskbitmap, lgc, imagemask, 0, 0, 0, 0, width,
501                      height);
502            XPutImage(display, cursorbitmap, lgc, imagecursor, 0, 0, 0, 0, width,
503                      height); XFree(imagemask);
504            XFree(imagecursor);
505            free(cmask);
506            free(cdata);
507            XFreeGC(display, lgc);
508            cursor =
509                    XCreatePixmapCursor(display, cursorbitmap, maskbitmap, &fg,
510                                        &bg, x, y);
511            XFreePixmap(display, maskbitmap);
512            XFreePixmap(display, cursorbitmap);
513            return (HCURSOR) cursor;
514    }
515    
516    void
517    ui_set_cursor(HCURSOR cursor)
518    {
519            XDefineCursor(display, wnd, (Cursor) cursor);
520    }
521    
522    void
523    ui_destroy_cursor(HCURSOR cursor)
524    {
525            XFreeCursor(display, (Cursor) cursor);
526    }
527    
528  HGLYPH  HGLYPH
529  ui_create_glyph(int width, int height, uint8 *data)  ui_create_glyph(int width, int height, uint8 *data)
530  {  {
# Line 288  ui_destroy_glyph(HGLYPH glyph) Line 561  ui_destroy_glyph(HGLYPH glyph)
561  HCOLOURMAP  HCOLOURMAP
562  ui_create_colourmap(COLOURMAP *colours)  ui_create_colourmap(COLOURMAP *colours)
563  {  {
564          COLOURENTRY *entry;          if (!private_colormap)
         XColor *xcolours, *xentry;  
         Colormap map;  
         int i, ncolours = colours->ncolours;  
   
         xcolours = xmalloc(sizeof(XColor) * ncolours);  
         for (i = 0; i < ncolours; i++)  
565          {          {
566                  entry = &colours->colours[i];                  COLOURENTRY *entry;
567                  xentry = &xcolours[i];                  int i, ncolours = colours->ncolours;
568                    uint32 *nc = xmalloc(sizeof(*colmap) * ncolours);
569                  xentry->pixel = i;                  for (i = 0; i < ncolours; i++)
570                  xentry->red = entry->red << 8;                  {
571                  xentry->blue = entry->blue << 8;                          XColor xc;
572                  xentry->green = entry->green << 8;                          entry = &colours->colours[i];
573                  xentry->flags = DoRed | DoBlue | DoGreen;                          xc.red = entry->red << 8;
574                            xc.green = entry->green << 8;
575                            xc.blue = entry->blue << 8;
576                            XAllocColor(display,
577                                        DefaultColormap(display,
578                                                        DefaultScreen(display)),
579                                        &xc);
580                            /* XXX Check return value */
581                            nc[i] = xc.pixel;
582                    }
583                    return nc;
584          }          }
585            else
586            {
587                    COLOURENTRY *entry;
588                    XColor *xcolours, *xentry;
589                    Colormap map;
590                    int i, ncolours = colours->ncolours;
591                    xcolours = xmalloc(sizeof(XColor) * ncolours);
592                    for (i = 0; i < ncolours; i++)
593                    {
594                            entry = &colours->colours[i];
595                            xentry = &xcolours[i];
596    
597          map = XCreateColormap(display, wnd, visual, AllocAll);                          xentry->pixel = i;
598          XStoreColors(display, map, xcolours, ncolours);                          xentry->red = entry->red << 8;
599                            xentry->blue = entry->blue << 8;
600                            xentry->green = entry->green << 8;
601                            xentry->flags = DoRed | DoBlue | DoGreen;
602                    }
603    
604                    map = XCreateColormap(display, wnd, visual, AllocAll);
605                    XStoreColors(display, map, xcolours, ncolours);
606    
607          xfree(xcolours);                  xfree(xcolours);
608          return (HCOLOURMAP) map;                  return (HCOLOURMAP) map;
609            }
610  }  }
611    
612  void  void
# Line 322  ui_destroy_colourmap(HCOLOURMAP map) Line 618  ui_destroy_colourmap(HCOLOURMAP map)
618  void  void
619  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
620  {  {
621          XSetWindowColormap(display, wnd, (Colormap) map);  
622            /* XXX, change values of all pixels on the screen if the new colmap
623             * doesn't have the same values as the old one? */
624            if (!private_colormap)
625                    colmap = map;
626            else
627            {
628                    XSetWindowColormap(display, wnd, (Colormap) map);
629                    if (fullscreen)
630                            XInstallColormap(display, (Colormap) map);
631            }
632  }  }
633    
634  void  void
# Line 355  ui_bell() Line 661  ui_bell()
661          XBell(display, 0);          XBell(display, 0);
662  }  }
663    
 static int rop2_map[] = {  
         GXclear,                /* 0 */  
         GXnor,                  /* DPon */  
         GXandInverted,          /* DPna */  
         GXcopyInverted,         /* Pn */  
         GXandReverse,           /* PDna */  
         GXinvert,               /* Dn */  
         GXxor,                  /* DPx */  
         GXnand,                 /* DPan */  
         GXand,                  /* DPa */  
         GXequiv,                /* DPxn */  
         GXnoop,                 /* D */  
         GXorInverted,           /* DPno */  
         GXcopy,                 /* P */  
         GXorReverse,            /* PDno */  
         GXor,                   /* DPo */  
         GXset                   /* 1 */  
 };  
   
 static void  
 xwin_set_function(uint8 rop2)  
 {  
         XSetFunction(display, gc, rop2_map[rop2]);  
 }  
   
664  void  void
665  ui_destblt(uint8 opcode,  ui_destblt(uint8 opcode,
666             /* dest */ int x, int y, int cx, int cy)             /* dest */ int x, int y, int cx, int cy)
# Line 396  ui_patblt(uint8 opcode, Line 677  ui_patblt(uint8 opcode,
677  {  {
678          Display *dpy = display;          Display *dpy = display;
679          Pixmap fill;          Pixmap fill;
680            uint8 i, ipattern[8];
681    
682          xwin_set_function(opcode);          xwin_set_function(opcode);
683    
684          switch (brush->style)          switch (brush->style)
685          {          {
686                  case 0: /* Solid */                  case 0: /* Solid */
687                          XSetForeground(dpy, gc, fgcolour);                          XSetForeground(dpy, gc, Ctrans(fgcolour));
688                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
689                          break;                          break;
690    
691                  case 3: /* Pattern */                  case 3: /* Pattern */
692                          fill = (Pixmap) ui_create_glyph(8, 8, brush->pattern);                          for (i = 0; i != 8; i++)
693                                    ipattern[i] = ~brush->pattern[i];
694                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
695    
696                          XSetForeground(dpy, gc, fgcolour);                          XSetForeground(dpy, gc, Ctrans(fgcolour));
697                          XSetBackground(dpy, gc, bgcolour);                          XSetBackground(dpy, gc, Ctrans(bgcolour));
698                          XSetFillStyle(dpy, gc, FillOpaqueStippled);                          XSetFillStyle(dpy, gc, FillOpaqueStippled);
699                          XSetStipple(dpy, gc, fill);                          XSetStipple(dpy, gc, fill);
700    
# Line 470  ui_triblt(uint8 opcode, Line 754  ui_triblt(uint8 opcode,
754                                    brush, bgcolour, fgcolour);                                    brush, bgcolour, fgcolour);
755                          break;                          break;
756    
757                    case 0xc0:
758                            ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
759                            ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,
760                                      fgcolour);
761                            break;
762    
763                  default:                  default:
764                          NOTIMP("triblt 0x%x\n", opcode);                          NOTIMP("triblt 0x%x\n", opcode);
765                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
# Line 483  ui_line(uint8 opcode, Line 773  ui_line(uint8 opcode,
773  {  {
774          xwin_set_function(opcode);          xwin_set_function(opcode);
775    
776          XSetForeground(display, gc, pen->colour);          XSetForeground(display, gc, Ctrans(pen->colour));
777          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(display, wnd, gc, startx, starty, endx, endy);
778  }  }
779    
# Line 494  ui_rect( Line 784  ui_rect(
784  {  {
785          xwin_set_function(ROP2_COPY);          xwin_set_function(ROP2_COPY);
786    
787          XSetForeground(display, gc, colour);          XSetForeground(display, gc, Ctrans(colour));
788          XFillRectangle(display, wnd, gc, x, y, cx, cy);          XFillRectangle(display, wnd, gc, x, y, cx, cy);
789  }  }
790    
# Line 508  ui_draw_glyph(int mixmode, Line 798  ui_draw_glyph(int mixmode,
798    
799          xwin_set_function(ROP2_COPY);          xwin_set_function(ROP2_COPY);
800    
         XSetForeground(display, gc, fgcolour);  
801    
802            XSetForeground(display, gc, Ctrans(fgcolour));
803          switch (mixmode)          switch (mixmode)
804          {          {
805                  case MIX_TRANSPARENT:                  case MIX_TRANSPARENT:
# Line 521  ui_draw_glyph(int mixmode, Line 811  ui_draw_glyph(int mixmode,
811                          break;                          break;
812    
813                  case MIX_OPAQUE:                  case MIX_OPAQUE:
814                          XSetBackground(display, gc, bgcolour);                          XSetBackground(display, gc, Ctrans(bgcolour));
815                          XCopyPlane(display, pixmap, wnd, gc,  /*      XCopyPlane (display, pixmap, back_pixmap, back_gc, srcx, srcy, cx, cy, x, y, 1); */
816                                     srcx, srcy, cx, cy, x, y, 1);                          XSetStipple(display, gc, pixmap);
817                            XSetFillStyle(display, gc, FillOpaqueStippled);
818                            XSetTSOrigin(display, gc, x, y);
819                            XFillRectangle(display, wnd, gc, x, y, cx, cy);
820                            XSetFillStyle(display, gc, FillSolid);
821                          break;                          break;
822    
823                  default:                  default:
# Line 538  ui_draw_text(uint8 font, uint8 flags, in Line 832  ui_draw_text(uint8 font, uint8 flags, in
832               int bgcolour, int fgcolour, uint8 *text, uint8 length)               int bgcolour, int fgcolour, uint8 *text, uint8 length)
833  {  {
834          FONTGLYPH *glyph;          FONTGLYPH *glyph;
835          int i;          int i, xyoffset;
836    
837            xwin_set_function(ROP2_COPY);
838            XSetForeground(display, gc, Ctrans(bgcolour));
839    
840          if (boxcx > 1)          if (boxcx > 1)
841          {                  XFillRectangle(display, wnd, gc, boxx, boxy, boxcx, boxcy);
                 ui_rect(boxx, boxy, boxcx, boxcy, bgcolour);  
         }  
842          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
843          {                  XFillRectangle(display, wnd, gc, clipx, clipy, clipcx, clipcy);
                 ui_rect(clipx, clipy, clipcx, clipcy, bgcolour);  
         }  
844    
845          /* Paint text, character by character */          /* Paint text, character by character */
846          for (i = 0; i < length; i++)          for (i = 0; i < length; i++)
# Line 555  ui_draw_text(uint8 font, uint8 flags, in Line 848  ui_draw_text(uint8 font, uint8 flags, in
848                  glyph = cache_get_font(font, text[i]);                  glyph = cache_get_font(font, text[i]);
849    
850                  if (!(flags & TEXT2_IMPLICIT_X))                  if (!(flags & TEXT2_IMPLICIT_X))
                         x += text[++i];  
851    
852                    {
853                            xyoffset = text[++i];
854                            if ((xyoffset & 0x80))
855                            {
856                                    if (flags & 0x04)       /* vertical text */
857                                            y += text[++i] | (text[++i] << 8);
858                                    else
859                                            x += text[++i] | (text[++i] << 8);
860                            }
861                            else
862                            {
863                                    if (flags & 0x04)       /* vertical text */
864                                            y += xyoffset;
865                                    else
866                                            x += xyoffset;
867                            }
868    
869                    }
870                  if (glyph != NULL)                  if (glyph != NULL)
871                  {                  {
872                          ui_draw_glyph(mixmode, x + (short) glyph->offset,                          ui_draw_glyph(mixmode, x + (short) glyph->offset,
# Line 574  ui_draw_text(uint8 font, uint8 flags, in Line 884  ui_draw_text(uint8 font, uint8 flags, in
884  void  void
885  ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)  ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
886  {  {
887            Pixmap pix;
888          XImage *image;          XImage *image;
889    
890          image = XGetImage(display, wnd, x, y, cx, cy, 0xffffffff, ZPixmap);          pix = XCreatePixmap(display, wnd, cx, cy, depth);
891          cache_put_desktop(offset, cx, cy, image->bytes_per_line, image->data);          xwin_set_function(ROP2_COPY);
892          XFree(image->data);  
893          XFree(image);          XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
894            image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
895    
896            offset *= bpp/8;
897            cache_put_desktop(offset, cx, cy, image->bytes_per_line,
898                              bpp/8, image->data);
899    
900            XDestroyImage(image);
901            XFreePixmap(display, pix);
902  }  }
903    
904  void  void
# Line 588  ui_desktop_restore(uint32 offset, int x, Line 907  ui_desktop_restore(uint32 offset, int x,
907          XImage *image;          XImage *image;
908          uint8 *data;          uint8 *data;
909    
910          data = cache_get_desktop(offset, cx, cy);          offset *= bpp/8;
911            data = cache_get_desktop(offset, cx, cy, bpp/8);
912          if (data == NULL)          if (data == NULL)
913                  return;                  return;
914            image =
915          image = XCreateImage(display, visual, 8, ZPixmap, 0,                  XCreateImage(display, visual,
916                               data, cx, cy, 32, cx);                               depth, ZPixmap,
917          XSetFunction(display, gc, GXcopy);                               0, data, cx, cy, BitmapPad(display),
918                                 cx * bpp/8);
919            xwin_set_function(ROP2_COPY);
920          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
921          XFree(image);          XFree(image);
922  }  }
923    
924    /* unroll defines, used to make the loops a bit more readable... */
925    #define unroll8Expr(uexp) uexp uexp uexp uexp uexp uexp uexp uexp
926    #define unroll8Lefts(uexp) case 7: uexp \
927            case 6: uexp \
928            case 5: uexp \
929            case 4: uexp \
930            case 3: uexp \
931            case 2: uexp \
932            case 1: uexp
933    
934    static uint8 *
935    translate(int width, int height, uint8 *data)
936    {
937            uint32 i;
938            uint32 size = width * height;
939            uint8 *d2 = xmalloc(size * bpp/8);
940            uint8 *d3 = d2;
941            uint32 pix;
942            i = (size & ~0x7);
943    
944            /* XXX: where are the bits swapped??? */
945    #ifdef L_ENDIAN                 /* little-endian */
946            /* big-endian screen */
947            if (screen_msbfirst)
948            {
949                    switch (bpp)
950                    {
951                            case 32:
952                                    while (i)
953                                    {
954                                            unroll8Expr(pix = colmap[*data++];
955                                                        *d3++ = pix >> 24;
956                                                        *d3++ = pix >> 16;
957                                                        *d3++ = pix >> 8;
958                                                        *d3++ = pix;) i -= 8;
959                                    }
960                                    i = (size & 0x7);
961                                    if (i != 0)
962                                            switch (i)
963                                            {
964                                                            unroll8Lefts(pix =
965                                                                         colmap
966                                                                         [*data++];
967                                                                         *d3++ =
968                                                                         pix >>
969                                                                         24;
970                                                                         *d3++ =
971                                                                         pix >>
972                                                                         16;
973                                                                         *d3++ =
974                                                                         pix >> 8;
975                                                                         *d3++ =
976                                                                         pix;)}
977                                    break;
978                            case 24:
979                                    while (i)
980                                    {
981                                            unroll8Expr(pix = colmap[*data++];
982                                                        *d3++ = pix >> 16;
983                                                        *d3++ = pix >> 8;
984                                                        *d3++ = pix;) i -= 8;
985                                    }
986                                    i = (size & 0x7);
987                                    if (i != 0)
988                                            switch (i)
989                                            {
990                                                            unroll8Lefts(pix =
991                                                                         colmap
992                                                                         [*data++];
993                                                                         *d3++ =
994                                                                         pix >>
995                                                                         16;
996                                                                         *d3++ =
997                                                                         pix >> 8;
998                                                                         *d3++ =
999                                                                         pix;)}
1000                                    break;
1001                            case 16:
1002                                    while (i)
1003                                    {
1004                                            unroll8Expr(pix = colmap[*data++];
1005                                                        *d3++ = pix >> 8;
1006                                                        *d3++ = pix;) i -= 8;
1007                                    }
1008                                    i = (size & 0x7);
1009                                    if (i != 0)
1010                                            switch (i)
1011                                            {
1012                                                            unroll8Lefts(pix =
1013                                                                         colmap
1014                                                                         [*data++];
1015                                                                         *d3++ =
1016                                                                         pix >> 8;
1017                                                                         *d3++ =
1018                                                                         pix;)}
1019                                    break;
1020                            case 8:
1021                                    while (i)
1022                                    {
1023                                            unroll8Expr(pix = colmap[*data++];
1024                                                        *d3++ = pix;
1025                                                    )i -= 8;
1026                                    }
1027                                    i = (size & 0x7);
1028                                    if (i != 0)
1029                                            switch (i)
1030                                            {
1031                                                            unroll8Lefts(pix =
1032                                                                         colmap
1033                                                                         [*data++];
1034                                                                         *d3++ =
1035                                                                         pix;)}
1036                                    break;
1037                    }
1038            }
1039            else
1040            {                       /* little-endian screen */
1041                    switch (bpp)
1042                    {
1043                            case 32:
1044                                    while (i)
1045                                    {
1046                                            unroll8Expr(*((uint32 *) d3) =
1047                                                        colmap[*data++];
1048                                                        d3 += sizeof(uint32);
1049                                                    )i -= 8;
1050                                    }
1051                                    i = (size & 0x7);
1052                                    if (i != 0)
1053                                            switch (i)
1054                                            {
1055                                                            unroll8Lefts(*
1056                                                                         ((uint32
1057                                                                           *) d3)
1058    = colmap[*data++];
1059    d3 += sizeof(uint32);
1060                                            )}
1061                                    break;
1062                            case 24:
1063                                    while (i)
1064                                    {
1065                                            unroll8Expr(pix = colmap[*data++];
1066                                                        *d3++ = pix;
1067                                                        *d3++ = pix >> 8;
1068                                                        *d3++ = pix >> 16;
1069                                                    )i -= 8;
1070                                    }
1071                                    i = (size & 0x7);
1072                                    if (i != 0)
1073                                            switch (i)
1074                                            {
1075                                                            unroll8Lefts(pix =
1076                                                                         colmap
1077                                                                         [*data++];
1078                                                                         *d3++ =
1079                                                                         pix;
1080                                                                         *d3++ =
1081                                                                         pix >> 8;
1082                                                                         *d3++ =
1083                                                                         pix >>
1084                                                                         16;)}
1085                                    break;
1086                            case 16:
1087                                    while (i)
1088                                    {
1089                                            unroll8Expr(pix = colmap[*data++];
1090                                                        *d3++ = pix;
1091                                                        *d3++ = pix >> 8;
1092                                                    )i -= 8;
1093                                    }
1094                                    i = (size & 0x7);
1095                                    if (i != 0)
1096                                            switch (i)
1097                                            {
1098                                                            unroll8Lefts(pix =
1099                                                                         colmap
1100                                                                         [*data++];
1101                                                                         *d3++ =
1102                                                                         pix;
1103                                                                         *d3++ =
1104                                                                         pix >> 8;
1105                                            )}
1106                                    break;
1107                            case 8:
1108                                    while (i)
1109                                    {
1110                                            unroll8Expr(pix = colmap[*data++];
1111                                                        *d3++ = pix;
1112                                                    )i -= 8;
1113                                    }
1114                                    i = (size & 0x7);
1115                                    if (i != 0)
1116                                            switch (i)
1117                                            {
1118                                                            unroll8Lefts(pix =
1119                                                                         colmap
1120                                                                         [*data++];
1121                                                                         *d3++ =
1122                                                                         pix;)}
1123                    }
1124            }
1125    
1126    #else /* bigendian-compiled */
1127            if (screen_msbfirst)
1128            {
1129                    /* big-endian screen */
1130                    switch (bpp)
1131                    {
1132                            case 32:
1133                                    while (i)
1134                                    {
1135                                            unroll8Expr(*((uint32 *) d3) =
1136                                                        colmap[*data++];
1137                                                        d3 += sizeof(uint32);
1138                                                    )i -= 8;
1139                                    }
1140                                    i = (size & 0x7);
1141                                    if (i != 0)
1142                                            switch (i)
1143                                            {
1144                                                            unroll8Lefts(*
1145                                                                         ((uint32
1146                                                                           *) d3)
1147    = colmap[*data++];
1148    d3 += sizeof(uint32);
1149                                            )}
1150                                    break;
1151                            case 24:
1152                                    while (i)
1153                                    {
1154                                            unroll8Expr(pix = colmap[*data++];
1155                                                        *d3++ = pix;
1156                                                        *d3++ = pix >> 8;
1157                                                        *d3++ = pix >> 16;
1158                                                    )i -= 8;
1159                                    }
1160                                    i = (size & 0x7);
1161                                    if (i != 0)
1162                                            switch (i)
1163                                            {
1164                                                            unroll8Lefts(pix =
1165                                                                         colmap
1166                                                                         [*data++];
1167                                                                         *d3++ =
1168                                                                         pix;
1169                                                                         *d3++ =
1170                                                                         pix >> 8;
1171                                                                         *d3++ =
1172                                                                         pix >>
1173                                                                         16;)}
1174                                    break;
1175                            case 16:
1176                                    while (i)
1177                                    {
1178                                            unroll8Expr(pix = colmap[*data++];
1179                                                        *d3++ = pix;
1180                                                        *d3++ = pix >> 8;
1181                                                    )i -= 8;
1182                                    }
1183                                    i = (size & 0x7);
1184                                    if (i != 0)
1185                                            switch (i)
1186                                            {
1187                                                            unroll8Lefts(pix =
1188                                                                         colmap
1189                                                                         [*data++];
1190                                                                         *d3++ =
1191                                                                         pix;
1192                                                                         *d3++ =
1193                                                                         pix >> 8;
1194                                            )}
1195                                    break;
1196                            case 8:
1197                                    while (i)
1198                                    {
1199                                            unroll8Expr(pix = colmap[*data++];
1200                                                        *d3++ = pix;
1201                                                    )i -= 8;
1202                                    }
1203                                    i = (size & 0x7);
1204                                    if (i != 0)
1205                                            switch (i)
1206                                            {
1207                                                            unroll8Lefts(pix =
1208                                                                         colmap
1209                                                                         [*data++];
1210                                                                         *d3++ =
1211                                                                         pix;)}
1212                    }
1213            }
1214            else
1215            {
1216                    /* little-endian screen */
1217                    switch (bpp)
1218                    {
1219                            case 32:
1220                                    while (i)
1221                                    {
1222                                            unroll8Expr(pix = colmap[*data++];
1223                                                        *d3++ = pix;
1224                                                        *d3++ = pix >> 8;
1225                                                        *d3++ = pix >> 16;
1226                                                        *d3++ = pix >> 24;
1227                                                    )i -= 8;
1228                                    }
1229                                    i = (size & 0x7);
1230                                    if (i != 0)
1231                                            switch (i)
1232                                            {
1233                                                            unroll8Lefts(pix =
1234                                                                         colmap
1235                                                                         [*data++];
1236                                                                         *d3++ =
1237                                                                         pix;
1238                                                                         *d3++ =
1239                                                                         pix >> 8;
1240                                                                         *d3++ =
1241                                                                         pix >>
1242                                                                         16;
1243                                                                         *d3++ =
1244                                                                         pix >>
1245                                                                         24;)}
1246                                    break;
1247                            case 24:
1248                                    while (i)
1249                                    {
1250                                            unroll8Expr(pix = colmap[*data++];
1251                                                        *d3++ = pix;
1252                                                        *d3++ = pix >> 8;
1253                                                        *d3++ = pix >> 16;
1254                                                    )i -= 8;
1255                                    }
1256                                    i = (size & 0x7);
1257                                    if (i != 0)
1258                                            switch (i)
1259                                            {
1260                                                            unroll8Lefts(pix =
1261                                                                         colmap
1262                                                                         [*data++];
1263                                                                         *d3++ =
1264                                                                         pix;
1265                                                                         *d3++ =
1266                                                                         pix >> 8;
1267                                                                         *d3++ =
1268                                                                         pix >>
1269                                                                         16;)}
1270                                    break;
1271                            case 16:
1272                                    while (i)
1273                                    {
1274                                            unroll8Expr(pix = colmap[*data++];
1275                                                        *d3++ = pix;
1276                                                        *d3++ = pix >> 8;
1277                                                    )i -= 8;
1278                                    }
1279                                    i = (size & 0x7);
1280                                    if (i != 0)
1281                                            switch (i)
1282                                            {
1283                                                            unroll8Lefts(pix =
1284                                                                         colmap
1285                                                                         [*data++];
1286                                                                         *d3++ =
1287                                                                         pix;
1288                                                                         *d3++ =
1289                                                                         pix >> 8;
1290                                            )}
1291                                    break;
1292                            case 8:
1293                                    while (i)
1294                                    {
1295                                            unroll8Expr(pix = colmap[*data++];
1296                                                        *d3++ = pix;
1297                                                    )i -= 8;
1298                                    }
1299                                    i = (size & 0x7);
1300                                    if (i != 0)
1301                                            switch (i)
1302                                            {
1303                                                            unroll8Lefts(pix =
1304                                                                         colmap
1305                                                                         [*data++];
1306                                                                         *d3++ =
1307                                                                         pix;)}
1308                    }
1309            }
1310    #endif
1311    
1312            return d2;
1313    }

Legend:
Removed from v.25  
changed lines
  Added in v.28

  ViewVC Help
Powered by ViewVC 1.1.26