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

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

  ViewVC Help
Powered by ViewVC 1.1.26