/[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 30 by matty, Fri Sep 14 13:51:38 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 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 sendmotion;
29    extern BOOL fullscreen;
30    
31  static Display *display;  static Display *display;
32  static Window wnd;  static Window wnd;
33  static GC gc;  static GC gc;
34  static Visual *visual;  static Visual *visual;
35  static XIM IM;  static int depth;
36    static int bpp;
37    static BOOL backpixmap;
38    
39    static BOOL owncolmap;
40    static Colormap xcolmap;
41    static uint32 white;
42    static uint32 *colmap;
43    
44    #define TRANSLATE(col)          ( owncolmap ? col : colmap[col] )
45    #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));
46    #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));
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    #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }
68    #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
69    
70    static void
71    translate8(uint8 *data, uint8 *out, uint8 *end)
72    {
73            while (out < end)
74                    *(out++) = (uint8)colmap[*(data++)];
75    }
76    
77    static void
78    translate16(uint8 *data, uint16 *out, uint16 *end)
79    {
80            while (out < end)
81                    *(out++) = (uint16)colmap[*(data++)];
82    }
83    
84    /* XXX endianness */
85    static void
86    translate24(uint8 *data, uint8 *out, uint8 *end)
87    {
88            uint32 value;
89    
90            while (out < end)
91            {
92                    value = colmap[*(data++)];
93                    *(out++) = value;
94                    *(out++) = value >> 8;
95                    *(out++) = value >> 16;
96            }
97    }
98    
99    static void
100    translate32(uint8 *data, uint32 *out, uint32 *end)
101    {
102            while (out < end)
103                    *(out++) = colmap[*(data++)];
104    }
105    
106    static uint8 *
107    translate(int width, int height, uint8 *data)
108    {
109            int size = width * height * bpp/8;
110            uint8 *out = xmalloc(size);
111            uint8 *end = out + size;
112    
113            switch (bpp)
114            {
115                    case 8:
116                            translate8(data, out, end);
117                            break;
118    
119                    case 16:
120                            translate16(data, (uint16 *)out, (uint16 *)end);
121                            break;
122    
123                    case 24:
124                            translate24(data, out, end);
125                            break;
126    
127                    case 32:
128                            translate32(data, (uint32 *)out, (uint32 *)end);
129                            break;
130            }
131    
132            return out;
133    }
134    
135    #define L_ENDIAN
136    int screen_msbfirst = 0;
137    
138    
139  BOOL  BOOL
140  ui_create_window(char *title)  ui_create_window(char *title)
141  {  {
         Screen *screen;  
142          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
143            XClassHint *classhints;
144            XSizeHints *sizehints;
145          unsigned long input_mask;          unsigned long input_mask;
146            XPixmapFormatValues *pfm;
147            Screen *screen;
148          int i;          int i;
149    
150    
151          display = XOpenDisplay(NULL);          display = XOpenDisplay(NULL);
152          if (display == NULL)          if (display == NULL)
153          {          {
154                  ERROR("Failed to open display\n");                  error("Failed to open display\n");
155                  return False;                  return False;
156          }          }
157    
         /* Check the screen supports 8-bit depth. */  
158          screen = DefaultScreenOfDisplay(display);          screen = DefaultScreenOfDisplay(display);
159          for (i = 0; i < screen->ndepths; i++)          visual = DefaultVisualOfScreen(screen);
160                  if (screen->depths[i].depth == 8)          depth = DefaultDepthOfScreen(screen);
                         break;  
161    
162          if (i >= screen->ndepths)          pfm = XListPixmapFormats(display, &i);
163            if (pfm != NULL)
164          {          {
165                  ERROR("8-bit depth required (in this version).\n");                  /* Use maximum bpp for this depth - this is generally
166                       desirable, e.g. 24 bits->32 bits. */
167                    while (i--)
168                    {
169                            if ((pfm[i].depth == depth)
170                                && (pfm[i].bits_per_pixel > bpp))
171                            {
172                                    bpp = pfm[i].bits_per_pixel;
173                            }
174                    }
175                    XFree(pfm);
176            }
177    
178            if (bpp < 8)
179            {
180                    error("Less than 8 bpp not currently supported.\n");
181                  XCloseDisplay(display);                  XCloseDisplay(display);
182                  return False;                  return False;
183          }          }
184    
185          visual = DefaultVisual(display, DefaultScreen(display));          if (depth <= 8)
186                    owncolmap = True;
187            else
188                    xcolmap = DefaultColormapOfScreen(screen);
189    
190            white = WhitePixelOfScreen(screen);
191            attribs.background_pixel = BlackPixelOfScreen(screen);
192            attribs.backing_store = DoesBackingStore(screen);
193    
194            if (attribs.backing_store == NotUseful)
195                    backpixmap = True;
196    
197            if (fullscreen)
198            {
199                    attribs.override_redirect = True;
200                    width = WidthOfScreen(screen);
201                    height = HeightOfScreen(screen);
202            }
203            else
204            {
205                    attribs.override_redirect = False;
206            }
207    
208            width = (width + 3) & ~3; /* make width a multiple of 32 bits */
209    
210          attribs.background_pixel =          wnd = XCreateWindow(display, RootWindowOfScreen(screen),
211                  BlackPixel(display, DefaultScreen(display));                              0, 0, width, height, 0, CopyFromParent,
212          attribs.backing_store = Always;                              InputOutput, CopyFromParent,
213          wnd = XCreateWindow(display, DefaultRootWindow(display),                              CWBackingStore | CWBackPixel | CWOverrideRedirect,
214                              0, 0, width, height, 0, 8, InputOutput, visual,                              &attribs);
                             CWBackingStore | CWBackPixel, &attribs);  
215    
216          XStoreName(display, wnd, title);          XStoreName(display, wnd, title);
         XMapWindow(display, wnd);  
217    
218          input_mask = KeyPressMask | KeyReleaseMask;          classhints = XAllocClassHint();
219          input_mask |= ButtonPressMask | ButtonReleaseMask;          if (classhints != NULL)
220          if (motion)          {
221                    classhints->res_name = classhints->res_class = "rdesktop";
222                    XSetClassHint(display, wnd, classhints);
223                    XFree(classhints);
224            }
225    
226            sizehints = XAllocSizeHints();
227            if (sizehints)
228            {
229                    sizehints->flags = PMinSize | PMaxSize;
230                    sizehints->min_width = sizehints->max_width = width;
231                    sizehints->min_height = sizehints->max_height = height;
232                    XSetWMNormalHints(display, wnd, sizehints);
233                    XFree(sizehints);
234            }
235    
236            input_mask = KeyPressMask | KeyReleaseMask
237                            | ButtonPressMask | ButtonReleaseMask
238                            | EnterWindowMask | LeaveWindowMask;
239    
240            if (sendmotion)
241                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
242    
243          XSelectInput(display, wnd, input_mask);          XSelectInput(display, wnd, input_mask);
244          gc = XCreateGC(display, wnd, 0, NULL);          gc = XCreateGC(display, wnd, 0, NULL);
245    
246          IM = XOpenIM(display, NULL, NULL, NULL);          XMapWindow(display, wnd);
247          return True;          return True;
248  }  }
249    
250  void  void
251  ui_destroy_window()  ui_destroy_window()
252  {  {
         XCloseIM(IM);  
253          XFreeGC(display, gc);          XFreeGC(display, gc);
254          XDestroyWindow(display, wnd);          XDestroyWindow(display, wnd);
255          XCloseDisplay(display);          XCloseDisplay(display);
256            display = NULL;
257  }  }
258    
259  static uint8  static uint8
260  xwin_translate_key(unsigned long key)  xwin_translate_key(unsigned long key)
261  {  {
262          DEBUG("KEY(code=0x%lx)\n", key);          DEBUG(("KEY(code=0x%lx)\n", key));
263    
264          if ((key > 8) && (key <= 0x60))          if ((key > 8) && (key <= 0x60))
265                  return (key - 8);                  return (key - 8);
266    
267          switch (key)          switch (key)
268          {          {
269                  case 0x62:      /* left arrow */                  case 0x61:      /* home */
270                          return 0x48;                          return 0x47 | 0x80;
271                  case 0x64:      /* up arrow */                  case 0x62:      /* up arrow */
272                          return 0x4b;                          return 0x48 | 0x80;
273                  case 0x66:      /* down arrow */                  case 0x63:      /* page up */
274                          return 0x4d;                          return 0x49 | 0x80;
275                  case 0x68:      /* right arrow */                  case 0x64:      /* left arrow */
276                          return 0x50;                          return 0x4b | 0x80;
277                  case 0x73:      /* Windows key */                  case 0x66:      /* right arrow */
278                          DEBUG("CHECKPOINT\n");                          return 0x4d | 0x80;
279                    case 0x67:      /* end */
280                            return 0x4f | 0x80;
281                    case 0x68:      /* down arrow */
282                            return 0x50 | 0x80;
283                    case 0x69:      /* page down */
284                            return 0x51 | 0x80;
285                    case 0x6a:      /* insert */
286                            return 0x52 | 0x80;
287                    case 0x6b:      /* delete */
288                            return 0x53 | 0x80;
289                    case 0x6c:      /* keypad enter */
290                            return 0x1c | 0x80;
291                    case 0x6d:      /* right ctrl */
292                            return 0x1d | 0x80;
293                    case 0x6f:      /* ctrl - print screen */
294                            return 0x37 | 0x80;
295                    case 0x70:      /* keypad '/' */
296                            return 0x35 | 0x80;
297                    case 0x71:      /* right alt */
298                            return 0x38 | 0x80;
299                    case 0x72:      /* ctrl break */
300                            return 0x46 | 0x80;
301                    case 0x73:      /* left window key */
302                            return 0xff;    /* real scancode is 5b */
303                    case 0x74:      /* right window key */
304                            return 0xff;    /* real scancode is 5c */
305                    case 0x75:      /* menu key */
306                            return 0x5d | 0x80;
307          }          }
308    
309          return 0;          return 0;
# Line 145  ui_process_events() Line 336  ui_process_events()
336          if (display == NULL)          if (display == NULL)
337                  return;                  return;
338    
339          while (XCheckWindowEvent(display, wnd, 0xffffffff, &event))          while (XCheckWindowEvent(display, wnd, ~0, &event))
340          {          {
341                  ev_time = time(NULL);                  ev_time = time(NULL);
342    
343                  switch (event.type)                  switch (event.type)
344                  {                  {
345                          case KeyPress:                          case KeyPress:
346                                  scancode =                                  scancode = xwin_translate_key(event.xkey.keycode);
                                         xwin_translate_key(event.  
                                                            xkey.keycode);  
347                                  if (scancode == 0)                                  if (scancode == 0)
348                                          break;                                          break;
349    
# Line 163  ui_process_events() Line 352  ui_process_events()
352                                  break;                                  break;
353    
354                          case KeyRelease:                          case KeyRelease:
355                                  scancode =                                  scancode = xwin_translate_key(event.xkey.keycode);
                                         xwin_translate_key(event.  
                                                            xkey.keycode);  
356                                  if (scancode == 0)                                  if (scancode == 0)
357                                          break;                                          break;
358    
# Line 175  ui_process_events() Line 362  ui_process_events()
362                                  break;                                  break;
363    
364                          case ButtonPress:                          case ButtonPress:
365                                  button =                                  button = xwin_translate_mouse(event.xbutton.button);
                                         xwin_translate_mouse(event.  
                                                              xbutton.button);  
   
366                                  if (button == 0)                                  if (button == 0)
367                                          break;                                          break;
368    
# Line 189  ui_process_events() Line 373  ui_process_events()
373                                  break;                                  break;
374    
375                          case ButtonRelease:                          case ButtonRelease:
376                                  button =                                  button = xwin_translate_mouse(event.xbutton.button);
                                         xwin_translate_mouse(event.  
                                                              xbutton.button);  
377                                  if (button == 0)                                  if (button == 0)
378                                          break;                                          break;
379    
# Line 206  ui_process_events() Line 388  ui_process_events()
388                                                 MOUSE_FLAG_MOVE,                                                 MOUSE_FLAG_MOVE,
389                                                 event.xmotion.x,                                                 event.xmotion.x,
390                                                 event.xmotion.y);                                                 event.xmotion.y);
391                                    break;
392    
393                            case EnterNotify:
394                                    XGrabKeyboard(display, wnd, True, GrabModeAsync,
395                                                  GrabModeAsync, CurrentTime);
396                                    break;
397    
398                            case LeaveNotify:
399                                    XUngrabKeyboard(display, CurrentTime);
400                                    break;
401                  }                  }
402          }          }
403  }  }
# Line 221  ui_create_bitmap(int width, int height, Line 413  ui_create_bitmap(int width, int height,
413  {  {
414          XImage *image;          XImage *image;
415          Pixmap bitmap;          Pixmap bitmap;
416            uint8 *tdata;
417    
418          bitmap = XCreatePixmap(display, wnd, width, height, 8);          tdata = (owncolmap ? data : translate(width, height, data));
419            bitmap = XCreatePixmap(display, wnd, width, height, depth);
420            image = XCreateImage(display, visual, depth, ZPixmap,
421                                 0, tdata, width, height, 8, 0);
422    
         image = XCreateImage(display, visual, 8, ZPixmap, 0,  
                              data, width, height, 8, width);  
         XSetFunction(display, gc, GXcopy);  
423          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
         XFree(image);  
424    
425            XFree(image);
426            if (!owncolmap)
427                    xfree(tdata);
428          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
429  }  }
430    
# Line 238  ui_paint_bitmap(int x, int y, int cx, in Line 433  ui_paint_bitmap(int x, int y, int cx, in
433                  int width, int height, uint8 *data)                  int width, int height, uint8 *data)
434  {  {
435          XImage *image;          XImage *image;
436            uint8 *tdata;
437    
438            tdata = (owncolmap ? data : translate(width, height, data));
439            image = XCreateImage(display, visual, depth, ZPixmap,
440                                 0, tdata, width, height, 8, 0);
441    
         image = XCreateImage(display, visual, 8, ZPixmap, 0,  
                              data, width, height, 8, width);  
         XSetFunction(display, gc, GXcopy);  
442          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
443    
444          XFree(image);          XFree(image);
445            if (!owncolmap)
446                    xfree(tdata);
447  }  }
448    
449  void  void
450  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(HBITMAP bmp)
451  {  {
452          XFreePixmap(display, (Pixmap) bmp);          XFreePixmap(display, (Pixmap)bmp);
453  }  }
454    
455  HGLYPH  HGLYPH
# Line 271  ui_create_glyph(int width, int height, u Line 471  ui_create_glyph(int width, int height, u
471          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
472          XInitImage(image);          XInitImage(image);
473    
         XSetFunction(display, gc, GXcopy);  
