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

📄 xwin.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
					sw_all_to_desktop(This, sw->wnd, sw->desktop);
				}

				break;
			case MapNotify:
				if (!This->xwin.seamless_active)
					rdp_send_client_window_status(This, 1);
				break;
			case UnmapNotify:
				if (!This->xwin.seamless_active)
					rdp_send_client_window_status(This, 0);
				break;
			case ConfigureNotify:
				if (!This->xwin.seamless_active)
					break;

				sw = sw_get_window_by_wnd(This, 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(This, sw);
				break;
		}
	}
	/* Keep going */
	return 1;
}

/* Returns 0 after user quit, 1 otherwise */
int
ui_select(RDPCLIENT * This, int rdp_socket)
{
	int n;
	fd_set rfds, wfds;
	struct timeval tv;
	BOOL s_timeout = False;

	while (True)
	{
		n = (rdp_socket > This->xwin.x_socket) ? rdp_socket : This->xwin.x_socket;
		/* Process any events already waiting */
		if (!xwin_process_events(This))
			/* User quit */
			return 0;

		if (This->xwin.seamless_active)
			sw_check_timers(This);

		FD_ZERO(&rfds);
		FD_ZERO(&wfds);
		FD_SET(rdp_socket, &rfds);
		FD_SET(This->xwin.x_socket, &rfds);

#ifdef WITH_RDPSND
		/* FIXME: there should be an API for registering fds */
		if (This->dsp_busy)
		{
			FD_SET(This->dsp_fd, &wfds);
			n = (This->dsp_fd > n) ? This->dsp_fd : n;
		}
#endif
		/* default timeout */
		tv.tv_sec = 60;
		tv.tv_usec = 0;

		/* add redirection handles */
		rdpdr_add_fds(This, &n, &rfds, &wfds, &tv, &s_timeout);
		seamless_select_timeout(This, &tv);

		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(This, &rfds, &wfds, (BOOL) True);
				continue;
		}

		rdpdr_check_fds(This, &rfds, &wfds, (BOOL) False);

		if (FD_ISSET(rdp_socket, &rfds))
			return 1;

#ifdef WITH_RDPSND
		if (This->dsp_busy && FD_ISSET(This->dsp_fd, &wfds))
			wave_out_play();
#endif
	}
}

void
ui_move_pointer(RDPCLIENT * This, int x, int y)
{
	XWarpPointer(This->display, This->wnd, This->wnd, 0, 0, 0, 0, x, y);
}

HBITMAP
ui_create_bitmap(RDPCLIENT * This, int width, int height, uint8 * data)
{
	XImage *image;
	Pixmap bitmap;
	uint8 *tdata;
	int bitmap_pad;

	if (This->server_depth == 8)
	{
		bitmap_pad = 8;
	}
	else
	{
		bitmap_pad = This->xwin.bpp;

		if (This->xwin.bpp == 24)
			bitmap_pad = 32;
	}

	tdata = (This->owncolmap ? data : translate_image(This, width, height, data));
	bitmap = XCreatePixmap(This->display, This->wnd, width, height, This->xwin.depth);
	image = XCreateImage(This->display, This->xwin.visual, This->xwin.depth, ZPixmap, 0,
			     (char *) tdata, width, height, bitmap_pad, 0);

	XPutImage(This->display, bitmap, This->xwin.create_bitmap_gc, image, 0, 0, 0, 0, width, height);

	XFree(image);
	if (tdata != data)
		xfree(tdata);
	return (HBITMAP) bitmap;
}

void
ui_paint_bitmap(RDPCLIENT * This, int x, int y, int cx, int cy, int width, int height, uint8 * data)
{
	XImage *image;
	uint8 *tdata;
	int bitmap_pad;

	if (This->server_depth == 8)
	{
		bitmap_pad = 8;
	}
	else
	{
		bitmap_pad = This->xwin.bpp;

		if (This->xwin.bpp == 24)
			bitmap_pad = 32;
	}

	tdata = (This->owncolmap ? data : translate_image(This, width, height, data));
	image = XCreateImage(This->display, This->xwin.visual, This->xwin.depth, ZPixmap, 0,
			     (char *) tdata, width, height, bitmap_pad, 0);

	if (This->ownbackstore)
	{
		XPutImage(This->display, This->xwin.backstore, This->xwin.gc, image, 0, 0, x, y, cx, cy);
		XCopyArea(This->display, This->xwin.backstore, This->wnd, This->xwin.gc, x, y, cx, cy, x, y);
		ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
					(This->display, This->xwin.backstore, sw->wnd, This->xwin.gc, x, y, cx, cy,
					 x - sw->xoffset, y - sw->yoffset));
	}
	else
	{
		XPutImage(This->display, This->wnd, This->xwin.gc, image, 0, 0, x, y, cx, cy);
		ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
					(This->display, This->wnd, sw->wnd, This->xwin.gc, x, y, cx, cy,
					 x - sw->xoffset, y - sw->yoffset));
	}

	XFree(image);
	if (tdata != data)
		xfree(tdata);
}

