/[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 7 by matty, Fri Jul 7 09:40:03 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    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  HWINDOW ui_create_window(int width, int height)  #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          struct window *wnd;          while (out < end)
74          Display *display;                  *(out++) = (uint8)colmap[*(data++)];
75          Window window;  }
76          int black;  
77          GC gc;  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    {
142            XSetWindowAttributes attribs;
143            XClassHint *classhints;
144            XSizeHints *sizehints;
145            unsigned long input_mask;
146            XPixmapFormatValues *pfm;
147            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            screen = DefaultScreenOfDisplay(display);
159            visual = DefaultVisualOfScreen(screen);
160            depth = DefaultDepthOfScreen(screen);
161    
162            pfm = XListPixmapFormats(display, &i);
163            if (pfm != NULL)
164            {
165                    /* Use maximum bpp for this depth - this is generally
166                       desirable, e.g. 24 bits->32 bits. */
167                    while (i--)
168                    {
169                            if ((pfm[i].depth == depth)
170                                && (pfm[i].bits_per_pixel > bpp))
171                            {
172                                    bpp = pfm[i].bits_per_pixel;
173                            }
174                    }
175                    XFree(pfm);
176            }
177    
178            if (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            wnd = XCreateWindow(display, RootWindowOfScreen(screen),
211                                0, 0, width, height, 0, CopyFromParent,
212                                InputOutput, CopyFromParent,
213                                CWBackingStore | CWBackPixel | CWOverrideRedirect,
214                                &attribs);
215    
216            XStoreName(display, wnd, title);
217    
218            classhints = XAllocClassHint();
219            if (classhints != NULL)
220            {
221                    classhints->res_name = classhints->res_class = "rdesktop";
222                    XSetClassHint(display, wnd, classhints);
223                    XFree(classhints);
224            }
225    
226            sizehints = XAllocSizeHints();
227            if (sizehints)
228            {
229                    sizehints->flags = PMinSize | PMaxSize;
230                    sizehints->min_width = sizehints->max_width = width;
231                    sizehints->min_height = sizehints->max_height = height;
232                    XSetWMNormalHints(display, wnd, sizehints);
233                    XFree(sizehints);
234            }
235    
236            input_mask = KeyPressMask | KeyReleaseMask
237                            | ButtonPressMask | ButtonReleaseMask
238                            | EnterWindowMask | LeaveWindowMask;
239    
240            if (sendmotion)
241                    input_mask |= PointerMotionMask;
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
251    ui_destroy_window()
252    {
253            XFreeGC(display, gc);
254            XDestroyWindow(display, wnd);
255            XCloseDisplay(display);
256            display = NULL;
257    }
258    
259    static uint8
260    xwin_translate_key(unsigned long key)
261    {
262            DEBUG("KEY(code=0x%lx)\n", key);
263    
264            if ((key > 8) && (key <= 0x60))
265                    return (key - 8);
266    
267            switch (key)
268            {
269                    case 0x61:      /* home */
270                            return 0x47 | 0x80;
271                    case 0x62:      /* up arrow */
272                            return 0x48 | 0x80;
273                    case 0x63:      /* page up */
274                            return 0x49 | 0x80;
275                    case 0x64:      /* left arrow */
276                            return 0x4b | 0x80;
277                    case 0x66:      /* right arrow */
278                            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;
310    }
311    
312    static uint16
313    xwin_translate_mouse(unsigned long button)
314    {
315            switch (button)
316            {
317                    case Button1:   /* left */
318                            return MOUSE_FLAG_BUTTON1;
319                    case Button2:   /* middle */
320                            return MOUSE_FLAG_BUTTON3;
321                    case Button3:   /* right */
322                            return MOUSE_FLAG_BUTTON2;
323            }
324    
325            return 0;
326    }
327    
328    void
329    ui_process_events()
330    {
331            XEvent event;
332            uint8 scancode;
333            uint16 button;
334            uint32 ev_time;
335    
336            if (display == NULL)
337                    return;
338    
339            while (XCheckWindowEvent(display, wnd, ~0, &event))
340            {
341                    ev_time = time(NULL);
342    
343                    switch (event.type)
344                    {
345                            case KeyPress:
346                                    scancode = xwin_translate_key(event.xkey.keycode);
347                                    if (scancode == 0)
348                                            break;
349    
350                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,
351                                                   scancode, 0);
352                                    break;
353    
354                            case KeyRelease:
355                                    scancode = xwin_translate_key(event.xkey.keycode);
356                                    if (scancode == 0)
357                                            break;
358    
359                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
360                                                   KBD_FLAG_DOWN | KBD_FLAG_UP,
361                                                   scancode, 0);
362                                    break;
363    
364                            case ButtonPress:
365                                    button = xwin_translate_mouse(event.xbutton.button);
366                                    if (button == 0)
367                                            break;
368    
369                                    rdp_send_input(ev_time, RDP_INPUT_MOUSE,
370                                                   button | MOUSE_FLAG_DOWN,
371                                                   event.xbutton.x,
372                                                   event.xbutton.y);
373                                    break;
374    
375                            case ButtonRelease:
376                                    button = xwin_translate_mouse(event.xbutton.button);
377                                    if (button == 0)
378                                            break;
379    
380                                    rdp_send_input(ev_time, RDP_INPUT_MOUSE,
381                                                   button,
382                                                   event.xbutton.x,
383                                                   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
406    ui_move_pointer(int x, int y)
407    {
408            XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
409    }
410    
411          black = BlackPixel(display, DefaultScreen(display));  HBITMAP
412          window = XCreateSimpleWindow(display, DefaultRootWindow(display),  ui_create_bitmap(int width, int height, uint8 *data)
413                                  0, 0, width, height, 0, black, black);  {
414            XImage *image;
415            Pixmap bitmap;
416            uint8 *tdata;
417    
418            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    
425            XFree(image);
426            if (!owncolmap)
427                    xfree(tdata);
428            return (HBITMAP) bitmap;
429    }
430    
431          XMapWindow(display, window);  void
432          XSync(display, True);  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          gc = XCreateGC(display, window, 0, NULL);          tdata = (owncolmap ? data : translate(width, height, data));
439            image = XCreateImage(display, visual, depth, ZPixmap,
440                                 0, tdata, width, height, 8, 0);
441    
442          wnd = xmalloc(sizeof(struct window));          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
         wnd->display = display;  
         wnd->wnd = window;  
         wnd->gc = gc;  
         wnd->visual = DefaultVisual(wnd->display, DefaultScreen(wnd->display));  
443    
444          return wnd;          XFree(image);
445            if (!owncolmap)
446                    xfree(tdata);
447  }  }
448    
449  void ui_destroy_window(HWINDOW wnd)  void
450    ui_destroy_bitmap(HBITMAP bmp)
451  {  {
452          XFreeGC(wnd->display, wnd->gc);          XFreePixmap(display, (Pixmap)bmp);
         XDestroyWindow(wnd->display, wnd->wnd);  
         XCloseDisplay(wnd->display);  
453  }  }
454    
455  HBITMAP ui_create_bitmap(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;
460            int scanline;
461            GC gc;
462    
463            scanline = (width + 7) / 8;
464    
465            bitmap = XCreatePixmap(display, wnd, width, height, 1);
466            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    
476            XFree(image);
477            XFreeGC(display, gc);
478            return (HGLYPH)bitmap;
479    }
480    
481    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            XDefineCursor(display, wnd, (Cursor)cursor);
561    }
562    
563    void
564    ui_destroy_cursor(HCURSOR cursor)
565    {
566            XFreeCursor(display, (Cursor)cursor);
567    }
568    
569    #define MAKE_XCOLOR(xc,c) \
570                    (xc)->red   = ((c)->red   << 8) | (c)->red; \
571                    (xc)->green = ((c)->green << 8) | (c)->green; \
572                    (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
573                    (xc)->flags = DoRed | DoGreen | DoBlue;
574    
575    HCOLOURMAP
576    ui_create_colourmap(COLOURMAP *colours)
577    {
578            COLOURENTRY *entry;
579            int i, ncolours = colours->ncolours;
580    
581            if (owncolmap)
582            {
583                    XColor *xcolours, *xentry;
584                    Colormap map;
585    
586                    xcolours = xmalloc(sizeof(XColor) * ncolours);
587                    for (i = 0; i < ncolours; i++)
588                    {
589                            entry = &colours->colours[i];
590                            xentry = &xcolours[i];
591                            xentry->pixel = i;
592                            MAKE_XCOLOR(xentry, entry);
593                    }
594    
595                    map = XCreateColormap(display, wnd, visual, AllocAll);
596                    XStoreColors(display, map, xcolours, ncolours);
597    
598                    xfree(xcolours);
599                    return (HCOLOURMAP)map;
600            }
601            else
602            {
603                    uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
604                    XColor xentry;
605    
606                    for (i = 0; i < ncolours; i++)
607                    {
608                            entry = &colours->colours[i];
609                            MAKE_XCOLOR(&xentry, entry);
610    
611                            if (XAllocColor(display, xcolmap, &xentry) != 0)
612                                    map[i] = xentry.pixel;
613                            else
614                                    map[i] = white;
615                    }
616    
617                    return map;
618            }
619    }
620    
621          image = XCreateImage(wnd->display, wnd->visual, 8, ZPixmap, 0,  void
622                                  data, width, height, 32, width);  ui_destroy_colourmap(HCOLOURMAP map)
623    {
624            if (owncolmap)
625                    XFreeColormap(display, (Colormap)map);
626            else
627                    xfree(map);
628    }
629    
630          return (HBITMAP)image;  void
631    ui_set_colourmap(HCOLOURMAP map)
632    {
633            if (owncolmap)
634                    XSetWindowColormap(display, wnd, (Colormap)map);
635            else
636                    colmap = map;
637  }  }
638    
639  void ui_destroy_bitmap(HWINDOW wnd, HBITMAP bmp)  void
640    ui_set_clip(int x, int y, int cx, int cy)
641  {  {
642          XDestroyImage((XImage *)bmp);          XRectangle rect;
643    
644            rect.x = x;
645            rect.y = y;
646            rect.width = cx;
647            rect.height = cy;
648            XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
649  }  }
650    
651  void ui_paint_bitmap(HWINDOW wnd, HBITMAP bmp, int x, int y)  void
652    ui_reset_clip()
653  {  {
654          XImage *image = (XImage *)bmp;          XRectangle rect;
655    
656          XPutImage(wnd->display, wnd->wnd, wnd->gc, image,          rect.x = 0;
657                          0, 0, x, y, image->width, image->height);          rect.y = 0;
658            rect.width = width;
659            rect.height = height;
660            XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
661    }
662    
663          XSync(wnd->display, True);  void
664    ui_bell()
665    {
666            XBell(display, 0);
667  }  }
668    
669  HCOLORMAP ui_create_colormap(HWINDOW wnd, COLORMAP *colors)  void
670    ui_destblt(uint8 opcode,
671               /* dest */ int x, int y, int cx, int cy)
672  {  {
673          COLORENTRY *entry;          SET_FUNCTION(opcode);
674          XColor *xcolors, *xentry;          XFillRectangle(display, wnd, gc, x, y, cx, cy);
675          Colormap map;          RESET_FUNCTION(opcode);
676          int i, ncolors = colors->ncolors;  }
677    
678    void
679    ui_patblt(uint8 opcode,
680              /* dest */ int x, int y, int cx, int cy,
681              /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
682    {
683            Pixmap fill;
684    
685          xcolors = malloc(sizeof(XColor) * ncolors);          SET_FUNCTION(opcode);
686          for (i = 0; i < ncolors; i++)  
687            switch (brush->style)
688          {          {
689                  entry = &colors->colors[i];                  case 0: /* Solid */
690                  xentry = &xcolors[i];                          SET_FOREGROUND(fgcolour);
691                            XFillRectangle(display, wnd, gc, x, y, cx, cy);
692                            break;
693    
694                    case 3: /* Pattern */
695                            fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);
696    
697                            SET_FOREGROUND(bgcolour);
698                            SET_BACKGROUND(fgcolour);
699                            XSetFillStyle(display, gc, FillOpaqueStippled);
700                            XSetStipple(display, gc, fill);
701                            XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
702    
703                            XFillRectangle(display, wnd, gc, x, y, cx, cy);
704    
705                            XSetFillStyle(display, gc, FillSolid);
706                            ui_destroy_glyph((HGLYPH)fill);
707                            break;
708    
709                  xentry->pixel = i;                  default:
710                  xentry->red = entry->red << 8;                          NOTIMP("brush %d\n", brush->style);
                 xentry->blue = entry->blue << 8;  
                 xentry->green = entry->green << 8;  
                 xentry->flags = DoRed | DoBlue | DoGreen;  
711          }          }
712    
713          map = XCreateColormap(wnd->display, wnd->wnd, wnd->visual, AllocAll);          RESET_FUNCTION(opcode);
714          XStoreColors(wnd->display, map, xcolors, ncolors);  }
715    
716    void
717    ui_screenblt(uint8 opcode,
718                 /* dest */ int x, int y, int cx, int cy,
719                 /* src */ int srcx, int srcy)
720    {
721            SET_FUNCTION(opcode);
722            XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
723            RESET_FUNCTION(opcode);
724    }
725    
726          free(xcolors);  void
727          return (HCOLORMAP)map;  ui_memblt(uint8 opcode,
728              /* dest */ int x, int y, int cx, int cy,
729              /* src */ HBITMAP src, int srcx, int srcy)
730    {
731            SET_FUNCTION(opcode);
732            XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);
733            RESET_FUNCTION(opcode);
734  }  }
735    
736  void ui_destroy_colormap(HWINDOW wnd, HCOLORMAP map)  void
737    ui_triblt(uint8 opcode,
738              /* dest */ int x, int y, int cx, int cy,
739              /* src */ HBITMAP src, int srcx, int srcy,
740              /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
741  {  {
742          XFreeColormap(wnd->display, (Colormap)map);          /* This is potentially difficult to do in general. Until someone
743               comes up with a more efficient way of doing it I am using cases. */
744    
745            switch (opcode)
746            {
747                    case 0x69:      /* PDSxxn */
748                            ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
749                            ui_patblt(ROP2_NXOR, x, y, cx, cy,
750                                      brush, bgcolour, fgcolour);
751                            break;
752    
753                    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;
766    
767                    default:
768                            NOTIMP("triblt 0x%x\n", opcode);
769                            ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
770            }
771  }  }
772    
773  void ui_set_colormap(HWINDOW wnd, HCOLORMAP map)  void
774    ui_line(uint8 opcode,
775            /* dest */ int startx, int starty, int endx, int endy,
776            /* pen */ PEN *pen)
777  {  {
778          XSetWindowColormap(wnd->display, wnd->wnd, (Colormap)map);          SET_FUNCTION(opcode);
779            SET_FOREGROUND(pen->colour);
780            XDrawLine(display, wnd, gc, startx, starty, endx, endy);
781            RESET_FUNCTION(opcode);
782  }  }
783    
784  void ui_draw_rectangle(HWINDOW wnd, int x, int y, int width, int height)  void
785    ui_rect(
786                   /* dest */ int x, int y, int cx, int cy,
787                   /* brush */ int colour)
788  {  {
789          static int white = 0;          SET_FOREGROUND(colour);
790            XFillRectangle(display, wnd, gc, x, y, cx, cy);
791    }
792    
793    void
794    ui_draw_glyph(int mixmode,
795                  /* dest */ int x, int y, int cx, int cy,
796                  /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,
797                  int fgcolour)
798    {
799            SET_FOREGROUND(fgcolour);
800            SET_BACKGROUND(bgcolour);
801    
802            XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)
803                          ? FillStippled : FillOpaqueStippled);
804            XSetStipple(display, gc, (Pixmap)glyph);
805            XSetTSOrigin(display, gc, x, y);
806    
807          XSetForeground(wnd->display, wnd->gc, white);          XFillRectangle(display, wnd, gc, x, y, cx, cy);
         XFillRectangle(wnd->display, wnd->wnd, wnd->gc, x, y, width, height);  
808    
809          white++;          XSetFillStyle(display, gc, FillSolid);
810  }  }
811    
812  void ui_move_pointer(HWINDOW wnd, int x, int y)  void
813    ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
814                 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          XWarpPointer(wnd->display, wnd->wnd, wnd->wnd, 0, 0, 0, 0, x, y);          FONTGLYPH *glyph;
819            int i, offset;
820    
821            SET_FOREGROUND(bgcolour);
822    
823            if (boxcx > 1)
824                    XFillRectangle(display, wnd, gc, boxx, boxy, boxcx, boxcy);
825            else if (mixmode == MIX_OPAQUE)
826                    XFillRectangle(display, wnd, gc, clipx, clipy, clipcx, clipcy);
827    
828            /* Paint text, character by character */
829            for (i = 0; i < length; i++)
830            {
831                    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)
846                    {
847                            ui_draw_glyph(mixmode, x + (short) glyph->offset,
848                                          y + (short) glyph->baseline,
849                                          glyph->width, glyph->height,
850                                          glyph->pixmap, 0, 0,
851                                          bgcolour, fgcolour);
852    
853                            if (flags & TEXT2_IMPLICIT_X)
854                                    x += glyph->width;
855                    }
856            }
857  }  }
858    
859    void
860    ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
861    {
862            Pixmap pix;
863            XImage *image;
864    
865            pix = XCreatePixmap(display, wnd, cx, cy, depth);
866            XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
867    
868            image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
869    
870            offset *= bpp/8;
871            cache_put_desktop(offset, cx, cy, image->bytes_per_line,
872                              bpp/8, image->data);
873    
874            XDestroyImage(image);
875            XFreePixmap(display, pix);
876    }
877    
878    void
879    ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
880    {
881            XImage *image;
882            uint8 *data;
883    
884            offset *= bpp/8;
885            data = cache_get_desktop(offset, cx, cy, bpp/8);
886            if (data == NULL)
887                    return;
888    
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);
895    }
896    

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

  ViewVC Help
Powered by ViewVC 1.1.26