/[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 25 - (hide annotations)
Sat Jan 6 03:47:04 2001 UTC (23 years, 4 months ago) by matty
File MIME type: text/plain
File size: 12685 byte(s)
Changed indentation style (-psl).

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

  ViewVC Help
Powered by ViewVC 1.1.26