/[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 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    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  HWINDOW ui_create_window(int width, int height)  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                  return NULL;          {
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          black = BlackPixel(display, DefaultScreen(display));  void
402          window = XCreateSimpleWindow(display, DefaultRootWindow(display),  ui_destroy_bitmap(HBITMAP bmp)
403                                  0, 0, width, height, 0, black, black);  {
404            XFreePixmap(display, (Pixmap) bmp);
405    }
406    
407          XMapWindow(display, window);  HCURSOR
408          XSync(display, True);  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;
429            }
430            i = (height - 1) * scanlinelen;
431    
432            if (!screen_msbfirst)
433            {
434                    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    
         gc = XCreateGC(display, window, 0, NULL);  
461    
462          wnd = xmalloc(sizeof(struct window));          fg.red = 0;
463          wnd->display = display;          fg.blue = 0;
464          wnd->wnd = window;          fg.green = 0;
465          wnd->gc = gc;          fg.flags = DoRed | DoBlue | DoGreen;
466          wnd->visual = DefaultVisual(wnd->display, DefaultScreen(wnd->display));          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                                    {
488                                            XPutPixel(imagecursor, x1, y1, 0);
489                                            XPutPixel(imagemask, x1, y1, 0);        /* mask is blank for text cursor! */
490                                    }
491    
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          return wnd;  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            Pixmap bitmap;
533            int scanline;
534            GC gc;
535    
536            scanline = (width + 7) / 8;
537    
538            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
556    ui_destroy_glyph(HGLYPH glyph)
557    {
558            XFreePixmap(display, (Pixmap) glyph);
559    }
560    
561    HCOLOURMAP
562    ui_create_colourmap(COLOURMAP *colours)
563    {
564            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          image = XCreateImage(wnd->display, wnd->visual, 8, ZPixmap, 0,          /* XXX, change values of all pixels on the screen if the new colmap
623                                  data, width, height, 32, width);           * 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          return (HBITMAP)image;          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 ui_destroy_bitmap(HWINDOW wnd, HBITMAP bmp)  void
647    ui_reset_clip()
648  {  {
649          XDestroyImage((XImage *)bmp);          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 ui_paint_bitmap(HWINDOW wnd, HBITMAP bmp, int x, int y)  void
659    ui_bell()
660  {  {
661          XImage *image = (XImage *)bmp;          XBell(display, 0);
662    }
663    
664          XPutImage(wnd->display, wnd->wnd, wnd->gc, image,  void
665                          0, 0, x, y, image->width, image->height);  ui_destblt(uint8 opcode,
666               /* dest */ int x, int y, int cx, int cy)
667    {
668            xwin_set_function(opcode);
669    
670          XSync(wnd->display, True);          XFillRectangle(display, wnd, gc, x, y, cx, cy);
671  }  }
672    
673  HCOLORMAP ui_create_colormap(HWINDOW wnd, COLORMAP *colors)  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          COLORENTRY *entry;          Display *dpy = display;
679          XColor *xcolors, *xentry;          Pixmap fill;
680          Colormap map;          uint8 i, ipattern[8];
         int i, ncolors = colors->ncolors;  
681    
682          xcolors = malloc(sizeof(XColor) * ncolors);          xwin_set_function(opcode);
683          for (i = 0; i < ncolors; i++)  
684            switch (brush->style)
685          {          {
686                  entry = &colors->colors[i];                  case 0: /* Solid */
687                  xentry = &xcolors[i];                          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                  xentry->pixel = i;  void
723                  xentry->red = entry->red << 8;  ui_memblt(uint8 opcode,
724                  xentry->blue = entry->blue << 8;            /* dest */ int x, int y, int cx, int cy,
725                  xentry->green = entry->green << 8;            /* src */ HBITMAP src, int srcx, int srcy)
726                  xentry->flags = DoRed | DoBlue | DoGreen;  {
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          map = XCreateColormap(wnd->display, wnd->wnd, wnd->visual, AllocAll);  void
781          XStoreColors(wnd->display, map, xcolors, ncolors);  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          free(xcolors);          XSetForeground(display, gc, Ctrans(colour));
788          return (HCOLORMAP)map;          XFillRectangle(display, wnd, gc, x, y, cx, cy);
789  }  }
790    
791  void ui_destroy_colormap(HWINDOW wnd, HCOLORMAP map)  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          XFreeColormap(wnd->display, (Colormap)map);          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 ui_set_colormap(HWINDOW wnd, HCOLORMAP map)  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          XSetWindowColormap(wnd->display, wnd->wnd, (Colormap)map);          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 ui_draw_rectangle(HWINDOW wnd, int x, int y, int width, int height)  void
885    ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
886  {  {
887          static int white = 0;          Pixmap pix;
888            XImage *image;
889    
890            pix = XCreatePixmap(display, wnd, cx, cy, depth);
891            xwin_set_function(ROP2_COPY);
892    
893          XSetForeground(wnd->display, wnd->gc, white);          XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
894          XFillRectangle(wnd->display, wnd->wnd, wnd->gc, x, y, width, height);          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          white++;          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  void ui_move_pointer(HWINDOW wnd, int x, int y)  /* 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          XWarpPointer(wnd->display, wnd->wnd, wnd->wnd, 0, 0, 0, 0, x, y);          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    #else /* bigendian-compiled */
1127            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            return d2;
1313  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26