ReactOS  0.4.14-dev-55-g2da92ac
xwin.c
Go to the documentation of this file.
1 /* -*- c-basic-offset: 8 -*-
2  rdesktop: A Remote Desktop Protocol client.
3  User interface services - X Window System
4  Copyright (C) Matthew Chapman 1999-2005
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License along
17  with this program; if not, write to the Free Software Foundation, Inc.,
18  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20 
21 #include <X11/Xlib.h>
22 #include <X11/Xutil.h>
23 #include <unistd.h>
24 #include <sys/time.h>
25 #include <time.h>
26 #include <errno.h>
27 #include <strings.h>
28 #include "rdesktop.h"
29 #include "xproto.h"
30 
31 /* We can't include Xproto.h because of conflicting defines for BOOL */
32 #define X_ConfigureWindow 12
33 
34 /* MWM decorations */
35 #define MWM_HINTS_DECORATIONS (1L << 1)
36 #define PROP_MOTIF_WM_HINTS_ELEMENTS 5
37 typedef struct
38 {
39  unsigned long flags;
40  unsigned long functions;
41  unsigned long decorations;
42  long inputMode;
43  unsigned long status;
44 }
46 
47 typedef struct
48 {
52 }
54 
55 #define ON_ALL_SEAMLESS_WINDOWS(func, args) \
56  do { \
57  seamless_window *sw; \
58  XRectangle rect; \
59  if (!This->xwin.seamless_windows) break; \
60  for (sw = This->xwin.seamless_windows; sw; sw = sw->next) { \
61  rect.x = This->xwin.clip_rectangle.x - sw->xoffset; \
62  rect.y = This->xwin.clip_rectangle.y - sw->yoffset; \
63  rect.width = This->xwin.clip_rectangle.width; \
64  rect.height = This->xwin.clip_rectangle.height; \
65  XSetClipRectangles(This->display, This->xwin.gc, 0, 0, &rect, 1, YXBanded); \
66  func args; \
67  } \
68  XSetClipRectangles(This->display, This->xwin.gc, 0, 0, &This->xwin.clip_rectangle, 1, YXBanded); \
69  } while (0)
70 
71 static void
72 seamless_XFillPolygon(RDPCLIENT * This, Drawable d, XPoint * points, int npoints, int xoffset, int yoffset)
73 {
74  points[0].x -= xoffset;
75  points[0].y -= yoffset;
76  XFillPolygon(This->display, d, This->xwin.gc, points, npoints, Complex, CoordModePrevious);
77  points[0].x += xoffset;
78  points[0].y += yoffset;
79 }
80 
81 static void
82 seamless_XDrawLines(RDPCLIENT * This, Drawable d, XPoint * points, int npoints, int xoffset, int yoffset)
83 {
84  points[0].x -= xoffset;
85  points[0].y -= yoffset;
86  XDrawLines(This->display, d, This->xwin.gc, points, npoints, CoordModePrevious);
87  points[0].x += xoffset;
88  points[0].y += yoffset;
89 }
90 
91 #define FILL_RECTANGLE(x,y,cx,cy)\
92 { \
93  XFillRectangle(This->display, This->wnd, This->xwin.gc, x, y, cx, cy); \
94  ON_ALL_SEAMLESS_WINDOWS(XFillRectangle, (This->display, sw->wnd, This->xwin.gc, x-sw->xoffset, y-sw->yoffset, cx, cy)); \
95  if (This->ownbackstore) \
96  XFillRectangle(This->display, This->xwin.backstore, This->xwin.gc, x, y, cx, cy); \
97 }
98 
99 #define FILL_RECTANGLE_BACKSTORE(x,y,cx,cy)\
100 { \
101  XFillRectangle(This->display, This->ownbackstore ? This->xwin.backstore : This->wnd, This->xwin.gc, x, y, cx, cy); \
102 }
103 
104 #define FILL_POLYGON(p,np)\
105 { \
106  XFillPolygon(This->display, This->wnd, This->xwin.gc, p, np, Complex, CoordModePrevious); \
107  if (This->ownbackstore) \
108  XFillPolygon(This->display, This->xwin.backstore, This->xwin.gc, p, np, Complex, CoordModePrevious); \
109  ON_ALL_SEAMLESS_WINDOWS(seamless_XFillPolygon, (This, sw->wnd, p, np, sw->xoffset, sw->yoffset)); \
110 }
111 
112 #define DRAW_ELLIPSE(x,y,cx,cy,m)\
113 { \
114  switch (m) \
115  { \
116  case 0: /* Outline */ \
117  XDrawArc(This->display, This->wnd, This->xwin.gc, x, y, cx, cy, 0, 360*64); \
118  ON_ALL_SEAMLESS_WINDOWS(XDrawArc, (This->display, sw->wnd, This->xwin.gc, x-sw->xoffset, y-sw->yoffset, cx, cy, 0, 360*64)); \
119  if (This->ownbackstore) \
120  XDrawArc(This->display, This->xwin.backstore, This->xwin.gc, x, y, cx, cy, 0, 360*64); \
121  break; \
122  case 1: /* Filled */ \
123  XFillArc(This->display, This->wnd, This->xwin.gc, x, y, cx, cy, 0, 360*64); \
124  ON_ALL_SEAMLESS_WINDOWS(XCopyArea, (This->display, This->ownbackstore ? This->xwin.backstore : This->wnd, sw->wnd, This->xwin.gc, \
125  x, y, cx, cy, x-sw->xoffset, y-sw->yoffset)); \
126  if (This->ownbackstore) \
127  XFillArc(This->display, This->xwin.backstore, This->xwin.gc, x, y, cx, cy, 0, 360*64); \
128  break; \
129  } \
130 }
131 
132 #define TRANSLATE(col) ( This->server_depth != 8 ? translate_colour(This, col) : This->owncolmap ? col : This->xwin.colmap[col] )
133 #define SET_FOREGROUND(col) XSetForeground(This->display, This->xwin.gc, TRANSLATE(col));
134 #define SET_BACKGROUND(col) XSetBackground(This->display, This->xwin.gc, TRANSLATE(col));
135 
136 static const int rop2_map[] = {
137  GXclear, /* 0 */
138  GXnor, /* DPon */
139  GXandInverted, /* DPna */
140  GXcopyInverted, /* Pn */
141  GXandReverse, /* PDna */
142  GXinvert, /* Dn */
143  GXxor, /* DPx */
144  GXnand, /* DPan */
145  GXand, /* DPa */
146  GXequiv, /* DPxn */
147  GXnoop, /* D */
148  GXorInverted, /* DPno */
149  GXcopy, /* P */
150  GXorReverse, /* PDno */
151  GXor, /* DPo */
152  GXset /* 1 */
153 };
154 
155 #define SET_FUNCTION(rop2) { if (rop2 != ROP2_COPY) XSetFunction(This->display, This->xwin.gc, rop2_map[rop2]); }
156 #define RESET_FUNCTION(rop2) { if (rop2 != ROP2_COPY) XSetFunction(This->display, This->xwin.gc, GXcopy); }
157 
158 static seamless_window *
159 sw_get_window_by_id(RDPCLIENT * This, unsigned long id)
160 {
161  seamless_window *sw;
162  for (sw = This->xwin.seamless_windows; sw; sw = sw->next)
163  {
164  if (sw->id == id)
165  return sw;
166  }
167  return NULL;
168 }
169 
170 
171 static seamless_window *
173 {
174  seamless_window *sw;
175  for (sw = This->xwin.seamless_windows; sw; sw = sw->next)
176  {
177  if (sw->wnd == wnd)
178  return sw;
179  }
180  return NULL;
181 }
182 
183 
184 static void
185 sw_remove_window(RDPCLIENT * This, seamless_window * win)
186 {
187  seamless_window *sw, **prevnext = &This->xwin.seamless_windows;
188  for (sw = This->xwin.seamless_windows; sw; sw = sw->next)
189  {
190  if (sw == win)
191  {
192  *prevnext = sw->next;
193  sw->group->refcnt--;
194  if (sw->group->refcnt == 0)
195  {
196  XDestroyWindow(This->display, sw->group->wnd);
197  xfree(sw->group);
198  }
199  xfree(sw->position_timer);
200  xfree(sw);
201  return;
202  }
203  prevnext = &sw->next;
204  }
205  return;
206 }
207 
208 
209 /* Move all windows except wnd to new desktop */
210 static void
211 sw_all_to_desktop(RDPCLIENT * This, Window wnd, unsigned int desktop)
212 {
213  seamless_window *sw;
214  for (sw = This->xwin.seamless_windows; sw; sw = sw->next)
215  {
216  if (sw->wnd == wnd)
217  continue;
218  if (sw->desktop != desktop)
219  {
220  ewmh_move_to_desktop(This, sw->wnd, desktop);
221  sw->desktop = desktop;
222  }
223  }
224 }
225 
226 
227 /* Send our position */
228 static void
229 sw_update_position(RDPCLIENT * This, seamless_window * sw)
230 {
231  XWindowAttributes wa;
232  int x, y;
233  Window child_return;
234  unsigned int serial;
235 
236  XGetWindowAttributes(This->display, sw->wnd, &wa);
237  XTranslateCoordinates(This->display, sw->wnd, wa.root,
238  -wa.border_width, -wa.border_width, &x, &y, &child_return);
239 
240  serial = seamless_send_position(This, sw->id, x, y, wa.width, wa.height, 0);
241 
242  sw->outstanding_position = True;
243  sw->outpos_serial = serial;
244 
245  sw->outpos_xoffset = x;
246  sw->outpos_yoffset = y;
247  sw->outpos_width = wa.width;
248  sw->outpos_height = wa.height;
249 }
250 
251 
252 /* Check if it's time to send our position */
253 static void
255 {
256  seamless_window *sw;
257  struct timeval now;
258 
259  gettimeofday(&now, NULL);
260  for (sw = This->xwin.seamless_windows; sw; sw = sw->next)
261  {
262  if (timerisset(sw->position_timer) && timercmp(sw->position_timer, &now, <))
263  {
264  timerclear(sw->position_timer);
266  }
267  }
268 }
269 
270 
271 static void
272 sw_restack_window(RDPCLIENT * This, seamless_window * sw, unsigned long behind)
273 {
274  seamless_window *sw_above;
275 
276  /* Remove window from stack */
277  for (sw_above = This->xwin.seamless_windows; sw_above; sw_above = sw_above->next)
278  {
279  if (sw_above->behind == sw->id)
280  break;
281  }
282 
283  if (sw_above)
284  sw_above->behind = sw->behind;
285 
286  /* And then add it at the new position */
287  for (sw_above = This->xwin.seamless_windows; sw_above; sw_above = sw_above->next)
288  {
289  if (sw_above->behind == behind)
290  break;
291  }
292 
293  if (sw_above)
294  sw_above->behind = sw->id;
295 
296  sw->behind = behind;
297 }
298 
299 
300 static void
301 sw_handle_restack(RDPCLIENT * This, seamless_window * sw)
302 {
303  Status status;
304  Window root, parent, *children;
305  unsigned int nchildren, i;
306  seamless_window *sw_below;
307 
308  status = XQueryTree(This->display, RootWindowOfScreen(This->xwin.screen),
309  &root, &parent, &children, &nchildren);
310  if (!status || !nchildren)
311  return;
312 
313  sw_below = NULL;
314 
315  i = 0;
316  while (children[i] != sw->wnd)
317  {
318  i++;
319  if (i >= nchildren)
320  goto end;
321  }
322 
323  for (i++; i < nchildren; i++)
324  {
325  sw_below = sw_get_window_by_wnd(This, children[i]);
326  if (sw_below)
327  break;
328  }
329 
330  if (!sw_below && !sw->behind)
331  goto end;
332  if (sw_below && (sw_below->id == sw->behind))
333  goto end;
334 
335  if (sw_below)
336  {
337  seamless_send_zchange(This, sw->id, sw_below->id, 0);
338  sw_restack_window(This, sw, sw_below->id);
339  }
340  else
341  {
342  seamless_send_zchange(This, sw->id, 0, 0);
343  sw_restack_window(This, sw, 0);
344  }
345 
346  end:
347  XFree(children);
348 }
349 
350 
351 static seamless_group *
352 sw_find_group(RDPCLIENT * This, unsigned long id, BOOL dont_create)
353 {
354  seamless_window *sw;
355  seamless_group *sg;
356  XSetWindowAttributes attribs;
357 
358  for (sw = This->xwin.seamless_windows; sw; sw = sw->next)
359  {
360  if (sw->group->id == id)
361  return sw->group;
362  }
363 
364  if (dont_create)
365  return NULL;
366 
367  sg = xmalloc(sizeof(seamless_group));
368 
369  sg->wnd =
370  XCreateWindow(This->display, RootWindowOfScreen(This->xwin.screen), -1, -1, 1, 1, 0,
371  CopyFromParent, CopyFromParent, CopyFromParent, 0, &attribs);
372 
373  sg->id = id;
374  sg->refcnt = 0;
375 
376  return sg;
377 }
378 
379 
380 static void
382 {
383  PropMotifWmHints motif_hints;
384  Atom hintsatom;
385 
386  /* setup the property */
387  motif_hints.flags = MWM_HINTS_DECORATIONS;
388  motif_hints.decorations = 0;
389 
390  /* get the atom for the property */
391  hintsatom = XInternAtom(This->display, "_MOTIF_WM_HINTS", False);
392  if (!hintsatom)
393  {
394  warning("Failed to get atom _MOTIF_WM_HINTS: probably your window manager does not support MWM hints\n");
395  return;
396  }
397 
398  XChangeProperty(This->display, wnd, hintsatom, hintsatom, 32, PropModeReplace,
399  (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
400 
401 }
402 
403 #define SPLITCOLOUR15(colour, rv) \
404 { \
405  rv.red = ((colour >> 7) & 0xf8) | ((colour >> 12) & 0x7); \
406  rv.green = ((colour >> 2) & 0xf8) | ((colour >> 8) & 0x7); \
407  rv.blue = ((colour << 3) & 0xf8) | ((colour >> 2) & 0x7); \
408 }
409 
410 #define SPLITCOLOUR16(colour, rv) \
411 { \
412  rv.red = ((colour >> 8) & 0xf8) | ((colour >> 13) & 0x7); \
413  rv.green = ((colour >> 3) & 0xfc) | ((colour >> 9) & 0x3); \
414  rv.blue = ((colour << 3) & 0xf8) | ((colour >> 2) & 0x7); \
415 } \
416 
417 #define SPLITCOLOUR24(colour, rv) \
418 { \
419  rv.blue = (colour & 0xff0000) >> 16; \
420  rv.green = (colour & 0x00ff00) >> 8; \
421  rv.red = (colour & 0x0000ff); \
422 }
423 
424 #define MAKECOLOUR(pc) \
425  ((pc.red >> This->xwin.red_shift_r) << This->xwin.red_shift_l) \
426  | ((pc.green >> This->xwin.green_shift_r) << This->xwin.green_shift_l) \
427  | ((pc.blue >> This->xwin.blue_shift_r) << This->xwin.blue_shift_l) \
428 
429 #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
430 #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | (x & 0xff00)); }
431 #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
432  x = (x << 16) | (x >> 16); }
433 
434 /* The following macros output the same octet sequences
435  on both BE and LE hosts: */
436 
437 #define BOUT16(o, x) { *(o++) = x >> 8; *(o++) = x; }
438 #define BOUT24(o, x) { *(o++) = x >> 16; *(o++) = x >> 8; *(o++) = x; }
439 #define BOUT32(o, x) { *(o++) = x >> 24; *(o++) = x >> 16; *(o++) = x >> 8; *(o++) = x; }
440 #define LOUT16(o, x) { *(o++) = x; *(o++) = x >> 8; }
441 #define LOUT24(o, x) { *(o++) = x; *(o++) = x >> 8; *(o++) = x >> 16; }
442 #define LOUT32(o, x) { *(o++) = x; *(o++) = x >> 8; *(o++) = x >> 16; *(o++) = x >> 24; }
443 
444 static uint32
446 {
447  PixelColour pc;
448  switch (This->server_depth)
449  {
450  case 15:
451  SPLITCOLOUR15(colour, pc);
452  break;
453  case 16:
454  SPLITCOLOUR16(colour, pc);
455  break;
456  case 24:
457  SPLITCOLOUR24(colour, pc);
458  break;
459  default:
460  /* Avoid warning */
461  pc.red = 0;
462  pc.green = 0;
463  pc.blue = 0;
464  break;
465  }
466  return MAKECOLOUR(pc);
467 }
468 
469 /* indent is confused by UNROLL8 */
470 /* *INDENT-OFF* */
471 
472 /* repeat and unroll, similar to bitmap.c */
473 /* potentialy any of the following translate */
474 /* functions can use repeat but just doing */
475 /* the most common ones */
476 
477 #define UNROLL8(stm) { stm stm stm stm stm stm stm stm }
478 /* 2 byte output repeat */
479 #define REPEAT2(stm) \
480 { \
481  while (out <= end - 8 * 2) \
482  UNROLL8(stm) \
483  while (out < end) \
484  { stm } \
485 }
486 /* 3 byte output repeat */
487 #define REPEAT3(stm) \
488 { \
489  while (out <= end - 8 * 3) \
490  UNROLL8(stm) \
491  while (out < end) \
492  { stm } \
493 }
494 /* 4 byte output repeat */
495 #define REPEAT4(stm) \
496 { \
497  while (out <= end - 8 * 4) \
498  UNROLL8(stm) \
499  while (out < end) \
500  { stm } \
501 }
502 /* *INDENT-ON* */
503 
504 static void
506 {
507  while (out < end)
508  *(out++) = (uint8) This->xwin.colmap[*(data++)];
509 }
510 
511 static void
513 {
514  uint16 value;
515 
516  if (This->xwin.compatible_arch)
517  {
518  /* *INDENT-OFF* */
519  REPEAT2
520  (
521  *((uint16 *) out) = This->xwin.colmap[*(data++)];
522  out += 2;
523  )
524  /* *INDENT-ON* */
525  }
526  else if (This->xwin.xserver_be)
527  {
528  while (out < end)
529  {
530  value = (uint16) This->xwin.colmap[*(data++)];
531  BOUT16(out, value);
532  }
533  }
534  else
535  {
536  while (out < end)
537  {
538  value = (uint16) This->xwin.colmap[*(data++)];
539  LOUT16(out, value);
540  }
541  }
542 }
543 
544 /* little endian - conversion happens when colourmap is built */
545 static void
547 {
548  uint32 value;
549 
550  if (This->xwin.compatible_arch)
551  {
552  while (out < end)
553  {
554  value = This->xwin.colmap[*(data++)];
555  BOUT24(out, value);
556  }
557  }
558  else
559  {
560  while (out < end)
561  {
562  value = This->xwin.colmap[*(data++)];
563  LOUT24(out, value);
564  }
565  }
566 }
567 
568 static void
570 {
571  uint32 value;
572 
573  if (This->xwin.compatible_arch)
574  {
575  /* *INDENT-OFF* */
576  REPEAT4
577  (
578  *((uint32 *) out) = This->xwin.colmap[*(data++)];
579  out += 4;
580  )
581  /* *INDENT-ON* */
582  }
583  else if (This->xwin.xserver_be)
584  {
585  while (out < end)
586  {
587  value = This->xwin.colmap[*(data++)];
588  BOUT32(out, value);
589  }
590  }
591  else
592  {
593  while (out < end)
594  {
595  value = This->xwin.colmap[*(data++)];
596  LOUT32(out, value);
597  }
598  }
599 }
600 
601 static void
603 {
604  uint16 pixel;
605  uint16 value;
606  PixelColour pc;
607 
608  if (This->xwin.xserver_be)
609  {
610  while (out < end)
611  {
612  pixel = *(data++);
613  if (This->xwin.host_be)
614  {
615  BSWAP16(pixel);
616  }
617  SPLITCOLOUR15(pixel, pc);
618  value = MAKECOLOUR(pc);
619  BOUT16(out, value);
620  }
621  }
622  else
623  {
624  while (out < end)
625  {
626  pixel = *(data++);
627  if (This->xwin.host_be)
628  {
629  BSWAP16(pixel);
630  }
631  SPLITCOLOUR15(pixel, pc);
632  value = MAKECOLOUR(pc);
633  LOUT16(out, value);
634  }
635  }
636 }
637 
638 static void
640 {
641  uint32 value;
642  uint16 pixel;
643  PixelColour pc;
644 
645  if (This->xwin.compatible_arch)
646  {
647  /* *INDENT-OFF* */
648  REPEAT3
649  (
650  pixel = *(data++);
651  SPLITCOLOUR15(pixel, pc);
652  *(out++) = pc.blue;
653  *(out++) = pc.green;
654  *(out++) = pc.red;
655  )
656  /* *INDENT-ON* */
657  }
658  else if (This->xwin.xserver_be)
659  {
660  while (out < end)
661  {
662  pixel = *(data++);
663  if (This->xwin.host_be)
664  {
665  BSWAP16(pixel);
666  }
667  SPLITCOLOUR15(pixel, pc);
668  value = MAKECOLOUR(pc);
669  BOUT24(out, value);
670  }
671  }
672  else
673  {
674  while (out < end)
675  {
676  pixel = *(data++);
677  if (This->xwin.host_be)
678  {
679  BSWAP16(pixel);
680  }
681  SPLITCOLOUR15(pixel, pc);
682  value = MAKECOLOUR(pc);
683  LOUT24(out, value);
684  }
685  }
686 }
687 
688 static void
690 {
691  uint16 pixel;
692  uint32 value;
693  PixelColour pc;
694 
695  if (This->xwin.compatible_arch)
696  {
697  /* *INDENT-OFF* */
698  REPEAT4
699  (
700  pixel = *(data++);
701  SPLITCOLOUR15(pixel, pc);
702  *(out++) = pc.blue;
703  *(out++) = pc.green;
704  *(out++) = pc.red;
705  *(out++) = 0;
706  )
707  /* *INDENT-ON* */
708  }
709  else if (This->xwin.xserver_be)
710  {
711  while (out < end)
712  {
713  pixel = *(data++);
714  if (This->xwin.host_be)
715  {
716  BSWAP16(pixel);
717  }
718  SPLITCOLOUR15(pixel, pc);
719  value = MAKECOLOUR(pc);
720  BOUT32(out, value);
721  }
722  }
723  else
724  {
725  while (out < end)
726  {
727  pixel = *(data++);
728  if (This->xwin.host_be)
729  {
730  BSWAP16(pixel);
731  }
732  SPLITCOLOUR15(pixel, pc);
733  value = MAKECOLOUR(pc);
734  LOUT32(out, value);
735  }
736  }
737 }
738 
739 static void
741 {
742  uint16 pixel;
743  uint16 value;
744  PixelColour pc;
745 
746  if (This->xwin.xserver_be)
747  {
748  if (This->xwin.host_be)
749  {
750  while (out < end)
751  {
752  pixel = *(data++);
753  BSWAP16(pixel);
754  SPLITCOLOUR16(pixel, pc);
755  value = MAKECOLOUR(pc);
756  BOUT16(out, value);
757  }
758  }
759  else
760  {
761  while (out < end)
762  {
763  pixel = *(data++);
764  SPLITCOLOUR16(pixel, pc);
765  value = MAKECOLOUR(pc);
766  BOUT16(out, value);
767  }
768  }
769  }
770  else
771  {
772  if (This->xwin.host_be)
773  {
774  while (out < end)
775  {
776  pixel = *(data++);
777  BSWAP16(pixel);
778  SPLITCOLOUR16(pixel, pc);
779  value = MAKECOLOUR(pc);
780  LOUT16(out, value);
781  }
782  }
783  else
784  {
785  while (out < end)
786  {
787  pixel = *(data++);
788  SPLITCOLOUR16(pixel, pc);
789  value = MAKECOLOUR(pc);
790  LOUT16(out, value);
791  }
792  }
793  }
794 }
795 
796 static void
798 {
799  uint32 value;
800  uint16 pixel;
801  PixelColour pc;
802 
803  if (This->xwin.compatible_arch)
804  {
805  /* *INDENT-OFF* */
806  REPEAT3
807  (
808  pixel = *(data++);
809  SPLITCOLOUR16(pixel, pc);
810  *(out++) = pc.blue;
811  *(out++) = pc.green;
812  *(out++) = pc.red;
813  )
814  /* *INDENT-ON* */
815  }
816  else if (This->xwin.xserver_be)
817  {
818  if (This->xwin.host_be)
819  {
820  while (out < end)
821  {
822  pixel = *(data++);
823  BSWAP16(pixel);
824  SPLITCOLOUR16(pixel, pc);
825  value = MAKECOLOUR(pc);
826  BOUT24(out, value);
827  }
828  }
829  else
830  {
831  while (out < end)
832  {
833  pixel = *(data++);
834  SPLITCOLOUR16(pixel, pc);
835  value = MAKECOLOUR(pc);
836  BOUT24(out, value);
837  }
838  }
839  }
840  else
841  {
842  if (This->xwin.host_be)
843  {
844  while (out < end)
845  {
846  pixel = *(data++);
847  BSWAP16(pixel);
848  SPLITCOLOUR16(pixel, pc);
849  value = MAKECOLOUR(pc);
850  LOUT24(out, value);
851  }
852  }
853  else
854  {
855  while (out < end)
856  {
857  pixel = *(data++);
858  SPLITCOLOUR16(pixel, pc);
859  value = MAKECOLOUR(pc);
860  LOUT24(out, value);
861  }
862  }
863  }
864 }
865 
866 static void
868 {
869  uint16 pixel;
870  uint32 value;
871  PixelColour pc;
872 
873  if (This->xwin.compatible_arch)
874  {
875  /* *INDENT-OFF* */
876  REPEAT4
877  (
878  pixel = *(data++);
879  SPLITCOLOUR16(pixel, pc);
880  *(out++) = pc.blue;
881  *(out++) = pc.green;
882  *(out++) = pc.red;
883  *(out++) = 0;
884  )
885  /* *INDENT-ON* */
886  }
887  else if (This->xwin.xserver_be)
888  {
889  if (This->xwin.host_be)
890  {
891  while (out < end)
892  {
893  pixel = *(data++);
894  BSWAP16(pixel);
895  SPLITCOLOUR16(pixel, pc);
896  value = MAKECOLOUR(pc);
897  BOUT32(out, value);
898  }
899  }
900  else
901  {
902  while (out < end)
903  {
904  pixel = *(data++);
905  SPLITCOLOUR16(pixel, pc);
906  value = MAKECOLOUR(pc);
907  BOUT32(out, value);
908  }
909  }
910  }
911  else
912  {
913  if (This->xwin.host_be)
914  {
915  while (out < end)
916  {
917  pixel = *(data++);
918  BSWAP16(pixel);
919  SPLITCOLOUR16(pixel, pc);
920  value = MAKECOLOUR(pc);
921  LOUT32(out, value);
922  }
923  }
924  else
925  {
926  while (out < end)
927  {
928  pixel = *(data++);
929  SPLITCOLOUR16(pixel, pc);
930  value = MAKECOLOUR(pc);
931  LOUT32(out, value);
932  }
933  }
934  }
935 }
936 
937 static void
939 {
940  uint32 pixel = 0;
941  uint16 value;
942  PixelColour pc;
943 
944  while (out < end)
945  {
946  pixel = *(data++) << 16;
947  pixel |= *(data++) << 8;
948  pixel |= *(data++);
949  SPLITCOLOUR24(pixel, pc);
950  value = MAKECOLOUR(pc);
951  if (This->xwin.xserver_be)
952  {
953  BOUT16(out, value);
954  }
955  else
956  {
957  LOUT16(out, value);
958  }
959  }
960 }
961 
962 static void
964 {
965  uint32 pixel;
966  uint32 value;
967  PixelColour pc;
968 
969  if (This->xwin.xserver_be)
970  {
971  while (out < end)
972  {
973  pixel = *(data++) << 16;
974  pixel |= *(data++) << 8;
975  pixel |= *(data++);
976  SPLITCOLOUR24(pixel, pc);
977  value = MAKECOLOUR(pc);
978  BOUT24(out, value);
979  }
980  }
981  else
982  {
983  while (out < end)
984  {
985  pixel = *(data++) << 16;
986  pixel |= *(data++) << 8;
987  pixel |= *(data++);
988  SPLITCOLOUR24(pixel, pc);
989  value = MAKECOLOUR(pc);
990  LOUT24(out, value);
991  }
992  }
993 }
994 
995 static void
997 {
998  uint32 pixel;
999  uint32 value;
1000  PixelColour pc;
1001 
1002  if (This->xwin.compatible_arch)
1003  {
1004  /* *INDENT-OFF* */
1005 #ifdef NEED_ALIGN
1006  REPEAT4
1007  (
1008  *(out++) = *(data++);
1009  *(out++) = *(data++);
1010  *(out++) = *(data++);
1011  *(out++) = 0;
1012  )
1013 #else
1014  REPEAT4
1015  (
1016  /* Only read 3 bytes. Reading 4 bytes means reading beyond buffer. */
1017  *((uint32 *) out) = *((uint16 *) data) + (*((uint8 *) data + 2) << 16);
1018  out += 4;
1019  data += 3;
1020  )
1021 #endif
1022  /* *INDENT-ON* */
1023  }
1024  else if (This->xwin.xserver_be)
1025  {
1026  while (out < end)
1027  {
1028  pixel = *(data++) << 16;
1029  pixel |= *(data++) << 8;
1030  pixel |= *(data++);
1031  SPLITCOLOUR24(pixel, pc);
1032  value = MAKECOLOUR(pc);
1033  BOUT32(out, value);
1034  }
1035  }
1036  else
1037  {
1038  while (out < end)
1039  {
1040  pixel = *(data++) << 16;
1041  pixel |= *(data++) << 8;
1042  pixel |= *(data++);
1043  SPLITCOLOUR24(pixel, pc);
1044  value = MAKECOLOUR(pc);
1045  LOUT32(out, value);
1046  }
1047  }
1048 }
1049 
1050 static uint8 *
1052 {
1053  int size;
1054  uint8 *out;
1055  uint8 *end;
1056 
1057  /*
1058  If RDP depth and X Visual depths match,
1059  and arch(endian) matches, no need to translate:
1060  just return data.
1061  Note: select_visual should've already ensured g_no_translate
1062  is only set for compatible depths, but the RDP depth might've
1063  changed during connection negotiations.
1064  */
1065  if (This->xwin.no_translate_image)
1066  {
1067  if ((This->xwin.depth == 15 && This->server_depth == 15) ||
1068  (This->xwin.depth == 16 && This->server_depth == 16) ||
1069  (This->xwin.depth == 24 && This->server_depth == 24))
1070  return data;
1071  }
1072 
1073  size = width * height * (This->xwin.bpp / 8);
1074  out = (uint8 *) xmalloc(size);
1075  end = out + size;
1076 
1077  switch (This->server_depth)
1078  {
1079  case 24:
1080  switch (This->xwin.bpp)
1081  {
1082  case 32:
1084  break;
1085  case 24:
1087  break;
1088  case 16:
1090  break;
1091  }
1092  break;
1093  case 16:
1094  switch (This->xwin.bpp)
1095  {
1096  case 32:
1098  break;
1099  case 24:
1101  break;
1102  case 16:
1104  break;
1105  }
1106  break;
1107  case 15:
1108  switch (This->xwin.bpp)
1109  {
1110  case 32:
1112  break;
1113  case 24:
1115  break;
1116  case 16:
1118  break;
1119  }
1120  break;
1121  case 8:
1122  switch (This->xwin.bpp)
1123  {
1124  case 8:
1126  break;
1127  case 16:
1129  break;
1130  case 24:
1132  break;
1133  case 32:
1135  break;
1136  }
1137  break;
1138  }
1139  return out;
1140 }
1141 
1142 BOOL
1143 get_key_state(RDPCLIENT * This, unsigned int state, uint32 keysym)
1144 {
1145  int modifierpos, key, keysymMask = 0;
1146  int offset;
1147 
1148  KeyCode keycode = XKeysymToKeycode(This->display, keysym);
1149 
1150  if (keycode == NoSymbol)
1151  return False;
1152 
1153  for (modifierpos = 0; modifierpos < 8; modifierpos++)
1154  {
1155  offset = This->xwin.mod_map->max_keypermod * modifierpos;
1156 
1157  for (key = 0; key < This->xwin.mod_map->max_keypermod; key++)
1158  {
1159  if (This->xwin.mod_map->modifiermap[offset + key] == keycode)
1160  keysymMask |= 1 << modifierpos;
1161  }
1162  }
1163 
1164  return (state & keysymMask) ? True : False;
1165 }
1166 
1167 static void
1168 calculate_shifts(uint32 mask, int *shift_r, int *shift_l)
1169 {
1170  *shift_l = ffs(mask) - 1;
1171  mask >>= *shift_l;
1172  *shift_r = 8 - ffs(mask & ~(mask >> 1));
1173 }
1174 
1175 /* Given a mask of a colour channel (e.g. XVisualInfo.red_mask),
1176  calculates the bits-per-pixel of this channel (a.k.a. colour weight).
1177  */
1178 static unsigned
1180 {
1181  unsigned weight = 0;
1182  do
1183  {
1184  weight += (mask & 1);
1185  }
1186  while (mask >>= 1);
1187  return weight;
1188 }
1189 
1190 static BOOL
1192 {
1193  XPixmapFormatValues *pfm;
1194  int pixmap_formats_count, visuals_count;
1195  XVisualInfo *vmatches = NULL;
1196  XVisualInfo template;
1197  int i;
1198  unsigned red_weight, blue_weight, green_weight;
1199 
1200  red_weight = blue_weight = green_weight = 0;
1201 
1202  if (This->server_depth == -1)
1203  {
1204  This->server_depth = DisplayPlanes(This->display, DefaultScreen(This->display));
1205  }
1206 
1207  pfm = XListPixmapFormats(This->display, &pixmap_formats_count);
1208  if (pfm == NULL)
1209  {
1210  error("Unable to get list of pixmap formats from display.\n");
1211  XCloseDisplay(This->display);
1212  return False;
1213  }
1214 
1215  /* Search for best TrueColor visual */
1216  template.class = TrueColor;
1217  vmatches = XGetVisualInfo(This->display, VisualClassMask, &template, &visuals_count);
1218  This->xwin.visual = NULL;
1219  This->xwin.no_translate_image = False;
1220  This->xwin.compatible_arch = False;
1221  if (vmatches != NULL)
1222  {
1223  for (i = 0; i < visuals_count; ++i)
1224  {
1225  XVisualInfo *visual_info = &vmatches[i];
1226  BOOL can_translate_to_bpp = False;
1227  int j;
1228 
1229  /* Try to find a no-translation visual that'll
1230  allow us to use RDP bitmaps directly as ZPixmaps. */
1231  if (!This->xwin.xserver_be && (((visual_info->depth == 15) &&
1232  /* R5G5B5 */
1233  (visual_info->red_mask == 0x7c00) &&
1234  (visual_info->green_mask == 0x3e0) &&
1235  (visual_info->blue_mask == 0x1f)) ||
1236  ((visual_info->depth == 16) &&
1237  /* R5G6B5 */
1238  (visual_info->red_mask == 0xf800) &&
1239  (visual_info->green_mask == 0x7e0) &&
1240  (visual_info->blue_mask == 0x1f)) ||
1241  ((visual_info->depth == 24) &&
1242  /* R8G8B8 */
1243  (visual_info->red_mask == 0xff0000) &&
1244  (visual_info->green_mask == 0xff00) &&
1245  (visual_info->blue_mask == 0xff))))
1246  {
1247  This->xwin.visual = visual_info->visual;
1248  This->xwin.depth = visual_info->depth;
1249  This->xwin.compatible_arch = !This->xwin.host_be;
1250  This->xwin.no_translate_image = (visual_info->depth == This->server_depth);
1251  if (This->xwin.no_translate_image)
1252  /* We found the best visual */
1253  break;
1254  }
1255  else
1256  {
1257  This->xwin.compatible_arch = False;
1258  }
1259 
1260  if (visual_info->depth > 24)
1261  {
1262  /* Avoid 32-bit visuals and likes like the plague.
1263  They're either untested or proven to work bad
1264  (e.g. nvidia's Composite 32-bit visual).
1265  Most implementation offer a 24-bit visual anyway. */
1266  continue;
1267  }
1268 
1269  /* Only care for visuals, for whose BPPs (not depths!)
1270  we have a translateXtoY function. */
1271  for (j = 0; j < pixmap_formats_count; ++j)
1272  {
1273  if (pfm[j].depth == visual_info->depth)
1274  {
1275  if ((pfm[j].bits_per_pixel == 16) ||
1276  (pfm[j].bits_per_pixel == 24) ||
1277  (pfm[j].bits_per_pixel == 32))
1278  {
1279  can_translate_to_bpp = True;
1280  }
1281  break;
1282  }
1283  }
1284 
1285  /* Prefer formats which have the most colour depth.
1286  We're being truly aristocratic here, minding each
1287  weight on its own. */
1288  if (can_translate_to_bpp)
1289  {
1290  unsigned vis_red_weight =
1291  calculate_mask_weight(visual_info->red_mask);
1292  unsigned vis_green_weight =
1293  calculate_mask_weight(visual_info->green_mask);
1294  unsigned vis_blue_weight =
1295  calculate_mask_weight(visual_info->blue_mask);
1296  if ((vis_red_weight >= red_weight)
1297  && (vis_green_weight >= green_weight)
1298  && (vis_blue_weight >= blue_weight))
1299  {
1300  red_weight = vis_red_weight;
1301  green_weight = vis_green_weight;
1302  blue_weight = vis_blue_weight;
1303  This->xwin.visual = visual_info->visual;
1304  This->xwin.depth = visual_info->depth;
1305  }
1306  }
1307  }
1308  XFree(vmatches);
1309  }
1310 
1311  if (This->xwin.visual != NULL)
1312  {
1313  This->owncolmap = False;
1314  calculate_shifts(This->xwin.visual->red_mask, &This->xwin.red_shift_r, &This->xwin.red_shift_l);
1315  calculate_shifts(This->xwin.visual->green_mask, &This->xwin.green_shift_r, &This->xwin.green_shift_l);
1316  calculate_shifts(This->xwin.visual->blue_mask, &This->xwin.blue_shift_r, &This->xwin.blue_shift_l);
1317  }
1318  else
1319  {
1320  template.class = PseudoColor;
1321  template.depth = 8;
1322  template.colormap_size = 256;
1323  vmatches =
1324  XGetVisualInfo(This->display,
1325  VisualClassMask | VisualDepthMask | VisualColormapSizeMask,
1326  &template, &visuals_count);
1327  if (vmatches == NULL)
1328  {
1329  error("No usable TrueColor or PseudoColor visuals on this display.\n");
1330  XCloseDisplay(This->display);
1331  XFree(pfm);
1332  return False;
1333  }
1334 
1335  /* we use a colourmap, so the default visual should do */
1336  This->owncolmap = True;
1337  This->xwin.visual = vmatches[0].visual;
1338  This->xwin.depth = vmatches[0].depth;
1339  }
1340 
1341  This->xwin.bpp = 0;
1342  for (i = 0; i < pixmap_formats_count; ++i)
1343  {
1344  XPixmapFormatValues *pf = &pfm[i];
1345  if (pf->depth == This->xwin.depth)
1346  {
1347  This->xwin.bpp = pf->bits_per_pixel;
1348 
1349  if (This->xwin.no_translate_image)
1350  {
1351  switch (This->server_depth)
1352  {
1353  case 15:
1354  case 16:
1355  if (This->xwin.bpp != 16)
1356  This->xwin.no_translate_image = False;
1357  break;
1358  case 24:
1359  /* Yes, this will force image translation
1360  on most modern servers which use 32 bits
1361  for R8G8B8. */
1362  if (This->xwin.bpp != 24)
1363  This->xwin.no_translate_image = False;
1364  break;
1365  default:
1366  This->xwin.no_translate_image = False;
1367  break;
1368  }
1369  }
1370 
1371  /* Pixmap formats list is a depth-to-bpp mapping --
1372  there's just a single entry for every depth,
1373  so we can safely break here */
1374  break;
1375  }
1376  }
1377  XFree(pfm);
1378  pfm = NULL;
1379  return True;
1380 }
1381 
1382 /*
1383 static int
1384 error_handler(RDPCLIENT * This, Display * dpy, XErrorEvent * eev)
1385 {
1386  if ((eev->error_code == BadMatch) && (eev->request_code == X_ConfigureWindow))
1387  {
1388  fprintf(stderr, "Got \"BadMatch\" when trying to restack windows.\n");
1389  fprintf(stderr,
1390  "This is most likely caused by a broken window manager (commonly KWin).\n");
1391  return 0;
1392  }
1393 
1394  return This->xwin.old_error_handler(dpy, eev);
1395 }
1396 */
1397 
1398 BOOL
1400 {
1401  int screen_num;
1402 
1403  This->display = XOpenDisplay(NULL);
1404  if (This->display == NULL)
1405  {
1406  error("Failed to open display: %s\n", XDisplayName(NULL));
1407  return False;
1408  }
1409 
1410  {
1411  uint16 endianess_test = 1;
1412  This->xwin.host_be = !(BOOL) (*(uint8 *) (&endianess_test));
1413  }
1414 
1415  /*This->xwin.old_error_handler = XSetErrorHandler(error_handler);*/
1416  This->xwin.xserver_be = (ImageByteOrder(This->display) == MSBFirst);
1417  screen_num = DefaultScreen(This->display);
1418  This->xwin.x_socket = ConnectionNumber(This->display);
1419  This->xwin.screen = ScreenOfDisplay(This->display, screen_num);
1420  This->xwin.depth = DefaultDepthOfScreen(This->xwin.screen);
1421 
1422  if (!select_visual(This))
1423  return False;
1424 
1425  if (This->xwin.no_translate_image)
1426  {
1427  DEBUG(("Performance optimization possible: avoiding image translation (colour depth conversion).\n"));
1428  }
1429 
1430  if (This->server_depth > This->xwin.bpp)
1431  {
1432  warning("Remote desktop colour depth %d higher than display colour depth %d.\n",
1433  This->server_depth, This->xwin.bpp);
1434  }
1435 
1436  DEBUG(("RDP depth: %d, display depth: %d, display bpp: %d, X server BE: %d, host BE: %d\n",
1437  This->server_depth, This->xwin.depth, This->xwin.bpp, This->xwin.xserver_be, This->xwin.host_be));
1438 
1439  if (!This->owncolmap)
1440  {
1441  This->xwin.xcolmap =
1442  XCreateColormap(This->display, RootWindowOfScreen(This->xwin.screen), This->xwin.visual,
1443  AllocNone);
1444  if (This->xwin.depth <= 8)
1445  warning("Display colour depth is %d bit: you may want to use -C for a private colourmap.\n", This->xwin.depth);
1446  }
1447 
1448  if ((!This->ownbackstore) && (DoesBackingStore(This->xwin.screen) != Always))
1449  {
1450  warning("External BackingStore not available. Using internal.\n");
1451  This->ownbackstore = True;
1452  }
1453 
1454  /*
1455  * Determine desktop size
1456  */
1457  if (This->fullscreen)
1458  {
1459  This->width = WidthOfScreen(This->xwin.screen);
1460  This->height = HeightOfScreen(This->xwin.screen);
1461  This->xwin.using_full_workarea = True;
1462  }
1463  else if (This->width < 0)
1464  {
1465  /* Percent of screen */
1466  if (-This->width >= 100)
1467  This->xwin.using_full_workarea = True;
1468  This->height = HeightOfScreen(This->xwin.screen) * (-This->width) / 100;
1469  This->width = WidthOfScreen(This->xwin.screen) * (-This->width) / 100;
1470  }
1471  else if (This->width == 0)
1472  {
1473  /* Fetch geometry from _NET_WORKAREA */
1474  uint32 x, y, cx, cy;
1475  if (get_current_workarea(This, &x, &y, &cx, &cy) == 0)
1476  {
1477  This->width = cx;
1478  This->height = cy;
1479  This->xwin.using_full_workarea = True;
1480  }
1481  else
1482  {
1483  warning("Failed to get workarea: probably your window manager does not support extended hints\n");
1484  This->width = WidthOfScreen(This->xwin.screen);
1485  This->height = HeightOfScreen(This->xwin.screen);
1486  }
1487  }
1488 
1489  /* make sure width is a multiple of 4 */
1490  This->width = (This->width + 3) & ~3;
1491 
1492  This->xwin.mod_map = XGetModifierMapping(This->display);
1493 
1494  xkeymap_init(This);
1495 
1496  if (This->enable_compose)
1497  This->xwin.IM = XOpenIM(This->display, NULL, NULL, NULL);
1498 
1499  xclip_init(This);
1500  ewmh_init(This);
1501  if (This->seamless_rdp)
1503 
1504  DEBUG_RDP5(("server bpp %d client bpp %d depth %d\n", This->server_depth, This->xwin.bpp, This->xwin.depth));
1505 
1506  return True;
1507 }
1508 
1509 void
1511 {
1512  while (This->xwin.seamless_windows)
1513  {
1514  XDestroyWindow(This->display, This->xwin.seamless_windows->wnd);
1515  sw_remove_window(This, This->xwin.seamless_windows);
1516  }
1517 
1518  xclip_deinit(This);
1519 
1520  if (This->xwin.IM != NULL)
1521  XCloseIM(This->xwin.IM);
1522 
1523  if (This->xwin.null_cursor != NULL)
1524  ui_destroy_cursor(This, This->xwin.null_cursor);
1525 
1526  XFreeModifiermap(This->xwin.mod_map);
1527 
1528  if (This->ownbackstore)
1529  XFreePixmap(This->display, This->xwin.backstore);
1530 
1531  XFreeGC(This->display, This->xwin.gc);
1532  XCloseDisplay(This->display);
1533  This->display = NULL;
1534 }
1535 
1536 
1537 static void
1538 get_window_attribs(RDPCLIENT * This, XSetWindowAttributes * attribs)
1539 {
1540  attribs->background_pixel = BlackPixelOfScreen(This->xwin.screen);
1541  attribs->background_pixel = WhitePixelOfScreen(This->xwin.screen);
1542  attribs->border_pixel = WhitePixelOfScreen(This->xwin.screen);
1543  attribs->backing_store = This->ownbackstore ? NotUseful : Always;
1544  attribs->override_redirect = This->fullscreen;
1545  attribs->colormap = This->xwin.xcolmap;
1546 }
1547 
1548 static void
1549 get_input_mask(RDPCLIENT * This, long *input_mask)
1550 {
1551  *input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
1552  VisibilityChangeMask | FocusChangeMask | StructureNotifyMask;
1553 
1554  if (This->sendmotion)
1555  *input_mask |= PointerMotionMask;
1556  if (This->ownbackstore)
1557  *input_mask |= ExposureMask;
1558  if (This->fullscreen || This->grab_keyboard)
1559  *input_mask |= EnterWindowMask;
1560  if (This->grab_keyboard)
1561  *input_mask |= LeaveWindowMask;
1562 }
1563 
1564 BOOL
1566 {
1567  uint8 null_pointer_mask[1] = { 0x80 };
1568  uint8 null_pointer_data[24] = { 0x00 };
1569 
1570  XSetWindowAttributes attribs;
1571  XClassHint *classhints;
1572  XSizeHints *sizehints;
1573  int wndwidth, wndheight;
1574  long input_mask, ic_input_mask;
1575  XEvent xevent;
1576 
1577  wndwidth = This->fullscreen ? WidthOfScreen(This->xwin.screen) : This->width;
1578  wndheight = This->fullscreen ? HeightOfScreen(This->xwin.screen) : This->height;
1579 
1580  /* Handle -x-y portion of geometry string */
1581  if (This->xpos < 0 || (This->xpos == 0 && (This->pos & 2)))
1582  This->xpos = WidthOfScreen(This->xwin.screen) + This->xpos - This->width;
1583  if (This->ypos < 0 || (This->ypos == 0 && (This->pos & 4)))
1584  This->ypos = HeightOfScreen(This->xwin.screen) + This->ypos - This->height;
1585 
1587 
1588  This->wnd = XCreateWindow(This->display, RootWindowOfScreen(This->xwin.screen), This->xpos, This->ypos, wndwidth,
1589  wndheight, 0, This->xwin.depth, InputOutput, This->xwin.visual,
1590  CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
1591  CWBorderPixel, &attribs);
1592 
1593  if (This->xwin.gc == NULL)
1594  {
1595  This->xwin.gc = XCreateGC(This->display, This->wnd, 0, NULL);
1597  }
1598 
1599  if (This->xwin.create_bitmap_gc == NULL)
1600  This->xwin.create_bitmap_gc = XCreateGC(This->display, This->wnd, 0, NULL);
1601 
1602  if ((This->ownbackstore) && (This->xwin.backstore == 0))
1603  {
1604  This->xwin.backstore = XCreatePixmap(This->display, This->wnd, This->width, This->height, This->xwin.depth);
1605 
1606  /* clear to prevent rubbish being exposed at startup */
1607  XSetForeground(This->display, This->xwin.gc, BlackPixelOfScreen(This->xwin.screen));
1608  XFillRectangle(This->display, This->xwin.backstore, This->xwin.gc, 0, 0, This->width, This->height);
1609  }
1610 
1611  XStoreName(This->display, This->wnd, This->title);
1612 
1613  if (This->hide_decorations)
1615 
1616  classhints = XAllocClassHint();
1617  if (classhints != NULL)
1618  {
1619  classhints->res_name = classhints->res_class = "rdesktop";
1620  XSetClassHint(This->display, This->wnd, classhints);
1621  XFree(classhints);
1622  }
1623 
1624  sizehints = XAllocSizeHints();
1625  if (sizehints)
1626  {
1627  sizehints->flags = PMinSize | PMaxSize;
1628  if (This->pos)
1629  sizehints->flags |= PPosition;
1630  sizehints->min_width = sizehints->max_width = This->width;
1631  sizehints->min_height = sizehints->max_height = This->height;
1632  XSetWMNormalHints(This->display, This->wnd, sizehints);
1633  XFree(sizehints);
1634  }
1635 
1636  if (This->embed_wnd)
1637  {
1638  XReparentWindow(This->display, This->wnd, (Window) This->embed_wnd, 0, 0);
1639  }
1640 
1641  get_input_mask(This, &input_mask);
1642 
1643  if (This->xwin.IM != NULL)
1644  {
1645  This->xwin.IC = XCreateIC(This->xwin.IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
1646  XNClientWindow, This->wnd, XNFocusWindow, This->wnd, NULL);
1647 
1648  if ((This->xwin.IC != NULL)
1649  && (XGetICValues(This->xwin.IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))
1650  input_mask |= ic_input_mask;
1651  }
1652 
1653  XSelectInput(This->display, This->wnd, input_mask);
1654  XMapWindow(This->display, This->wnd);
1655 
1656  /* wait for VisibilityNotify */
1657  do
1658  {
1659  XMaskEvent(This->display, VisibilityChangeMask, &xevent);
1660  }
1661  while (xevent.type != VisibilityNotify);
1662  This->Unobscured = xevent.xvisibility.state == VisibilityUnobscured;
1663 
1664  This->xwin.focused = False;
1665  This->xwin.mouse_in_wnd = False;
1666 
1667  /* handle the WM_DELETE_WINDOW protocol */
1668  This->xwin.protocol_atom = XInternAtom(This->display, "WM_PROTOCOLS", True);
1669  This->xwin.kill_atom = XInternAtom(This->display, "WM_DELETE_WINDOW", True);
1670  XSetWMProtocols(This->display, This->wnd, &This->xwin.kill_atom, 1);
1671 
1672  /* create invisible 1x1 cursor to be used as null cursor */
1673  if (This->xwin.null_cursor == NULL)
1674  This->xwin.null_cursor = ui_create_cursor(This, 0, 0, 1, 1, null_pointer_mask, null_pointer_data);
1675 
1676  return True;
1677 }
1678 
1679 void
1681 {
1682  XSizeHints *sizehints;
1683  Pixmap bs;
1684 
1685  sizehints = XAllocSizeHints();
1686  if (sizehints)
1687  {
1688  sizehints->flags = PMinSize | PMaxSize;
1689  sizehints->min_width = sizehints->max_width = This->width;
1690  sizehints->min_height = sizehints->max_height = This->height;
1691  XSetWMNormalHints(This->display, This->wnd, sizehints);
1692  XFree(sizehints);
1693  }
1694 
1695  if (!(This->fullscreen || This->embed_wnd))
1696  {
1697  XResizeWindow(This->display, This->wnd, This->width, This->height);
1698  }
1699 
1700  /* create new backstore pixmap */
1701  if (This->xwin.backstore != 0)
1702  {
1703  bs = XCreatePixmap(This->display, This->wnd, This->width, This->height, This->xwin.depth);
1704  XSetForeground(This->display, This->xwin.gc, BlackPixelOfScreen(This->xwin.screen));
1705  XFillRectangle(This->display, bs, This->xwin.gc, 0, 0, This->width, This->height);
1706  XCopyArea(This->display, This->xwin.backstore, bs, This->xwin.gc, 0, 0, This->width, This->height, 0, 0);
1707  XFreePixmap(This->display, This->xwin.backstore);
1708  This->xwin.backstore = bs;
1709  }
1710 }
1711 
1712 void
1714 {
1715  if (This->xwin.IC != NULL)
1716  XDestroyIC(This->xwin.IC);
1717 
1718  XDestroyWindow(This->display, This->wnd);
1719 }
1720 
1721 void
1723 {
1724  Pixmap contents = 0;
1725 
1726  if (This->xwin.seamless_active)
1727  /* Turn off SeamlessRDP mode */
1729 
1730  if (!This->ownbackstore)
1731  {
1732  /* need to save contents of window */
1733  contents = XCreatePixmap(This->display, This->wnd, This->width, This->height, This->xwin.depth);
1734  XCopyArea(This->display, This->wnd, contents, This->xwin.gc, 0, 0, This->width, This->height, 0, 0);
1735  }
1736 
1738  This->fullscreen = !This->fullscreen;
1740 
1741  XDefineCursor(This->display, This->wnd, This->xwin.current_cursor);
1742 
1743  if (!This->ownbackstore)
1744  {
1745  XCopyArea(This->display, contents, This->wnd, This->xwin.gc, 0, 0, This->width, This->height, 0, 0);
1746  XFreePixmap(This->display, contents);
1747  }
1748 }
1749 
1750 static void
1752 {
1753  uint16 button, flags = 0;
1754  This->last_gesturetime = xevent.xbutton.time;
1755  button = xkeymap_translate_button(xevent.xbutton.button);
1756  if (button == 0)
1757  return;
1758 
1759  if (down)
1761 
1762  /* Stop moving window when button is released, regardless of cursor position */
1763  if (This->xwin.moving_wnd && (xevent.type == ButtonRelease))
1764  This->xwin.moving_wnd = False;
1765 
1766  /* If win_button_sizee is nonzero, enable single app mode */
1767  if (xevent.xbutton.y < This->win_button_size)
1768  {
1769  /* Check from right to left: */
1770  if (xevent.xbutton.x >= This->width - This->win_button_size)
1771  {
1772  /* The close button, continue */
1773  ;
1774  }
1775  else if (xevent.xbutton.x >= This->width - This->win_button_size * 2)
1776  {
1777  /* The maximize/restore button. Do not send to
1778  server. It might be a good idea to change the
1779  cursor or give some other visible indication
1780  that rdesktop inhibited this click */
1781  if (xevent.type == ButtonPress)
1782  return;
1783  }
1784  else if (xevent.xbutton.x >= This->width - This->win_button_size * 3)
1785  {
1786  /* The minimize button. Iconify window. */
1787  if (xevent.type == ButtonRelease)
1788  {
1789  /* Release the mouse button outside the minimize button, to prevent the
1790  actual minimazation to happen */
1791  rdp_send_input(This, time(NULL), RDP_INPUT_MOUSE, button, 1, 1);
1792  XIconifyWindow(This->display, This->wnd, DefaultScreen(This->display));
1793  return;
1794  }
1795  }
1796  else if (xevent.xbutton.x <= This->win_button_size)
1797  {
1798  /* The system menu. Ignore. */
1799  if (xevent.type == ButtonPress)
1800  return;
1801  }
1802  else
1803  {
1804  /* The title bar. */
1805  if (xevent.type == ButtonPress)
1806  {
1807  if (!This->fullscreen && This->hide_decorations && !This->xwin.using_full_workarea)
1808  {
1809  This->xwin.moving_wnd = True;
1810  This->xwin.move_x_offset = xevent.xbutton.x;
1811  This->xwin.move_y_offset = xevent.xbutton.y;
1812  }
1813  return;
1814  }
1815  }
1816  }
1817 
1818  if (xevent.xmotion.window == This->wnd)
1819  {
1821  flags | button, xevent.xbutton.x, xevent.xbutton.y);
1822  }
1823  else
1824  {
1825  /* SeamlessRDP */
1827  flags | button, xevent.xbutton.x_root, xevent.xbutton.y_root);
1828  }
1829 }
1830 
1831 
1832 /* Process events in Xlib queue
1833  Returns 0 after user quit, 1 otherwise */
1834 static int
1836 {
1837  XEvent xevent;
1838  KeySym keysym;
1839  uint32 ev_time;
1840  char str[256];
1841  Status status;
1842  int events = 0;
1843  seamless_window *sw;
1844 
1845  while ((XPending(This->display) > 0) && events++ < 20)
1846  {
1847  XNextEvent(This->display, &xevent);
1848 
1849  if ((This->xwin.IC != NULL) && (XFilterEvent(&xevent, None) == True))
1850  {
1851  DEBUG_KBD(("Filtering event\n"));
1852  continue;
1853  }
1854 
1855  switch (xevent.type)
1856  {
1857  case VisibilityNotify:
1858  if (xevent.xvisibility.window == This->wnd)
1859  This->Unobscured =
1860  xevent.xvisibility.state == VisibilityUnobscured;
1861 
1862  break;
1863  case ClientMessage:
1864  /* the window manager told us to quit */
1865  if ((xevent.xclient.message_type == This->xwin.protocol_atom)
1866  && ((Atom) xevent.xclient.data.l[0] == This->xwin.kill_atom))
1867  /* Quit */
1868  return 0;
1869  break;
1870 
1871  case KeyPress:
1872  This->last_gesturetime = xevent.xkey.time;
1873  if (This->xwin.IC != NULL)
1874  /* Multi_key compatible version */
1875  {
1876  XmbLookupString(This->xwin.IC,
1877  &xevent.xkey, str, sizeof(str), &keysym,
1878  &status);
1879  if (!((status == XLookupKeySym) || (status == XLookupBoth)))
1880  {
1881  error("XmbLookupString failed with status 0x%x\n",
1882  status);
1883  break;
1884  }
1885  }
1886  else
1887  {
1888  /* Plain old XLookupString */
1889  DEBUG_KBD(("\nNo input context, using XLookupString\n"));
1890  XLookupString((XKeyEvent *) & xevent,
1891  str, sizeof(str), &keysym, NULL);
1892  }
1893 
1894  DEBUG_KBD(("KeyPress for keysym (0x%lx, %s)\n", keysym,
1895  get_ksname(keysym)));
1896 
1897  ev_time = time(NULL);
1898  if (handle_special_keys(This, keysym, xevent.xkey.state, ev_time, True))
1899  break;
1900 
1901  xkeymap_send_keys(This, keysym, xevent.xkey.keycode, xevent.xkey.state,
1902  ev_time, True, 0);
1903  break;
1904 
1905  case KeyRelease:
1906  This->last_gesturetime = xevent.xkey.time;
1907  XLookupString((XKeyEvent *) & xevent, str,
1908  sizeof(str), &keysym, NULL);
1909 
1910  DEBUG_KBD(("\nKeyRelease for keysym (0x%lx, %s)\n", keysym,
1911  get_ksname(keysym)));
1912 
1913  ev_time = time(NULL);
1914  if (handle_special_keys(This, keysym, xevent.xkey.state, ev_time, False))
1915  break;
1916 
1917  xkeymap_send_keys(This, keysym, xevent.xkey.keycode, xevent.xkey.state,
1918  ev_time, False, 0);
1919  break;
1920 
1921  case ButtonPress:
1922  handle_button_event(This, xevent, True);
1923  break;
1924 
1925  case ButtonRelease:
1926  handle_button_event(This, xevent, False);
1927  break;
1928 
1929  case MotionNotify:
1930  if (This->xwin.moving_wnd)
1931  {
1932  XMoveWindow(This->display, This->wnd,
1933  xevent.xmotion.x_root - This->xwin.move_x_offset,
1934  xevent.xmotion.y_root - This->xwin.move_y_offset);
1935  break;
1936  }
1937 
1938  if (This->fullscreen && !This->xwin.focused)
1939  XSetInputFocus(This->display, This->wnd, RevertToPointerRoot,
1940  CurrentTime);
1941 
1942  if (xevent.xmotion.window == This->wnd)
1943  {
1945  xevent.xmotion.x, xevent.xmotion.y);
1946  }
1947  else
1948  {
1949  /* SeamlessRDP */
1951  xevent.xmotion.x_root,
1952  xevent.xmotion.y_root);
1953  }
1954  break;
1955 
1956  case FocusIn:
1957  if (xevent.xfocus.mode == NotifyGrab)
1958  break;
1959  This->xwin.focused = True;
1961  if (This->grab_keyboard && This->xwin.mouse_in_wnd)
1962  XGrabKeyboard(This->display, This->wnd, True,
1963  GrabModeAsync, GrabModeAsync, CurrentTime);
1964 
1965  sw = sw_get_window_by_wnd(This, xevent.xfocus.window);
1966  if (!sw)
1967  break;
1968 
1969  if (sw->id != This->xwin.seamless_focused)
1970  {
1971  seamless_send_focus(This, sw->id, 0);
1972  This->xwin.seamless_focused = sw->id;
1973  }
1974  break;
1975 
1976  case FocusOut:
1977  if (xevent.xfocus.mode == NotifyUngrab)
1978  break;
1979  This->xwin.focused = False;
1980  if (xevent.xfocus.mode == NotifyWhileGrabbed)
1981  XUngrabKeyboard(This->display, CurrentTime);
1982  break;
1983 
1984  case EnterNotify:
1985  /* we only register for this event when in fullscreen mode */
1986  /* or grab_keyboard */
1987  This->xwin.mouse_in_wnd = True;
1988  if (This->fullscreen)
1989  {
1990  XSetInputFocus(This->display, This->wnd, RevertToPointerRoot,
1991  CurrentTime);
1992  break;
1993  }
1994  if (This->xwin.focused)
1995  XGrabKeyboard(This->display, This->wnd, True,
1996  GrabModeAsync, GrabModeAsync, CurrentTime);
1997  break;
1998 
1999  case LeaveNotify:
2000  /* we only register for this event when grab_keyboard */
2001  This->xwin.mouse_in_wnd = False;
2002  XUngrabKeyboard(This->display, CurrentTime);
2003  break;
2004 
2005  case Expose:
2006  if (xevent.xexpose.window == This->wnd)
2007  {
2008  XCopyArea(This->display, This->xwin.backstore, xevent.xexpose.window,
2009  This->xwin.gc,
2010  xevent.xexpose.x, xevent.xexpose.y,
2011  xevent.xexpose.width, xevent.xexpose.height,
2012  xevent.xexpose.x, xevent.xexpose.y);
2013  }
2014  else
2015  {
2016  sw = sw_get_window_by_wnd(This, xevent.xexpose.window);
2017  if (!sw)
2018  break;
2019  XCopyArea(This->display, This->xwin.backstore,
2020  xevent.xexpose.window, This->xwin.gc,
2021  xevent.xexpose.x + sw->xoffset,
2022  xevent.xexpose.y + sw->yoffset,
2023  xevent.xexpose.width,
2024  xevent.xexpose.height, xevent.xexpose.x,
2025  xevent.xexpose.y);
2026  }
2027 
2028  break;
2029 
2030  case MappingNotify:
2031  /* Refresh keyboard mapping if it has changed. This is important for
2032  Xvnc, since it allocates keycodes dynamically */
2033  if (xevent.xmapping.request == MappingKeyboard
2034  || xevent.xmapping.request == MappingModifier)
2035  XRefreshKeyboardMapping(&xevent.xmapping);
2036 
2037  if (xevent.xmapping.request == MappingModifier)
2038  {
2039  XFreeModifiermap(This->xwin.mod_map);
2040  This->xwin.mod_map = XGetModifierMapping(This->display);
2041  }
2042  break;
2043 
2044  /* clipboard stuff */
2045  case SelectionNotify:
2046  xclip_handle_SelectionNotify(This, &xevent.xselection);
2047  break;
2048  case SelectionRequest:
2049  xclip_handle_SelectionRequest(This, &xevent.xselectionrequest);
2050  break;
2051  case SelectionClear:
2053  break;
2054  case PropertyNotify:
2055  xclip_handle_PropertyNotify(This, &xevent.xproperty);
2056  if (xevent.xproperty.window == This->wnd)
2057  break;
2058  if (xevent.xproperty.window == DefaultRootWindow(This->display))
2059  break;
2060 
2061  /* seamless */
2062  sw = sw_get_window_by_wnd(This, xevent.xproperty.window);
2063  if (!sw)
2064  break;
2065 
2066  if ((xevent.xproperty.atom == This->net_wm_state_atom)
2067  && (xevent.xproperty.state == PropertyNewValue))
2068  {
2069  sw->state = ewmh_get_window_state(This, sw->wnd);
2070  seamless_send_state(This, sw->id, sw->state, 0);
2071  }
2072 
2073  if ((xevent.xproperty.atom == This->net_wm_desktop_atom)
2074  && (xevent.xproperty.state == PropertyNewValue))
2075  {
2076  sw->desktop = ewmh_get_window_desktop(This, sw->wnd);
2077  sw_all_to_desktop(This, sw->wnd, sw->desktop);
2078  }
2079 
2080  break;
2081  case MapNotify:
2082  if (!This->xwin.seamless_active)
2084  break;
2085  case UnmapNotify:
2086  if (!This->xwin.seamless_active)
2088  break;
2089  case ConfigureNotify:
2090  if (!This->xwin.seamless_active)
2091  break;
2092 
2093  sw = sw_get_window_by_wnd(This, xevent.xconfigure.window);
2094  if (!sw)
2095  break;
2096 
2097  gettimeofday(sw->position_timer, NULL);
2098  if (sw->position_timer->tv_usec + SEAMLESSRDP_POSITION_TIMER >=
2099  1000000)
2100  {
2101  sw->position_timer->tv_usec +=
2102  SEAMLESSRDP_POSITION_TIMER - 1000000;
2103  sw->position_timer->tv_sec += 1;
2104  }
2105  else
2106  {
2107  sw->position_timer->tv_usec += SEAMLESSRDP_POSITION_TIMER;
2108  }
2109 
2110  sw_handle_restack(This, sw);
2111  break;
2112  }
2113  }
2114  /* Keep going */
2115  return 1;
2116 }
2117 
2118 /* Returns 0 after user quit, 1 otherwise */
2119 int
2120 ui_select(RDPCLIENT * This, int rdp_socket)
2121 {
2122  int n;
2123  fd_set rfds, wfds;
2124  struct timeval tv;
2125  BOOL s_timeout = False;
2126 
2127  while (True)
2128  {
2129  n = (rdp_socket > This->xwin.x_socket) ? rdp_socket : This->xwin.x_socket;
2130  /* Process any events already waiting */
2132  /* User quit */
2133  return 0;
2134 
2135  if (This->xwin.seamless_active)
2137 
2138  FD_ZERO(&rfds);
2139  FD_ZERO(&wfds);
2140  FD_SET(rdp_socket, &rfds);
2141  FD_SET(This->xwin.x_socket, &rfds);
2142 
2143 #ifdef WITH_RDPSND
2144  /* FIXME: there should be an API for registering fds */
2145  if (This->dsp_busy)
2146  {
2147  FD_SET(This->dsp_fd, &wfds);
2148  n = (This->dsp_fd > n) ? This->dsp_fd : n;
2149  }
2150 #endif
2151  /* default timeout */
2152  tv.tv_sec = 60;
2153  tv.tv_usec = 0;
2154 
2155  /* add redirection handles */
2156  rdpdr_add_fds(This, &n, &rfds, &wfds, &tv, &s_timeout);
2158 
2159  n++;
2160 
2161  switch (select(n, &rfds, &wfds, NULL, &tv))
2162  {
2163  case -1:
2164  error("select: %s\n", strerror(errno));
2165 
2166  case 0:
2167  /* Abort serial read calls */
2168  if (s_timeout)
2169  rdpdr_check_fds(This, &rfds, &wfds, (BOOL) True);
2170  continue;
2171  }
2172 
2173  rdpdr_check_fds(This, &rfds, &wfds, (BOOL) False);
2174 
2175  if (FD_ISSET(rdp_socket, &rfds))
2176  return 1;
2177 
2178 #ifdef WITH_RDPSND
2179  if (This->dsp_busy && FD_ISSET(This->dsp_fd, &wfds))
2180  wave_out_play();
2181 #endif
2182  }
2183 }
2184 
2185 void
2187 {
2188  XWarpPointer(This->display, This->wnd, This->wnd, 0, 0, 0, 0, x, y);
2189 }
2190 
2191 HBITMAP
2193 {
2194  XImage *image;
2195  Pixmap bitmap;
2196  uint8 *tdata;
2197  int bitmap_pad;
2198 
2199  if (This->server_depth == 8)
2200  {
2201  bitmap_pad = 8;
2202  }
2203  else
2204  {
2205  bitmap_pad = This->xwin.bpp;
2206 
2207  if (This->xwin.bpp == 24)
2208  bitmap_pad = 32;
2209  }
2210 
2211  tdata = (This->owncolmap ? data : translate_image(This, width, height, data));
2212  bitmap = XCreatePixmap(This->display, This->wnd, width, height, This->xwin.depth);
2213  image = XCreateImage(This->display, This->xwin.visual, This->xwin.depth, ZPixmap, 0,
2214  (char *) tdata, width, height, bitmap_pad, 0);
2215 
2216  XPutImage(This->display, bitmap, This->xwin.create_bitmap_gc, image, 0, 0, 0, 0, width, height);
2217 
2218  XFree(image);
2219  if (tdata != data)
2220  xfree(tdata);
2221  return (HBITMAP) bitmap;
2222 }
2223 
2224 void
2225 ui_paint_bitmap(RDPCLIENT * This, int x, int y, int cx, int cy, int width, int height, uint8 * data)
2226 {
2227  XImage *image;
2228  uint8 *tdata;
2229  int bitmap_pad;
2230 
2231  if (This->server_depth == 8)
2232  {
2233  bitmap_pad = 8;
2234  }
2235  else
2236  {
2237  bitmap_pad = This->xwin.bpp;
2238 
2239  if (This->xwin.bpp == 24)
2240  bitmap_pad = 32;
2241  }
2242 
2243  tdata = (This->owncolmap ? data : translate_image(This, width, height, data));
2244  image = XCreateImage(This->display, This->xwin.visual, This->xwin.depth, ZPixmap, 0,
2245  (char *) tdata, width, height, bitmap_pad, 0);
2246 
2247  if (This->ownbackstore)
2248  {
2249  XPutImage(This->display, This->xwin.backstore, This->xwin.gc, image, 0, 0, x, y, cx, cy);
2250  XCopyArea(This->display, This->xwin.backstore, This->wnd, This->xwin.gc, x, y, cx, cy, x, y);
2251  ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
2252  (This->display, This->xwin.backstore, sw->wnd, This->xwin.gc, x, y, cx, cy,
2253  x - sw->xoffset, y - sw->yoffset));
2254  }
2255  else
2256  {
2257  XPutImage(This->display, This->wnd, This->xwin.gc, image, 0, 0, x, y, cx, cy);
2258  ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
2259  (This->display, This->wnd, sw->wnd, This->xwin.gc, x, y, cx, cy,
2260  x - sw->xoffset, y - sw->yoffset));
2261  }
2262 
2263  XFree(image);
2264  if (tdata != data)
2265  xfree(tdata);
2266 }
2267 
2268 void
2270 {
2271  XFreePixmap(This->display, (Pixmap) bmp);
2272 }
2273 
2274 HGLYPH
2276 {
2277  XImage *image;
2278  Pixmap bitmap;
2279  int scanline;
2280 
2281  scanline = (width + 7) / 8;
2282 
2283  bitmap = XCreatePixmap(This->display, This->wnd, width, height, 1);
2284  if (This->xwin.create_glyph_gc == 0)
2285  This->xwin.create_glyph_gc = XCreateGC(This->display, bitmap, 0, NULL);
2286 
2287  image = XCreateImage(This->display, This->xwin.visual, 1, ZPixmap, 0, (char *) data,
2288  width, height, 8, scanline);
2289  image->byte_order = MSBFirst;
2290  image->bitmap_bit_order = MSBFirst;
2291  XInitImage(image);
2292 
2293  XPutImage(This->display, bitmap, This->xwin.create_glyph_gc, image, 0, 0, 0, 0, width, height);
2294 
2295  XFree(image);
2296  return (HGLYPH) bitmap;
2297 }
2298 
2299 void
2301 {
2302  XFreePixmap(This->display, (Pixmap) glyph);
2303 }
2304 
2305 HCURSOR
2306 ui_create_cursor(RDPCLIENT * This, unsigned int x, unsigned int y, int width, int height,
2307  uint8 * andmask, uint8 * xormask)
2308 {
2309  HGLYPH maskglyph, cursorglyph;
2310  XColor bg, fg;
2311  Cursor xcursor;
2312  uint8 *cursor, *pcursor;
2313  uint8 *mask, *pmask;
2314  uint8 nextbit;
2315  int scanline, offset;
2316  int i, j;
2317 
2318  scanline = (width + 7) / 8;
2319  offset = scanline * height;
2320 
2321  cursor = (uint8 *) xmalloc(offset);
2322  memset(cursor, 0, offset);
2323 
2324  mask = (uint8 *) xmalloc(offset);
2325  memset(mask, 0, offset);
2326 
2327  /* approximate AND and XOR masks with a monochrome X pointer */
2328  for (i = 0; i < height; i++)
2329  {
2330  offset -= scanline;
2331  pcursor = &cursor[offset];
2332  pmask = &mask[offset];
2333 
2334  for (j = 0; j < scanline; j++)
2335  {
2336  for (nextbit = 0x80; nextbit != 0; nextbit >>= 1)
2337  {
2338  if (xormask[0] || xormask[1] || xormask[2])
2339  {
2340  *pcursor |= (~(*andmask) & nextbit);
2341  *pmask |= nextbit;
2342  }
2343  else
2344  {
2345  *pcursor |= ((*andmask) & nextbit);
2346  *pmask |= (~(*andmask) & nextbit);
2347  }
2348 
2349  xormask += 3;
2350  }
2351 
2352  andmask++;
2353  pcursor++;
2354  pmask++;
2355  }
2356  }
2357 
2358  fg.red = fg.blue = fg.green = 0xffff;
2359  bg.red = bg.blue = bg.green = 0x0000;
2360  fg.flags = bg.flags = DoRed | DoBlue | DoGreen;
2361 
2362  cursorglyph = ui_create_glyph(This, width, height, cursor);
2363  maskglyph = ui_create_glyph(This, width, height, mask);
2364 
2365  xcursor =
2366  XCreatePixmapCursor(This->display, (Pixmap) cursorglyph,
2367  (Pixmap) maskglyph, &fg, &bg, x, y);
2368 
2369  ui_destroy_glyph(This, maskglyph);
2370  ui_destroy_glyph(This, cursorglyph);
2371  xfree(mask);
2372  xfree(cursor);
2373  return (HCURSOR) xcursor;
2374 }
2375 
2376 void
2378 {
2379  This->xwin.current_cursor = (Cursor) cursor;
2380  XDefineCursor(This->display, This->wnd, This->xwin.current_cursor);
2381  ON_ALL_SEAMLESS_WINDOWS(XDefineCursor, (This->display, sw->wnd, This->xwin.current_cursor));
2382 }
2383 
2384 void
2386 {
2387  XFreeCursor(This->display, (Cursor) cursor);
2388 }
2389 
2390 void
2392 {
2393  ui_set_cursor(This, This->xwin.null_cursor);
2394 }
2395 
2396 #define MAKE_XCOLOR(xc,c) \
2397  (xc)->red = ((c)->red << 8) | (c)->red; \
2398  (xc)->green = ((c)->green << 8) | (c)->green; \
2399  (xc)->blue = ((c)->blue << 8) | (c)->blue; \
2400  (xc)->flags = DoRed | DoGreen | DoBlue;
2401 
2402 
2403 HCOLOURMAP
2405 {
2406  COLOURENTRY *entry;
2407  int i, ncolours = colours->ncolours;
2408  if (!This->owncolmap)
2409  {
2410  uint32 *map = (uint32 *) xmalloc(sizeof(*This->xwin.colmap) * ncolours);
2411  XColor xentry;
2412  XColor xc_cache[256];
2413  uint32 colour;
2414  int colLookup = 256;
2415  for (i = 0; i < ncolours; i++)
2416  {
2417  entry = &colours->colours[i];
2418  MAKE_XCOLOR(&xentry, entry);
2419 
2420  if (XAllocColor(This->display, This->xwin.xcolmap, &xentry) == 0)
2421  {
2422  /* Allocation failed, find closest match. */
2423  int j = 256;
2424  int nMinDist = 3 * 256 * 256;
2425  long nDist = nMinDist;
2426 
2427  /* only get the colors once */
2428  while (colLookup--)
2429  {
2430  xc_cache[colLookup].pixel = colLookup;
2431  xc_cache[colLookup].red = xc_cache[colLookup].green =
2432  xc_cache[colLookup].blue = 0;
2433  xc_cache[colLookup].flags = 0;
2434  XQueryColor(This->display,
2435  DefaultColormap(This->display,
2436  DefaultScreen(This->display)),
2437  &xc_cache[colLookup]);
2438  }
2439  colLookup = 0;
2440 
2441  /* approximate the pixel */
2442  while (j--)
2443  {
2444  if (xc_cache[j].flags)
2445  {
2446  nDist = ((long) (xc_cache[j].red >> 8) -
2447  (long) (xentry.red >> 8)) *
2448  ((long) (xc_cache[j].red >> 8) -
2449  (long) (xentry.red >> 8)) +
2450  ((long) (xc_cache[j].green >> 8) -
2451  (long) (xentry.green >> 8)) *
2452  ((long) (xc_cache[j].green >> 8) -
2453  (long) (xentry.green >> 8)) +
2454  ((long) (xc_cache[j].blue >> 8) -
2455  (long) (xentry.blue >> 8)) *
2456  ((long) (xc_cache[j].blue >> 8) -
2457  (long) (xentry.blue >> 8));
2458  }
2459  if (nDist < nMinDist)
2460  {
2461  nMinDist = nDist;
2462  xentry.pixel = j;
2463  }
2464  }
2465  }
2466  colour = xentry.pixel;
2467 
2468  /* update our cache */
2469  if (xentry.pixel < 256)
2470  {
2471  xc_cache[xentry.pixel].red = xentry.red;
2472  xc_cache[xentry.pixel].green = xentry.green;
2473  xc_cache[xentry.pixel].blue = xentry.blue;
2474 
2475  }
2476 
2477  map[i] = colour;
2478  }
2479  return map;
2480  }
2481  else
2482  {
2483  XColor *xcolours, *xentry;
2484  Colormap map;
2485 
2486  xcolours = (XColor *) xmalloc(sizeof(XColor) * ncolours);
2487  for (i = 0; i < ncolours; i++)
2488  {
2489  entry = &colours->colours[i];
2490  xentry = &xcolours[i];
2491  xentry->pixel = i;
2492  MAKE_XCOLOR(xentry, entry);
2493  }
2494 
2495  map = XCreateColormap(This->display, This->wnd, This->xwin.visual, AllocAll);
2496  XStoreColors(This->display, map, xcolours, ncolours);
2497 
2498  xfree(xcolours);
2499  return (HCOLOURMAP) map;
2500  }
2501 }
2502 
2503 void
2505 {
2506  if (!This->owncolmap)
2507  xfree(map);
2508  else
2509  XFreeColormap(This->display, (Colormap) map);
2510 }
2511 
2512 void
2514 {
2515  if (!This->owncolmap)
2516  {
2517  if (This->xwin.colmap)
2518  xfree(This->xwin.colmap);
2519 
2520  This->xwin.colmap = (uint32 *) map;
2521  }
2522  else
2523  {
2524  XSetWindowColormap(This->display, This->wnd, (Colormap) map);
2525  ON_ALL_SEAMLESS_WINDOWS(XSetWindowColormap, (This->display, sw->wnd, (Colormap) map));
2526  }
2527 }
2528 
2529 void
2530 ui_set_clip(RDPCLIENT * This, int x, int y, int cx, int cy)
2531 {
2532  This->xwin.clip_rectangle.x = x;
2533  This->xwin.clip_rectangle.y = y;
2534  This->xwin.clip_rectangle.width = cx;
2535  This->xwin.clip_rectangle.height = cy;
2536  XSetClipRectangles(This->display, This->xwin.gc, 0, 0, &This->xwin.clip_rectangle, 1, YXBanded);
2537 }
2538 
2539 void
2541 {
2542  This->xwin.clip_rectangle.x = 0;
2543  This->xwin.clip_rectangle.y = 0;
2544  This->xwin.clip_rectangle.width = This->width;
2545  This->xwin.clip_rectangle.height = This->height;
2546  XSetClipRectangles(This->display, This->xwin.gc, 0, 0, &This->xwin.clip_rectangle, 1, YXBanded);
2547 }
2548 
2549 void
2551 {
2552  XBell(This->display, 0);
2553 }
2554 
2555 void
2557  /* dest */ int x, int y, int cx, int cy)
2558 {
2559  SET_FUNCTION(opcode);
2560  FILL_RECTANGLE(x, y, cx, cy);
2561  RESET_FUNCTION(opcode);
2562 }
2563 
2564 static const uint8 hatch_patterns[] = {
2565  0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0 - bsHorizontal */
2566  0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 1 - bsVertical */
2567  0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, /* 2 - bsFDiagonal */
2568  0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* 3 - bsBDiagonal */
2569  0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, /* 4 - bsCross */
2570  0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 /* 5 - bsDiagCross */
2571 };
2572 
2573 void
2575  /* dest */ int x, int y, int cx, int cy,
2576  /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2577 {
2578  Pixmap fill;
2579  uint8 i, ipattern[8];
2580 
2581  SET_FUNCTION(opcode);
2582 
2583  switch (brush->style)
2584  {
2585  case 0: /* Solid */
2586  SET_FOREGROUND(fgcolour);
2588  break;
2589 
2590  case 2: /* Hatch */
2591  fill = (Pixmap) ui_create_glyph(This, 8, 8,
2592  hatch_patterns + brush->pattern[0] * 8);
2593  SET_FOREGROUND(fgcolour);
2594  SET_BACKGROUND(bgcolour);
2595  XSetFillStyle(This->display, This->xwin.gc, FillOpaqueStippled);
2596  XSetStipple(This->display, This->xwin.gc, fill);
2597  XSetTSOrigin(This->display, This->xwin.gc, brush->xorigin, brush->yorigin);
2599  XSetFillStyle(This->display, This->xwin.gc, FillSolid);
2600  XSetTSOrigin(This->display, This->xwin.gc, 0, 0);
2602  break;
2603 
2604  case 3: /* Pattern */
2605  for (i = 0; i != 8; i++)
2606  ipattern[7 - i] = brush->pattern[i];
2607  fill = (Pixmap) ui_create_glyph(This, 8, 8, ipattern);
2608  SET_FOREGROUND(bgcolour);
2609  SET_BACKGROUND(fgcolour);
2610  XSetFillStyle(This->display, This->xwin.gc, FillOpaqueStippled);
2611  XSetStipple(This->display, This->xwin.gc, fill);
2612  XSetTSOrigin(This->display, This->xwin.gc, brush->xorigin, brush->yorigin);
2614  XSetFillStyle(This->display, This->xwin.gc, FillSolid);
2615  XSetTSOrigin(This->display, This->xwin.gc, 0, 0);
2617  break;
2618 
2619  default:
2620  unimpl("brush %d\n", brush->style);
2621  }
2622 
2623  RESET_FUNCTION(opcode);
2624 
2625  if (This->ownbackstore)
2626  XCopyArea(This->display, This->xwin.backstore, This->wnd, This->xwin.gc, x, y, cx, cy, x, y);
2627  ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
2628  (This->display, This->ownbackstore ? This->xwin.backstore : This->wnd, sw->wnd, This->xwin.gc,
2629  x, y, cx, cy, x - sw->xoffset, y - sw->yoffset));
2630 }
2631 
2632 void
2634  /* dest */ int x, int y, int cx, int cy,
2635  /* src */ int srcx, int srcy)
2636 {
2637  SET_FUNCTION(opcode);
2638  if (This->ownbackstore)
2639  {
2640  XCopyArea(This->display, This->Unobscured ? This->wnd : This->xwin.backstore,
2641  This->wnd, This->xwin.gc, srcx, srcy, cx, cy, x, y);
2642  XCopyArea(This->display, This->xwin.backstore, This->xwin.backstore, This->xwin.gc, srcx, srcy, cx, cy, x, y);
2643  }
2644  else
2645  {
2646  XCopyArea(This->display, This->wnd, This->wnd, This->xwin.gc, srcx, srcy, cx, cy, x, y);
2647  }
2648 
2649  ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
2650  (This->display, This->ownbackstore ? This->xwin.backstore : This->wnd,
2651  sw->wnd, This->xwin.gc, x, y, cx, cy, x - sw->xoffset, y - sw->yoffset));
2652 
2653  RESET_FUNCTION(opcode);
2654 }
2655 
2656 void
2658  /* dest */ int x, int y, int cx, int cy,
2659  /* src */ HBITMAP src, int srcx, int srcy)
2660 {
2661  SET_FUNCTION(opcode);
2662  XCopyArea(This->display, (Pixmap) src, This->wnd, This->xwin.gc, srcx, srcy, cx, cy, x, y);
2663  ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
2664  (This->display, (Pixmap) src, sw->wnd, This->xwin.gc,
2665  srcx, srcy, cx, cy, x - sw->xoffset, y - sw->yoffset));
2666  if (This->ownbackstore)
2667  XCopyArea(This->display, (Pixmap) src, This->xwin.backstore, This->xwin.gc, srcx, srcy, cx, cy, x, y);
2668  RESET_FUNCTION(opcode);
2669 }
2670 
2671 void
2673  /* dest */ int x, int y, int cx, int cy,
2674  /* src */ HBITMAP src, int srcx, int srcy,
2675  /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2676 {
2677  /* This is potentially difficult to do in general. Until someone
2678  comes up with a more efficient way of doing it I am using cases. */
2679 
2680  switch (opcode)
2681  {
2682  case 0x69: /* PDSxxn */
2683  ui_memblt(This, ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
2684  ui_patblt(This, ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
2685  break;
2686 
2687  case 0xb8: /* PSDPxax */
2688  ui_patblt(This, ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
2689  ui_memblt(This, ROP2_AND, x, y, cx, cy, src, srcx, srcy);
2690  ui_patblt(This, ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
2691  break;
2692 
2693  case 0xc0: /* PSa */
2694  ui_memblt(This, ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
2695  ui_patblt(This, ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
2696  break;
2697 
2698  default:
2699  unimpl("triblt 0x%x\n", opcode);
2700  ui_memblt(This, ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
2701  }
2702 }
2703 
2704 void
2706  /* dest */ int startx, int starty, int endx, int endy,
2707  /* pen */ PEN * pen)
2708 {
2709  SET_FUNCTION(opcode);
2710  SET_FOREGROUND(pen->colour);
2711  XDrawLine(This->display, This->wnd, This->xwin.gc, startx, starty, endx, endy);
2712  ON_ALL_SEAMLESS_WINDOWS(XDrawLine, (This->display, sw->wnd, This->xwin.gc,
2713  startx - sw->xoffset, starty - sw->yoffset,
2714  endx - sw->xoffset, endy - sw->yoffset));
2715  if (This->ownbackstore)
2716  XDrawLine(This->display, This->xwin.backstore, This->xwin.gc, startx, starty, endx, endy);
2717  RESET_FUNCTION(opcode);
2718 }
2719 
2720 void
2722  /* dest */ int x, int y, int cx, int cy,
2723  /* brush */ int colour)
2724 {
2725  SET_FOREGROUND(colour);
2726  FILL_RECTANGLE(x, y, cx, cy);
2727 }
2728 
2729 void
2731  /* mode */ uint8 fillmode,
2732  /* dest */ POINT * point, int npoints,
2733  /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2734 {
2735  uint8 style, i, ipattern[8];
2736  Pixmap fill;
2737 
2738  SET_FUNCTION(opcode);
2739 
2740  switch (fillmode)
2741  {
2742  case ALTERNATE:
2743  XSetFillRule(This->display, This->xwin.gc, EvenOddRule);
2744  break;
2745  case WINDING:
2746  XSetFillRule(This->display, This->xwin.gc, WindingRule);
2747  break;
2748  default:
2749  unimpl("fill mode %d\n", fillmode);
2750  }
2751 
2752  if (brush)
2753  style = brush->style;
2754  else
2755  style = 0;
2756 
2757  switch (style)
2758  {
2759  case 0: /* Solid */
2760  SET_FOREGROUND(fgcolour);
2761  FILL_POLYGON((XPoint *) point, npoints);
2762  break;
2763 
2764  case 2: /* Hatch */
2765  fill = (Pixmap) ui_create_glyph(This, 8, 8,
2766  hatch_patterns + brush->pattern[0] * 8);
2767  SET_FOREGROUND(fgcolour);
2768  SET_BACKGROUND(bgcolour);
2769  XSetFillStyle(This->display, This->xwin.gc, FillOpaqueStippled);
2770  XSetStipple(This->display, This->xwin.gc, fill);
2771  XSetTSOrigin(This->display, This->xwin.gc, brush->xorigin, brush->yorigin);
2772  FILL_POLYGON((XPoint *) point, npoints);
2773  XSetFillStyle(This->display, This->xwin.gc, FillSolid);
2774  XSetTSOrigin(This->display, This->xwin.gc, 0, 0);
2776  break;
2777 
2778  case 3: /* Pattern */
2779  for (i = 0; i != 8; i++)
2780  ipattern[7 - i] = brush->pattern[i];
2781  fill = (Pixmap) ui_create_glyph(This, 8, 8, ipattern);
2782  SET_FOREGROUND(bgcolour);
2783  SET_BACKGROUND(fgcolour);
2784  XSetFillStyle(This->display, This->xwin.gc, FillOpaqueStippled);
2785  XSetStipple(This->display, This->xwin.gc, fill);
2786  XSetTSOrigin(This->display, This->xwin.gc, brush->xorigin, brush->yorigin);
2787  FILL_POLYGON((XPoint *) point, npoints);
2788  XSetFillStyle(This->display, This->xwin.gc, FillSolid);
2789  XSetTSOrigin(This->display, This->xwin.gc, 0, 0);
2791  break;
2792 
2793  default:
2794  unimpl("brush %d\n", brush->style);
2795  }
2796 
2797  RESET_FUNCTION(opcode);
2798 }
2799 
2800 void
2802  /* dest */ POINT * points, int npoints,
2803  /* pen */ PEN * pen)
2804 {
2805  /* TODO: set join style */
2806  SET_FUNCTION(opcode);
2807  SET_FOREGROUND(pen->colour);
2808  XDrawLines(This->display, This->wnd, This->xwin.gc, (XPoint *) points, npoints, CoordModePrevious);
2809  if (This->ownbackstore)
2810  XDrawLines(This->display, This->xwin.backstore, This->xwin.gc, (XPoint *) points, npoints,
2811  CoordModePrevious);
2812 
2814  (This, sw->wnd, (XPoint *) points, npoints, sw->xoffset, sw->yoffset));
2815 
2816  RESET_FUNCTION(opcode);
2817 }
2818 
2819 void
2821  /* mode */ uint8 fillmode,
2822  /* dest */ int x, int y, int cx, int cy,
2823  /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2824 {
2825  uint8 style, i, ipattern[8];
2826  Pixmap fill;
2827 
2828  SET_FUNCTION(opcode);
2829 
2830  if (brush)
2831  style = brush->style;
2832  else
2833  style = 0;
2834 
2835  switch (style)
2836  {
2837  case 0: /* Solid */
2838  SET_FOREGROUND(fgcolour);
2839  DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2840  break;
2841 
2842  case 2: /* Hatch */
2843  fill = (Pixmap) ui_create_glyph(This, 8, 8,
2844  hatch_patterns + brush->pattern[0] * 8);
2845  SET_FOREGROUND(fgcolour);
2846  SET_BACKGROUND(bgcolour);
2847  XSetFillStyle(This->display, This->xwin.gc, FillOpaqueStippled);
2848  XSetStipple(This->display, This->xwin.gc, fill);
2849  XSetTSOrigin(This->display, This->xwin.gc, brush->xorigin, brush->yorigin);
2850  DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2851  XSetFillStyle(This->display, This->xwin.gc, FillSolid);
2852  XSetTSOrigin(This->display, This->xwin.gc, 0, 0);
2854  break;
2855 
2856  case 3: /* Pattern */
2857  for (i = 0; i != 8; i++)
2858  ipattern[7 - i] = brush->pattern[i];
2859  fill = (Pixmap) ui_create_glyph(This, 8, 8, ipattern);
2860  SET_FOREGROUND(bgcolour);
2861  SET_BACKGROUND(fgcolour);
2862  XSetFillStyle(This->display, This->xwin.gc, FillOpaqueStippled);
2863  XSetStipple(This->display, This->xwin.gc, fill);
2864  XSetTSOrigin(This->display, This->xwin.gc, brush->xorigin, brush->yorigin);
2865  DRAW_ELLIPSE(x, y, cx, cy, fillmode);
2866  XSetFillStyle(This->display, This->xwin.gc, FillSolid);
2867  XSetTSOrigin(This->display, This->xwin.gc, 0, 0);
2869  break;
2870 
2871  default:
2872  unimpl("brush %d\n", brush->style);
2873  }
2874 
2875  RESET_FUNCTION(opcode);
2876 }
2877 
2878 /* warning, this function only draws on wnd or backstore, not both */
2879 void
2881  /* dest */ int x, int y, int cx, int cy,
2882  /* src */ HGLYPH glyph, int srcx, int srcy,
2883  int bgcolour, int fgcolour)
2884 {
2885  SET_FOREGROUND(fgcolour);
2886  SET_BACKGROUND(bgcolour);
2887 
2888  XSetFillStyle(This->display, This->xwin.gc,
2889  (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
2890  XSetStipple(This->display, This->xwin.gc, (Pixmap) glyph);
2891  XSetTSOrigin(This->display, This->xwin.gc, x, y);
2892 
2894 
2895  XSetFillStyle(This->display, This->xwin.gc, FillSolid);
2896 }
2897 
2898 #define DO_GLYPH(ttext,idx) \
2899 {\
2900  glyph = cache_get_font (This, font, ttext[idx]);\
2901  if (!(flags & TEXT2_IMPLICIT_X))\
2902  {\
2903  xyoffset = ttext[++idx];\
2904  if ((xyoffset & 0x80))\
2905  {\
2906  if (flags & TEXT2_VERTICAL)\
2907  y += ttext[idx+1] | (ttext[idx+2] << 8);\
2908  else\
2909  x += ttext[idx+1] | (ttext[idx+2] << 8);\
2910  idx += 2;\
2911  }\
2912  else\
2913  {\
2914  if (flags & TEXT2_VERTICAL)\
2915  y += xyoffset;\
2916  else\
2917  x += xyoffset;\
2918  }\
2919  }\
2920  if (glyph != NULL)\
2921  {\
2922  x1 = x + glyph->offset;\
2923  y1 = y + glyph->baseline;\
2924  XSetStipple(This->display, This->xwin.gc, (Pixmap) glyph->pixmap);\
2925  XSetTSOrigin(This->display, This->xwin.gc, x1, y1);\
2926  FILL_RECTANGLE_BACKSTORE(x1, y1, glyph->width, glyph->height);\
2927  if (flags & TEXT2_IMPLICIT_X)\
2928  x += glyph->width;\
2929  }\
2930 }
2931 
2932 void
2933 ui_draw_text(RDPCLIENT * This, uint8 font, uint8 flags, uint8 opcode, int mixmode, int x, int y,
2934  int clipx, int clipy, int clipcx, int clipcy,
2935  int boxx, int boxy, int boxcx, int boxcy, BRUSH * brush,
2936  int bgcolour, int fgcolour, uint8 * text, uint8 length)
2937 {
2938  /* TODO: use brush appropriately */
2939 
2940  FONTGLYPH *glyph;
2941  int i, j, xyoffset, x1, y1;
2942  DATABLOB *entry;
2943 
2944  SET_FOREGROUND(bgcolour);
2945 
2946  /* Sometimes, the boxcx value is something really large, like
2947  32691. This makes XCopyArea fail with Xvnc. The code below
2948  is a quick fix. */
2949  if (boxx + boxcx > This->width)
2950  boxcx = This->width - boxx;
2951 
2952  if (boxcx > 1)
2953  {
2954  FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy);
2955  }
2956  else if (mixmode == MIX_OPAQUE)
2957  {
2958  FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy);
2959  }
2960 
2961  SET_FOREGROUND(fgcolour);
2962  SET_BACKGROUND(bgcolour);
2963  XSetFillStyle(This->display, This->xwin.gc, FillStippled);
2964 
2965  /* Paint text, character by character */
2966  for (i = 0; i < length;)
2967  {
2968  switch (text[i])
2969  {
2970  case 0xff:
2971  /* At least two bytes needs to follow */
2972  if (i + 3 > length)
2973  {
2974  warning("Skipping short 0xff command:");
2975  for (j = 0; j < length; j++)
2976  fprintf(stderr, "%02x ", text[j]);
2977  fprintf(stderr, "\n");
2978  i = length = 0;
2979  break;
2980  }
2981  cache_put_text(This, text[i + 1], text, text[i + 2]);
2982  i += 3;
2983  length -= i;
2984  /* this will move pointer from start to first character after FF command */
2985  text = &(text[i]);
2986  i = 0;
2987  break;
2988 
2989  case 0xfe:
2990  /* At least one byte needs to follow */
2991  if (i + 2 > length)
2992  {
2993  warning("Skipping short 0xfe command:");
2994  for (j = 0; j < length; j++)
2995  fprintf(stderr, "%02x ", text[j]);
2996  fprintf(stderr, "\n");
2997  i = length = 0;
2998  break;
2999  }
3000  entry = cache_get_text(This, text[i + 1]);
3001  if (entry->data != NULL)
3002  {
3003  if ((((uint8 *) (entry->data))[1] == 0)
3004  && (!(flags & TEXT2_IMPLICIT_X)) && (i + 2 < length))
3005  {
3006  if (flags & TEXT2_VERTICAL)
3007  y += text[i + 2];
3008  else
3009  x += text[i + 2];
3010  }
3011  for (j = 0; j < entry->size; j++)
3012  DO_GLYPH(((uint8 *) (entry->data)), j);
3013  }
3014  if (i + 2 < length)
3015  i += 3;
3016  else
3017  i += 2;
3018  length -= i;
3019  /* this will move pointer from start to first character after FE command */
3020  text = &(text[i]);
3021  i = 0;
3022  break;
3023 
3024  default:
3025  DO_GLYPH(text, i);
3026  i++;
3027  break;
3028  }
3029  }
3030 
3031  XSetFillStyle(This->display, This->xwin.gc, FillSolid);
3032 
3033  if (This->ownbackstore)
3034  {
3035  if (boxcx > 1)
3036  {
3037  XCopyArea(This->display, This->xwin.backstore, This->wnd, This->xwin.gc, boxx,
3038  boxy, boxcx, boxcy, boxx, boxy);
3039  ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
3040  (This->display, This->xwin.backstore, sw->wnd, This->xwin.gc,
3041  boxx, boxy,
3042  boxcx, boxcy,
3043  boxx - sw->xoffset, boxy - sw->yoffset));
3044  }
3045  else
3046  {
3047  XCopyArea(This->display, This->xwin.backstore, This->wnd, This->xwin.gc, clipx,
3048  clipy, clipcx, clipcy, clipx, clipy);
3049  ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
3050  (This->display, This->xwin.backstore, sw->wnd, This->xwin.gc,
3051  clipx, clipy,
3052  clipcx, clipcy, clipx - sw->xoffset,
3053  clipy - sw->yoffset));
3054  }
3055  }
3056 }
3057 
3058 void
3059 ui_desktop_save(RDPCLIENT * This, uint32 offset, int x, int y, int cx, int cy)
3060 {
3061  Pixmap pix;
3062  XImage *image;
3063 
3064  if (This->ownbackstore)
3065  {
3066  image = XGetImage(This->display, This->xwin.backstore, x, y, cx, cy, AllPlanes, ZPixmap);
3067  }
3068  else
3069  {
3070  pix = XCreatePixmap(This->display, This->wnd, cx, cy, This->xwin.depth);
3071  XCopyArea(This->display, This->wnd, pix, This->xwin.gc, x, y, cx, cy, 0, 0);
3072  image = XGetImage(This->display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
3073  XFreePixmap(This->display, pix);
3074  }
3075 
3076  offset *= This->xwin.bpp / 8;
3077  cache_put_desktop(This, offset, cx, cy, image->bytes_per_line, This->xwin.bpp / 8, (uint8 *) image->data);
3078 
3079  XDestroyImage(image);
3080 }
3081 
3082 void
3084 {
3085  XImage *image;
3086  uint8 *data;
3087 
3088  offset *= This->xwin.bpp / 8;
3089  data = cache_get_desktop(This, offset, cx, cy, This->xwin.bpp / 8);
3090  if (data == NULL)
3091  return;
3092 
3093  image = XCreateImage(This->display, This->xwin.visual, This->xwin.depth, ZPixmap, 0,
3094  (char *) data, cx, cy, BitmapPad(This->display), cx * This->xwin.bpp / 8);
3095 
3096  if (This->ownbackstore)
3097  {
3098  XPutImage(This->display, This->xwin.backstore, This->xwin.gc, image, 0, 0, x, y, cx, cy);
3099  XCopyArea(This->display, This->xwin.backstore, This->wnd, This->xwin.gc, x, y, cx, cy, x, y);
3100  ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
3101  (This->display, This->xwin.backstore, sw->wnd, This->xwin.gc,
3102  x, y, cx, cy, x - sw->xoffset, y - sw->yoffset));
3103  }
3104  else
3105  {
3106  XPutImage(This->display, This->wnd, This->xwin.gc, image, 0, 0, x, y, cx, cy);
3107  ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
3108  (This->display, This->wnd, sw->wnd, This->xwin.gc, x, y, cx, cy,
3109  x - sw->xoffset, y - sw->yoffset));
3110  }
3111 
3112  XFree(image);
3113 }
3114 
3115 /* these do nothing here but are used in uiports */
3116 void
3118 {
3119 }
3120 
3121 void
3123 {
3124 }
3125 
3126 
3127 void
3129 {
3130  if (!This->seamless_rdp)
3131  return;
3132 
3133  if (This->xwin.seamless_started)
3134  return;
3135 
3136  This->xwin.seamless_started = True;
3137  This->xwin.seamless_hidden = hidden;
3138 
3139  if (!hidden)
3141 }
3142 
3143 
3144 void
3146 {
3147  if (!This->seamless_rdp)
3148  return;
3149 
3150  if (!This->xwin.seamless_started)
3151  return;
3152 
3153  if (This->xwin.seamless_active)
3155 
3156  This->xwin.seamless_hidden = True;
3157 }
3158 
3159 
3160 void
3162 {
3163  if (!This->seamless_rdp)
3164  return;
3165 
3166  if (!This->xwin.seamless_started)
3167  return;
3168 
3169  This->xwin.seamless_hidden = False;
3170 
3172 }
3173 
3174 
3175 void
3177 {
3178  if (!This->seamless_rdp)
3179  return;
3180 
3181  if (!This->xwin.seamless_started)
3182  return;
3183 
3184  if (This->xwin.seamless_hidden)
3185  return;
3186 
3187  if (This->xwin.seamless_active)
3188  {
3189  /* Deactivate */
3190  while (This->xwin.seamless_windows)
3191  {
3192  XDestroyWindow(This->display, This->xwin.seamless_windows->wnd);
3193  sw_remove_window(This, This->xwin.seamless_windows);
3194  }
3195  XMapWindow(This->display, This->wnd);
3196  }
3197  else
3198  {
3199  /* Activate */
3200  XUnmapWindow(This->display, This->wnd);
3202  }
3203 
3204  This->xwin.seamless_active = !This->xwin.seamless_active;
3205 }
3206 
3207 
3208 void
3209 ui_seamless_create_window(RDPCLIENT * This, unsigned long id, unsigned long group, unsigned long parent,
3210  unsigned long flags)
3211 {
3212  Window wnd;
3213  XSetWindowAttributes attribs;
3214  XClassHint *classhints;
3215  XSizeHints *sizehints;
3216  XWMHints *wmhints;
3217  long input_mask;
3218  seamless_window *sw, *sw_parent;
3219 
3220  if (!This->xwin.seamless_active)
3221  return;
3222 
3223  /* Ignore CREATEs for existing windows */
3224  sw = sw_get_window_by_id(This, id);
3225  if (sw)
3226  return;
3227 
3229  wnd = XCreateWindow(This->display, RootWindowOfScreen(This->xwin.screen), -1, -1, 1, 1, 0, This->xwin.depth,
3230  InputOutput, This->xwin.visual,
3231  CWBackPixel | CWBackingStore | CWColormap | CWBorderPixel, &attribs);
3232 
3233  XStoreName(This->display, wnd, "SeamlessRDP");
3234  ewmh_set_wm_name(This, wnd, "SeamlessRDP");
3235 
3236  mwm_hide_decorations(This, wnd);
3237 
3238  classhints = XAllocClassHint();
3239  if (classhints != NULL)
3240  {
3241  classhints->res_name = "rdesktop";
3242  classhints->res_class = "SeamlessRDP";
3243  XSetClassHint(This->display, wnd, classhints);
3244  XFree(classhints);
3245  }
3246 
3247  /* WM_NORMAL_HINTS */
3248  sizehints = XAllocSizeHints();
3249  if (sizehints != NULL)
3250  {
3251  sizehints->flags = USPosition;
3252  XSetWMNormalHints(This->display, wnd, sizehints);
3253  XFree(sizehints);
3254  }
3255 
3256  /* Parent-less transient windows */
3257  if (parent == 0xFFFFFFFF)
3258  {
3259  XSetTransientForHint(This->display, wnd, RootWindowOfScreen(This->xwin.screen));
3260  /* Some buggy wm:s (kwin) do not handle the above, so fake it
3261  using some other hints. */
3263  }
3264  /* Normal transient windows */
3265  else if (parent != 0x00000000)
3266  {
3267  sw_parent = sw_get_window_by_id(This, parent);
3268  if (sw_parent)
3269  XSetTransientForHint(This->display, wnd, sw_parent->wnd);
3270  else
3271  warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);
3272  }
3273 
3275  {
3276  /* We do this to support buggy wm:s (*cough* metacity *cough*)
3277  somewhat at least */
3278  if (parent == 0x00000000)
3279  XSetTransientForHint(This->display, wnd, RootWindowOfScreen(This->xwin.screen));
3281  }
3282 
3283  /* FIXME: Support for Input Context:s */
3284 
3285  get_input_mask(This, &input_mask);
3286  input_mask |= PropertyChangeMask;
3287 
3288  XSelectInput(This->display, wnd, input_mask);
3289 
3290  /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a
3291  seamless window, we could try to close the window on the
3292  serverside, instead of terminating rdesktop */
3293  XSetWMProtocols(This->display, wnd, &This->xwin.kill_atom, 1);
3294 
3295  sw = xmalloc(sizeof(seamless_window));
3296  sw->wnd = wnd;
3297  sw->id = id;
3298  sw->behind = 0;
3299  sw->group = sw_find_group(This, group, False);
3300  sw->group->refcnt++;
3301  sw->xoffset = 0;
3302  sw->yoffset = 0;
3303  sw->width = 0;
3304  sw->height = 0;
3305  sw->state = SEAMLESSRDP_NOTYETMAPPED;
3306  sw->desktop = 0;
3307  sw->position_timer = xmalloc(sizeof(struct timeval));
3308  timerclear(sw->position_timer);
3309 
3310  sw->outstanding_position = False;
3311  sw->outpos_serial = 0;
3312  sw->outpos_xoffset = sw->outpos_yoffset = 0;
3313  sw->outpos_width = sw->outpos_height = 0;
3314 
3315  sw->next = This->xwin.seamless_windows;
3316  This->xwin.seamless_windows = sw;
3317 
3318  /* WM_HINTS */
3319  wmhints = XAllocWMHints();
3320  if (wmhints)
3321  {
3322  wmhints->flags = WindowGroupHint;
3323  wmhints->window_group = sw->group->wnd;
3324  XSetWMHints(This->display, sw->wnd, wmhints);
3325  XFree(wmhints);
3326  }
3327 }
3328 
3329 
3330 void
3331 ui_seamless_destroy_window(RDPCLIENT * This, unsigned long id, unsigned long flags)
3332 {
3333  seamless_window *sw;
3334 
3335  if (!This->xwin.seamless_active)
3336  return;
3337 
3338  sw = sw_get_window_by_id(This, id);
3339  if (!sw)
3340  {
3341  warning("ui_seamless_destroy_window: No information for window 0x%lx\n", id);
3342  return;
3343  }
3344 
3345  XDestroyWindow(This->display, sw->wnd);
3346  sw_remove_window(This, sw);
3347 }
3348 
3349 
3350 void
3351 ui_seamless_destroy_group(RDPCLIENT * This, unsigned long id, unsigned long flags)
3352 {
3353  seamless_window *sw, *sw_next;
3354 
3355  if (!This->xwin.seamless_active)
3356  return;
3357 
3358  for (sw = This->xwin.seamless_windows; sw; sw = sw_next)
3359  {
3360  sw_next = sw->next;
3361 
3362  if (sw->group->id == id)
3363  {
3364  XDestroyWindow(This->display, sw->wnd);
3365  sw_remove_window(This, sw);
3366  }
3367  }
3368 }
3369 
3370 
3371 void
3372 ui_seamless_move_window(RDPCLIENT * This, unsigned long id, int x, int y, int width, int height, unsigned long flags)
3373 {
3374  seamless_window *sw;
3375 
3376  if (!This->xwin.seamless_active)
3377  return;
3378 
3379  sw = sw_get_window_by_id(This, id);
3380  if (!sw)
3381  {
3382  warning("ui_seamless_move_window: No information for window 0x%lx\n", id);
3383  return;
3384  }
3385 
3386  /* We ignore server updates until it has handled our request. */
3387  if (sw->outstanding_position)
3388  return;
3389 
3390  if (!width || !height)
3391  /* X11 windows must be at least 1x1 */
3392  return;
3393 
3394  sw->xoffset = x;
3395  sw->yoffset = y;
3396  sw->width = width;
3397  sw->height = height;
3398 
3399  /* If we move the window in a maximized state, then KDE won't
3400  accept restoration */
3401  switch (sw->state)
3402  {
3403  case SEAMLESSRDP_MINIMIZED:
3404  case SEAMLESSRDP_MAXIMIZED:
3405  return;
3406  }
3407 
3408  /* FIXME: Perhaps use ewmh_net_moveresize_window instead */
3409  XMoveResizeWindow(This->display, sw->wnd, sw->xoffset, sw->yoffset, sw->width, sw->height);
3410 }
3411 
3412 
3413 void
3414 ui_seamless_restack_window(RDPCLIENT * This, unsigned long id, unsigned long behind, unsigned long flags)
3415 {
3416  seamless_window *sw;
3417 
3418  if (!This->xwin.seamless_active)
3419  return;
3420 
3421  sw = sw_get_window_by_id(This, id);
3422  if (!sw)
3423  {
3424  warning("ui_seamless_restack_window: No information for window 0x%lx\n", id);
3425  return;
3426  }
3427 
3428  if (behind)
3429  {
3430  seamless_window *sw_behind;
3431  Window wnds[2];
3432 
3433  sw_behind = sw_get_window_by_id(This, behind);
3434  if (!sw_behind)
3435  {
3436  warning("ui_seamless_restack_window: No information for window 0x%lx\n",
3437  behind);
3438  return;
3439  }
3440 
3441  wnds[1] = sw_behind->wnd;
3442  wnds[0] = sw->wnd;
3443 
3444  XRestackWindows(This->display, wnds, 2);
3445  }
3446  else
3447  {
3448  XRaiseWindow(This->display, sw->wnd);
3449  }
3450 
3451  sw_restack_window(This, sw, behind);
3452 }
3453 
3454 
3455 void
3456 ui_seamless_settitle(RDPCLIENT * This, unsigned long id, const char *title, unsigned long flags)
3457 {
3458  seamless_window *sw;
3459 
3460  if (!This->xwin.seamless_active)
3461  return;
3462 
3463  sw = sw_get_window_by_id(This, id);
3464  if (!sw)
3465  {
3466  warning("ui_seamless_settitle: No information for window 0x%lx\n", id);
3467  return;
3468  }
3469 
3470  /* FIXME: Might want to convert the name for non-EWMH WMs */
3471  XStoreName(This->display, sw->wnd, title);
3472  ewmh_set_wm_name(This, sw->wnd, title);
3473 }
3474 
3475 
3476 void
3477 ui_seamless_setstate(RDPCLIENT * This, unsigned long id, unsigned int state, unsigned long flags)
3478 {
3479  seamless_window *sw;
3480 
3481  if (!This->xwin.seamless_active)
3482  return;
3483 
3484  sw = sw_get_window_by_id(This, id);
3485  if (!sw)
3486  {
3487  warning("ui_seamless_setstate: No information for window 0x%lx\n", id);
3488  return;
3489  }
3490 
3491  switch (state)
3492  {
3493  case SEAMLESSRDP_NORMAL:
3494  case SEAMLESSRDP_MAXIMIZED:
3495  ewmh_change_state(This, sw->wnd, state);
3496  XMapWindow(This->display, sw->wnd);
3497  break;
3498  case SEAMLESSRDP_MINIMIZED:
3499  /* EWMH says: "if an Application asks to toggle _NET_WM_STATE_HIDDEN
3500  the Window Manager should probably just ignore the request, since
3501  _NET_WM_STATE_HIDDEN is a function of some other aspect of the window
3502  such as minimization, rather than an independent state." Besides,
3503  XIconifyWindow is easier. */
3504  if (sw->state == SEAMLESSRDP_NOTYETMAPPED)
3505  {
3506  XWMHints *hints;
3507  hints = XGetWMHints(This->display, sw->wnd);
3508  if (hints)
3509  {
3510  hints->flags |= StateHint;
3511  hints->initial_state = IconicState;
3512  XSetWMHints(This->display, sw->wnd, hints);
3513  XFree(hints);
3514  }
3515  XMapWindow(This->display, sw->wnd);
3516  }
3517  else
3518  XIconifyWindow(This->display, sw->wnd, DefaultScreen(This->display));
3519  break;
3520  default:
3521  warning("SeamlessRDP: Invalid state %d\n", state);
3522  break;
3523  }
3524 
3525  sw->state = state;
3526 }
3527 
3528 
3529 void
3531 {
3532  if (!This->xwin.seamless_active)
3533  return;
3534 
3535  /* Destroy all seamless windows */
3536  while (This->xwin.seamless_windows)
3537  {
3538  XDestroyWindow(This->display, This->xwin.seamless_windows->wnd);
3539  sw_remove_window(This, This->xwin.seamless_windows);
3540  }
3541 }
3542 
3543 
3544 void
3546 {
3547  seamless_window *sw;
3548  for (sw = This->xwin.seamless_windows; sw; sw = sw->next)
3549  {
3550  if (sw->outstanding_position && (sw->outpos_serial == serial))
3551  {
3552  sw->xoffset = sw->outpos_xoffset;
3553  sw->yoffset = sw->outpos_yoffset;
3554  sw->width = sw->outpos_width;
3555  sw->height = sw->outpos_height;
3556  sw->outstanding_position = False;
3557 
3558  /* Do a complete redraw of the window as part of the
3559  completion of the move. This is to remove any
3560  artifacts caused by our lack of synchronization. */
3561  XCopyArea(This->display, This->xwin.backstore,
3562  sw->wnd, This->xwin.gc,
3563  sw->xoffset, sw->yoffset, sw->width, sw->height, 0, 0);
3564 
3565  break;
3566  }
3567  }
3568 }
Definition: winsock.h:66
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG y1
Definition: winddi.h:3706
int ewmh_set_window_popup(RDPCLIENT *This, Window wnd)
Definition: ewmhints.c:402
static void sw_restack_window(RDPCLIENT *This, seamless_window *sw, unsigned long behind)
Definition: xwin.c:272
namespace GUID const ADDRINFOEXW * hints
Definition: sock.c:80
GLeglImageOES image
Definition: gl.h:2204
HCURSOR ui_create_cursor(RDPCLIENT *This, unsigned int x, unsigned int y, int width, int height, uint8 *andmask, uint8 *xormask)
Definition: xwin.c:2306
int ewmh_change_state(RDPCLIENT *This, Window wnd, int state)
Definition: ewmhints.c:321
GLint GLint GLsizei width
Definition: gl.h:1546
#define NoSymbol
Definition: x11stubs.h:10
#define DEBUG_KBD(args)
Definition: rdesktop.h:135
void ui_begin_update(RDPCLIENT *This)
Definition: xwin.c:3117
#define WINDING
Definition: constants.h:279
static void translate8to16(RDPCLIENT *This, const uint8 *data, uint8 *out, uint8 *end)
Definition: xwin.c:512
uint16 ncolours
Definition: types.h:66
unsigned int seamless_send_focus(unsigned long id, unsigned long flags)
RD_BOOL seamless_init(void)
static void sw_handle_restack(RDPCLIENT *This, seamless_window *sw)
Definition: xwin.c:301
#define FILL_RECTANGLE(x, y, cx, cy)
Definition: xwin.c:91
void ui_seamless_begin(RDPCLIENT *This, BOOL hidden)
Definition: xwin.c:3128
void ui_destroy_colourmap(RDPCLIENT *This, HCOLOURMAP map)
Definition: xwin.c:2504
#define error(str)
Definition: mkdosfs.c:1605
#define REPEAT4(stm)
Definition: xwin.c:495
#define TEXT2_IMPLICIT_X
Definition: constants.h:276
void xclip_deinit(void)
Definition: mk_font.cpp:20
void ui_rect(RDPCLIENT *This, int x, int y, int cx, int cy, int colour)
Definition: xwin.c:2721
static void translate8to24(RDPCLIENT *This, const uint8 *data, uint8 *out, uint8 *end)
Definition: xwin.c:546
uint16 xkeymap_translate_button(unsigned int button)
Definition: xkeymap.c:714
static void seamless_XFillPolygon(RDPCLIENT *This, Drawable d, XPoint *points, int npoints, int xoffset, int yoffset)
Definition: xwin.c:72
void ui_destblt(RDPCLIENT *This, uint8 opcode, int x, int y, int cx, int cy)
Definition: xwin.c:2556
const WCHAR * text
Definition: package.c:1827
int ffs(int x)
BOOL get_key_state(RDPCLIENT *This, unsigned int state, uint32 keysym)
Definition: xwin.c:1143
const GLint * attribs
Definition: glext.h:10538
BOOL ui_create_window(RDPCLIENT *This)
Definition: xwin.c:1565
unsigned int uint32
Definition: types.h:32
#define SPLITCOLOUR24(colour, rv)
Definition: xwin.c:417
static void translate16to24(RDPCLIENT *This, const uint16 *data, uint8 *out, uint8 *end)
Definition: xwin.c:797
void ui_bell(RDPCLIENT *This)
Definition: xwin.c:2550
struct _root root
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
Definition: types.h:82
void ui_deinit(RDPCLIENT *This)
Definition: xwin.c:1510
unsigned long tv_sec
Definition: linux.h:1738
unsigned int seamless_send_position(unsigned long id, int x, int y, int width, int height, unsigned long flags)
static int xwin_process_events(RDPCLIENT *This)
Definition: xwin.c:1835
GLintptr offset
Definition: glext.h:5920
GLdouble n
Definition: glext.h:7729
unsigned long flags
Definition: xwin.c:39
#define MSBFirst
Definition: pcf.h:178
#define LOUT16(o, x)
Definition: xwin.c:440
#define MIX_OPAQUE
Definition: constants.h:273
BOOL APIENTRY FillSolid(SURFOBJ *pso, PRECTL pRect, ULONG iColor)
Definition: paint.c:35
void seamless_select_timeout(struct timeval *tv)
void xwin_toggle_fullscreen(RDPCLIENT *This)
Definition: xwin.c:1722
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
void xclip_handle_SelectionRequest(RDPCLIENT *This, XSelectionRequestEvent *event)
Definition: xclip.c:673
#define SEAMLESSRDP_MAXIMIZED
Definition: constants.h:569
static void sw_update_position(RDPCLIENT *This, seamless_window *sw)
Definition: xwin.c:229
void xkeymap_send_keys(uint32 keysym, unsigned int keycode, unsigned int state, uint32 ev_time, RD_BOOL pressed, uint8 nesting)
GLuint GLuint end
Definition: gl.h:1545
int errno
static void translate16to16(RDPCLIENT *This, const uint16 *data, uint8 *out, uint8 *end)
Definition: xwin.c:740
__u16 time
Definition: mkdosfs.c:366
HICON HCURSOR
Definition: windef.h:284
#define FD_ZERO(set)
Definition: winsock.h:96
_Out_ RTL_ATOM * Atom
Definition: class.h:54
void ui_patblt(RDPCLIENT *This, uint8 opcode, int x, int y, int cx, int cy, BRUSH *brush, int bgcolour, int fgcolour)
Definition: xwin.c:2574
#define FD_SET(fd, set)
Definition: winsock.h:89
#define BOOL
Definition: nt_native.h:43
char * get_ksname(uint32 keysym)
Definition: xkeymap.c:734
#define FILL_RECTANGLE_BACKSTORE(x, y, cx, cy)
Definition: xwin.c:99
void ui_paint_bitmap(RDPCLIENT *This, int x, int y, int cx, int cy, int width, int height, uint8 *data)
Definition: xwin.c:2225
const char * strerror(int err)
Definition: compat_str.c:23
void ui_line(RDPCLIENT *This, uint8 opcode, int startx, int starty, int endx, int endy, PEN *pen)
Definition: xwin.c:2705
GLint GLint GLint yoffset
Definition: gl.h:1547
POINTL point
Definition: edittest.c:50
void ui_destroy_glyph(RDPCLIENT *This, HGLYPH glyph)
Definition: xwin.c:2300
void rdpdr_check_fds(fd_set *rfds, fd_set *wfds, RD_BOOL timed_out)
GLuint GLuint GLfloat weight
Definition: glext.h:11719
#define DO_GLYPH(ttext, idx)
Definition: xwin.c:2898
HGLYPH ui_create_glyph(RDPCLIENT *This, int width, int height, const uint8 *data)
Definition: xwin.c:2275
__u32 hidden
Definition: mkdosfs.c:371
#define down(mutex)
Definition: glue.h:29
static void seamless_XDrawLines(RDPCLIENT *This, Drawable d, XPoint *points, int npoints, int xoffset, int yoffset)
Definition: xwin.c:82
uint32 red
Definition: xwin.c:49
void ui_set_null_cursor(RDPCLIENT *This)
Definition: xwin.c:2391
RD_BOOL handle_special_keys(uint32 keysym, unsigned int state, uint32 ev_time, RD_BOOL pressed)
#define gettimeofday(tv, tz)
Definition: adns_win32.h:159
Definition: window.c:29
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
void ui_destroy_window(RDPCLIENT *This)
Definition: xwin.c:1713
#define SET_FUNCTION(rop2)
Definition: xwin.c:155
#define MOUSE_FLAG_DOWN
Definition: constants.h:260
#define ALTERNATE
Definition: constants.h:278
GLenum GLint GLuint mask
Definition: glext.h:6028
unsigned int seamless_send_zchange(unsigned long id, unsigned long below, unsigned long flags)
static void sw_all_to_desktop(RDPCLIENT *This, Window wnd, unsigned int desktop)
Definition: xwin.c:211
void ui_triblt(RDPCLIENT *This, uint8 opcode, int x, int y, int cx, int cy, HBITMAP src, int srcx, int srcy, BRUSH *brush, int bgcolour, int fgcolour)
Definition: xwin.c:2672
void ui_set_clip(RDPCLIENT *This, int x, int y, int cx, int cy)
Definition: xwin.c:2530
static seamless_group * sw_find_group(RDPCLIENT *This, unsigned long id, BOOL dont_create)
Definition: xwin.c:352
static const uint8 hatch_patterns[]
Definition: xwin.c:2564
#define None
Definition: i386-dis.c:444
void * xmalloc(int size)
Definition: uimain.c:747
unsigned int seamless_send_sync(void)
unsigned int BOOL
Definition: ntddk_ex.h:94
#define FD_ISSET(fd, set)
Definition: winsock.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
GLint GLint xoffset
Definition: gl.h:1547
#define REPEAT2(stm)
Definition: xwin.c:479
time_t now
Definition: finger.c:65
void ui_polyline(RDPCLIENT *This, uint8 opcode, POINT *points, int npoints, PEN *pen)
Definition: xwin.c:2801
#define LOUT24(o, x)
Definition: xwin.c:441
#define SET_FOREGROUND(col)
Definition: xwin.c:133
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:570
#define SEAMLESSRDP_NORMAL
Definition: constants.h:567
uint8 * cache_get_desktop(uint32 offset, int cx, int cy, int bytes_per_pixel)
Definition: cache.c:353
int ui_select(RDPCLIENT *This, int rdp_socket)
Definition: xwin.c:2120
const WCHAR * str
void cache_put_text(uint8 cache_id, void *data, int length)
Definition: cache.c:335
#define RESET_FUNCTION(rop2)
Definition: xwin.c:156
void rdpdr_add_fds(int *n, fd_set *rfds, fd_set *wfds, struct timeval *tv, RD_BOOL *timeout)
void cache_put_desktop(uint32 offset, int cx, int cy, int scanline, int bytes_per_pixel, uint8 *data)
Definition: cache.c:371
smooth NULL
Definition: ftsmooth.c:416
void ui_desktop_save(RDPCLIENT *This, uint32 offset, int x, int y, int cx, int cy)
Definition: xwin.c:3059
unsigned long tv_usec
Definition: linux.h:1739
#define MIX_TRANSPARENT
Definition: constants.h:272
void reset_modifier_keys(void)
static THRDCREATEWIN wnds[3]
Definition: multithrdwin.c:20
unsigned long functions
Definition: xwin.c:40
long inputMode
Definition: xwin.c:42
GLclampf GLclampf blue
Definition: gl.h:1740
void ui_desktop_restore(RDPCLIENT *This, uint32 offset, int x, int y, int cx, int cy)
Definition: xwin.c:3083
uint32 green
Definition: xwin.c:50
void ui_set_colourmap(RDPCLIENT *This, HCOLOURMAP map)
Definition: xwin.c:2513
static void translate24to32(RDPCLIENT *This, const uint8 *data, uint8 *out, uint8 *end)
Definition: xwin.c:996
COLOURENTRY * colours
Definition: types.h:67
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
int ewmh_get_window_state(RDPCLIENT *This, Window w)
Definition: ewmhints.c:191
static seamless_window * sw_get_window_by_id(RDPCLIENT *This, unsigned long id)
Definition: xwin.c:159
static void translate8to32(RDPCLIENT *This, const uint8 *data, uint8 *out, uint8 *end)
Definition: xwin.c:569
GLboolean GLuint group
Definition: glext.h:11120
Definition: uimain.c:88
#define True
Definition: types.h:24
void rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
Definition: rdp.c:551
#define False
Definition: types.h:25
GLsizeiptr size
Definition: glext.h:5919
#define MAKECOLOUR(pc)
Definition: xwin.c:424
void xfree(void *mem)
Definition: uimain.c:758
#define d
Definition: ke_i.h:81
static uint32 translate_colour(RDPCLIENT *This, uint32 colour)
Definition: xwin.c:445
int get_current_workarea(uint32 *x, uint32 *y, uint32 *width, uint32 *height)
static void translate24to16(RDPCLIENT *This, const uint8 *data, uint8 *out, uint8 *end)
Definition: xwin.c:938
r parent
Definition: btrfs.c:2897
void ui_screenblt(RDPCLIENT *This, uint8 opcode, int x, int y, int cx, int cy, int srcx, int srcy)
Definition: xwin.c:2633
void wave_out_play(void)
Definition: rdpsnd_libao.c:174
if(!(yy_init))
Definition: macro.lex.yy.c:714
void ui_seamless_hide_desktop(RDPCLIENT *This)
Definition: xwin.c:3145
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define ROP2_AND
Definition: constants.h:268
_STLP_MOVE_TO_STD_NAMESPACE void fill(_ForwardIter __first, _ForwardIter __last, const _Tp &__val)
Definition: _algobase.h:449
#define ROP2_XOR
Definition: constants.h:267
#define MOUSE_FLAG_MOVE
Definition: constants.h:254
void ui_seamless_ack(RDPCLIENT *This, unsigned int serial)
Definition: xwin.c:3545
Definition: brush.hpp:15
#define BSWAP16(x)
Definition: xwin.c:429
static void calculate_shifts(uint32 mask, int *shift_r, int *shift_l)
Definition: xwin.c:1168
void xclip_handle_SelectionNotify(RDPCLIENT *This, XSelectionEvent *event)
Definition: xclip.c:417
static seamless_window * sw_get_window_by_wnd(RDPCLIENT *This, Window wnd)
Definition: xwin.c:172
void ui_reset_clip(RDPCLIENT *This)
Definition: xwin.c:2540
static FILE * out
Definition: regtests2xml.c:44
GLclampf green
Definition: gl.h:1740
#define SET_BACKGROUND(col)
Definition: xwin.c:134
unsigned char uint8
Definition: types.h:28
uint32 blue
Definition: xwin.c:51
#define red
Definition: linetest.c:67
void ui_resize_window(RDPCLIENT *This)
Definition: xwin.c:1680
Definition: _map.h:44
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
BITMAP bmp
Definition: alphablend.c:62
void xkeymap_init(void)
GLbitfield flags
Definition: glext.h:7161
uint32 colour
Definition: types.h:86
GLsizei const GLfloat * points
Definition: glext.h:8112
static void translate15to32(RDPCLIENT *This, const uint16 *data, uint8 *out, uint8 *end)
Definition: xwin.c:689
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
static void translate15to16(RDPCLIENT *This, const uint16 *data, uint8 *out, uint8 *end)
Definition: xwin.c:602
void ui_seamless_destroy_group(RDPCLIENT *This, unsigned long id, unsigned long flags)
Definition: xwin.c:3351
HKEY key
Definition: reg.c:42
static int state
Definition: maze.c:121
void ui_destroy_bitmap(RDPCLIENT *This, HBITMAP bmp)
Definition: xwin.c:2269
uint32_t entry
Definition: isohybrid.c:63
void ui_end_update(RDPCLIENT *This)
Definition: xwin.c:3122
HCOLOURMAP ui_create_colourmap(RDPCLIENT *This, COLOURMAP *colours)
Definition: xwin.c:2404
GLenum src
Definition: glext.h:6340
HBITMAP ui_create_bitmap(RDPCLIENT *This, int width, int height, uint8 *data)
Definition: xwin.c:2192
void ui_memblt(RDPCLIENT *This, uint8 opcode, int x, int y, int cx, int cy, HBITMAP src, int srcx, int srcy)
Definition: xwin.c:2657
GLsizei const GLfloat * value
Definition: glext.h:6069
#define SEAMLESSRDP_POSITION_TIMER
Definition: constants.h:570
static void mwm_hide_decorations(RDPCLIENT *This, Window wnd)
Definition: xwin.c:381
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
static const int rop2_map[]
Definition: xwin.c:136
void xclip_handle_SelectionClear(RDPCLIENT *This)
Definition: xclip.c:770
Status
Definition: gdiplustypes.h:24
void ui_seamless_syncbegin(RDPCLIENT *This, unsigned long flags)
Definition: xwin.c:3530
int ewmh_set_window_modal(RDPCLIENT *This, Window wnd)
Definition: ewmhints.c:411
void ui_polygon(RDPCLIENT *This, uint8 opcode, uint8 fillmode, POINT *point, int npoints, BRUSH *brush, int bgcolour, int fgcolour)
Definition: xwin.c:2730
#define MAKE_XCOLOR(xc, c)
Definition: xwin.c:2396
static unsigned calculate_mask_weight(uint32 mask)
Definition: xwin.c:1179
#define DEBUG_RDP5(args)
Definition: rdesktop.h:141
static void translate24to24(RDPCLIENT *This, const uint8 *data, uint8 *out, uint8 *end)
Definition: xwin.c:963
void ui_set_cursor(RDPCLIENT *This, HCURSOR cursor)
Definition: xwin.c:2377
#define PROP_MOTIF_WM_HINTS_ELEMENTS
Definition: xwin.c:36
uint32_t serial
Definition: fsck.fat.h:64
static real win[4][36]
const char cursor[]
Definition: icontest.c:13
#define SPLITCOLOUR15(colour, rv)
Definition: xwin.c:403
#define ON_ALL_SEAMLESS_WINDOWS(func, args)
Definition: xwin.c:55
unsigned short uint16
Definition: types.h:30
#define ROP2_COPY
Definition: constants.h:266
#define long
Definition: qsort.c:33
void ui_seamless_settitle(RDPCLIENT *This, unsigned long id, const char *title, unsigned long flags)
Definition: xwin.c:3456
rfbKeySym KeySym
Definition: x11stubs.h:27
static void sw_check_timers(RDPCLIENT *This)
Definition: xwin.c:254
static void translate8to8(RDPCLIENT *This, const uint8 *data, uint8 *out, uint8 *end)
Definition: xwin.c:505
#define BOUT24(o, x)
Definition: xwin.c:438
void ui_seamless_toggle(RDPCLIENT *This)
Definition: xwin.c:3176
static void get_window_attribs(RDPCLIENT *This, XSetWindowAttributes *attribs)
Definition: xwin.c:1538
#define SPLITCOLOUR16(colour, rv)
Definition: xwin.c:410
void ui_move_pointer(RDPCLIENT *This, int x, int y)
Definition: xwin.c:2186
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
static void translate16to32(RDPCLIENT *This, const uint16 *data, uint8 *out, uint8 *end)
Definition: xwin.c:867
void ui_seamless_setstate(RDPCLIENT *This, unsigned long id, unsigned int state, unsigned long flags)
Definition: xwin.c:3477
#define BOUT32(o, x)
Definition: xwin.c:439
static void get_input_mask(RDPCLIENT *This, long *input_mask)
Definition: xwin.c:1549
struct define * next
Definition: wpp.c:35
HANDLE events[2]
Definition: event.c:4
static void handle_button_event(RDPCLIENT *This, XEvent xevent, BOOL down)
Definition: xwin.c:1751
static uint8 * translate_image(RDPCLIENT *This, int width, int height, uint8 *data)
Definition: xwin.c:1051
unsigned int seamless_send_state(unsigned long id, unsigned int state, unsigned long flags)
#define timerisset(tvp)
Definition: rdesktop.h:180
BOOL ui_init(RDPCLIENT *This)
Definition: xwin.c:1399
#define SEAMLESSRDP_CREATE_MODAL
Definition: constants.h:572
#define ROP2_NXOR
Definition: constants.h:269
_Out_opt_ int * cx
Definition: commctrl.h:570
#define timercmp(tvp, uvp, cmp)
Definition: rdesktop.h:184
void xclip_init(void)
void ui_draw_glyph(RDPCLIENT *This, int mixmode, int x, int y, int cx, int cy, HGLYPH glyph, int srcx, int srcy, int bgcolour, int fgcolour)
Definition: xwin.c:2880
void ui_seamless_unhide_desktop(RDPCLIENT *This)
Definition: xwin.c:3161
void ewmh_set_wm_name(RDPCLIENT *This, Window wnd, const char *title)
Definition: ewmhints.c:391
GLenum GLuint id
Definition: glext.h:5579
FILE * stderr
void ui_seamless_destroy_window(RDPCLIENT *This, unsigned long id, unsigned long flags)
Definition: xwin.c:3331
#define DRAW_ELLIPSE(x, y, cx, cy, m)
Definition: xwin.c:112
static void sw_remove_window(RDPCLIENT *This, seamless_window *win)
Definition: xwin.c:185
int ewmh_get_window_desktop(RDPCLIENT *This, Window wnd)
Definition: ewmhints.c:346
void unimpl(char *format,...)
Definition: uimain.c:801
int ewmh_move_to_desktop(RDPCLIENT *This, Window wnd, unsigned int desktop)
Definition: ewmhints.c:368
static HBITMAP bitmap
Definition: clipboard.c:1344
#define DEBUG(args)
Definition: rdesktop.h:129
DATABLOB * cache_get_text(uint8 cache_id)
Definition: cache.c:325
void ui_seamless_restack_window(RDPCLIENT *This, unsigned long id, unsigned long behind, unsigned long flags)
Definition: xwin.c:3414
static HBITMAP
Definition: button.c:44
void ui_ellipse(RDPCLIENT *This, uint8 opcode, uint8 fillmode, int x, int y, int cx, int cy, BRUSH *brush, int bgcolour, int fgcolour)
Definition: xwin.c:2820
void ui_seamless_move_window(RDPCLIENT *This, unsigned long id, int x, int y, int width, int height, unsigned long flags)
Definition: xwin.c:3372
#define LOUT32(o, x)
Definition: xwin.c:442
static struct msdos_boot_sector bs
Definition: mkdosfs.c:539
#define BOUT16(o, x)
Definition: xwin.c:437
#define TEXT2_VERTICAL
Definition: constants.h:275
void ewmh_init(void)
#define SEAMLESSRDP_NOTYETMAPPED
Definition: constants.h:566
unsigned long status
Definition: xwin.c:43
Arabic default style
Definition: afstyles.h:93
void xclip_handle_PropertyNotify(RDPCLIENT *This, XPropertyEvent *event)
Definition: xclip.c:779
void ui_destroy_cursor(RDPCLIENT *This, HCURSOR cursor)
Definition: xwin.c:2385
#define memset(x, y, z)
Definition: compat.h:39
static BOOL select_visual(RDPCLIENT *This)
Definition: xwin.c:1191
#define timerclear(tvp)
Definition: rdesktop.h:190
static SERVICE_STATUS status
Definition: service.c:31
static char title[]
Definition: ps.c:92
#define REPEAT3(stm)
Definition: xwin.c:487
unsigned long decorations
Definition: xwin.c:41
void ui_draw_text(RDPCLIENT *This, uint8 font, uint8 flags, uint8 opcode, int mixmode, int x, int y, int clipx, int clipy, int clipcx, int clipcy, int boxx, int boxy, int boxcx, int boxcy, BRUSH *brush, int bgcolour, int fgcolour, uint8 *text, uint8 length)
Definition: xwin.c:2933
void ui_seamless_create_window(RDPCLIENT *This, unsigned long id, unsigned long group, unsigned long parent, unsigned long flags)
Definition: xwin.c:3209
#define warning(s)
Definition: debug.h:71
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint GLenum GLenum GLenum GLint GLuint GLenum GLenum GLfloat GLenum GLfloat GLenum map
Definition: glfuncs.h:262
#define SEAMLESSRDP_MINIMIZED
Definition: constants.h:568
Definition: path.c:42
void rdp_send_client_window_status(int status)
Definition: rdp.c:572
#define MWM_HINTS_DECORATIONS
Definition: xwin.c:35
static void translate15to24(RDPCLIENT *This, const uint16 *data, uint8 *out, uint8 *end)
Definition: xwin.c:639
#define FILL_POLYGON(p, np)
Definition: xwin.c:104
Definition: ps.c:97