/[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 17 by matty, Thu Sep 28 15:54:11 2000 UTC revision 31 by matty, Sat Sep 15 03:16:05 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    
38  BOOL ui_create_window(char *title)  static BOOL ownbackstore;
39    static Pixmap backstore;
40    
41    #define FILL_RECTANGLE(x,y,cx,cy)\
42    { \
43            XFillRectangle(display, wnd, gc, x, y, cx, cy); \
44            if (ownbackstore) \
45                    XFillRectangle(display, backstore, gc, x, y, cx, cy); \
46    }
47    
48    static BOOL owncolmap;
49    static Colormap xcolmap;
50    static uint32 white;
51    static uint32 *colmap;
52    
53    #define TRANSLATE(col)          ( owncolmap ? col : colmap[col] )
54    #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));
55    #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));
56    
57    static int rop2_map[] = {
58            GXclear,                /* 0 */
59            GXnor,                  /* DPon */
60            GXandInverted,          /* DPna */
61            GXcopyInverted,         /* Pn */
62            GXandReverse,           /* PDna */
63            GXinvert,               /* Dn */
64            GXxor,                  /* DPx */
65            GXnand,                 /* DPan */
66            GXand,                  /* DPa */
67            GXequiv,                /* DPxn */
68            GXnoop,                 /* D */
69            GXorInverted,           /* DPno */
70            GXcopy,                 /* P */
71            GXorReverse,            /* PDno */
72            GXor,                   /* DPo */
73            GXset                   /* 1 */
74    };
75    
76    #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }
77    #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
78    
79    static void
80    translate8(uint8 *data, uint8 *out, uint8 *end)
81    {
82            while (out < end)
83                    *(out++) = (uint8)colmap[*(data++)];
84    }
85    
86    static void
87    translate16(uint8 *data, uint16 *out, uint16 *end)
88    {
89            while (out < end)
90                    *(out++) = (uint16)colmap[*(data++)];
91    }
92    
93    /* XXX endianness */
94    static void
95    translate24(uint8 *data, uint8 *out, uint8 *end)
96    {
97            uint32 value;
98    
99            while (out < end)
100            {
101                    value = colmap[*(data++)];
102                    *(out++) = value;
103                    *(out++) = value >> 8;
104                    *(out++) = value >> 16;
105            }
106    }
107    
108    static void
109    translate32(uint8 *data, uint32 *out, uint32 *end)
110    {
111            while (out < end)
112                    *(out++) = colmap[*(data++)];
113    }
114    
115    static uint8 *
116    translate(int width, int height, uint8 *data)
117    {
118            int size = width * height * bpp/8;
119            uint8 *out = xmalloc(size);
120            uint8 *end = out + size;
121    
122            switch (bpp)
123            {
124                    case 8:
125                            translate8(data, out, end);
126                            break;
127    
128                    case 16:
129                            translate16(data, (uint16 *)out, (uint16 *)end);
130                            break;
131    
132                    case 24:
133                            translate24(data, out, end);
134                            break;
135    
136                    case 32:
137                            translate32(data, (uint32 *)out, (uint32 *)end);
138                            break;
139            }
140    
141            return out;
142    }
143    
144    #define L_ENDIAN
145    int screen_msbfirst = 0;
146    
147    
148    BOOL
149    ui_create_window(char *title)
150  {  {
         Screen *screen;  
151          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
152            XClassHint *classhints;
153            XSizeHints *sizehints;
154          unsigned long input_mask;          unsigned long input_mask;
155            XPixmapFormatValues *pfm;
156            Screen *screen;
157          int i;          int i;
158    
159    
160          display = XOpenDisplay(NULL);          display = XOpenDisplay(NULL);
161          if (display == NULL)          if (display == NULL)
162            {
163                    error("Failed to open display\n");
164                  return False;                  return False;
165            }
166    
         /* Check the screen supports 8-bit depth. */  
167          screen = DefaultScreenOfDisplay(display);          screen = DefaultScreenOfDisplay(display);
168          for (i = 0; i < screen->ndepths; i++)          visual = DefaultVisualOfScreen(screen);
169                  if (screen->depths[i].depth == 8)          depth = DefaultDepthOfScreen(screen);
170                          break;  
171            pfm = XListPixmapFormats(display, &i);
172            if (pfm != NULL)
173            {
174                    /* Use maximum bpp for this depth - this is generally
175                       desirable, e.g. 24 bits->32 bits. */
176                    while (i--)
177                    {
178                            if ((pfm[i].depth == depth)
179                                && (pfm[i].bits_per_pixel > bpp))
180                            {
181                                    bpp = pfm[i].bits_per_pixel;
182                            }
183                    }
184                    XFree(pfm);
185            }
186    
187          if (i >= screen->ndepths)          if (bpp < 8)
188          {          {
189                  ERROR("8-bit depth required (in this version).\n");                  error("Less than 8 bpp not currently supported.\n");
190                  XCloseDisplay(display);                  XCloseDisplay(display);
191                  return False;                  return False;
192          }          }
193    
194          visual = DefaultVisual(display, DefaultScreen(display));          if (depth <= 8)
195                    owncolmap = True;
196            else
197                    xcolmap = DefaultColormapOfScreen(screen);
198    
199            white = WhitePixelOfScreen(screen);
200            attribs.background_pixel = BlackPixelOfScreen(screen);
201            attribs.backing_store = DoesBackingStore(screen);
202    
203            if (attribs.backing_store == NotUseful)
204                    ownbackstore = True;
205    
206            if (fullscreen)
207            {
208                    attribs.override_redirect = True;
209                    width = WidthOfScreen(screen);
210                    height = HeightOfScreen(screen);
211            }
212            else
213            {
214                    attribs.override_redirect = False;
215            }
216    
217            width = (width + 3) & ~3; /* make width a multiple of 32 bits */
218    
219          attribs.background_pixel = BlackPixel(display, DefaultScreen(display));          wnd = XCreateWindow(display, RootWindowOfScreen(screen),
220          attribs.backing_store = Always;                              0, 0, width, height, 0, CopyFromParent,
221          wnd = XCreateWindow(display, DefaultRootWindow(display),                              InputOutput, CopyFromParent,
222                          0, 0, width, height, 0, 8, InputOutput, visual,                              CWBackingStore | CWBackPixel | CWOverrideRedirect,
223                          CWBackingStore | CWBackPixel, &attribs);                              &attribs);
224    
225          XStoreName(display, wnd, title);          XStoreName(display, wnd, title);
         XMapWindow(display, wnd);  
226    
227          input_mask  = KeyPressMask | KeyReleaseMask;          classhints = XAllocClassHint();
228          input_mask |= ButtonPressMask | ButtonReleaseMask;          if (classhints != NULL)
229          if (motion)          {
230                    classhints->res_name = classhints->res_class = "rdesktop";
231                    XSetClassHint(display, wnd, classhints);
232                    XFree(classhints);
233            }
234    
235            sizehints = XAllocSizeHints();
236            if (sizehints)
237            {
238                    sizehints->flags = PMinSize | PMaxSize;
239                    sizehints->min_width = sizehints->max_width = width;
240                    sizehints->min_height = sizehints->max_height = height;
241                    XSetWMNormalHints(display, wnd, sizehints);
242                    XFree(sizehints);
243            }
244    
245            input_mask = KeyPressMask | KeyReleaseMask
246                            | ButtonPressMask | ButtonReleaseMask
247                            | EnterWindowMask | LeaveWindowMask;
248    
249            if (sendmotion)
250                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
251    
252            if (ownbackstore)
253                    input_mask |= ExposureMask;
254    
255          XSelectInput(display, wnd, input_mask);          XSelectInput(display, wnd, input_mask);
256          gc = XCreateGC(display, wnd, 0, NULL);          gc = XCreateGC(display, wnd, 0, NULL);
257    
258          IM = XOpenIM(display, NULL, NULL, NULL);          if (ownbackstore)
259                    backstore = XCreatePixmap(display, wnd, width, height, depth);
260    
261            XMapWindow(display, wnd);
262          return True;          return True;
263  }  }
264    
265  void ui_destroy_window()  void
266    ui_destroy_window()
267  {  {
268          XCloseIM(IM);          if (ownbackstore)
269                    XFreePixmap(display, backstore);
270    
271          XFreeGC(display, gc);          XFreeGC(display, gc);
272          XDestroyWindow(display, wnd);          XDestroyWindow(display, wnd);
273          XCloseDisplay(display);          XCloseDisplay(display);
274            display = NULL;
275  }  }
276    
277  static uint8 xwin_translate_key(unsigned long key)  static uint8
278    xwin_translate_key(unsigned long key)
279  {  {
280          DEBUG("KEY(code=0x%lx)\n", key);          DEBUG(("KEY(code=0x%lx)\n", key));
281    
282          if ((key > 8) && (key <= 0x60))          if ((key > 8) && (key <= 0x60))
283                  return (key - 8);                  return (key - 8);
284    
285          switch (key)          switch (key)
286          {          {
287                  case 0x62: /* left arrow */                  case 0x61:      /* home */
288                          return 0x48;                          return 0x47 | 0x80;
289                  case 0x64: /* up arrow */                  case 0x62:      /* up arrow */
290                          return 0x4b;                          return 0x48 | 0x80;
291                  case 0x66: /* down arrow */                  case 0x63:      /* page up */
292                          return 0x4d;                          return 0x49 | 0x80;
293                  case 0x68: /* right arrow */                  case 0x64:      /* left arrow */
294                          return 0x50;                          return 0x4b | 0x80;
295                  case 0x73: /* Windows key */                  case 0x66:      /* right arrow */
296                          DEBUG("CHECKPOINT\n");                          return 0x4d | 0x80;
297                    case 0x67:      /* end */
298                            return 0x4f | 0x80;
299                    case 0x68:      /* down arrow */
300                            return 0x50 | 0x80;
301                    case 0x69:      /* page down */
302                            return 0x51 | 0x80;
303                    case 0x6a:      /* insert */
304                            return 0x52 | 0x80;
305                    case 0x6b:      /* delete */
306                            return 0x53 | 0x80;
307                    case 0x6c:      /* keypad enter */
308                            return 0x1c | 0x80;
309                    case 0x6d:      /* right ctrl */
310                            return 0x1d | 0x80;
311                    case 0x6f:      /* ctrl - print screen */
312                            return 0x37 | 0x80;
313                    case 0x70:      /* keypad '/' */
314                            return 0x35 | 0x80;
315                    case 0x71:      /* right alt */
316                            return 0x38 | 0x80;
317                    case 0x72:      /* ctrl break */
318                            return 0x46 | 0x80;
319                    case 0x73:      /* left window key */
320                            return 0xff;    /* real scancode is 5b */
321                    case 0x74:      /* right window key */
322                            return 0xff;    /* real scancode is 5c */
323                    case 0x75:      /* menu key */
324                            return 0x5d | 0x80;
325          }          }
326    
327          return 0;          return 0;
328  }  }
329    
330  static uint16 xwin_translate_mouse(unsigned long button)  static uint16
331    xwin_translate_mouse(unsigned long button)
332  {  {
333          switch (button)          switch (button)
334          {          {
335                  case Button1: /* left */                  case Button1:   /* left */
336                          return MOUSE_FLAG_BUTTON1;                          return MOUSE_FLAG_BUTTON1;
337                  case Button2: /* middle */                  case Button2:   /* middle */
338                          return MOUSE_FLAG_BUTTON3;                          return MOUSE_FLAG_BUTTON3;
339                  case Button3: /* right */                  case Button3:   /* right */
340                          return MOUSE_FLAG_BUTTON2;                          return MOUSE_FLAG_BUTTON2;
341          }          }
342    
343          return 0;          return 0;
344  }  }
345    
346  void ui_process_events()  void
347    ui_process_events()
348  {  {
349          XEvent event;          XEvent event;
350          uint8 scancode;          uint8 scancode;
# Line 136  void ui_process_events() Line 354  void ui_process_events()
354          if (display == NULL)          if (display == NULL)
355                  return;                  return;
356    
357          while (XCheckWindowEvent(display, wnd, 0xffffffff, &event))          while (XCheckWindowEvent(display, wnd, ~0, &event))
358          {          {
359                  ev_time = time(NULL);                  ev_time = time(NULL);
360    
# Line 148  void ui_process_events() Line 366  void ui_process_events()
366                                          break;                                          break;
367    
368                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,
369                                                  scancode, 0);                                                 scancode, 0);
370                                  break;                                  break;
371    
372                          case KeyRelease:                          case KeyRelease:
# Line 157  void ui_process_events() Line 375  void ui_process_events()
375                                          break;                                          break;
376    
377                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE,                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
378                                                  KBD_FLAG_DOWN | KBD_FLAG_UP,                                                 KBD_FLAG_DOWN | KBD_FLAG_UP,
379                                                  scancode, 0);                                                 scancode, 0);
380                                  break;                                  break;
381    
382                          case ButtonPress:                          case ButtonPress:
383                                  button = xwin_translate_mouse(event.xbutton.button);                                  button = xwin_translate_mouse(event.xbutton.button);
   
384                                  if (button == 0)                                  if (button == 0)
385                                          break;                                          break;
386    
387                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
388                                                  button | MOUSE_FLAG_DOWN,                                                 button | MOUSE_FLAG_DOWN,
389                                                  event.xbutton.x,                                                 event.xbutton.x,
390                                                  event.xbutton.y);                                                 event.xbutton.y);
391                                  break;                                  break;
392    
393                          case ButtonRelease:                          case ButtonRelease:
# Line 179  void ui_process_events() Line 396  void ui_process_events()
396                                          break;                                          break;
397    
398                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
399                                                  button,                                                 button,
400                                                  event.xbutton.x,                                                 event.xbutton.x,
401                                                  event.xbutton.y);                                                 event.xbutton.y);
402                                  break;                                  break;
403    
404                          case MotionNotify:                          case MotionNotify:
405                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
406                                                  MOUSE_FLAG_MOVE,                                                 MOUSE_FLAG_MOVE,
407                                                  event.xmotion.x,                                                 event.xmotion.x,
408                                                  event.xmotion.y);                                                 event.xmotion.y);
409                                    break;
410    
411                            case EnterNotify:
412                                    XGrabKeyboard(display, wnd, True, GrabModeAsync,
413                                                  GrabModeAsync, CurrentTime);
414                                    break;
415    
416                            case LeaveNotify:
417                                    XUngrabKeyboard(display, CurrentTime);
418                                    break;
419    
420                            case Expose:
421                                    XCopyArea(display, backstore, wnd, gc,
422                                              event.xexpose.x, event.xexpose.y,
423                                              event.xexpose.width, event.xexpose.height,
424                                              event.xexpose.x, event.xexpose.y);
425                                    break;
426                  }                  }
427          }          }
428  }  }
429    
430  void ui_move_pointer(int x, int y)  void
431    ui_move_pointer(int x, int y)
432  {  {
433          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
434  }  }
435    
436  HBITMAP ui_create_bitmap(int width, int height, uint8 *data)  HBITMAP
437    ui_create_bitmap(int width, int height, uint8 *data)
438  {  {
439          XImage *image;          XImage *image;
440          Pixmap bitmap;          Pixmap bitmap;
441            uint8 *tdata;
442    
443          bitmap = XCreatePixmap(display, wnd, width, height, 8);          tdata = (owncolmap ? data : translate(width, height, data));
444            bitmap = XCreatePixmap(display, wnd, width, height, depth);
445            image = XCreateImage(display, visual, depth, ZPixmap,
446                                 0, tdata, width, height, 8, 0);
447    
         image = XCreateImage(display, visual, 8, ZPixmap, 0,  
                                 data, width, height, 8, width);  
         XSetFunction(display, gc, GXcopy);  
448          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
449    
450          XFree(image);          XFree(image);
451                    if (!owncolmap)
452          return (HBITMAP)bitmap;                  xfree(tdata);
453            return (HBITMAP) bitmap;
454  }  }
455    
456  void ui_paint_bitmap(int x, int y, int cx, int cy,  void
457                          int width, int height, uint8 *data)  ui_paint_bitmap(int x, int y, int cx, int cy,
458                    int width, int height, uint8 *data)
459  {  {
460          XImage *image;          XImage *image;
461            uint8 *tdata;
462    
463            tdata = (owncolmap ? data : translate(width, height, data));
464            image = XCreateImage(display, visual, depth, ZPixmap,
465                                 0, tdata, width, height, 8, 0);
466    
467            if (ownbackstore)
468            {
469                    XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
470                    XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
471            }
472            else
473            {
474                    XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
475            }
476    
477          image = XCreateImage(display, visual, 8, ZPixmap, 0,          XFree(image);
478                                  data, width, height, 8, width);          if (!owncolmap)
479          XSetFunction(display, gc, GXcopy);                  xfree(tdata);
         XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);  
         XFree(image);  
480  }  }
481    
482  void ui_destroy_bitmap(HBITMAP bmp)  void
483    ui_destroy_bitmap(HBITMAP bmp)
484  {  {
485          XFreePixmap(display, (Pixmap)bmp);          XFreePixmap(display, (Pixmap)bmp);
486  }  }
487    
488  HGLYPH ui_create_glyph(int width, int height, uint8 *data)  HGLYPH
489    ui_create_glyph(int width, int height, uint8 *data)
490  {  {
491          XImage *image;          XImage *image;
492          Pixmap bitmap;          Pixmap bitmap;
# Line 244  HGLYPH ui_create_glyph(int width, int he Line 499  HGLYPH ui_create_glyph(int width, int he
499          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(display, bitmap, 0, NULL);
500    
501          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(display, visual, 1, ZPixmap, 0,
502                                  data, width, height, 8, scanline);                               data, width, height, 8, scanline);
503          XSetFunction(display, gc, GXcopy);          image->byte_order = MSBFirst;
504            image->bitmap_bit_order = MSBFirst;
505            XInitImage(image);
506    
507          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
508    
509          XFree(image);          XFree(image);
510          XFreeGC(display, gc);          XFreeGC(display, gc);
           
511          return (HGLYPH)bitmap;          return (HGLYPH)bitmap;
512  }  }
513    
514  void ui_destroy_glyph(HGLYPH glyph)  void
515    ui_destroy_glyph(HGLYPH glyph)
516  {  {
517          XFreePixmap(display, (Pixmap)glyph);          XFreePixmap(display, (Pixmap)glyph);
518  }  }
519    
520  HCOLOURMAP ui_create_colourmap(COLOURMAP *colours)  HCURSOR
521    ui_create_cursor(unsigned int x, unsigned int y, int width,
522                     int height, uint8 *andmask, uint8 *xormask)
523    {
524            HGLYPH maskglyph, cursorglyph;
525            XColor bg, fg;
526            Cursor xcursor;
527            uint8 *cursor, *pcursor;
528            uint8 *mask, *pmask;
529            uint8 nextbit;
530            int scanline, offset;
531            int i, j;
532    
533            scanline = (width + 7) / 8;
534            offset = scanline * height;
535    
536            cursor = xmalloc(offset);
537            memset(cursor, 0, offset);
538    
539            mask = xmalloc(offset);
540            memset(mask, 0, offset);
541    
542            /* approximate AND and XOR masks with a monochrome X pointer */
543            for (i = 0; i < height; i++)
544            {
545                    offset -= scanline;
546                    pcursor = &cursor[offset];
547                    pmask = &mask[offset];
548    
549                    for (j = 0; j < scanline; j++)
550                    {
551                            for (nextbit = 0x80; nextbit != 0; nextbit >>= 1)
552                            {
553                                    if (xormask[0] || xormask[1] || xormask[2])
554                                    {
555                                            *pcursor |= (~(*andmask) & nextbit);
556                                            *pmask |= nextbit;
557                                    }
558                                    else
559                                    {
560                                            *pcursor |= ((*andmask) & nextbit);
561                                            *pmask |= (~(*andmask) & nextbit);
562                                    }
563    
564                                    xormask += 3;
565                            }
566    
567                            andmask++;
568                            pcursor++;
569                            pmask++;
570                    }
571            }
572    
573            fg.red = fg.blue = fg.green = 0xffff;
574            bg.red = bg.blue = bg.green = 0x0000;
575            fg.flags = bg.flags = DoRed | DoBlue | DoGreen;
576    
577            cursorglyph = ui_create_glyph(width, height, cursor);
578            maskglyph = ui_create_glyph(width, height, mask);
579            
580            xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,
581                                    (Pixmap)maskglyph, &fg, &bg, x, y);
582    
583            ui_destroy_glyph(maskglyph);
584            ui_destroy_glyph(cursorglyph);
585            xfree(mask);
586            xfree(cursor);
587            return (HCURSOR)xcursor;
588    }
589    
590    void
591    ui_set_cursor(HCURSOR cursor)
592    {
593            XDefineCursor(display, wnd, (Cursor)cursor);
594    }
595    
596    void
597    ui_destroy_cursor(HCURSOR cursor)
598    {
599            XFreeCursor(display, (Cursor)cursor);
600    }
601    
602    #define MAKE_XCOLOR(xc,c) \
603                    (xc)->red   = ((c)->red   << 8) | (c)->red; \
604                    (xc)->green = ((c)->green << 8) | (c)->green; \
605                    (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
606                    (xc)->flags = DoRed | DoGreen | DoBlue;
607    
608    HCOLOURMAP
609    ui_create_colourmap(COLOURMAP *colours)
610  {  {
611          COLOURENTRY *entry;          COLOURENTRY *entry;
         XColor *xcolours, *xentry;  
         Colormap map;  
612          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
613    
614          xcolours = xmalloc(sizeof(XColor) * ncolours);          if (owncolmap)
         for (i = 0; i < ncolours; i++)  
615          {          {
616                  entry = &colours->colours[i];                  XColor *xcolours, *xentry;
617                  xentry = &xcolours[i];                  Colormap map;
618    
619                    xcolours = xmalloc(sizeof(XColor) * ncolours);
620                    for (i = 0; i < ncolours; i++)
621                    {
622                            entry = &colours->colours[i];
623                            xentry = &xcolours[i];
624                            xentry->pixel = i;
625                            MAKE_XCOLOR(xentry, entry);
626                    }
627    
628                    map = XCreateColormap(display, wnd, visual, AllocAll);
629                    XStoreColors(display, map, xcolours, ncolours);
630    
631                  xentry->pixel = i;                  xfree(xcolours);
632                  xentry->red = entry->red << 8;                  return (HCOLOURMAP)map;
                 xentry->blue = entry->blue << 8;  
                 xentry->green = entry->green << 8;  
                 xentry->flags = DoRed | DoBlue | DoGreen;  
633          }          }
634            else
635            {
636                    uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
637                    XColor xentry;
638    
639                    for (i = 0; i < ncolours; i++)
640                    {
641                            entry = &colours->colours[i];
642                            MAKE_XCOLOR(&xentry, entry);
643    
644          map = XCreateColormap(display, wnd, visual, AllocAll);                          if (XAllocColor(display, xcolmap, &xentry) != 0)
645          XStoreColors(display, map, xcolours, ncolours);                                  map[i] = xentry.pixel;
646                            else
647                                    map[i] = white;
648                    }
649    
650          xfree(xcolours);                  return map;
651          return (HCOLOURMAP)map;          }
652  }  }
653    
654  void ui_destroy_colourmap(HCOLOURMAP map)  void
655    ui_destroy_colourmap(HCOLOURMAP map)
656  {  {
657          XFreeColormap(display, (Colormap)map);          if (owncolmap)
658                    XFreeColormap(display, (Colormap)map);
659            else
660                    xfree(map);
661  }  }
662    
663  void ui_set_colourmap(HCOLOURMAP map)  void
664    ui_set_colourmap(HCOLOURMAP map)
665  {  {
666          XSetWindowColormap(display, wnd, (Colormap)map);          if (owncolmap)
667                    XSetWindowColormap(display, wnd, (Colormap)map);
668            else
669                    colmap = map;
670  }  }
671    
672  void ui_set_clip(int x, int y, int cx, int cy)  void
673    ui_set_clip(int x, int y, int cx, int cy)
674  {  {
675          XRectangle rect;          XRectangle rect;
676    
# Line 306  void ui_set_clip(int x, int y, int cx, i Line 681  void ui_set_clip(int x, int y, int cx, i
681          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
682  }  }
683    
684  void ui_reset_clip()  void
685    ui_reset_clip()
686  {  {
687          XRectangle rect;          XRectangle rect;
688    
# Line 317  void ui_reset_clip() Line 693  void ui_reset_clip()
693          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
694  }  }
695    
696  void ui_bell()  void
697    ui_bell()
698  {  {
699          XBell(display, 0);          XBell(display, 0);
700  }  }
701    
702  static int rop2_map[] = {  void
703          GXclear,        /* 0 */  ui_destblt(uint8 opcode,
704          GXnor,          /* DPon */             /* dest */ int x, int y, int cx, int cy)
705          GXandInverted,  /* DPna */  {
706          GXcopyInverted, /* Pn */          SET_FUNCTION(opcode);
707          GXandReverse,   /* PDna */          FILL_RECTANGLE(x, y, cx, cy);
708          GXinvert,       /* Dn */          RESET_FUNCTION(opcode);
         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]);  
 }  
   
 void ui_destblt(uint8 opcode,  
         /* dest */  int x, int y, int cx, int cy)  
 {  
         xwin_set_function(opcode);  
   
         XFillRectangle(display, wnd, gc, x, y, cx, cy);  
709  }  }
710    
711  void ui_patblt(uint8 opcode,  void
712          /* dest */  int x, int y, int cx, int cy,  ui_patblt(uint8 opcode,
713          /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* dest */ int x, int y, int cx, int cy,
714              /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
715  {  {
         Display *dpy = display;  
716          Pixmap fill;          Pixmap fill;
717    
718          xwin_set_function(opcode);          SET_FUNCTION(opcode);
719    
720          switch (brush->style)          switch (brush->style)
721          {          {
722                  case 0: /* Solid */                  case 0: /* Solid */
723                          XSetForeground(dpy, gc, fgcolour);                          SET_FOREGROUND(fgcolour);
724                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
725                          break;                          break;
726    
727                  case 3: /* Pattern */                  case 3: /* Pattern */
728                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);
729    
730                          XSetForeground(dpy, gc, fgcolour);                          SET_FOREGROUND(bgcolour);
731                          XSetBackground(dpy, gc, bgcolour);                          SET_BACKGROUND(fgcolour);
732                          XSetFillStyle(dpy, gc, FillOpaqueStippled);                          XSetFillStyle(display, gc, FillOpaqueStippled);
733                          XSetStipple(dpy, gc, fill);                          XSetStipple(display, gc, fill);
734                            XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
735    
736                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
737    
738                          XSetFillStyle(dpy, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
739                          ui_destroy_glyph((HGLYPH)fill);                          ui_destroy_glyph((HGLYPH)fill);
740                          break;                          break;
741    
742                  default:                  default:
743                          NOTIMP("brush %d\n", brush->style);                          unimpl("brush %d\n", brush->style);
744          }          }
745    
746            RESET_FUNCTION(opcode);
747  }  }
748    
749  void ui_screenblt(uint8 opcode,  void
750                  /* dest */ int x, int y, int cx, int cy,  ui_screenblt(uint8 opcode,
751                  /* src */  int srcx, int srcy)               /* dest */ int x, int y, int cx, int cy,
752                 /* src */ int srcx, int srcy)
753  {  {
754          xwin_set_function(opcode);          SET_FUNCTION(opcode);
755            XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
756          XCopyArea(display, wnd, wnd, gc, srcx, srcy,          if (ownbackstore)
757                          cx, cy, x, y);                  XCopyArea(display, backstore, backstore, gc, srcx, srcy,
758                              cx, cy, x, y);
759            RESET_FUNCTION(opcode);
760  }  }
761    
762  void ui_memblt(uint8 opcode,  void
763          /* dest */  int x, int y, int cx, int cy,  ui_memblt(uint8 opcode,
764          /* src */   HBITMAP src, int srcx, int srcy)            /* dest */ int x, int y, int cx, int cy,
765              /* src */ HBITMAP src, int srcx, int srcy)
766  {  {
767          xwin_set_function(opcode);          SET_FUNCTION(opcode);
768            XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);
769          XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy,          if (ownbackstore)
770                          cx, cy, x, y);                  XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,
771                              cx, cy, x, y);
772            RESET_FUNCTION(opcode);
773  }  }
774    
775  void ui_triblt(uint8 opcode,  void
776          /* dest */  int x, int y, int cx, int cy,  ui_triblt(uint8 opcode,
777          /* src */   HBITMAP src, int srcx, int srcy,            /* dest */ int x, int y, int cx, int cy,
778          /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* src */ HBITMAP src, int srcx, int srcy,
779              /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
780  {  {
781          /* This is potentially difficult to do in general. Until someone          /* This is potentially difficult to do in general. Until someone
782             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. */
783    
784          switch (opcode)          switch (opcode)
785          {          {
786                  case 0x69: /* PDSxxn */                  case 0x69:      /* PDSxxn */
787                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
788                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy,
789                                          brush, bgcolour, fgcolour);                                    brush, bgcolour, fgcolour);
790                          break;                          break;
791    
792                  case 0xb8: /* PSDPxax */                  case 0xb8:      /* PSDPxax */
793                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy,
794                                          brush, bgcolour, fgcolour);                                    brush, bgcolour, fgcolour);
795                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
796                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy,
797                                          brush, bgcolour, fgcolour);                                    brush, bgcolour, fgcolour);
798                            break;
799    
800                    case 0xc0:      /* PSa */
801                            ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
802                            ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,
803                                      fgcolour);
804                          break;                          break;
805    
806                  default:                  default:
807                          NOTIMP("triblt 0x%x\n", opcode);                          unimpl("triblt 0x%x\n", opcode);
808                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
809          }          }
810  }  }
811    
812  void ui_line(uint8 opcode,  void
813          /* dest */  int startx, int starty, int endx, int endy,  ui_line(uint8 opcode,
814          /* pen */   PEN *pen)          /* dest */ int startx, int starty, int endx, int endy,
815            /* pen */ PEN *pen)
816  {  {
817          xwin_set_function(opcode);          SET_FUNCTION(opcode);
818            SET_FOREGROUND(pen->colour);
         XSetForeground(display, gc, pen->colour);  
819          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(display, wnd, gc, startx, starty, endx, endy);
820            if (ownbackstore)
821                    XDrawLine(display, backstore, gc, startx, starty, endx, endy);
822            RESET_FUNCTION(opcode);
823  }  }
824    
825  void ui_rect(  void
826          /* dest */  int x, int y, int cx, int cy,  ui_rect(
827          /* brush */ int colour)                 /* dest */ int x, int y, int cx, int cy,
828                   /* brush */ int colour)
829  {  {
830          xwin_set_function(ROP2_COPY);          SET_FOREGROUND(colour);
831            FILL_RECTANGLE(x, y, cx, cy);
         XSetForeground(display, gc, colour);  
         XFillRectangle(display, wnd, gc, x, y, cx, cy);  
832  }  }
833    
834  void ui_draw_glyph(int mixmode,  void
835          /* dest */ int x, int y, int cx, int cy,  ui_draw_glyph(int mixmode,
836          /* src */  HGLYPH glyph, int srcx, int srcy, int bgcolour, int fgcolour)                /* dest */ int x, int y, int cx, int cy,
837                  /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,
838                  int fgcolour)
839  {  {
840          Pixmap pixmap = (Pixmap)glyph;          SET_FOREGROUND(fgcolour);
841            SET_BACKGROUND(bgcolour);
842    
843          xwin_set_function(ROP2_COPY);          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)
844                          ? FillStippled : FillOpaqueStippled);
845          XSetForeground(display, gc, fgcolour);          XSetStipple(display, gc, (Pixmap)glyph);
846            XSetTSOrigin(display, gc, x, y);
         switch (mixmode)  
         {  
                 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;  
847    
848                  case MIX_OPAQUE:          FILL_RECTANGLE(x, y, cx, cy);
                         XSetBackground(display, gc, bgcolour);  
                         XCopyPlane(display, pixmap, wnd, gc,  
                                         srcx, srcy, cx, cy, x, y, 1);  
                         break;  
849    
850                  default:          XSetFillStyle(display, gc, FillSolid);
                         NOTIMP("mix %d\n", mixmode);  
         }  
