/[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 10 by matty, Tue Aug 15 10:23:24 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          image = XCreateImage(display, visual, 8, ZPixmap, 0,          tdata = (owncolmap ? data : translate(width, height, data));
464                                  data, width, height, 8, width);          image = XCreateImage(display, visual, depth, ZPixmap,
465          XSetFunction(display, gc, GXcopy);                               0, tdata, width, height, 8, 0);
466          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);  
467          XFree(image);          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            XFree(image);
478            if (!owncolmap)
479                    xfree(tdata);
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                  xentry->pixel = i;                  xcolours = xmalloc(sizeof(XColor) * ncolours);
620                  xentry->red = entry->red << 8;                  for (i = 0; i < ncolours; i++)
621                  xentry->blue = entry->blue << 8;                  {
622                  xentry->green = entry->green << 8;                          entry = &colours->colours[i];
623                  xentry->flags = DoRed | DoBlue | DoGreen;                          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                    xfree(xcolours);
632                    return (HCOLOURMAP)map;
633          }          }
634            else
635            {
636                    uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
637                    XColor xentry;
638    
639          map = XCreateColormap(display, wnd, visual, AllocAll);                  for (i = 0; i < ncolours; i++)
640          XStoreColors(display, map, xcolours, ncolours);                  {
641                            entry = &colours->colours[i];
642                            MAKE_XCOLOR(&xentry, entry);
643    
644          xfree(xcolours);                          if (XAllocColor(display, xcolmap, &xentry) != 0)
645          return (HCOLOURMAP)map;                                  map[i] = xentry.pixel;
646                            else
647                                    map[i] = white;
648                    }
649    
650                    return map;
651            }
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          }          }
 }  
   
 void ui_screenblt(uint8 opcode,  
                 /* dest */ int x, int y, int cx, int cy,  
                 /* src */  int srcx, int srcy)  
 {  
         xwin_set_function(opcode);  
745    
746          XCopyArea(display, wnd, wnd, gc, srcx, srcy,          RESET_FUNCTION(opcode);
                         cx, cy, x, y);  
747  }  }
748    
749  void ui_memblt(uint8 opcode,  void
750          /* dest */  int x, int y, int cx, int cy,  ui_screenblt(uint8 opcode,
751          /* src */   HBITMAP src, int srcx, int srcy)               /* dest */ int x, int y, int cx, int cy,
752  {               /* src */ int srcx, int srcy)
753          xwin_set_function(opcode);  {
754            SET_FUNCTION(opcode);
755          XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy,          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
756                          cx, cy, x, y);          if (ownbackstore)
757  }                  XCopyArea(display, backstore, backstore, gc, srcx, srcy,
758                              cx, cy, x, y);
759  void ui_triblt(uint8 opcode,          RESET_FUNCTION(opcode);
760          /* dest */  int x, int y, int cx, int cy,  }
761          /* src */   HBITMAP src, int srcx, int srcy,  
762          /* brush */ BRUSH *brush, int bgcolour, int fgcolour)  void
763    ui_memblt(uint8 opcode,
764              /* dest */ int x, int y, int cx, int cy,
765              /* src */ HBITMAP src, int srcx, int srcy)
766    {
767            SET_FUNCTION(opcode);
768            XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);
769            if (ownbackstore)
770                    XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,
771                              cx, cy, x, y);
772            RESET_FUNCTION(opcode);
773    }
774    
775    void
776    ui_triblt(uint8 opcode,
777              /* dest */ int x, int y, int cx, int cy,
778              /* 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 0xb8: /* PSDPxax */                  case 0x69:      /* PDSxxn */
787                            ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
788                            ui_patblt(ROP2_NXOR, x, y, cx, cy,
789                                      brush, bgcolour, fgcolour);
790                            break;
791    
792                    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,                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
                                         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,                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
                                         brush, bgcolour, fgcolour);  
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);
         xwin_set_function(ROP2_COPY);  
842    
843          XSetForeground(display, gc, fgcolour);          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)
844                          ? FillStippled : FillOpaqueStippled);
845            XSetStipple(display, gc, (Pixmap)glyph);
846            XSetTSOrigin(display, gc, x, y);
847    
848          switch (mixmode)          FILL_RECTANGLE(x, y, cx, cy);
         {  
                 case MIX_TRANSPARENT:  
                         XSetStipple(display, gc, pixmap);  
                         XSetFillStyle(display, gc, FillStippled);  
                         XSetTSOrigin(display, gc, x, y);  
                         XFillRectangle(display, wnd, gc,  
                                         x, y, cx, cy);  
                         XSetFillStyle(display, gc, FillSolid);  
                         break;  
849    
850                  case MIX_OPAQUE:          XSetFillStyle(display, gc, FillSolid);
                         XSetBackground(display, gc, bgcolour);  
                         XCopyPlane(display, pixmap, wnd, gc,  
                                         srcx, srcy, cx, cy, x, y, 1);  
                         break;  
   
                 default:  
                         NOTIMP("mix %d\n", mixmode);  
         }  
851  }  }
852    
853  void ui_draw_text(uint8 font, uint8 flags, int mixmode, int x,  void
854                          int y, int boxx, int boxy, int boxcx, int boxcy,  ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
855                          int bgcolour, int fgcolour, uint8 *text, uint8 length)               int clipx, int clipy, int clipcx, int clipcy,
856                 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)
869            {
870                    FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);
871          }          }
872    
873          /* Paint text, character by character */          /* Paint text, character by character */
# Line 504  void ui_draw_text(uint8 font, uint8 flag Line 875  void ui_draw_text(uint8 font, uint8 flag
875          {          {
876                  glyph = cache_get_font(font, text[i]);                  glyph = cache_get_font(font, text[i]);
877    
878                    if (!(flags & TEXT2_IMPLICIT_X))
879                    {
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;
                         else  
                                 x += text[++i];  
900                  }                  }
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;
         int scanline;  
909    
910          scanline = (cx + 3) & ~3;          if (ownbackstore)
911          STATUS("XGetImage(%p,%x,%d,%d,%d,%d,%x,%d)\n", display, wnd, x, y,          {
912                  cx, cy, 0xffffffff, ZPixmap);                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,
913          image = XGetImage(display, wnd, x, y, cx, cy, 0xffffffff, ZPixmap);                                    ZPixmap);
914          cache_put_desktop(offset, scanline*cy, image->data);          }
915          XFree(image->data);          else
916          XFree(image);          {
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;
         int scanline;  
935          uint8 *data;          uint8 *data;
936    
937          scanline = (cx + 3) & ~3;          offset *= bpp/8;
938          data = cache_get_desktop(offset, scanline*cy);          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, scanline);                               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.10  
changed lines
  Added in v.31

  ViewVC Help
Powered by ViewVC 1.1.26