/[rdesktop]/sourceforge.net/branches/seamlessrdp-branch/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

Annotation of /sourceforge.net/branches/seamlessrdp-branch/rdesktop/xwin.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9 - (hide annotations)
Tue Jul 25 12:34:29 2000 UTC (23 years, 9 months ago) by matty
Original Path: sourceforge.net/trunk/rdesktop/xwin.c
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 matty 6 /*
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 matty 9 HWINDOW ui_create_window(HCONN conn, int width, int height)
24 matty 6 {
25     struct window *wnd;
26 matty 9 XSetWindowAttributes attribs;
27 matty 6 Display *display;
28 matty 9 Visual *visual;
29 matty 6 Window window;
30     int black;
31     GC gc;
32    
33     display = XOpenDisplay(NULL);
34     if (display == NULL)
35     return NULL;
36    
37 matty 9 visual = DefaultVisual(display, DefaultScreen(display));
38 matty 6 black = BlackPixel(display, DefaultScreen(display));
39    
40 matty 9 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 matty 6 XMapWindow(display, window);
48 matty 9 XSelectInput(display, window, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
49 matty 6 XSync(display, True);
50    
51     gc = XCreateGC(display, window, 0, NULL);
52    
53     wnd = xmalloc(sizeof(struct window));
54 matty 9 wnd->conn = conn;
55     wnd->width = width;
56     wnd->height = height;
57 matty 6 wnd->display = display;
58     wnd->wnd = window;
59     wnd->gc = gc;
60 matty 9 wnd->visual = visual;
61 matty 7
62 matty 6 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 matty 9 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 matty 6 HBITMAP ui_create_bitmap(HWINDOW wnd, int width, int height, uint8 *data)
174     {
175     XImage *image;
176 matty 9 Pixmap bitmap;
177 matty 6
178 matty 9 bitmap = XCreatePixmap(wnd->display, wnd->wnd, width, height, 8);
179    
180 matty 7 image = XCreateImage(wnd->display, wnd->visual, 8, ZPixmap, 0,
181 matty 9 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 matty 6 }
189    
190 matty 7 void ui_destroy_bitmap(HWINDOW wnd, HBITMAP bmp)
191 matty 6 {
192 matty 9 XFreePixmap(wnd->display, (Pixmap)bmp);
193 matty 6 }
194    
195 matty 9 HGLYPH ui_create_glyph(HWINDOW wnd, int width, int height, uint8 *data)
196 matty 6 {
197 matty 9 XImage *image;
198     Pixmap bitmap;
199     int scanline;
200     GC gc;
201 matty 6
202 matty 9 scanline = (width + 7) / 8;
203 matty 6
204 matty 9 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 matty 6 }
216 matty 7
217 matty 9 void ui_destroy_glyph(HWINDOW wnd, HGLYPH glyph)
218 matty 7 {
219 matty 9 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 matty 7 Colormap map;
227 matty 9 int i, ncolours = colours->ncolours;
228 matty 7
229 matty 9 xcolours = malloc(sizeof(XColor) * ncolours);
230     for (i = 0; i < ncolours; i++)
231 matty 7 {
232 matty 9 entry = &colours->colours[i];
233     xentry = &xcolours[i];
234 matty 7
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 matty 9 XStoreColors(wnd->display, map, xcolours, ncolours);
244 matty 7
245 matty 9 free(xcolours);
246     return (HCOLOURMAP)map;
247 matty 7 }
248    
249 matty 9 void ui_destroy_colourmap(HWINDOW wnd, HCOLOURMAP map)
250 matty 7 {
251     XFreeColormap(wnd->display, (Colormap)map);
252     }
253    
254 matty 9 void ui_set_colourmap(HWINDOW wnd, HCOLOURMAP map)
255 matty 7 {
256     XSetWindowColormap(wnd->display, wnd->wnd, (Colormap)map);
257     }
258    
259 matty 9 void ui_set_clip(HWINDOW wnd, int x, int y, int cx, int cy)
260 matty 7 {
261 matty 9 XRectangle rect;
262 matty 7
263 matty 9 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 matty 7
270 matty 9 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 matty 7 }
280    
281 matty 9 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 matty 7 {
302 matty 9 XSetFunction(wnd->display, wnd->gc, rop2_map[rop2]);
303 matty 7 }
304 matty 9
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