/[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 504 - (hide annotations)
Sun Oct 19 11:59:41 2003 UTC (20 years, 6 months ago) by stargo
File MIME type: text/plain
File size: 42058 byte(s)
Make sure that g_dsp_busy is initialized to False

1 forsberg 415 /* -*- c-basic-offset: 8 -*-
2 matty 6 rdesktop: A Remote Desktop Protocol client.
3 matthewc 38 User interface services - X Window System
4 matthewc 207 Copyright (C) Matthew Chapman 1999-2002
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 matty 10 #include <time.h>
24 matty 33 #include <errno.h>
25 matty 10 #include "rdesktop.h"
26 forsberg 415 #include "xproto.h"
27 matty 6
28 jsorg71 447 extern int g_width;
29     extern int g_height;
30     extern BOOL g_sendmotion;
31     extern BOOL g_fullscreen;
32 jsorg71 450 extern BOOL g_grab_keyboard;
33     extern BOOL g_hide_decorations;
34     extern char g_title[];
35 jsorg71 438 extern int g_server_bpp;
36 jsorg71 450 extern int g_win_button_size;
37 matty 10
38 jsorg71 450 Display *g_display;
39     Time g_last_gesturetime;
40     static int g_x_socket;
41     static Screen *g_screen;
42     Window g_wnd;
43 matthewc 481 BOOL g_enable_compose = False;
44 jsorg71 450 static GC g_gc;
45     static Visual *g_visual;
46     static int g_depth;
47     static int g_bpp;
48     static XIM g_IM;
49     static XIC g_IC;
50     static XModifierKeymap *g_mod_map;
51     static Cursor g_current_cursor;
52     static Atom g_protocol_atom, g_kill_atom;
53 matthewc 481 static BOOL g_focused;
54     static BOOL g_mouse_in_wnd;
55 matty 29
56 matty 33 /* endianness */
57 jsorg71 450 static BOOL g_host_be;
58     static BOOL g_xserver_be;
59 matty 33
60     /* software backing store */
61 jsorg71 450 static BOOL g_ownbackstore;
62     static Pixmap g_backstore;
63 matty 31
64 astrand 342 /* Moving in single app mode */
65 jsorg71 450 static BOOL g_moving_wnd;
66     static int g_move_x_offset = 0;
67     static int g_move_y_offset = 0;
68 astrand 342
69 matthewc 474 #ifdef WITH_RDPSND
70     extern int g_dsp_fd;
71     extern BOOL g_dsp_busy;
72 stargo 501 extern BOOL g_rdpsnd;
73 matthewc 474 #endif
74    
75 astrand 262 /* MWM decorations */
76     #define MWM_HINTS_DECORATIONS (1L << 1)
77     #define PROP_MOTIF_WM_HINTS_ELEMENTS 5
78     typedef struct
79     {
80 matthewc 301 uint32 flags;
81     uint32 functions;
82     uint32 decorations;
83     sint32 inputMode;
84     uint32 status;
85 astrand 262 }
86     PropMotifWmHints;
87    
88 jsorg71 316 typedef struct
89     {
90     uint32 red;
91     uint32 green;
92     uint32 blue;
93     }
94     PixelColour;
95 astrand 262
96 forsberg 415
97 matty 31 #define FILL_RECTANGLE(x,y,cx,cy)\
98     { \
99 jsorg71 450 XFillRectangle(g_display, g_wnd, g_gc, x, y, cx, cy); \
100     if (g_ownbackstore) \
101     XFillRectangle(g_display, g_backstore, g_gc, x, y, cx, cy); \
102 matty 31 }
103    
104 matthewc 296 #define FILL_RECTANGLE_BACKSTORE(x,y,cx,cy)\
105 jsorg71 281 { \
106 jsorg71 450 XFillRectangle(g_display, g_ownbackstore ? g_backstore : g_wnd, g_gc, x, y, cx, cy); \
107 jsorg71 281 }
108    
109 matty 33 /* colour maps */
110 jsorg71 450 BOOL g_owncolmap = False;
111     static Colormap g_xcolmap;
112     static uint32 *g_colmap = NULL;
113 matty 10
114 jsorg71 450 #define TRANSLATE(col) ( g_server_bpp != 8 ? translate_colour(col) : g_owncolmap ? col : translate_colour(g_colmap[col]) )
115     #define SET_FOREGROUND(col) XSetForeground(g_display, g_gc, TRANSLATE(col));
116     #define SET_BACKGROUND(col) XSetBackground(g_display, g_gc, TRANSLATE(col));
117 matty 28
118     static int rop2_map[] = {
119     GXclear, /* 0 */
120     GXnor, /* DPon */
121     GXandInverted, /* DPna */
122     GXcopyInverted, /* Pn */
123     GXandReverse, /* PDna */
124     GXinvert, /* Dn */
125     GXxor, /* DPx */
126     GXnand, /* DPan */
127     GXand, /* DPa */
128     GXequiv, /* DPxn */
129     GXnoop, /* D */
130     GXorInverted, /* DPno */
131     GXcopy, /* P */
132     GXorReverse, /* PDno */
133     GXor, /* DPo */
134     GXset /* 1 */
135     };
136    
137 jsorg71 450 #define SET_FUNCTION(rop2) { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, rop2_map[rop2]); }
138     #define RESET_FUNCTION(rop2) { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, GXcopy); }
139 matty 29
140 astrand 319 static void
141 astrand 262 mwm_hide_decorations(void)
142     {
143     PropMotifWmHints motif_hints;
144     Atom hintsatom;
145    
146     /* setup the property */
147     motif_hints.flags = MWM_HINTS_DECORATIONS;
148     motif_hints.decorations = 0;
149    
150     /* get the atom for the property */
151 jsorg71 450 hintsatom = XInternAtom(g_display, "_MOTIF_WM_HINTS", False);
152 astrand 262 if (!hintsatom)
153     {
154 matthewc 297 warning("Failed to get atom _MOTIF_WM_HINTS: probably your window manager does not support MWM hints\n");
155 astrand 262 return;
156     }
157    
158 jsorg71 450 XChangeProperty(g_display, g_wnd, hintsatom, hintsatom, 32, PropModeReplace,
159 astrand 262 (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
160     }
161    
162 astrand 319 static PixelColour
163 jsorg71 316 split_colour15(uint32 colour)
164 jsorg71 311 {
165 jsorg71 316 PixelColour rv;
166     rv.red = (colour & 0x7c00) >> 10;
167     rv.red = (rv.red * 0xff) / 0x1f;
168     rv.green = (colour & 0x03e0) >> 5;
169     rv.green = (rv.green * 0xff) / 0x1f;
170     rv.blue = (colour & 0x1f);
171     rv.blue = (rv.blue * 0xff) / 0x1f;
172     return rv;
173 jsorg71 311 }
174    
175 astrand 319 static PixelColour
176 jsorg71 316 split_colour16(uint32 colour)
177 jsorg71 311 {
178 jsorg71 316 PixelColour rv;
179     rv.red = (colour & 0xf800) >> 11;
180     rv.red = (rv.red * 0xff) / 0x1f;
181     rv.green = (colour & 0x07e0) >> 5;
182     rv.green = (rv.green * 0xff) / 0x3f;
183     rv.blue = (colour & 0x001f);
184     rv.blue = (rv.blue * 0xff) / 0x1f;
185     return rv;
186 jsorg71 311 }
187    
188 astrand 319 static PixelColour
189 jsorg71 316 split_colour24(uint32 colour)
190 jsorg71 311 {
191 jsorg71 316 PixelColour rv;
192     rv.blue = (colour & 0xff0000) >> 16;
193     rv.green = (colour & 0xff00) >> 8;
194     rv.red = (colour & 0xff);
195     return rv;
196 jsorg71 311 }
197    
198 astrand 319 static uint32
199 astrand 318 make_colour16(PixelColour pc)
200 jsorg71 316 {
201     pc.red = (pc.red * 0x1f) / 0xff;
202     pc.green = (pc.green * 0x3f) / 0xff;
203     pc.blue = (pc.blue * 0x1f) / 0xff;
204     return (pc.red << 11) | (pc.green << 5) | pc.blue;
205     }
206    
207 astrand 319 static uint32
208 astrand 318 make_colour24(PixelColour pc)
209 jsorg71 316 {
210 jsorg71 472 if (g_xserver_be)
211     {
212     return pc.red | (pc.green << 8) | (pc.blue << 16);
213     }
214     else
215     {
216     return (pc.red << 16) | (pc.green << 8) | pc.blue;
217     }
218 jsorg71 316 }
219    
220 astrand 319 static uint32
221 astrand 318 make_colour32(PixelColour pc)
222 jsorg71 316 {
223 jsorg71 472 if (g_xserver_be)
224     {
225     return pc.red | (pc.green << 8) | (pc.blue << 16);
226     }
227     else
228     {
229     return (pc.red << 16) | (pc.green << 8) | pc.blue;
230     }
231 jsorg71 316 }
232    
233 jsorg71 311 #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
234     #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }
235     #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
236     x = (x << 16) | (x >> 16); }
237    
238     static uint32
239     translate_colour(uint32 colour)
240     {
241 jsorg71 438 switch (g_server_bpp)
242 jsorg71 311 {
243 jsorg71 316 case 15:
244 jsorg71 450 switch (g_bpp)
245 jsorg71 316 {
246     case 16:
247     colour = make_colour16(split_colour15(colour));
248     break;
249     case 24:
250     colour = make_colour24(split_colour15(colour));
251     break;
252     case 32:
253     colour = make_colour32(split_colour15(colour));
254     break;
255     }
256     break;
257 jsorg71 311 case 16:
258 jsorg71 450 switch (g_bpp)
259 jsorg71 311 {
260     case 16:
261     break;
262     case 24:
263 jsorg71 316 colour = make_colour24(split_colour16(colour));
264 jsorg71 311 break;
265     case 32:
266 jsorg71 316 colour = make_colour32(split_colour16(colour));
267 jsorg71 311 break;
268     }
269     break;
270     case 24:
271 jsorg71 450 switch (g_bpp)
272 jsorg71 311 {
273 jsorg71 316 case 16:
274     colour = make_colour16(split_colour24(colour));
275     break;
276 jsorg71 311 case 24:
277     break;
278     case 32:
279 jsorg71 316 colour = make_colour32(split_colour24(colour));
280 jsorg71 311 break;
281     }
282     break;
283     }
284     return colour;
285     }
286    
287 matty 28 static void
288 jsorg71 311 translate8to8(uint8 * data, uint8 * out, uint8 * end)
289 matty 28 {
290 matty 29 while (out < end)
291 jsorg71 450 *(out++) = (uint8) g_colmap[*(data++)];
292 matty 29 }
293 matty 28
294 matty 29 static void
295 jsorg71 311 translate8to16(uint8 * data, uint16 * out, uint16 * end)
296 matty 29 {
297     while (out < end)
298 jsorg71 450 *(out++) = (uint16) g_colmap[*(data++)];
299 matty 29 }
300    
301 jsorg71 316 /* little endian - conversion happens when colourmap is built */
302 jsorg71 311 static void
303 jsorg71 316 translate8to24(uint8 * data, uint8 * out, uint8 * end)
304 jsorg71 311 {
305 jsorg71 316 uint32 value;
306    
307 jsorg71 311 while (out < end)
308 jsorg71 316 {
309 jsorg71 450 value = g_colmap[*(data++)];
310 jsorg71 316 *(out++) = value;
311     *(out++) = value >> 8;
312     *(out++) = value >> 16;
313     }
314 jsorg71 311 }
315    
316 matty 29 static void
317 jsorg71 316 translate8to32(uint8 * data, uint32 * out, uint32 * end)
318 matty 29 {
319 jsorg71 316 while (out < end)
320 jsorg71 450 *(out++) = g_colmap[*(data++)];
321 jsorg71 316 }
322    
323     /* todo the remaining translate function might need some big endian check ?? */
324    
325     static void
326 jsorg71 483 translate15to16(uint16 * data, uint8 * out, uint8 * end)
327 jsorg71 316 {
328 jsorg71 483 uint16 pixel;
329     uint16 value;
330    
331 jsorg71 316 while (out < end)
332 jsorg71 483 {
333     pixel = *(data++);
334    
335     if (g_host_be)
336     {
337 astrand 499 BSWAP16(pixel)}
338 jsorg71 483
339     value = make_colour16(split_colour15(pixel));
340    
341     if (g_xserver_be)
342     {
343     *(out++) = value >> 8;
344     *(out++) = value;
345     }
346     else
347     {
348     *(out++) = value;
349     *(out++) = value >> 8;
350     }
351     }
352 jsorg71 316 }
353    
354     static void
355     translate15to24(uint16 * data, uint8 * out, uint8 * end)
356     {
357 matty 29 uint32 value;
358 jsorg71 483 uint16 pixel;
359 matty 29
360     while (out < end)
361 matty 28 {
362 jsorg71 483 pixel = *(data++);
363    
364     if (g_host_be)
365     {
366 astrand 499 BSWAP16(pixel)}
367 jsorg71 483
368     value = make_colour24(split_colour15(pixel));
369     if (g_xserver_be)
370     {
371     *(out++) = value >> 16;
372     *(out++) = value >> 8;
373     *(out++) = value;
374     }
375     else
376     {
377     *(out++) = value;
378     *(out++) = value >> 8;
379     *(out++) = value >> 16;
380     }
381 matty 28 }
382     }
383    
384     static void
385 jsorg71 483 translate15to32(uint16 * data, uint8 * out, uint8 * end)
386 jsorg71 316 {
387 jsorg71 472 uint16 pixel;
388 jsorg71 483 uint32 value;
389 jsorg71 472
390 jsorg71 316 while (out < end)
391 jsorg71 472 {
392 jsorg71 483 pixel = *(data++);
393    
394 jsorg71 472 if (g_host_be)
395     {
396 jsorg71 483 BSWAP16(pixel);
397 jsorg71 472 }
398 jsorg71 483
399     value = make_colour32(split_colour15(pixel));
400    
401     if (g_xserver_be)
402     {
403     *(out++) = value >> 24;
404     *(out++) = value >> 16;
405     *(out++) = value >> 8;
406     *(out++) = value;
407     }
408 jsorg71 472 else
409     {
410 jsorg71 483 *(out++) = value;
411     *(out++) = value >> 8;
412     *(out++) = value >> 16;
413     *(out++) = value >> 24;
414 jsorg71 472 }
415     }
416 jsorg71 316 }
417    
418     static void
419     translate16to16(uint16 * data, uint16 * out, uint16 * end)
420     {
421 jsorg71 483 uint16 value;
422    
423     if (g_xserver_be)
424     {
425     while (out < end)
426     {
427     value = *data;
428     BSWAP16(value);
429     *out = value;
430     data++;
431     out++;
432     }
433    
434     }
435     else
436     {
437     while (out < end)
438     {
439     *out = *data;
440     out++;
441     data++;
442     }
443     }
444 jsorg71 316 }
445    
446    
447     static void
448 jsorg71 311 translate16to24(uint16 * data, uint8 * out, uint8 * end)
449 matty 28 {
450 jsorg71 311 uint32 value;
451 jsorg71 483 uint16 pixel;
452 jsorg71 311
453 matty 29 while (out < end)
454 jsorg71 311 {
455 jsorg71 483 pixel = *(data++);
456    
457     if (g_host_be)
458     {
459 astrand 499 BSWAP16(pixel)}
460 jsorg71 483
461     value = make_colour24(split_colour16(pixel));
462    
463     if (g_xserver_be)
464     {
465     *(out++) = value >> 16;
466     *(out++) = value >> 8;
467     *(out++) = value;
468     }
469     else
470     {
471     *(out++) = value;
472     *(out++) = value >> 8;
473     *(out++) = value >> 16;
474     }
475 jsorg71 311 }
476     }
477    
478     static void
479 jsorg71 483 translate16to32(uint16 * data, uint8 * out, uint8 * end)
480 jsorg71 311 {
481 jsorg71 472 uint16 pixel;
482 jsorg71 483 uint32 value;
483 jsorg71 472
484 jsorg71 311 while (out < end)
485 jsorg71 472 {
486 jsorg71 483 pixel = *(data++);
487    
488 jsorg71 472 if (g_host_be)
489     {
490 astrand 499 BSWAP16(pixel)}
491 jsorg71 483
492     value = make_colour32(split_colour16(pixel));
493    
494     if (g_xserver_be)
495 jsorg71 472 {
496 jsorg71 483 *(out++) = value >> 24;
497     *(out++) = value >> 16;
498     *(out++) = value >> 8;
499     *(out++) = value;
500 astrand 499 }
501     else
502     {
503 jsorg71 483 *(out++) = value;
504     *(out++) = value >> 8;
505     *(out++) = value >> 16;
506     *(out++) = value >> 24;
507 astrand 499 }
508     }
509 matty 28 }
510    
511 jsorg71 311 static void
512 jsorg71 483 translate24to16(uint8 * data, uint8 * out, uint8 * end)
513 jsorg71 311 {
514 jsorg71 316 uint32 pixel = 0;
515 jsorg71 483 uint16 value;
516 jsorg71 311 while (out < end)
517 jsorg71 316 {
518     pixel = *(data++) << 16;
519     pixel |= *(data++) << 8;
520     pixel |= *(data++);
521 jsorg71 483
522     value = (uint16) make_colour16(split_colour24(pixel));
523    
524     if (g_xserver_be)
525     {
526     *(out++) = value >> 8;
527     *(out++) = value;
528     }
529     else
530     {
531     *(out++) = value;
532     *(out++) = value >> 8;
533     }
534 jsorg71 316 }
535 jsorg71 311 }
536    
537 jsorg71 316 static void
538     translate24to24(uint8 * data, uint8 * out, uint8 * end)
539     {
540     while (out < end)
541     {
542     *(out++) = (*(data++));
543     }
544     }
545    
546     static void
547 jsorg71 483 translate24to32(uint8 * data, uint8 * out, uint8 * end)
548 jsorg71 316 {
549     while (out < end)
550     {
551 jsorg71 483 if (g_xserver_be)
552 jsorg71 472 {
553 jsorg71 483 *(out++) = 0x00;
554     *(out++) = *(data++);
555     *(out++) = *(data++);
556     *(out++) = *(data++);
557 jsorg71 472 }
558     else
559     {
560 jsorg71 483 *(out++) = *(data++);
561     *(out++) = *(data++);
562     *(out++) = *(data++);
563     *(out++) = 0x00;
564 jsorg71 472 }
565 jsorg71 316 }
566     }
567    
568 matty 29 static uint8 *
569 astrand 64 translate_image(int width, int height, uint8 * data)
570 matty 28 {
571 jsorg71 450 int size = width * height * g_bpp / 8;
572 forsberg 415 uint8 *out = (uint8 *) xmalloc(size);
573 matty 29 uint8 *end = out + size;
574    
575 jsorg71 438 switch (g_server_bpp)
576 jsorg71 311 {
577 jsorg71 316 case 24:
578 jsorg71 450 switch (g_bpp)
579 jsorg71 316 {
580     case 32:
581 jsorg71 483 translate24to32(data, out, end);
582 jsorg71 316 break;
583     case 24:
584     translate24to24(data, out, end);
585     break;
586     case 16:
587 jsorg71 483 translate24to16(data, out, end);
588 jsorg71 316 break;
589     }
590 matty 29 break;
591     case 16:
592 jsorg71 450 switch (g_bpp)
593 jsorg71 316 {
594     case 32:
595 jsorg71 483 translate16to32((uint16 *) data, out, end);
596 jsorg71 316 break;
597     case 24:
598     translate16to24((uint16 *) data, out, end);
599     break;
600     case 16:
601 astrand 318 translate16to16((uint16 *) data, (uint16 *) out,
602     (uint16 *) end);
603 jsorg71 316 break;
604     }
605 matty 29 break;
606 jsorg71 316 case 15:
607 jsorg71 450 switch (g_bpp)
608 jsorg71 316 {
609     case 32:
610 jsorg71 483 translate15to32((uint16 *) data, out, end);
611 jsorg71 316 break;
612     case 24:
613     translate15to24((uint16 *) data, out, end);
614     break;
615     case 16:
616 jsorg71 483 translate15to16((uint16 *) data, out, end);
617 jsorg71 316 break;
618     }
619 matty 29 break;
620 jsorg71 316 case 8:
621 jsorg71 450 switch (g_bpp)
622 jsorg71 316 {
623     case 8:
624     translate8to8(data, out, end);
625     break;
626     case 16:
627     translate8to16(data, (uint16 *) out, (uint16 *) end);
628     break;
629     case 24:
630     translate8to24(data, out, end);
631     break;
632     case 32:
633     translate8to32(data, (uint32 *) out, (uint32 *) end);
634     break;
635     }
636 matty 29 break;
637     }
638     return out;
639 matty 28 }
640    
641 astrand 118 BOOL
642 matthewc 209 get_key_state(unsigned int state, uint32 keysym)
643 astrand 102 {
644 matthewc 203 int modifierpos, key, keysymMask = 0;
645 astrand 102 int offset;
646    
647 jsorg71 450 KeyCode keycode = XKeysymToKeycode(g_display, keysym);
648 astrand 102
649     if (keycode == NoSymbol)
650     return False;
651    
652     for (modifierpos = 0; modifierpos < 8; modifierpos++)
653     {
654 jsorg71 450 offset = g_mod_map->max_keypermod * modifierpos;
655 astrand 102
656 jsorg71 450 for (key = 0; key < g_mod_map->max_keypermod; key++)
657 astrand 102 {
658 jsorg71 450 if (g_mod_map->modifiermap[offset + key] == keycode)
659 matthewc 203 keysymMask |= 1 << modifierpos;
660 astrand 102 }
661     }
662    
663 matthewc 203 return (state & keysymMask) ? True : False;
664 astrand 102 }
665    
666 jsorg71 81 BOOL
667 matthewc 192 ui_init(void)
668 jsorg71 81 {
669 matthewc 121 XPixmapFormatValues *pfm;
670     uint16 test;
671     int i;
672    
673 jsorg71 450 g_display = XOpenDisplay(NULL);
674     if (g_display == NULL)
675 jsorg71 81 {
676 matthewc 210 error("Failed to open display: %s\n", XDisplayName(NULL));
677 jsorg71 81 return False;
678     }
679 matthewc 121
680 jsorg71 450 g_x_socket = ConnectionNumber(g_display);
681     g_screen = DefaultScreenOfDisplay(g_display);
682     g_visual = DefaultVisualOfScreen(g_screen);
683     g_depth = DefaultDepthOfScreen(g_screen);
684 matthewc 121
685 jsorg71 450 pfm = XListPixmapFormats(g_display, &i);
686 matthewc 121 if (pfm != NULL)
687     {
688     /* Use maximum bpp for this depth - this is generally
689     desirable, e.g. 24 bits->32 bits. */
690     while (i--)
691     {
692 jsorg71 450 if ((pfm[i].depth == g_depth) && (pfm[i].bits_per_pixel > g_bpp))
693 matthewc 121 {
694 jsorg71 450 g_bpp = pfm[i].bits_per_pixel;
695 matthewc 121 }
696     }
697     XFree(pfm);
698     }
699    
700 jsorg71 450 if (g_bpp < 8)
701 matthewc 121 {
702     error("Less than 8 bpp not currently supported.\n");
703 jsorg71 450 XCloseDisplay(g_display);
704 matthewc 121 return False;
705     }
706    
707 jsorg71 450 if (g_owncolmap != True)
708 n-ki 279 {
709 jsorg71 450 g_xcolmap = DefaultColormapOfScreen(g_screen);
710     if (g_depth <= 8)
711 matthewc 297 warning("Screen depth is 8 bits or lower: you may want to use -C for a private colourmap\n");
712 n-ki 279 }
713    
714 jsorg71 450 g_gc = XCreateGC(g_display, RootWindowOfScreen(g_screen), 0, NULL);
715 matthewc 121
716 jsorg71 450 if (DoesBackingStore(g_screen) != Always)
717     g_ownbackstore = True;
718 matthewc 121
719     test = 1;
720 jsorg71 450 g_host_be = !(BOOL) (*(uint8 *) (&test));
721     g_xserver_be = (ImageByteOrder(g_display) == MSBFirst);
722 matthewc 121
723 astrand 500 /*
724     * Determine desktop size
725     */
726     if (g_width < 0)
727 astrand 263 {
728 astrand 500 /* Percent of screen */
729     g_height = HeightOfScreen(g_screen) * (-g_width) / 100;
730     g_width = WidthOfScreen(g_screen) * (-g_width) / 100;
731     }
732     else if (g_width == 0)
733     {
734 astrand 263 /* Fetch geometry from _NET_WORKAREA */
735 matthewc 300 uint32 x, y, cx, cy;
736 astrand 263
737 matthewc 300 if (get_current_workarea(&x, &y, &cx, &cy) == 0)
738 astrand 263 {
739 jsorg71 447 g_width = cx;
740     g_height = cy;
741 matthewc 300 }
742     else
743     {
744 matthewc 297 warning("Failed to get workarea: probably your window manager does not support extended hints\n");
745 jsorg71 447 g_width = 800;
746     g_height = 600;
747 astrand 263 }
748     }
749 astrand 500 else if (g_fullscreen)
750 jsorg71 81 {
751 jsorg71 450 g_width = WidthOfScreen(g_screen);
752     g_height = HeightOfScreen(g_screen);
753 jsorg71 81 }
754 matthewc 121
755 matthewc 160 /* make sure width is a multiple of 4 */
756 jsorg71 447 g_width = (g_width + 3) & ~3;
757 matthewc 160
758 jsorg71 450 if (g_ownbackstore)
759 matthewc 188 {
760 jsorg71 450 g_backstore =
761     XCreatePixmap(g_display, RootWindowOfScreen(g_screen), g_width, g_height,
762     g_depth);
763 matthewc 188
764     /* clear to prevent rubbish being exposed at startup */
765 jsorg71 450 XSetForeground(g_display, g_gc, BlackPixelOfScreen(g_screen));
766     XFillRectangle(g_display, g_backstore, g_gc, 0, 0, g_width, g_height);
767 matthewc 188 }
768    
769 jsorg71 450 g_mod_map = XGetModifierMapping(g_display);
770 matthewc 203
771 astrand 498 xkeymap_init();
772    
773 jsorg71 447 if (g_enable_compose)
774 jsorg71 450 g_IM = XOpenIM(g_display, NULL, NULL, NULL);
775 matthewc 188
776 matthewc 432 xclip_init();
777 jsorg71 316
778     /* todo take this out when high colour is done */
779 jsorg71 450 printf("server bpp %d client bpp %d depth %d\n", g_server_bpp, g_bpp, g_depth);
780 jsorg71 316
781 jsorg71 81 return True;
782     }
783 astrand 66
784 matthewc 188 void
785 matthewc 192 ui_deinit(void)
786 matthewc 188 {
787 jsorg71 450 if (g_IM != NULL)
788     XCloseIM(g_IM);
789 matthewc 188
790 jsorg71 450 XFreeModifiermap(g_mod_map);
791 matthewc 203
792 jsorg71 450 if (g_ownbackstore)
793     XFreePixmap(g_display, g_backstore);
794 matthewc 188
795 jsorg71 450 XFreeGC(g_display, g_gc);
796     XCloseDisplay(g_display);
797     g_display = NULL;
798 matthewc 188 }
799    
800 matthewc 121 BOOL
801 matthewc 192 ui_create_window(void)
802 matty 6 {
803 matthewc 121 XSetWindowAttributes attribs;
804 matty 28 XClassHint *classhints;
805     XSizeHints *sizehints;
806 matthewc 188 int wndwidth, wndheight;
807 matthewc 432 long input_mask, ic_input_mask;
808 jsorg71 100 XEvent xevent;
809    
810 jsorg71 450 wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;
811     wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;
812 matthewc 188
813 jsorg71 450 attribs.background_pixel = BlackPixelOfScreen(g_screen);
814     attribs.backing_store = g_ownbackstore ? NotUseful : Always;
815 jsorg71 447 attribs.override_redirect = g_fullscreen;
816 matthewc 188
817 jsorg71 450 g_wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), 0, 0, wndwidth, wndheight,
818 astrand 456 0, CopyFromParent, InputOutput, CopyFromParent,
819     CWBackPixel | CWBackingStore | CWOverrideRedirect, &attribs);
820 jsorg71 100
821 jsorg71 450 XStoreName(g_display, g_wnd, g_title);
822 jsorg71 100
823 jsorg71 450 if (g_hide_decorations)
824 astrand 262 mwm_hide_decorations();
825    
826 jsorg71 100 classhints = XAllocClassHint();
827     if (classhints != NULL)
828     {
829     classhints->res_name = classhints->res_class = "rdesktop";
830 jsorg71 450 XSetClassHint(g_display, g_wnd, classhints);
831 jsorg71 100 XFree(classhints);
832     }
833    
834     sizehints = XAllocSizeHints();
835     if (sizehints)
836     {
837     sizehints->flags = PMinSize | PMaxSize;
838 jsorg71 447 sizehints->min_width = sizehints->max_width = g_width;
839     sizehints->min_height = sizehints->max_height = g_height;
840 jsorg71 450 XSetWMNormalHints(g_display, g_wnd, sizehints);
841 jsorg71 100 XFree(sizehints);
842     }
843    
844 matthewc 121 input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
845 jsorg71 257 VisibilityChangeMask | FocusChangeMask;
846 matthewc 121
847 jsorg71 447 if (g_sendmotion)
848 matthewc 121 input_mask |= PointerMotionMask;
849 jsorg71 450 if (g_ownbackstore)
850 matthewc 121 input_mask |= ExposureMask;
851 jsorg71 450 if (g_fullscreen || g_grab_keyboard)
852 matthewc 250 input_mask |= EnterWindowMask;
853 jsorg71 450 if (g_grab_keyboard)
854 jsorg71 257 input_mask |= LeaveWindowMask;
855 jsorg71 100
856 jsorg71 450 if (g_IM != NULL)
857 matthewc 188 {
858 jsorg71 450 g_IC = XCreateIC(g_IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
859 astrand 456 XNClientWindow, g_wnd, XNFocusWindow, g_wnd, NULL);
860 matthewc 188
861 jsorg71 450 if ((g_IC != NULL)
862     && (XGetICValues(g_IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))
863 matthewc 188 input_mask |= ic_input_mask;
864     }
865    
866 jsorg71 450 XSelectInput(g_display, g_wnd, input_mask);
867     XMapWindow(g_display, g_wnd);
868 jsorg71 100
869 matthewc 208 /* wait for VisibilityNotify */
870 astrand 196 do
871     {
872 jsorg71 450 XMaskEvent(g_display, VisibilityChangeMask, &xevent);
873 astrand 196 }
874 matthewc 208 while (xevent.type != VisibilityNotify);
875 matthewc 123
876 jsorg71 447 g_focused = False;
877     g_mouse_in_wnd = False;
878 jsorg71 257
879 astrand 275 /* handle the WM_DELETE_WINDOW protocol */
880 jsorg71 450 g_protocol_atom = XInternAtom(g_display, "WM_PROTOCOLS", True);
881     g_kill_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", True);
882     XSetWMProtocols(g_display, g_wnd, &g_kill_atom, 1);
883 astrand 275
884 matty 10 return True;
885 matty 6 }
886    
887 matty 25 void
888 matthewc 192 ui_destroy_window(void)
889 matty 6 {
890 jsorg71 450 if (g_IC != NULL)
891     XDestroyIC(g_IC);
892 matty 31
893 jsorg71 450 XDestroyWindow(g_display, g_wnd);
894 matty 6 }
895    
896 jsorg71 100 void
897 matthewc 192 xwin_toggle_fullscreen(void)
898 jsorg71 100 {
899 matthewc 188 Pixmap contents = 0;
900 matthewc 123
901 jsorg71 450 if (!g_ownbackstore)
902 matthewc 188 {
903     /* need to save contents of window */
904 jsorg71 450 contents = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);
905     XCopyArea(g_display, g_wnd, contents, g_gc, 0, 0, g_width, g_height, 0, 0);
906 matthewc 188 }
907    
908     ui_destroy_window();
909 jsorg71 447 g_fullscreen = !g_fullscreen;
910 matthewc 188 ui_create_window();
911 matthewc 123
912 jsorg71 450 XDefineCursor(g_display, g_wnd, g_current_cursor);
913 matthewc 188
914 jsorg71 450 if (!g_ownbackstore)
915 matthewc 188 {
916 jsorg71 450 XCopyArea(g_display, contents, g_wnd, g_gc, 0, 0, g_width, g_height, 0, 0);
917     XFreePixmap(g_display, contents);
918 matthewc 188 }
919 jsorg71 100 }
920    
921 jsorg71 447 /* Process all events in Xlib queue
922 astrand 275 Returns 0 after user quit, 1 otherwise */
923     static int
924 matthewc 192 xwin_process_events(void)
925 matty 9 {
926 n-ki 54 XEvent xevent;
927 matthewc 38 KeySym keysym;
928 matthewc 50 uint16 button, flags;
929 matty 10 uint32 ev_time;
930 astrand 66 key_translation tr;
931     char str[256];
932     Status status;
933 matthewc 203 unsigned int state;
934     Window wdummy;
935     int dummy;
936 matty 9
937 jsorg71 450 while (XPending(g_display) > 0)
938 matty 9 {
939 jsorg71 450 XNextEvent(g_display, &xevent);
940 matthewc 123
941 jsorg71 450 if ((g_IC != NULL) && (XFilterEvent(&xevent, None) == True))
942 astrand 66 {
943 astrand 84 DEBUG_KBD(("Filtering event\n"));
944 astrand 66 continue;
945     }
946    
947 matthewc 50 flags = 0;
948 matty 10
949 n-ki 54 switch (xevent.type)
950 matty 9 {
951 astrand 275 case ClientMessage:
952     /* the window manager told us to quit */
953 jsorg71 450 if ((xevent.xclient.message_type == g_protocol_atom)
954     && ((Atom) xevent.xclient.data.l[0] == g_kill_atom))
955 astrand 275 /* Quit */
956     return 0;
957     break;
958    
959 matty 9 case KeyPress:
960 jsorg71 450 g_last_gesturetime = xevent.xkey.time;
961     if (g_IC != NULL)
962 astrand 66 /* Multi_key compatible version */
963     {
964 jsorg71 450 XmbLookupString(g_IC,
965 astrand 435 &xevent.xkey, str, sizeof(str), &keysym,
966     &status);
967 astrand 82 if (!((status == XLookupKeySym) || (status == XLookupBoth)))
968 astrand 66 {
969 astrand 82 error("XmbLookupString failed with status 0x%x\n",
970     status);
971 astrand 66 break;
972     }
973     }
974     else
975     {
976     /* Plain old XLookupString */
977 astrand 182 DEBUG_KBD(("\nNo input context, using XLookupString\n"));
978 astrand 66 XLookupString((XKeyEvent *) & xevent,
979 astrand 82 str, sizeof(str), &keysym, NULL);
980 astrand 66 }
981    
982 astrand 261 DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,
983     get_ksname(keysym)));
984 astrand 66
985 matthewc 203 ev_time = time(NULL);
986     if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
987 astrand 118 break;
988    
989 astrand 66 tr = xkeymap_translate_key(keysym,
990 astrand 82 xevent.xkey.keycode, xevent.xkey.state);
991 astrand 69
992 astrand 66 if (tr.scancode == 0)
993 n-ki 52 break;
994    
995 astrand 470 save_remote_modifiers(tr.scancode);
996 astrand 115 ensure_remote_modifiers(ev_time, tr);
997 astrand 449 rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
998 astrand 470 restore_remote_modifiers(ev_time, tr.scancode);
999 astrand 115
1000 astrand 66 break;
1001 matthewc 203
1002 astrand 66 case KeyRelease:
1003 jsorg71 450 g_last_gesturetime = xevent.xkey.time;
1004 astrand 66 XLookupString((XKeyEvent *) & xevent, str,
1005     sizeof(str), &keysym, NULL);
1006 n-ki 52
1007 astrand 84 DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
1008 matthewc 203 get_ksname(keysym)));
1009 n-ki 52
1010 matthewc 203 ev_time = time(NULL);
1011     if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
1012 astrand 118 break;
1013    
1014 astrand 66 tr = xkeymap_translate_key(keysym,
1015 astrand 82 xevent.xkey.keycode, xevent.xkey.state);
1016 astrand 66
1017     if (tr.scancode == 0)
1018     break;
1019    
1020 astrand 82 rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
1021 matty 9 break;
1022    
1023     case ButtonPress:
1024 matthewc 50 flags = MOUSE_FLAG_DOWN;
1025     /* fall through */
1026 matty 9
1027     case ButtonRelease:
1028 jsorg71 450 g_last_gesturetime = xevent.xbutton.time;
1029 astrand 82 button = xkeymap_translate_button(xevent.xbutton.button);
1030 matty 9 if (button == 0)
1031     break;
1032    
1033 astrand 328 /* If win_button_size is nonzero, enable single app mode */
1034 jsorg71 450 if (xevent.xbutton.y < g_win_button_size)
1035 astrand 328 {
1036 astrand 342 /* Stop moving window when button is released, regardless of cursor position */
1037 jsorg71 450 if (g_moving_wnd && (xevent.type == ButtonRelease))
1038     g_moving_wnd = False;
1039 astrand 332
1040 astrand 342 /* Check from right to left: */
1041    
1042 jsorg71 450 if (xevent.xbutton.x >= g_width - g_win_button_size)
1043 astrand 328 {
1044 astrand 331 /* The close button, continue */
1045 astrand 328 ;
1046     }
1047 astrand 456 else if (xevent.xbutton.x >=
1048     g_width - g_win_button_size * 2)
1049 astrand 328 {
1050     /* The maximize/restore button. Do not send to
1051     server. It might be a good idea to change the
1052 jsorg71 447 cursor or give some other visible indication
1053 astrand 328 that rdesktop inhibited this click */
1054     break;
1055     }
1056 astrand 456 else if (xevent.xbutton.x >=
1057     g_width - g_win_button_size * 3)
1058 astrand 328 {
1059     /* The minimize button. Iconify window. */
1060 jsorg71 450 XIconifyWindow(g_display, g_wnd,
1061     DefaultScreen(g_display));
1062 astrand 328 break;
1063     }
1064 jsorg71 450 else if (xevent.xbutton.x <= g_win_button_size)
1065 astrand 342 {
1066     /* The system menu. Ignore. */
1067     break;
1068     }
1069 astrand 332 else
1070     {
1071 astrand 342 /* The title bar. */
1072 jsorg71 447 if ((xevent.type == ButtonPress) && !g_fullscreen
1073 jsorg71 450 && g_hide_decorations)
1074 astrand 342 {
1075 jsorg71 450 g_moving_wnd = True;
1076     g_move_x_offset = xevent.xbutton.x;
1077     g_move_y_offset = xevent.xbutton.y;
1078 astrand 342 }
1079 astrand 332 break;
1080 astrand 342
1081 astrand 332 }
1082 astrand 328 }
1083    
1084 matthewc 203 rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1085 astrand 82 flags | button, xevent.xbutton.x, xevent.xbutton.y);
1086 matty 10 break;
1087    
1088     case MotionNotify:
1089 jsorg71 450 if (g_moving_wnd)
1090 astrand 342 {
1091 jsorg71 450 XMoveWindow(g_display, g_wnd,
1092     xevent.xmotion.x_root - g_move_x_offset,
1093     xevent.xmotion.y_root - g_move_y_offset);
1094 astrand 342 break;
1095     }
1096    
1097 jsorg71 447 if (g_fullscreen && !g_focused)
1098 jsorg71 450 XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,
1099 jsorg71 288 CurrentTime);
1100 matthewc 203 rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1101 astrand 82 MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
1102 matty 28 break;
1103    
1104 matthewc 194 case FocusIn:
1105 jsorg71 257 if (xevent.xfocus.mode == NotifyGrab)
1106     break;
1107 jsorg71 447 g_focused = True;
1108 jsorg71 450 XQueryPointer(g_display, g_wnd, &wdummy, &wdummy, &dummy, &dummy,
1109 astrand 261 &dummy, &dummy, &state);
1110 matthewc 203 reset_modifier_keys(state);
1111 jsorg71 450 if (g_grab_keyboard && g_mouse_in_wnd)
1112     XGrabKeyboard(g_display, g_wnd, True,
1113 astrand 82 GrabModeAsync, GrabModeAsync, CurrentTime);
1114 matty 28 break;
1115    
1116 matthewc 194 case FocusOut:
1117 jsorg71 257 if (xevent.xfocus.mode == NotifyUngrab)
1118     break;
1119 jsorg71 447 g_focused = False;
1120 matthewc 201 if (xevent.xfocus.mode == NotifyWhileGrabbed)
1121 jsorg71 450 XUngrabKeyboard(g_display, CurrentTime);
1122 matty 28 break;
1123 matty 31
1124 matthewc 250 case EnterNotify:
1125     /* we only register for this event when in fullscreen mode */
1126 jsorg71 257 /* or grab_keyboard */
1127 jsorg71 447 g_mouse_in_wnd = True;
1128     if (g_fullscreen)
1129 jsorg71 257 {
1130 jsorg71 450 XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,
1131 astrand 261 CurrentTime);
1132 jsorg71 257 break;
1133     }
1134 jsorg71 447 if (g_focused)
1135 jsorg71 450 XGrabKeyboard(g_display, g_wnd, True,
1136 jsorg71 257 GrabModeAsync, GrabModeAsync, CurrentTime);
1137 matthewc 250 break;
1138    
1139 matthewc 253 case LeaveNotify:
1140 jsorg71 257 /* we only register for this event when grab_keyboard */
1141 jsorg71 447 g_mouse_in_wnd = False;
1142 jsorg71 450 XUngrabKeyboard(g_display, CurrentTime);
1143 matthewc 253 break;
1144    
1145 matty 31 case Expose:
1146 jsorg71 450 XCopyArea(g_display, g_backstore, g_wnd, g_gc,
1147 n-ki 54 xevent.xexpose.x, xevent.xexpose.y,
1148 astrand 64 xevent.xexpose.width,
1149     xevent.xexpose.height,
1150 n-ki 54 xevent.xexpose.x, xevent.xexpose.y);
1151 matty 31 break;
1152 astrand 119
1153     case MappingNotify:
1154     /* Refresh keyboard mapping if it has changed. This is important for
1155     Xvnc, since it allocates keycodes dynamically */
1156     if (xevent.xmapping.request == MappingKeyboard
1157     || xevent.xmapping.request == MappingModifier)
1158     XRefreshKeyboardMapping(&xevent.xmapping);
1159 matthewc 203
1160     if (xevent.xmapping.request == MappingModifier)
1161     {
1162 jsorg71 450 XFreeModifiermap(g_mod_map);
1163     g_mod_map = XGetModifierMapping(g_display);
1164 matthewc 203 }
1165 astrand 119 break;
1166 matthewc 432
1167 astrand 435 /* clipboard stuff */
1168 forsberg 415 case SelectionNotify:
1169 matthewc 432 xclip_handle_SelectionNotify(&xevent.xselection);
1170 forsberg 415 break;
1171     case SelectionRequest:
1172 matthewc 432 xclip_handle_SelectionRequest(&xevent.xselectionrequest);
1173 forsberg 415 break;
1174 matthewc 432 case SelectionClear:
1175     xclip_handle_SelectionClear();
1176     break;
1177 forsberg 415 case PropertyNotify:
1178 matthewc 432 xclip_handle_PropertyNotify(&xevent.xproperty);
1179 forsberg 415 break;
1180 matty 9 }
1181     }
1182 astrand 275 /* Keep going */
1183     return 1;
1184 matty 9 }
1185    
1186 astrand 275 /* Returns 0 after user quit, 1 otherwise */
1187     int
1188 matty 33 ui_select(int rdp_socket)
1189     {
1190 jsorg71 450 int n = (rdp_socket > g_x_socket) ? rdp_socket + 1 : g_x_socket + 1;
1191 matthewc 474 fd_set rfds, wfds;
1192 matty 33
1193     while (True)
1194     {
1195 matthewc 121 /* Process any events already waiting */
1196 astrand 275 if (!xwin_process_events())
1197     /* User quit */
1198     return 0;
1199 astrand 119
1200 matty 33 FD_ZERO(&rfds);
1201 matthewc 474 FD_ZERO(&wfds);
1202 matty 33 FD_SET(rdp_socket, &rfds);
1203 jsorg71 450 FD_SET(g_x_socket, &rfds);
1204 matty 33
1205 matthewc 474 #ifdef WITH_RDPSND
1206     /* FIXME: there should be an API for registering fds */
1207 stargo 504 if (g_dsp_busy)
1208 matty 33 {
1209 matthewc 474 FD_SET(g_dsp_fd, &wfds);
1210     n = (g_dsp_fd + 1 > n) ? g_dsp_fd + 1 : n;
1211 astrand 499 }
1212 matthewc 474 #endif
1213    
1214     switch (select(n, &rfds, &wfds, NULL, NULL))
1215     {
1216 matty 33 case -1:
1217     error("select: %s\n", strerror(errno));
1218    
1219     case 0:
1220     continue;
1221     }
1222    
1223     if (FD_ISSET(rdp_socket, &rfds))
1224 astrand 275 return 1;
1225 matthewc 474
1226     #ifdef WITH_RDPSND
1227 stargo 504 if (g_dsp_busy && FD_ISSET(g_dsp_fd, &wfds))
1228 matthewc 474 wave_out_play();
1229     #endif
1230 matty 33 }
1231     }
1232    
1233     void
1234 matty 25 ui_move_pointer(int x, int y)
1235 matty 9 {
1236 jsorg71 450 XWarpPointer(g_display, g_wnd, g_wnd, 0, 0, 0, 0, x, y);
1237 matty 9 }
1238    
1239 matty 25 HBITMAP
1240 astrand 64 ui_create_bitmap(int width, int height, uint8 * data)
1241 matty 6 {
1242     XImage *image;
1243 matty 9 Pixmap bitmap;
1244 matty 28 uint8 *tdata;
1245 matty 29
1246 jsorg71 450 tdata = (g_owncolmap ? data : translate_image(width, height, data));
1247     bitmap = XCreatePixmap(g_display, g_wnd, width, height, g_depth);
1248     image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1249     (char *) tdata, width, height, g_server_bpp == 8 ? 8 : g_bpp, 0);
1250 matty 6
1251 jsorg71 450 XPutImage(g_display, bitmap, g_gc, image, 0, 0, 0, 0, width, height);
1252 matty 9
1253     XFree(image);
1254 jsorg71 450 if (!g_owncolmap)
1255 n-ki 279 xfree(tdata);
1256 matty 24 return (HBITMAP) bitmap;
1257 matty 6 }
1258    
1259 matty 25 void
1260 astrand 82 ui_paint_bitmap(int x, int y, int cx, int cy, int width, int height, uint8 * data)
1261 matty 6 {
1262 matty 10 XImage *image;
1263 matty 29 uint8 *tdata;
1264 jsorg71 450 tdata = (g_owncolmap ? data : translate_image(width, height, data));
1265     image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1266     (char *) tdata, width, height, g_server_bpp == 8 ? 8 : g_bpp, 0);
1267 matty 28
1268 jsorg71 450 if (g_ownbackstore)
1269 matty 31 {
1270 jsorg71 450 XPutImage(g_display, g_backstore, g_gc, image, 0, 0, x, y, cx, cy);
1271     XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
1272 matty 31 }
1273     else
1274     {
1275 jsorg71 450 XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy);
1276 matty 31 }
1277 matty 29
1278 matty 24 XFree(image);
1279 jsorg71 450 if (!g_owncolmap)
1280 n-ki 279 xfree(tdata);
1281 matty 6 }
1282    
1283 matty 25 void
1284     ui_destroy_bitmap(HBITMAP bmp)
1285 matty 6 {
1286 jsorg71 450 XFreePixmap(g_display, (Pixmap) bmp);
1287 matty 10 }
1288    
1289 matty 25 HGLYPH
1290 astrand 64 ui_create_glyph(int width, int height, uint8 * data)
1291 matty 10 {
1292 matty 9 XImage *image;
1293     Pixmap bitmap;
1294     int scanline;
1295     GC gc;
1296 matty 6
1297 matty 9 scanline = (width + 7) / 8;
1298 matty 6
1299 jsorg71 450 bitmap = XCreatePixmap(g_display, g_wnd, width, height, 1);
1300     gc = XCreateGC(g_display, bitmap, 0, NULL);
1301 matty 9
1302 jsorg71 450 image = XCreateImage(g_display, g_visual, 1, ZPixmap, 0, (char *) data,
1303 astrand 73 width, height, 8, scanline);
1304 matty 23 image->byte_order = MSBFirst;
1305     image->bitmap_bit_order = MSBFirst;
1306     XInitImage(image);
1307    
1308 jsorg71 450 XPutImage(g_display, bitmap, gc, image, 0, 0, 0, 0, width, height);
1309 matty 29
1310 matty 9 XFree(image);
1311 jsorg71 450 XFreeGC(g_display, gc);
1312 astrand 64 return (HGLYPH) bitmap;
1313 matty 6 }
1314 matty 7
1315 matty 25 void
1316     ui_destroy_glyph(HGLYPH glyph)
1317 matty 7 {
1318 jsorg71 450 XFreePixmap(g_display, (Pixmap) glyph);
1319 matty 9 }
1320    
1321 matty 29 HCURSOR
1322 astrand 66 ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
1323     uint8 * andmask, uint8 * xormask)
1324 matty 9 {
1325 matty 29 HGLYPH maskglyph, cursorglyph;
1326     XColor bg, fg;
1327     Cursor xcursor;
1328     uint8 *cursor, *pcursor;
1329     uint8 *mask, *pmask;
1330     uint8 nextbit;
1331     int scanline, offset;
1332     int i, j;
1333    
1334     scanline = (width + 7) / 8;
1335     offset = scanline * height;
1336    
1337 forsberg 415 cursor = (uint8 *) xmalloc(offset);
1338 matty 29 memset(cursor, 0, offset);
1339    
1340 forsberg 415 mask = (uint8 *) xmalloc(offset);
1341 matty 29 memset(mask, 0, offset);
1342    
1343     /* approximate AND and XOR masks with a monochrome X pointer */
1344     for (i = 0; i < height; i++)
1345 matty 7 {
1346 matty 29 offset -= scanline;
1347     pcursor = &cursor[offset];
1348     pmask = &mask[offset];
1349    
1350     for (j = 0; j < scanline; j++)
1351 matty 28 {
1352 matty 29 for (nextbit = 0x80; nextbit != 0; nextbit >>= 1)
1353     {
1354     if (xormask[0] || xormask[1] || xormask[2])
1355     {
1356     *pcursor |= (~(*andmask) & nextbit);
1357     *pmask |= nextbit;
1358     }
1359     else
1360     {
1361     *pcursor |= ((*andmask) & nextbit);
1362     *pmask |= (~(*andmask) & nextbit);
1363     }
1364    
1365     xormask += 3;
1366     }
1367    
1368     andmask++;
1369     pcursor++;
1370     pmask++;
1371 matty 28 }
1372 matty 7 }
1373 matty 29
1374     fg.red = fg.blue = fg.green = 0xffff;
1375     bg.red = bg.blue = bg.green = 0x0000;
1376     fg.flags = bg.flags = DoRed | DoBlue | DoGreen;
1377    
1378     cursorglyph = ui_create_glyph(width, height, cursor);
1379     maskglyph = ui_create_glyph(width, height, mask);
1380    
1381 astrand 66 xcursor =
1382 jsorg71 450 XCreatePixmapCursor(g_display, (Pixmap) cursorglyph,
1383 astrand 66 (Pixmap) maskglyph, &fg, &bg, x, y);
1384 astrand 64
1385 matty 29 ui_destroy_glyph(maskglyph);
1386     ui_destroy_glyph(cursorglyph);
1387     xfree(mask);
1388     xfree(cursor);
1389 astrand 64 return (HCURSOR) xcursor;
1390 matty 29 }
1391    
1392     void
1393     ui_set_cursor(HCURSOR cursor)
1394     {
1395 jsorg71 450 g_current_cursor = (Cursor) cursor;
1396     XDefineCursor(g_display, g_wnd, g_current_cursor);
1397 matty 29 }
1398    
1399     void
1400     ui_destroy_cursor(HCURSOR cursor)
1401     {
1402 jsorg71 450 XFreeCursor(g_display, (Cursor) cursor);
1403 matty 29 }
1404    
1405     #define MAKE_XCOLOR(xc,c) \
1406     (xc)->red = ((c)->red << 8) | (c)->red; \
1407     (xc)->green = ((c)->green << 8) | (c)->green; \
1408     (xc)->blue = ((c)->blue << 8) | (c)->blue; \
1409     (xc)->flags = DoRed | DoGreen | DoBlue;
1410    
1411 n-ki 279
1412 matty 29 HCOLOURMAP
1413 astrand 64 ui_create_colourmap(COLOURMAP * colours)
1414 matty 29 {
1415     COLOURENTRY *entry;
1416     int i, ncolours = colours->ncolours;
1417 jsorg71 450 if (!g_owncolmap)
1418 matty 28 {
1419 jsorg71 450 uint32 *map = (uint32 *) xmalloc(sizeof(*g_colmap) * ncolours);
1420 n-ki 279 XColor xentry;
1421     XColor xc_cache[256];
1422     uint32 colour;
1423     int colLookup = 256;
1424     for (i = 0; i < ncolours; i++)
1425 matty 28 {
1426 n-ki 279 entry = &colours->colours[i];
1427     MAKE_XCOLOR(&xentry, entry);
1428 matty 7
1429 jsorg71 450 if (XAllocColor(g_display, g_xcolmap, &xentry) == 0)
1430 astrand 196 {
1431 n-ki 279 /* Allocation failed, find closest match. */
1432     int j = 256;
1433     int nMinDist = 3 * 256 * 256;
1434     long nDist = nMinDist;
1435 matty 28
1436 n-ki 279 /* only get the colors once */
1437     while (colLookup--)
1438 astrand 196 {
1439 n-ki 279 xc_cache[colLookup].pixel = colLookup;
1440     xc_cache[colLookup].red = xc_cache[colLookup].green =
1441     xc_cache[colLookup].blue = 0;
1442     xc_cache[colLookup].flags = 0;
1443 jsorg71 450 XQueryColor(g_display,
1444     DefaultColormap(g_display,
1445     DefaultScreen(g_display)),
1446 n-ki 279 &xc_cache[colLookup]);
1447 n-ki 185 }
1448 n-ki 279 colLookup = 0;
1449    
1450     /* approximate the pixel */
1451     while (j--)
1452 astrand 196 {
1453 n-ki 279 if (xc_cache[j].flags)
1454     {
1455     nDist = ((long) (xc_cache[j].red >> 8) -
1456     (long) (xentry.red >> 8)) *
1457     ((long) (xc_cache[j].red >> 8) -
1458     (long) (xentry.red >> 8)) +
1459     ((long) (xc_cache[j].green >> 8) -
1460     (long) (xentry.green >> 8)) *
1461     ((long) (xc_cache[j].green >> 8) -
1462     (long) (xentry.green >> 8)) +
1463     ((long) (xc_cache[j].blue >> 8) -
1464     (long) (xentry.blue >> 8)) *
1465     ((long) (xc_cache[j].blue >> 8) -
1466     (long) (xentry.blue >> 8));
1467     }
1468     if (nDist < nMinDist)
1469     {
1470     nMinDist = nDist;
1471     xentry.pixel = j;
1472     }
1473 n-ki 185 }
1474     }
1475 n-ki 279 colour = xentry.pixel;
1476    
1477     /* update our cache */
1478     if (xentry.pixel < 256)
1479     {
1480     xc_cache[xentry.pixel].red = xentry.red;
1481     xc_cache[xentry.pixel].green = xentry.green;
1482     xc_cache[xentry.pixel].blue = xentry.blue;
1483    
1484     }
1485    
1486    
1487     /* byte swap here to make translate_image faster */
1488     map[i] = translate_colour(colour);
1489 n-ki 185 }
1490 n-ki 279 return map;
1491     }
1492     else
1493     {
1494     XColor *xcolours, *xentry;
1495     Colormap map;
1496 matty 29
1497 forsberg 415 xcolours = (XColor *) xmalloc(sizeof(XColor) * ncolours);
1498 n-ki 279 for (i = 0; i < ncolours; i++)
1499 astrand 196 {
1500 n-ki 279 entry = &colours->colours[i];
1501     xentry = &xcolours[i];
1502     xentry->pixel = i;
1503     MAKE_XCOLOR(xentry, entry);
1504 matty 29 }
1505    
1506 jsorg71 450 map = XCreateColormap(g_display, g_wnd, g_visual, AllocAll);
1507     XStoreColors(g_display, map, xcolours, ncolours);
1508 n-ki 185
1509 n-ki 279 xfree(xcolours);
1510     return (HCOLOURMAP) map;
1511 matty 29 }
1512 matty 7 }
1513    
1514 matty 25 void
1515     ui_destroy_colourmap(HCOLOURMAP map)
1516 matty 7 {
1517 jsorg71 450 if (!g_owncolmap)
1518 n-ki 279 xfree(map);
1519     else
1520 jsorg71 450 XFreeColormap(g_display, (Colormap) map);
1521 matty 7 }
1522    
1523 matty 25 void
1524     ui_set_colourmap(HCOLOURMAP map)
1525 matty 7 {
1526 jsorg71 450 if (!g_owncolmap)
1527 astrand 448 {
1528 jsorg71 450 if (g_colmap)
1529     xfree(g_colmap);
1530 astrand 448
1531 jsorg71 450 g_colmap = (uint32 *) map;
1532 astrand 448 }
1533 n-ki 279 else
1534 jsorg71 450 XSetWindowColormap(g_display, g_wnd, (Colormap) map);
1535 matty 7 }
1536    
1537 matty 25 void
1538     ui_set_clip(int x, int y, int cx, int cy)
1539 matty 7 {
1540 matty 9 XRectangle rect;
1541 matty 7
1542 matty 9 rect.x = x;
1543     rect.y = y;
1544     rect.width = cx;
1545     rect.height = cy;
1546 jsorg71 450 XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);
1547 matty 9 }
1548 matty 7
1549 matty 25 void
1550 matthewc 192 ui_reset_clip(void)
1551 matty 9 {
1552     XRectangle rect;
1553    
1554     rect.x = 0;
1555     rect.y = 0;
1556 jsorg71 447 rect.width = g_width;
1557     rect.height = g_height;
1558 jsorg71 450 XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);
1559 matty 7 }
1560    
1561 matty 25 void
1562 matthewc 192 ui_bell(void)
1563 matty 10 {
1564 jsorg71 450 XBell(g_display, 0);
1565 matty 10 }
1566    
1567 matty 25 void
1568     ui_destblt(uint8 opcode,
1569     /* dest */ int x, int y, int cx, int cy)
1570 matty 9 {
1571 matty 29 SET_FUNCTION(opcode);
1572 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1573 matty 29 RESET_FUNCTION(opcode);
1574 matty 9 }
1575    
1576 jsorg71 373 static uint8 hatch_patterns[] = {
1577 forsberg 415 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0 - bsHorizontal */
1578     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 1 - bsVertical */
1579     0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, /* 2 - bsFDiagonal */
1580     0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* 3 - bsBDiagonal */
1581     0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, /* 4 - bsCross */
1582     0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 /* 5 - bsDiagCross */
1583 jsorg71 373 };
1584    
1585 matty 25 void
1586     ui_patblt(uint8 opcode,
1587     /* dest */ int x, int y, int cx, int cy,
1588 astrand 64 /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1589 matty 9 {
1590     Pixmap fill;
1591 jsorg71 59 uint8 i, ipattern[8];
1592 matty 9
1593 matty 29 SET_FUNCTION(opcode);
1594 matty 9
1595     switch (brush->style)
1596     {
1597 matty 24 case 0: /* Solid */
1598 matty 29 SET_FOREGROUND(fgcolour);
1599 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1600 matty 9 break;
1601    
1602 jsorg71 373 case 2: /* Hatch */
1603 forsberg 415 fill = (Pixmap) ui_create_glyph(8, 8,
1604     hatch_patterns + brush->pattern[0] * 8);
1605 astrand 487 SET_FOREGROUND(fgcolour);
1606     SET_BACKGROUND(bgcolour);
1607 jsorg71 450 XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
1608     XSetStipple(g_display, g_gc, fill);
1609     XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
1610 jsorg71 373 FILL_RECTANGLE(x, y, cx, cy);
1611 jsorg71 450 XSetFillStyle(g_display, g_gc, FillSolid);
1612     XSetTSOrigin(g_display, g_gc, 0, 0);
1613 jsorg71 373 ui_destroy_glyph((HGLYPH) fill);
1614     break;
1615    
1616 matty 24 case 3: /* Pattern */
1617 jsorg71 59 for (i = 0; i != 8; i++)
1618     ipattern[7 - i] = brush->pattern[i];
1619     fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
1620 matty 9
1621 matty 29 SET_FOREGROUND(bgcolour);
1622     SET_BACKGROUND(fgcolour);
1623 jsorg71 450 XSetFillStyle(g_display, g_gc, FillOpaqueStippled);
1624     XSetStipple(g_display, g_gc, fill);
1625     XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin);
1626 matty 9
1627 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1628 matty 9
1629 jsorg71 450 XSetFillStyle(g_display, g_gc, FillSolid);
1630     XSetTSOrigin(g_display, g_gc, 0, 0);
1631 astrand 64 ui_destroy_glyph((HGLYPH) fill);
1632 matty 9 break;
1633    
1634     default:
1635 matty 30 unimpl("brush %d\n", brush->style);
1636 matty 9 }
1637 matty 29
1638     RESET_FUNCTION(opcode);
1639 matty 9 }
1640    
1641 matty 25 void
1642     ui_screenblt(uint8 opcode,
1643     /* dest */ int x, int y, int cx, int cy,
1644     /* src */ int srcx, int srcy)
1645 matty 9 {
1646 matty 29 SET_FUNCTION(opcode);
1647 jsorg71 450 XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
1648     if (g_ownbackstore)
1649     XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x, y);
1650 matty 29 RESET_FUNCTION(opcode);
1651 matty 9 }
1652    
1653 matty 25 void
1654     ui_memblt(uint8 opcode,
1655     /* dest */ int x, int y, int cx, int cy,
1656     /* src */ HBITMAP src, int srcx, int srcy)
1657 matty 9 {
1658 matty 29 SET_FUNCTION(opcode);
1659 jsorg71 450 XCopyArea(g_display, (Pixmap) src, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
1660     if (g_ownbackstore)
1661     XCopyArea(g_display, (Pixmap) src, g_backstore, g_gc, srcx, srcy, cx, cy, x, y);
1662 matty 29 RESET_FUNCTION(opcode);
1663 matty 9 }
1664    
1665 matty 25 void
1666     ui_triblt(uint8 opcode,
1667     /* dest */ int x, int y, int cx, int cy,
1668     /* src */ HBITMAP src, int srcx, int srcy,
1669 astrand 64 /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1670 matty 9 {
1671     /* This is potentially difficult to do in general. Until someone
1672 matty 10 comes up with a more efficient way of doing it I am using cases. */
1673 matty 9
1674     switch (opcode)
1675     {
1676 matty 24 case 0x69: /* PDSxxn */
1677 matty 16 ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1678 astrand 82 ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
1679 matty 16 break;
1680    
1681 matty 24 case 0xb8: /* PSDPxax */
1682 astrand 82 ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
1683 matty 16 ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1684 astrand 82 ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
1685 matty 9 break;
1686    
1687 matty 29 case 0xc0: /* PSa */
1688 matty 28 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1689 astrand 82 ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
1690 matty 28 break;
1691    
1692 matty 9 default:
1693 matty 30 unimpl("triblt 0x%x\n", opcode);
1694 matty 16 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1695 matty 9 }
1696     }
1697    
1698 matty 25 void
1699     ui_line(uint8 opcode,
1700     /* dest */ int startx, int starty, int endx, int endy,
1701 astrand 64 /* pen */ PEN * pen)
1702 matty 9 {
1703 matty 29 SET_FUNCTION(opcode);
1704     SET_FOREGROUND(pen->colour);
1705 jsorg71 450 XDrawLine(g_display, g_wnd, g_gc, startx, starty, endx, endy);
1706     if (g_ownbackstore)
1707     XDrawLine(g_display, g_backstore, g_gc, startx, starty, endx, endy);
1708 matty 29 RESET_FUNCTION(opcode);
1709 matty 9 }
1710    
1711 matty 25 void
1712     ui_rect(
1713     /* dest */ int x, int y, int cx, int cy,
1714     /* brush */ int colour)
1715 matty 9 {
1716 matty 29 SET_FOREGROUND(colour);
1717 matty 31 FILL_RECTANGLE(x, y, cx, cy);
1718 matty 9 }
1719    
1720 jsorg71 278 /* warning, this function only draws on wnd or backstore, not both */
1721 matty 25 void
1722     ui_draw_glyph(int mixmode,
1723     /* dest */ int x, int y, int cx, int cy,
1724 astrand 66 /* src */ HGLYPH glyph, int srcx, int srcy,
1725     int bgcolour, int fgcolour)
1726 matty 9 {
1727 matty 29 SET_FOREGROUND(fgcolour);
1728     SET_BACKGROUND(bgcolour);
1729 matty 9
1730 jsorg71 450 XSetFillStyle(g_display, g_gc,
1731 astrand 82 (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1732 jsorg71 450 XSetStipple(g_display, g_gc, (Pixmap) glyph);
1733     XSetTSOrigin(g_display, g_gc, x, y);
1734 matty 9
1735 matthewc 296 FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
1736 matty 9
1737 jsorg71 450 XSetFillStyle(g_display, g_gc, FillSolid);
1738 matty 9 }
1739    
1740 mmihalik 49 #define DO_GLYPH(ttext,idx) \
1741     {\
1742     glyph = cache_get_font (font, ttext[idx]);\
1743     if (!(flags & TEXT2_IMPLICIT_X))\
1744     {\
1745     xyoffset = ttext[++idx];\
1746     if ((xyoffset & 0x80))\
1747     {\
1748     if (flags & TEXT2_VERTICAL) \
1749 astrand 72 y += ttext[idx+1] | (ttext[idx+2] << 8);\
1750 mmihalik 49 else\
1751 astrand 72 x += ttext[idx+1] | (ttext[idx+2] << 8);\
1752     idx += 2;\
1753 mmihalik 49 }\
1754     else\
1755     {\
1756     if (flags & TEXT2_VERTICAL) \
1757     y += xyoffset;\
1758     else\
1759     x += xyoffset;\
1760     }\
1761     }\
1762     if (glyph != NULL)\
1763     {\
1764 matthewc 299 ui_draw_glyph (mixmode, x + glyph->offset,\
1765     y + glyph->baseline,\
1766 mmihalik 49 glyph->width, glyph->height,\
1767     glyph->pixmap, 0, 0, bgcolour, fgcolour);\
1768     if (flags & TEXT2_IMPLICIT_X)\
1769     x += glyph->width;\
1770     }\
1771     }
1772    
1773 matty 25 void
1774     ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
1775 astrand 66 int clipx, int clipy, int clipcx, int clipcy,
1776     int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1777 mmihalik 49 int fgcolour, uint8 * text, uint8 length)
1778 matty 9 {
1779 matty 10 FONTGLYPH *glyph;
1780 mmihalik 49 int i, j, xyoffset;
1781     DATABLOB *entry;
1782 matty 9
1783 matty 29 SET_FOREGROUND(bgcolour);
1784 matty 28
1785 matty 9 if (boxcx > 1)
1786 matty 31 {
1787 matthewc 296 FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);
1788 matty 31 }
1789 matty 17 else if (mixmode == MIX_OPAQUE)
1790 matty 31 {
1791 matthewc 296 FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
1792 matty 31 }
1793 matty 9
1794     /* Paint text, character by character */
1795 astrand 64 for (i = 0; i < length;)
1796     {
1797     switch (text[i])
1798     {
1799     case 0xff:
1800     if (i + 2 < length)
1801 astrand 82 cache_put_text(text[i + 1], text, text[i + 2]);
1802 astrand 64 else
1803     {
1804     error("this shouldn't be happening\n");
1805 astrand 265 exit(1);
1806 astrand 64 }
1807     /* this will move pointer from start to first character after FF command */
1808     length -= i + 3;
1809     text = &(text[i + 3]);
1810     i = 0;
1811 mmihalik 49 break;
1812 matty 9
1813 astrand 64 case 0xfe:
1814     entry = cache_get_text(text[i + 1]);
1815     if (entry != NULL)
1816     {
1817     if ((((uint8 *) (entry->data))[1] ==
1818 astrand 82 0) && (!(flags & TEXT2_IMPLICIT_X)))
1819 astrand 64 {
1820     if (flags & TEXT2_VERTICAL)
1821     y += text[i + 2];
1822     else
1823     x += text[i + 2];
1824     }
1825     for (j = 0; j < entry->size; j++)
1826 astrand 82 DO_GLYPH(((uint8 *) (entry->data)), j);
1827 matthewc 44 }
1828 jsorg71 286 if (i + 2 < length)
1829     i += 3;
1830     else
1831     i += 2;
1832     length -= i;
1833     /* this will move pointer from start to first character after FE command */
1834     text = &(text[i]);
1835     i = 0;
1836 astrand 64 break;
1837 matty 17
1838 astrand 64 default:
1839     DO_GLYPH(text, i);
1840     i++;
1841     break;
1842 matty 29 }
1843 mmihalik 49 }
1844 jsorg71 450 if (g_ownbackstore)
1845 jsorg71 278 {
1846     if (boxcx > 1)
1847 jsorg71 450 XCopyArea(g_display, g_backstore, g_wnd, g_gc, boxx,
1848 jsorg71 278 boxy, boxcx, boxcy, boxx, boxy);
1849     else
1850 jsorg71 450 XCopyArea(g_display, g_backstore, g_wnd, g_gc, clipx,
1851 jsorg71 278 clipy, clipcx, clipcy, clipx, clipy);
1852     }
1853 matty 9 }
1854    
1855 matty 25 void
1856     ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
1857 matty 9 {
1858 matty 28 Pixmap pix;
1859 matty 9 XImage *image;
1860    
1861 jsorg71 450 if (g_ownbackstore)
1862 matty 31 {
1863 jsorg71 450 image = XGetImage(g_display, g_backstore, x, y, cx, cy, AllPlanes, ZPixmap);
1864 matty 31 }
1865     else
1866     {
1867 jsorg71 450 pix = XCreatePixmap(g_display, g_wnd, cx, cy, g_depth);
1868     XCopyArea(g_display, g_wnd, pix, g_gc, x, y, cx, cy, 0, 0);
1869     image = XGetImage(g_display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
1870     XFreePixmap(g_display, pix);
1871 matty 31 }
1872 matty 28
1873 jsorg71 450 offset *= g_bpp / 8;
1874     cache_put_desktop(offset, cx, cy, image->bytes_per_line, g_bpp / 8, (uint8 *) image->data);
1875 matty 28
1876     XDestroyImage(image);
1877 matty 9 }
1878    
1879 matty 25 void
1880     ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
1881 matty 9 {
1882     XImage *image;
1883 matty 10 uint8 *data;
1884 matty 9
1885 jsorg71 450 offset *= g_bpp / 8;
1886     data = cache_get_desktop(offset, cx, cy, g_bpp / 8);
1887 matty 10 if (data == NULL)
1888     return;
1889 matty 29
1890 jsorg71 450 image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
1891     (char *) data, cx, cy, BitmapPad(g_display), cx * g_bpp / 8);
1892 matty 29
1893 jsorg71 450 if (g_ownbackstore)
1894 matty 31 {
1895 jsorg71 450 XPutImage(g_display, g_backstore, g_gc, image, 0, 0, x, y, cx, cy);
1896     XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
1897 matty 31 }
1898     else
1899     {
1900 jsorg71 450 XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy);
1901 matty 31 }
1902    
1903 matty 9 XFree(image);
1904     }

  ViewVC Help
Powered by ViewVC 1.1.26