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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 21 - (show 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 /*
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 #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 BOOL ui_create_window(char *title)
36 {
37 Screen *screen;
38 XSetWindowAttributes attribs;
39 unsigned long input_mask;
40 int i;
41
42 display = XOpenDisplay(NULL);
43 if (display == NULL)
44 {
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 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 void ui_process_events()
133 {
134 XEvent event;
135 uint8 scancode;
136 uint16 button;
137 uint32 ev_time;
138
139 if (display == NULL)
140 return;
141
142 while (XCheckWindowEvent(display, wnd, 0xffffffff, &event))
143 {
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_move_pointer(int x, int y)
200 {
201 XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
202 }
203
204 HBITMAP ui_create_bitmap(int width, int height, uint8 *data)
205 {
206 XImage *image;
207 Pixmap bitmap;
208
209 bitmap = XCreatePixmap(display, wnd, width, height, 8);
210
211 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)
233 {
234 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 XSetFunction(display, gc, GXcopy);
252 XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
253 XFree(image);
254 XFreeGC(display, gc);
255
256 return (HGLYPH)bitmap;
257 }
258
259 void ui_destroy_glyph(HGLYPH glyph)
260 {
261 XFreePixmap(display, (Pixmap)glyph);
262 }
263
264 HCOLOURMAP ui_create_colourmap(COLOURMAP *colours)
265 {
266 COLOURENTRY *entry;
267 XColor *xcolours, *xentry;
268 Colormap map;
269 int i, ncolours = colours->ncolours;
270
271 xcolours = xmalloc(sizeof(XColor) * ncolours);
272 for (i = 0; i < ncolours; i++)
273 {
274 entry = &colours->colours[i];
275 xentry = &xcolours[i];
276
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 map = XCreateColormap(display, wnd, visual, AllocAll);
285 XStoreColors(display, map, xcolours, ncolours);
286
287 xfree(xcolours);
288 return (HCOLOURMAP)map;
289 }
290
291 void ui_destroy_colourmap(HCOLOURMAP map)
292 {
293 XFreeColormap(display, (Colormap)map);
294 }
295
296 void ui_set_colourmap(HCOLOURMAP map)
297 {
298 XSetWindowColormap(display, wnd, (Colormap)map);
299 }
300
301 void ui_set_clip(int x, int y, int cx, int cy)
302 {
303 XRectangle rect;
304
305 rect.x = x;
306 rect.y = y;
307 rect.width = cx;
308 rect.height = cy;
309 XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
310 }
311
312 void ui_reset_clip()
313 {
314 XRectangle rect;
315
316 rect.x = 0;
317 rect.y = 0;
318 rect.width = width;
319 rect.height = height;
320 XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
321 }
322
323 void ui_bell()
324 {
325 XBell(display, 0);
326 }
327
328 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 static void xwin_set_function(uint8 rop2)
348 {
349 XSetFunction(display, gc, rop2_map[rop2]);
350 }
351
352 void ui_destblt(uint8 opcode,
353 /* dest */ int x, int y, int cx, int cy)
354 {
355 xwin_set_function(opcode);
356
357 XFillRectangle(display, wnd, gc, x, y, cx, cy);
358 }
359
360 void ui_patblt(uint8 opcode,
361 /* dest */ int x, int y, int cx, int cy,
362 /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
363 {
364 Display *dpy = display;
365 Pixmap fill;
366
367 xwin_set_function(opcode);
368
369 switch (brush->style)
370 {
371 case 0: /* Solid */
372 XSetForeground(dpy, gc, fgcolour);
373 XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
374 break;
375
376 case 3: /* Pattern */
377 fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);
378
379 XSetForeground(dpy, gc, fgcolour);
380 XSetBackground(dpy, gc, bgcolour);
381 XSetFillStyle(dpy, gc, FillOpaqueStippled);
382 XSetStipple(dpy, gc, fill);
383
384 XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
385
386 XSetFillStyle(dpy, gc, FillSolid);
387 ui_destroy_glyph((HGLYPH)fill);
388 break;
389
390 default:
391 NOTIMP("brush %d\n", brush->style);
392 }
393 }
394
395 void ui_screenblt(uint8 opcode,
396 /* dest */ int x, int y, int cx, int cy,
397 /* src */ int srcx, int srcy)
398 {
399 xwin_set_function(opcode);
400
401 XCopyArea(display, wnd, wnd, gc, srcx, srcy,
402 cx, cy, x, y);
403 }
404
405 void ui_memblt(uint8 opcode,
406 /* dest */ int x, int y, int cx, int cy,
407 /* src */ HBITMAP src, int srcx, int srcy)
408 {
409 xwin_set_function(opcode);
410
411 XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy,
412 cx, cy, x, y);
413 }
414
415 void ui_triblt(uint8 opcode,
416 /* 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 comes up with a more efficient way of doing it I am using cases. */
422
423 switch (opcode)
424 {
425 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 case 0xb8: /* PSDPxax */
432 ui_patblt(ROP2_XOR, x, y, cx, cy,
433 brush, bgcolour, fgcolour);
434 ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
435 ui_patblt(ROP2_XOR, x, y, cx, cy,
436 brush, bgcolour, fgcolour);
437 break;
438
439 default:
440 NOTIMP("triblt 0x%x\n", opcode);
441 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
442 }
443 }
444
445 void ui_line(uint8 opcode,
446 /* dest */ int startx, int starty, int endx, int endy,
447 /* pen */ PEN *pen)
448 {
449 xwin_set_function(opcode);
450
451 XSetForeground(display, gc, pen->colour);
452 XDrawLine(display, wnd, gc, startx, starty, endx, endy);
453 }
454
455 void ui_rect(
456 /* dest */ int x, int y, int cx, int cy,
457 /* brush */ int colour)
458 {
459 xwin_set_function(ROP2_COPY);
460
461 XSetForeground(display, gc, colour);
462 XFillRectangle(display, wnd, gc, x, y, cx, cy);
463 }
464
465 void ui_draw_glyph(int mixmode,
466 /* 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 xwin_set_function(ROP2_COPY);
472
473 XSetForeground(display, gc, fgcolour);
474
475 switch (mixmode)
476 {
477 case MIX_TRANSPARENT:
478 XSetStipple(display, gc, pixmap);
479 XSetFillStyle(display, gc, FillStippled);
480 XSetTSOrigin(display, gc, x, y);
481 XFillRectangle(display, wnd, gc,
482 x, y, cx, cy);
483 XSetFillStyle(display, gc, FillSolid);
484 break;
485
486 case MIX_OPAQUE:
487 XSetBackground(display, gc, bgcolour);
488 XCopyPlane(display, pixmap, wnd, gc,
489 srcx, srcy, cx, cy, x, y, 1);
490 break;
491
492 default:
493 NOTIMP("mix %d\n", mixmode);
494 }
495 }
496
497 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 int bgcolour, int fgcolour, uint8 *text, uint8 length)
501 {
502 FONTGLYPH *glyph;
503 int i;
504
505 if (boxcx > 1)
506 {
507 ui_rect(boxx, boxy, boxcx, boxcy, bgcolour);
508 }
509 else if (mixmode == MIX_OPAQUE)
510 {
511 ui_rect(clipx, clipy, clipcx, clipcy, bgcolour);
512 }
513
514 /* Paint text, character by character */
515 for (i = 0; i < length; i++)
516 {
517 glyph = cache_get_font(font, text[i]);
518
519 if (!(flags & TEXT2_IMPLICIT_X))
520 x += text[++i];
521
522 if (glyph != NULL)
523 {
524 ui_draw_glyph(mixmode, x + (short)glyph->offset,
525 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 void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
537 {
538 XImage *image;
539
540 image = XGetImage(display, wnd, x, y, cx, cy, 0xffffffff, ZPixmap);
541 cache_put_desktop(offset, cx, cy, image->bytes_per_line, image->data);
542 XFree(image->data);
543 XFree(image);
544 }
545
546 void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
547 {
548 XImage *image;
549 uint8 *data;
550
551 data = cache_get_desktop(offset, cx, cy);
552 if (data == NULL)
553 return;
554
555 image = XCreateImage(display, visual, 8, ZPixmap, 0,
556 data, cx, cy, 32, cx);
557 XSetFunction(display, gc, GXcopy);
558 XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
559 XFree(image);
560 }

  ViewVC Help
Powered by ViewVC 1.1.26