From daf1ac67521a082960d5e65d2265c386c2f61a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20=C3=85strand?= Date: Mon, 18 Nov 2002 18:12:49 +0000 Subject: [PATCH] Support for extended WM hint _NET_WORKAREA, via -g workarea git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@262 423420c4-83ab-492f-b58f-81f9feb106b5 --- Makefile | 2 +- ewmhints.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++++ proto.h | 5 +- rdesktop.c | 9 +++- xwin.c | 13 +++++ 5 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 ewmhints.c diff --git a/Makefile b/Makefile index f62374b..4295daa 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ datadir = $(prefix)/share/rdesktop KEYMAP_PATH = $(datadir)/keymaps/ -RDPOBJ = rdesktop.o tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o xwin.o xkeymap.o +RDPOBJ = rdesktop.o tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o xwin.o xkeymap.o ewmhints.c CRYPTOBJ = crypto/rc4_enc.o crypto/rc4_skey.o crypto/md5_dgst.o crypto/sha1dgst.o crypto/bn_exp.o crypto/bn_mul.o crypto/bn_div.o crypto/bn_sqr.o crypto/bn_add.o crypto/bn_shift.o crypto/bn_asm.o crypto/bn_ctx.o crypto/bn_lib.o include Makeconf # configure-generated diff --git a/ewmhints.c b/ewmhints.c new file mode 100644 index 0000000..b8ec82e --- /dev/null +++ b/ewmhints.c @@ -0,0 +1,152 @@ +/* + rdesktop: A Remote Desktop Protocol client. + + Support functions for Extended Window Manager Hints, + http://www.freedesktop.org/standards/wm-spec.html + + Copyright (C) Matthew Chapman 1999-2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "rdesktop.h" +#include + +extern Display *display; + +/* + Get window property value (32 bit format) + Returns zero on success, -1 on error +*/ +static int +get_property_value(char *propname, long max_length, + unsigned long *nitems_return, unsigned char **prop_return) +{ + int result; + Atom property; + Atom actual_type_return; + int actual_format_return; + unsigned long bytes_after_return; + + property = XInternAtom(display, propname, True); + if (property == None) + { + fprintf(stderr, "Atom %s does not exist\n", propname); + return (-1); + } + + result = XGetWindowProperty(display, DefaultRootWindow(display), property, 0, /* long_offset */ + max_length, /* long_length */ + False, /* delete */ + AnyPropertyType, /* req_type */ + &actual_type_return, + &actual_format_return, + nitems_return, &bytes_after_return, prop_return); + + if (result != Success) + { + fprintf(stderr, "XGetWindowProperty failed\n"); + return (-1); + } + + if (actual_type_return == None || actual_format_return == 0) + { + fprintf(stderr, "Root window is missing property %s\n", propname); + return (-1); + } + + if (bytes_after_return) + { + fprintf(stderr, "%s is too big for me\n", propname); + return (-1); + } + + if (actual_format_return != 32) + { + fprintf(stderr, "%s has bad format\n", propname); + return (-1); + } + + return (0); +} + +/* + Get current desktop number + Returns -1 on error +*/ +static int +get_current_desktop() +{ + unsigned long nitems_return; + uint32 *prop_return; + int current_desktop; + + if (get_property_value("_NET_CURRENT_DESKTOP", 1, &nitems_return, + (unsigned char **) &prop_return) < 0) + return (-1); + + if (nitems_return != 1) + { + fprintf(stderr, "_NET_CURRENT_DESKTOP has bad length\n"); + return (-1); + } + + current_desktop = *prop_return; + XFree(prop_return); + return current_desktop; +} + +/* + Get workarea geometry + Returns zero on success, -1 on error + */ + +int +get_current_workarea(uint32 * x, uint32 * y, uint32 * width, uint32 * height) +{ + int current_desktop; + unsigned long nitems_return; + uint32 *prop_return; + const uint32 net_workarea_x_offset = 0; + const uint32 net_workarea_y_offset = 1; + const uint32 net_workarea_width_offset = 2; + const uint32 net_workarea_height_offset = 3; + const uint32 max_prop_length = 32 * 4; /* Max 32 desktops */ + + if (get_property_value("_NET_WORKAREA", max_prop_length, &nitems_return, + (unsigned char **) &prop_return) < 0) + return (-1); + + if (nitems_return % 4) + { + fprintf(stderr, "_NET_WORKAREA has odd length\n"); + return (-1); + } + + current_desktop = get_current_desktop(); + + if (current_desktop < 0) + return -1; + + *x = prop_return[current_desktop * 4 + net_workarea_x_offset]; + *y = prop_return[current_desktop * 4 + net_workarea_y_offset]; + *width = prop_return[current_desktop * 4 + net_workarea_width_offset]; + *height = prop_return[current_desktop * 4 + net_workarea_height_offset]; + + XFree(prop_return); + + return (0); + +} diff --git a/proto.h b/proto.h index c1eb10f..7a32d7f 100644 --- a/proto.h +++ b/proto.h @@ -14,6 +14,8 @@ void cache_put_desktop(uint32 offset, int cx, int cy, int scanline, int bytes_pe uint8 * data); HCURSOR cache_get_cursor(uint16 cache_idx); void cache_put_cursor(uint16 cache_idx, HCURSOR cursor); +/* ewmhints.c */ +int get_current_workarea(uint32 * x, uint32 * y, uint32 * width, uint32 * height); /* iso.c */ STREAM iso_init(int length); void iso_send(STREAM s); @@ -48,8 +50,6 @@ void rdp_main_loop(void); BOOL rdp_connect(char *server, uint32 flags, char *domain, char *password, char *command, char *directory); void rdp_disconnect(void); -/* readpass.c */ -char *askpass(char *askpass, const char *msg); /* secure.c */ void sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt); void sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2); @@ -77,6 +77,7 @@ void ensure_remote_modifiers(uint32 ev_time, key_translation tr); void reset_modifier_keys(unsigned int state); void rdp_send_scancode(uint32 time, uint16 flags, uint8 scancode); /* xwin.c */ +void mwm_hide_decorations(void); BOOL get_key_state(unsigned int state, uint32 keysym); BOOL ui_init(void); void ui_deinit(void); diff --git a/rdesktop.c b/rdesktop.c index 8ef7cd3..cca7376 100644 --- a/rdesktop.c +++ b/rdesktop.c @@ -45,7 +45,8 @@ char username[16]; char hostname[16]; char keymapname[16]; int keylayout = 0x409; /* Defaults to US keyboard layout */ -int width = 800; +int width = 800; /* If width or height are reset to zero, the geometry will + be fetched from _NET_WORKAREA */ int height = 600; int tcp_port_rdp = TCP_PORT_RDP; BOOL bitmap_compression = True; @@ -185,6 +186,12 @@ main(int argc, char *argv[]) break; case 'g': + if (!strcmp(optarg, "workarea")) + { + width = height = 0; + break; + } + width = strtol(optarg, &p, 10); if (*p == 'x') height = strtol(p + 1, NULL, 10); diff --git a/xwin.c b/xwin.c index b64b030..0567fc1 100644 --- a/xwin.c +++ b/xwin.c @@ -298,6 +298,19 @@ ui_init(void) host_be = !(BOOL) (*(uint8 *) (&test)); xserver_be = (ImageByteOrder(display) == MSBFirst); + if ((width == 0) || (height == 0)) + { + /* Fetch geometry from _NET_WORKAREA */ + uint32 xpos, ypos; + + if (get_current_workarea(&xpos, &ypos, &width, &height) < 0) + { + error("Failed to get workarea.\n"); + error("Perhaps your window manager does not support EWMH?\n"); + exit(1); + } + } + if (fullscreen) { width = WidthOfScreen(screen);