/[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 23 by matty, Tue Oct 17 08:24:09 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            attribs.background_pixel = BlackPixel(display, DefaultScreen(display));
65            attribs.backing_store = Always;
66            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            XSelectInput(display, wnd, input_mask);
79            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          black = BlackPixel(display, DefaultScreen(display));  static uint16 xwin_translate_mouse(unsigned long button)
118          window = XCreateSimpleWindow(display, DefaultRootWindow(display),  {
119                                  0, 0, width, height, 0, black, black);          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          XMapWindow(display, window);          return 0;
130          XSync(display, True);  }
131    
132          gc = XCreateGC(display, window, 0, NULL);  void ui_process_events()
133    {
134            XEvent event;
135            uint8 scancode;
136            uint16 button;
137            uint32 ev_time;
138    
139          wnd = xmalloc(sizeof(struct window));          if (display == NULL)
140          wnd->display = display;                  return;
141          wnd->wnd = window;  
142          wnd->gc = gc;          while (XCheckWindowEvent(display, wnd, 0xffffffff, &event))
143          return wnd;          {
144                    ev_time = time(NULL);
145    
146                    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          Visual *visual;          Pixmap bitmap;
208    
209          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);  
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_paint_bitmap(int x, int y, int cx, int cy,
221                            int width, int height, uint8 *data)
222    {
223            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_destroy_bitmap(HBITMAP bmp)  void ui_destroy_bitmap(HBITMAP bmp)
233  {  {
234          XDestroyImage((XImage *)bmp);          XFreePixmap(display, (Pixmap)bmp);
235    }
236    
237    HGLYPH ui_create_glyph(int width, int height, uint8 *data)
238    {
239            XImage *image;
240            Pixmap bitmap;
241            int scanline;
242            GC gc;
243    
244            scanline = (width + 7) / 8;
245    
246            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            image->byte_order = MSBFirst;
252            image->bitmap_bit_order = MSBFirst;
253            XInitImage(image);
254    
255            XSetFunction(display, gc, GXcopy);
256            XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
257            XFree(image);
258            XFreeGC(display, gc);
259            
260            return (HGLYPH)bitmap;
261    }
262    
263    void ui_destroy_glyph(HGLYPH glyph)
264    {
265            XFreePixmap(display, (Pixmap)glyph);
266    }
267    
268    HCOLOURMAP ui_create_colourmap(COLOURMAP *colours)
269    {
270            COLOURENTRY *entry;
271            XColor *xcolours, *xentry;
272            Colormap map;
273            int i, ncolours = colours->ncolours;
274    
275            xcolours = xmalloc(sizeof(XColor) * ncolours);
276            for (i = 0; i < ncolours; i++)
277            {
278                    entry = &colours->colours[i];
279                    xentry = &xcolours[i];
280    
281                    xentry->pixel = i;
282                    xentry->red = entry->red << 8;
283                    xentry->blue = entry->blue << 8;
284                    xentry->green = entry->green << 8;
285                    xentry->flags = DoRed | DoBlue | DoGreen;
286            }
287    
288            map = XCreateColormap(display, wnd, visual, AllocAll);
289            XStoreColors(display, map, xcolours, ncolours);
290    
291            xfree(xcolours);
292            return (HCOLOURMAP)map;
293    }
294    
295    void ui_destroy_colourmap(HCOLOURMAP map)
296    {
297            XFreeColormap(display, (Colormap)map);
298    }
299    
300    void ui_set_colourmap(HCOLOURMAP map)
301    {
302            XSetWindowColormap(display, wnd, (Colormap)map);
303    }
304    
305    void ui_set_clip(int x, int y, int cx, int cy)
306    {
307            XRectangle rect;
308    
309            rect.x = x;
310            rect.y = y;
311            rect.width = cx;
312            rect.height = cy;
313            XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
314    }
315    
316    void ui_reset_clip()
317    {
318            XRectangle rect;
319    
320            rect.x = 0;
321            rect.y = 0;
322            rect.width = width;
323            rect.height = height;
324            XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
325    }
326    
327    void ui_bell()
328    {
329            XBell(display, 0);
330    }
331    
332    static int rop2_map[] = {
333            GXclear,        /* 0 */
334            GXnor,          /* DPon */
335            GXandInverted,  /* DPna */
336            GXcopyInverted, /* Pn */
337            GXandReverse,   /* PDna */
338            GXinvert,       /* Dn */
339            GXxor,          /* DPx */
340            GXnand,         /* DPan */
341            GXand,          /* DPa */
342            GXequiv,        /* DPxn */
343            GXnoop,         /* D */
344            GXorInverted,   /* DPno */
345            GXcopy,         /* P */
346            GXorReverse,    /* PDno */
347            GXor,           /* DPo */
348            GXset           /* 1 */
349    };
350    
351    static void xwin_set_function(uint8 rop2)
352    {
353            XSetFunction(display, gc, rop2_map[rop2]);
354    }
355    
356    void ui_destblt(uint8 opcode,
357            /* dest */  int x, int y, int cx, int cy)
358    {
359            xwin_set_function(opcode);
360    
361            XFillRectangle(display, wnd, gc, x, y, cx, cy);
362    }
363    
364    void ui_patblt(uint8 opcode,
365            /* dest */  int x, int y, int cx, int cy,
366            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
367    {
368            Display *dpy = display;
369            Pixmap fill;
370    
371            xwin_set_function(opcode);
372    
373            switch (brush->style)
374            {
375                    case 0: /* Solid */
376                            XSetForeground(dpy, gc, fgcolour);
377                            XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
378                            break;
379    
380                    case 3: /* Pattern */
381                            fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);
382    
383                            XSetForeground(dpy, gc, fgcolour);
384                            XSetBackground(dpy, gc, bgcolour);
385                            XSetFillStyle(dpy, gc, FillOpaqueStippled);
386                            XSetStipple(dpy, gc, fill);
387    
388                            XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
389    
390                            XSetFillStyle(dpy, gc, FillSolid);
391                            ui_destroy_glyph((HGLYPH)fill);
392                            break;
393    
394                    default:
395                            NOTIMP("brush %d\n", brush->style);
396            }
397    }
398    
399    void ui_screenblt(uint8 opcode,
400                    /* dest */ int x, int y, int cx, int cy,
401                    /* src */  int srcx, int srcy)
402    {
403            xwin_set_function(opcode);
404    
405            XCopyArea(display, wnd, wnd, gc, srcx, srcy,
406                            cx, cy, x, y);
407    }
408    
409    void ui_memblt(uint8 opcode,
410            /* dest */  int x, int y, int cx, int cy,
411            /* src */   HBITMAP src, int srcx, int srcy)
412    {
413            xwin_set_function(opcode);
414    
415            XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy,
416                            cx, cy, x, y);
417    }
418    
419    void ui_triblt(uint8 opcode,
420            /* dest */  int x, int y, int cx, int cy,
421            /* src */   HBITMAP src, int srcx, int srcy,
422            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
423    {
424            /* This is potentially difficult to do in general. Until someone
425               comes up with a more efficient way of doing it I am using cases. */
426    
427            switch (opcode)
428            {
429                    case 0x69: /* PDSxxn */
430                            ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
431                            ui_patblt(ROP2_NXOR, x, y, cx, cy,
432                                            brush, bgcolour, fgcolour);
433                            break;
434    
435                    case 0xb8: /* PSDPxax */
436                            ui_patblt(ROP2_XOR, x, y, cx, cy,
437                                            brush, bgcolour, fgcolour);
438                            ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
439                            ui_patblt(ROP2_XOR, x, y, cx, cy,
440                                            brush, bgcolour, fgcolour);
441                            break;
442    
443                    default:
444                            NOTIMP("triblt 0x%x\n", opcode);
445                            ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
446            }
447    }
448    
449    void ui_line(uint8 opcode,
450            /* dest */  int startx, int starty, int endx, int endy,
451            /* pen */   PEN *pen)
452    {
453            xwin_set_function(opcode);
454    
455            XSetForeground(display, gc, pen->colour);
456            XDrawLine(display, wnd, gc, startx, starty, endx, endy);
457    }
458    
459    void ui_rect(
460            /* dest */  int x, int y, int cx, int cy,
461            /* brush */ int colour)
462    {
463            xwin_set_function(ROP2_COPY);
464    
465            XSetForeground(display, gc, colour);
466            XFillRectangle(display, wnd, gc, x, y, cx, cy);
467    }
468    
469    void ui_draw_glyph(int mixmode,
470            /* dest */ int x, int y, int cx, int cy,
471            /* src */  HGLYPH glyph, int srcx, int srcy, int bgcolour, int fgcolour)
472    {
473            Pixmap pixmap = (Pixmap)glyph;
474    
475            xwin_set_function(ROP2_COPY);
476    
477            XSetForeground(display, gc, fgcolour);
478    
479            switch (mixmode)
480            {
481                    case MIX_TRANSPARENT:
482                            XSetStipple(display, gc, pixmap);
483                            XSetFillStyle(display, gc, FillStippled);
484                            XSetTSOrigin(display, gc, x, y);
485                            XFillRectangle(display, wnd, gc,
486                                            x, y, cx, cy);
487                            XSetFillStyle(display, gc, FillSolid);
488                            break;
489    
490                    case MIX_OPAQUE:
491                            XSetBackground(display, gc, bgcolour);
492                            XCopyPlane(display, pixmap, wnd, gc,
493                                            srcx, srcy, cx, cy, x, y, 1);
494                            break;
495    
496                    default:
497                            NOTIMP("mix %d\n", mixmode);
498            }
499  }  }
500    
501  void ui_paint_bitmap(HWINDOW wnd, HBITMAP bmp, int x, int y)  void ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
502                            int clipx, int clipy, int clipcx, int clipcy,
503                            int boxx, int boxy, int boxcx, int boxcy,
504                            int bgcolour, int fgcolour, uint8 *text, uint8 length)
505  {  {
506          XImage *image = (XImage *)bmp;          FONTGLYPH *glyph;
507            int i;
508    
509          XPutImage(wnd->display, wnd->wnd, wnd->gc, image,          if (boxcx > 1)
510                          0, 0, x, y, image->width, image->height);          {
511                    ui_rect(boxx, boxy, boxcx, boxcy, bgcolour);
512            }
513            else if (mixmode == MIX_OPAQUE)
514            {
515                    ui_rect(clipx, clipy, clipcx, clipcy, bgcolour);
516            }
517    
518            /* Paint text, character by character */
519            for (i = 0; i < length; i++)
520            {
521                    glyph = cache_get_font(font, text[i]);
522    
523                    if (!(flags & TEXT2_IMPLICIT_X))
524                            x += text[++i];
525    
526                    if (glyph != NULL)
527                    {
528                            ui_draw_glyph(mixmode, x + (short)glyph->offset,
529                                            y + (short)glyph->baseline,
530                                            glyph->width, glyph->height,
531                                            glyph->pixmap, 0, 0,
532                                            bgcolour, fgcolour);
533    
534                            if (flags & TEXT2_IMPLICIT_X)
535                                    x += glyph->width;
536                    }
537            }
538    }
539    
540    void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
541    {
542            XImage *image;
543    
544            image = XGetImage(display, wnd, x, y, cx, cy, 0xffffffff, ZPixmap);
545            cache_put_desktop(offset, cx, cy, image->bytes_per_line, image->data);
546            XFree(image->data);
547            XFree(image);
548    }
549    
550    void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
551    {
552            XImage *image;
553            uint8 *data;
554    
555          XSync(wnd->display, True);          data = cache_get_desktop(offset, cx, cy);
556            if (data == NULL)
557                    return;
558    
559            image = XCreateImage(display, visual, 8, ZPixmap, 0,
560                                    data, cx, cy, 32, cx);
561            XSetFunction(display, gc, GXcopy);
562            XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
563            XFree(image);
564  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26