/[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 9 - (show annotations)
Tue Jul 25 12:34:29 2000 UTC (23 years, 9 months ago) by matty
File MIME type: text/plain
File size: 11943 byte(s)
Committing some awesome progress I made while overseas - this commit
really embodies a huge number of changes. We are now able to talk quite
fluently to a French NT Terminal Server - in normal usage only minor
font issues remain (handling of TEXT2 order is not perfect).

The next major hurdle is encryption, and it will be quite a big hurdle
- there seems to be some quite nasty session key stuff.

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

  ViewVC Help
Powered by ViewVC 1.1.26