⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xwin.c

📁 rdesktop is a client for Microsoft Windows NT Terminal Server, Windows 2000 Terminal Services, Wind
💻 C
📖 第 1 页 / 共 5 页
字号:
/* -*- c-basic-offset: 8 -*-   rdesktop: A Remote Desktop Protocol client.   User interface services - X Window System   Copyright (C) Matthew Chapman 1999-2005   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 <X11/Xlib.h>#include <X11/Xutil.h>#include <unistd.h>#include <sys/time.h>#include <time.h>#include <errno.h>#include <strings.h>#include "rdesktop.h"#include "xproto.h"/* We can't include Xproto.h because of conflicting defines for BOOL */#define X_ConfigureWindow              12extern int g_width;extern int g_height;extern int g_xpos;extern int g_ypos;extern int g_pos;extern BOOL g_sendmotion;extern BOOL g_fullscreen;extern BOOL g_grab_keyboard;extern BOOL g_hide_decorations;extern char g_title[];/* Color depth of the RDP session.   As of RDP 5.1, it may be 8, 15, 16 or 24. */extern int g_server_depth;extern int g_win_button_size;Display *g_display;Time g_last_gesturetime;static int g_x_socket;static Screen *g_screen;Window g_wnd;/* SeamlessRDP support */typedef struct _seamless_group{	Window wnd;	unsigned long id;	unsigned int refcnt;} seamless_group;typedef struct _seamless_window{	Window wnd;	unsigned long id;	unsigned long behind;	seamless_group *group;	int xoffset, yoffset;	int width, height;	int state;		/* normal/minimized/maximized. */	unsigned int desktop;	struct timeval *position_timer;	BOOL outstanding_position;	unsigned int outpos_serial;	int outpos_xoffset, outpos_yoffset;	int outpos_width, outpos_height;	struct _seamless_window *next;} seamless_window;static seamless_window *g_seamless_windows = NULL;static unsigned long g_seamless_focused = 0;static BOOL g_seamless_started = False;	/* Server end is up and running */static BOOL g_seamless_active = False;	/* We are currently in seamless mode */static BOOL g_seamless_hidden = False;	/* Desktop is hidden on server */extern BOOL g_seamless_rdp;extern uint32 g_embed_wnd;BOOL g_enable_compose = False;BOOL g_Unobscured;		/* used for screenblt */static GC g_gc = NULL;static GC g_create_bitmap_gc = NULL;static GC g_create_glyph_gc = NULL;static XRectangle g_clip_rectangle;static Visual *g_visual;/* Color depth of the X11 visual of our window (e.g. 24 for True Color R8G8B visual).   This may be 32 for R8G8B8 visuals, and then the rest of the bits are undefined   as far as we're concerned. */static int g_depth;/* Bits-per-Pixel of the pixmaps we'll be using to draw on our window.   This may be larger than g_depth, in which case some of the bits would   be kept solely for alignment (e.g. 32bpp pixmaps on a 24bpp visual). */static int g_bpp;static XIM g_IM;static XIC g_IC;static XModifierKeymap *g_mod_map;static Cursor g_current_cursor;static HCURSOR g_null_cursor = NULL;static Atom g_protocol_atom, g_kill_atom;extern Atom g_net_wm_state_atom;extern Atom g_net_wm_desktop_atom;static BOOL g_focused;static BOOL g_mouse_in_wnd;/* Indicates that:   1) visual has 15, 16 or 24 depth and the same color channel masks      as its RDP equivalent (implies X server is LE),   2) host is LE   This will trigger an optimization whose real value is questionable.*/static BOOL g_compatible_arch;/* Indicates whether RDP's bitmaps and our XImages have the same   binary format. If so, we can avoid an expensive translation.   Note that this can be true when g_compatible_arch is false,   e.g.:        RDP(LE) <-> host(BE) <-> X-Server(LE)        ('host' is the machine running rdesktop; the host simply memcpy's    so its endianess doesn't matter) */static BOOL g_no_translate_image = False;/* endianness */static BOOL g_host_be;static BOOL g_xserver_be;static int g_red_shift_r, g_blue_shift_r, g_green_shift_r;static int g_red_shift_l, g_blue_shift_l, g_green_shift_l;/* software backing store */extern BOOL g_ownbackstore;static Pixmap g_backstore = 0;/* Moving in single app mode */static BOOL g_moving_wnd;static int g_move_x_offset = 0;static int g_move_y_offset = 0;static BOOL g_using_full_workarea = False;#ifdef WITH_RDPSNDextern int g_dsp_fd;extern BOOL g_dsp_busy;extern BOOL g_rdpsnd;#endif/* MWM decorations */#define MWM_HINTS_DECORATIONS   (1L << 1)#define PROP_MOTIF_WM_HINTS_ELEMENTS    5typedef struct{	unsigned long flags;	unsigned long functions;	unsigned long decorations;	long inputMode;	unsigned long status;}PropMotifWmHints;typedef struct{	uint32 red;	uint32 green;	uint32 blue;}PixelColour;#define ON_ALL_SEAMLESS_WINDOWS(func, args) \        do { \                seamless_window *sw; \                XRectangle rect; \		if (!g_seamless_windows) break; \                for (sw = g_seamless_windows; sw; sw = sw->next) { \                    rect.x = g_clip_rectangle.x - sw->xoffset; \                    rect.y = g_clip_rectangle.y - sw->yoffset; \                    rect.width = g_clip_rectangle.width; \                    rect.height = g_clip_rectangle.height; \                    XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded); \                    func args; \                } \                XSetClipRectangles(g_display, g_gc, 0, 0, &g_clip_rectangle, 1, YXBanded); \        } while (0)static voidseamless_XFillPolygon(Drawable d, XPoint * points, int npoints, int xoffset, int yoffset){	points[0].x -= xoffset;	points[0].y -= yoffset;	XFillPolygon(g_display, d, g_gc, points, npoints, Complex, CoordModePrevious);	points[0].x += xoffset;	points[0].y += yoffset;}static voidseamless_XDrawLines(Drawable d, XPoint * points, int npoints, int xoffset, int yoffset){	points[0].x -= xoffset;	points[0].y -= yoffset;	XDrawLines(g_display, d, g_gc, points, npoints, CoordModePrevious);	points[0].x += xoffset;	points[0].y += yoffset;}#define FILL_RECTANGLE(x,y,cx,cy)\{ \	XFillRectangle(g_display, g_wnd, g_gc, x, y, cx, cy); \        ON_ALL_SEAMLESS_WINDOWS(XFillRectangle, (g_display, sw->wnd, g_gc, x-sw->xoffset, y-sw->yoffset, cx, cy)); \	if (g_ownbackstore) \		XFillRectangle(g_display, g_backstore, g_gc, x, y, cx, cy); \}#define FILL_RECTANGLE_BACKSTORE(x,y,cx,cy)\{ \	XFillRectangle(g_display, g_ownbackstore ? g_backstore : g_wnd, g_gc, x, y, cx, cy); \}#define FILL_POLYGON(p,np)\{ \	XFillPolygon(g_display, g_wnd, g_gc, p, np, Complex, CoordModePrevious); \	if (g_ownbackstore) \		XFillPolygon(g_display, g_backstore, g_gc, p, np, Complex, CoordModePrevious); \	ON_ALL_SEAMLESS_WINDOWS(seamless_XFillPolygon, (sw->wnd, p, np, sw->xoffset, sw->yoffset)); \}#define DRAW_ELLIPSE(x,y,cx,cy,m)\{ \	switch (m) \	{ \		case 0:	/* Outline */ \			XDrawArc(g_display, g_wnd, g_gc, x, y, cx, cy, 0, 360*64); \                        ON_ALL_SEAMLESS_WINDOWS(XDrawArc, (g_display, sw->wnd, g_gc, x-sw->xoffset, y-sw->yoffset, cx, cy, 0, 360*64)); \			if (g_ownbackstore) \				XDrawArc(g_display, g_backstore, g_gc, x, y, cx, cy, 0, 360*64); \			break; \		case 1: /* Filled */ \			XFillArc(g_display, g_wnd, g_gc, x, y, cx, cy, 0, 360*64); \			ON_ALL_SEAMLESS_WINDOWS(XFillArc, (g_display, sw->wnd, g_gc, x-sw->xoffset, y-sw->yoffset, cx, cy, 0, 360*64)); \			if (g_ownbackstore) \				XFillArc(g_display, g_backstore, g_gc, x, y, cx, cy, 0, 360*64); \			break; \	} \}/* colour maps */extern BOOL g_owncolmap;static Colormap g_xcolmap;static uint32 *g_colmap = NULL;#define TRANSLATE(col)		( g_server_depth != 8 ? translate_colour(col) : g_owncolmap ? col : g_colmap[col] )#define SET_FOREGROUND(col)	XSetForeground(g_display, g_gc, TRANSLATE(col));#define SET_BACKGROUND(col)	XSetBackground(g_display, g_gc, TRANSLATE(col));static int rop2_map[] = {	GXclear,		/* 0 */	GXnor,			/* DPon */	GXandInverted,		/* DPna */	GXcopyInverted,		/* Pn */	GXandReverse,		/* PDna */	GXinvert,		/* Dn */	GXxor,			/* DPx */	GXnand,			/* DPan */	GXand,			/* DPa */	GXequiv,		/* DPxn */	GXnoop,			/* D */	GXorInverted,		/* DPno */	GXcopy,			/* P */	GXorReverse,		/* PDno */	GXor,			/* DPo */	GXset			/* 1 */};#define SET_FUNCTION(rop2)	{ if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, rop2_map[rop2]); }#define RESET_FUNCTION(rop2)	{ if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, GXcopy); }static seamless_window *sw_get_window_by_id(unsigned long id){	seamless_window *sw;	for (sw = g_seamless_windows; sw; sw = sw->next)	{		if (sw->id == id)			return sw;	}	return NULL;}static seamless_window *sw_get_window_by_wnd(Window wnd){	seamless_window *sw;	for (sw = g_seamless_windows; sw; sw = sw->next)	{		if (sw->wnd == wnd)			return sw;	}	return NULL;}static voidsw_remove_window(seamless_window * win){	seamless_window *sw, **prevnext = &g_seamless_windows;	for (sw = g_seamless_windows; sw; sw = sw->next)	{		if (sw == win)		{			*prevnext = sw->next;			sw->group->refcnt--;			if (sw->group->refcnt == 0)			{				XDestroyWindow(g_display, sw->group->wnd);				xfree(sw->group);			}			xfree(sw->position_timer);			xfree(sw);			return;		}		prevnext = &sw->next;	}	return;}/* Move all windows except wnd to new desktop */static voidsw_all_to_desktop(Window wnd, unsigned int desktop){	seamless_window *sw;	for (sw = g_seamless_windows; sw; sw = sw->next)	{		if (sw->wnd == wnd)			continue;		if (sw->desktop != desktop)		{			ewmh_move_to_desktop(sw->wnd, desktop);			sw->desktop = desktop;		}	}}/* Send our position */static voidsw_update_position(seamless_window * sw){	XWindowAttributes wa;	int x, y;	Window child_return;	unsigned int serial;	XGetWindowAttributes(g_display, sw->wnd, &wa);	XTranslateCoordinates(g_display, sw->wnd, wa.root,			      -wa.border_width, -wa.border_width, &x, &y, &child_return);	serial = seamless_send_position(sw->id, x, y, wa.width, wa.height, 0);	sw->outstanding_position = True;	sw->outpos_serial = serial;	sw->outpos_xoffset = x;	sw->outpos_yoffset = y;	sw->outpos_width = wa.width;	sw->outpos_height = wa.height;}/* Check if it's time to send our position */static voidsw_check_timers(){	seamless_window *sw;	struct timeval now;	gettimeofday(&now, NULL);	for (sw = g_seamless_windows; sw; sw = sw->next)	{		if (timerisset(sw->position_timer) && timercmp(sw->position_timer, &now, <))		{			timerclear(sw->position_timer);			sw_update_position(sw);		}	}}static voidsw_restack_window(seamless_window * sw, unsigned long behind){	seamless_window *sw_above;	/* Remove window from stack */	for (sw_above = g_seamless_windows; sw_above; sw_above = sw_above->next)	{		if (sw_above->behind == sw->id)			break;	}	if (sw_above)		sw_above->behind = sw->behind;	/* And then add it at the new position */	for (sw_above = g_seamless_windows; sw_above; sw_above = sw_above->next)	{		if (sw_above->behind == behind)			break;	}	if (sw_above)		sw_above->behind = sw->id;	sw->behind = behind;}static voidsw_handle_restack(seamless_window * sw){	Status status;	Window root, parent, *children;	unsigned int nchildren, i;	seamless_window *sw_below;	status = XQueryTree(g_display, RootWindowOfScreen(g_screen),			    &root, &parent, &children, &nchildren);	if (!status || !nchildren)		return;	sw_below = NULL;	i = 0;	while (children[i] != sw->wnd)	{		i++;		if (i >= nchildren)			goto end;	}	for (i++; i < nchildren; i++)	{		sw_below = sw_get_window_by_wnd(children[i]);		if (sw_below)			break;	}	if (!sw_below && !sw->behind)		goto end;	if (sw_below && (sw_below->id == sw->behind))		goto end;	if (sw_below)	{		seamless_send_zchange(sw->id, sw_below->id, 0);		sw_restack_window(sw, sw_below->id);	}	else	{		seamless_send_zchange(sw->id, 0, 0);		sw_restack_window(sw, 0);	}      end:	XFree(children);}static seamless_group *sw_find_group(unsigned long id, BOOL dont_create){	seamless_window *sw;	seamless_group *sg;	XSetWindowAttributes attribs;	for (sw = g_seamless_windows; sw; sw = sw->next)	{		if (sw->group->id == id)			return sw->group;	}	if (dont_create)		return NULL;	sg = xmalloc(sizeof(seamless_group));	sg->wnd =		XCreateWindow(g_display, RootWindowOfScreen(g_screen), -1, -1, 1, 1, 0,			      CopyFromParent, CopyFromParent, CopyFromParent, 0, &attribs);	sg->id = id;	sg->refcnt = 0;	return sg;}static voidmwm_hide_decorations(Window wnd){	PropMotifWmHints motif_hints;	Atom hintsatom;	/* setup the property */	motif_hints.flags = MWM_HINTS_DECORATIONS;	motif_hints.decorations = 0;	/* get the atom for the property */	hintsatom = XInternAtom(g_display, "_MOTIF_WM_HINTS", False);	if (!hintsatom)	{		warning("Failed to get atom _MOTIF_WM_HINTS: probably your window manager does not support MWM hints\n");		return;	}	XChangeProperty(g_display, wnd, hintsatom, hintsatom, 32, PropModeReplace,			(unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);}#define SPLITCOLOUR15(colour, rv) \{ \	rv.red = ((colour >> 7) & 0xf8) | ((colour >> 12) & 0x7); \	rv.green = ((colour >> 2) & 0xf8) | ((colour >> 8) & 0x7); \	rv.blue = ((colour << 3) & 0xf8) | ((colour >> 2) & 0x7); \}#define SPLITCOLOUR16(colour, rv) \{ \	rv.red = ((colour >> 8) & 0xf8) | ((colour >> 13) & 0x7); \	rv.green = ((colour >> 3) & 0xfc) | ((colour >> 9) & 0x3); \	rv.blue = ((colour << 3) & 0xf8) | ((colour >> 2) & 0x7); \} \#define SPLITCOLOUR24(colour, rv) \{ \	rv.blue = (colour & 0xff0000) >> 16; \	rv.green = (colour & 0x00ff00) >> 8; \	rv.red = (colour & 0x0000ff); \}#define MAKECOLOUR(pc) \	((pc.red >> g_red_shift_r) << g_red_shift_l) \		| ((pc.green >> g_green_shift_r) << g_green_shift_l) \		| ((pc.blue >> g_blue_shift_r) << g_blue_shift_l) \#define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }#define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | (x & 0xff00)); }#define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \			x = (x << 16) | (x >> 16); }/* The following macros output the same octet sequences   on both BE and LE hosts: */#define BOUT16(o, x) { *(o++) = x >> 8; *(o++) = x; }#define BOUT24(o, x) { *(o++) = x >> 16; *(o++) = x >> 8; *(o++) = x; }#define BOUT32(o, x) { *(o++) = x >> 24; *(o++) = x >> 16; *(o++) = x >> 8; *(o++) = x; }#define LOUT16(o, x) { *(o++) = x; *(o++) = x >> 8; }#define LOUT24(o, x) { *(o++) = x; *(o++) = x >> 8; *(o++) = x >> 16; }#define LOUT32(o, x) { *(o++) = x; *(o++) = x >> 8; *(o++) = x >> 16; *(o++) = x >> 24; }static uint32translate_colour(uint32 colour){	PixelColour pc;	switch (g_server_depth)	{		case 15:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -