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

📄 xwin.c

📁 运行在sdl上的rdesktop(远程桌面)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   rdesktop: A Remote Desktop Protocol client.   User interface services - X-Windows   Copyright (C) Matthew Chapman 1999-2001      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 <time.h>#include <errno.h>#include "rdesktop.h"extern int width;extern int height;extern BOOL sendmotion;extern BOOL fullscreen;static Display *display;static int x_socket;static Window wnd;static GC gc;static Visual *visual;static int depth;static int bpp;/* endianness */static BOOL host_be;static BOOL xserver_be;/* software backing store */static BOOL ownbackstore;static Pixmap backstore;#define FILL_RECTANGLE(x,y,cx,cy)\{ \	XFillRectangle(display, wnd, gc, x, y, cx, cy); \	if (ownbackstore) \		XFillRectangle(display, backstore, gc, x, y, cx, cy); \}/* colour maps */static BOOL owncolmap;static Colormap xcolmap;static uint32 white;static uint32 *colmap;#define TRANSLATE(col)		( owncolmap ? col : translate_colour(colmap[col]) )#define SET_FOREGROUND(col)	XSetForeground(display, gc, TRANSLATE(col));#define SET_BACKGROUND(col)	XSetBackground(display, 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(display, gc, rop2_map[rop2]); }#define RESET_FUNCTION(rop2)	{ if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }static voidtranslate8(uint8 *data, uint8 *out, uint8 *end){	while (out < end)		*(out++) = (uint8)colmap[*(data++)];}static voidtranslate16(uint8 *data, uint16 *out, uint16 *end){	while (out < end)		*(out++) = (uint16)colmap[*(data++)];}/* little endian - conversion happens when colourmap is built */static voidtranslate24(uint8 *data, uint8 *out, uint8 *end){	uint32 value;	while (out < end)	{		value = colmap[*(data++)];		*(out++) = value;		*(out++) = value >> 8;		*(out++) = value >> 16;	}}static voidtranslate32(uint8 *data, uint32 *out, uint32 *end){	while (out < end)		*(out++) = colmap[*(data++)];}static uint8 *translate_image(int width, int height, uint8 *data){	int size = width * height * bpp/8;	uint8 *out = xmalloc(size);	uint8 *end = out + size;	switch (bpp)	{		case 8:			translate8(data, out, end);			break;		case 16:			translate16(data, (uint16 *)out, (uint16 *)end);			break;		case 24:			translate24(data, out, end);			break;		case 32:			translate32(data, (uint32 *)out, (uint32 *)end);			break;	}	return out;}#define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }#define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }#define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \			x = (x << 16) | (x >> 16); }static uint32translate_colour(uint32 colour){	switch (bpp)	{		case 16:			if (host_be != xserver_be)				BSWAP16(colour);			break;		case 24:			if (xserver_be)				BSWAP24(colour);			break;		case 32:			if (host_be != xserver_be)				BSWAP32(colour);			break;	}	return colour;}BOOLui_create_window(char *title){	XSetWindowAttributes attribs;	XClassHint *classhints;	XSizeHints *sizehints;	unsigned long input_mask;	XPixmapFormatValues *pfm;	Screen *screen;	uint16 test;	int i;	display = XOpenDisplay(NULL);	if (display == NULL)	{		error("Failed to open display\n");		return False;	}	x_socket = ConnectionNumber(display);	screen = DefaultScreenOfDisplay(display);	visual = DefaultVisualOfScreen(screen);	depth = DefaultDepthOfScreen(screen);	pfm = XListPixmapFormats(display, &i);	if (pfm != NULL)	{		/* Use maximum bpp for this depth - this is generally		   desirable, e.g. 24 bits->32 bits. */		while (i--)		{			if ((pfm[i].depth == depth)			    && (pfm[i].bits_per_pixel > bpp))			{				bpp = pfm[i].bits_per_pixel;			}		}		XFree(pfm);	}	if (bpp < 8)	{		error("Less than 8 bpp not currently supported.\n");		XCloseDisplay(display);		return False;	}	if (depth <= 8)		owncolmap = True;	else		xcolmap = DefaultColormapOfScreen(screen);	test = 1;	host_be = !(BOOL)(*(uint8 *)(&test));	xserver_be = (ImageByteOrder(display) == MSBFirst);	white = WhitePixelOfScreen(screen);	attribs.background_pixel = BlackPixelOfScreen(screen);	attribs.backing_store = DoesBackingStore(screen);	if (attribs.backing_store == NotUseful)		ownbackstore = True;	if (fullscreen)	{		attribs.override_redirect = True;		width = WidthOfScreen(screen);		height = HeightOfScreen(screen);	}	else	{		attribs.override_redirect = False;	}	width = (width + 3) & ~3; /* make width a multiple of 32 bits */	wnd = XCreateWindow(display, RootWindowOfScreen(screen),			    0, 0, width, height, 0, CopyFromParent,			    InputOutput, CopyFromParent,			    CWBackingStore | CWBackPixel | CWOverrideRedirect,			    &attribs);	XStoreName(display, wnd, title);	classhints = XAllocClassHint();	if (classhints != NULL)	{		classhints->res_name = classhints->res_class = "rdesktop";		XSetClassHint(display, wnd, classhints);		XFree(classhints);	}	sizehints = XAllocSizeHints();	if (sizehints)	{		sizehints->flags = PMinSize | PMaxSize;		sizehints->min_width = sizehints->max_width = width;		sizehints->min_height = sizehints->max_height = height;		XSetWMNormalHints(display, wnd, sizehints);		XFree(sizehints);	}	input_mask = KeyPressMask | KeyReleaseMask			| ButtonPressMask | ButtonReleaseMask			| EnterWindowMask | LeaveWindowMask;	if (sendmotion)		input_mask |= PointerMotionMask;	if (ownbackstore)		input_mask |= ExposureMask;	XSelectInput(display, wnd, input_mask);	gc = XCreateGC(display, wnd, 0, NULL);	if (ownbackstore)		backstore = XCreatePixmap(display, wnd, width, height, depth);	XMapWindow(display, wnd);	return True;}voidui_destroy_window(){	if (ownbackstore)		XFreePixmap(display, backstore);	XFreeGC(display, gc);	XDestroyWindow(display, wnd);	XCloseDisplay(display);	display = NULL;}static uint8xwin_translate_key(unsigned long key){	DEBUG(("KEY(code=0x%lx)\n", key));	if ((key > 8) && (key <= 0x60))		return (key - 8);	switch (key)	{		case 0x61:	/* home */			return 0x47 | 0x80;		case 0x62:	/* up arrow */			return 0x48 | 0x80;		case 0x63:	/* page up */			return 0x49 | 0x80;		case 0x64:	/* left arrow */			return 0x4b | 0x80;		case 0x66:	/* right arrow */			return 0x4d | 0x80;		case 0x67:	/* end */			return 0x4f | 0x80;		case 0x68:	/* down arrow */			return 0x50 | 0x80;		case 0x69:	/* page down */			return 0x51 | 0x80;		case 0x6a:	/* insert */			return 0x52 | 0x80;		case 0x6b:	/* delete */			return 0x53 | 0x80;		case 0x6c:	/* keypad enter */			return 0x1c | 0x80;		case 0x6d:	/* right ctrl */			return 0x1d | 0x80;		case 0x6f:	/* ctrl - print screen */			return 0x37 | 0x80;		case 0x70:	/* keypad '/' */			return 0x35 | 0x80;		case 0x71:	/* right alt */			return 0x38 | 0x80;		case 0x72:	/* ctrl break */			return 0x46 | 0x80;		case 0x73:	/* left window key */			return 0xff;	/* real scancode is 5b */		case 0x74:	/* right window key */			return 0xff;	/* real scancode is 5c */		case 0x75:	/* menu key */			return 0x5d | 0x80;	}	return 0;}static uint16xwin_translate_mouse(unsigned long button){	switch (button)	{		case Button1:	/* left */			return MOUSE_FLAG_BUTTON1;		case Button2:	/* middle */			return MOUSE_FLAG_BUTTON3;		case Button3:	/* right */			return MOUSE_FLAG_BUTTON2;	}	return 0;}static voidxwin_process_events(){	XEvent event;	uint8 scancode;	uint16 button;	uint32 ev_time;	if (display == NULL)		return;	while (XCheckWindowEvent(display, wnd, ~0, &event))	{		ev_time = time(NULL);		switch (event.type)		{			case KeyPress:				scancode = xwin_translate_key(event.xkey.keycode);				if (scancode == 0)					break;				rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,					       scancode, 0);				break;			case KeyRelease:				scancode = xwin_translate_key(event.xkey.keycode);				if (scancode == 0)					break;				rdp_send_input(ev_time, RDP_INPUT_SCANCODE,					       KBD_FLAG_DOWN | KBD_FLAG_UP,					       scancode, 0);				break;			case ButtonPress:				button = xwin_translate_mouse(event.xbutton.button);				if (button == 0)					break;				rdp_send_input(ev_time, RDP_INPUT_MOUSE,					       button | MOUSE_FLAG_DOWN,					       event.xbutton.x,					       event.xbutton.y);				break;			case ButtonRelease:				button = xwin_translate_mouse(event.xbutton.button);				if (button == 0)					break;				rdp_send_input(ev_time, RDP_INPUT_MOUSE,					       button,					       event.xbutton.x,					       event.xbutton.y);				break;			case MotionNotify:				rdp_send_input(ev_time, RDP_INPUT_MOUSE,					       MOUSE_FLAG_MOVE,					       event.xmotion.x,					       event.xmotion.y);				break;			case EnterNotify:				XGrabKeyboard(display, wnd, True, GrabModeAsync,					      GrabModeAsync, CurrentTime);				break;			case LeaveNotify:				XUngrabKeyboard(display, CurrentTime);				break;			case Expose:				XCopyArea(display, backstore, wnd, gc,					  event.xexpose.x, event.xexpose.y,					  event.xexpose.width, event.xexpose.height,					  event.xexpose.x, event.xexpose.y);				break;		}	}}voidui_select(int rdp_socket){	int n = (rdp_socket > x_socket) ? rdp_socket+1 : x_socket+1;	fd_set rfds;	XFlush(display);	FD_ZERO(&rfds);	while (True)	{		FD_ZERO(&rfds);		FD_SET(rdp_socket, &rfds);		FD_SET(x_socket, &rfds);		switch (select(n, &rfds, NULL, NULL, NULL))		{			case -1:				error("select: %s\n", strerror(errno));			case 0:				continue;		}		if (FD_ISSET(x_socket, &rfds))			xwin_process_events();		if (FD_ISSET(rdp_socket, &rfds))			return;	}}voidui_move_pointer(int x, int y){	XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);}HBITMAPui_create_bitmap(int width, int height, uint8 *data){	XImage *image;	Pixmap bitmap;	uint8 *tdata;	tdata = (owncolmap ? data : translate_image(width, height, data));	bitmap = XCreatePixmap(display, wnd, width, height, depth);	image = XCreateImage(display, visual, depth, ZPixmap,			     0, tdata, width, height, 8, 0);

⌨️ 快捷键说明

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