/[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 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            if ((key > 8) && (key <= 0x60))
99                    return (key - 8);
100    
101          XMapWindow(display, window);          switch (key)
102          XSync(display, True);          {
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          gc = XCreateGC(display, window, 0, NULL);          return 0;
116    }
117    
118          wnd = xmalloc(sizeof(struct window));  static uint16 xwin_translate_mouse(unsigned long button)
119          wnd->display = display;  {
120          wnd->wnd = window;          switch (button)
121          wnd->gc = gc;          {
122          wnd->visual = DefaultVisual(wnd->display, DefaultScreen(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 wnd;          return 0;
131  }  }
132    
133  void ui_destroy_window(HWINDOW wnd)  void ui_process_events()
134  {  {
135          XFreeGC(wnd->display, wnd->gc);          XEvent event;
136          XDestroyWindow(wnd->display, wnd->wnd);          uint8 scancode;
137          XCloseDisplay(wnd->display);          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  HBITMAP ui_create_bitmap(HWINDOW wnd, int width, int height, uint8 *data)  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            Pixmap bitmap;
217    
218          image = XCreateImage(wnd->display, wnd->visual, 8, ZPixmap, 0,          bitmap = XCreatePixmap(display, wnd, width, height, 8);
                                 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_destroy_bitmap(HWINDOW wnd, HBITMAP bmp)  void ui_paint_bitmap(int x, int y, int cx, int cy,
230                         int width, int height, uint8 *data)
231  {  {
232          XDestroyImage((XImage *)bmp);          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_paint_bitmap(HWINDOW wnd, HBITMAP bmp, int x, int y)  void ui_destroy_bitmap(HBITMAP bmp)
242  {  {
243          XImage *image = (XImage *)bmp;          XFreePixmap(display, (Pixmap) bmp);
244    }
245    
246          XPutImage(wnd->display, wnd->wnd, wnd->gc, image,  HGLYPH ui_create_glyph(int width, int height, uint8 *data)
247                          0, 0, x, y, image->width, image->height);  {
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          XSync(wnd->display, True);          return (HGLYPH) bitmap;
270    }
271    
272    void ui_destroy_glyph(HGLYPH glyph)
273    {
274            XFreePixmap(display, (Pixmap) glyph);
275  }  }
276    
277  HCOLORMAP ui_create_colormap(HWINDOW wnd, COLORMAP *colors)  HCOLOURMAP ui_create_colourmap(COLOURMAP *colours)
278  {  {
279          COLORENTRY *entry;          COLOURENTRY *entry;
280          XColor *xcolors, *xentry;          XColor *xcolours, *xentry;
281          Colormap map;          Colormap map;
282          int i, ncolors = colors->ncolors;          int i, ncolours = colours->ncolours;
283    
284          xcolors = malloc(sizeof(XColor) * ncolors);          xcolours = xmalloc(sizeof(XColor) * ncolours);
285          for (i = 0; i < ncolors; i++)          for (i = 0; i < ncolours; i++)
286          {          {
287                  entry = &colors->colors[i];                  entry = &colours->colours[i];
288                  xentry = &xcolors[i];                  xentry = &xcolours[i];
289    
290                  xentry->pixel = i;                  xentry->pixel = i;
291                  xentry->red = entry->red << 8;                  xentry->red = entry->red << 8;
# Line 102  HCOLORMAP ui_create_colormap(HWINDOW wnd Line 294  HCOLORMAP ui_create_colormap(HWINDOW wnd
294                  xentry->flags = DoRed | DoBlue | DoGreen;                  xentry->flags = DoRed | DoBlue | DoGreen;
295          }          }
296    
297          map = XCreateColormap(wnd->display, wnd->wnd, wnd->visual, AllocAll);          map = XCreateColormap(display, wnd, visual, AllocAll);
298          XStoreColors(wnd->display, map, xcolors, ncolors);          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_destblt(uint8 opcode,
366                    /* dest */ int x, int y, int cx, int cy)
367    {
368            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            switch (brush->style)
383            {
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          free(xcolors);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
         return (HCOLORMAP)map;  
415  }  }
416    
417  void ui_destroy_colormap(HWINDOW wnd, HCOLORMAP map)  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          XFreeColormap(wnd->display, (Colormap)map);          xwin_set_function(opcode);
422    
423            XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
424  }  }
425    
426  void ui_set_colormap(HWINDOW wnd, HCOLORMAP map)  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          XSetWindowColormap(wnd->display, wnd->wnd, (Colormap)map);          /* 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_draw_rectangle(HWINDOW wnd, int x, int y, int width, int height)  void ui_line(uint8 opcode,
457                 /* dest */ int startx, int starty, int endx, int endy,
458                 /* pen */ PEN *pen)
459  {  {
460          static int white = 0;          xwin_set_function(opcode);
461    
462          XSetForeground(wnd->display, wnd->gc, white);          XSetForeground(display, gc, pen->colour);
463          XFillRectangle(wnd->display, wnd->wnd, wnd->gc, x, y, width, height);          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          white++;          XSetForeground(display, gc, colour);
473            XFillRectangle(display, wnd, gc, x, y, cx, cy);
474  }  }
475    
476  void ui_move_pointer(HWINDOW wnd, int x, int y)  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          XWarpPointer(wnd->display, wnd->wnd, wnd->wnd, 0, 0, 0, 0, x, y);          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            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.7  
changed lines
  Added in v.24

  ViewVC Help
Powered by ViewVC 1.1.26