851  }  }
852    
853  void ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,  void
854                          int clipx, int clipy, int clipcx, int clipcy,  ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
855                          int boxx, int boxy, int boxcx, int boxcy,               int clipx, int clipy, int clipcx, int clipcy,
856                          int bgcolour, int fgcolour, uint8 *text, uint8 length)               int boxx, int boxy, int boxcx, int boxcy,
857                 int bgcolour, int fgcolour, uint8 *text, uint8 length)
858  {  {
859          FONTGLYPH *glyph;          FONTGLYPH *glyph;
860          int i;          int i, offset;
861    
862            SET_FOREGROUND(bgcolour);
863    
864          if (boxcx > 1)          if (boxcx > 1)
865          {          {
866                  ui_rect(boxx, boxy, boxcx, boxcy, bgcolour);                  FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);
867          }          }
868          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
869          {          {
870                  ui_rect(clipx, clipy, clipcx, clipcy, bgcolour);                  FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);
871          }          }
872    
873          /* Paint text, character by character */          /* Paint text, character by character */
# Line 514  void ui_draw_text(uint8 font, uint8 flag Line 876  void ui_draw_text(uint8 font, uint8 flag
876                  glyph = cache_get_font(font, text[i]);                  glyph = cache_get_font(font, text[i]);
877    
878                  if (!(flags & TEXT2_IMPLICIT_X))                  if (!(flags & TEXT2_IMPLICIT_X))
879                          x += text[++i];                  {
880                            offset = text[++i];
881                            if (offset & 0x80)
882                                    offset = ((offset & 0x7f) << 8) | text[++i];
883    
884                            if (flags & TEXT2_VERTICAL)
885                                    y += offset;
886                            else
887                                    x += offset;
888                    }
889    
890                  if (glyph != NULL)                  if (glyph != NULL)
891                  {                  {
892                          ui_draw_glyph(mixmode, x,                          ui_draw_glyph(mixmode, x + (short) glyph->offset,
893                                          y + (short)glyph->baseline,                                        y + (short) glyph->baseline,
894                                          glyph->width, glyph->height,                                        glyph->width, glyph->height,
895                                          glyph->pixmap, 0, 0,                                        glyph->pixmap, 0, 0,
896                                          bgcolour, fgcolour);                                        bgcolour, fgcolour);
897    
898                          if (flags & TEXT2_IMPLICIT_X)                          if (flags & TEXT2_IMPLICIT_X)
899                                  x += glyph->width;                                  x += glyph->width;
# Line 530  void ui_draw_text(uint8 font, uint8 flag Line 901  void ui_draw_text(uint8 font, uint8 flag
901          }          }
902  }  }
903    
904  void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)  void
905    ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
906  {  {
907            Pixmap pix;
908          XImage *image;          XImage *image;
909    
910          image = XGetImage(display, wnd, x, y, cx, cy, 0xffffffff, ZPixmap);          if (ownbackstore)
911          cache_put_desktop(offset, cx, cy, image->bytes_per_line, image->data);          {
912          XFree(image->data);                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,
913          XFree(image);                                    ZPixmap);
914            }
915            else
916            {
917                    pix = XCreatePixmap(display, wnd, cx, cy, depth);
918                    XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
919                    image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,
920                                      ZPixmap);
921                    XFreePixmap(display, pix);
922            }
923    
924            offset *= bpp/8;
925            cache_put_desktop(offset, cx, cy, image->bytes_per_line,
926                              bpp/8, image->data);
927    
928            XDestroyImage(image);
929  }  }
930    
931  void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)  void
932    ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
933  {  {
934          XImage *image;          XImage *image;
935          uint8 *data;          uint8 *data;
936    
937          data = cache_get_desktop(offset, cx, cy);          offset *= bpp/8;
938            data = cache_get_desktop(offset, cx, cy, bpp/8);
939          if (data == NULL)          if (data == NULL)
940                  return;                  return;
941    
942          image = XCreateImage(display, visual, 8, ZPixmap, 0,          image = XCreateImage(display, visual, depth, ZPixmap,
943                                  data, cx, cy, 32, cx);                               0, data, cx, cy, BitmapPad(display),
944          XSetFunction(display, gc, GXcopy);                               cx * bpp/8);
945          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);  
946            if (ownbackstore)
947            {
948                    XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
949                    XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
950            }
951            else
952            {
953                    XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
954            }
955    
956          XFree(image);          XFree(image);
957  }  }

Legend:
Removed from v.17  
changed lines
  Added in v.31

  ViewVC Help
Powered by ViewVC 1.1.26