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

📄 xwin.c

📁 LInux 下的远程桌面工具 Rdesktop
💻 C
📖 第 1 页 / 共 5 页
字号:
static intxwin_process_events(void){	XEvent xevent;	KeySym keysym;	uint32 ev_time;	char str[256];	Status status;	int events = 0;	seamless_window *sw;	while ((XPending(g_display) > 0) && events++ < 20)	{		XNextEvent(g_display, &xevent);		if ((g_IC != NULL) && (XFilterEvent(&xevent, None) == True))		{			DEBUG_KBD(("Filtering event\n"));			continue;		}		switch (xevent.type)		{			case VisibilityNotify:				if (xevent.xvisibility.window == g_wnd)					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))				{					/* When killing a seamless window, close the window on the					   serverside instead of terminating rdesktop */					sw = sw_get_window_by_wnd(xevent.xclient.window);					if (!sw)						/* Otherwise, quit */						return 0;					/* send seamless destroy process message */					seamless_send_destroy(sw->id);				}				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;				xkeymap_send_keys(keysym, xevent.xkey.keycode, xevent.xkey.state,						  ev_time, True, 0);				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;				xkeymap_send_keys(keysym, xevent.xkey.keycode, xevent.xkey.state,						  ev_time, False, 0);				break;			case ButtonPress:				handle_button_event(xevent, True);				break;			case ButtonRelease:				handle_button_event(xevent, False);				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);				if (xevent.xmotion.window == g_wnd)				{					rdp_send_input(time(NULL), RDP_INPUT_MOUSE, MOUSE_FLAG_MOVE,						       xevent.xmotion.x, xevent.xmotion.y);				}				else				{					/* SeamlessRDP */					rdp_send_input(time(NULL), RDP_INPUT_MOUSE, MOUSE_FLAG_MOVE,						       xevent.xmotion.x_root,						       xevent.xmotion.y_root);				}				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);				sw = sw_get_window_by_wnd(xevent.xfocus.window);				if (!sw)					break;				/* Menu windows are real X11 windows,				   with focus. When such a window is				   destroyed, focus is reverted to the				   main application window, which				   would cause us to send FOCUS. This				   breaks window switching in, say,				   Seamonkey. We shouldn't need to				   send FOCUS: Windows should also				   revert focus to some other window				   when the menu window is				   destroyed. So, we only send FOCUS				   if the previous focus window still				   exists. */				if (sw->id != g_seamless_focused)				{					if (sw_window_exists(g_seamless_focused))						seamless_send_focus(sw->id, 0);					g_seamless_focused = sw->id;				}				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:				if (xevent.xexpose.window == g_wnd)				{					XCopyArea(g_display, g_backstore, xevent.xexpose.window,						  g_gc,						  xevent.xexpose.x, xevent.xexpose.y,						  xevent.xexpose.width, xevent.xexpose.height,						  xevent.xexpose.x, xevent.xexpose.y);				}				else				{					sw = sw_get_window_by_wnd(xevent.xexpose.window);					if (!sw)						break;					XCopyArea(g_display, g_backstore,						  xevent.xexpose.window, g_gc,						  xevent.xexpose.x + sw->xoffset,						  xevent.xexpose.y + sw->yoffset,						  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);				}				if (xevent.xmapping.request == MappingPointer)				{					xwin_refresh_pointer_map();				}				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);				if (xevent.xproperty.window == g_wnd)					break;				if (xevent.xproperty.window == DefaultRootWindow(g_display))					break;				/* seamless */				sw = sw_get_window_by_wnd(xevent.xproperty.window);				if (!sw)					break;				if ((xevent.xproperty.atom == g_net_wm_state_atom)				    && (xevent.xproperty.state == PropertyNewValue))				{					sw->state = ewmh_get_window_state(sw->wnd);					seamless_send_state(sw->id, sw->state, 0);				}				if ((xevent.xproperty.atom == g_net_wm_desktop_atom)				    && (xevent.xproperty.state == PropertyNewValue))				{					sw->desktop = ewmh_get_window_desktop(sw->wnd);					sw_all_to_desktop(sw->wnd, sw->desktop);				}				break;			case MapNotify:				if (!g_seamless_active)					rdp_send_client_window_status(1);				break;			case UnmapNotify:				if (!g_seamless_active)					rdp_send_client_window_status(0);				break;			case ConfigureNotify:				if (!g_seamless_active)					break;				sw = sw_get_window_by_wnd(xevent.xconfigure.window);				if (!sw)					break;				gettimeofday(sw->position_timer, NULL);				if (sw->position_timer->tv_usec + SEAMLESSRDP_POSITION_TIMER >=				    1000000)				{					sw->position_timer->tv_usec +=						SEAMLESSRDP_POSITION_TIMER - 1000000;					sw->position_timer->tv_sec += 1;				}				else				{					sw->position_timer->tv_usec += SEAMLESSRDP_POSITION_TIMER;				}				sw_handle_restack(sw);				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;	RD_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;		if (g_seamless_active)			sw_check_timers();		FD_ZERO(&rfds);		FD_ZERO(&wfds);		FD_SET(rdp_socket, &rfds);		FD_SET(g_x_socket, &rfds);		/* default timeout */		tv.tv_sec = 60;		tv.tv_usec = 0;#ifdef WITH_RDPSND		rdpsnd_add_fds(&n, &rfds, &wfds, &tv);#endif		/* add redirection handles */		rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);		seamless_select_timeout(&tv);		n++;		switch (select(n, &rfds, &wfds, NULL, &tv))		{			case -1:				error("select: %s\n", strerror(errno));			case 0:#ifdef WITH_RDPSND				rdpsnd_check_fds(&rfds, &wfds);#endif				/* Abort serial read calls */				if (s_timeout)					rdpdr_check_fds(&rfds, &wfds, (RD_BOOL) True);				continue;		}#ifdef WITH_RDPSND		rdpsnd_check_fds(&rfds, &wfds);#endif		rdpdr_check_fds(&rfds, &wfds, (RD_BOOL) False);		if (FD_ISSET(rdp_socket, &rfds))			return 1;	}}voidui_move_pointer(int x, int y){	XWarpPointer(g_display, g_wnd, g_wnd, 0, 0, 0, 0, x, y);}RD_HBITMAPui_create_bitmap(int width, int height, uint8 * data){	XImage *image;	Pixmap bitmap;	uint8 *tdata;	int bitmap_pad;	if (g_server_depth == 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 (RD_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_depth == 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);		ON_ALL_SEAMLESS_WINDOWS(XCopyArea,					(g_display, g_backstore, sw->wnd, g_gc, x, y, cx, cy,					 x - sw->xoffset, y - sw->yoffset));	}	else	{		XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy);		ON_ALL_SEAMLESS_WINDOWS(XCopyArea,					(g_display, g_wnd, sw->wnd, g_gc, x, y, cx, cy,					 x - sw->xoffset, y - sw->yoffset));	}	XFree(image);	if (tdata != data)		xfree(tdata);}voidui_destroy_bitmap(RD_HBITMAP bmp){	XFreePixmap(g_display, (Pixmap) bmp);}RD_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 (RD_HGLYPH) bitmap;}voidui_destroy_glyph(RD_HGLYPH glyph){	XFreePixmap(g_display, (Pixmap) glyph);}RD_HCURSORui_create_cursor(unsigned int x, unsigned int y, int width, int height,		 uint8 * andmask, uint8 * xormask){	RD_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);					*pmask |= nextbit;				}				else				{					*pcursor |= ((*andmask) & nextbit);					*pmask |= (~(*andmask) & nextbit);				}				xormask += 3;			}			andmask++;			pcursor++;			pmask++;		}	}	fg.red = fg.blue = fg.green = 0xffff;	bg.red = bg.blue = bg.green = 0x0000;	fg.flags = bg.flags = DoRed | DoBlue | DoGreen;	cursorglyph = ui_create_glyph(width, height, cursor);	maskglyph = ui_create_glyph(width, height, mask);	xcursor =		XCreatePixmapCursor(g_display, (Pixmap) cursorglyph,				    (Pixmap) maskglyph, &fg, &bg, x, y);	ui_destroy_glyph

⌨️ 快捷键说明

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