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

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

  ViewVC Help
Powered by ViewVC 1.1.26