/[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 59 - (hide annotations)
Sun Jul 14 04:20:25 2002 UTC (21 years, 10 months ago) by jsorg71
File MIME type: text/plain
File size: 28628 byte(s)
upside down pattern in patblt

1 matty 6 /*
2     rdesktop: A Remote Desktop Protocol client.
3 matthewc 38 User interface services - X Window System
4 matty 30 Copyright (C) Matthew Chapman 1999-2001
5 n-ki 52
6 matty 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 n-ki 52
11 matty 6 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 n-ki 52
16 matty 6 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 matty 28 #include <X11/Xutil.h>
23 n-ki 52 #include <X11/XKBlib.h>
24 matty 10 #include <time.h>
25 matty 33 #include <errno.h>
26 matty 10 #include "rdesktop.h"
27 matty 6
28 matthewc 38 extern char keymapname[16];
29     extern int keylayout;
30 matty 10 extern int width;
31     extern int height;
32 matty 29 extern BOOL sendmotion;
33 matty 28 extern BOOL fullscreen;
34 matty 10
35 matthewc 50 Display *display;
36 n-ki 52 XkbDescPtr xkb;
37 matty 33 static int x_socket;
38 matty 10 static Window wnd;
39     static GC gc;
40     static Visual *visual;
41 matty 29 static int depth;
42     static int bpp;
43    
44 matty 33 /* endianness */
45     static BOOL host_be;
46     static BOOL xserver_be;
47    
48     /* software backing store */
49 matty 31 static BOOL ownbackstore;
50     static Pixmap backstore;
51    
52 n-ki 52 /* needed to keep track of the modifiers */
53 n-ki 54 static unsigned int numlock_modifier_mask = 0;
54 n-ki 52 static unsigned int key_down_state = 0;
55    
56 n-ki 54
57 n-ki 52 #define DShift1Mask (1<<0)
58 n-ki 54 #define DLockMask (1<<1)
59 n-ki 52 #define DControl1Mask (1<<2)
60 n-ki 54 #define DMod1Mask (1<<3)
61     #define DMod2Mask (1<<4)
62     #define DMod3Mask (1<<5)
63     #define DMod4Mask (1<<6)
64     #define DMod5Mask (1<<7)
65     #define DShift2Mask (1<<8)
66     #define DControl2Mask (1<<9)
67     #define DNumLockMask (1<<10)
68 n-ki 52
69 matty 31 #define FILL_RECTANGLE(x,y,cx,cy)\
70     { \
71     XFillRectangle(display, wnd, gc, x, y, cx, cy); \
72     if (ownbackstore) \
73     XFillRectangle(display, backstore, gc, x, y, cx, cy); \
74     }
75    
76 matty 33 /* colour maps */
77 matty 29 static BOOL owncolmap;
78     static Colormap xcolmap;
79     static uint32 white;
80 matty 28 static uint32 *colmap;
81 matty 10
82 matty 33 #define TRANSLATE(col) ( owncolmap ? col : translate_colour(colmap[col]) )
83 matty 29 #define SET_FOREGROUND(col) XSetForeground(display, gc, TRANSLATE(col));
84     #define SET_BACKGROUND(col) XSetBackground(display, gc, TRANSLATE(col));
85 matty 28
86     static int rop2_map[] = {
87     GXclear, /* 0 */
88     GXnor, /* DPon */
89     GXandInverted, /* DPna */
90     GXcopyInverted, /* Pn */
91     GXandReverse, /* PDna */
92     GXinvert, /* Dn */
93     GXxor, /* DPx */
94     GXnand, /* DPan */
95     GXand, /* DPa */
96     GXequiv, /* DPxn */
97     GXnoop, /* D */
98     GXorInverted, /* DPno */
99     GXcopy, /* P */
100     GXorReverse, /* PDno */
101     GXor, /* DPo */
102     GXset /* 1 */
103     };
104    
105 matty 29 #define SET_FUNCTION(rop2) { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }
106     #define RESET_FUNCTION(rop2) { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
107    
108 n-ki 54 void xwin_get_numlock_mask();
109     void xwin_mod_update(uint32 state, uint32 ev_time );
110     void xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode);
111     void xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode);
112 n-ki 52
113 matty 28 static void
114 matty 29 translate8(uint8 *data, uint8 *out, uint8 *end)
115 matty 28 {
116 matty 29 while (out < end)
117     *(out++) = (uint8)colmap[*(data++)];
118     }
119 matty 28
120 matty 29 static void
121     translate16(uint8 *data, uint16 *out, uint16 *end)
122     {
123     while (out < end)
124     *(out++) = (uint16)colmap[*(data++)];
125     }
126    
127 matty 33 /* little endian - conversion happens when colourmap is built */
128 matty 29 static void
129     translate24(uint8 *data, uint8 *out, uint8 *end)
130     {
131     uint32 value;
132    
133     while (out < end)
134 matty 28 {
135 matty 29 value = colmap[*(data++)];
136     *(out++) = value;
137     *(out++) = value >> 8;
138     *(out++) = value >> 16;
139 matty 28 }
140     }
141    
142     static void
143 matty 29 translate32(uint8 *data, uint32 *out, uint32 *end)
144 matty 28 {
145 matty 29 while (out < end)
146     *(out++) = colmap[*(data++)];
147 matty 28 }
148    
149 matty 29 static uint8 *
150 matty 33 translate_image(int width, int height, uint8 *data)
151 matty 28 {
152 matty 29 int size = width * height * bpp/8;
153     uint8 *out = xmalloc(size);
154     uint8 *end = out + size;
155    
156     switch (bpp)
157     {
158     case 8:
159     translate8(data, out, end);
160     break;
161    
162     case 16:
163     translate16(data, (uint16 *)out, (uint16 *)end);
164     break;
165    
166     case 24:
167     translate24(data, out, end);
168     break;
169    
170     case 32:
171     translate32(data, (uint32 *)out, (uint32 *)end);
172     break;
173     }
174    
175     return out;
176 matty 28 }
177    
178 matty 35 #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
179     #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }
180     #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
181     x = (x << 16) | (x >> 16); }
182 matty 29
183 matty 33 static uint32
184     translate_colour(uint32 colour)
185     {
186     switch (bpp)
187     {
188     case 16:
189     if (host_be != xserver_be)
190     BSWAP16(colour);
191     break;
192 matty 29
193 matty 33 case 24:
194     if (xserver_be)
195     BSWAP24(colour);
196     break;
197    
198     case 32:
199     if (host_be != xserver_be)
200     BSWAP32(colour);
201     break;
202     }
203    
204     return colour;
205     }
206    
207 matty 25 BOOL
208     ui_create_window(char *title)
209 matty 6 {
210 matty 9 XSetWindowAttributes attribs;
211 matty 28 XClassHint *classhints;
212     XSizeHints *sizehints;
213 matty 10 unsigned long input_mask;
214 matty 28 XPixmapFormatValues *pfm;
215 matty 29 Screen *screen;
216 matty 33 uint16 test;
217 matty 29 int i;
218 n-ki 52
219     int xkb_minor, xkb_major;
220     int xkb_event, xkb_error, xkb_reason;
221 matty 6
222 n-ki 52 /* compare compiletime libs with runtime libs. */
223     xkb_major = XkbMajorVersion;
224     xkb_minor = XkbMinorVersion;
225     if( XkbLibraryVersion( &xkb_major, &xkb_minor ) == False )
226     {
227     error("please re-compile rdesktop\ncompile time version of xkb is not compatible with\nyour runtime version of the library\n");
228     return False;
229     }
230    
231    
232     display = XkbOpenDisplay( NULL, &xkb_event, &xkb_error, &xkb_major, &xkb_minor, &xkb_reason );
233     switch(xkb_reason)
234     {
235     case XkbOD_BadLibraryVersion:
236     error("XkbOD_BadLibraryVersion: XKB extensions in server and the library rdesktop is linked against aren't compatible with each other.\n");
237     break;
238     case XkbOD_ConnectionRefused:
239     error("XkbOD_ConnectionRefused\n");
240     break;
241     case XkbOD_BadServerVersion:
242     error("XkbOD_BadServerVersion\n");
243     break;
244     case XkbOD_NonXkbServer:
245     error("XkbOD_NonXkbServer: XKB extension not present in server\nupdate your X server.\n");
246     break;
247     case XkbOD_Success:
248     DEBUG("XkbOD_Success: Connection established with display\n");
249     break;
250     }
251    
252 matty 6 if (display == NULL)
253 matty 21 {
254 matty 30 error("Failed to open display\n");
255 matty 10 return False;
256 matty 21 }
257 matty 6
258 matty 33 x_socket = ConnectionNumber(display);
259 matty 29 screen = DefaultScreenOfDisplay(display);
260     visual = DefaultVisualOfScreen(screen);
261     depth = DefaultDepthOfScreen(screen);
262 n-ki 52
263 matty 29 pfm = XListPixmapFormats(display, &i);
264 matty 28 if (pfm != NULL)
265     {
266 matty 29 /* Use maximum bpp for this depth - this is generally
267     desirable, e.g. 24 bits->32 bits. */
268     while (i--)
269 matty 28 {
270 matty 29 if ((pfm[i].depth == depth)
271     && (pfm[i].bits_per_pixel > bpp))
272 matty 28 {
273 matty 29 bpp = pfm[i].bits_per_pixel;
274 matty 28 }
275     }
276     XFree(pfm);
277     }
278 matty 10
279 matty 28 if (bpp < 8)
280 matty 10 {
281 matty 30 error("Less than 8 bpp not currently supported.\n");
282 matty 10 XCloseDisplay(display);
283     return False;
284     }
285    
286 matty 29 if (depth <= 8)
287     owncolmap = True;
288     else
289     xcolmap = DefaultColormapOfScreen(screen);
290 matty 6
291 matty 33 test = 1;
292     host_be = !(BOOL)(*(uint8 *)(&test));
293     xserver_be = (ImageByteOrder(display) == MSBFirst);
294    
295 matty 29 white = WhitePixelOfScreen(screen);
296     attribs.background_pixel = BlackPixelOfScreen(screen);
297     attribs.backing_store = DoesBackingStore(screen);
298 matty 28
299 matty 29 if (attribs.backing_store == NotUseful)
300 matty 31 ownbackstore = True;
301 matty 29
302 matty 28 if (fullscreen)
303     {
304     attribs.override_redirect = True;
305 matty 29 width = WidthOfScreen(screen);
306     height = HeightOfScreen(screen);
307 matty 28 }
308     else
309     {
310     attribs.override_redirect = False;
311     }
312    
313 matty 30 width = (width + 3) & ~3; /* make width a multiple of 32 bits */
314 matty 29
315     wnd = XCreateWindow(display, RootWindowOfScreen(screen),
316 matty 28 0, 0, width, height, 0, CopyFromParent,
317     InputOutput, CopyFromParent,
318     CWBackingStore | CWBackPixel | CWOverrideRedirect,
319     &attribs);
320 matty 9
321 matty 10 XStoreName(display, wnd, title);
322 matty 6
323 matty 28 classhints = XAllocClassHint();
324     if (classhints != NULL)
325     {
326 matty 29 classhints->res_name = classhints->res_class = "rdesktop";
327 matty 28 XSetClassHint(display, wnd, classhints);
328     XFree(classhints);
329     }
330    
331     sizehints = XAllocSizeHints();
332     if (sizehints)
333     {
334 matty 29 sizehints->flags = PMinSize | PMaxSize;
335     sizehints->min_width = sizehints->max_width = width;
336     sizehints->min_height = sizehints->max_height = height;
337 matty 28 XSetWMNormalHints(display, wnd, sizehints);
338     XFree(sizehints);
339     }
340    
341 matthewc 50 xkeymap_init();
342 matthewc 38
343 n-ki 52 input_mask = KeyPressMask | KeyReleaseMask |
344     ButtonPressMask | ButtonReleaseMask |
345 n-ki 54 EnterWindowMask | LeaveWindowMask;
346 matty 29 if (sendmotion)
347 matty 10 input_mask |= PointerMotionMask;
348 matty 6
349 matty 31 if (ownbackstore)
350     input_mask |= ExposureMask;
351    
352 matty 10 XSelectInput(display, wnd, input_mask);
353     gc = XCreateGC(display, wnd, 0, NULL);
354 matty 7
355 matty 31 if (ownbackstore)
356     backstore = XCreatePixmap(display, wnd, width, height, depth);
357    
358 matty 28 XMapWindow(display, wnd);
359 n-ki 52
360     /* TODO: error texts... make them friendly. */
361     xkb = XkbGetKeyboard(display, XkbAllComponentsMask, XkbUseCoreKbd);
362     if ((int)xkb == BadAlloc || xkb == NULL)
363     {
364     error( "XkbGetKeyboard failed.\n");
365     exit(0);
366     }
367    
368     /* TODO: error texts... make them friendly. */
369     if( XkbSelectEvents(display, xkb->device_spec, XkbAllEventsMask, XkbAllEventsMask) == False )
370     {
371     error( "XkbSelectEvents failed.\n");
372     exit(0);
373     }
374 n-ki 54
375     xwin_get_numlock_mask();
376 n-ki 52
377 matty 10 return True;
378 matty 6 }
379    
380 matty 25 void
381 n-ki 54 xwin_get_numlock_mask()
382     {
383     KeyCode numlockcode;
384     KeyCode* keycode;
385     XModifierKeymap *modmap;
386     int i,j;
387    
388     /* Find out if numlock is already defined as a modifier key, and if so where */
389     numlockcode = XKeysymToKeycode(display, 0xFF7F); /* XF_Num_Lock = 0xFF7F */
390     if (numlockcode) {
391     modmap = XGetModifierMapping(display);
392     if (modmap) {
393     keycode = modmap->modifiermap;
394     for (i = 0; i < 8; i++)
395     for (j = modmap->max_keypermod; j--;) {
396     if (*keycode == numlockcode) {
397     numlock_modifier_mask = (1 << i);
398     i = 8;
399     break;
400     }
401     keycode++;
402     }
403     if (!numlock_modifier_mask) {
404     modmap->modifiermap[7 * modmap->max_keypermod] = numlockcode;
405     if (XSetModifierMapping(display, modmap) == MappingSuccess)
406     numlock_modifier_mask = (1 << 7);
407     else
408     printf("XSetModifierMapping failed!\n");
409     }
410     XFreeModifiermap(modmap);
411     }
412     }
413    
414     if (!numlock_modifier_mask)
415     printf("WARNING: Failed to get a numlock modifier mapping.\n");
416    
417     }
418    
419     void
420 matty 25 ui_destroy_window()
421 matty 6 {
422 n-ki 52 if( xkb != NULL )
423     XkbFreeKeyboard(xkb, XkbAllControlsMask, True);
424    
425 matty 31 if (ownbackstore)
426     XFreePixmap(display, backstore);
427    
428 matty 10 XFreeGC(display, gc);
429     XDestroyWindow(display, wnd);
430     XCloseDisplay(display);
431 matty 28 display = NULL;
432 matty 6 }
433    
434 matty 33 static void
435     xwin_process_events()
436 matty 9 {
437 n-ki 54 XEvent xevent;
438    
439 matthewc 38 KeySym keysym;
440 matty 9 uint8 scancode;
441 matthewc 50 uint16 button, flags;
442 matty 10 uint32 ev_time;
443 n-ki 52 uint32 tmpmods;
444 matty 9
445 n-ki 54 while (XCheckMaskEvent(display, ~0, &xevent))
446 matty 9 {
447 matty 10 ev_time = time(NULL);
448 matthewc 50 flags = 0;
449 matty 10
450 n-ki 54 switch (xevent.type)
451 matty 9 {
452 matthewc 50 case KeyRelease:
453     flags = KBD_FLAG_DOWN | KBD_FLAG_UP;
454     /* fall through */
455 matty 9 case KeyPress:
456 n-ki 54 if( XkbTranslateKeyCode(xkb, xevent.xkey.keycode, xevent.xkey.state, &tmpmods, &keysym) == False )
457 matty 9 break;
458 n-ki 54 scancode = xkeymap_translate_key(keysym, xevent.xkey.keycode, &flags);
459 matty 9
460 n-ki 52 if (scancode == 0 )
461     break;
462    
463     /* keep track of the modifiers -- needed for stickykeys... */
464 n-ki 54 if( xevent.type == KeyPress )
465     xwin_mod_press( xevent.xkey.state, ev_time, scancode );
466 n-ki 52
467 matthewc 50 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, flags, scancode, 0);
468 n-ki 52
469 n-ki 54 if( xevent.type == KeyRelease )
470     xwin_mod_release( xevent.xkey.state, ev_time, scancode );
471 n-ki 52
472 matty 9 break;
473    
474     case ButtonPress:
475 matthewc 50 flags = MOUSE_FLAG_DOWN;
476     /* fall through */
477 matty 9
478     case ButtonRelease:
479 n-ki 54 button = xkeymap_translate_button(xevent.xbutton.button);
480 matty 9 if (button == 0)
481     break;
482    
483 matty 10 rdp_send_input(ev_time, RDP_INPUT_MOUSE,
484 matthewc 50 flags | button,
485 n-ki 54 xevent.xbutton.x,
486     xevent.xbutton.y);
487 matty 10 break;
488    
489     case MotionNotify:
490     rdp_send_input(ev_time, RDP_INPUT_MOUSE,
491 matty 24 MOUSE_FLAG_MOVE,
492 n-ki 54 xevent.xmotion.x,
493     xevent.xmotion.y);
494 matty 28 break;
495    
496     case EnterNotify:
497 matty 29 XGrabKeyboard(display, wnd, True, GrabModeAsync,
498     GrabModeAsync, CurrentTime);
499 n-ki 54
500     xwin_mod_update( xevent.xcrossing.state, ev_time );
501 matty 28 break;
502    
503     case LeaveNotify:
504 matty 29 XUngrabKeyboard(display, CurrentTime);
505 matty 28 break;
506 matty 31
507     case Expose:
508     XCopyArea(display, backstore, wnd, gc,
509 n-ki 54 xevent.xexpose.x, xevent.xexpose.y,
510     xevent.xexpose.width, xevent.xexpose.height,
511     xevent.xexpose.x, xevent.xexpose.y);
512 matty 31 break;
513 matty 9 }
514     }
515     }
516    
517 matty 25 void
518 n-ki 54 xwin_mod_update(uint32 state, uint32 ev_time )
519 n-ki 52 {
520 n-ki 54 xwin_mod_press(state, ev_time, 0);
521     xwin_mod_release(state, ev_time, 0);
522     }
523    
524     void
525     xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode)
526     {
527 n-ki 52 switch (scancode) {
528     case 0x2a:
529     key_down_state &= ~DShift1Mask;
530     break;
531     case 0x36:
532     key_down_state &= ~DShift2Mask;
533     break;
534     case 0x1d:
535     key_down_state &= ~DControl1Mask;
536     break;
537     case 0x9d:
538     key_down_state &= ~DControl2Mask;
539     break;
540     case 0x38:
541     key_down_state &= ~DMod1Mask;
542     break;
543     case 0xb8:
544     key_down_state &= ~DMod2Mask;
545     break;
546     }
547    
548 n-ki 54 if( !(numlock_modifier_mask & state) && (key_down_state & DNumLockMask) )
549 n-ki 52 {
550 n-ki 54 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0);
551     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0);
552     key_down_state &= ~DNumLockMask;
553     }
554    
555     if( !(LockMask & state) && (key_down_state & DLockMask))
556     {
557     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);
558     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);
559     key_down_state &= ~DLockMask;
560    
561     }
562    
563    
564     if( !(ShiftMask & state) && (key_down_state & DShift1Mask))
565     {
566 n-ki 52 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x2a, 0);
567     key_down_state &= ~DShift1Mask;
568    
569     }
570    
571 n-ki 54 if( !(ControlMask & state) && (key_down_state & DControl1Mask))
572 n-ki 52 {
573     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x1d, 0);
574     key_down_state &= ~DControl1Mask;
575    
576     }
577 n-ki 54
578     if( !(Mod1Mask & state) && (key_down_state & DMod1Mask))
579 n-ki 52 {
580     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x38, 0);
581     key_down_state &= ~DMod1Mask;
582    
583     }
584 n-ki 54
585     if( !(Mod2Mask & state) && (key_down_state & DMod2Mask))
586 n-ki 52 {
587     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0xb8, 0);
588     key_down_state &= ~DMod2Mask;
589     }
590     }
591    
592    
593     void
594 n-ki 54 xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode)
595 n-ki 52 {
596    
597     switch (scancode) {
598     case 0x2a:
599     key_down_state |= DShift1Mask;
600     break;
601     case 0x36:
602     key_down_state |= DShift2Mask;
603     break;
604     case 0x1d:
605     key_down_state |= DControl1Mask;
606     break;
607     case 0x9d:
608     key_down_state |= DControl2Mask;
609     break;
610 n-ki 54 case 0x3a:
611     key_down_state ^= DLockMask;
612     break;
613     case 0x45:
614     key_down_state ^= DNumLockMask;
615     break;
616 n-ki 52 case 0x38:
617     key_down_state |= DMod1Mask;
618     break;
619     case 0xb8:
620     key_down_state |= DMod2Mask;
621     break;
622     }
623    
624 n-ki 54 if( (numlock_modifier_mask && state) && !(key_down_state & DNumLockMask) )
625 n-ki 52 {
626 n-ki 54 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0);
627     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0);
628     key_down_state |= DNumLockMask;
629     }
630    
631     if( (LockMask & state) && !(key_down_state & DLockMask))
632     {
633     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);
634     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);
635     key_down_state |= DLockMask;
636    
637     }
638    
639    
640     if( (ShiftMask & state) && !((key_down_state & DShift1Mask) || (key_down_state & DShift2Mask)))
641     {
642 n-ki 52 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x2a, 0);
643     key_down_state |= DShift1Mask;
644    
645     }
646    
647 n-ki 54 if( (ControlMask & state) && !((key_down_state & DControl1Mask) || (key_down_state & DControl2Mask)))
648 n-ki 52 {
649     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x1d, 0);
650     key_down_state |= DControl1Mask;
651    
652     }
653    
654 n-ki 54 if( (Mod1Mask & state) && !(key_down_state & DMod1Mask))
655 n-ki 52 {
656     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x38, 0);
657     key_down_state |= DMod1Mask;
658    
659     }
660    
661 n-ki 54 if( (Mod2Mask & state) && !(key_down_state & DMod2Mask))
662 n-ki 52 {
663     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0xb8, 0);
664     key_down_state |= DMod2Mask;
665    
666     }
667     }
668    
669     void
670 matty 33 ui_select(int rdp_socket)
671     {
672     int n = (rdp_socket > x_socket) ? rdp_socket+1 : x_socket+1;
673     fd_set rfds;
674    
675     FD_ZERO(&rfds);
676    
677     while (True)
678     {
679     FD_ZERO(&rfds);
680     FD_SET(rdp_socket, &rfds);
681 matthewc 53 if (display != NULL)
682     {
683     FD_SET(x_socket, &rfds);
684     XFlush(display);
685     }
686 matty 33
687     switch (select(n, &rfds, NULL, NULL, NULL))
688     {
689     case -1:
690     error("select: %s\n", strerror(errno));
691    
692     case 0:
693     continue;
694     }
695    
696     if (FD_ISSET(x_socket, &rfds))
697     xwin_process_events();
698    
699     if (FD_ISSET(rdp_socket, &rfds))
700     return;
701     }
702     }
703    
704     void
705 matty 25 ui_move_pointer(int x, int y)
706 matty 9 {
707 matty 10 XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
708 matty 9 }
709    
710 matty 25 HBITMAP
711     ui_create_bitmap(int width, int height, uint8 *data)
712 matty 6 {
713     XImage *image;
714 matty 9 Pixmap bitmap;
715 matty 28 uint8 *tdata;
716 matty 29
717 matty 33 tdata = (owncolmap ? data : translate_image(width, height, data));
718 matty 28 bitmap = XCreatePixmap(display, wnd, width, height, depth);
719 matty 29 image = XCreateImage(display, visual, depth, ZPixmap,
720     0, tdata, width, height, 8, 0);
721 matty 6
722 matty 28 XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
723 matty 9
724     XFree(image);
725 matty 29 if (!owncolmap)
726 matty 28 xfree(tdata);
727 matty 24 return (HBITMAP) bitmap;
728 matty 6 }
729    
730 matty 25 void
731     ui_paint_bitmap(int x, int y, int cx, int cy,
732     int width, int height, uint8 *data)
733 matty 6 {
734 matty 10 XImage *image;
735 matty 29 uint8 *tdata;
736 matty 10
737 matty 33 tdata = (owncolmap ? data : translate_image(width, height, data));
738 matty 29 image = XCreateImage(display, visual, depth, ZPixmap,
739     0, tdata, width, height, 8, 0);
740 matty 28
741 matty 31 if (ownbackstore)
742     {
743     XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
744     XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
745     }
746     else
747     {
748     XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
749     }
750 matty 29
751 matty 24 XFree(image);
752 matty 29 if (!owncolmap)
753 matty 28 xfree(tdata);
754 matty 6 }
755    
756 matty 25 void
757     ui_destroy_bitmap(HBITMAP bmp)
758 matty 6 {
759 matty 29 XFreePixmap(display, (Pixmap)bmp);
760 matty 10 }
761    
762 matty 25 HGLYPH
763     ui_create_glyph(int width, int height, uint8 *data)
764 matty 10 {
765 matty 9 XImage *image;
766     Pixmap bitmap;
767     int scanline;
768     GC gc;
769 matty 6
770 matty 9 scanline = (width + 7) / 8;
771 matty 6
772 matty 10 bitmap = XCreatePixmap(display, wnd, width, height, 1);
773     gc = XCreateGC(display, bitmap, 0, NULL);
774 matty 9
775 matty 10 image = XCreateImage(display, visual, 1, ZPixmap, 0,
776 matty 24 data, width, height, 8, scanline);
777 matty 23 image->byte_order = MSBFirst;
778     image->bitmap_bit_order = MSBFirst;
779     XInitImage(image);
780    
781 matty 10 XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
782 matty 29
783 matty 9 XFree(image);
784 matty 10 XFreeGC(display, gc);
785 matty 29 return (HGLYPH)bitmap;
786 matty 6 }
787 matty 7
788 matty 25 void
789     ui_destroy_glyph(HGLYPH glyph)
790 matty 7 {
791 matty 29 XFreePixmap(display, (Pixmap)glyph);
792 matty 9 }
793    
794 matty 29 HCURSOR
795     ui_create_cursor(unsigned int x, unsigned int y, int width,
796     int height, uint8 *andmask, uint8 *xormask)
797 matty 9 {
798 matty 29 HGLYPH maskglyph, cursorglyph;
799     XColor bg, fg;
800     Cursor xcursor;
801     uint8 *cursor, *pcursor;
802     uint8 *mask, *pmask;
803     uint8 nextbit;
804     int scanline, offset;
805     int i, j;
806    
807     scanline = (width + 7) / 8;
808     offset = scanline * height;
809    
810     cursor = xmalloc(offset);
811     memset(cursor, 0, offset);
812    
813     mask = xmalloc(offset);
814     memset(mask, 0, offset);
815    
816     /* approximate AND and XOR masks with a monochrome X pointer */
817     for (i = 0; i < height; i++)
818 matty 7 {
819 matty 29 offset -= scanline;
820     pcursor = &cursor[offset];
821     pmask = &mask[offset];
822    
823     for (j = 0; j < scanline; j++)
824 matty 28 {
825 matty 29 for (nextbit = 0x80; nextbit != 0; nextbit >>= 1)
826     {
827     if (xormask[0] || xormask[1] || xormask[2])
828     {
829     *pcursor |= (~(*andmask) & nextbit);
830     *pmask |= nextbit;
831     }
832     else
833     {
834     *pcursor |= ((*andmask) & nextbit);
835     *pmask |= (~(*andmask) & nextbit);
836     }
837    
838     xormask += 3;
839     }
840    
841     andmask++;
842     pcursor++;
843     pmask++;
844 matty 28 }
845 matty 7 }
846 matty 29
847     fg.red = fg.blue = fg.green = 0xffff;
848     bg.red = bg.blue = bg.green = 0x0000;
849     fg.flags = bg.flags = DoRed | DoBlue | DoGreen;
850    
851     cursorglyph = ui_create_glyph(width, height, cursor);
852     maskglyph = ui_create_glyph(width, height, mask);
853    
854     xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,
855     (Pixmap)maskglyph, &fg, &bg, x, y);
856    
857     ui_destroy_glyph(maskglyph);
858     ui_destroy_glyph(cursorglyph);
859     xfree(mask);
860     xfree(cursor);
861     return (HCURSOR)xcursor;
862     }
863    
864     void
865     ui_set_cursor(HCURSOR cursor)
866     {
867     XDefineCursor(display, wnd, (Cursor)cursor);
868     }
869    
870     void
871     ui_destroy_cursor(HCURSOR cursor)
872     {
873     XFreeCursor(display, (Cursor)cursor);
874     }
875    
876     #define MAKE_XCOLOR(xc,c) \
877     (xc)->red = ((c)->red << 8) | (c)->red; \
878     (xc)->green = ((c)->green << 8) | (c)->green; \
879     (xc)->blue = ((c)->blue << 8) | (c)->blue; \
880     (xc)->flags = DoRed | DoGreen | DoBlue;
881    
882     HCOLOURMAP
883     ui_create_colourmap(COLOURMAP *colours)
884     {
885     COLOURENTRY *entry;
886     int i, ncolours = colours->ncolours;
887    
888     if (owncolmap)
889 matty 28 {
890     XColor *xcolours, *xentry;
891     Colormap map;
892 matty 29
893 matty 28 xcolours = xmalloc(sizeof(XColor) * ncolours);
894     for (i = 0; i < ncolours; i++)
895     {
896     entry = &colours->colours[i];
897     xentry = &xcolours[i];
898     xentry->pixel = i;
899 matty 29 MAKE_XCOLOR(xentry, entry);
900 matty 28 }
901 matty 7
902 matty 28 map = XCreateColormap(display, wnd, visual, AllocAll);
903     XStoreColors(display, map, xcolours, ncolours);
904    
905     xfree(xcolours);
906 matty 29 return (HCOLOURMAP)map;
907 matty 28 }
908 matty 29 else
909     {
910     uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
911     XColor xentry;
912 matty 33 uint32 colour;
913 matty 29
914     for (i = 0; i < ncolours; i++)
915     {
916     entry = &colours->colours[i];
917     MAKE_XCOLOR(&xentry, entry);
918    
919     if (XAllocColor(display, xcolmap, &xentry) != 0)
920 matty 34 colour = xentry.pixel;
921 matty 29 else
922 matty 34 colour = white;
923 matty 33
924     /* byte swap here to make translate_image faster */
925     map[i] = translate_colour(colour);
926 matty 29 }
927    
928     return map;
929     }
930 matty 7 }
931    
932 matty 25 void
933     ui_destroy_colourmap(HCOLOURMAP map)
934 matty 7 {
935 matty 29 if (owncolmap)
936     XFreeColormap(display, (Colormap)map);
937     else
938     xfree(map);
939 matty 7 }
940    
941 matty 25 void
942     ui_set_colourmap(HCOLOURMAP map)
943 matty 7 {
944 matty 29 if (owncolmap)
945     XSetWindowColormap(display, wnd, (Colormap)map);
946     else
947 matty 28 colmap = map;
948 matty 7 }
949    
950 matty 25 void
951     ui_set_clip(int x, int y, int cx, int cy)
952 matty 7 {
953 matty 9 XRectangle rect;
954 matty 7
955 matty 9 rect.x = x;
956     rect.y = y;
957     rect.width = cx;
958     rect.height = cy;
959 matty 10 XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
960 matty 9 }
961 matty 7
962 matty 25 void
963     ui_reset_clip()
964 matty 9 {
965     XRectangle rect;
966    
967     rect.x = 0;
968     rect.y = 0;
969 matty 10 rect.width = width;
970     rect.height = height;
971     XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
972 matty 7 }
973    
974 matty 25 void
975     ui_bell()
976 matty 10 {
977     XBell(display, 0);
978     }
979    
980 matty 25 void
981     ui_destblt(uint8 opcode,
982     /* dest */ int x, int y, int cx, int cy)
983 matty 9 {
984 matty 29 SET_FUNCTION(opcode);
985 matty 31 FILL_RECTANGLE(x, y, cx, cy);
986 matty 29 RESET_FUNCTION(opcode);
987 matty 9 }
988    
989 matty 25 void
990     ui_patblt(uint8 opcode,
991     /* dest */ int x, int y, int cx, int cy,
992     /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
993 matty 9 {
994     Pixmap fill;
995 jsorg71 59 uint8 i, ipattern[8];
996 matty 9
997 matty 29 SET_FUNCTION(opcode);
998 matty 9
999     switch (brush->style)
1000     {
1001 matty 24 case 0: /* Solid */
1002 matty 29 SET_FOREGROUND(fgcolour);
1003 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1004 matty 9 break;
1005    
1006 matty 24 case 3: /* Pattern */
1007 jsorg71 59 for (i = 0; i != 8; i++)
1008     ipattern[7 - i] = brush->pattern[i];
1009     fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
1010 matty 9
1011 matty 29 SET_FOREGROUND(bgcolour);
1012     SET_BACKGROUND(fgcolour);
1013     XSetFillStyle(display, gc, FillOpaqueStippled);
1014     XSetStipple(display, gc, fill);
1015     XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
1016 matty 9
1017 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1018 matty 9
1019 matty 29 XSetFillStyle(display, gc, FillSolid);
1020     ui_destroy_glyph((HGLYPH)fill);
1021 matty 9 break;
1022    
1023     default:
1024 matty 30 unimpl("brush %d\n", brush->style);
1025 matty 9 }
1026 matty 29
1027     RESET_FUNCTION(opcode);
1028 matty 9 }
1029    
1030 matty 25 void
1031     ui_screenblt(uint8 opcode,
1032     /* dest */ int x, int y, int cx, int cy,
1033     /* src */ int srcx, int srcy)
1034 matty 9 {
1035 matty 29 SET_FUNCTION(opcode);
1036 matty 24 XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
1037 matty 31 if (ownbackstore)
1038     XCopyArea(display, backstore, backstore, gc, srcx, srcy,
1039     cx, cy, x, y);
1040 matty 29 RESET_FUNCTION(opcode);
1041 matty 9 }
1042    
1043 matty 25 void
1044     ui_memblt(uint8 opcode,
1045     /* dest */ int x, int y, int cx, int cy,
1046     /* src */ HBITMAP src, int srcx, int srcy)
1047 matty 9 {
1048 matty 29 SET_FUNCTION(opcode);
1049     XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);
1050 matty 31 if (ownbackstore)
1051     XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,
1052     cx, cy, x, y);
1053 matty 29 RESET_FUNCTION(opcode);
1054 matty 9 }
1055    
1056 matty 25 void
1057     ui_triblt(uint8 opcode,
1058     /* dest */ int x, int y, int cx, int cy,
1059     /* src */ HBITMAP src, int srcx, int srcy,
1060     /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
1061 matty 9 {
1062     /* This is potentially difficult to do in general. Until someone
1063 matty 10 comes up with a more efficient way of doing it I am using cases. */
1064 matty 9
1065     switch (opcode)
1066     {
1067 matty 24 case 0x69: /* PDSxxn */
1068 matty 16 ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1069     ui_patblt(ROP2_NXOR, x, y, cx, cy,
1070 matty 24 brush, bgcolour, fgcolour);
1071 matty 16 break;
1072    
1073 matty 24 case 0xb8: /* PSDPxax */
1074 matty 10 ui_patblt(ROP2_XOR, x, y, cx, cy,
1075 matty 24 brush, bgcolour, fgcolour);
1076 matty 16 ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1077 matty 10 ui_patblt(ROP2_XOR, x, y, cx, cy,
1078 matty 24 brush, bgcolour, fgcolour);
1079 matty 9 break;
1080    
1081 matty 29 case 0xc0: /* PSa */
1082 matty 28 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1083     ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,
1084     fgcolour);
1085     break;
1086    
1087 matty 9 default:
1088 matty 30 unimpl("triblt 0x%x\n", opcode);
1089 matty 16 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1090 matty 9 }
1091     }
1092    
1093 matty 25 void
1094     ui_line(uint8 opcode,
1095     /* dest */ int startx, int starty, int endx, int endy,
1096     /* pen */ PEN *pen)
1097 matty 9 {
1098 matty 29 SET_FUNCTION(opcode);
1099     SET_FOREGROUND(pen->colour);
1100 matty 10 XDrawLine(display, wnd, gc, startx, starty, endx, endy);
1101 matty 31 if (ownbackstore)
1102     XDrawLine(display, backstore, gc, startx, starty, endx, endy);
1103 matty 29 RESET_FUNCTION(opcode);
1104 matty 9 }
1105    
1106 matty 25 void
1107     ui_rect(
1108     /* dest */ int x, int y, int cx, int cy,
1109     /* brush */ int colour)
1110 matty 9 {
1111 matty 29 SET_FOREGROUND(colour);
1112 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1113 matty 9 }
1114    
1115 matty 25 void
1116     ui_draw_glyph(int mixmode,
1117     /* dest */ int x, int y, int cx, int cy,
1118     /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,
1119     int fgcolour)
1120 matty 9 {
1121 matty 29 SET_FOREGROUND(fgcolour);
1122     SET_BACKGROUND(bgcolour);
1123 matty 9
1124 matty 29 XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)
1125     ? FillStippled : FillOpaqueStippled);
1126     XSetStipple(display, gc, (Pixmap)glyph);
1127     XSetTSOrigin(display, gc, x, y);
1128 matty 9
1129 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1130 matty 9
1131 matty 29 XSetFillStyle(display, gc, FillSolid);
1132 matty 9 }
1133    
1134 mmihalik 49 #define DO_GLYPH(ttext,idx) \
1135     {\
1136     glyph = cache_get_font (font, ttext[idx]);\
1137     if (!(flags & TEXT2_IMPLICIT_X))\
1138     {\
1139     xyoffset = ttext[++idx];\
1140     if ((xyoffset & 0x80))\
1141     {\
1142     if (flags & TEXT2_VERTICAL) \
1143     y += ttext[++idx] | (ttext[++idx] << 8);\
1144     else\
1145     x += ttext[++idx] | (ttext[++idx] << 8);\
1146     }\
1147     else\
1148     {\
1149     if (flags & TEXT2_VERTICAL) \
1150     y += xyoffset;\
1151     else\
1152     x += xyoffset;\
1153     }\
1154     }\
1155     if (glyph != NULL)\
1156     {\
1157     ui_draw_glyph (mixmode, x + (short) glyph->offset,\
1158     y + (short) glyph->baseline,\
1159     glyph->width, glyph->height,\
1160     glyph->pixmap, 0, 0, bgcolour, fgcolour);\
1161     if (flags & TEXT2_IMPLICIT_X)\
1162     x += glyph->width;\
1163     }\
1164     }
1165    
1166 matty 25 void
1167     ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
1168 mmihalik 49 int clipx, int clipy, int clipcx, int clipcy, int boxx,
1169     int boxy, int boxcx, int boxcy, int bgcolour,
1170     int fgcolour, uint8 * text, uint8 length)
1171 matty 9 {
1172 matty 10 FONTGLYPH *glyph;
1173 mmihalik 49 int i, j, xyoffset;
1174     DATABLOB *entry;
1175 matty 9
1176 matty 29 SET_FOREGROUND(bgcolour);
1177 matty 28
1178 matty 9 if (boxcx > 1)
1179 matty 31 {
1180     FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);
1181     }
1182 matty 17 else if (mixmode == MIX_OPAQUE)
1183 matty 31 {
1184     FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);
1185     }
1186 matty 9
1187     /* Paint text, character by character */
1188 mmihalik 49 for (i = 0; i < length;) {
1189     switch (text[i]) {
1190     case 0xff:
1191     if (i + 2 < length)
1192     cache_put_text(text[i + 1], text, text[i + 2]);
1193     else {
1194     error("this shouldn't be happening\n");
1195     break;
1196     }
1197     /* this will move pointer from start to first character after FF command */
1198     length -= i + 3;
1199     text = &(text[i + 3]);
1200     i = 0;
1201     break;
1202 matty 9
1203 mmihalik 49 case 0xfe:
1204     entry = cache_get_text(text[i + 1]);
1205     if (entry != NULL) {
1206     if ((((uint8 *) (entry->data))[1] == 0)
1207     && (!(flags & TEXT2_IMPLICIT_X))) {
1208 n-ki 52 if (flags & TEXT2_VERTICAL)
1209 mmihalik 49 y += text[i + 2];
1210     else
1211     x += text[i + 2];
1212 matthewc 44 }
1213 mmihalik 49 if (i + 2 < length)
1214     i += 3;
1215 matthewc 44 else
1216 mmihalik 49 i += 2;
1217 n-ki 52 length -= i;
1218 mmihalik 49 /* this will move pointer from start to first character after FE command */
1219     text = &(text[i]);
1220     i = 0;
1221     for (j = 0; j < entry->size; j++)
1222     DO_GLYPH(((uint8 *) (entry->data)), j);
1223 matthewc 44 }
1224 mmihalik 49 break;
1225 matty 17
1226 mmihalik 49 default:
1227     DO_GLYPH(text, i);
1228     i++;
1229     break;
1230 matty 29 }
1231 mmihalik 49 }
1232 matty 28
1233 matty 9
1234     }
1235    
1236 matty 25 void
1237     ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
1238 matty 9 {
1239 matty 28 Pixmap pix;
1240 matty 9 XImage *image;
1241    
1242 matty 31 if (ownbackstore)
1243     {
1244     image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,
1245     ZPixmap);
1246     }
1247     else
1248     {
1249     pix = XCreatePixmap(display, wnd, cx, cy, depth);
1250     XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
1251     image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,
1252     ZPixmap);
1253     XFreePixmap(display, pix);
1254     }
1255 matty 28
1256     offset *= bpp/8;
1257     cache_put_desktop(offset, cx, cy, image->bytes_per_line,
1258 matty 36 bpp/8, (uint8 *)image->data);
1259 matty 28
1260     XDestroyImage(image);
1261 matty 9 }
1262    
1263 matty 25 void
1264     ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
1265 matty 9 {
1266     XImage *image;
1267 matty 10 uint8 *data;
1268 matty 9
1269 matty 28 offset *= bpp/8;
1270     data = cache_get_desktop(offset, cx, cy, bpp/8);
1271 matty 10 if (data == NULL)
1272     return;
1273 matty 29
1274     image = XCreateImage(display, visual, depth, ZPixmap,
1275 matty 28 0, data, cx, cy, BitmapPad(display),
1276     cx * bpp/8);
1277 matty 29
1278 matty 31 if (ownbackstore)
1279     {
1280     XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
1281     XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
1282     }
1283     else
1284     {
1285     XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
1286     }
1287    
1288 matty 9 XFree(image);
1289     }

  ViewVC Help
Powered by ViewVC 1.1.26