void
ui_destroy_bitmap(RDPCLIENT * This, HBITMAP bmp)
{
	XFreePixmap(This->display, (Pixmap) bmp);
}

HGLYPH
ui_create_glyph(RDPCLIENT * This, int width, int height, const uint8 * data)
{
	XImage *image;
	Pixmap bitmap;
	int scanline;

	scanline = (width + 7) / 8;

	bitmap = XCreatePixmap(This->display, This->wnd, width, height, 1);
	if (This->xwin.create_glyph_gc == 0)
		This->xwin.create_glyph_gc = XCreateGC(This->display, bitmap, 0, NULL);

	image = XCreateImage(This->display, This->xwin.visual, 1, ZPixmap, 0, (char *) data,
			     width, height, 8, scanline);
	image->byte_order = MSBFirst;
	image->bitmap_bit_order = MSBFirst;
	XInitImage(image);

	XPutImage(This->display, bitmap, This->xwin.create_glyph_gc, image, 0, 0, 0, 0, width, height);

	XFree(image);
	return (HGLYPH) bitmap;
}

void
ui_destroy_glyph(RDPCLIENT * This, HGLYPH glyph)
{
	XFreePixmap(This->display, (Pixmap) glyph);
}

HCURSOR
ui_create_cursor(RDPCLIENT * This, 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);
					*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(This, width, height, cursor);
	maskglyph = ui_create_glyph(This, width, height, mask);

	xcursor =
		XCreatePixmapCursor(This->display, (Pixmap) cursorglyph,
				    (Pixmap) maskglyph, &fg, &bg, x, y);

	ui_destroy_glyph(This, maskglyph);
	ui_destroy_glyph(This, cursorglyph);
	xfree(mask);
	xfree(cursor);
	return (HCURSOR) xcursor;
}

void
ui_set_cursor(RDPCLIENT * This, HCURSOR cursor)
{
	This->xwin.current_cursor = (Cursor) cursor;
	XDefineCursor(This->display, This->wnd, This->xwin.current_cursor);
	ON_ALL_SEAMLESS_WINDOWS(XDefineCursor, (This->display, sw->wnd, This->xwin.current_cursor));
}

void
ui_destroy_cursor(RDPCLIENT * This, HCURSOR cursor)
{
	XFreeCursor(This->display, (Cursor) cursor);
}

void
ui_set_null_cursor(RDPCLIENT * This)
{
	ui_set_cursor(This, This->xwin.null_cursor);
}

