/[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 25 - (show annotations)
Sat Jan 6 03:47:04 2001 UTC (23 years, 4 months ago) by matty
File MIME type: text/plain
File size: 12685 byte(s)
Changed indentation style (-psl).

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
36 ui_create_window(char *title)
37 {
38 Screen *screen;
39 XSetWindowAttributes attribs;
40 unsigned long input_mask;
41 int i;
42
43 display = XOpenDisplay(NULL);
44 if (display == NULL)
45 {
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 static uint8
97 xwin_translate_key(unsigned long key)
98 {
99 DEBUG("KEY(code=0x%lx)\n", key);
100
101 if ((key > 8) && (key <= 0x60))
102 return (key - 8);
103
104 switch (key)
105 {
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 return 0;
119 }
120
121 static uint16
122 xwin_translate_mouse(unsigned long button)
123 {
124 switch (button)
125 {
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 0;
135 }
136
137 void
138 ui_process_events()
139 {
140 XEvent event;
141 uint8 scancode;
142 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 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;
223 Pixmap bitmap;
224
225 bitmap = XCreatePixmap(display, wnd, width, height, 8);
226
227 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
237 ui_paint_bitmap(int x, int y, int cx, int cy,
238 int width, int height, uint8 *data)
239 {
240 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
250 ui_destroy_bitmap(HBITMAP bmp)
251 {
252 XFreePixmap(display, (Pixmap) bmp);
253 }
254
255 HGLYPH
256 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 return (HGLYPH) bitmap;
280 }
281
282 void
283 ui_destroy_glyph(HGLYPH glyph)
284 {
285 XFreePixmap(display, (Pixmap) glyph);
286 }
287
288 HCOLOURMAP
289 ui_create_colourmap(COLOURMAP *colours)
290 {
291 COLOURENTRY *entry;
292 XColor *xcolours, *xentry;
293 Colormap map;
294 int i, ncolours = colours->ncolours;
295
296 xcolours = xmalloc(sizeof(XColor) * ncolours);
297 for (i = 0; i < ncolours; i++)
298 {
299 entry = &colours->colours[i];
300 xentry = &xcolours[i];
301
302 xentry->pixel = i;
303 xentry->red = entry->red << 8;
304 xentry->blue = entry->blue << 8;
305 xentry->green = entry->green << 8;
306 xentry->flags = DoRed | DoBlue | DoGreen;
307 }
308
309 map = XCreateColormap(display, wnd, visual, AllocAll);
310 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 XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
436 }
437
438 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 xwin_set_function(opcode);
444
445 XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
446 }
447
448 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 /* 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
480 ui_line(uint8 opcode,
481 /* dest */ int startx, int starty, int endx, int endy,
482 /* pen */ PEN *pen)
483 {
484 xwin_set_function(opcode);
485
486 XSetForeground(display, gc, pen->colour);
487 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 XSetForeground(display, gc, colour);
498 XFillRectangle(display, wnd, gc, x, y, cx, cy);
499 }
500
501 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 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 }

  ViewVC Help
Powered by ViewVC 1.1.26