/[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 6 by matty, Wed Jul 5 07:44:21 2000 UTC revision 28 by matty, Wed Jun 20 13:54:48 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  HWINDOW ui_create_window(int width, int height)  extern int width;
27    extern int height;
28    extern BOOL motion;
29    extern BOOL grab_keyboard;
30    extern BOOL fullscreen;
31    extern int private_colormap;
32    
33    static int bpp;
34    static int depth;
35    static Display *display;
36    static Window wnd;
37    static GC gc;
38    static Visual *visual;
39    static uint32 *colmap;
40    
41    #define Ctrans(col) ( private_colormap ? col : colmap[col])
42    
43    #define L_ENDIAN
44    int screen_msbfirst = 0;
45    
46    static uint8 *translate(int width, int height, uint8 *data);
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    static void
68    xwin_set_function(uint8 rop2)
69  {  {
70          struct window *wnd;          static uint8 last_rop2 = ROP2_COPY;
71          Display *display;  
72          Window window;          if (last_rop2 != rop2)
73          int black;          {
74          GC gc;                  XSetFunction(display, gc, rop2_map[rop2]);
75                    last_rop2 = rop2;
76            }
77    }
78    
79    static void
80    xwin_grab_keyboard()
81    {
82            XGrabKeyboard(display, wnd, True, GrabModeAsync, GrabModeAsync,
83                          CurrentTime);
84    }
85    
86    static void
87    xwin_ungrab_keyboard()
88    {
89            XUngrabKeyboard(display, CurrentTime);
90    }
91    
92    BOOL
93    ui_create_window(char *title)
94    {
95            XSetWindowAttributes attribs;
96            XClassHint *classhints;
97            XSizeHints *sizehints;
98            unsigned long input_mask;
99            XPixmapFormatValues *pfm;
100            int count;
101    
102          display = XOpenDisplay(NULL);          display = XOpenDisplay(NULL);
103          if (display == NULL)          if (display == NULL)
104            {
105                    ERROR("Failed to open display\n");
106                    return False;
107            }
108    
109            visual = DefaultVisual(display, DefaultScreen(display));
110            depth = DefaultDepth(display, DefaultScreen(display));
111            pfm = XListPixmapFormats(display, &count);
112            if (pfm != NULL)
113            {
114                    while (count--)
115                    {
116                            if ((pfm + count)->depth == depth
117                                && (pfm + count)->bits_per_pixel > bpp)
118                            {
119                                    bpp = (pfm + count)->bits_per_pixel;
120                            }
121                    }
122                    XFree(pfm);
123            }
124    
125            if (bpp < 8)
126            {
127                    ERROR("Less than 8 bpp not currently supported.\n");
128                    XCloseDisplay(display);
129                    return False;
130            }
131    
132            width &= ~3; /* make width nicely divisible */
133    
134            attribs.background_pixel = BlackPixel(display, DefaultScreen(display));
135            attribs.backing_store = Always;
136    
137            if (fullscreen)
138            {
139                    attribs.override_redirect = True;
140                    width = WidthOfScreen(DefaultScreenOfDisplay(display));
141                    height = HeightOfScreen(DefaultScreenOfDisplay(display));
142                    XSetInputFocus(display, PointerRoot, RevertToPointerRoot,
143                                   CurrentTime);
144            }
145            else
146            {
147                    attribs.override_redirect = False;
148            }
149    
150            wnd = XCreateWindow(display, DefaultRootWindow(display),
151                                0, 0, width, height, 0, CopyFromParent,
152                                InputOutput, CopyFromParent,
153                                CWBackingStore | CWBackPixel | CWOverrideRedirect,
154                                &attribs);
155    
156            XStoreName(display, wnd, title);
157    
158            classhints = XAllocClassHint();
159            if (classhints != NULL)
160    
161            {
162                    classhints->res_name = "rdesktop";
163                    classhints->res_class = "rdesktop";
164                    XSetClassHint(display, wnd, classhints);
165                    XFree(classhints);
166            }
167    
168            sizehints = XAllocSizeHints();
169            if (sizehints)
170            {
171                    sizehints->flags =
172                            PPosition | PSize | PMinSize | PMaxSize | PBaseSize;
173                    sizehints->min_width = width;
174                    sizehints->max_width = width;
175                    sizehints->min_height = height;
176                    sizehints->max_height = height;
177                    sizehints->base_width = width;
178                    sizehints->base_height = height;
179                    XSetWMNormalHints(display, wnd, sizehints);
180                    XFree(sizehints);
181            }
182    
183            input_mask = KeyPressMask | KeyReleaseMask;
184            input_mask |= ButtonPressMask | ButtonReleaseMask;
185            if (motion)
186                    input_mask |= PointerMotionMask;
187            if (grab_keyboard)
188                    input_mask |= EnterWindowMask | LeaveWindowMask;
189    
190            XSelectInput(display, wnd, input_mask);
191            gc = XCreateGC(display, wnd, 0, NULL);
192    
193            XMapWindow(display, wnd);
194            return True;
195    }
196    
197    void
198    ui_destroy_window()
199    {
200            XFreeGC(display, gc);
201            XDestroyWindow(display, wnd);
202            XCloseDisplay(display);
203            display = NULL;
204    }
205    
206    static uint8
207    xwin_translate_key(unsigned long key)
208    {
209            DEBUG("KEY(code=0x%lx)\n", key);
210    
211            if ((key > 8) && (key <= 0x60))
212                    return (key - 8);
213    
214            switch (key)
215            {
216                    case 0x61:      /* home */
217                            return 0x47 | 0x80;
218                    case 0x62:      /* up arrow */
219                            return 0x48 | 0x80;
220                    case 0x63:      /* page up */
221                            return 0x49 | 0x80;
222                    case 0x64:      /* left arrow */
223                            return 0x4b | 0x80;
224                    case 0x66:      /* right arrow */
225                            return 0x4d | 0x80;
226                    case 0x67:      /* end */
227                            return 0x4f | 0x80;
228                    case 0x68:      /* down arrow */
229                            return 0x50 | 0x80;
230                    case 0x69:      /* page down */
231                            return 0x51 | 0x80;
232                    case 0x6a:      /* insert */
233                            return 0x52 | 0x80;
234                    case 0x6b:      /* delete */
235                            return 0x53 | 0x80;
236                    case 0x6c:      /* keypad enter */
237                            return 0x1c | 0x80;
238                    case 0x6d:      /* right ctrl */
239                            return 0x1d | 0x80;
240                    case 0x6f:      /* ctrl - print screen */
241                            return 0x37 | 0x80;
242                    case 0x70:      /* keypad '/' */
243                            return 0x35 | 0x80;
244                    case 0x71:      /* right alt */
245                            return 0x38 | 0x80;
246                    case 0x72:      /* ctrl break */
247                            return 0x46 | 0x80;
248                    case 0x73:      /* left window key */
249                            return 0xff;    /* real scancode is 5b */
250                    case 0x74:      /* right window key */
251                            return 0xff;    /* real scancode is 5c */
252                    case 0x75:      /* menu key */
253                            return 0x5d | 0x80;
254            }
255    
256            return 0;
257    }
258    
259    static uint16
260    xwin_translate_mouse(unsigned long button)
261    {
262            switch (button)
263            {
264                    case Button1:   /* left */
265                            return MOUSE_FLAG_BUTTON1;
266                    case Button2:   /* middle */
267                            return MOUSE_FLAG_BUTTON3;
268                    case Button3:   /* right */
269                            return MOUSE_FLAG_BUTTON2;
270            }
271    
272            return 0;
273    }
274    
275    void
276    ui_process_events()
277    {
278            XEvent event;
279            uint8 scancode;
280            uint16 button;
281            uint32 ev_time;
282    
283            if (display == NULL)
284                    return;
285    
286            while (XCheckWindowEvent(display, wnd, ~0, &event))
287            {
288                    ev_time = time(NULL);
289    
290                    switch (event.type)
291                    {
292                            case KeyPress:
293                                    scancode = xwin_translate_key(event.xkey.keycode);
294                                    if (scancode == 0)
295                                            break;
296    
297                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,
298                                                   scancode, 0);
299                                    break;
300    
301                            case KeyRelease:
302                                    scancode = xwin_translate_key(event.xkey.keycode);
303                                    if (scancode == 0)
304                                            break;
305    
306                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
307                                                   KBD_FLAG_DOWN | KBD_FLAG_UP,
308                                                   scancode, 0);
309                                    break;
310    
311                            case ButtonPress:
312                                    button = xwin_translate_mouse(event.xbutton.button);
313                                    if (button == 0)
314                                            break;
315    
316                                    rdp_send_input(ev_time, RDP_INPUT_MOUSE,
317                                                   button | MOUSE_FLAG_DOWN,
318                                                   event.xbutton.x,
319                                                   event.xbutton.y);
320                                    break;
321    
322                            case ButtonRelease:
323                                    button = xwin_translate_mouse(event.xbutton.button);
324                                    if (button == 0)
325                                            break;
326    
327                                    rdp_send_input(ev_time, RDP_INPUT_MOUSE,
328                                                   button,
329                                                   event.xbutton.x,
330                                                   event.xbutton.y);
331                                    break;
332    
333                            case MotionNotify:
334                                    rdp_send_input(ev_time, RDP_INPUT_MOUSE,
335                                                   MOUSE_FLAG_MOVE,
336                                                   event.xmotion.x,
337                                                   event.xmotion.y);
338                                    break;
339    
340                            case EnterNotify:
341                                    if (grab_keyboard)
342                                            xwin_grab_keyboard();
343                                    break;
344    
345                            case LeaveNotify:
346                                    if (grab_keyboard)
347                                            xwin_ungrab_keyboard();
348                                    break;
349                    }
350            }
351    }
352    
353    void
354    ui_move_pointer(int x, int y)
355    {
356            XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
357    }
358    
359    HBITMAP
360    ui_create_bitmap(int width, int height, uint8 *data)
361    {
362            XImage *image;
363            Pixmap bitmap;
364            uint8 *tdata;
365            tdata = (private_colormap ? data : translate(width, height, data));
366            bitmap = XCreatePixmap(display, wnd, width, height, depth);
367            image =
368                    XCreateImage(display, visual,
369                                 depth, ZPixmap,
370                                 0, tdata, width, height, BitmapPad(display), 0);
371    
372            xwin_set_function(ROP2_COPY);
373            XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
374    
375            XFree(image);
376            if (!private_colormap)
377                    xfree(tdata);
378            return (HBITMAP) bitmap;
379    }
380    
381    void
382    ui_paint_bitmap(int x, int y, int cx, int cy,
383                    int width, int height, uint8 *data)
384    {
385            XImage *image;
386            uint8 *tdata =
387                    (private_colormap ? data : translate(width, height, data));
388            image =
389                    XCreateImage(display, visual, depth, ZPixmap, 0, tdata, width,
390                                 height, BitmapPad(display), 0);
391    
392            xwin_set_function(ROP2_COPY);
393    
394            /* Window */
395            XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
396            XFree(image);
397            if (!private_colormap)
398                    xfree(tdata);
399    }
400    
401    void
402    ui_destroy_bitmap(HBITMAP bmp)
403    {
404            XFreePixmap(display, (Pixmap) bmp);
405    }
406    
407    HCURSOR
408    ui_create_cursor(unsigned int x, unsigned int y, int width,
409                     int height, uint8 *mask, uint8 *data)
410    {
411            XImage *imagecursor;
412            XImage *imagemask;
413            Pixmap maskbitmap, cursorbitmap;
414            Cursor cursor;
415            XColor bg, fg;
416            GC lgc;
417            int i, x1, y1, scanlinelen;
418            uint8 *cdata, *cmask;
419            uint8 c;
420            cdata = (uint8 *) malloc(sizeof(uint8) * width * height);
421            if (!cdata)
422                    return NULL;
423            scanlinelen = (width + 7) >> 3;
424            cmask = (uint8 *) malloc(sizeof(uint8) * scanlinelen * height);
425            if (!cmask)
426            {
427                    free(cdata);
428                  return NULL;                  return NULL;
429            }
430            i = (height - 1) * scanlinelen;
431    
432          black = BlackPixel(display, DefaultScreen(display));          if (!screen_msbfirst)
433          window = XCreateSimpleWindow(display, DefaultRootWindow(display),          {
434                                  0, 0, width, height, 0, black, black);                  while (i >= 0)
435                    {
436                            for (x1 = 0; x1 < scanlinelen; x1++)
437                            {
438                                    c = *(mask++);
439                                    cmask[i + x1] =
440                                            ((c & 0x1) << 7) | ((c & 0x2) << 5) |
441                                            ((c & 0x4) << 3) | ((c & 0x8) << 1) |
442                                            ((c & 0x10) >> 1) | ((c & 0x20) >> 3)
443                                            | ((c & 0x40) >> 5) | ((c & 0x80) >>
444                                                                   7);
445                            }
446                            i -= scanlinelen;
447                    }
448            }
449            else
450            {
451                    while (i >= 0)
452                    {
453                            for (x1 = 0; x1 < scanlinelen; x1++)
454                            {
455                                    cmask[i + x1] = *(mask++);
456                            }
457                            i -= scanlinelen;
458                    }
459            }
460    
         XMapWindow(display, window);  
         XSync(display, True);  
461    
462          gc = XCreateGC(display, window, 0, NULL);          fg.red = 0;
463            fg.blue = 0;
464            fg.green = 0;
465            fg.flags = DoRed | DoBlue | DoGreen;
466            bg.red = 65535;
467            bg.blue = 65535;
468            bg.green = 65535;
469            bg.flags = DoRed | DoBlue | DoGreen;
470            maskbitmap = XCreatePixmap(display, wnd, width, height, 1);
471            cursorbitmap = XCreatePixmap(display, wnd, width, height, 1);
472            lgc = XCreateGC(display, maskbitmap, 0, NULL);
473            XSetFunction(display, lgc, GXcopy);
474            imagemask =
475                    XCreateImage(display, visual, 1, XYBitmap, 0, cmask, width,
476                                 height, 8, 0);
477            imagecursor =
478                    XCreateImage(display, visual, 1, XYBitmap, 0, cdata, width,
479                                 height, 8, 0);
480            for (y1 = height - 1; y1 >= 0; y1--)
481                    for (x1 = 0; x1 < width; x1++)
482                    {
483                            if (data[0] >= 0x80 || data[1] >= 0x80
484                                || data[2] >= 0x80)
485                                    if (XGetPixel(imagemask, x1, y1))
486    
487          wnd = xmalloc(sizeof(struct window));                                  {
488          wnd->display = display;                                          XPutPixel(imagecursor, x1, y1, 0);
489          wnd->wnd = window;                                          XPutPixel(imagemask, x1, y1, 0);        /* mask is blank for text cursor! */
490          wnd->gc = gc;                                  }
491          return wnd;  
492                                    else
493                                            XPutPixel(imagecursor, x1, y1, 1);
494    
495                            else
496                                    XPutPixel(imagecursor, x1, y1,
497                                              XGetPixel(imagemask, x1, y1));
498                            data += 3;
499                    }
500            XPutImage(display, maskbitmap, lgc, imagemask, 0, 0, 0, 0, width,
501                      height);
502            XPutImage(display, cursorbitmap, lgc, imagecursor, 0, 0, 0, 0, width,
503                      height); XFree(imagemask);
504            XFree(imagecursor);
505            free(cmask);
506            free(cdata);
507            XFreeGC(display, lgc);
508            cursor =
509                    XCreatePixmapCursor(display, cursorbitmap, maskbitmap, &fg,
510                                        &bg, x, y);
511            XFreePixmap(display, maskbitmap);
512            XFreePixmap(display, cursorbitmap);
513            return (HCURSOR) cursor;
514    }
515    
516    void
517    ui_set_cursor(HCURSOR cursor)
518    {
519            XDefineCursor(display, wnd, (Cursor) cursor);
520  }  }
521    
522  void ui_destroy_window(HWINDOW wnd)  void
523    ui_destroy_cursor(HCURSOR cursor)
524  {  {
525          XFreeGC(wnd->display, wnd->gc);          XFreeCursor(display, (Cursor) cursor);
         XDestroyWindow(wnd->display, wnd->wnd);  
         XCloseDisplay(wnd->display);  
526  }  }
527    
528  HBITMAP ui_create_bitmap(HWINDOW wnd, int width, int height, uint8 *data)  HGLYPH
529    ui_create_glyph(int width, int height, uint8 *data)
530  {  {
531          XImage *image;          XImage *image;
532          Visual *visual;          Pixmap bitmap;
533            int scanline;
534            GC gc;
535    
536          visual = DefaultVisual(wnd->display, DefaultScreen(wnd->display));          scanline = (width + 7) / 8;
         image = XCreateImage(wnd->display, visual, 8, ZPixmap, 0,  
                                 data, width, height, 32, width);  
537    
538          return (HBITMAP)image;          bitmap = XCreatePixmap(display, wnd, width, height, 1);
539            gc = XCreateGC(display, bitmap, 0, NULL);
540    
541            image = XCreateImage(display, visual, 1, ZPixmap, 0,
542                                 data, width, height, 8, scanline);
543            image->byte_order = MSBFirst;
544            image->bitmap_bit_order = MSBFirst;
545            XInitImage(image);
546    
547            XSetFunction(display, gc, GXcopy);
548            XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
549            XFree(image);
550            XFreeGC(display, gc);
551    
552            return (HGLYPH) bitmap;
553  }  }
554    
555  void ui_destroy_bitmap(HBITMAP bmp)  void
556    ui_destroy_glyph(HGLYPH glyph)
557  {  {
558          XDestroyImage((XImage *)bmp);          XFreePixmap(display, (Pixmap) glyph);
559  }  }
560    
561  void ui_paint_bitmap(HWINDOW wnd, HBITMAP bmp, int x, int y)  HCOLOURMAP
562    ui_create_colourmap(COLOURMAP *colours)
563  {  {
564          XImage *image = (XImage *)bmp;          if (!private_colormap)
565            {
566                    COLOURENTRY *entry;
567                    int i, ncolours = colours->ncolours;
568                    uint32 *nc = xmalloc(sizeof(*colmap) * ncolours);
569                    for (i = 0; i < ncolours; i++)
570                    {
571                            XColor xc;
572                            entry = &colours->colours[i];
573                            xc.red = entry->red << 8;
574                            xc.green = entry->green << 8;
575                            xc.blue = entry->blue << 8;
576                            XAllocColor(display,
577                                        DefaultColormap(display,
578                                                        DefaultScreen(display)),
579                                        &xc);
580                            /* XXX Check return value */
581                            nc[i] = xc.pixel;
582                    }
583                    return nc;
584            }
585            else
586            {
587                    COLOURENTRY *entry;
588                    XColor *xcolours, *xentry;
589                    Colormap map;
590                    int i, ncolours = colours->ncolours;
591                    xcolours = xmalloc(sizeof(XColor) * ncolours);
592                    for (i = 0; i < ncolours; i++)
593                    {
594                            entry = &colours->colours[i];
595                            xentry = &xcolours[i];
596    
597                            xentry->pixel = i;
598                            xentry->red = entry->red << 8;
599                            xentry->blue = entry->blue << 8;
600                            xentry->green = entry->green << 8;
601                            xentry->flags = DoRed | DoBlue | DoGreen;
602                    }
603    
604                    map = XCreateColormap(display, wnd, visual, AllocAll);
605                    XStoreColors(display, map, xcolours, ncolours);
606    
607                    xfree(xcolours);
608                    return (HCOLOURMAP) map;
609            }
610    }
611    
612    void
613    ui_destroy_colourmap(HCOLOURMAP map)
614    {
615            XFreeColormap(display, (Colormap) map);
616    }
617    
618    void
619    ui_set_colourmap(HCOLOURMAP map)
620    {
621    
622            /* XXX, change values of all pixels on the screen if the new colmap
623             * doesn't have the same values as the old one? */
624            if (!private_colormap)
625                    colmap = map;
626            else
627            {
628                    XSetWindowColormap(display, wnd, (Colormap) map);
629                    if (fullscreen)
630                            XInstallColormap(display, (Colormap) map);
631            }
632    }
633    
634    void
635    ui_set_clip(int x, int y, int cx, int cy)
636    {
637            XRectangle rect;
638    
639            rect.x = x;
640            rect.y = y;
641            rect.width = cx;
642            rect.height = cy;
643            XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
644    }
645    
646    void
647    ui_reset_clip()
648    {
649            XRectangle rect;
650    
651            rect.x = 0;
652            rect.y = 0;
653            rect.width = width;
654            rect.height = height;
655            XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
656    }
657    
658    void
659    ui_bell()
660    {
661            XBell(display, 0);
662    }
663    
664    void
665    ui_destblt(uint8 opcode,
666               /* dest */ int x, int y, int cx, int cy)
667    {
668            xwin_set_function(opcode);
669    
670            XFillRectangle(display, wnd, gc, x, y, cx, cy);
671    }
672    
673    void
674    ui_patblt(uint8 opcode,
675              /* dest */ int x, int y, int cx, int cy,
676              /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
677    {
678            Display *dpy = display;
679            Pixmap fill;
680            uint8 i, ipattern[8];
681    
682            xwin_set_function(opcode);
683    
684            switch (brush->style)
685            {
686                    case 0: /* Solid */
687                            XSetForeground(dpy, gc, Ctrans(fgcolour));
688                            XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
689                            break;
690    
691                    case 3: /* Pattern */
692                            for (i = 0; i != 8; i++)
693                                    ipattern[i] = ~brush->pattern[i];
694                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
695    
696                            XSetForeground(dpy, gc, Ctrans(fgcolour));
697                            XSetBackground(dpy, gc, Ctrans(bgcolour));
698                            XSetFillStyle(dpy, gc, FillOpaqueStippled);
699                            XSetStipple(dpy, gc, fill);
700    
701                            XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
702    
703                            XSetFillStyle(dpy, gc, FillSolid);
704                            ui_destroy_glyph((HGLYPH) fill);
705                            break;
706    
707                    default:
708                            NOTIMP("brush %d\n", brush->style);
709            }
710    }
711    
712    void
713    ui_screenblt(uint8 opcode,
714                 /* dest */ int x, int y, int cx, int cy,
715                 /* src */ int srcx, int srcy)
716    {
717            xwin_set_function(opcode);
718    
719            XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
720    }
721    
722    void
723    ui_memblt(uint8 opcode,
724              /* dest */ int x, int y, int cx, int cy,
725              /* src */ HBITMAP src, int srcx, int srcy)
726    {
727            xwin_set_function(opcode);
728    
729            XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
730    }
731    
732    void
733    ui_triblt(uint8 opcode,
734              /* dest */ int x, int y, int cx, int cy,
735              /* src */ HBITMAP src, int srcx, int srcy,
736              /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
737    {
738            /* This is potentially difficult to do in general. Until someone
739               comes up with a more efficient way of doing it I am using cases. */
740    
741            switch (opcode)
742            {
743                    case 0x69:      /* PDSxxn */
744                            ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
745                            ui_patblt(ROP2_NXOR, x, y, cx, cy,
746                                      brush, bgcolour, fgcolour);
747                            break;
748    
749                    case 0xb8:      /* PSDPxax */
750                            ui_patblt(ROP2_XOR, x, y, cx, cy,
751                                      brush, bgcolour, fgcolour);
752                            ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
753                            ui_patblt(ROP2_XOR, x, y, cx, cy,
754                                      brush, bgcolour, fgcolour);
755                            break;
756    
757                    case 0xc0:
758                            ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
759                            ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,
760                                      fgcolour);
761                            break;
762    
763                    default:
764                            NOTIMP("triblt 0x%x\n", opcode);
765                            ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
766            }
767    }
768    
769    void
770    ui_line(uint8 opcode,
771            /* dest */ int startx, int starty, int endx, int endy,
772            /* pen */ PEN *pen)
773    {
774            xwin_set_function(opcode);
775    
776            XSetForeground(display, gc, Ctrans(pen->colour));
777            XDrawLine(display, wnd, gc, startx, starty, endx, endy);
778    }
779    
780    void
781    ui_rect(
782                   /* dest */ int x, int y, int cx, int cy,
783                   /* brush */ int colour)
784    {
785            xwin_set_function(ROP2_COPY);
786    
787            XSetForeground(display, gc, Ctrans(colour));
788            XFillRectangle(display, wnd, gc, x, y, cx, cy);
789    }
790    
791    void
792    ui_draw_glyph(int mixmode,
793                  /* dest */ int x, int y, int cx, int cy,
794                  /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,
795                  int fgcolour)
796    {
797            Pixmap pixmap = (Pixmap) glyph;
798    
799            xwin_set_function(ROP2_COPY);
800    
801    
802            XSetForeground(display, gc, Ctrans(fgcolour));
803            switch (mixmode)
804            {
805                    case MIX_TRANSPARENT:
806                            XSetStipple(display, gc, pixmap);
807                            XSetFillStyle(display, gc, FillStippled);
808                            XSetTSOrigin(display, gc, x, y);
809                            XFillRectangle(display, wnd, gc, x, y, cx, cy);
810                            XSetFillStyle(display, gc, FillSolid);
811                            break;
812    
813                    case MIX_OPAQUE:
814                            XSetBackground(display, gc, Ctrans(bgcolour));
815    /*      XCopyPlane (display, pixmap, back_pixmap, back_gc, srcx, srcy, cx, cy, x, y, 1); */
816                            XSetStipple(display, gc, pixmap);
817                            XSetFillStyle(display, gc, FillOpaqueStippled);
818                            XSetTSOrigin(display, gc, x, y);
819                            XFillRectangle(display, wnd, gc, x, y, cx, cy);
820                            XSetFillStyle(display, gc, FillSolid);
821                            break;
822    
823                    default:
824                            NOTIMP("mix %d\n", mixmode);
825            }
826    }
827    
828    void
829    ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
830                 int clipx, int clipy, int clipcx, int clipcy,
831                 int boxx, int boxy, int boxcx, int boxcy,
832                 int bgcolour, int fgcolour, uint8 *text, uint8 length)
833    {
834            FONTGLYPH *glyph;
835            int i, xyoffset;
836    
837            xwin_set_function(ROP2_COPY);
838            XSetForeground(display, gc, Ctrans(bgcolour));
839    
840            if (boxcx > 1)
841                    XFillRectangle(display, wnd, gc, boxx, boxy, boxcx, boxcy);
842            else if (mixmode == MIX_OPAQUE)
843                    XFillRectangle(display, wnd, gc, clipx, clipy, clipcx, clipcy);
844    
845            /* Paint text, character by character */
846            for (i = 0; i < length; i++)
847            {
848                    glyph = cache_get_font(font, text[i]);
849    
850                    if (!(flags & TEXT2_IMPLICIT_X))
851    
852                    {
853                            xyoffset = text[++i];
854                            if ((xyoffset & 0x80))
855                            {
856                                    if (flags & 0x04)       /* vertical text */
857                                            y += text[++i] | (text[++i] << 8);
858                                    else
859                                            x += text[++i] | (text[++i] << 8);
860                            }
861                            else
862                            {
863                                    if (flags & 0x04)       /* vertical text */
864                                            y += xyoffset;
865                                    else
866                                            x += xyoffset;
867                            }
868    
869                    }
870                    if (glyph != NULL)
871                    {
872                            ui_draw_glyph(mixmode, x + (short) glyph->offset,
873                                          y + (short) glyph->baseline,
874                                          glyph->width, glyph->height,
875                                          glyph->pixmap, 0, 0,
876                                          bgcolour, fgcolour);
877    
878                            if (flags & TEXT2_IMPLICIT_X)
879                                    x += glyph->width;
880                    }
881            }
882    }
883    
884    void
885    ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
886    {
887            Pixmap pix;
888            XImage *image;
889    
890            pix = XCreatePixmap(display, wnd, cx, cy, depth);
891            xwin_set_function(ROP2_COPY);
892    
893            XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
894            image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
895    
896            offset *= bpp/8;
897            cache_put_desktop(offset, cx, cy, image->bytes_per_line,
898                              bpp/8, image->data);
899    
900            XDestroyImage(image);
901            XFreePixmap(display, pix);
902    }
903    
904    void
905    ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
906    {
907            XImage *image;
908            uint8 *data;
909    
910            offset *= bpp/8;
911            data = cache_get_desktop(offset, cx, cy, bpp/8);
912            if (data == NULL)
913                    return;
914            image =
915                    XCreateImage(display, visual,
916                                 depth, ZPixmap,
917                                 0, data, cx, cy, BitmapPad(display),
918                                 cx * bpp/8);
919            xwin_set_function(ROP2_COPY);
920            XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
921            XFree(image);
922    }
923    
924    /* unroll defines, used to make the loops a bit more readable... */
925    #define unroll8Expr(uexp) uexp uexp uexp uexp uexp uexp uexp uexp
926    #define unroll8Lefts(uexp) case 7: uexp \
927            case 6: uexp \
928            case 5: uexp \
929            case 4: uexp \
930            case 3: uexp \
931            case 2: uexp \
932            case 1: uexp
933    
934    static uint8 *
935    translate(int width, int height, uint8 *data)
936    {
937            uint32 i;
938            uint32 size = width * height;
939            uint8 *d2 = xmalloc(size * bpp/8);
940            uint8 *d3 = d2;
941            uint32 pix;
942            i = (size & ~0x7);
943    
944            /* XXX: where are the bits swapped??? */
945    #ifdef L_ENDIAN                 /* little-endian */
946            /* big-endian screen */
947            if (screen_msbfirst)
948            {
949                    switch (bpp)
950                    {
951                            case 32:
952                                    while (i)
953                                    {
954                                            unroll8Expr(pix = colmap[*data++];
955                                                        *d3++ = pix >> 24;
956                                                        *d3++ = pix >> 16;
957                                                        *d3++ = pix >> 8;
958                                                        *d3++ = pix;) i -= 8;
959                                    }
960                                    i = (size & 0x7);
961                                    if (i != 0)
962                                            switch (i)
963                                            {
964                                                            unroll8Lefts(pix =
965                                                                         colmap
966                                                                         [*data++];
967                                                                         *d3++ =
968                                                                         pix >>
969                                                                         24;
970                                                                         *d3++ =
971                                                                         pix >>
972                                                                         16;
973                                                                         *d3++ =
974                                                                         pix >> 8;
975                                                                         *d3++ =
976                                                                         pix;)}
977                                    break;
978                            case 24:
979                                    while (i)
980                                    {
981                                            unroll8Expr(pix = colmap[*data++];
982                                                        *d3++ = pix >> 16;
983                                                        *d3++ = pix >> 8;
984                                                        *d3++ = pix;) i -= 8;
985                                    }
986                                    i = (size & 0x7);
987                                    if (i != 0)
988                                            switch (i)
989                                            {
990                                                            unroll8Lefts(pix =
991                                                                         colmap
992                                                                         [*data++];
993                                                                         *d3++ =
994                                                                         pix >>
995                                                                         16;
996                                                                         *d3++ =
997                                                                         pix >> 8;
998                                                                         *d3++ =
999                                                                         pix;)}
1000                                    break;
1001                            case 16:
1002                                    while (i)
1003                                    {
1004                                            unroll8Expr(pix = colmap[*data++];
1005                                                        *d3++ = pix >> 8;
1006                                                        *d3++ = pix;) i -= 8;
1007                                    }
1008                                    i = (size & 0x7);
1009                                    if (i != 0)
1010                                            switch (i)
1011                                            {
1012                                                            unroll8Lefts(pix =
1013                                                                         colmap
1014                                                                         [*data++];
1015                                                                         *d3++ =
1016                                                                         pix >> 8;
1017                                                                         *d3++ =
1018                                                                         pix;)}
1019                                    break;
1020                            case 8:
1021                                    while (i)
1022                                    {
1023                                            unroll8Expr(pix = colmap[*data++];
1024                                                        *d3++ = pix;
1025                                                    )i -= 8;
1026                                    }
1027                                    i = (size & 0x7);
1028                                    if (i != 0)
1029                                            switch (i)
1030                                            {
1031                                                            unroll8Lefts(pix =
1032                                                                         colmap
1033                                                                         [*data++];
1034                                                                         *d3++ =
1035                                                                         pix;)}
1036                                    break;
1037                    }
1038            }
1039            else
1040            {                       /* little-endian screen */
1041                    switch (bpp)
1042                    {
1043                            case 32:
1044                                    while (i)
1045                                    {
1046                                            unroll8Expr(*((uint32 *) d3) =
1047                                                        colmap[*data++];
1048                                                        d3 += sizeof(uint32);
1049                                                    )i -= 8;
1050                                    }
1051                                    i = (size & 0x7);
1052                                    if (i != 0)
1053                                            switch (i)
1054                                            {
1055                                                            unroll8Lefts(*
1056                                                                         ((uint32
1057                                                                           *) d3)
1058    = colmap[*data++];
1059    d3 += sizeof(uint32);
1060                                            )}
1061                                    break;
1062                            case 24:
1063                                    while (i)
1064                                    {
1065                                            unroll8Expr(pix = colmap[*data++];
1066                                                        *d3++ = pix;
1067                                                        *d3++ = pix >> 8;
1068                                                        *d3++ = pix >> 16;
1069                                                    )i -= 8;
1070                                    }
1071                                    i = (size & 0x7);
1072                                    if (i != 0)
1073                                            switch (i)
1074                                            {
1075                                                            unroll8Lefts(pix =
1076                                                                         colmap
1077                                                                         [*data++];
1078                                                                         *d3++ =
1079                                                                         pix;
1080                                                                         *d3++ =
1081                                                                         pix >> 8;
1082                                                                         *d3++ =
1083                                                                         pix >>
1084                                                                         16;)}
1085                                    break;
1086                            case 16:
1087                                    while (i)
1088                                    {
1089                                            unroll8Expr(pix = colmap[*data++];
1090                                                        *d3++ = pix;
1091                                                        *d3++ = pix >> 8;
1092                                                    )i -= 8;
1093                                    }
1094                                    i = (size & 0x7);
1095                                    if (i != 0)
1096                                            switch (i)
1097                                            {
1098                                                            unroll8Lefts(pix =
1099                                                                         colmap
1100                                                                         [*data++];
1101                                                                         *d3++ =
1102                                                                         pix;
1103                                                                         *d3++ =
1104                                                                         pix >> 8;
1105                                            )}
1106                                    break;
1107                            case 8:
1108                                    while (i)
1109                                    {
1110                                            unroll8Expr(pix = colmap[*data++];
1111                                                        *d3++ = pix;
1112                                                    )i -= 8;
1113                                    }
1114                                    i = (size & 0x7);
1115                                    if (i != 0)
1116                                            switch (i)
1117                                            {
1118                                                            unroll8Lefts(pix =
1119                                                                         colmap
1120                                                                         [*data++];
1121                                                                         *d3++ =
1122                                                                         pix;)}
1123                    }
1124            }
1125    
1126          XPutImage(wnd->display, wnd->wnd, wnd->gc, image,  #else /* bigendian-compiled */
1127                          0, 0, x, y, image->width, image->height);          if (screen_msbfirst)
1128            {
1129                    /* big-endian screen */
1130                    switch (bpp)
1131                    {
1132                            case 32:
1133                                    while (i)
1134                                    {
1135                                            unroll8Expr(*((uint32 *) d3) =
1136                                                        colmap[*data++];
1137                                                        d3 += sizeof(uint32);
1138                                                    )i -= 8;
1139                                    }
1140                                    i = (size & 0x7);
1141                                    if (i != 0)
1142                                            switch (i)
1143                                            {
1144                                                            unroll8Lefts(*
1145                                                                         ((uint32
1146                                                                           *) d3)
1147    = colmap[*data++];
1148    d3 += sizeof(uint32);
1149                                            )}
1150                                    break;
1151                            case 24:
1152                                    while (i)
1153                                    {
1154                                            unroll8Expr(pix = colmap[*data++];
1155                                                        *d3++ = pix;
1156                                                        *d3++ = pix >> 8;
1157                                                        *d3++ = pix >> 16;
1158                                                    )i -= 8;
1159                                    }
1160                                    i = (size & 0x7);
1161                                    if (i != 0)
1162                                            switch (i)
1163                                            {
1164                                                            unroll8Lefts(pix =
1165                                                                         colmap
1166                                                                         [*data++];
1167                                                                         *d3++ =
1168                                                                         pix;
1169                                                                         *d3++ =
1170                                                                         pix >> 8;
1171                                                                         *d3++ =
1172                                                                         pix >>
1173                                                                         16;)}
1174                                    break;
1175                            case 16:
1176                                    while (i)
1177                                    {
1178                                            unroll8Expr(pix = colmap[*data++];
1179                                                        *d3++ = pix;
1180                                                        *d3++ = pix >> 8;
1181                                                    )i -= 8;
1182                                    }
1183                                    i = (size & 0x7);
1184                                    if (i != 0)
1185                                            switch (i)
1186                                            {
1187                                                            unroll8Lefts(pix =
1188                                                                         colmap
1189                                                                         [*data++];
1190                                                                         *d3++ =
1191                                                                         pix;
1192                                                                         *d3++ =
1193                                                                         pix >> 8;
1194                                            )}
1195                                    break;
1196                            case 8:
1197                                    while (i)
1198                                    {
1199                                            unroll8Expr(pix = colmap[*data++];
1200                                                        *d3++ = pix;
1201                                                    )i -= 8;
1202                                    }
1203                                    i = (size & 0x7);
1204                                    if (i != 0)
1205                                            switch (i)
1206                                            {
1207                                                            unroll8Lefts(pix =
1208                                                                         colmap
1209                                                                         [*data++];
1210                                                                         *d3++ =
1211                                                                         pix;)}
1212                    }
1213            }
1214            else
1215            {
1216                    /* little-endian screen */
1217                    switch (bpp)
1218                    {
1219                            case 32:
1220                                    while (i)
1221                                    {
1222                                            unroll8Expr(pix = colmap[*data++];
1223                                                        *d3++ = pix;
1224                                                        *d3++ = pix >> 8;
1225                                                        *d3++ = pix >> 16;
1226                                                        *d3++ = pix >> 24;
1227                                                    )i -= 8;
1228                                    }
1229                                    i = (size & 0x7);
1230                                    if (i != 0)
1231                                            switch (i)
1232                                            {
1233                                                            unroll8Lefts(pix =
1234                                                                         colmap
1235                                                                         [*data++];
1236                                                                         *d3++ =
1237                                                                         pix;
1238                                                                         *d3++ =
1239                                                                         pix >> 8;
1240                                                                         *d3++ =
1241                                                                         pix >>
1242                                                                         16;
1243                                                                         *d3++ =
1244                                                                         pix >>
1245                                                                         24;)}
1246                                    break;
1247                            case 24:
1248                                    while (i)
1249                                    {
1250                                            unroll8Expr(pix = colmap[*data++];
1251                                                        *d3++ = pix;
1252                                                        *d3++ = pix >> 8;
1253                                                        *d3++ = pix >> 16;
1254                                                    )i -= 8;
1255                                    }
1256                                    i = (size & 0x7);
1257                                    if (i != 0)
1258                                            switch (i)
1259                                            {
1260                                                            unroll8Lefts(pix =
1261                                                                         colmap
1262                                                                         [*data++];
1263                                                                         *d3++ =
1264                                                                         pix;
1265                                                                         *d3++ =
1266                                                                         pix >> 8;
1267                                                                         *d3++ =
1268                                                                         pix >>
1269                                                                         16;)}
1270                                    break;
1271                            case 16:
1272                                    while (i)
1273                                    {
1274                                            unroll8Expr(pix = colmap[*data++];
1275                                                        *d3++ = pix;
1276                                                        *d3++ = pix >> 8;
1277                                                    )i -= 8;
1278                                    }
1279                                    i = (size & 0x7);
1280                                    if (i != 0)
1281                                            switch (i)
1282                                            {
1283                                                            unroll8Lefts(pix =
1284                                                                         colmap
1285                                                                         [*data++];
1286                                                                         *d3++ =
1287                                                                         pix;
1288                                                                         *d3++ =
1289                                                                         pix >> 8;
1290                                            )}
1291                                    break;
1292                            case 8:
1293                                    while (i)
1294                                    {
1295                                            unroll8Expr(pix = colmap[*data++];
1296                                                        *d3++ = pix;
1297                                                    )i -= 8;
1298                                    }
1299                                    i = (size & 0x7);
1300                                    if (i != 0)
1301                                            switch (i)
1302                                            {
1303                                                            unroll8Lefts(pix =
1304                                                                         colmap
1305                                                                         [*data++];
1306                                                                         *d3++ =
1307                                                                         pix;)}
1308                    }
1309            }
1310    #endif
1311    
1312          XSync(wnd->display, True);          return d2;
1313  }  }

Legend:
Removed from v.6  
changed lines
  Added in v.28

  ViewVC Help
Powered by ViewVC 1.1.26