/[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 10 by matty, Tue Aug 15 10:23:24 2000 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 <time.h>
23    #include "rdesktop.h"
24    
25    extern int width;
26    extern int height;
27    extern BOOL motion;
28    
29    static Display *display;
30    static Window wnd;
31    static GC gc;
32    static Visual *visual;
33    static XIM IM;
34    
35  HWINDOW ui_create_window(int width, int height)  BOOL ui_create_window(char *title)
36  {  {
37          struct window *wnd;          Screen *screen;
38          Display *display;          XSetWindowAttributes attribs;
39          Window window;          unsigned long input_mask;
40          int black;          int i;
         GC gc;  
41    
42          display = XOpenDisplay(NULL);          display = XOpenDisplay(NULL);
43          if (display == NULL)          if (display == NULL)
44                  return NULL;                  return False;
45    
46            /* Check the screen supports 8-bit depth. */
47            screen = DefaultScreenOfDisplay(display);
48            for (i = 0; i < screen->ndepths; i++)
49                    if (screen->depths[i].depth == 8)
50                            break;
51    
52            if (i >= screen->ndepths)
53            {
54                    ERROR("8-bit depth required (in this version).\n");
55                    XCloseDisplay(display);
56                    return False;
57            }
58    
59            visual = DefaultVisual(display, DefaultScreen(display));
60    
61            attribs.background_pixel = BlackPixel(display, DefaultScreen(display));
62            attribs.backing_store = Always;
63            wnd = XCreateWindow(display, DefaultRootWindow(display),
64                            0, 0, width, height, 0, 8, InputOutput, visual,
65                            CWBackingStore | CWBackPixel, &attribs);
66    
67            XStoreName(display, wnd, title);
68            XMapWindow(display, wnd);
69    
70            input_mask  = KeyPressMask | KeyReleaseMask;
71            input_mask |= ButtonPressMask | ButtonReleaseMask;
72            if (motion)
73                    input_mask |= PointerMotionMask;
74    
75            XSelectInput(display, wnd, input_mask);
76            gc = XCreateGC(display, wnd, 0, NULL);
77    
78            IM = XOpenIM(display, NULL, NULL, NULL);
79            return True;
80    }
81    
82    void ui_destroy_window()
83    {
84            XCloseIM(IM);
85            XFreeGC(display, gc);
86            XDestroyWindow(display, wnd);
87            XCloseDisplay(display);
88    }
89    
90          black = BlackPixel(display, DefaultScreen(display));  static uint8 xwin_translate_key(unsigned long key)
91          window = XCreateSimpleWindow(display, DefaultRootWindow(display),  {
92                                  0, 0, width, height, 0, black, black);          DEBUG("KEY(code=0x%lx)\n", key);
93    
94          XMapWindow(display, window);          if ((key > 8) && (key <= 0x60))
95          XSync(display, True);                  return (key - 8);
96    
97          gc = XCreateGC(display, window, 0, NULL);          switch (key)
98            {
99                    case 0x62: /* left arrow */
100                            return 0x48;
101                    case 0x64: /* up arrow */
102                            return 0x4b;
103                    case 0x66: /* down arrow */
104                            return 0x4d;
105                    case 0x68: /* right arrow */
106                            return 0x50;
107                    case 0x73: /* Windows key */
108                            DEBUG("CHECKPOINT\n");
109            }
110    
111          wnd = xmalloc(sizeof(struct window));          return 0;
         wnd->display = display;  
         wnd->wnd = window;  
         wnd->gc = gc;  
         return wnd;  
112  }  }
113    
114  void ui_destroy_window(HWINDOW wnd)  static uint16 xwin_translate_mouse(unsigned long button)
115  {  {
116          XFreeGC(wnd->display, wnd->gc);          switch (button)
117          XDestroyWindow(wnd->display, wnd->wnd);          {
118          XCloseDisplay(wnd->display);                  case Button1: /* left */
119                            return MOUSE_FLAG_BUTTON1;
120                    case Button2: /* middle */
121                            return MOUSE_FLAG_BUTTON3;
122                    case Button3: /* right */
123                            return MOUSE_FLAG_BUTTON2;
124            }
125    
126            return 0;
127  }  }
128    
129  HBITMAP ui_create_bitmap(HWINDOW wnd, int width, int height, uint8 *data)  void ui_process_events()
130    {
131            XEvent event;
132            uint8 scancode;
133            uint16 button;
134            uint32 ev_time;
135    
136            if (display == NULL)
137                    return;
138    
139            while (XCheckWindowEvent(display, wnd, 0xffffffff, &event))
140            {
141                    ev_time = time(NULL);
142    
143                    switch (event.type)
144                    {
145                            case KeyPress:
146                                    scancode = xwin_translate_key(event.xkey.keycode);
147                                    if (scancode == 0)
148                                            break;
149    
150                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,
151                                                    scancode, 0);
152                                    break;
153    
154                            case KeyRelease:
155                                    scancode = xwin_translate_key(event.xkey.keycode);
156                                    if (scancode == 0)
157                                            break;
158    
159                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
160                                                    KBD_FLAG_DOWN | KBD_FLAG_UP,
161                                                    scancode, 0);
162                                    break;
163    
164                            case ButtonPress:
165                                    button = xwin_translate_mouse(event.xbutton.button);
166    
167                                    if (button == 0)
168                                            break;
169    
170                                    rdp_send_input(ev_time, RDP_INPUT_MOUSE,
171                                                    button | MOUSE_FLAG_DOWN,
172                                                    event.xbutton.x,
173                                                    event.xbutton.y);
174                                    break;
175    
176                            case ButtonRelease:
177                                    button = xwin_translate_mouse(event.xbutton.button);
178                                    if (button == 0)
179                                            break;
180    
181                                    rdp_send_input(ev_time, RDP_INPUT_MOUSE,
182                                                    button,
183                                                    event.xbutton.x,
184                                                    event.xbutton.y);
185                                    break;
186    
187                            case MotionNotify:
188                                    rdp_send_input(ev_time, RDP_INPUT_MOUSE,
189                                                    MOUSE_FLAG_MOVE,
190                                                    event.xmotion.x,
191                                                    event.xmotion.y);
192                    }
193            }
194    }
195    
196    void ui_move_pointer(int x, int y)
197    {
198            XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
199    }
200    
201    HBITMAP ui_create_bitmap(int width, int height, uint8 *data)
202  {  {
203          XImage *image;          XImage *image;
204          Visual *visual;          Pixmap bitmap;
205    
206          visual = DefaultVisual(wnd->display, DefaultScreen(wnd->display));          bitmap = XCreatePixmap(display, wnd, width, height, 8);
         image = XCreateImage(wnd->display, visual, 8, ZPixmap, 0,  
                                 data, width, height, 32, width);  
207    
208          return (HBITMAP)image;          image = XCreateImage(display, visual, 8, ZPixmap, 0,
209                                    data, width, height, 8, width);
210            XSetFunction(display, gc, GXcopy);
211            XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
212            XFree(image);
213            
214            return (HBITMAP)bitmap;
215    }
216    
217    void ui_paint_bitmap(int x, int y, int cx, int cy,
218                            int width, int height, uint8 *data)
219    {
220            XImage *image;
221    
222            image = XCreateImage(display, visual, 8, ZPixmap, 0,
223                                    data, width, height, 8, width);
224            XSetFunction(display, gc, GXcopy);
225            XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
226            XFree(image);
227  }  }
228    
229  void ui_destroy_bitmap(HBITMAP bmp)  void ui_destroy_bitmap(HBITMAP bmp)
230  {  {
231          XDestroyImage((XImage *)bmp);          XFreePixmap(display, (Pixmap)bmp);
232  }  }
233    
234  void ui_paint_bitmap(HWINDOW wnd, HBITMAP bmp, int x, int y)  HGLYPH ui_create_glyph(int width, int height, uint8 *data)
235  {  {
236          XImage *image = (XImage *)bmp;          XImage *image;
237            Pixmap bitmap;
238            int scanline;
239            GC gc;
240    
241            scanline = (width + 7) / 8;
242    
243          XPutImage(wnd->display, wnd->wnd, wnd->gc, image,          bitmap = XCreatePixmap(display, wnd, width, height, 1);
244                          0, 0, x, y, image->width, image->height);          gc = XCreateGC(display, bitmap, 0, NULL);
245    
246            image = XCreateImage(display, visual, 1, ZPixmap, 0,
247                                    data, width, height, 8, scanline);
248            XSetFunction(display, gc, GXcopy);
249            XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
250            XFree(image);
251            XFreeGC(display, gc);
252            
253            return (HGLYPH)bitmap;
254    }
255    
256    void ui_destroy_glyph(HGLYPH glyph)
257    {
258            XFreePixmap(display, (Pixmap)glyph);
259    }
260    
261    HCOLOURMAP ui_create_colourmap(COLOURMAP *colours)
262    {
263            COLOURENTRY *entry;
264            XColor *xcolours, *xentry;
265            Colormap map;
266            int i, ncolours = colours->ncolours;
267    
268            xcolours = xmalloc(sizeof(XColor) * ncolours);
269            for (i = 0; i < ncolours; i++)
270            {
271                    entry = &colours->colours[i];
272                    xentry = &xcolours[i];
273    
274                    xentry->pixel = i;
275                    xentry->red = entry->red << 8;
276                    xentry->blue = entry->blue << 8;
277                    xentry->green = entry->green << 8;
278                    xentry->flags = DoRed | DoBlue | DoGreen;
279            }
280    
281            map = XCreateColormap(display, wnd, visual, AllocAll);
282            XStoreColors(display, map, xcolours, ncolours);
283    
284            xfree(xcolours);
285            return (HCOLOURMAP)map;
286    }
287    
288    void ui_destroy_colourmap(HCOLOURMAP map)
289    {
290            XFreeColormap(display, (Colormap)map);
291    }
292    
293    void ui_set_colourmap(HCOLOURMAP map)
294    {
295            XSetWindowColormap(display, wnd, (Colormap)map);
296    }
297    
298    void ui_set_clip(int x, int y, int cx, int cy)
299    {
300            XRectangle rect;
301    
302            rect.x = x;
303            rect.y = y;
304            rect.width = cx;
305            rect.height = cy;
306            XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
307    }
308    
309    void ui_reset_clip()
310    {
311            XRectangle rect;
312    
313            rect.x = 0;
314            rect.y = 0;
315            rect.width = width;
316            rect.height = height;
317            XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
318    }
319    
320    void ui_bell()
321    {
322            XBell(display, 0);
323    }
324    
325    static int rop2_map[] = {
326            GXclear,        /* 0 */
327            GXnor,          /* DPon */
328            GXandInverted,  /* DPna */
329            GXcopyInverted, /* Pn */
330            GXandReverse,   /* PDna */
331            GXinvert,       /* Dn */
332            GXxor,          /* DPx */
333            GXnand,         /* DPan */
334            GXand,          /* DPa */
335            GXequiv,        /* DPxn */
336            GXnoop,         /* D */
337            GXorInverted,   /* DPno */
338            GXcopy,         /* P */
339            GXorReverse,    /* PDno */
340            GXor,           /* DPo */
341            GXset           /* 1 */
342    };
343    
344    static void xwin_set_function(uint8 rop2)
345    {
346            XSetFunction(display, gc, rop2_map[rop2]);
347    }
348    
349    void ui_destblt(uint8 opcode,
350            /* dest */  int x, int y, int cx, int cy)
351    {
352            xwin_set_function(opcode);
353    
354            XFillRectangle(display, wnd, gc, x, y, cx, cy);
355    }
356    
357    void ui_patblt(uint8 opcode,
358            /* dest */  int x, int y, int cx, int cy,
359            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
360    {
361            Display *dpy = display;
362            Pixmap fill;
363    
364            xwin_set_function(opcode);
365    
366            switch (brush->style)
367            {
368                    case 0: /* Solid */
369                            XSetForeground(dpy, gc, fgcolour);
370                            XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
371                            break;
372    
373                    case 3: /* Pattern */
374                            fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);
375    
376                            XSetForeground(dpy, gc, fgcolour);
377                            XSetBackground(dpy, gc, bgcolour);
378                            XSetFillStyle(dpy, gc, FillOpaqueStippled);
379                            XSetStipple(dpy, gc, fill);
380    
381                            XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
382    
383                            XSetFillStyle(dpy, gc, FillSolid);
384                            ui_destroy_glyph((HGLYPH)fill);
385                            break;
386    
387                    default:
388                            NOTIMP("brush %d\n", brush->style);
389            }
390    }
391    
392    void ui_screenblt(uint8 opcode,
393                    /* dest */ int x, int y, int cx, int cy,
394                    /* src */  int srcx, int srcy)
395    {
396            xwin_set_function(opcode);
397    
398            XCopyArea(display, wnd, wnd, gc, srcx, srcy,
399                            cx, cy, x, y);
400    }
401    
402    void ui_memblt(uint8 opcode,
403            /* dest */  int x, int y, int cx, int cy,
404            /* src */   HBITMAP src, int srcx, int srcy)
405    {
406            xwin_set_function(opcode);
407    
408            XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy,
409                            cx, cy, x, y);
410    }
411    
412    void ui_triblt(uint8 opcode,
413            /* dest */  int x, int y, int cx, int cy,
414            /* src */   HBITMAP src, int srcx, int srcy,
415            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
416    {
417            /* This is potentially difficult to do in general. Until someone
418               comes up with a more efficient way of doing it I am using cases. */
419    
420            switch (opcode)
421            {
422                    case 0xb8: /* PSDPxax */
423                            ui_patblt(ROP2_XOR, x, y, cx, cy,
424                                            brush, bgcolour, fgcolour);
425                            ui_memblt(ROP2_AND, x, y, cx, cy,
426                                            src, srcx, srcy);
427                            ui_patblt(ROP2_XOR, x, y, cx, cy,
428                                            brush, bgcolour, fgcolour);
429                            break;
430    
431                    default:
432                            NOTIMP("triblt 0x%x\n", opcode);
433                            ui_memblt(ROP2_COPY, x, y, cx, cy,
434                                            brush, bgcolour, fgcolour);
435            }
436    }
437    
438    void ui_line(uint8 opcode,
439            /* dest */  int startx, int starty, int endx, int endy,
440            /* pen */   PEN *pen)
441    {
442            xwin_set_function(opcode);
443    
444            XSetForeground(display, gc, pen->colour);
445            XDrawLine(display, wnd, gc, startx, starty, endx, endy);
446    }
447    
448    void ui_rect(
449            /* dest */  int x, int y, int cx, int cy,
450            /* brush */ int colour)
451    {
452            xwin_set_function(ROP2_COPY);
453    
454            XSetForeground(display, gc, colour);
455            XFillRectangle(display, wnd, gc, x, y, cx, cy);
456    }
457    
458    void ui_draw_glyph(int mixmode,
459            /* dest */ int x, int y, int cx, int cy,
460            /* src */  HGLYPH glyph, int srcx, int srcy, int bgcolour, int fgcolour)
461    {
462            Pixmap pixmap = (Pixmap)glyph;
463    
464            xwin_set_function(ROP2_COPY);
465    
466            XSetForeground(display, gc, fgcolour);
467    
468            switch (mixmode)
469            {
470                    case MIX_TRANSPARENT:
471                            XSetStipple(display, gc, pixmap);
472                            XSetFillStyle(display, gc, FillStippled);
473                            XSetTSOrigin(display, gc, x, y);
474                            XFillRectangle(display, wnd, gc,
475                                            x, y, cx, cy);
476                            XSetFillStyle(display, gc, FillSolid);
477                            break;
478    
479                    case MIX_OPAQUE:
480                            XSetBackground(display, gc, bgcolour);
481                            XCopyPlane(display, pixmap, wnd, gc,
482                                            srcx, srcy, cx, cy, x, y, 1);
483                            break;
484    
485                    default:
486                            NOTIMP("mix %d\n", mixmode);
487            }
488    }
489    
490    void ui_draw_text(uint8 font, uint8 flags, int mixmode, int x,
491                            int y, int boxx, int boxy, int boxcx, int boxcy,
492                            int bgcolour, int fgcolour, uint8 *text, uint8 length)
493    {
494            FONTGLYPH *glyph;
495            int i;
496    
497            if (boxcx > 1)
498            {
499                    ui_rect(boxx, boxy, boxcx, boxcy, bgcolour);
500            }
501    
502            /* Paint text, character by character */
503            for (i = 0; i < length; i++)
504            {
505                    glyph = cache_get_font(font, text[i]);
506    
507                    if (glyph != NULL)
508                    {
509                            ui_draw_glyph(mixmode, x,
510                                            y + (short)glyph->baseline,
511                                            glyph->width, glyph->height,
512                                            glyph->pixmap, 0, 0,
513                                            bgcolour, fgcolour);
514    
515                            if (flags & TEXT2_IMPLICIT_X)
516                                    x += glyph->width;
517                            else
518                                    x += text[++i];
519                    }
520            }
521    }
522    
523    void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
524    {
525            XImage *image;
526            int scanline;
527    
528            scanline = (cx + 3) & ~3;
529            STATUS("XGetImage(%p,%x,%d,%d,%d,%d,%x,%d)\n", display, wnd, x, y,
530                    cx, cy, 0xffffffff, ZPixmap);
531            image = XGetImage(display, wnd, x, y, cx, cy, 0xffffffff, ZPixmap);
532            cache_put_desktop(offset, scanline*cy, image->data);
533            XFree(image->data);
534            XFree(image);
535    }
536    
537    void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
538    {
539            XImage *image;
540            int scanline;
541            uint8 *data;
542    
543          XSync(wnd->display, True);          scanline = (cx + 3) & ~3;
544            data = cache_get_desktop(offset, scanline*cy);
545            if (data == NULL)
546                    return;
547    
548            image = XCreateImage(display, visual, 8, ZPixmap, 0,
549                                    data, cx, cy, 32, scanline);
550            XSetFunction(display, gc, GXcopy);
551            XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
552            XFree(image);
553  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26