/[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 10 - (show annotations)
Tue Aug 15 10:23:24 2000 UTC (23 years, 8 months ago) by matty
File MIME type: text/plain
File size: 12141 byte(s)
Major commit of work from laptop - done in various free moments.
Implemented encryption layer and some basic licensing negotiation.
Reorganised code somewhat. While this is not quite as clean, it is
a lot faster - our parser speed was becoming a bottle-neck.

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

  ViewVC Help
Powered by ViewVC 1.1.26