/[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 17 by matty, Thu Sep 28 15:54:11 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 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, int y,
495                            int clipx, int clipy, int clipcx, int clipcy,
496                            int boxx, int boxy, int boxcx, int boxcy,
497                            int bgcolour, int fgcolour, uint8 *text, uint8 length)
498    {
499            FONTGLYPH *glyph;
500            int i;
501    
502            if (boxcx > 1)
503            {
504                    ui_rect(boxx, boxy, boxcx, boxcy, bgcolour);
505            }
506            else if (mixmode == MIX_OPAQUE)
507            {
508                    ui_rect(clipx, clipy, clipcx, clipcy, bgcolour);
509            }
510    
511            /* Paint text, character by character */
512            for (i = 0; i < length; i++)
513            {
514                    glyph = cache_get_font(font, text[i]);
515    
516                    if (!(flags & TEXT2_IMPLICIT_X))
517                            x += text[++i];
518    
519                    if (glyph != NULL)
520                    {
521                            ui_draw_glyph(mixmode, x,
522                                            y + (short)glyph->baseline,
523                                            glyph->width, glyph->height,
524                                            glyph->pixmap, 0, 0,
525                                            bgcolour, fgcolour);
526    
527                            if (flags & TEXT2_IMPLICIT_X)
528                                    x += glyph->width;
529                    }
530            }
531    }
532    
533    void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
534    {
535            XImage *image;
536    
537            image = XGetImage(display, wnd, x, y, cx, cy, 0xffffffff, ZPixmap);
538            cache_put_desktop(offset, cx, cy, image->bytes_per_line, image->data);
539            XFree(image->data);
540            XFree(image);
541    }
542    
543    void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
544    {
545            XImage *image;
546            uint8 *data;
547    
548          XSync(wnd->display, True);          data = cache_get_desktop(offset, cx, cy);
549            if (data == NULL)
550                    return;
551    
552            image = XCreateImage(display, visual, 8, ZPixmap, 0,
553                                    data, cx, cy, 32, cx);
554            XSetFunction(display, gc, GXcopy);
555            XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
556            XFree(image);
557  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26