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

Legend:
Removed from v.9  
changed lines
  Added in v.29

  ViewVC Help
Powered by ViewVC 1.1.26