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

📄 xwin.c

📁 rdesktop is a client for Microsoft Windows NT Terminal Server, Windows 2000 Terminal Services, Wind
💻 C
📖 第 1 页 / 共 5 页
字号:
		while (out < end)		{			pixel = *(data++) << 16;			pixel |= *(data++) << 8;			pixel |= *(data++);			SPLITCOLOUR24(pixel, pc);			value = MAKECOLOUR(pc);			BOUT32(out, value);		}	}	else	{		while (out < end)		{			pixel = *(data++) << 16;			pixel |= *(data++) << 8;			pixel |= *(data++);			SPLITCOLOUR24(pixel, pc);			value = MAKECOLOUR(pc);			LOUT32(out, value);		}	}}static uint8 *translate_image(int width, int height, uint8 * data){	int size;	uint8 *out;	uint8 *end;	/*	   If RDP depth and X Visual depths match,	   and arch(endian) matches, no need to translate:	   just return data.	   Note: select_visual should've already ensured g_no_translate	   is only set for compatible depths, but the RDP depth might've	   changed during connection negotiations.	 */	if (g_no_translate_image)	{		if ((g_depth == 15 && g_server_depth == 15) ||		    (g_depth == 16 && g_server_depth == 16) ||		    (g_depth == 24 && g_server_depth == 24))			return data;	}	size = width * height * (g_bpp / 8);	out = (uint8 *) xmalloc(size);	end = out + size;	switch (g_server_depth)	{		case 24:			switch (g_bpp)			{				case 32:					translate24to32(data, out, end);					break;				case 24:					translate24to24(data, out, end);					break;				case 16:					translate24to16(data, out, end);					break;			}			break;		case 16:			switch (g_bpp)			{				case 32:					translate16to32((uint16 *) data, out, end);					break;				case 24:					translate16to24((uint16 *) data, out, end);					break;				case 16:					translate16to16((uint16 *) data, out, end);					break;			}			break;		case 15:			switch (g_bpp)			{				case 32:					translate15to32((uint16 *) data, out, end);					break;				case 24:					translate15to24((uint16 *) data, out, end);					break;				case 16:					translate15to16((uint16 *) data, out, end);					break;			}			break;		case 8:			switch (g_bpp)			{				case 8:					translate8to8(data, out, end);					break;				case 16:					translate8to16(data, out, end);					break;				case 24:					translate8to24(data, out, end);					break;				case 32:					translate8to32(data, out, end);					break;			}			break;	}	return out;}BOOLget_key_state(unsigned int state, uint32 keysym){	int modifierpos, key, keysymMask = 0;	int offset;	KeyCode keycode = XKeysymToKeycode(g_display, keysym);	if (keycode == NoSymbol)		return False;	for (modifierpos = 0; modifierpos < 8; modifierpos++)	{		offset = g_mod_map->max_keypermod * modifierpos;		for (key = 0; key < g_mod_map->max_keypermod; key++)		{			if (g_mod_map->modifiermap[offset + key] == keycode)				keysymMask |= 1 << modifierpos;		}	}	return (state & keysymMask) ? True : False;}static voidcalculate_shifts(uint32 mask, int *shift_r, int *shift_l){	*shift_l = ffs(mask) - 1;	mask >>= *shift_l;	*shift_r = 8 - ffs(mask & ~(mask >> 1));}/* Given a mask of a colour channel (e.g. XVisualInfo.red_mask),   calculates the bits-per-pixel of this channel (a.k.a. colour weight). */static unsignedcalculate_mask_weight(uint32 mask){	unsigned weight = 0;	do	{		weight += (mask & 1);	}	while (mask >>= 1);	return weight;}static BOOLselect_visual(int screen_num){	XPixmapFormatValues *pfm;	int pixmap_formats_count, visuals_count;	XVisualInfo *vmatches = NULL;	XVisualInfo template;	int i;	unsigned red_weight, blue_weight, green_weight;	red_weight = blue_weight = green_weight = 0;	if (g_server_depth == -1)	{		g_server_depth = DisplayPlanes(g_display, DefaultScreen(g_display));	}	pfm = XListPixmapFormats(g_display, &pixmap_formats_count);	if (pfm == NULL)	{		error("Unable to get list of pixmap formats from display.\n");		XCloseDisplay(g_display);		return False;	}	/* Search for best TrueColor visual */	template.class = TrueColor;	template.screen = screen_num;	vmatches =		XGetVisualInfo(g_display, VisualClassMask | VisualScreenMask, &template,			       &visuals_count);	g_visual = NULL;	g_no_translate_image = False;	g_compatible_arch = False;	if (vmatches != NULL)	{		for (i = 0; i < visuals_count; ++i)		{			XVisualInfo *visual_info = &vmatches[i];			BOOL can_translate_to_bpp = False;			int j;			/* Try to find a no-translation visual that'll			   allow us to use RDP bitmaps directly as ZPixmaps. */			if (!g_xserver_be && (((visual_info->depth == 15) &&					       /* R5G5B5 */					       (visual_info->red_mask == 0x7c00) &&					       (visual_info->green_mask == 0x3e0) &&					       (visual_info->blue_mask == 0x1f)) ||					      ((visual_info->depth == 16) &&					       /* R5G6B5 */					       (visual_info->red_mask == 0xf800) &&					       (visual_info->green_mask == 0x7e0) &&					       (visual_info->blue_mask == 0x1f)) ||					      ((visual_info->depth == 24) &&					       /* R8G8B8 */					       (visual_info->red_mask == 0xff0000) &&					       (visual_info->green_mask == 0xff00) &&					       (visual_info->blue_mask == 0xff))))			{				g_visual = visual_info->visual;				g_depth = visual_info->depth;				g_compatible_arch = !g_host_be;				g_no_translate_image = (visual_info->depth == g_server_depth);				if (g_no_translate_image)					/* We found the best visual */					break;			}			else			{				g_compatible_arch = False;			}			if (visual_info->depth > 24)			{				/* Avoid 32-bit visuals and likes like the plague.				   They're either untested or proven to work bad				   (e.g. nvidia's Composite 32-bit visual).				   Most implementation offer a 24-bit visual anyway. */				continue;			}			/* Only care for visuals, for whose BPPs (not depths!)			   we have a translateXtoY function. */			for (j = 0; j < pixmap_formats_count; ++j)			{				if (pfm[j].depth == visual_info->depth)				{					if ((pfm[j].bits_per_pixel == 16) ||					    (pfm[j].bits_per_pixel == 24) ||					    (pfm[j].bits_per_pixel == 32))					{						can_translate_to_bpp = True;					}					break;				}			}			/* Prefer formats which have the most colour depth.			   We're being truly aristocratic here, minding each			   weight on its own. */			if (can_translate_to_bpp)			{				unsigned vis_red_weight =					calculate_mask_weight(visual_info->red_mask);				unsigned vis_green_weight =					calculate_mask_weight(visual_info->green_mask);				unsigned vis_blue_weight =					calculate_mask_weight(visual_info->blue_mask);				if ((vis_red_weight >= red_weight)				    && (vis_green_weight >= green_weight)				    && (vis_blue_weight >= blue_weight))				{					red_weight = vis_red_weight;					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 interror_handler(Display * dpy, XErrorEvent * eev){	if ((eev->error_code == BadMatch) && (eev->request_code == X_ConfigureWindow))	{		fprintf(stderr, "Got \"BadMatch\" when trying to restack windows.\n");		fprintf(stderr,			"This is most likely caused by a broken window manager (commonly KWin).\n");		return 0;	}	return g_old_error_handler(dpy, eev);}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 = !(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);	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;}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();	}

⌨️ 快捷键说明

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