/[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 23 by matty, Tue Oct 17 08:24:09 2000 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  BOOL ui_create_window(char *title)  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
140    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);
161                          break;  
162            pfm = XListPixmapFormats(display, &i);
163            if (pfm != NULL)
164            {
165                    /* 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 (i >= screen->ndepths)          if (bpp < 8)
179          {          {
180                  ERROR("8-bit depth required (in this version).\n");                  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          attribs.background_pixel = BlackPixel(display, DefaultScreen(display));          if (attribs.backing_store == NotUseful)
195          attribs.backing_store = Always;                  backpixmap = True;
196          wnd = XCreateWindow(display, DefaultRootWindow(display),  
197                          0, 0, width, height, 0, 8, InputOutput, visual,          if (fullscreen)
198                          CWBackingStore | CWBackPixel, &attribs);          {
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            wnd = XCreateWindow(display, RootWindowOfScreen(screen),
211                                0, 0, width, height, 0, CopyFromParent,
212                                InputOutput, CopyFromParent,
213                                CWBackingStore | CWBackPixel | CWOverrideRedirect,
214                                &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 ui_destroy_window()  void
251    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 xwin_translate_key(unsigned long key)  static uint8
260    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;
310  }  }
311    
312  static uint16 xwin_translate_mouse(unsigned long button)  static uint16
313    xwin_translate_mouse(unsigned long button)
314  {  {
315          switch (button)          switch (button)
316          {          {
317                  case Button1: /* left */                  case Button1:   /* left */
318                          return MOUSE_FLAG_BUTTON1;                          return MOUSE_FLAG_BUTTON1;
319                  case Button2: /* middle */                  case Button2:   /* middle */
320                          return MOUSE_FLAG_BUTTON3;                          return MOUSE_FLAG_BUTTON3;
321                  case Button3: /* right */                  case Button3:   /* right */
322                          return MOUSE_FLAG_BUTTON2;                          return MOUSE_FLAG_BUTTON2;
323          }          }
324    
325          return 0;          return 0;
326  }  }
327    
328  void ui_process_events()  void
329    ui_process_events()
330  {  {
331          XEvent event;          XEvent event;
332          uint8 scancode;          uint8 scancode;
# Line 139  void ui_process_events() Line 336  void 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    
# Line 151  void ui_process_events() Line 348  void ui_process_events()
348                                          break;                                          break;
349    
350                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,
351                                                  scancode, 0);                                                 scancode, 0);
352                                  break;                                  break;
353    
354                          case KeyRelease:                          case KeyRelease:
# Line 160  void ui_process_events() Line 357  void ui_process_events()
357                                          break;                                          break;
358    
359                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE,                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
360                                                  KBD_FLAG_DOWN | KBD_FLAG_UP,                                                 KBD_FLAG_DOWN | KBD_FLAG_UP,
361                                                  scancode, 0);                                                 scancode, 0);
362                                  break;                                  break;
363    
364                          case ButtonPress:                          case ButtonPress:
365                                  button = xwin_translate_mouse(event.xbutton.button);                                  button = xwin_translate_mouse(event.xbutton.button);
   
