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

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

  ViewVC Help
Powered by ViewVC 1.1.26