1 |
/* -*- c-basic-offset: 8 -*- |
/* -*- c-basic-offset: 8 -*- |
2 |
rdesktop: A Remote Desktop Protocol client. |
rdesktop: A Remote Desktop Protocol client. |
3 |
User interface services - X Window System |
User interface services - X Window System |
4 |
Copyright (C) Matthew Chapman 1999-2005 |
Copyright (C) Matthew Chapman 1999-2007 |
5 |
|
|
6 |
This program is free software; you can redistribute it and/or modify |
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 |
it under the terms of the GNU General Public License as published by |
105 |
static XIC g_IC; |
static XIC g_IC; |
106 |
static XModifierKeymap *g_mod_map; |
static XModifierKeymap *g_mod_map; |
107 |
static Cursor g_current_cursor; |
static Cursor g_current_cursor; |
108 |
static HCURSOR g_null_cursor = NULL; |
static RD_HCURSOR g_null_cursor = NULL; |
109 |
static Atom g_protocol_atom, g_kill_atom; |
static Atom g_protocol_atom, g_kill_atom; |
110 |
extern Atom g_net_wm_state_atom; |
extern Atom g_net_wm_state_atom; |
111 |
extern Atom g_net_wm_desktop_atom; |
extern Atom g_net_wm_desktop_atom; |
147 |
static BOOL g_using_full_workarea = False; |
static BOOL g_using_full_workarea = False; |
148 |
|
|
149 |
#ifdef WITH_RDPSND |
#ifdef WITH_RDPSND |
|
extern int g_dsp_fd; |
|
|
extern BOOL g_dsp_busy; |
|
150 |
extern BOOL g_rdpsnd; |
extern BOOL g_rdpsnd; |
151 |
#endif |
#endif |
152 |
|
|
2266 |
FD_SET(rdp_socket, &rfds); |
FD_SET(rdp_socket, &rfds); |
2267 |
FD_SET(g_x_socket, &rfds); |
FD_SET(g_x_socket, &rfds); |
2268 |
|
|
|
#ifdef WITH_RDPSND |
|
|
/* FIXME: there should be an API for registering fds */ |
|
|
if (g_dsp_busy) |
|
|
{ |
|
|
FD_SET(g_dsp_fd, &wfds); |
|
|
n = (g_dsp_fd > n) ? g_dsp_fd : n; |
|
|
} |
|
|
#endif |
|
2269 |
/* default timeout */ |
/* default timeout */ |
2270 |
tv.tv_sec = 60; |
tv.tv_sec = 60; |
2271 |
tv.tv_usec = 0; |
tv.tv_usec = 0; |
2272 |
|
|
2273 |
|
#ifdef WITH_RDPSND |
2274 |
|
rdpsnd_add_fds(&n, &rfds, &wfds, &tv); |
2275 |
|
#endif |
2276 |
|
|
2277 |
/* add redirection handles */ |
/* add redirection handles */ |
2278 |
rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout); |
rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout); |
2279 |
seamless_select_timeout(&tv); |
seamless_select_timeout(&tv); |
2286 |
error("select: %s\n", strerror(errno)); |
error("select: %s\n", strerror(errno)); |
2287 |
|
|
2288 |
case 0: |
case 0: |
2289 |
|
#ifdef WITH_RDPSND |
2290 |
|
rdpsnd_check_fds(&rfds, &wfds); |
2291 |
|
#endif |
2292 |
|
|
2293 |
/* Abort serial read calls */ |
/* Abort serial read calls */ |
2294 |
if (s_timeout) |
if (s_timeout) |
2295 |
rdpdr_check_fds(&rfds, &wfds, (BOOL) True); |
rdpdr_check_fds(&rfds, &wfds, (BOOL) True); |
2296 |
continue; |
continue; |
2297 |
} |
} |
2298 |
|
|
2299 |
|
#ifdef WITH_RDPSND |
2300 |
|
rdpsnd_check_fds(&rfds, &wfds); |
2301 |
|
#endif |
2302 |
|
|
2303 |
rdpdr_check_fds(&rfds, &wfds, (BOOL) False); |
rdpdr_check_fds(&rfds, &wfds, (BOOL) False); |
2304 |
|
|
2305 |
if (FD_ISSET(rdp_socket, &rfds)) |
if (FD_ISSET(rdp_socket, &rfds)) |
2306 |
return 1; |
return 1; |
2307 |
|
|
|
#ifdef WITH_RDPSND |
|
|
if (g_dsp_busy && FD_ISSET(g_dsp_fd, &wfds)) |
|
|
wave_out_play(); |
|
|
#endif |
|
2308 |
} |
} |
2309 |
} |
} |
2310 |
|
|
2314 |
XWarpPointer(g_display, g_wnd, g_wnd, 0, 0, 0, 0, x, y); |
XWarpPointer(g_display, g_wnd, g_wnd, 0, 0, 0, 0, x, y); |
2315 |
} |
} |
2316 |
|
|
2317 |
HBITMAP |
RD_HBITMAP |
2318 |
ui_create_bitmap(int width, int height, uint8 * data) |
ui_create_bitmap(int width, int height, uint8 * data) |
2319 |
{ |
{ |
2320 |
XImage *image; |
XImage *image; |
2344 |
XFree(image); |
XFree(image); |
2345 |
if (tdata != data) |
if (tdata != data) |
2346 |
xfree(tdata); |
xfree(tdata); |
2347 |
return (HBITMAP) bitmap; |
return (RD_HBITMAP) bitmap; |
2348 |
} |
} |
2349 |
|
|
2350 |
void |
void |
2392 |
} |
} |
2393 |
|
|
2394 |
void |
void |
2395 |
ui_destroy_bitmap(HBITMAP bmp) |
ui_destroy_bitmap(RD_HBITMAP bmp) |
2396 |
{ |
{ |
2397 |
XFreePixmap(g_display, (Pixmap) bmp); |
XFreePixmap(g_display, (Pixmap) bmp); |
2398 |
} |
} |
2399 |
|
|
2400 |
HGLYPH |
RD_HGLYPH |
2401 |
ui_create_glyph(int width, int height, uint8 * data) |
ui_create_glyph(int width, int height, uint8 * data) |
2402 |
{ |
{ |
2403 |
XImage *image; |
XImage *image; |
2419 |
XPutImage(g_display, bitmap, g_create_glyph_gc, image, 0, 0, 0, 0, width, height); |
XPutImage(g_display, bitmap, g_create_glyph_gc, image, 0, 0, 0, 0, width, height); |
2420 |
|
|
2421 |
XFree(image); |
XFree(image); |
2422 |
return (HGLYPH) bitmap; |
return (RD_HGLYPH) bitmap; |
2423 |
} |
} |
2424 |
|
|
2425 |
void |
void |
2426 |
ui_destroy_glyph(HGLYPH glyph) |
ui_destroy_glyph(RD_HGLYPH glyph) |
2427 |
{ |
{ |
2428 |
XFreePixmap(g_display, (Pixmap) glyph); |
XFreePixmap(g_display, (Pixmap) glyph); |
2429 |
} |
} |
2430 |
|
|
2431 |
HCURSOR |
RD_HCURSOR |
2432 |
ui_create_cursor(unsigned int x, unsigned int y, int width, int height, |
ui_create_cursor(unsigned int x, unsigned int y, int width, int height, |
2433 |
uint8 * andmask, uint8 * xormask) |
uint8 * andmask, uint8 * xormask) |
2434 |
{ |
{ |
2435 |
HGLYPH maskglyph, cursorglyph; |
RD_HGLYPH maskglyph, cursorglyph; |
2436 |
XColor bg, fg; |
XColor bg, fg; |
2437 |
Cursor xcursor; |
Cursor xcursor; |
2438 |
uint8 *cursor, *pcursor; |
uint8 *cursor, *pcursor; |
2496 |
ui_destroy_glyph(cursorglyph); |
ui_destroy_glyph(cursorglyph); |
2497 |
xfree(mask); |
xfree(mask); |
2498 |
xfree(cursor); |
xfree(cursor); |
2499 |
return (HCURSOR) xcursor; |
return (RD_HCURSOR) xcursor; |
2500 |
} |
} |
2501 |
|
|
2502 |
void |
void |
2503 |
ui_set_cursor(HCURSOR cursor) |
ui_set_cursor(RD_HCURSOR cursor) |
2504 |
{ |
{ |
2505 |
g_current_cursor = (Cursor) cursor; |
g_current_cursor = (Cursor) cursor; |
2506 |
XDefineCursor(g_display, g_wnd, g_current_cursor); |
XDefineCursor(g_display, g_wnd, g_current_cursor); |
2508 |
} |
} |
2509 |
|
|
2510 |
void |
void |
2511 |
ui_destroy_cursor(HCURSOR cursor) |
ui_destroy_cursor(RD_HCURSOR cursor) |
2512 |
{ |
{ |
2513 |
XFreeCursor(g_display, (Cursor) cursor); |
XFreeCursor(g_display, (Cursor) cursor); |
2514 |
} |
} |
2526 |
(xc)->flags = DoRed | DoGreen | DoBlue; |
(xc)->flags = DoRed | DoGreen | DoBlue; |
2527 |
|
|
2528 |
|
|
2529 |
HCOLOURMAP |
RD_HCOLOURMAP |
2530 |
ui_create_colourmap(COLOURMAP * colours) |
ui_create_colourmap(COLOURMAP * colours) |
2531 |
{ |
{ |
2532 |
COLOURENTRY *entry; |
COLOURENTRY *entry; |
2622 |
XStoreColors(g_display, map, xcolours, ncolours); |
XStoreColors(g_display, map, xcolours, ncolours); |
2623 |
|
|
2624 |
xfree(xcolours); |
xfree(xcolours); |
2625 |
return (HCOLOURMAP) map; |
return (RD_HCOLOURMAP) map; |
2626 |
} |
} |
2627 |
} |
} |
2628 |
|
|
2629 |
void |
void |
2630 |
ui_destroy_colourmap(HCOLOURMAP map) |
ui_destroy_colourmap(RD_HCOLOURMAP map) |
2631 |
{ |
{ |
2632 |
if (!g_owncolmap) |
if (!g_owncolmap) |
2633 |
xfree(map); |
xfree(map); |
2636 |
} |
} |
2637 |
|
|
2638 |
void |
void |
2639 |
ui_set_colourmap(HCOLOURMAP map) |
ui_set_colourmap(RD_HCOLOURMAP map) |
2640 |
{ |
{ |
2641 |
if (!g_owncolmap) |
if (!g_owncolmap) |
2642 |
{ |
{ |
2724 |
FILL_RECTANGLE_BACKSTORE(x, y, cx, cy); |
FILL_RECTANGLE_BACKSTORE(x, y, cx, cy); |
2725 |
XSetFillStyle(g_display, g_gc, FillSolid); |
XSetFillStyle(g_display, g_gc, FillSolid); |
2726 |
XSetTSOrigin(g_display, g_gc, 0, 0); |
XSetTSOrigin(g_display, g_gc, 0, 0); |
2727 |
ui_destroy_glyph((HGLYPH) fill); |
ui_destroy_glyph((RD_HGLYPH) fill); |
2728 |
break; |
break; |
2729 |
|
|
2730 |
case 3: /* Pattern */ |
case 3: /* Pattern */ |
2739 |
FILL_RECTANGLE_BACKSTORE(x, y, cx, cy); |
FILL_RECTANGLE_BACKSTORE(x, y, cx, cy); |
2740 |
XSetFillStyle(g_display, g_gc, FillSolid); |
XSetFillStyle(g_display, g_gc, FillSolid); |
2741 |
XSetTSOrigin(g_display, g_gc, 0, 0); |
XSetTSOrigin(g_display, g_gc, 0, 0); |
2742 |
ui_destroy_glyph((HGLYPH) fill); |
ui_destroy_glyph((RD_HGLYPH) fill); |
2743 |
break; |
break; |
2744 |
|
|
2745 |
default: |
default: |
2782 |
void |
void |
2783 |
ui_memblt(uint8 opcode, |
ui_memblt(uint8 opcode, |
2784 |
/* dest */ int x, int y, int cx, int cy, |
/* dest */ int x, int y, int cx, int cy, |
2785 |
/* src */ HBITMAP src, int srcx, int srcy) |
/* src */ RD_HBITMAP src, int srcx, int srcy) |
2786 |
{ |
{ |
2787 |
SET_FUNCTION(opcode); |
SET_FUNCTION(opcode); |
2788 |
XCopyArea(g_display, (Pixmap) src, g_wnd, g_gc, srcx, srcy, cx, cy, x, y); |
XCopyArea(g_display, (Pixmap) src, g_wnd, g_gc, srcx, srcy, cx, cy, x, y); |
2797 |
void |
void |
2798 |
ui_triblt(uint8 opcode, |
ui_triblt(uint8 opcode, |
2799 |
/* dest */ int x, int y, int cx, int cy, |
/* dest */ int x, int y, int cx, int cy, |
2800 |
/* src */ HBITMAP src, int srcx, int srcy, |
/* src */ RD_HBITMAP src, int srcx, int srcy, |
2801 |
/* brush */ BRUSH * brush, int bgcolour, int fgcolour) |
/* brush */ BRUSH * brush, int bgcolour, int fgcolour) |
2802 |
{ |
{ |
2803 |
/* This is potentially difficult to do in general. Until someone |
/* This is potentially difficult to do in general. Until someone |
2855 |
void |
void |
2856 |
ui_polygon(uint8 opcode, |
ui_polygon(uint8 opcode, |
2857 |
/* mode */ uint8 fillmode, |
/* mode */ uint8 fillmode, |
2858 |
/* dest */ POINT * point, int npoints, |
/* dest */ RD_POINT * point, int npoints, |
2859 |
/* brush */ BRUSH * brush, int bgcolour, int fgcolour) |
/* brush */ BRUSH * brush, int bgcolour, int fgcolour) |
2860 |
{ |
{ |
2861 |
uint8 style, i, ipattern[8]; |
uint8 style, i, ipattern[8]; |
2898 |
FILL_POLYGON((XPoint *) point, npoints); |
FILL_POLYGON((XPoint *) point, npoints); |
2899 |
XSetFillStyle(g_display, g_gc, FillSolid); |
XSetFillStyle(g_display, g_gc, FillSolid); |
2900 |
XSetTSOrigin(g_display, g_gc, 0, 0); |
XSetTSOrigin(g_display, g_gc, 0, 0); |
2901 |
ui_destroy_glyph((HGLYPH) fill); |
ui_destroy_glyph((RD_HGLYPH) fill); |
2902 |
break; |
break; |
2903 |
|
|
2904 |
case 3: /* Pattern */ |
case 3: /* Pattern */ |
2913 |
FILL_POLYGON((XPoint *) point, npoints); |
FILL_POLYGON((XPoint *) point, npoints); |
2914 |
XSetFillStyle(g_display, g_gc, FillSolid); |
XSetFillStyle(g_display, g_gc, FillSolid); |
2915 |
XSetTSOrigin(g_display, g_gc, 0, 0); |
XSetTSOrigin(g_display, g_gc, 0, 0); |
2916 |
ui_destroy_glyph((HGLYPH) fill); |
ui_destroy_glyph((RD_HGLYPH) fill); |
2917 |
break; |
break; |
2918 |
|
|
2919 |
default: |
default: |
2925 |
|
|
2926 |
void |
void |
2927 |
ui_polyline(uint8 opcode, |
ui_polyline(uint8 opcode, |
2928 |
/* dest */ POINT * points, int npoints, |
/* dest */ RD_POINT * points, int npoints, |
2929 |
/* pen */ PEN * pen) |
/* pen */ PEN * pen) |
2930 |
{ |
{ |
2931 |
/* TODO: set join style */ |
/* TODO: set join style */ |
2976 |
DRAW_ELLIPSE(x, y, cx, cy, fillmode); |
DRAW_ELLIPSE(x, y, cx, cy, fillmode); |
2977 |
XSetFillStyle(g_display, g_gc, FillSolid); |
XSetFillStyle(g_display, g_gc, FillSolid); |
2978 |
XSetTSOrigin(g_display, g_gc, 0, 0); |
XSetTSOrigin(g_display, g_gc, 0, 0); |
2979 |
ui_destroy_glyph((HGLYPH) fill); |
ui_destroy_glyph((RD_HGLYPH) fill); |
2980 |
break; |
break; |
2981 |
|
|
2982 |
case 3: /* Pattern */ |
case 3: /* Pattern */ |
2991 |
DRAW_ELLIPSE(x, y, cx, cy, fillmode); |
DRAW_ELLIPSE(x, y, cx, cy, fillmode); |
2992 |
XSetFillStyle(g_display, g_gc, FillSolid); |
XSetFillStyle(g_display, g_gc, FillSolid); |
2993 |
XSetTSOrigin(g_display, g_gc, 0, 0); |
XSetTSOrigin(g_display, g_gc, 0, 0); |
2994 |
ui_destroy_glyph((HGLYPH) fill); |
ui_destroy_glyph((RD_HGLYPH) fill); |
2995 |
break; |
break; |
2996 |
|
|
2997 |
default: |
default: |
3005 |
void |
void |
3006 |
ui_draw_glyph(int mixmode, |
ui_draw_glyph(int mixmode, |
3007 |
/* dest */ int x, int y, int cx, int cy, |
/* dest */ int x, int y, int cx, int cy, |
3008 |
/* src */ HGLYPH glyph, int srcx, int srcy, |
/* src */ RD_HGLYPH glyph, int srcx, int srcy, |
3009 |
int bgcolour, int fgcolour) |
int bgcolour, int fgcolour) |
3010 |
{ |
{ |
3011 |
SET_FOREGROUND(fgcolour); |
SET_FOREGROUND(fgcolour); |
3190 |
if (g_ownbackstore) |
if (g_ownbackstore) |
3191 |
{ |
{ |
3192 |
image = XGetImage(g_display, g_backstore, x, y, cx, cy, AllPlanes, ZPixmap); |
image = XGetImage(g_display, g_backstore, x, y, cx, cy, AllPlanes, ZPixmap); |
3193 |
|
exit_if_null(image); |
3194 |
} |
} |
3195 |
else |
else |
3196 |
{ |
{ |
3197 |
pix = XCreatePixmap(g_display, g_wnd, cx, cy, g_depth); |
pix = XCreatePixmap(g_display, g_wnd, cx, cy, g_depth); |
3198 |
XCopyArea(g_display, g_wnd, pix, g_gc, x, y, cx, cy, 0, 0); |
XCopyArea(g_display, g_wnd, pix, g_gc, x, y, cx, cy, 0, 0); |
3199 |
image = XGetImage(g_display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap); |
image = XGetImage(g_display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap); |
3200 |
|
exit_if_null(image); |
3201 |
XFreePixmap(g_display, pix); |
XFreePixmap(g_display, pix); |
3202 |
} |
} |
3203 |
|
|