/[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

Annotation of /sourceforge.net/trunk/rdesktop/xwin.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 21 - (hide annotations)
Mon Oct 16 08:44:48 2000 UTC (23 years, 7 months ago) by matty
File MIME type: text/plain
File size: 12339 byte(s)
Added a number of command line options including autologon.
Inverted sense of -m (the default is now to send mouse move events).
Preparing for release of 1.0.0.

1 matty 6 /*
2     rdesktop: A Remote Desktop Protocol client.
3     User interface services - X-Windows
4     Copyright (C) Matthew Chapman 1999-2000
5    
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10    
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     GNU General Public License for more details.
15    
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20    
21 matty 10 #include <X11/Xlib.h>
22     #include <time.h>
23     #include "rdesktop.h"
24 matty 6
25 matty 10 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     BOOL ui_create_window(char *title)
36 matty 6 {
37 matty 10 Screen *screen;
38 matty 9 XSetWindowAttributes attribs;
39 matty 10 unsigned long input_mask;
40     int i;
41 matty 6
42     display = XOpenDisplay(NULL);
43     if (display == NULL)
44 matty 21 {
45     ERROR("Failed to open display\n");
46 matty 10 return False;
47 matty 21 }
48 matty 6
49 matty 10 /* 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 matty 9 visual = DefaultVisual(display, DefaultScreen(display));
63 matty 6
64 matty 10 attribs.background_pixel = BlackPixel(display, DefaultScreen(display));
65 matty 9 attribs.backing_store = Always;
66 matty 10 wnd = XCreateWindow(display, DefaultRootWindow(display),
67     0, 0, width, height, 0, 8, InputOutput, visual,
68 matty 9 CWBackingStore | CWBackPixel, &attribs);
69    
70 matty 10 XStoreName(display, wnd, title);
71     XMapWindow(display, wnd);
72 matty 6
73 matty 10 input_mask = KeyPressMask | KeyReleaseMask;
74     input_mask |= ButtonPressMask | ButtonReleaseMask;
75     if (motion)
76     input_mask |= PointerMotionMask;
77 matty 6
78 matty 10 XSelectInput(display, wnd, input_mask);
79     gc = XCreateGC(display, wnd, 0, NULL);
80 matty 7
81 matty 10 IM = XOpenIM(display, NULL, NULL, NULL);
82     return True;
83 matty 6 }
84    
85 matty 10 void ui_destroy_window()
86 matty 6 {
87 matty 10 XCloseIM(IM);
88     XFreeGC(display, gc);
89     XDestroyWindow(display, wnd);
90     XCloseDisplay(display);
91 matty 6 }
92    
93 matty 9 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     static uint16 xwin_translate_mouse(unsigned long button)
118     {
119     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     return 0;
130     }
131    
132 matty 10 void ui_process_events()
133 matty 9 {
134     XEvent event;
135     uint8 scancode;
136     uint16 button;
137 matty 10 uint32 ev_time;
138 matty 9
139 matty 10 if (display == NULL)
140 matty 9 return;
141    
142 matty 10 while (XCheckWindowEvent(display, wnd, 0xffffffff, &event))
143 matty 9 {
144 matty 10 ev_time = time(NULL);
145    
146 matty 9 switch (event.type)
147     {
148     case KeyPress:
149     scancode = xwin_translate_key(event.xkey.keycode);
150     if (scancode == 0)
151     break;
152    
153 matty 10 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,
154 matty 9 scancode, 0);
155     break;
156    
157     case KeyRelease:
158     scancode = xwin_translate_key(event.xkey.keycode);
159     if (scancode == 0)
160     break;
161    
162 matty 10 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
163 matty 9 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 matty 10 rdp_send_input(ev_time, RDP_INPUT_MOUSE,
174 matty 9 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 matty 10 rdp_send_input(ev_time, RDP_INPUT_MOUSE,
185 matty 9 button,
186     event.xbutton.x,
187     event.xbutton.y);
188 matty 10 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 matty 9 }
196     }
197     }
198    
199 matty 10 void ui_move_pointer(int x, int y)
200 matty 9 {
201 matty 10 XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
202 matty 9 }
203    
204 matty 10 HBITMAP ui_create_bitmap(int width, int height, uint8 *data)
205 matty 6 {
206     XImage *image;
207 matty 9 Pixmap bitmap;
208 matty 6
209 matty 10 bitmap = XCreatePixmap(display, wnd, width, height, 8);
210 matty 9
211 matty 10 image = XCreateImage(display, visual, 8, ZPixmap, 0,
212 matty 9 data, width, height, 8, width);
213 matty 10 XSetFunction(display, gc, GXcopy);
214     XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
215 matty 9 XFree(image);
216    
217     return (HBITMAP)bitmap;
218 matty 6 }
219    
220 matty 10 void ui_paint_bitmap(int x, int y, int cx, int cy,
221     int width, int height, uint8 *data)
222 matty 6 {
223 matty 10 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 matty 6 }
231    
232 matty 10 void ui_destroy_bitmap(HBITMAP bmp)
233 matty 6 {
234 matty 10 XFreePixmap(display, (Pixmap)bmp);
235     }
236    
237     HGLYPH ui_create_glyph(int width, int height, uint8 *data)
238     {
239 matty 9 XImage *image;
240     Pixmap bitmap;
241     int scanline;
242     GC gc;
243 matty 6
244 matty 9 scanline = (width + 7) / 8;
245 matty 6
246 matty 10 bitmap = XCreatePixmap(display, wnd, width, height, 1);
247     gc = XCreateGC(display, bitmap, 0, NULL);
248 matty 9
249 matty 10 image = XCreateImage(display, visual, 1, ZPixmap, 0,
250 matty 9 data, width, height, 8, scanline);
251 matty 10 XSetFunction(display, gc, GXcopy);
252     XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
253 matty 9 XFree(image);
254 matty 10 XFreeGC(display, gc);
255 matty 9
256     return (HGLYPH)bitmap;
257 matty 6 }
258 matty 7
259 matty 10 void ui_destroy_glyph(HGLYPH glyph)
260 matty 7 {
261 matty 10 XFreePixmap(display, (Pixmap)glyph);
262 matty 9 }
263    
264 matty 10 HCOLOURMAP ui_create_colourmap(COLOURMAP *colours)
265 matty 9 {
266     COLOURENTRY *entry;
267     XColor *xcolours, *xentry;
268 matty 7 Colormap map;
269 matty 9 int i, ncolours = colours->ncolours;
270 matty 7
271 matty 10 xcolours = xmalloc(sizeof(XColor) * ncolours);
272 matty 9 for (i = 0; i < ncolours; i++)
273 matty 7 {
274 matty 9 entry = &colours->colours[i];
275     xentry = &xcolours[i];
276 matty 7
277     xentry->pixel = i;
278     xentry->red = entry->red << 8;
279     xentry->blue = entry->blue << 8;
280     xentry->green = entry->green << 8;
281     xentry->flags = DoRed | DoBlue | DoGreen;
282     }
283    
284 matty 10 map = XCreateColormap(display, wnd, visual, AllocAll);
285     XStoreColors(display, map, xcolours, ncolours);
286 matty 7
287 matty 10 xfree(xcolours);
288 matty 9 return (HCOLOURMAP)map;
289 matty 7 }
290    
291 matty 10 void ui_destroy_colourmap(HCOLOURMAP map)
292 matty 7 {
293 matty 10 XFreeColormap(display, (Colormap)map);
294 matty 7 }
295    
296 matty 10 void ui_set_colourmap(HCOLOURMAP map)
297 matty 7 {
298 matty 10 XSetWindowColormap(display, wnd, (Colormap)map);
299 matty 7 }
300    
301 matty 10 void ui_set_clip(int x, int y, int cx, int cy)
302 matty 7 {
303 matty 9 XRectangle rect;
304 matty 7
305 matty 9 rect.x = x;
306     rect.y = y;
307     rect.width = cx;
308     rect.height = cy;
309 matty 10 XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
310 matty 9 }
311 matty 7
312 matty 10 void ui_reset_clip()
313 matty 9 {
314     XRectangle rect;
315    
316     rect.x = 0;
317     rect.y = 0;
318 matty 10 rect.width = width;
319     rect.height = height;
320     XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
321 matty 7 }
322    
323 matty 10 void ui_bell()
324     {
325     XBell(display, 0);
326     }
327    
328 matty 9 static int rop2_map[] = {
329     GXclear, /* 0 */
330     GXnor, /* DPon */
331     GXandInverted, /* DPna */
332     GXcopyInverted, /* Pn */
333     GXandReverse, /* PDna */
334     GXinvert, /* Dn */
335     GXxor, /* DPx */
336     GXnand, /* DPan */
337     GXand, /* DPa */
338     GXequiv, /* DPxn */
339     GXnoop, /* D */
340     GXorInverted, /* DPno */
341     GXcopy, /* P */
342     GXorReverse, /* PDno */
343     GXor, /* DPo */
344     GXset /* 1 */
345     };
346    
347 matty 10 static void xwin_set_function(uint8 rop2)
348 matty 7 {
349 matty 10 XSetFunction(display, gc, rop2_map[rop2]);
350 matty 7 }
351 matty 9
352 matty 10 void ui_destblt(uint8 opcode,
353 matty 9 /* dest */ int x, int y, int cx, int cy)
354     {
355 matty 10 xwin_set_function(opcode);
356 matty 9
357 matty 10 XFillRectangle(display, wnd, gc, x, y, cx, cy);
358 matty 9 }
359    
360 matty 10 void ui_patblt(uint8 opcode,
361 matty 9 /* dest */ int x, int y, int cx, int cy,
362     /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
363     {
364 matty 10 Display *dpy = display;
365 matty 9 Pixmap fill;
366    
367 matty 10 xwin_set_function(opcode);
368 matty 9
369     switch (brush->style)
370     {
371     case 0: /* Solid */
372     XSetForeground(dpy, gc, fgcolour);
373 matty 10 XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
374 matty 9 break;
375    
376     case 3: /* Pattern */
377 matty 10 fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);
378 matty 9
379     XSetForeground(dpy, gc, fgcolour);
380     XSetBackground(dpy, gc, bgcolour);
381     XSetFillStyle(dpy, gc, FillOpaqueStippled);
382     XSetStipple(dpy, gc, fill);
383    
384 matty 10 XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
385 matty 9
386     XSetFillStyle(dpy, gc, FillSolid);
387 matty 10 ui_destroy_glyph((HGLYPH)fill);
388 matty 9 break;
389    
390     default:
391 matty 10 NOTIMP("brush %d\n", brush->style);
392 matty 9 }
393     }
394    
395 matty 10 void ui_screenblt(uint8 opcode,
396 matty 9 /* dest */ int x, int y, int cx, int cy,
397     /* src */ int srcx, int srcy)
398     {
399 matty 10 xwin_set_function(opcode);
400 matty 9
401 matty 10 XCopyArea(display, wnd, wnd, gc, srcx, srcy,
402 matty 9 cx, cy, x, y);
403     }
404    
405 matty 10 void ui_memblt(uint8 opcode,
406 matty 9 /* dest */ int x, int y, int cx, int cy,
407     /* src */ HBITMAP src, int srcx, int srcy)
408     {
409 matty 10 xwin_set_function(opcode);
410 matty 9
411 matty 10 XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy,
412 matty 9 cx, cy, x, y);
413     }
414    
415 matty 10 void ui_triblt(uint8 opcode,
416 matty 9 /* dest */ int x, int y, int cx, int cy,
417     /* src */ HBITMAP src, int srcx, int srcy,
418     /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
419     {
420     /* This is potentially difficult to do in general. Until someone
421 matty 10 comes up with a more efficient way of doing it I am using cases. */
422 matty 9
423     switch (opcode)
424     {
425 matty 16 case 0x69: /* PDSxxn */
426     ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
427     ui_patblt(ROP2_NXOR, x, y, cx, cy,
428     brush, bgcolour, fgcolour);
429     break;
430    
431 matty 9 case 0xb8: /* PSDPxax */
432 matty 10 ui_patblt(ROP2_XOR, x, y, cx, cy,
433 matty 9 brush, bgcolour, fgcolour);
434 matty 16 ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
435 matty 10 ui_patblt(ROP2_XOR, x, y, cx, cy,
436 matty 9 brush, bgcolour, fgcolour);
437     break;
438    
439     default:
440 matty 10 NOTIMP("triblt 0x%x\n", opcode);
441 matty 16 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
442 matty 9 }
443     }
444    
445 matty 10 void ui_line(uint8 opcode,
446 matty 9 /* dest */ int startx, int starty, int endx, int endy,
447     /* pen */ PEN *pen)
448     {
449 matty 10 xwin_set_function(opcode);
450 matty 9
451 matty 10 XSetForeground(display, gc, pen->colour);
452     XDrawLine(display, wnd, gc, startx, starty, endx, endy);
453 matty 9 }
454    
455 matty 10 void ui_rect(
456 matty 9 /* dest */ int x, int y, int cx, int cy,
457     /* brush */ int colour)
458     {
459 matty 10 xwin_set_function(ROP2_COPY);
460 matty 9
461 matty 10 XSetForeground(display, gc, colour);
462     XFillRectangle(display, wnd, gc, x, y, cx, cy);
463 matty 9 }
464    
465 matty 10 void ui_draw_glyph(int mixmode,
466 matty 9 /* dest */ int x, int y, int cx, int cy,
467     /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour, int fgcolour)
468     {
469     Pixmap pixmap = (Pixmap)glyph;
470    
471 matty 10 xwin_set_function(ROP2_COPY);
472 matty 9
473 matty 10 XSetForeground(display, gc, fgcolour);
474 matty 9
475     switch (mixmode)
476     {
477     case MIX_TRANSPARENT:
478 matty 10 XSetStipple(display, gc, pixmap);
479     XSetFillStyle(display, gc, FillStippled);
480     XSetTSOrigin(display, gc, x, y);
481     XFillRectangle(display, wnd, gc,
482 matty 9 x, y, cx, cy);
483 matty 10 XSetFillStyle(display, gc, FillSolid);
484 matty 9 break;
485    
486     case MIX_OPAQUE:
487 matty 10 XSetBackground(display, gc, bgcolour);
488     XCopyPlane(display, pixmap, wnd, gc,
489 matty 9 srcx, srcy, cx, cy, x, y, 1);
490     break;
491    
492     default:
493 matty 10 NOTIMP("mix %d\n", mixmode);
494 matty 9 }
495     }
496    
497 matty 17 void ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
498     int clipx, int clipy, int clipcx, int clipcy,
499     int boxx, int boxy, int boxcx, int boxcy,
500 matty 9 int bgcolour, int fgcolour, uint8 *text, uint8 length)
501     {
502 matty 10 FONTGLYPH *glyph;
503 matty 9 int i;
504    
505     if (boxcx > 1)
506     {
507 matty 10 ui_rect(boxx, boxy, boxcx, boxcy, bgcolour);
508 matty 9 }
509 matty 17 else if (mixmode == MIX_OPAQUE)
510     {
511     ui_rect(clipx, clipy, clipcx, clipcy, bgcolour);
512     }
513 matty 9
514     /* Paint text, character by character */
515     for (i = 0; i < length; i++)
516     {
517 matty 10 glyph = cache_get_font(font, text[i]);
518 matty 9
519 matty 17 if (!(flags & TEXT2_IMPLICIT_X))
520     x += text[++i];
521    
522 matty 9 if (glyph != NULL)
523     {
524 matty 20 ui_draw_glyph(mixmode, x + (short)glyph->offset,
525 matty 9 y + (short)glyph->baseline,
526     glyph->width, glyph->height,
527     glyph->pixmap, 0, 0,
528     bgcolour, fgcolour);
529    
530     if (flags & TEXT2_IMPLICIT_X)
531     x += glyph->width;
532     }
533     }
534     }
535    
536 matty 10 void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
537 matty 9 {
538     XImage *image;
539    
540 matty 10 image = XGetImage(display, wnd, x, y, cx, cy, 0xffffffff, ZPixmap);
541 matty 16 cache_put_desktop(offset, cx, cy, image->bytes_per_line, image->data);
542 matty 10 XFree(image->data);
543     XFree(image);
544 matty 9 }
545    
546 matty 10 void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
547 matty 9 {
548     XImage *image;
549 matty 10 uint8 *data;
550 matty 9
551 matty 16 data = cache_get_desktop(offset, cx, cy);
552 matty 10 if (data == NULL)
553     return;
554    
555     image = XCreateImage(display, visual, 8, ZPixmap, 0,
556 matty 16 data, cx, cy, 32, cx);
557 matty 10 XSetFunction(display, gc, GXcopy);
558     XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
559 matty 9 XFree(image);
560     }

  ViewVC Help
Powered by ViewVC 1.1.26