/[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

Annotation of /sourceforge.net/trunk/rdesktop/xwin.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (hide annotations)
Tue Oct 17 08:24:09 2000 UTC (23 years, 7 months ago) by matty
File MIME type: text/plain
File size: 12428 byte(s)
Fix for big-endian X-servers: rely on server to handle byte/bit order.

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

  ViewVC Help
Powered by ViewVC 1.1.26