474          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
475    
476          XFree(image);          XFree(image);
477          XFreeGC(display, gc);          XFreeGC(display, gc);
478            return (HGLYPH)bitmap;
         return (HGLYPH) bitmap;  
479  }  }
480    
481  void  void
482  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
483  {  {
484          XFreePixmap(display, (Pixmap) glyph);          XFreePixmap(display, (Pixmap)glyph);
485  }  }
486    
487    HCURSOR
488    ui_create_cursor(unsigned int x, unsigned int y, int width,
489                     int height, uint8 *andmask, uint8 *xormask)
490    {
491            HGLYPH maskglyph, cursorglyph;
492            XColor bg, fg;
493            Cursor xcursor;
494            uint8 *cursor, *pcursor;
495            uint8 *mask, *pmask;
496            uint8 nextbit;
497            int scanline, offset;
498            int i, j;
499    
500            scanline = (width + 7) / 8;
501            offset = scanline * height;
502    
503            cursor = xmalloc(offset);
504            memset(cursor, 0, offset);
505    
506            mask = xmalloc(offset);
507            memset(mask, 0, offset);
508    
509            /* approximate AND and XOR masks with a monochrome X pointer */
510            for (i = 0; i < height; i++)
511            {
512                    offset -= scanline;
513                    pcursor = &cursor[offset];
514                    pmask = &mask[offset];
515    
516                    for (j = 0; j < scanline; j++)
517                    {
518                            for (nextbit = 0x80; nextbit != 0; nextbit >>= 1)
519                            {
520                                    if (xormask[0] || xormask[1] || xormask[2])
521                                    {
522                                            *pcursor |= (~(*andmask) & nextbit);
523                                            *pmask |= nextbit;
524                                    }
525                                    else
526                                    {
527                                            *pcursor |= ((*andmask) & nextbit);
528                                            *pmask |= (~(*andmask) & nextbit);
529                                    }
530    
531                                    xormask += 3;
532                            }
533    
534                            andmask++;
535                            pcursor++;
536                            pmask++;
537                    }
538            }
539    
540            fg.red = fg.blue = fg.green = 0xffff;
541            bg.red = bg.blue = bg.green = 0x0000;
542            fg.flags = bg.flags = DoRed | DoBlue | DoGreen;
543    
544            cursorglyph = ui_create_glyph(width, height, cursor);
545            maskglyph = ui_create_glyph(width, height, mask);
546            
547            xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,
548                                    (Pixmap)maskglyph, &fg, &bg, x, y);
549    
550            ui_destroy_glyph(maskglyph);
551            ui_destroy_glyph(cursorglyph);
552            xfree(mask);
553            xfree(cursor);
554            return (HCURSOR)xcursor;
555    }
556    
557    void
558    ui_set_cursor(HCURSOR cursor)
559    {
560            XDefineCursor(display, wnd, (Cursor)cursor);
561    }
562    
563    void
564    ui_destroy_cursor(HCURSOR cursor)
565    {
566            XFreeCursor(display, (Cursor)cursor);
567    }
568    
569    #define MAKE_XCOLOR(xc,c) \
570                    (xc)->red   = ((c)->red   << 8) | (c)->red; \
571                    (xc)->green = ((c)->green << 8) | (c)->green; \
572                    (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
573                    (xc)->flags = DoRed | DoGreen | DoBlue;
574    
575  HCOLOURMAP  HCOLOURMAP
576  ui_create_colourmap(COLOURMAP *colours)  ui_create_colourmap(COLOURMAP *colours)
577  {  {
578          COLOURENTRY *entry;          COLOURENTRY *entry;
         XColor *xcolours, *xentry;  
         Colormap map;  
579          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
580    
581          xcolours = xmalloc(sizeof(XColor) * ncolours);          if (owncolmap)
         for (i = 0; i < ncolours; i++)  
582          {          {
583                  entry = &colours->colours[i];                  XColor *xcolours, *xentry;
584                  xentry = &xcolours[i];                  Colormap map;
585    
586                    xcolours = xmalloc(sizeof(XColor) * ncolours);
587                    for (i = 0; i < ncolours; i++)
588                    {
589                            entry = &colours->colours[i];
590                            xentry = &xcolours[i];
591                            xentry->pixel = i;
592                            MAKE_XCOLOR(xentry, entry);
593                    }
594    
595                    map = XCreateColormap(display, wnd, visual, AllocAll);
596                    XStoreColors(display, map, xcolours, ncolours);
597    
598                  xentry->pixel = i;                  xfree(xcolours);
599                  xentry->red = entry->red << 8;                  return (HCOLOURMAP)map;
                 xentry->blue = entry->blue << 8;  
                 xentry->green = entry->green << 8;  
                 xentry->flags = DoRed | DoBlue | DoGreen;  
600          }          }
601            else
602            {
603                    uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
604                    XColor xentry;
605    
606          map = XCreateColormap(display, wnd, visual, AllocAll);                  for (i = 0; i < ncolours; i++)
607          XStoreColors(display, map, xcolours, ncolours);                  {
608                            entry = &colours->colours[i];
609                            MAKE_XCOLOR(&xentry, entry);
610    
611                            if (XAllocColor(display, xcolmap, &xentry) != 0)
612                                    map[i] = xentry.pixel;
613                            else
614                                    map[i] = white;
615                    }
616    
617          xfree(xcolours);                  return map;
618          return (HCOLOURMAP) map;          }
619  }  }
620    
621  void  void
622  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
623  {  {
624          XFreeColormap(display, (Colormap) map);          if (owncolmap)
625                    XFreeColormap(display, (Colormap)map);
626            else
627                    xfree(map);
628  }  }
629    
630  void  void
631  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
632  {  {
633          XSetWindowColormap(display, wnd, (Colormap) map);          if (owncolmap)
634                    XSetWindowColormap(display, wnd, (Colormap)map);
635            else
636                    colmap = map;
637  }  }
638    
639  void  void
# Line 355  ui_bell() Line 666  ui_bell()
666          XBell(display, 0);          XBell(display, 0);
667  }  }
668    
 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]);  
 }  
   
