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

📄 xwin.c

📁 LInux 下的远程桌面工具 Rdesktop
💻 C
📖 第 1 页 / 共 5 页
字号:
					green_weight = vis_green_weight;					blue_weight = vis_blue_weight;					g_visual = visual_info->visual;					g_depth = visual_info->depth;				}			}		}		XFree(vmatches);	}	if (g_visual != NULL)	{		g_owncolmap = False;		calculate_shifts(g_visual->red_mask, &g_red_shift_r, &g_red_shift_l);		calculate_shifts(g_visual->green_mask, &g_green_shift_r, &g_green_shift_l);		calculate_shifts(g_visual->blue_mask, &g_blue_shift_r, &g_blue_shift_l);	}	else	{		template.class = PseudoColor;		template.depth = 8;		template.colormap_size = 256;		vmatches =			XGetVisualInfo(g_display,				       VisualClassMask | VisualDepthMask | VisualColormapSizeMask,				       &template, &visuals_count);		if (vmatches == NULL)		{			error("No usable TrueColor or PseudoColor visuals on this display.\n");			XCloseDisplay(g_display);			XFree(pfm);			return False;		}		/* we use a colourmap, so the default visual should do */		g_owncolmap = True;		g_visual = vmatches[0].visual;		g_depth = vmatches[0].depth;	}	g_bpp = 0;	for (i = 0; i < pixmap_formats_count; ++i)	{		XPixmapFormatValues *pf = &pfm[i];		if (pf->depth == g_depth)		{			g_bpp = pf->bits_per_pixel;			if (g_no_translate_image)			{				switch (g_server_depth)				{					case 15:					case 16:						if (g_bpp != 16)							g_no_translate_image = False;						break;					case 24:						/* Yes, this will force image translation						   on most modern servers which use 32 bits						   for R8G8B8. */						if (g_bpp != 24)							g_no_translate_image = False;						break;					default:						g_no_translate_image = False;						break;				}			}			/* Pixmap formats list is a depth-to-bpp mapping --			   there's just a single entry for every depth,			   so we can safely break here */			break;		}	}	XFree(pfm);	pfm = NULL;	return True;}static XErrorHandler g_old_error_handler;static RD_BOOL g_error_expected = False;/* Check if the X11 window corresponding to a seamless window with   specified id exists. */RD_BOOLsw_window_exists(unsigned long id){	seamless_window *sw;	char *name;	Status sts = 0;	sw = sw_get_window_by_id(id);	if (!sw)		return False;	g_error_expected = True;	sts = XFetchName(g_display, sw->wnd, &name);	g_error_expected = False;	if (sts)	{		XFree(name);	}	return sts;}static interror_handler(Display * dpy, XErrorEvent * eev){	if (g_error_expected)		return 0;	return g_old_error_handler(dpy, eev);}RD_BOOLui_init(void){	int screen_num;	g_display = XOpenDisplay(NULL);	if (g_display == NULL)	{		error("Failed to open display: %s\n", XDisplayName(NULL));		return False;	}	{		uint16 endianess_test = 1;		g_host_be = !(RD_BOOL) (*(uint8 *) (&endianess_test));	}	g_old_error_handler = XSetErrorHandler(error_handler);	g_xserver_be = (ImageByteOrder(g_display) == MSBFirst);	screen_num = DefaultScreen(g_display);	g_x_socket = ConnectionNumber(g_display);	g_screen = ScreenOfDisplay(g_display, screen_num);	g_depth = DefaultDepthOfScreen(g_screen);	if (!select_visual(screen_num))		return False;	if (g_no_translate_image)	{		DEBUG(("Performance optimization possible: avoiding image translation (colour depth conversion).\n"));	}	if (g_server_depth > g_bpp)	{		warning("Remote desktop colour depth %d higher than display colour depth %d.\n",			g_server_depth, g_bpp);	}	DEBUG(("RDP depth: %d, display depth: %d, display bpp: %d, X server BE: %d, host BE: %d\n",	       g_server_depth, g_depth, g_bpp, g_xserver_be, g_host_be));	if (!g_owncolmap)	{		g_xcolmap =			XCreateColormap(g_display, RootWindowOfScreen(g_screen), g_visual,					AllocNone);		if (g_depth <= 8)			warning("Display colour depth is %d bit: you may want to use -C for a private colourmap.\n", g_depth);	}	if ((!g_ownbackstore) && (DoesBackingStore(g_screen) != Always))	{		warning("External BackingStore not available. Using internal.\n");		g_ownbackstore = True;	}	/*	 * Determine desktop size	 */	if (g_fullscreen)	{		g_width = WidthOfScreen(g_screen);		g_height = HeightOfScreen(g_screen);		g_using_full_workarea = True;	}	else if (g_width < 0)	{		/* Percent of screen */		if (-g_width >= 100)			g_using_full_workarea = True;		g_height = HeightOfScreen(g_screen) * (-g_width) / 100;		g_width = WidthOfScreen(g_screen) * (-g_width) / 100;	}	else if (g_width == 0)	{		/* Fetch geometry from _NET_WORKAREA */		uint32 x, y, cx, cy;		if (get_current_workarea(&x, &y, &cx, &cy) == 0)		{			g_width = cx;			g_height = cy;			g_using_full_workarea = True;		}		else		{			warning("Failed to get workarea: probably your window manager does not support extended hints\n");			g_width = WidthOfScreen(g_screen);			g_height = HeightOfScreen(g_screen);		}	}	/* make sure width is a multiple of 4 */	g_width = (g_width + 3) & ~3;	g_mod_map = XGetModifierMapping(g_display);	xwin_refresh_pointer_map();	xkeymap_init();	if (g_enable_compose)		g_IM = XOpenIM(g_display, NULL, NULL, NULL);	xclip_init();	ewmh_init();	if (g_seamless_rdp)	{		seamless_init();	}	DEBUG_RDP5(("server bpp %d client bpp %d depth %d\n", g_server_depth, g_bpp, g_depth));	return True;}voidui_deinit(void){	while (g_seamless_windows)	{		XDestroyWindow(g_display, g_seamless_windows->wnd);		sw_remove_window(g_seamless_windows);	}	xclip_deinit();	if (g_IM != NULL)		XCloseIM(g_IM);	if (g_null_cursor != NULL)		ui_destroy_cursor(g_null_cursor);	XFreeModifiermap(g_mod_map);	if (g_ownbackstore)		XFreePixmap(g_display, g_backstore);	XFreeGC(g_display, g_gc);	XCloseDisplay(g_display);	g_display = NULL;}static voidget_window_attribs(XSetWindowAttributes * attribs){	attribs->background_pixel = BlackPixelOfScreen(g_screen);	attribs->background_pixel = WhitePixelOfScreen(g_screen);	attribs->border_pixel = WhitePixelOfScreen(g_screen);	attribs->backing_store = g_ownbackstore ? NotUseful : Always;	attribs->override_redirect = g_fullscreen;	attribs->colormap = g_xcolmap;}static voidget_input_mask(long *input_mask){	*input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |		VisibilityChangeMask | FocusChangeMask | StructureNotifyMask;	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;}RD_BOOLui_create_window(void){	uint8 null_pointer_mask[1] = { 0x80 };	uint8 null_pointer_data[24] = { 0x00 };	XSetWindowAttributes attribs;	XClassHint *classhints;	XSizeHints *sizehints;	int wndwidth, wndheight;	long input_mask, ic_input_mask;	XEvent xevent;	wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width;	wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height;	/* Handle -x-y portion of geometry string */	if (g_xpos < 0 || (g_xpos == 0 && (g_pos & 2)))		g_xpos = WidthOfScreen(g_screen) + g_xpos - g_width;	if (g_ypos < 0 || (g_ypos == 0 && (g_pos & 4)))		g_ypos = HeightOfScreen(g_screen) + g_ypos - g_height;	get_window_attribs(&attribs);	g_wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), g_xpos, g_ypos, wndwidth,			      wndheight, 0, g_depth, InputOutput, g_visual,			      CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |			      CWBorderPixel, &attribs);	if (g_gc == NULL)	{		g_gc = XCreateGC(g_display, g_wnd, 0, NULL);		ui_reset_clip();	}	if (g_create_bitmap_gc == NULL)		g_create_bitmap_gc = XCreateGC(g_display, g_wnd, 0, NULL);	if ((g_ownbackstore) && (g_backstore == 0))	{		g_backstore = XCreatePixmap(g_display, g_wnd, g_width, g_height, g_depth);		/* clear to prevent rubbish being exposed at startup */		XSetForeground(g_display, g_gc, BlackPixelOfScreen(g_screen));		XFillRectangle(g_display, g_backstore, g_gc, 0, 0, g_width, g_height);	}	XStoreName(g_display, g_wnd, g_title);	ewmh_set_wm_name(g_wnd, g_title);	if (g_hide_decorations)		mwm_hide_decorations(g_wnd);	classhints = XAllocClassHint();	if (classhints != NULL)	{		classhints->res_name = classhints->res_class = "rdesktop";		XSetClassHint(g_display, g_wnd, classhints);		XFree(classhints);	}	sizehints = XAllocSizeHints();	if (sizehints)	{		sizehints->flags = PMinSize | PMaxSize;		if (g_pos)			sizehints->flags |= PPosition;		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_embed_wnd)	{		XReparentWindow(g_display, g_wnd, (Window) g_embed_wnd, 0, 0);	}	get_input_mask(&input_mask);	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);	if (g_seamless_rdp)	{		seamless_restack_test();	}	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_seamless_active)		/* Turn off SeamlessRDP mode */		ui_seamless_toggle();	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);	}}static voidhandle_button_event(XEvent xevent, RD_BOOL down){	uint16 button, flags = 0;	g_last_gesturetime = xevent.xbutton.time;	/* Reverse the pointer button mapping, e.g. in the case of	   "left-handed mouse mode"; the RDP session expects to	   receive physical buttons (true in mstsc as well) and	   logical button behavior depends on the remote desktop's own	   mouse settings */	xevent.xbutton.button = g_pointer_log_to_phys_map[xevent.xbutton.button - 1];	button = xkeymap_translate_button(xevent.xbutton.button);	if (button == 0)		return;	if (down)		flags = MOUSE_FLAG_DOWN;	/* Stop moving window when button is released, regardless of cursor position */	if (g_moving_wnd && (xevent.type == ButtonRelease))		g_moving_wnd = False;	/* If win_button_size is nonzero, enable single app mode */	if (xevent.xbutton.y < g_win_button_size)	{		/*  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 */			if (xevent.type == ButtonPress)				return;		}		else if (xevent.xbutton.x >= g_width - g_win_button_size * 3)		{			/* The minimize button. Iconify window. */			if (xevent.type == ButtonRelease)			{				/* Release the mouse button outside the minimize button, to prevent the				   actual minimazation to happen */				rdp_send_input(time(NULL), RDP_INPUT_MOUSE, button, 1, 1);				XIconifyWindow(g_display, g_wnd, DefaultScreen(g_display));				return;			}		}		else if (xevent.xbutton.x <= g_win_button_size)		{			/* The system menu. Ignore. */			if (xevent.type == ButtonPress)				return;		}		else		{			/* The title bar. */			if (xevent.type == ButtonPress)			{				if (!g_fullscreen && g_hide_decorations && !g_using_full_workarea)				{					g_moving_wnd = True;					g_move_x_offset = xevent.xbutton.x;					g_move_y_offset = xevent.xbutton.y;				}				return;			}		}	}	if (xevent.xmotion.window == g_wnd)	{		rdp_send_input(time(NULL), RDP_INPUT_MOUSE,			       flags | button, xevent.xbutton.x, xevent.xbutton.y);	}	else	{		/* SeamlessRDP */		rdp_send_input(time(NULL), RDP_INPUT_MOUSE,			       flags | button, xevent.xbutton.x_root, xevent.xbutton.y_root);	}}/* Process events in Xlib queue   Returns 0 after user quit, 1 otherwise */

⌨️ 快捷键说明

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