/[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 24 - (show annotations)
Sat Jan 6 03:12:10 2001 UTC (23 years, 4 months ago) by matty
File MIME type: text/plain
File size: 12713 byte(s)
ran indent (-bli0 -i8 -cli8 -npcs -npsl)

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 =
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 static uint8 xwin_translate_key(unsigned long key)
95 {
96 DEBUG("KEY(code=0x%lx)\n", key);
97
98 if ((key > 8) && (key <= 0x60))
99 return (key - 8);
100
101 switch (key)
102 {
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 return 0;
116 }
117
118 static uint16 xwin_translate_mouse(unsigned long button)
119 {
120 switch (button)
121 {
122 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 0;
131 }
132
133 void ui_process_events()
134 {
135 XEvent event;
136 uint8 scancode;
137 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 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;
216 Pixmap bitmap;
217
218 bitmap = XCreatePixmap(display, wnd, width, height, 8);
219
220 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_paint_bitmap(int x, int y, int cx, int cy,
230 int width, int height, uint8 *data)
231 {
232 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_destroy_bitmap(HBITMAP bmp)
242 {
243 XFreePixmap(display, (Pixmap) bmp);
244 }
245
246 HGLYPH ui_create_glyph(int width, int height, uint8 *data)
247 {
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 return (HGLYPH) bitmap;
270 }
271
272 void ui_destroy_glyph(HGLYPH glyph)
273 {
274 XFreePixmap(display, (Pixmap) glyph);
275 }
276
277 HCOLOURMAP ui_create_colourmap(COLOURMAP *colours)
278 {
279 COLOURENTRY *entry;
280 XColor *xcolours, *xentry;
281 Colormap map;
282 int i, ncolours = colours->ncolours;
283
284 xcolours = xmalloc(sizeof(XColor) * ncolours);
285 for (i = 0; i < ncolours; i++)
286 {
287 entry = &colours->colours[i];
288 xentry = &xcolours[i];
289
290 xentry->pixel = i;
291 xentry->red = entry->red << 8;
292 xentry->blue = entry->blue << 8;
293 xentry->green = entry->green << 8;
294 xentry->flags = DoRed | DoBlue | DoGreen;
295 }
296
297 map = XCreateColormap(display, wnd, visual, AllocAll);
298 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 XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
415 }
416
417 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 xwin_set_function(opcode);
422
423 XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
424 }
425
426 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 /* 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_line(uint8 opcode,
457 /* dest */ int startx, int starty, int endx, int endy,
458 /* pen */ PEN *pen)
459 {
460 xwin_set_function(opcode);
461
462 XSetForeground(display, gc, pen->colour);
463 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 XSetForeground(display, gc, colour);
473 XFillRectangle(display, wnd, gc, x, y, cx, cy);
474 }
475
476 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 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 }

  ViewVC Help
Powered by ViewVC 1.1.26