/[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 16 by matty, Thu Sep 28 07:04:14 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    static uint8 xwin_translate_key(unsigned long key)
91    {
92            DEBUG("KEY(code=0x%lx)\n", key);
93    
94            if ((key > 8) && (key <= 0x60))
95                    return (key - 8);
96    
97            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            return 0;
112    }
113    
114          black = BlackPixel(display, DefaultScreen(display));  static uint16 xwin_translate_mouse(unsigned long button)
115          window = XCreateSimpleWindow(display, DefaultRootWindow(display),  {
116                                  0, 0, width, height, 0, black, black);          switch (button)
117            {
118                    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          XMapWindow(display, window);          return 0;
127          XSync(display, True);  }
128    
129          gc = XCreateGC(display, window, 0, NULL);  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          wnd = xmalloc(sizeof(struct window));          while (XCheckWindowEvent(display, wnd, 0xffffffff, &event))
140          wnd->display = display;          {
141          wnd->wnd = window;                  ev_time = time(NULL);
         wnd->gc = gc;  
         wnd->visual = DefaultVisual(wnd->display, DefaultScreen(wnd->display));  
142    
143          return wnd;                  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_destroy_window(HWINDOW wnd)  void ui_move_pointer(int x, int y)
197  {  {
198          XFreeGC(wnd->display, wnd->gc);          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
         XDestroyWindow(wnd->display, wnd->wnd);  
         XCloseDisplay(wnd->display);  
199  }  }
200    
201  HBITMAP ui_create_bitmap(HWINDOW wnd, int width, int height, uint8 *data)  HBITMAP ui_create_bitmap(int width, int height, uint8 *data)
202  {  {
203          XImage *image;          XImage *image;
204            Pixmap bitmap;
205    
206          image = XCreateImage(wnd->display, wnd->visual, 8, ZPixmap, 0,          bitmap = XCreatePixmap(display, wnd, width, height, 8);
207                                  data, width, height, 32, width);  
208            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          return (HBITMAP)image;          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(HWINDOW wnd, 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          XPutImage(wnd->display, wnd->wnd, wnd->gc, image,          scanline = (width + 7) / 8;
                         0, 0, x, y, image->width, image->height);  
242    
243          XSync(wnd->display, True);          bitmap = XCreatePixmap(display, wnd, width, height, 1);
244            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  HCOLORMAP ui_create_colormap(HWINDOW wnd, COLORMAP *colors)  void ui_destroy_glyph(HGLYPH glyph)
257  {  {
258          COLORENTRY *entry;          XFreePixmap(display, (Pixmap)glyph);
259          XColor *xcolors, *xentry;  }
260    
261    HCOLOURMAP ui_create_colourmap(COLOURMAP *colours)
262    {
263            COLOURENTRY *entry;
264            XColor *xcolours, *xentry;
265          Colormap map;          Colormap map;
266          int i, ncolors = colors->ncolors;          int i, ncolours = colours->ncolours;
267    
268          xcolors = malloc(sizeof(XColor) * ncolors);          xcolours = xmalloc(sizeof(XColor) * ncolours);
269          for (i = 0; i < ncolors; i++)          for (i = 0; i < ncolours; i++)
270          {          {
271                  entry = &colors->colors[i];                  entry = &colours->colours[i];
272                  xentry = &xcolors[i];                  xentry = &xcolours[i];
273    
274                  xentry->pixel = i;                  xentry->pixel = i;
275                  xentry->red = entry->red << 8;                  xentry->red = entry->red << 8;
# Line 102  HCOLORMAP ui_create_colormap(HWINDOW wnd Line 278  HCOLORMAP ui_create_colormap(HWINDOW wnd
278                  xentry->flags = DoRed | DoBlue | DoGreen;                  xentry->flags = DoRed | DoBlue | DoGreen;
279          }          }
280    
281          map = XCreateColormap(wnd->display, wnd->wnd, wnd->visual, AllocAll);          map = XCreateColormap(display, wnd, visual, AllocAll);
282          XStoreColors(wnd->display, map, xcolors, ncolors);          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          free(xcolors);  void ui_set_clip(int x, int y, int cx, int cy)
299          return (HCOLORMAP)map;  {
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_destroy_colormap(HWINDOW wnd, HCOLORMAP map)  void ui_reset_clip()
310  {  {
311          XFreeColormap(wnd->display, (Colormap)map);          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_set_colormap(HWINDOW wnd, HCOLORMAP map)  void ui_bell()
321  {  {
322          XSetWindowColormap(wnd->display, wnd->wnd, (Colormap)map);          XBell(display, 0);
323  }  }
324    
325  void ui_draw_rectangle(HWINDOW wnd, int x, int y, int width, int height)  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          static int white = 0;          XSetFunction(display, gc, rop2_map[rop2]);
347    }
348    
349          XSetForeground(wnd->display, wnd->gc, white);  void ui_destblt(uint8 opcode,
350          XFillRectangle(wnd->display, wnd->wnd, wnd->gc, x, y, width, height);          /* dest */  int x, int y, int cx, int cy)
351    {
352            xwin_set_function(opcode);
353    
354          white++;          XFillRectangle(display, wnd, gc, x, y, cx, cy);
355  }  }
356    
357  void ui_move_pointer(HWINDOW wnd, int x, int y)  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          XWarpPointer(wnd->display, wnd->wnd, wnd->wnd, 0, 0, 0, 0, x, y);          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 0x69: /* PDSxxn */
423                            ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
424                            ui_patblt(ROP2_NXOR, x, y, cx, cy,
425                                            brush, bgcolour, fgcolour);
426                            break;
427    
428                    case 0xb8: /* PSDPxax */
429                            ui_patblt(ROP2_XOR, x, y, cx, cy,
430                                            brush, bgcolour, fgcolour);
431                            ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
432                            ui_patblt(ROP2_XOR, x, y, cx, cy,
433                                            brush, bgcolour, fgcolour);
434                            break;
435    
436                    default:
437                            NOTIMP("triblt 0x%x\n", opcode);
438                            ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
439            }
440    }
441    
442    void ui_line(uint8 opcode,
443            /* dest */  int startx, int starty, int endx, int endy,
444            /* pen */   PEN *pen)
445    {
446            xwin_set_function(opcode);
447    
448            XSetForeground(display, gc, pen->colour);
449            XDrawLine(display, wnd, gc, startx, starty, endx, endy);
450    }
451    
452    void ui_rect(
453            /* dest */  int x, int y, int cx, int cy,
454            /* brush */ int colour)
455    {
456            xwin_set_function(ROP2_COPY);
457    
458            XSetForeground(display, gc, colour);
459            XFillRectangle(display, wnd, gc, x, y, cx, cy);
460    }
461    
462    void ui_draw_glyph(int mixmode,
463            /* dest */ int x, int y, int cx, int cy,
464            /* src */  HGLYPH glyph, int srcx, int srcy, int bgcolour, int fgcolour)
465    {
466            Pixmap pixmap = (Pixmap)glyph;
467    
468            xwin_set_function(ROP2_COPY);
469    
470            XSetForeground(display, gc, fgcolour);
471    
472            switch (mixmode)
473            {
474                    case MIX_TRANSPARENT:
475                            XSetStipple(display, gc, pixmap);
476                            XSetFillStyle(display, gc, FillStippled);
477                            XSetTSOrigin(display, gc, x, y);
478                            XFillRectangle(display, wnd, gc,
479                                            x, y, cx, cy);
480                            XSetFillStyle(display, gc, FillSolid);
481                            break;
482    
483                    case MIX_OPAQUE:
484                            XSetBackground(display, gc, bgcolour);
485                            XCopyPlane(display, pixmap, wnd, gc,
486                                            srcx, srcy, cx, cy, x, y, 1);
487                            break;
488    
489                    default:
490                            NOTIMP("mix %d\n", mixmode);
491            }
492    }
493    
494    void ui_draw_text(uint8 font, uint8 flags, int mixmode, int x,
495                            int y, int boxx, int boxy, int boxcx, int boxcy,
496                            int bgcolour, int fgcolour, uint8 *text, uint8 length)
497    {
498            FONTGLYPH *glyph;
499            int i;
500    
501            if (boxcx > 1)
502            {
503                    ui_rect(boxx, boxy, boxcx, boxcy, bgcolour);
504            }
505    
506            /* Paint text, character by character */
507            for (i = 0; i < length; i++)
508            {
509                    glyph = cache_get_font(font, text[i]);
510    
511                    if (glyph != NULL)
512                    {
513                            ui_draw_glyph(mixmode, x,
514                                            y + (short)glyph->baseline,
515                                            glyph->width, glyph->height,
516                                            glyph->pixmap, 0, 0,
517                                            bgcolour, fgcolour);
518    
519                            if (flags & TEXT2_IMPLICIT_X)
520                                    x += glyph->width;
521                            else
522                                    x += text[++i];
523                    }
524            }
525    }
526    
527    void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
528    {
529            XImage *image;
530    
531            image = XGetImage(display, wnd, x, y, cx, cy, 0xffffffff, ZPixmap);
532            cache_put_desktop(offset, cx, cy, image->bytes_per_line, 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            uint8 *data;
541    
542            data = cache_get_desktop(offset, cx, cy);
543            if (data == NULL)
544                    return;
545    
546            image = XCreateImage(display, visual, 8, ZPixmap, 0,
547                                    data, cx, cy, 32, cx);
548            XSetFunction(display, gc, GXcopy);
549            XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
550            XFree(image);
551  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26