669  void  void
670  ui_destblt(uint8 opcode,  ui_destblt(uint8 opcode,
671             /* dest */ int x, int y, int cx, int cy)             /* dest */ int x, int y, int cx, int cy)
672  {  {
673          xwin_set_function(opcode);          SET_FUNCTION(opcode);
   
674          XFillRectangle(display, wnd, gc, x, y, cx, cy);          XFillRectangle(display, wnd, gc, x, y, cx, cy);
675            RESET_FUNCTION(opcode);
676  }  }
677    
678  void  void
# Line 394  ui_patblt(uint8 opcode, Line 680  ui_patblt(uint8 opcode,
680            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
681            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
682  {  {
         Display *dpy = display;  
683          Pixmap fill;          Pixmap fill;
684    
685          xwin_set_function(opcode);          SET_FUNCTION(opcode);
686    
687          switch (brush->style)          switch (brush->style)
688          {          {
689                  case 0: /* Solid */                  case 0: /* Solid */
690                          XSetForeground(dpy, gc, fgcolour);                          SET_FOREGROUND(fgcolour);
691                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);                          XFillRectangle(display, wnd, gc, x, y, cx, cy);
692                          break;                          break;
693    
694                  case 3: /* Pattern */                  case 3: /* Pattern */
695                          fill = (Pixmap) ui_create_glyph(8, 8, brush->pattern);                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);
696    
697                          XSetForeground(dpy, gc, fgcolour);                          SET_FOREGROUND(bgcolour);
698                          XSetBackground(dpy, gc, bgcolour);                          SET_BACKGROUND(fgcolour);
699                          XSetFillStyle(dpy, gc, FillOpaqueStippled);                          XSetFillStyle(display, gc, FillOpaqueStippled);
700                          XSetStipple(dpy, gc, fill);                          XSetStipple(display, gc, fill);
701                            XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
702    
703                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);                          XFillRectangle(display, wnd, gc, x, y, cx, cy);
704    
705                          XSetFillStyle(dpy, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
706                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH)fill);
707                          break;                          break;
708    
709                  default:                  default:
710                          NOTIMP("brush %d\n", brush->style);                          unimpl("brush %d\n", brush->style);
711          }          }
712    
713            RESET_FUNCTION(opcode);
714  }  }
715    
716  void  void
# Line 430  ui_screenblt(uint8 opcode, Line 718  ui_screenblt(uint8 opcode,
718               /* dest */ int x, int y, int cx, int cy,               /* dest */ int x, int y, int cx, int cy,
719               /* src */ int srcx, int srcy)               /* src */ int srcx, int srcy)
720  {  {
721          xwin_set_function(opcode);          SET_FUNCTION(opcode);
   
722          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
723            RESET_FUNCTION(opcode);
724  }  }
725    
726  void  void
# Line 440  ui_memblt(uint8 opcode, Line 728  ui_memblt(uint8 opcode,
728            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
729            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
730  {  {
731          xwin_set_function(opcode);          SET_FUNCTION(opcode);
732            XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);
733          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);          RESET_FUNCTION(opcode);
734  }  }
735    
736  void  void
# Line 470  ui_triblt(uint8 opcode, Line 758  ui_triblt(uint8 opcode,
758                                    brush, bgcolour, fgcolour);                                    brush, bgcolour, fgcolour);
759                          break;                          break;
760    
761                    case 0xc0:      /* PSa */
762                            ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
763                            ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,
764                                      fgcolour);
765                            break;
766    
767                  default:                  default:
768                          NOTIMP("triblt 0x%x\n", opcode);                          unimpl("triblt 0x%x\n", opcode);
769                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
770          }          }
771  }  }
# Line 481  ui_line(uint8 opcode, Line 775  ui_line(uint8 opcode,
775          /* dest */ int startx, int starty, int endx, int endy,          /* dest */ int startx, int starty, int endx, int endy,
776          /* pen */ PEN *pen)          /* pen */ PEN *pen)
777  {  {
778          xwin_set_function(opcode);          SET_FUNCTION(opcode);
779            SET_FOREGROUND(pen->colour);
         XSetForeground(display, gc, pen->colour);  
780          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(display, wnd, gc, startx, starty, endx, endy);
781            RESET_FUNCTION(opcode);
782  }  }
783    
784  void  void
# Line 492  ui_rect( Line 786  ui_rect(
786                 /* dest */ int x, int y, int cx, int cy,                 /* dest */ int x, int y, int cx, int cy,
787                 /* brush */ int colour)                 /* brush */ int colour)
788  {  {
789          xwin_set_function(ROP2_COPY);          SET_FOREGROUND(colour);
   
         XSetForeground(display, gc, colour);  
790          XFillRectangle(display, wnd, gc, x, y, cx, cy);          XFillRectangle(display, wnd, gc, x, y, cx, cy);
791  }  }
792    
# Line 504  ui_draw_glyph(int mixmode, Line 796  ui_draw_glyph(int mixmode,
796                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,
797                int fgcolour)                int fgcolour)
798  {  {
799          Pixmap pixmap = (Pixmap) glyph;          SET_FOREGROUND(fgcolour);
800            SET_BACKGROUND(bgcolour);
         xwin_set_function(ROP2_COPY);  
801    
802          XSetForeground(display, gc, fgcolour);          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)
803                          ? FillStippled : FillOpaqueStippled);
804            XSetStipple(display, gc, (Pixmap)glyph);
805            XSetTSOrigin(display, gc, x, y);
806    
807          switch (mixmode)          XFillRectangle(display, wnd, gc, x, y, cx, cy);
         {  
                 case MIX_TRANSPARENT:  
                         XSetStipple(display, gc, pixmap);  
                         XSetFillStyle(display, gc, FillStippled);  
                         XSetTSOrigin(display, gc, x, y);  
                         XFillRectangle(display, wnd, gc, x, y, cx, cy);  
                         XSetFillStyle(display, gc, FillSolid);  
                         break;  
   
                 case MIX_OPAQUE:  
                         XSetBackground(display, gc, bgcolour);  
                         XCopyPlane(display, pixmap, wnd, gc,  
                                    srcx, srcy, cx, cy, x, y, 1);  
                         break;  
808    
809                  default:          XSetFillStyle(display, gc, FillSolid);
                         NOTIMP("mix %d\n", mixmode);  
         }  
