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
This commit is contained in:
Peter Åstrand 2002-11-18 18:12:49 +00:00
parent 1ad250fcba
commit daf1ac6752
5 changed files with 177 additions and 4 deletions

View File

@ -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

152
ewmhints.c Normal file
View File

@ -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 <X11/Xlib.h>
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);
}

View File

@ -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);

View File

@ -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);

13
xwin.c
View File

@ -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);