366                                  if (button == 0)                                  if (button == 0)
367                                          break;                                          break;
368    
369                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
370                                                  button | MOUSE_FLAG_DOWN,                                                 button | MOUSE_FLAG_DOWN,
371                                                  event.xbutton.x,                                                 event.xbutton.x,
372                                                  event.xbutton.y);                                                 event.xbutton.y);
373                                  break;                                  break;
374    
375                          case ButtonRelease:                          case ButtonRelease:
# Line 182  void ui_process_events() Line 378  void ui_process_events()
378                                          break;                                          break;
379    
380                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
381                                                  button,                                                 button,
382                                                  event.xbutton.x,                                                 event.xbutton.x,
383                                                  event.xbutton.y);                                                 event.xbutton.y);
384                                  break;                                  break;
385    
386                          case MotionNotify:                          case MotionNotify:
387                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
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  }  }
404    
405  void ui_move_pointer(int x, int y)  void
406    ui_move_pointer(int x, int y)
407  {  {
408          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
409  }  }
410    
411  HBITMAP ui_create_bitmap(int width, int height, uint8 *data)  HBITMAP
412    ui_create_bitmap(int width, int height, uint8 *data)
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);
424    
425          XFree(image);          XFree(image);
426                    if (!owncolmap)
427          return (HBITMAP)bitmap;                  xfree(tdata);
428            return (HBITMAP) bitmap;
429  }  }
430    
431  void ui_paint_bitmap(int x, int y, int cx, int cy,  void
432                          int width, int height, uint8 *data)  ui_paint_bitmap(int x, int y, int cx, int cy,
433                    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          XFree(image);  
444            XFree(image);
445            if (!owncolmap)
446                    xfree(tdata);
447  }  }
448    
449  void ui_destroy_bitmap(HBITMAP bmp)  void
450    ui_destroy_bitmap(HBITMAP bmp)
451  {  {
452          XFreePixmap(display, (Pixmap)bmp);          XFreePixmap(display, (Pixmap)bmp);
453  }  }
454    
455  HGLYPH ui_create_glyph(int width, int height, uint8 *data)  HGLYPH
456    ui_create_glyph(int width, int height, uint8 *data)
457  {  {
458          XImage *image;          XImage *image;
459          Pixmap bitmap;          Pixmap bitmap;
# Line 247  HGLYPH ui_create_glyph(int width, int he Line 466  HGLYPH ui_create_glyph(int width, int he
466          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(display, bitmap, 0, NULL);
467    
468          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(display, visual, 1, ZPixmap, 0,
469                                  data, width, height, 8, scanline);                               data, width, height, 8, scanline);
470          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
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 ui_destroy_glyph(HGLYPH glyph)  void
482    ui_destroy_glyph(HGLYPH glyph)
483  {  {
484          XFreePixmap(display, (Pixmap)glyph);          XFreePixmap(display, (Pixmap)glyph);
485  }  }
486    
487  HCOLOURMAP ui_create_colourmap(COLOURMAP *colours)  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
576    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                  xentry->pixel = i;                  xcolours = xmalloc(sizeof(XColor) * ncolours);
587                  xentry->red = entry->red << 8;                  for (i = 0; i < ncolours; i++)
588                  xentry->blue = entry->blue << 8;                  {
589                  xentry->green = entry->green << 8;                          entry = &colours->colours[i];
590                  xentry->flags = DoRed | DoBlue | DoGreen;                          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                    xfree(xcolours);
599                    return (HCOLOURMAP)map;
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 ui_destroy_colourmap(HCOLOURMAP map)  void
622    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 ui_set_colourmap(HCOLOURMAP map)  void
631    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 ui_set_clip(int x, int y, int cx, int cy)  void
640    ui_set_clip(int x, int y, int cx, int cy)
641  {  {
642          XRectangle rect;          XRectangle rect;
643    
# Line 313  void ui_set_clip(int x, int y, int cx, i Line 648  void ui_set_clip(int x, int y, int cx, i
648          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
649  }  }
650    
651  void ui_reset_clip()  void
652    ui_reset_clip()
653  {  {
654          XRectangle rect;          XRectangle rect;
655    
# Line 324  void ui_reset_clip() Line 660  void ui_reset_clip()
660          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
661  }  }
662    
663  void ui_bell()  void
664    ui_bell()
665  {  {
666          XBell(display, 0);          XBell(display, 0);
667  }  }
668    
669  static int rop2_map[] = {  void
670          GXclear,        /* 0 */  ui_destblt(uint8 opcode,
671          GXnor,          /* DPon */             /* dest */ int x, int y, int cx, int cy)
         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)  
672  {  {
673          XSetFunction(display, gc, rop2_map[rop2]);          SET_FUNCTION(opcode);
 }  
   
 void ui_destblt(uint8 opcode,  
         /* dest */  int x, int y, int cx, int cy)  
 {  
         xwin_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 ui_patblt(uint8 opcode,  void
679          /* dest */  int x, int y, int cx, int cy,  ui_patblt(uint8 opcode,
680          /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* dest */ int x, int y, int cx, int cy,
681              /* 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 ui_screenblt(uint8 opcode,  void
717                  /* dest */ int x, int y, int cx, int cy,  ui_screenblt(uint8 opcode,
718                  /* src */  int srcx, int srcy)               /* dest */ int x, int y, int cx, int cy,
719                 /* 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);
723          XCopyArea(display, wnd, wnd, gc, srcx, srcy,          RESET_FUNCTION(opcode);
                         cx, cy, x, y);  
724  }  }
725    
726  void ui_memblt(uint8 opcode,  void
727          /* dest */  int x, int y, int cx, int cy,  ui_memblt(uint8 opcode,
728          /* src */   HBITMAP src, int srcx, int srcy)            /* dest */ int x, int y, int cx, int cy,
729              /* 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,          RESET_FUNCTION(opcode);
                         cx, cy, x, y);  
734  }  }
735    
736  void ui_triblt(uint8 opcode,  void
737          /* dest */  int x, int y, int cx, int cy,  ui_triblt(uint8 opcode,
738          /* src */   HBITMAP src, int srcx, int srcy,            /* dest */ int x, int y, int cx, int cy,
739          /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* src */ HBITMAP src, int srcx, int srcy,
740              /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
741  {  {
742          /* This is potentially difficult to do in general. Until someone          /* This is potentially difficult to do in general. Until someone
743             comes up with a more efficient way of doing it I am using cases. */             comes up with a more efficient way of doing it I am using cases. */
744    
745          switch (opcode)          switch (opcode)
746          {          {
747                  case 0x69: /* PDSxxn */                  case 0x69:      /* PDSxxn */
748                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
749                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy,
750                                          brush, bgcolour, fgcolour);                                    brush, bgcolour, fgcolour);
751                          break;                          break;
752    
753                  case 0xb8: /* PSDPxax */                  case 0xb8:      /* PSDPxax */
754                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy,
755                                          brush, bgcolour, fgcolour);                                    brush, bgcolour, fgcolour);
756                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
757                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy,
758                                          brush, bgcolour, fgcolour);                                    brush, bgcolour, fgcolour);
759                            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;                          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  }  }
772    
773  void ui_line(uint8 opcode,  void
774          /* dest */  int startx, int starty, int endx, int endy,  ui_line(uint8 opcode,
775          /* pen */   PEN *pen)          /* dest */ int startx, int starty, int endx, int endy,
776            /* 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 ui_rect(  void
785          /* dest */  int x, int y, int cx, int cy,  ui_rect(
786          /* brush */ int colour)                 /* dest */ int x, int y, int cx, int cy,
787                   /* 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    
793  void ui_draw_glyph(int mixmode,  void
794          /* dest */ int x, int y, int cx, int cy,  ui_draw_glyph(int mixmode,
795          /* src */  HGLYPH glyph, int srcx, int srcy, int bgcolour, int fgcolour)                /* dest */ int x, int y, int cx, int cy,
796  {                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,
797          Pixmap pixmap = (Pixmap)glyph;                int fgcolour)
798    {
799          xwin_set_function(ROP2_COPY);          SET_FOREGROUND(fgcolour);
800            SET_BACKGROUND(bgcolour);
801          XSetForeground(display, gc, fgcolour);  
802            XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)
803          switch (mixmode)                        ? FillStippled : FillOpaqueStippled);
804          {          XSetStipple(display, gc, (Pixmap)glyph);
805                  case MIX_TRANSPARENT:          XSetTSOrigin(display, gc, x, y);
                         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;  
806    
807                  case MIX_OPAQUE:          XFillRectangle(display, wnd, gc, x, y, cx, cy);
                         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 ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,  void
813                          int clipx, int clipy, int clipcx, int clipcy,  ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
814                          int boxx, int boxy, int boxcx, int boxcy,               int clipx, int clipy, int clipcx, int clipcy,
815                          int bgcolour, int fgcolour, uint8 *text, uint8 length)               int boxx, int boxy, int boxcx, int boxcy,
816                 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 521  void ui_draw_text(uint8 font, uint8 flag Line 831  void ui_draw_text(uint8 font, uint8 flag
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                  {                  {
847                          ui_draw_glyph(mixmode, x + (short)glyph->offset,                          ui_draw_glyph(mixmode, x + (short) glyph->offset,
848                                          y + (short)glyph->baseline,                                        y + (short) glyph->baseline,
849                                          glyph->width, glyph->height,                                        glyph->width, glyph->height,
850                                          glyph->pixmap, 0, 0,                                        glyph->pixmap, 0, 0,
851                                          bgcolour, fgcolour);                                        bgcolour, fgcolour);
852    
853                          if (flags & TEXT2_IMPLICIT_X)                          if (flags & TEXT2_IMPLICIT_X)
854                                  x += glyph->width;                                  x += glyph->width;
# Line 537  void ui_draw_text(uint8 font, uint8 flag Line 856  void ui_draw_text(uint8 font, uint8 flag
856          }          }
857  }  }
858    
859  void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)  void
860    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 ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)  void
879    ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
880  {  {
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.23  
changed lines
  Added in v.30

  ViewVC Help
Powered by ViewVC 1.1.26