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

📄 orders.c

📁 rdesktop is a client for Microsoft Windows NT Terminal Server, Windows 2000 Terminal Services, Wind
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- c-basic-offset: 8 -*-   rdesktop: A Remote Desktop Protocol client.   RDP order processing   Copyright (C) Matthew Chapman 1999-2005   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "rdesktop.h"#include "orders.h"extern uint8 *g_next_packet;static RDP_ORDER_STATE g_order_state;extern BOOL g_use_rdp5;/* Read field indicating which parameters are present */static voidrdp_in_present(STREAM s, uint32 * present, uint8 flags, int size){	uint8 bits;	int i;	if (flags & RDP_ORDER_SMALL)	{		size--;	}	if (flags & RDP_ORDER_TINY)	{		if (size < 2)			size = 0;		else			size -= 2;	}	*present = 0;	for (i = 0; i < size; i++)	{		in_uint8(s, bits);		*present |= bits << (i * 8);	}}/* Read a co-ordinate (16-bit, or 8-bit delta) */static voidrdp_in_coord(STREAM s, sint16 * coord, BOOL delta){	sint8 change;	if (delta)	{		in_uint8(s, change);		*coord += change;	}	else	{		in_uint16_le(s, *coord);	}}/* Parse a delta co-ordinate in polyline/polygon order form */static intparse_delta(uint8 * buffer, int *offset){	int value = buffer[(*offset)++];	int two_byte = value & 0x80;	if (value & 0x40)	/* sign bit */		value |= ~0x3f;	else		value &= 0x3f;	if (two_byte)		value = (value << 8) | buffer[(*offset)++];	return value;}/* Read a colour entry */static voidrdp_in_colour(STREAM s, uint32 * colour){	uint32 i;	in_uint8(s, i);	*colour = i;	in_uint8(s, i);	*colour |= i << 8;	in_uint8(s, i);	*colour |= i << 16;}/* Parse bounds information */static BOOLrdp_parse_bounds(STREAM s, BOUNDS * bounds){	uint8 present;	in_uint8(s, present);	if (present & 1)		rdp_in_coord(s, &bounds->left, False);	else if (present & 16)		rdp_in_coord(s, &bounds->left, True);	if (present & 2)		rdp_in_coord(s, &bounds->top, False);	else if (present & 32)		rdp_in_coord(s, &bounds->top, True);	if (present & 4)		rdp_in_coord(s, &bounds->right, False);	else if (present & 64)		rdp_in_coord(s, &bounds->right, True);	if (present & 8)		rdp_in_coord(s, &bounds->bottom, False);	else if (present & 128)		rdp_in_coord(s, &bounds->bottom, True);	return s_check(s);}/* Parse a pen */static BOOLrdp_parse_pen(STREAM s, PEN * pen, uint32 present){	if (present & 1)		in_uint8(s, pen->style);	if (present & 2)		in_uint8(s, pen->width);	if (present & 4)		rdp_in_colour(s, &pen->colour);	return s_check(s);}/* Parse a brush */static BOOLrdp_parse_brush(STREAM s, BRUSH * brush, uint32 present){	if (present & 1)		in_uint8(s, brush->xorigin);	if (present & 2)		in_uint8(s, brush->yorigin);	if (present & 4)		in_uint8(s, brush->style);	if (present & 8)		in_uint8(s, brush->pattern[0]);	if (present & 16)		in_uint8a(s, &brush->pattern[1], 7);	return s_check(s);}/* Process a destination blt order */static voidprocess_destblt(STREAM s, DESTBLT_ORDER * os, uint32 present, BOOL delta){	if (present & 0x01)		rdp_in_coord(s, &os->x, delta);	if (present & 0x02)		rdp_in_coord(s, &os->y, delta);	if (present & 0x04)		rdp_in_coord(s, &os->cx, delta);	if (present & 0x08)		rdp_in_coord(s, &os->cy, delta);	if (present & 0x10)		in_uint8(s, os->opcode);	DEBUG(("DESTBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d)\n",	       os->opcode, os->x, os->y, os->cx, os->cy));	ui_destblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy);}/* Process a pattern blt order */static voidprocess_patblt(STREAM s, PATBLT_ORDER * os, uint32 present, BOOL delta){	if (present & 0x0001)		rdp_in_coord(s, &os->x, delta);	if (present & 0x0002)		rdp_in_coord(s, &os->y, delta);	if (present & 0x0004)		rdp_in_coord(s, &os->cx, delta);	if (present & 0x0008)		rdp_in_coord(s, &os->cy, delta);	if (present & 0x0010)		in_uint8(s, os->opcode);	if (present & 0x0020)		rdp_in_colour(s, &os->bgcolour);	if (present & 0x0040)		rdp_in_colour(s, &os->fgcolour);	rdp_parse_brush(s, &os->brush, present >> 7);	DEBUG(("PATBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,bs=%d,bg=0x%x,fg=0x%x)\n", os->opcode, os->x,	       os->y, os->cx, os->cy, os->brush.style, os->bgcolour, os->fgcolour));	ui_patblt(ROP2_P(os->opcode), os->x, os->y, os->cx, os->cy,		  &os->brush, os->bgcolour, os->fgcolour);}/* Process a screen blt order */static voidprocess_screenblt(STREAM s, SCREENBLT_ORDER * os, uint32 present, BOOL delta){	if (present & 0x0001)		rdp_in_coord(s, &os->x, delta);	if (present & 0x0002)		rdp_in_coord(s, &os->y, delta);	if (present & 0x0004)		rdp_in_coord(s, &os->cx, delta);	if (present & 0x0008)		rdp_in_coord(s, &os->cy, delta);	if (present & 0x0010)		in_uint8(s, os->opcode);	if (present & 0x0020)		rdp_in_coord(s, &os->srcx, delta);	if (present & 0x0040)		rdp_in_coord(s, &os->srcy, delta);	DEBUG(("SCREENBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,srcx=%d,srcy=%d)\n",	       os->opcode, os->x, os->y, os->cx, os->cy, os->srcx, os->srcy));	ui_screenblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy, os->srcx, os->srcy);}/* Process a line order */static voidprocess_line(STREAM s, LINE_ORDER * os, uint32 present, BOOL delta){	if (present & 0x0001)		in_uint16_le(s, os->mixmode);	if (present & 0x0002)		rdp_in_coord(s, &os->startx, delta);	if (present & 0x0004)		rdp_in_coord(s, &os->starty, delta);	if (present & 0x0008)		rdp_in_coord(s, &os->endx, delta);	if (present & 0x0010)		rdp_in_coord(s, &os->endy, delta);	if (present & 0x0020)		rdp_in_colour(s, &os->bgcolour);	if (present & 0x0040)		in_uint8(s, os->opcode);	rdp_parse_pen(s, &os->pen, present >> 7);	DEBUG(("LINE(op=0x%x,sx=%d,sy=%d,dx=%d,dy=%d,fg=0x%x)\n",	       os->opcode, os->startx, os->starty, os->endx, os->endy, os->pen.colour));	if (os->opcode < 0x01 || os->opcode > 0x10)	{		error("bad ROP2 0x%x\n", os->opcode);		return;	}	ui_line(os->opcode - 1, os->startx, os->starty, os->endx, os->endy, &os->pen);}/* Process an opaque rectangle order */static voidprocess_rect(STREAM s, RECT_ORDER * os, uint32 present, BOOL delta){	uint32 i;	if (present & 0x01)		rdp_in_coord(s, &os->x, delta);	if (present & 0x02)		rdp_in_coord(s, &os->y, delta);	if (present & 0x04)		rdp_in_coord(s, &os->cx, delta);	if (present & 0x08)		rdp_in_coord(s, &os->cy, delta);	if (present & 0x10)	{		in_uint8(s, i);		os->colour = (os->colour & 0xffffff00) | i;	}	if (present & 0x20)	{		in_uint8(s, i);		os->colour = (os->colour & 0xffff00ff) | (i << 8);	}	if (present & 0x40)	{		in_uint8(s, i);		os->colour = (os->colour & 0xff00ffff) | (i << 16);	}	DEBUG(("RECT(x=%d,y=%d,cx=%d,cy=%d,fg=0x%x)\n", os->x, os->y, os->cx, os->cy, os->colour));	ui_rect(os->x, os->y, os->cx, os->cy, os->colour);}/* Process a desktop save order */static voidprocess_desksave(STREAM s, DESKSAVE_ORDER * os, uint32 present, BOOL delta){	int width, height;	if (present & 0x01)		in_uint32_le(s, os->offset);	if (present & 0x02)		rdp_in_coord(s, &os->left, delta);	if (present & 0x04)		rdp_in_coord(s, &os->top, delta);	if (present & 0x08)		rdp_in_coord(s, &os->right, delta);	if (present & 0x10)		rdp_in_coord(s, &os->bottom, delta);	if (present & 0x20)		in_uint8(s, os->action);	DEBUG(("DESKSAVE(l=%d,t=%d,r=%d,b=%d,off=%d,op=%d)\n",	       os->left, os->top, os->right, os->bottom, os->offset, os->action));	width = os->right - os->left + 1;	height = os->bottom - os->top + 1;	if (os->action == 0)		ui_desktop_save(os->offset, os->left, os->top, width, height);	else		ui_desktop_restore(os->offset, os->left, os->top, width, height);}/* Process a memory blt order */static voidprocess_memblt(STREAM s, MEMBLT_ORDER * os, uint32 present, BOOL delta){	HBITMAP bitmap;	if (present & 0x0001)	{		in_uint8(s, os->cache_id);		in_uint8(s, os->colour_table);	}	if (present & 0x0002)		rdp_in_coord(s, &os->x, delta);	if (present & 0x0004)		rdp_in_coord(s, &os->y, delta);	if (present & 0x0008)		rdp_in_coord(s, &os->cx, delta);	if (present & 0x0010)		rdp_in_coord(s, &os->cy, delta);	if (present & 0x0020)		in_uint8(s, os->opcode);	if (present & 0x0040)		rdp_in_coord(s, &os->srcx, delta);	if (present & 0x0080)		rdp_in_coord(s, &os->srcy, delta);	if (present & 0x0100)		in_uint16_le(s, os->cache_idx);	DEBUG(("MEMBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,id=%d,idx=%d)\n",	       os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id, os->cache_idx));	bitmap = cache_get_bitmap(os->cache_id, os->cache_idx);	if (bitmap == NULL)		return;	ui_memblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy, bitmap, os->srcx, os->srcy);}/* Process a 3-way blt order */static voidprocess_triblt(STREAM s, TRIBLT_ORDER * os, uint32 present, BOOL delta){	HBITMAP bitmap;	if (present & 0x000001)	{		in_uint8(s, os->cache_id);		in_uint8(s, os->colour_table);	}	if (present & 0x000002)		rdp_in_coord(s, &os->x, delta);	if (present & 0x000004)		rdp_in_coord(s, &os->y, delta);	if (present & 0x000008)		rdp_in_coord(s, &os->cx, delta);	if (present & 0x000010)		rdp_in_coord(s, &os->cy, delta);	if (present & 0x000020)		in_uint8(s, os->opcode);	if (present & 0x000040)		rdp_in_coord(s, &os->srcx, delta);	if (present & 0x000080)		rdp_in_coord(s, &os->srcy, delta);	if (present & 0x000100)		rdp_in_colour(s, &os->bgcolour);	if (present & 0x000200)		rdp_in_colour(s, &os->fgcolour);	rdp_parse_brush(s, &os->brush, present >> 10);	if (present & 0x008000)		in_uint16_le(s, os->cache_idx);	if (present & 0x010000)		in_uint16_le(s, os->unknown);	DEBUG(("TRIBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,id=%d,idx=%d,bs=%d,bg=0x%x,fg=0x%x)\n",	       os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id, os->cache_idx,	       os->brush.style, os->bgcolour, os->fgcolour));	bitmap = cache_get_bitmap(os->cache_id, os->cache_idx);	if (bitmap == NULL)		return;	ui_triblt(os->opcode, os->x, os->y, os->cx, os->cy,		  bitmap, os->srcx, os->srcy, &os->brush, os->bgcolour, os->fgcolour);}/* Process a polygon order */static voidprocess_polygon(STREAM s, POLYGON_ORDER * os, uint32 present, BOOL delta){	int index, data, next;	uint8 flags = 0;	POINT *points;	if (present & 0x01)		rdp_in_coord(s, &os->x, delta);	if (present & 0x02)		rdp_in_coord(s, &os->y, delta);	if (present & 0x04)		in_uint8(s, os->opcode);	if (present & 0x08)		in_uint8(s, os->fillmode);	if (present & 0x10)		rdp_in_colour(s, &os->fgcolour);	if (present & 0x20)		in_uint8(s, os->npoints);	if (present & 0x40)	{		in_uint8(s, os->datasize);		in_uint8a(s, os->data, os->datasize);	}	DEBUG(("POLYGON(x=%d,y=%d,op=0x%x,fm=%d,fg=0x%x,n=%d,sz=%d)\n",	       os->x, os->y, os->opcode, os->fillmode, os->fgcolour, os->npoints, os->datasize));	DEBUG(("Data: "));	for (index = 0; index < os->datasize; index++)		DEBUG(("%02x ", os->data[index]));	DEBUG(("\n"));	if (os->opcode < 0x01 || os->opcode > 0x10)	{		error("bad ROP2 0x%x\n", os->opcode);		return;	}	points = (POINT *) xmalloc((os->npoints + 1) * sizeof(POINT));	memset(points, 0, (os->npoints + 1) * sizeof(POINT));	points[0].x = os->x;	points[0].y = os->y;	index = 0;	data = ((os->npoints - 1) / 4) + 1;	for (next = 1; (next <= os->npoints) && (next < 256) && (data < os->datasize); next++)	{		if ((next - 1) % 4 == 0)			flags = os->data[index++];		if (~flags & 0x80)			points[next].x = parse_delta(os->data, &data);		if (~flags & 0x40)			points[next].y = parse_delta(os->data, &data);		flags <<= 2;	}	if (next - 1 == os->npoints)		ui_polygon(os->opcode - 1, os->fillmode, points, os->npoints + 1, NULL, 0,			   os->fgcolour);	else		error("polygon parse error\n");	xfree(points);}/* Process a polygon2 order */static voidprocess_polygon2(STREAM s, POLYGON2_ORDER * os, uint32 present, BOOL delta){	int index, data, next;	uint8 flags = 0;	POINT *points;	if (present & 0x0001)		rdp_in_coord(s, &os->x, delta);	if (present & 0x0002)		rdp_in_coord(s, &os->y, delta);	if (present & 0x0004)		in_uint8(s, os->opcode);	if (present & 0x0008)		in_uint8(s, os->fillmode);	if (present & 0x0010)		rdp_in_colour(s, &os->bgcolour);	if (present & 0x0020)		rdp_in_colour(s, &os->fgcolour);	rdp_parse_brush(s, &os->brush, present >> 6);	if (present & 0x0800)		in_uint8(s, os->npoints);	if (present & 0x1000)	{		in_uint8(s, os->datasize);		in_uint8a(s, os->data, os->datasize);	}	DEBUG(("POLYGON2(x=%d,y=%d,op=0x%x,fm=%d,bs=%d,bg=0x%x,fg=0x%x,n=%d,sz=%d)\n",	       os->x, os->y, os->opcode, os->fillmode, os->brush.style, os->bgcolour, os->fgcolour,	       os->npoints, os->datasize));	DEBUG(("Data: "));	for (index = 0; index < os->datasize; index++)		DEBUG(("%02x ", os->data[index]));	DEBUG(("\n"));	if (os->opcode < 0x01 || os->opcode > 0x10)	{		error("bad ROP2 0x%x\n", os->opcode);		return;	}	points = (POINT *) xmalloc((os->npoints + 1) * sizeof(POINT));	memset(points, 0, (os->npoints + 1) * sizeof(POINT));	points[0].x = os->x;	points[0].y = os->y;	index = 0;	data = ((os->npoints - 1) / 4) + 1;	for (next = 1; (next <= os->npoints) && (next < 256) && (data < os->datasize); next++)	{		if ((next - 1) % 4 == 0)			flags = os->data[index++];		if (~flags & 0x80)			points[next].x = parse_delta(os->data, &data);		if (~flags & 0x40)			points[next].y = parse_delta(os->data, &data);		flags <<= 2;	}	if (next - 1 == os->npoints)		ui_polygon(os->opcode - 1, os->fillmode, points, os->npoints + 1,			   &os->brush, os->bgcolour, os->fgcolour);	else		error("polygon2 parse error\n");	xfree(points);}/* Process a polyline order */static voidprocess_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, BOOL delta){	int index, next, data;	uint8 flags = 0;	PEN pen;	POINT *points;

⌨️ 快捷键说明

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