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

📄 xwin.c

📁 Linux环境下的远程登陆客户端软件,其采用RDP协议
💻 C
📖 第 1 页 / 共 4 页
字号:
	{		XReparentWindow(g_display, g_wnd, (Window) g_embed_wnd, 0, 0);	}	input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |		VisibilityChangeMask | FocusChangeMask;	if (g_sendmotion)		input_mask |= PointerMotionMask;	if (g_ownbackstore)		input_mask |= ExposureMask;	if (g_fullscreen || g_grab_keyboard)		input_mask |= EnterWindowMask;	if (g_grab_keyboard)		input_mask |= LeaveWindowMask;	if (g_IM != NULL)	{		g_IC = XCreateIC(g_IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),				 XNClientWindow, g_wnd, XNFocusWindow, g_wnd, NULL);		if ((g_IC != NULL)		    && (XGetICValues(g_IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))			input_mask |= ic_input_mask;	}	XSelectInput(g_display, g_wnd, input_mask);	XMapWindow(g_display, g_wnd);	/* wait for VisibilityNotify */	do	{		XMaskEvent(g_display, VisibilityChangeMask, &xevent);	}	while (xevent.type != VisibilityNotify);	g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;	g_focused = False;	g_mouse_in_wnd = False;	/* handle the WM_DELETE_WINDOW protocol */	g_protocol_atom = XInternAtom(g_display, "WM_PROTOCOLS", True);	g_kill_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", True);	XSetWMProtocols(g_display, g_wnd, &g_kill_atom, 1);	/* create invisible 1x1 cursor to be used as null cursor */	if (g_null_cursor == NULL)		g_null_cursor = ui_create_cursor(0, 0, 1, 1, null_pointer_mask, null_pointer_data);	return True;}voidui_resize_window(){	XSizeHints *sizehints;	Pixmap bs;	sizehints = XAllocSizeHints();	if (sizehints)	{		sizehints->flags = PMinSize | PMaxSize;		sizehints->min_width = sizehints->max_width = g_width;		sizehints->min_height = sizehints->max_height = g_height;		XSetWMNormalHints(g_display, g_wnd, sizehints);		XFree(sizehints);	}	if (!(g_fullscreen || g_embed_wnd))	{		XResizeWindow(g_display, g_wnd, g_width, g_height);	}	/* create new backstore pixmap */	if (g_backstore != 0)	{		bs = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);		XSetForeground(g_display, g_gc, BlackPixelOfScreen(g_screen));		XFillRectangle(g_display, bs, g_gc, 0, 0, g_width, g_height);		XCopyArea(g_display, g_backstore, bs, g_gc, 0, 0, g_width, g_height, 0, 0);		XFreePixmap(g_display, g_backstore);		g_backstore = bs;	}}voidui_destroy_window(void){	if (g_IC != NULL)		XDestroyIC(g_IC);	XDestroyWindow(g_display, g_wnd);}voidxwin_toggle_fullscreen(void){	Pixmap contents = 0;	if (!g_ownbackstore)	{		/* need to save contents of window */		contents = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);		XCopyArea(g_display, g_wnd, contents, g_gc, 0, 0, g_width, g_height, 0, 0);	}	ui_destroy_window();	g_fullscreen = !g_fullscreen;	ui_create_window();	XDefineCursor(g_display, g_wnd, g_current_cursor);	if (!g_ownbackstore)	{		XCopyArea(g_display, contents, g_wnd, g_gc, 0, 0, g_width, g_height, 0, 0);		XFreePixmap(g_display, contents);	}}/* Process all events in Xlib queue   Returns 0 after user quit, 1 otherwise */static intxwin_process_events(void){	XEvent xevent;	KeySym keysym;	uint16 button, flags;	uint32 ev_time;	key_translation tr;	char str[256];	Status status;	while (XPending(g_display) > 0)	{		XNextEvent(g_display, &xevent);		if ((g_IC != NULL) && (XFilterEvent(&xevent, None) == True))		{			DEBUG_KBD(("Filtering event\n"));			continue;		}		flags = 0;		switch (xevent.type)		{			case VisibilityNotify:				g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;				break;			case ClientMessage:				/* the window manager told us to quit */				if ((xevent.xclient.message_type == g_protocol_atom)				    && ((Atom) xevent.xclient.data.l[0] == g_kill_atom))					/* Quit */					return 0;				break;			case KeyPress:				g_last_gesturetime = xevent.xkey.time;				if (g_IC != NULL)					/* Multi_key compatible version */				{					XmbLookupString(g_IC,							&xevent.xkey, str, sizeof(str), &keysym,							&status);					if (!((status == XLookupKeySym) || (status == XLookupBoth)))					{						error("XmbLookupString failed with status 0x%x\n",						      status);						break;					}				}				else				{					/* Plain old XLookupString */					DEBUG_KBD(("\nNo input context, using XLookupString\n"));					XLookupString((XKeyEvent *) & xevent,						      str, sizeof(str), &keysym, NULL);				}				DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,					   get_ksname(keysym)));				ev_time = time(NULL);				if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))					break;				tr = xkeymap_translate_key(keysym,							   xevent.xkey.keycode, xevent.xkey.state);				if (tr.scancode == 0)					break;				save_remote_modifiers(tr.scancode);				ensure_remote_modifiers(ev_time, tr);				rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);				restore_remote_modifiers(ev_time, tr.scancode);				break;			case KeyRelease:				g_last_gesturetime = xevent.xkey.time;				XLookupString((XKeyEvent *) & xevent, str,					      sizeof(str), &keysym, NULL);				DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,					   get_ksname(keysym)));				ev_time = time(NULL);				if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))					break;				tr = xkeymap_translate_key(keysym,							   xevent.xkey.keycode, xevent.xkey.state);				if (tr.scancode == 0)					break;				rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);				break;			case ButtonPress:				flags = MOUSE_FLAG_DOWN;				/* fall through */			case ButtonRelease:				g_last_gesturetime = xevent.xbutton.time;				button = xkeymap_translate_button(xevent.xbutton.button);				if (button == 0)					break;				/* If win_button_size is nonzero, enable single app mode */				if (xevent.xbutton.y < g_win_button_size)				{					/* Stop moving window when button is released, regardless of cursor position */					if (g_moving_wnd && (xevent.type == ButtonRelease))						g_moving_wnd = False;					/*  Check from right to left: */					if (xevent.xbutton.x >= g_width - g_win_button_size)					{						/* The close button, continue */						;					}					else if (xevent.xbutton.x >=						 g_width - g_win_button_size * 2)					{						/* The maximize/restore button. Do not send to						   server.  It might be a good idea to change the						   cursor or give some other visible indication						   that rdesktop inhibited this click */						break;					}					else if (xevent.xbutton.x >=						 g_width - g_win_button_size * 3)					{						/* The minimize button. Iconify window. */						XIconifyWindow(g_display, g_wnd,							       DefaultScreen(g_display));						break;					}					else if (xevent.xbutton.x <= g_win_button_size)					{						/* The system menu. Ignore. */						break;					}					else					{						/* The title bar. */						if ((xevent.type == ButtonPress) && !g_fullscreen						    && g_hide_decorations)						{							g_moving_wnd = True;							g_move_x_offset = xevent.xbutton.x;							g_move_y_offset = xevent.xbutton.y;						}						break;					}				}				rdp_send_input(time(NULL), RDP_INPUT_MOUSE,					       flags | button, xevent.xbutton.x, xevent.xbutton.y);				break;			case MotionNotify:				if (g_moving_wnd)				{					XMoveWindow(g_display, g_wnd,						    xevent.xmotion.x_root - g_move_x_offset,						    xevent.xmotion.y_root - g_move_y_offset);					break;				}				if (g_fullscreen && !g_focused)					XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,						       CurrentTime);				rdp_send_input(time(NULL), RDP_INPUT_MOUSE,					       MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);				break;			case FocusIn:				if (xevent.xfocus.mode == NotifyGrab)					break;				g_focused = True;				reset_modifier_keys();				if (g_grab_keyboard && g_mouse_in_wnd)					XGrabKeyboard(g_display, g_wnd, True,						      GrabModeAsync, GrabModeAsync, CurrentTime);				break;			case FocusOut:				if (xevent.xfocus.mode == NotifyUngrab)					break;				g_focused = False;				if (xevent.xfocus.mode == NotifyWhileGrabbed)					XUngrabKeyboard(g_display, CurrentTime);				break;			case EnterNotify:				/* we only register for this event when in fullscreen mode */				/* or grab_keyboard */				g_mouse_in_wnd = True;				if (g_fullscreen)				{					XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,						       CurrentTime);					break;				}				if (g_focused)					XGrabKeyboard(g_display, g_wnd, True,						      GrabModeAsync, GrabModeAsync, CurrentTime);				break;			case LeaveNotify:				/* we only register for this event when grab_keyboard */				g_mouse_in_wnd = False;				XUngrabKeyboard(g_display, CurrentTime);				break;			case Expose:				XCopyArea(g_display, g_backstore, g_wnd, g_gc,					  xevent.xexpose.x, xevent.xexpose.y,					  xevent.xexpose.width,					  xevent.xexpose.height,					  xevent.xexpose.x, xevent.xexpose.y);				break;			case MappingNotify:				/* Refresh keyboard mapping if it has changed. This is important for				   Xvnc, since it allocates keycodes dynamically */				if (xevent.xmapping.request == MappingKeyboard				    || xevent.xmapping.request == MappingModifier)					XRefreshKeyboardMapping(&xevent.xmapping);				if (xevent.xmapping.request == MappingModifier)				{					XFreeModifiermap(g_mod_map);					g_mod_map = XGetModifierMapping(g_display);				}				break;				/* clipboard stuff */			case SelectionNotify:				xclip_handle_SelectionNotify(&xevent.xselection);				break;			case SelectionRequest:				xclip_handle_SelectionRequest(&xevent.xselectionrequest);				break;			case SelectionClear:				xclip_handle_SelectionClear();				break;			case PropertyNotify:				xclip_handle_PropertyNotify(&xevent.xproperty);				break;		}	}	/* Keep going */	return 1;}/* Returns 0 after user quit, 1 otherwise */intui_select(int rdp_socket){	int n;	fd_set rfds, wfds;	struct timeval tv;	BOOL s_timeout = False;	while (True)	{		n = (rdp_socket > g_x_socket) ? rdp_socket : g_x_socket;		/* Process any events already waiting */		if (!xwin_process_events())			/* User quit */			return 0;		FD_ZERO(&rfds);		FD_ZERO(&wfds);		FD_SET(rdp_socket, &rfds);		FD_SET(g_x_socket, &rfds);#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		/* default timeout */		tv.tv_sec = 60;		tv.tv_usec = 0;		/* add redirection handles */		rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);		n++;		switch (select(n, &rfds, &wfds, NULL, &tv))		{			case -1:				error("select: %s\n", strerror(errno));			case 0:				/* Abort serial read calls */				if (s_timeout)					rdpdr_check_fds(&rfds, &wfds, (BOOL) True);				continue;		}		rdpdr_check_fds(&rfds, &wfds, (BOOL) False);		if (FD_ISSET(rdp_socket, &rfds))			return 1;#ifdef WITH_RDPSND		if (g_dsp_busy && FD_ISSET(g_dsp_fd, &wfds))			wave_out_play();#endif	}}voidui_move_pointer(int x, int y){	XWarpPointer(g_display, g_wnd, g_wnd, 0, 0, 0, 0, x, y);}HBITMAPui_create_bitmap(int width, int height, uint8 * data){	XImage *image;	Pixmap bitmap;	uint8 *tdata;	int bitmap_pad;	if (g_server_bpp == 8)	{		bitmap_pad = 8;	}	else	{		bitmap_pad = g_bpp;		if (g_bpp == 24)			bitmap_pad = 32;	}	tdata = (g_owncolmap ? data : translate_image(width, height, data));	bitmap = XCreatePixmap(g_display, g_wnd, width, height, g_depth);	image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,			     (char *) tdata, width, height, bitmap_pad, 0);	XPutImage(g_display, bitmap, g_create_bitmap_gc, image, 0, 0, 0, 0, width, height);	XFree(image);	if (tdata != data)		xfree(tdata);	return (HBITMAP) bitmap;}voidui_paint_bitmap(int x, int y, int cx, int cy, int width, int height, uint8 * data){	XImage *image;	uint8 *tdata;	int bitmap_pad;	if (g_server_bpp == 8)	{		bitmap_pad = 8;	}	else	{		bitmap_pad = g_bpp;		if (g_bpp == 24)			bitmap_pad = 32;	}	tdata = (g_owncolmap ? data : translate_image(width, height, data));	image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,			     (char *) tdata, width, height, bitmap_pad, 0);	if (g_ownbackstore)	{		XPutImage(g_display, g_backstore, g_gc, image, 0, 0, x, y, cx, cy);		XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);	}	else	{		XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy);	}	XFree(image);	if (tdata != data)		xfree(tdata);}voidui_destroy_bitmap(HBITMAP bmp){	XFreePixmap(g_display, (Pixmap) bmp);}HGLYPHui_create_glyph(int width, int height, uint8 * data){	XImage *image;	Pixmap bitmap;	int scanline;	scanline = (width + 7) / 8;	bitmap = XCreatePixmap(g_display, g_wnd, width, height, 1);	if (g_create_glyph_gc == 0)		g_create_glyph_gc = XCreateGC(g_display, bitmap, 0, NULL);	image = XCreateImage(g_display, g_visual, 1, ZPixmap, 0, (char *) data,			     width, height, 8, scanline);	image->byte_order = MSBFirst;	image->bitmap_bit_order = MSBFirst;	XInitImage(image);	XPutImage(g_display, bitmap, g_create_glyph_gc, image, 0, 0, 0, 0, width, height);	XFree(image);	return (HGLYPH) bitmap;}voidui_destroy_glyph(HGLYPH glyph){	XFreePixmap(g_display, (Pixmap) glyph);}HCURSORui_create_cursor(unsigned int x, unsigned int y, int width, int height,		 uint8 * andmask, uint8 * xormask){	HGLYPH maskglyph, cursorglyph;	XColor bg, fg;	Cursor xcursor;	uint8 *cursor, *pcursor;	uint8 *mask, *pmask;	uint8 nextbit;	int scanline, offset;	int i, j;	scanline = (width + 7) / 8;	offset = scanline * height;	cursor = (uint8 *) xmalloc(offset);	memset(cursor, 0, offset);	mask = (uint8 *) xmalloc(offset);	memset(mask, 0, offset);	/* approximate AND and XOR masks with a monochrome X pointer */	for (i = 0; i < height; i++)	{		offset -= scanline;		pcursor = &cursor[offset];		pmask = &mask[offset];		for (j = 0; j < scanline; j++)		{			for (nextbit = 0x80; nextbit != 0; nextbit >>= 1)			{				if (xormask[0] || xormask[1] || xormask[2])				{					*pcursor |= (~(*andmask) & nextbit);

⌨️ 快捷键说明

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