#define MAKE_XCOLOR(xc,c) \
		(xc)->red   = ((c)->red   << 8) | (c)->red; \
		(xc)->green = ((c)->green << 8) | (c)->green; \
		(xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
		(xc)->flags = DoRed | DoGreen | DoBlue;


HCOLOURMAP
ui_create_colourmap(RDPCLIENT * This, COLOURMAP * colours)
{
	COLOURENTRY *entry;
	int i, ncolours = colours->ncolours;
	if (!This->owncolmap)
	{
		uint32 *map = (uint32 *) xmalloc(sizeof(*This->xwin.colmap) * ncolours);
		XColor xentry;
		XColor xc_cache[256];
		uint32 colour;
		int colLookup = 256;
		for (i = 0; i < ncolours; i++)
		{
			entry = &colours->colours[i];
			MAKE_XCOLOR(&xentry, entry);

			if (XAllocColor(This->display, This->xwin.xcolmap, &xentry) == 0)
			{
				/* Allocation failed, find closest match. */
				int j = 256;
				int nMinDist = 3 * 256 * 256;
				long nDist = nMinDist;

				/* only get the colors once */
				while (colLookup--)
				{
					xc_cache[colLookup].pixel = colLookup;
					xc_cache[colLookup].red = xc_cache[colLookup].green =
						xc_cache[colLookup].blue = 0;
					xc_cache[colLookup].flags = 0;
					XQueryColor(This->display,
						    DefaultColormap(This->display,
								    DefaultScreen(This->display)),
						    &xc_cache[colLookup]);
				}
				colLookup = 0;

				/* approximate the pixel */
				while (j--)
				{
					if (xc_cache[j].flags)
					{
						nDist = ((long) (xc_cache[j].red >> 8) -
							 (long) (xentry.red >> 8)) *
							((long) (xc_cache[j].red >> 8) -
							 (long) (xentry.red >> 8)) +
							((long) (xc_cache[j].green >> 8) -
							 (long) (xentry.green >> 8)) *
							((long) (xc_cache[j].green >> 8) -
							 (long) (xentry.green >> 8)) +
							((long) (xc_cache[j].blue >> 8) -
							 (long) (xentry.blue >> 8)) *
							((long) (xc_cache[j].blue >> 8) -
							 (long) (xentry.blue >> 8));
					}
					if (nDist < nMinDist)
					{
						nMinDist = nDist;
						xentry.pixel = j;
					}
				}
			}
			colour = xentry.pixel;

			/* update our cache */
			if (xentry.pixel < 256)
			{
				xc_cache[xentry.pixel].red = xentry.red;
				xc_cache[xentry.pixel].green = xentry.green;
				xc_cache[xentry.pixel].blue = xentry.blue;

			}

			map[i] = colour;
		}
		return map;
	}
	else
	{
		XColor *xcolours, *xentry;
		Colormap map;

		xcolours = (XColor *) xmalloc(sizeof(XColor) * ncolours);
		for (i = 0; i < ncolours; i++)
		{
			entry = &colours->colours[i];
			xentry = &xcolours[i];
			xentry->pixel = i;
			MAKE_XCOLOR(xentry, entry);
		}

		map = XCreateColormap(This->display, This->wnd, This->xwin.visual, AllocAll);
		XStoreColors(This->display, map, xcolours, ncolours);

		xfree(xcolours);
		return (HCOLOURMAP) map;
	}
}

void
ui_destroy_colourmap(RDPCLIENT * This, HCOLOURMAP map)
{
	if (!This->owncolmap)
		xfree(map);
	else
		XFreeColormap(This->display, (Colormap) map);
}

void
ui_set_colourmap(RDPCLIENT * This, HCOLOURMAP map)
{
	if (!This->owncolmap)
	{
		if (This->xwin.colmap)
			xfree(This->xwin.colmap);

		This->xwin.colmap = (uint32 *) map;
	}
	else
	{
		XSetWindowColormap(This->display, This->wnd, (Colormap) map);
		ON_ALL_SEAMLESS_WINDOWS(XSetWindowColormap, (This->display, sw->wnd, (Colormap) map));
	}
}

void
ui_set_clip(RDPCLIENT * This, int x, int y, int cx, int cy)
{
	This->xwin.clip_rectangle.x = x;
	This->xwin.clip_rectangle.y = y;
	This->xwin.clip_rectangle.width = cx;
	This->xwin.clip_rectangle.height = cy;
	XSetClipRectangles(This->display, This->xwin.gc, 0, 0, &This->xwin.clip_rectangle, 1, YXBanded);
}

void
ui_reset_clip(RDPCLIENT * This)
{
	This->xwin.clip_rectangle.x = 0;
	This->xwin.clip_rectangle.y = 0;
	This->xwin.clip_rectangle.width = This->width;
	This->xwin.clip_rectangle.height = This->height;
	XSetClipRectangles(This->display, This->xwin.gc, 0, 0, &This->xwin.clip_rectangle, 1, YXBanded);
}

void
ui_bell(RDPCLIENT * This)
{
	XBell(This->display, 0);
}

void
ui_destblt(RDPCLIENT * This, uint8 opcode,
	   /* dest */ int x, int y, int cx, int cy)
{
	SET_FUNCTION(opcode);
	FILL_RECTANGLE(x, y, cx, cy);
	RESET_FUNCTION(opcode);
}

static const uint8 hatch_patterns[] = {
	0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,	/* 0 - bsHorizontal */
	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,	/* 1 - bsVertical */
	0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,	/* 2 - bsFDiagonal */
	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,	/* 3 - bsBDiagonal */
	0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08,	/* 4 - bsCross */
	0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81	/* 5 - bsDiagCross */
};

void
ui_patblt(RDPCLIENT * This, uint8 opcode,
	  /* dest */ int x, int y, int cx, int cy,
	  /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
{
	Pixmap fill;
	uint8 i, ipattern[8];

	SET_FUNCTION(opcode);

	switch (brush->style)
	{
		case 0:	/* Solid */
			SET_FOREGROUND(fgcolour);
			FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
			break;

		case 2:	/* Hatch */
			fill = (Pixmap) ui_create_glyph(This, 8, 8,
							h

⌨️ 快捷键说明

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