810  }  }
811    
812  void  void
# Line 538  ui_draw_text(uint8 font, uint8 flags, in Line 816  ui_draw_text(uint8 font, uint8 flags, in
816               int bgcolour, int fgcolour, uint8 *text, uint8 length)               int bgcolour, int fgcolour, uint8 *text, uint8 length)
817  {  {
818          FONTGLYPH *glyph;          FONTGLYPH *glyph;
819          int i;          int i, offset;
820    
821            SET_FOREGROUND(bgcolour);
822    
823          if (boxcx > 1)          if (boxcx > 1)
824          {                  XFillRectangle(display, wnd, gc, boxx, boxy, boxcx, boxcy);
                 ui_rect(boxx, boxy, boxcx, boxcy, bgcolour);  
         }  
825          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
826          {                  XFillRectangle(display, wnd, gc, clipx, clipy, clipcx, clipcy);
                 ui_rect(clipx, clipy, clipcx, clipcy, bgcolour);  
         }  
827    
828          /* Paint text, character by character */          /* Paint text, character by character */
829          for (i = 0; i < length; i++)          for (i = 0; i < length; i++)
# Line 555  ui_draw_text(uint8 font, uint8 flags, in Line 831  ui_draw_text(uint8 font, uint8 flags, in
831                  glyph = cache_get_font(font, text[i]);                  glyph = cache_get_font(font, text[i]);
832    
833                  if (!(flags & TEXT2_IMPLICIT_X))                  if (!(flags & TEXT2_IMPLICIT_X))
834                          x += text[++i];                  {
835                            offset = text[++i];
836                            if (offset & 0x80)
837                                    offset = ((offset & 0x7f) << 8) | text[++i];
838    
839                            if (flags & TEXT2_VERTICAL)
840                                    y += offset;
841                            else
842                                    x += offset;
843                    }
844    
845                  if (glyph != NULL)                  if (glyph != NULL)
846                  {                  {
# Line 574  ui_draw_text(uint8 font, uint8 flags, in Line 859  ui_draw_text(uint8 font, uint8 flags, in
859  void  void
860  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)
861  {  {
862            Pixmap pix;
863          XImage *image;          XImage *image;
864    
865          image = XGetImage(display, wnd, x, y, cx, cy, 0xffffffff, ZPixmap);          pix = XCreatePixmap(display, wnd, cx, cy, depth);
866          cache_put_desktop(offset, cx, cy, image->bytes_per_line, image->data);          XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
867          XFree(image->data);  
868          XFree(image);          image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
869    
870            offset *= bpp/8;
871            cache_put_desktop(offset, cx, cy, image->bytes_per_line,
872                              bpp/8, image->data);
873    
874            XDestroyImage(image);
875            XFreePixmap(display, pix);
876  }  }
877    
878  void  void
# Line 588  ui_desktop_restore(uint32 offset, int x, Line 881  ui_desktop_restore(uint32 offset, int x,
881          XImage *image;          XImage *image;
882          uint8 *data;          uint8 *data;
883    
884          data = cache_get_desktop(offset, cx, cy);          offset *= bpp/8;
885            data = cache_get_desktop(offset, cx, cy, bpp/8);
886          if (data == NULL)          if (data == NULL)
887                  return;                  return;
888    
889          image = XCreateImage(display, visual, 8, ZPixmap, 0,          image = XCreateImage(display, visual, depth, ZPixmap,
890                               data, cx, cy, 32, cx);                               0, data, cx, cy, BitmapPad(display),
891          XSetFunction(display, gc, GXcopy);                               cx * bpp/8);
892    
893          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
894          XFree(image);          XFree(image);
895  }  }
896    

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

  ViewVC Help
Powered by ViewVC 1.1.26