major work and login screen

ulab-original
jsorg71 20 years ago
parent 6560bcc78b
commit e856dc67ab

@ -1,9 +1,10 @@
XRDPOBJ = xrdp.o os_calls.o xrdp_tcp.o xrdp_iso.o xrdp_mcs.o xrdp_sec.o xrdp_rdp.o \
xrdp_process.o xrdp_listen.o
CFLAGS = -Wall -O2 -DXRDP_DEBUG
#CFLAGS = -Wall -O2
CC = g++
xrdp_process.o xrdp_listen.o xrdp_orders.o xrdp_bitmap.o xrdp_wm.o \
xrdp_painter.o xrdp_list.o xrdp_region.o xrdp_cache.o
#CFLAGS = -Wall -O2 -DXRDP_DEBUG
CFLAGS = -Wall -O2
CC = gcc
all: xrdp

@ -370,3 +370,30 @@
#define exDiscReasonLicenseErrClientEncryption 0x0108
#define exDiscReasonLicenseCantUpgradeLicense 0x0109
#define exDiscReasonLicenseNoRemoteConnections 0x010a
#define RDP_ORDER_STANDARD 0x01
#define RDP_ORDER_SECONDARY 0x02
#define RDP_ORDER_BOUNDS 0x04
#define RDP_ORDER_CHANGE 0x08
#define RDP_ORDER_DELTA 0x10
#define RDP_ORDER_LASTBOUNDS 0x20
#define RDP_ORDER_SMALL 0x40
#define RDP_ORDER_TINY 0x80
#define RDP_ORDER_DESTBLT 0
#define RDP_ORDER_PATBLT 1
#define RDP_ORDER_SCREENBLT 2
#define RDP_ORDER_LINE 9
#define RDP_ORDER_RECT 10
#define RDP_ORDER_DESKSAVE 11
#define RDP_ORDER_MEMBLT 13
#define RDP_ORDER_TRIBLT 14
#define RDP_ORDER_POLYLINE 22
#define RDP_ORDER_TEXT2 27
#define RDP_ORDER_RAW_BMPCACHE 0
#define RDP_ORDER_COLCACHE 1
#define RDP_ORDER_BMPCACHE 2
#define RDP_ORDER_FONTCACHE 3
#define RDP_ORDER_RAW_BMPCACHE2 4
#define RDP_ORDER_BMPCACHE2 5

@ -28,6 +28,7 @@
#include <stdio.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <openssl/rc4.h>
@ -35,11 +36,121 @@
#include <openssl/sha.h>
#include <openssl/bn.h>
#include "xrdp.h"
//#define MEMLEAK
static pthread_mutex_t g_term_mutex = PTHREAD_MUTEX_INITIALIZER;
static int g_term = 0;
#ifdef MEMLEAK
int g_memsize = 0;
int g_memid = 0;
struct xrdp_list* g_memlist = 0;
#endif
/*****************************************************************************/
int g_init_system(void)
{
#ifdef MEMLEAK
g_memlist = xrdp_list_create();
#endif
return 0;
}
/*****************************************************************************/
int g_exit_system(void)
{
#ifdef MEMLEAK
int i;
struct xrdp_mem* p;
for (i = 0; i < g_memlist->count; i++)
{
p = (struct xrdp_mem*)xrdp_list_get_item(g_memlist, i);
g_printf("leak size %d id %d\n\r", p->size, p->id);
}
g_printf("mem %d\n\r", g_memsize);
xrdp_list_delete(g_memlist);
g_memlist = 0;
#endif
return 0;
}
/*****************************************************************************/
void* g_malloc(int size, int zero)
{
#ifdef MEMLEAK
char* rv;
struct xrdp_mem* p;
rv = (char*)malloc(size + sizeof(struct xrdp_mem));
if (zero)
memset(rv, 0, size + sizeof(struct xrdp_mem));
g_memsize += size;
p = (struct xrdp_mem*)rv;
p->size = size;
p->id = g_memid;
if (g_memlist != 0)
xrdp_list_add_item(g_memlist, (int)p);
g_memid++;
return rv + sizeof(struct xrdp_mem);
#else
char* rv;
rv = (char*)malloc(size);
if (zero)
memset(rv, 0, size);
return rv;
#endif
}
/*****************************************************************************/
void* g_malloc1(int size, int zero)
{
char* rv;
rv = (char*)malloc(size);
if (zero)
memset(rv, 0, size);
return rv;
}
/*****************************************************************************/
void g_free(void* ptr)
{
#ifdef MEMLEAK
struct xrdp_mem* p;
int i;
if (ptr != 0)
{
p = (struct xrdp_mem*)(((char*)ptr) - sizeof(struct xrdp_mem));
g_memsize -= p->size;
i = xrdp_list_index_of(g_memlist, (int)p);
if (i >= 0)
xrdp_list_remove_item(g_memlist, i);
free(p);
}
#else
if (ptr != 0)
{
free(ptr);
}
#endif
}
/*****************************************************************************/
void g_printf(char *format, ...)
void g_free1(void* ptr)
{
if (ptr != 0)
{
free(ptr);
}
}
/*****************************************************************************/
void g_printf(char* format, ...)
{
va_list ap;
@ -77,24 +188,6 @@ void g_hexdump(char* p, int len)
}
}
/*****************************************************************************/
void* g_malloc(int size, int zero)
{
void* rv;
rv = malloc(size);
if (zero)
memset(rv, 0, size);
return rv;
}
/*****************************************************************************/
void g_free(void* ptr)
{
if (ptr != 0)
free(ptr);
}
/*****************************************************************************/
void g_memset(void* ptr, int val, int size)
{
@ -116,7 +209,13 @@ int g_getchar(void)
/*****************************************************************************/
int g_tcp_socket(void)
{
return socket(PF_INET, SOCK_STREAM, 0);
int rv;
int i;
i = 1;
rv = socket(PF_INET, SOCK_STREAM, 0);
setsockopt(rv, IPPROTO_TCP, TCP_NODELAY, (void*)&i, sizeof(i));
return rv;
}
/*****************************************************************************/
@ -187,10 +286,13 @@ int g_tcp_last_error_would_block(int sck)
int g_tcp_select(int sck)
{
fd_set rfds;
struct timeval time;
time.tv_sec = 0;
time.tv_usec = 0;
FD_ZERO(&rfds);
FD_SET(sck, &rfds);
return select(sck + 1, &rfds, 0, 0, 0);
return select(sck + 1, &rfds, 0, 0, &time);
}
/*****************************************************************************/
@ -359,3 +461,64 @@ void g_random(char* data, int len)
close(fd);
}
}
/*****************************************************************************/
int g_abs(int i)
{
return abs(i);
}
/*****************************************************************************/
int g_memcmp(void* s1, void* s2, int len)
{
return memcmp(s1, s2, len);
}
/*****************************************************************************/
int g_file_open(char* file_name)
{
return open(file_name, O_RDWR | O_CREAT);
}
/*****************************************************************************/
int g_file_close(int fd)
{
close(fd);
return 0;
}
/*****************************************************************************/
/* read from file*/
int g_file_read(int fd, char* ptr, int len)
{
return read(fd, ptr, len);
}
/*****************************************************************************/
/* write to file */
int g_file_write(int fd, char* ptr, int len)
{
return write(fd, ptr, len);
}
/*****************************************************************************/
/* move file pointer */
int g_file_seek(int fd, int offset)
{
return lseek(fd, offset, SEEK_SET);
}
/*****************************************************************************/
/* do a write lock on a file */
int g_file_lock(int fd, int start, int len)
{
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = start;
lock.l_len = len;
if (fcntl(fd, F_SETLK, &lock) == -1)
return 0;
return 1;
}

@ -77,6 +77,12 @@ struct stream
s->p++; \
}
#define in_sint16_le(s, v) \
{ \
v = *((signed short*)(s->p)); \
s->p += 2; \
}
#define in_uint16_le(s, v) \
{ \
v = *((unsigned short*)(s->p)); \

@ -39,6 +39,7 @@ int main(int argc, char** argv)
{
int rv;
g_init_system();
rv = 0;
g_listen = xrdp_listen_create();
if (g_thread_create(xrdp_listen_run, 0) == 0)
@ -51,5 +52,6 @@ int main(int argc, char** argv)
else
rv = 1;
xrdp_listen_delete(g_listen);
g_exit_system();
return rv;
}

@ -29,11 +29,21 @@
#define DEBUG(args)
#endif
#define MIN(x, x1, x2) x = (x1) < (x2) ? (x1) : (x2)
#define MAX(x, x1, x2) x = (x1) > (x2) ? (x1) : (x2)
#define HIWORD(out, in) out = ((in) & 0xffff0000) >> 16
#define LOWORD(out, in) out = (in) & 0x0000ffff
#define MAKELONG(out, hi, lo) out = (((hi) << 16) || (lo))
/* os_calls.c */
int g_init_system(void);
int g_exit_system(void);
void g_printf(char *format, ...);
void g_hexdump(char* p, int len);
void* g_malloc(int size, int zero);
void* g_malloc1(int size, int zero);
void g_free(void* ptr);
void g_free1(void* ptr);
void g_memset(void* ptr, int val, int size);
void g_memcpy(void* d_ptr, const void* s_ptr, int size);
int g_getchar(void);
@ -67,6 +77,14 @@ void g_md5_transform(void* md5_info, char* data, int len);
void g_md5_complete(void* md5_info, char* data);
int g_mod_exp(char* out, char* in, char* mod, char* exp);
void g_random(char* data, int len);
int g_abs(int i);
int g_memcmp(void* s1, void* s2, int len);
int g_file_open(char* file_name);
int g_file_close(int fd);
int g_file_read(int fd, char* ptr, int len);
int g_file_write(int fd, char* ptr, int len);
int g_file_seek(int fd, int offset);
int g_file_lock(int fd, int start, int len);
/* xrdp_tcp.c */
struct xrdp_tcp* xrdp_tcp_create(struct xrdp_iso* owner);
@ -87,18 +105,20 @@ int xrdp_iso_incoming(struct xrdp_iso* self);
struct xrdp_mcs* xrdp_mcs_create(struct xrdp_sec* owner);
void xrdp_mcs_delete(struct xrdp_mcs* self);
int xrdp_mcs_init(struct xrdp_mcs* self, int len);
int xrdp_mcs_recv(struct xrdp_mcs* self);
int xrdp_mcs_recv(struct xrdp_mcs* self, int* chan);
int xrdp_mcs_send(struct xrdp_mcs* self);
int xrdp_mcs_incoming(struct xrdp_mcs* self);
int xrdp_mcs_disconnect(struct xrdp_mcs* self);
/* xrdp_sec.c */
struct xrdp_sec* xrdp_sec_create(struct xrdp_rdp* owner);
void xrdp_sec_delete(struct xrdp_sec* self);
int xrdp_sec_init(struct xrdp_sec* self, int len);
int xrdp_sec_recv(struct xrdp_sec* self);
int xrdp_sec_recv(struct xrdp_sec* self, int* chan);
int xrdp_sec_send(struct xrdp_sec* self, int flags);
int xrdp_rdp_send_data(struct xrdp_rdp* self, int data_pdu_type);
int xrdp_sec_incoming(struct xrdp_sec* self);
int xrdp_sec_disconnect(struct xrdp_sec* self);
/* xrdp_rdp.c */
struct xrdp_rdp* xrdp_rdp_create(struct xrdp_process* owner);
@ -111,6 +131,68 @@ int xrdp_rdp_incoming(struct xrdp_rdp* self);
int xrdp_rdp_send_demand_active(struct xrdp_rdp* self);
int xrdp_rdp_process_confirm_active(struct xrdp_rdp* self);
int xrdp_rdp_process_data(struct xrdp_rdp* self);
int xrdp_rdp_disconnect(struct xrdp_rdp* self);
/* xrdp_orders.c */
struct xrdp_orders* xrdp_orders_create(struct xrdp_process* owner);
void xrdp_orders_delete(struct xrdp_orders* self);
int xrdp_orders_init(struct xrdp_orders* self);
int xrdp_orders_send(struct xrdp_orders* self);
int xrdp_orders_rect(struct xrdp_orders* self, int x, int y, int cx, int cy,
int color, struct xrdp_rect* rect);
int xrdp_orders_screen_blt(struct xrdp_orders* self, int x, int y,
int cx, int cy, int srcx, int srcy,
int rop, struct xrdp_rect* rect);
int xrdp_orders_pat_blt(struct xrdp_orders* self, int x, int y,
int cx, int cy, int rop, int bg_color,
int fg_color, struct xrdp_brush* brush,
struct xrdp_rect* rect);
int xrdp_orders_dest_blt(struct xrdp_orders* self, int x, int y,
int cx, int cy, int rop,
struct xrdp_rect* rect);
int xrdp_orders_line(struct xrdp_orders* self, int mix_mode,
int startx, int starty,
int endx, int endy, int rop, int bg_color,
struct xrdp_pen* pen,
struct xrdp_rect* rect);
int xrdp_orders_mem_blt(struct xrdp_orders* self, int cache_id,
int color_table, int x, int y, int cx, int cy,
int rop, int srcx, int srcy,
int cache_idx, struct xrdp_rect* rect);
int xrdp_orders_send_palette(struct xrdp_orders* self, int* palette,
int cache_id);
int xrdp_orders_send_raw_bitmap(struct xrdp_orders* self,
struct xrdp_bitmap* bitmap,
int cache_id, int cache_idx);
/* xrdp_cache.c */
struct xrdp_cache* xrdp_cache_create(struct xrdp_wm* owner,
struct xrdp_orders* orders);
void xrdp_cache_delete(struct xrdp_cache* self);
int xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap);
int xrdp_cache_add_palette(struct xrdp_cache* self, int* palette);
/* xrdp_wm.c */
struct xrdp_wm* xrdp_wm_create(struct xrdp_process* owner);
void xrdp_wm_delete(struct xrdp_wm* self);
int xrdp_wm_send_palette(struct xrdp_wm* self);
int xrdp_wm_init(struct xrdp_wm* self);
int xrdp_wm_send_bitmap(struct xrdp_wm* self, struct xrdp_bitmap* bitmap,
int x, int y, int cx, int cy);
int xrdp_wm_get_vis_region(struct xrdp_wm* self, struct xrdp_bitmap* bitmap,
int x, int y, int cx, int cy,
struct xrdp_region* region);
int xrdp_wm_mouse_move(struct xrdp_wm* self, int x, int y);
int xrdp_wm_mouse_click(struct xrdp_wm* self, int x, int y, int but, int down);
int xrdp_wm_rect(struct xrdp_rect* r, int x, int y, int cx, int cy);
int xrdp_wm_rect_is_empty(struct xrdp_rect* in);
int xrdp_wm_rect_contains_pt(struct xrdp_rect* in, int x, int y);
int xrdp_wm_rect_intersect(struct xrdp_rect* in1, struct xrdp_rect* in2,
struct xrdp_rect* out);
int xrdp_wm_rect_offset(struct xrdp_rect* in, int dx, int dy);
int xrdp_wm_color15(int r, int g, int b);
int xrdp_wm_color16(int r, int g, int b);
int xrdp_wm_color24(int r, int g, int b);
/* xrdp_process.c */
struct xrdp_process* xrdp_process_create(struct xrdp_listen* owner);
@ -120,4 +202,58 @@ int xrdp_process_main_loop(struct xrdp_process* self);
/* xrdp_listen.c */
struct xrdp_listen* xrdp_listen_create(void);
void xrdp_listen_delete(struct xrdp_listen* self);
int xrdp_listen_delete_pro(struct xrdp_listen* self, struct xrdp_process* pro);
int xrdp_listen_main_loop(struct xrdp_listen* self);
/* xrdp_region.c */
struct xrdp_region* xrdp_region_create(struct xrdp_wm* wm);
void xrdp_region_delete(struct xrdp_region* self);
int xrdp_region_add_rect(struct xrdp_region* self, struct xrdp_rect* rect);
int xrdp_region_insert_rect(struct xrdp_region* self, int i, int left,
int top, int right, int bottom);
int xrdp_region_subtract_rect(struct xrdp_region* self,
struct xrdp_rect* rect);
int xrdp_region_get_rect(struct xrdp_region* self, int index,
struct xrdp_rect* rect);
/* xrdp_bitmap.c */
struct xrdp_bitmap* xrdp_bitmap_create(int width, int height, int bpp,
int type);
void xrdp_bitmap_delete(struct xrdp_bitmap* self);
int xrdp_bitmap_set_focus(struct xrdp_bitmap* self, int focused);
int xrdp_bitmap_load(struct xrdp_bitmap* self, char* filename, int* palette);
int xrdp_bitmap_get_pixel(struct xrdp_bitmap* self, int x, int y);
int xrdp_bitmap_set_pixel(struct xrdp_bitmap* self, int x, int y, int pixel);
int xrdp_bitmap_copy_box(struct xrdp_bitmap* self, struct xrdp_bitmap* dest,
int x, int y, int cx, int cy);
int xrdp_bitmap_compare(struct xrdp_bitmap* self, struct xrdp_bitmap* b);
int xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect);
/* xrdp_painter.c */
struct xrdp_painter* xrdp_painter_create(struct xrdp_wm* wn);
void xrdp_painter_delete(struct xrdp_painter* self);
int xrdp_painter_begin_update(struct xrdp_painter* self);
int xrdp_painter_end_update(struct xrdp_painter* self);
int xrdp_painter_set_clip(struct xrdp_painter* self,
int x, int y, int cx, int cy);
int xrdp_painter_clr_clip(struct xrdp_painter* self);
int xrdp_painter_fill_rect(struct xrdp_painter* self,
struct xrdp_bitmap* bitmap,
int x, int y, int cx, int cy);
int xrdp_painter_fill_rect2(struct xrdp_painter* self,
struct xrdp_bitmap* bitmap,
int x, int y, int cx, int cy);
int xrdp_painter_draw_bitmap(struct xrdp_painter* self,
struct xrdp_bitmap* bitmap,
struct xrdp_bitmap* to_draw,
int x, int y, int cx, int cy);
/* xrdp_list.c */
struct xrdp_list* xrdp_list_create(void);
void xrdp_list_delete(struct xrdp_list* self);
void xrdp_list_add_item(struct xrdp_list* self, int item);
int xrdp_list_get_item(struct xrdp_list* self, int index);
void xrdp_list_clear(struct xrdp_list* self);
int xrdp_list_index_of(struct xrdp_list* self, int item);
void xrdp_list_remove_item(struct xrdp_list* self, int index);
void xrdp_list_insert_item(struct xrdp_list* self, int index, int item);

@ -0,0 +1,479 @@
/*
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.
Copyright (C) Jay Sorg 2004
bitmap, drawable
*/
#include "xrdp.h"
/*****************************************************************************/
struct xrdp_bitmap* xrdp_bitmap_create(int width, int height, int bpp,
int type)
{
struct xrdp_bitmap* self;
int Bpp;
self = (struct xrdp_bitmap*)g_malloc(sizeof(struct xrdp_bitmap), 1);
self->type = type;
self->width = width;
self->height = height;
self->bpp = bpp;
Bpp = 4;
switch (bpp)
{
case 8: Bpp = 1; break;
case 15: Bpp = 2; break;
case 16: Bpp = 2; break;
}
self->data = (char*)g_malloc(width * height * Bpp, 1);
self->child_list = xrdp_list_create();
self->line_size = ((width + 3) & ~3) * Bpp;
return self;
}
/*****************************************************************************/
void xrdp_bitmap_delete(struct xrdp_bitmap* self)
{
int i;
if (self == 0)
return;
if (self->wm != 0)
{
if (self->wm->focused_window == self)
self->wm->focused_window = 0;
if (self->wm->dragging_window == self)
self->wm->dragging_window = 0;
if (self->wm->button_down == self)
self->wm->button_down = 0;
}
for (i = 0; i < self->child_list->count; i++)
xrdp_bitmap_delete((struct xrdp_bitmap*)self->child_list->items[i]);
xrdp_list_delete(self->child_list);
g_free(self->data);
g_free(self);
}
/*****************************************************************************/
int xrdp_bitmap_set_focus(struct xrdp_bitmap* self, int focused)
{
struct xrdp_painter* painter;
if (self == 0)
return 0;
if (self->type != 1)
return 0;
self->focused = focused;
painter = xrdp_painter_create(self->wm);
xrdp_painter_begin_update(painter);
if (focused)
{
/* active title bar */
painter->fg_color = self->wm->blue;
xrdp_painter_fill_rect(painter, self, 3, 3, self->width - 5, 18);
}
else
{
/* inactive title bar */
painter->fg_color = self->wm->dark_grey;
xrdp_painter_fill_rect(painter, self, 3, 3, self->width - 5, 18);
}
DEBUG(("1\n\r"));
xrdp_painter_end_update(painter);
DEBUG(("2\n\r"));
xrdp_painter_delete(painter);
DEBUG(("3\n\r"));
return 0;
}
/*****************************************************************************/
int xrdp_bitmap_get_index(struct xrdp_bitmap* self, int* palette, int color)
{
int i;
for (i = 0; i < 256; i++)
{
if (color == palette[i])
return i;
}
for (i = 1; i < 256; i++)
{
if (palette[i] == 0)
{
palette[i] = color;
return i;
}
}
g_printf("color %8.8x not found\n", color);
return 255;
}
/*****************************************************************************/
int xrdp_bitmap_resize(struct xrdp_bitmap* self, int width, int height)
{
int Bpp;
g_free(self->data);
self->width = width;
self->height = height;
Bpp = 4;
switch (self->bpp)
{
case 8: Bpp = 1; break;
case 15: Bpp = 2; break;
case 16: Bpp = 2; break;
}
self->data = (char*)g_malloc(width * height * Bpp, 1);
self->line_size = ((width + 3) & ~3) * Bpp;
return 0;
}
/*****************************************************************************/
/* load a bmp file */
/* return 0 ok */
/* return 1 error */
int xrdp_bitmap_load(struct xrdp_bitmap* self, char* filename, int* palette)
{
int fd;
int i;
int j;
int k;
int color;
int size;
int palette1[256];
char type1[3];
char* data;
struct xrdp_bmp_header header;
fd = g_file_open(filename);
if (fd != -1)
{
/* read file type */
if (g_file_read(fd, type1, 2) != 2)
{
g_file_close(fd);
return 1;
}
if (type1[0] != 'B' || type1[1] != 'M')
{
g_file_close(fd);
return 1;
}
/* read file size */
size = 0;
g_file_read(fd, (char*)&size, 4);
/* read bmp header */
g_file_seek(fd, 14);
g_file_read(fd, (char*)&header, sizeof(header));
if (header.bit_count != 8 && header.bit_count != 24)
{
g_file_close(fd);
return 1;
}
if (header.bit_count == 24) /* 24 bit bitmap */
{
g_file_seek(fd, 14 + header.size);
}
if (header.bit_count == 8) /* 8 bit bitmap */
{
/* read palette */
g_file_seek(fd, 14 + header.size);
g_file_read(fd, (char*)palette1, 256 * sizeof(int));
/* read data */
xrdp_bitmap_resize(self, header.image_width, header.image_height);
data = (char*)g_malloc(header.image_width * header.image_height, 1);
for (i = header.image_height - 1; i >= 0; i--)
g_file_read(fd, data + i * header.image_width, header.image_width);
for (i = 0; i < self->height; i++)
{
for (j = 0; j < self->width; j++)
{
k = (unsigned char)data[i * header.image_width + j];
color = palette1[k];
if (self->bpp == 8)
color = xrdp_bitmap_get_index(self, palette, color);
else if (self->bpp == 15)
color = xrdp_wm_color15((color & 0xff0000) >> 16,
(color & 0x00ff00) >> 8,
(color & 0x0000ff) >> 0);
else if (self->bpp == 16)
color = xrdp_wm_color16((color & 0xff0000) >> 16,
(color & 0x00ff00) >> 8,
(color & 0x0000ff) >> 0);
else if (self->bpp == 24)
color = xrdp_wm_color24((color & 0xff0000) >> 16,
(color & 0x00ff00) >> 8,
(color & 0x0000ff) >> 0);
xrdp_bitmap_set_pixel(self, j, i, color);
}
}
g_free(data);
}
g_file_close(fd);
}
return 0;
}
/*****************************************************************************/
int xrdp_bitmap_get_pixel(struct xrdp_bitmap* self, int x, int y)
{
if (self == 0)
return 0;
if (self->data == 0)
return 0;
if (x >= 0 && x < self->width && y >= 0 && y < self->height)
{
if (self->bpp == 8)
return self->data[y * self->width + x];
else if (self->bpp == 15 || self->bpp == 16)
return ((short*)self->data)[y * self->width + x];
else if (self->bpp == 24)
return ((int*)self->data)[y * self->width + x];
}
return 0;
}
/*****************************************************************************/
int xrdp_bitmap_set_pixel(struct xrdp_bitmap* self, int x, int y, int pixel)
{
if (x >= 0 && x < self->width && y >= 0 && y < self->height)
{
if (self->bpp == 8)
self->data[y * self->width + x] = pixel;
else if (self->bpp == 15 || self->bpp == 16)
((short*)(self->data))[y * self->width + x] = pixel;
else if (self->bpp == 24)
((int*)(self->data))[y * self->width + x] = pixel;
}
return 0;
}
/*****************************************************************************/
int xrdp_bitmap_copy_box(struct xrdp_bitmap* self, struct xrdp_bitmap* dest,
int x, int y, int cx, int cy)
{
int i;
int j;
if (self == 0)
return 0;
if (dest == 0)
return 0;
if (self->bpp != dest->bpp)
return 0;
for (i = 0; i < cy; i++)
{
for (j = 0; j < cx; j++)
{
xrdp_bitmap_set_pixel(dest, j, i,
xrdp_bitmap_get_pixel(self, j + x, i + y));
}
}
return 0;
}
/*****************************************************************************/
int xrdp_bitmap_compare(struct xrdp_bitmap* self, struct xrdp_bitmap* b)
{
if (self == 0)
return 0;
if (b == 0)
return 0;
if (self->bpp != b->bpp)
return 0;
if (self->width != b->width)
return 0;
if (self->height != b->height)
return 0;
if (g_memcmp(self->data, b->data, b->height * b->line_size) == 0)
return 1;
return 0;
}
/*****************************************************************************/
/* nil for rect means the whole thing */
int xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect)
{
int i;
struct xrdp_bitmap* b;
struct xrdp_rect r1;
struct xrdp_rect r2;
struct xrdp_painter* painter;
if (self == 0) /* if no bitmap */
return 0;
if (self->type == 0) /* if bitmap, leave */
return 0;
painter = xrdp_painter_create(self->wm);
painter->rop = 0xcc; /* copy */
if (rect == 0)
painter->use_clip = 0;
else
{
if (xrdp_wm_rect_is_empty(rect))
{
xrdp_painter_delete(painter);
return 0;
}
painter->clip = *rect;
painter->use_clip = 1;
}
xrdp_painter_begin_update(painter);
if (self->type == 1) /* normal window */
{
/* draw grey background */
painter->fg_color = self->bg_color;
xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height);
/* top white line */
painter->fg_color = self->wm->white;
xrdp_painter_fill_rect(painter, self, 1, 1, self->width - 2, 1);
/* left white line */
painter->fg_color = self->wm->white;
xrdp_painter_fill_rect(painter, self, 1, 1, 1, self->height - 2);
/* bottom dark grey line */
painter->fg_color = self->wm->dark_grey;
xrdp_painter_fill_rect(painter, self, 1, self->height - 2,
self->width - 2, 1);
/* right dark grey line */
painter->fg_color = self->wm->dark_grey;
xrdp_painter_fill_rect(painter, self, self->width - 2, 1, 1,
self->height - 2);
/* bottom black line */
painter->fg_color = self->wm->black;
xrdp_painter_fill_rect(painter, self, 0, self->height - 1,
self->width, 1);
/* right black line */
painter->fg_color = self->wm->black;
xrdp_painter_fill_rect(painter, self, self->width - 1, 0,
1, self->height);
if (self->focused)
{
/* active title bar */
painter->fg_color = self->wm->blue;
xrdp_painter_fill_rect(painter, self, 3, 3, self->width - 5, 18);
}
else
{
/* inactive title bar */
painter->fg_color = self->wm->dark_grey;
xrdp_painter_fill_rect(painter, self, 3, 3, self->width - 5, 18);
}
}
else if (self->type == 2) /* screen */
{
painter->fg_color = self->bg_color;
xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height);
}
else if (self->type == 3) /* button */
{
if (self->state == 0) /* button up */
{
/* gray box */
painter->fg_color = self->wm->grey;
xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height);
/* white top line */
painter->fg_color = self->wm->white;
xrdp_painter_fill_rect(painter, self, 0, 0, self->width, 1);
/* white left line */
painter->fg_color = self->wm->white;
xrdp_painter_fill_rect(painter, self, 0, 0, 1, self->height);
/* dark grey bottom line */
painter->fg_color = self->wm->dark_grey;
xrdp_painter_fill_rect(painter, self, 1, self->height - 2,
self->width - 1, 1);
/* dark grey right line */
painter->fg_color = self->wm->dark_grey;
xrdp_painter_fill_rect(painter, self, self->width - 2, 1,
1, self->height - 1);
/* black bottom line */
painter->fg_color = self->wm->black;
xrdp_painter_fill_rect(painter, self, 0, self->height - 1, self->width, 1);
/* black right line */
painter->fg_color = self->wm->black;
xrdp_painter_fill_rect(painter, self, self->width - 1, 0, 1, self->height);
}
else if (self->state == 1) /* button down */
{
/* black top line */
painter->fg_color = self->wm->black;
xrdp_painter_fill_rect(painter, self, 0, 0, self->width, 1);
/* black left line */
painter->fg_color = self->wm->black;
xrdp_painter_fill_rect(painter, self, 0, 0, 1, self->height);
/* dark grey top line */
painter->fg_color = self->wm->dark_grey;
xrdp_painter_fill_rect(painter, self, 1, 1, self->width - 2, 1);
/* dark grey left line */
painter->fg_color = self->wm->dark_grey;
xrdp_painter_fill_rect(painter, self, 1, 1, 1, self->height - 2);
}
}
else if (self->type == 4) /* image */
{
xrdp_painter_draw_bitmap(painter, self, self, 0, 0, self->width,
self->height);
}
else if (self->type == 5) /* edit */
{
/* draw gray box */
painter->fg_color = self->wm->grey;
xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height);
/* main white background */
painter->fg_color = self->wm->white;
xrdp_painter_fill_rect(painter, self, 1, 1, self->width - 3,
self->height - 3);
/* dark grey top line */
painter->fg_color = self->wm->dark_grey;
xrdp_painter_fill_rect(painter, self, 0, 0, self->width, 1);
/* dark grey left line */
painter->fg_color = self->wm->dark_grey;
xrdp_painter_fill_rect(painter, self, 0, 0, 1, self->height);
/* white bottom line */
painter->fg_color = self->wm->white;
xrdp_painter_fill_rect(painter, self, 0, self->height- 1, self->width, 1);
/* white right line */
painter->fg_color = self->wm->white;
xrdp_painter_fill_rect(painter, self, self->width - 1, 0, 1, self->height);
/* black left line */
painter->fg_color = self->wm->black;
xrdp_painter_fill_rect(painter, self, 1, 1, 1, self->height - 2);
/* black top line */
painter->fg_color = self->wm->black;
xrdp_painter_fill_rect(painter, self, 1, 1, self->width - 2, 1);
}
/* draw any child windows in the area */
for (i = 0; i < self->child_list->count; i++)
{
b = (struct xrdp_bitmap*)xrdp_list_get_item(self->child_list, i);
if (rect == 0)
xrdp_bitmap_invalidate(b, 0);
else
{
xrdp_wm_rect(&r1, b->left, b->top, b->width, b->height);
if (xrdp_wm_rect_intersect(rect, &r1, &r2))
{
xrdp_wm_rect_offset(&r2, -(b->left), -(b->top));
xrdp_bitmap_invalidate(b, &r2);
}
}
}
xrdp_painter_end_update(painter);
xrdp_painter_delete(painter);
return 0;
}

@ -0,0 +1,145 @@
/*
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.
Copyright (C) Jay Sorg 2004
cache
*/
#include "xrdp.h"
/*****************************************************************************/
struct xrdp_cache* xrdp_cache_create(struct xrdp_wm* owner,
struct xrdp_orders* orders)
{
struct xrdp_cache* self;
self = (struct xrdp_cache*)g_malloc(sizeof(struct xrdp_cache), 1);
self->wm = owner;
self->orders = orders;
return self;
}
/*****************************************************************************/
void xrdp_cache_delete(struct xrdp_cache* self)
{
int i;
int j;
if (self == 0)
return;
/* free all the cached bitmaps */
for (i = 0; i < 3; i++)
for (j = 0; j < 600; j++)
xrdp_bitmap_delete(self->bitmap_items[i][j].bitmap);
g_free(self);
}
/*****************************************************************************/
/* returns cache id */
int xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap)
{
int i;
int j;
int min_use;
int min_use_index1;
int min_use_index2;
struct xrdp_bitmap* b;
/* look for match */
for (i = 0; i < 3; i++)
{
for (j = 0; j < 600; j++)
{
if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap))
{
self->bitmap_items[i][j].use_count++;
DEBUG(("found bitmap at %d %d\n", i, j));
return (i << 16) | j;
}
}
}
/* look for least used */
min_use_index1 = 0;
min_use_index2 = 0;
min_use = 999999;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 600; j++)
{
if (self->bitmap_items[i][j].use_count < min_use)
{
min_use = self->bitmap_items[i][j].use_count;
min_use_index1 = i;
min_use_index2 = j;
}
}
}
DEBUG(("adding bitmap at %d %d\n", min_use_index1, min_use_index2));
/* set, send bitmap and return */
xrdp_bitmap_delete(self->bitmap_items[min_use_index1]
[min_use_index2].bitmap);
b = xrdp_bitmap_create(bitmap->width, bitmap->height, bitmap->bpp, 0);
xrdp_bitmap_copy_box(bitmap, b, 0, 0, bitmap->width, bitmap->height);
self->bitmap_items[min_use_index1][min_use_index2].bitmap = b;
self->bitmap_items[min_use_index1][min_use_index2].use_count++;
xrdp_orders_send_raw_bitmap(self->orders, b, min_use_index1,
min_use_index2);
return (min_use_index1 << 16) | min_use_index2;
}
/*****************************************************************************/
int xrdp_cache_add_palette(struct xrdp_cache* self, int* palette)
{
int i;
int min_use;
int min_use_index;
if (self == 0)
return 0;
if (palette == 0)
return 0;
if (self->wm->screen->bpp > 8)
return 0;
/* look for match */
for (i = 0; i < 6; i++)
{
if (g_memcmp(palette, self->palette_items[i].palette,
256 * sizeof(int)) == 0)
{
self->palette_items[i].use_count++;
return i;
}
}
/* look for least used */
min_use_index = 0;
min_use = 999999;
for (i = 0; i < 6; i++)
{
if (self->palette_items[i].use_count < min_use)
{
min_use = self->palette_items[i].use_count;
min_use_index = i;
}
}
/* set, send palette and return */
g_memcpy(self->palette_items[min_use_index].palette, palette,
256 * sizeof(int));
self->palette_items[min_use_index].use_count++;
xrdp_orders_send_palette(self->orders, palette, min_use_index);
return min_use_index;
}

@ -37,6 +37,8 @@ struct xrdp_iso* xrdp_iso_create(struct xrdp_mcs* owner)
/*****************************************************************************/
void xrdp_iso_delete(struct xrdp_iso* self)
{
if (self == 0)
return;
xrdp_tcp_delete(self->tcp_layer);
g_free(self);
}
@ -137,6 +139,7 @@ int xrdp_iso_send(struct xrdp_iso* self)
{
int len;
DEBUG((" in xrdp_iso_send\n\r"));
s_pop_layer(self->out_s, iso_hdr);
len = self->out_s->end - self->out_s->p;
out_uint8(self->out_s, 3);
@ -147,5 +150,6 @@ int xrdp_iso_send(struct xrdp_iso* self)
out_uint8(self->out_s, 0x80);
if (xrdp_tcp_send(self->tcp_layer) != 0)
return 1;
DEBUG((" out xrdp_iso_send\n\r"));
return 0;
}

@ -0,0 +1,149 @@
/*
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.
Copyright (C) Jay Sorg 2004
simple list
this list is used to track mem leaks so g_malloc1 and
g_free1 should be used for internal allocs but not
for auto_free items
*/
#include "xrdp.h"
/*****************************************************************************/
struct xrdp_list* xrdp_list_create(void)
{
struct xrdp_list* self;
self = (struct xrdp_list*)g_malloc1(sizeof(struct xrdp_list), 1);
self->grow_by = 10;
self->alloc_size = 10;
self->items = (int*)g_malloc1(sizeof(int) * 10, 1);
return self;
}
/*****************************************************************************/
void xrdp_list_delete(struct xrdp_list* self)
{
int i;
if (self == 0)
return;
if (self->auto_free)
for (i = 0; i < self->count; i++)
g_free((void*)self->items[i]);
g_free1(self->items);
g_free1(self);
}
/*****************************************************************************/
void xrdp_list_add_item(struct xrdp_list* self, int item)
{
int* p;
int i;
if (self->count >= self->alloc_size)
{
i = self->alloc_size;
self->alloc_size += self->grow_by;
p = (int*)g_malloc1(sizeof(int) * self->alloc_size, 1);
g_memcpy(p, self->items, sizeof(int) * i);
g_free1(self->items);
self->items = p;
}
self->items[self->count] = item;
self->count++;
}
/*****************************************************************************/
int xrdp_list_get_item(struct xrdp_list* self, int index)
{
if (index < 0 || index >= self->count)
return 0;
return self->items[index];
}
/*****************************************************************************/
void xrdp_list_clear(struct xrdp_list* self)
{
int i;
if (self->auto_free)
for (i = 0; i < self->count; i++)
g_free((void*)self->items[i]);
g_free1(self->items);
self->count = 0;
self->grow_by = 10;
self->alloc_size = 10;
self->items = (int*)g_malloc1(sizeof(int) * 10, 1);
}
/*****************************************************************************/
int xrdp_list_index_of(struct xrdp_list* self, int item)
{
int i;
for (i = 0; i < self->count; i++)
if (self->items[i] == item)
return i;
return -1;
}
/*****************************************************************************/
void xrdp_list_remove_item(struct xrdp_list* self, int index)
{
int i;
if (index >= 0 && index < self->count)
{
if (self->auto_free)
g_free((void*)self->items[index]);
for (i = index; i < (self->count - 1); i++)
self->items[i] = self->items[i + 1];
self->count--;
}
}
/*****************************************************************************/
void xrdp_list_insert_item(struct xrdp_list* self, int index, int item)
{
int* p;
int i;
if (index == self->count)
{
xrdp_list_add_item(self, item);
return;
}
if (index >= 0 && index < self->count)
{
self->count++;
if (self->count > self->alloc_size)
{
i = self->alloc_size;
self->alloc_size += self->grow_by;
p = (int*)g_malloc1(sizeof(int) * self->alloc_size, 1);
g_memcpy(p, self->items, sizeof(int) * i);
g_free1(self->items);
self->items = p;
}
for (i = (self->count - 2); i >= index; i--)
self->items[i + 1] = self->items[i];
self->items[index] = item;
}
}

@ -76,6 +76,7 @@ int xrdp_listen_add_pro(struct xrdp_listen* self)
return 0;
}
/* add process in unused slot */
/* this shouldn't happen */
if (self->process_list[i]->status <= 0)
{
xrdp_process_delete(self->process_list[i]);
@ -86,6 +87,24 @@ int xrdp_listen_add_pro(struct xrdp_listen* self)
return 1;
}
/*****************************************************************************/
int xrdp_listen_delete_pro(struct xrdp_listen* self, struct xrdp_process* pro)
{
int i;
for (i = 0; i < self->process_list_max; i++)
{
if (self->process_list[i] == pro)
{
DEBUG(("process deleted\n\r"));
xrdp_process_delete(pro);
self->process_list[i] = 0;
return 0;
}
}
return 0;
}
/*****************************************************************************/
/* i can't get stupid in_val to work, hum using global var for now */
void* xrdp_process_run(void* in_val)
@ -131,6 +150,10 @@ int xrdp_listen_main_loop(struct xrdp_listen* self)
}
}
}
else
{
DEBUG(("error, listener done\n\r"));
}
xrdp_listen_term_processes(self);
g_tcp_close(self->sck);
self->status = -1;

@ -41,6 +41,8 @@ struct xrdp_mcs* xrdp_mcs_create(struct xrdp_sec* owner)
/*****************************************************************************/
void xrdp_mcs_delete(struct xrdp_mcs* self)
{
if (self == 0)
return;
xrdp_iso_delete(self->iso_layer);
g_free(self);
}
@ -64,7 +66,7 @@ int xrdp_mcs_send_cjcf(struct xrdp_mcs* self, int chanid)
/*****************************************************************************/
/* returns error */
int xrdp_mcs_recv(struct xrdp_mcs* self)
int xrdp_mcs_recv(struct xrdp_mcs* self, int* chan)
{
int appid;
int opcode;
@ -91,7 +93,9 @@ int xrdp_mcs_recv(struct xrdp_mcs* self)
DEBUG((" out xrdp_mcs_recv err got 0x%x need MCS_SDRQ\n\r", appid));
return 1;
}
in_uint8s(self->in_s, 5);
in_uint8s(self->in_s, 2);
in_uint16_be(self->in_s, *chan);
in_uint8s(self->in_s, 1);
in_uint8(self->in_s, len);
if (len & 0x80)
in_uint8s(self->in_s, 1);
@ -407,6 +411,7 @@ int xrdp_mcs_send(struct xrdp_mcs* self)
{
int len;
DEBUG((" in xrdp_mcs_send\n\r"));
s_pop_layer(self->out_s, mcs_hdr);
len = (self->out_s->end - self->out_s->p) - 8;
len = len | 0x8000;
@ -415,6 +420,28 @@ int xrdp_mcs_send(struct xrdp_mcs* self)
out_uint16_be(self->out_s, MCS_GLOBAL_CHANNEL);
out_uint8(self->out_s, 0x70);
out_uint16_be(self->out_s, len);
if (xrdp_iso_send(self->iso_layer) != 0)
return 1;
DEBUG((" out xrdp_mcs_send\n\r"));
return 0;
}
/*****************************************************************************/
/* returns error */
int xrdp_mcs_disconnect(struct xrdp_mcs* self)
{
int len;
xrdp_mcs_init(self, 100);
s_mark_end(self->out_s);
s_pop_layer(self->out_s, mcs_hdr);
len = (self->out_s->end - self->out_s->p) - 8;
len = len | 0x8000;
out_uint8(self->out_s, MCS_DPUM << 2);
out_uint16_be(self->out_s, self->userid);
out_uint16_be(self->out_s, MCS_GLOBAL_CHANNEL);
out_uint8(self->out_s, 0x70);
out_uint16_be(self->out_s, len);
if (xrdp_iso_send(self->iso_layer) != 0)
return 1;
return 0;

@ -0,0 +1,976 @@
/*
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.
Copyright (C) Jay Sorg 2004
orders
*/
#include "xrdp.h"
/*****************************************************************************/
struct xrdp_orders* xrdp_orders_create(struct xrdp_process* owner)
{
struct xrdp_orders* self;
self = (struct xrdp_orders*)g_malloc(sizeof(struct xrdp_orders), 1);
self->pro_layer = owner;
self->rdp_layer = owner->rdp_layer;
self->out_s = &owner->out_s;
return self;
}
/*****************************************************************************/
void xrdp_orders_delete(struct xrdp_orders* self)
{
g_free(self);
}
/*****************************************************************************/
/* returns error */
int xrdp_orders_init(struct xrdp_orders* self)
{
self->order_level++;
if (self->order_level == 1)
{
self->order_count = 0;
if (xrdp_rdp_init_data(self->rdp_layer, 8192) != 0) /* is this big enough */
return 1;
out_uint16_le(self->out_s, RDP_UPDATE_ORDERS);
out_uint8s(self->out_s, 2); /* pad */
self->order_count_ptr = self->out_s->p;
out_uint8s(self->out_s, 2); /* number of orders, set later */
out_uint8s(self->out_s, 2); /* pad */
}
return 0;
}
/*****************************************************************************/
/* returns error */
int xrdp_orders_send(struct xrdp_orders* self)
{
int rv;
rv = 0;
if (self->order_level > 0)
{
self->order_level--;
if (self->order_level == 0)
{
s_mark_end(self->out_s);
*((short*)self->order_count_ptr) = self->order_count;
if (xrdp_rdp_send_data(self->rdp_layer, RDP_DATA_PDU_UPDATE) != 0)
rv = 1;
}
}
return rv;
}
/*****************************************************************************/
/* returns error */
int xrdp_orders_force_send(struct xrdp_orders* self)
{
if (self->order_count > 0)
{
s_mark_end(self->out_s);
*((short*)self->order_count_ptr) = self->order_count;
if (xrdp_rdp_send_data(self->rdp_layer, RDP_DATA_PDU_UPDATE) != 0)
return 1;
}
self->order_count = 0;
self->order_level = 0;
return 0;
}
/*****************************************************************************/
int xrdp_orders_check(struct xrdp_orders* self, int max_size)
{
int size;
if (self->order_level < 1)
{
if (max_size > 8000)
return 1;
else
return 0;
}
size = self->out_s->p - self->order_count_ptr;
if (size < 0 || size > 8192)
return 1;
if (size + max_size + 100 > 8000)
{
xrdp_orders_force_send(self);
xrdp_orders_init(self);
}
return 0;
}
/*****************************************************************************/
/* returns boolean */
int xrdp_orders_last_bounds(struct xrdp_orders* self,
struct xrdp_rect* rect)
{
if (rect == 0)
return 0;
if (rect->left == self->clip_left && rect->top == self->clip_top &&
rect->right == self->clip_right && rect->bottom == self->clip_bottom)
return 1;
return 0;
}
/*****************************************************************************/
/* returns boolean */
int xrdp_orders_send_delta(struct xrdp_orders* self, int* vals, int count)
{
int i;
for (i = 0; i < count; i += 2)
if (g_abs(vals[i] - vals[i + 1]) >= 128)
return 0;
return 1;
}
/*****************************************************************************/
/* returns error */
int xrdp_orders_out_bounds(struct xrdp_orders* self, struct xrdp_rect* rect)
{
char* bounds_flags_ptr;
int bounds_flags;
bounds_flags = 0;
bounds_flags_ptr = self->out_s->p;
out_uint8s(self->out_s, 1);
/* left */
if (rect->left == self->clip_left) ;
else if (g_abs(rect->left - self->clip_left) < 128)
bounds_flags |= 0x10;
else
bounds_flags |= 0x01;
/* top */
if (rect->top == self->clip_top) ;
else if (g_abs(rect->top - self->clip_top) < 128)
bounds_flags |= 0x20;
else
bounds_flags |= 0x02;
/* right */
if (rect->right == self->clip_right) ;
else if (g_abs(rect->right - self->clip_right) < 128)
bounds_flags |= 0x40;
else
bounds_flags |= 0x04;
/* bottom */
if (rect->bottom == self->clip_bottom) ;
else if (g_abs(rect->bottom - self->clip_bottom) < 128)
bounds_flags |= 0x80;
else
bounds_flags |= 0x08;
/* left */
if (bounds_flags & 0x01)
out_uint16_le(self->out_s, rect->left)
else if (bounds_flags & 0x10)
out_uint8(self->out_s, rect->left - self->clip_left)
self->clip_left = rect->left;
/* top */
if (bounds_flags & 0x02)
out_uint16_le(self->out_s, rect->top)
else if (bounds_flags & 0x20)
out_uint8(self->out_s, rect->top - self->clip_top)
self->clip_top = rect->top;
/* right */
if (bounds_flags & 0x04)
out_uint16_le(self->out_s, rect->right)
else if (bounds_flags & 0x40)
out_uint8(self->out_s, rect->right - self->clip_right)
self->clip_right = rect->right;
/* bottom */
if (bounds_flags & 0x08)
out_uint16_le(self->out_s, rect->bottom)
else if (bounds_flags & 0x80)
out_uint8(self->out_s, rect->bottom - self->clip_bottom)
self->clip_bottom = rect->bottom;
/* set flags */
*bounds_flags_ptr = bounds_flags;
return 0;
}
/*****************************************************************************/
/* returns error */
/* send a solid rect to client */
/* max size 23 */
int xrdp_orders_rect(struct xrdp_orders* self, int x, int y, int cx, int cy,
int color, struct xrdp_rect* rect)
{
int order_flags;
int vals[8];
int present;
char* present_ptr;
xrdp_orders_check(self, 23);
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
if (self->last_order != RDP_ORDER_RECT)
order_flags |= RDP_ORDER_CHANGE;
self->last_order = RDP_ORDER_RECT;
if (rect != 0)
{
order_flags |= RDP_ORDER_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
order_flags |= RDP_ORDER_LASTBOUNDS;
}
vals[0] = x; vals[1] = self->rect_x;
vals[2] = y; vals[3] = self->rect_y;
vals[4] = cx; vals[5] = self->rect_cx;
vals[6] = cy; vals[7] = self->rect_cy;
if (xrdp_orders_send_delta(self, vals, 8))
order_flags |= RDP_ORDER_DELTA;
out_uint8(self->out_s, order_flags)
if (order_flags & RDP_ORDER_CHANGE)
out_uint8(self->out_s, self->last_order)
present = 0;
present_ptr = self->out_s->p; /* hold 1 byte present pointer */
out_uint8s(self->out_s, 1)
if ((order_flags & RDP_ORDER_BOUNDS) &&
!(order_flags & RDP_ORDER_LASTBOUNDS))
xrdp_orders_out_bounds(self, rect);
if (x != self->rect_x)
{
present |= 0x01;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, x - self->rect_x)
else
out_uint16_le(self->out_s, x)
self->rect_x = x;
}
if (y != self->rect_y)
{
present |= 0x02;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, y - self->rect_y)
else
out_uint16_le(self->out_s, y)
self->rect_y = y;
}
if (cx != self->rect_cx)
{
present |= 0x04;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, cx - self->rect_cx)
else
out_uint16_le(self->out_s, cx)
self->rect_cx = cx;
}
if (cy != self->rect_cy)
{
present |= 0x08;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, cy - self->rect_cy)
else
out_uint16_le(self->out_s, cy)
self->rect_cy = cy;
}
if ((color & 0xff) != (self->rect_color & 0xff))
{
present |= 0x10;
self->rect_color = (self->rect_color & 0xffff00) | (color & 0xff);
out_uint8(self->out_s, color);
}
if ((color & 0xff00) != (self->rect_color & 0xff00))
{
present |= 0x20;
self->rect_color = (self->rect_color & 0xff00ff) | (color & 0xff00);
out_uint8(self->out_s, color >> 8);
}
if ((color & 0xff0000) != (self->rect_color & 0xff0000))
{
present |= 0x40;
self->rect_color = (self->rect_color & 0x00ffff) | (color & 0xff0000);
out_uint8(self->out_s, color >> 16);
}
*present_ptr = present;
return 0;
}
/*****************************************************************************/
/* returns error */
/* send a screen blt order */
/* max size 25 */
int xrdp_orders_screen_blt(struct xrdp_orders* self, int x, int y,
int cx, int cy, int srcx, int srcy,
int rop, struct xrdp_rect* rect)
{
int order_flags;
int vals[12];
int present;
char* present_ptr;
xrdp_orders_check(self, 25);
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
if (self->last_order != RDP_ORDER_SCREENBLT)
order_flags |= RDP_ORDER_CHANGE;
self->last_order = RDP_ORDER_SCREENBLT;
if (rect != 0)
{
order_flags |= RDP_ORDER_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
order_flags |= RDP_ORDER_LASTBOUNDS;
}
vals[0] = x; vals[1] = self->scr_blt_x;
vals[2] = y; vals[3] = self->scr_blt_y;
vals[4] = cx; vals[5] = self->scr_blt_cx;
vals[6] = cy; vals[7] = self->scr_blt_cy;
vals[8] = srcx; vals[9] = self->scr_blt_srcx;
vals[10] = srcy; vals[11] = self->scr_blt_srcy;
if (xrdp_orders_send_delta(self, vals, 12))
order_flags |= RDP_ORDER_DELTA;
out_uint8(self->out_s, order_flags);
if (order_flags & RDP_ORDER_CHANGE)
out_uint8(self->out_s, self->last_order)
present = 0;
present_ptr = self->out_s->p; /* hold 1 byte present pointer */
out_uint8s(self->out_s, 1)
if ((order_flags & RDP_ORDER_BOUNDS) &&
!(order_flags & RDP_ORDER_LASTBOUNDS))
xrdp_orders_out_bounds(self, rect);
if (x != self->scr_blt_x)
{
present |= 0x01;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, x - self->scr_blt_x)
else
out_uint16_le(self->out_s, x)
self->scr_blt_x = x;
}
if (y != self->scr_blt_y)
{
present |= 0x02;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, y - self->scr_blt_y)
else
out_uint16_le(self->out_s, y)
self->scr_blt_y = y;
}
if (cx != self->scr_blt_cx)
{
present |= 0x04;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, cx - self->scr_blt_cx)
else
out_uint16_le(self->out_s, cx)
self->scr_blt_cx = cx;
}
if (cy != self->scr_blt_cy)
{
present |= 0x08;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, cy - self->scr_blt_cy)
else
out_uint16_le(self->out_s, cy)
self->scr_blt_cy = cy;
}
if (rop != self->scr_blt_rop)
{
present |= 0x10;
out_uint8(self->out_s, rop);
self->scr_blt_rop = rop;
}
if (srcx != self->scr_blt_srcx)
{
present |= 0x20;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, srcx - self->scr_blt_srcx)
else
out_uint16_le(self->out_s, srcx)
self->scr_blt_srcx = srcx;
}
if (srcy != self->scr_blt_srcy)
{
present |= 0x40;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, srcy - self->scr_blt_srcy)
else
out_uint16_le(self->out_s, srcy)
self->scr_blt_srcy = srcy;
}
*present_ptr = present;
return 0;
}
/*****************************************************************************/
/* returns error */
/* send a pat blt order */
/* max size 39 */
int xrdp_orders_pat_blt(struct xrdp_orders* self, int x, int y,
int cx, int cy, int rop, int bg_color,
int fg_color, struct xrdp_brush* brush,
struct xrdp_rect* rect)
{
int order_flags;
int vals[8];
int present;
char* present_ptr;
struct xrdp_brush blank_brush;
xrdp_orders_check(self, 39);
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
if (self->last_order != RDP_ORDER_PATBLT)
order_flags |= RDP_ORDER_CHANGE;
self->last_order = RDP_ORDER_PATBLT;
if (rect != 0)
{
order_flags |= RDP_ORDER_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
order_flags |= RDP_ORDER_LASTBOUNDS;
}
vals[0] = x; vals[1] = self->pat_blt_x;
vals[2] = y; vals[3] = self->pat_blt_y;
vals[4] = cx; vals[5] = self->pat_blt_cx;
vals[6] = cy; vals[7] = self->pat_blt_cy;
if (xrdp_orders_send_delta(self, vals, 8))
order_flags |= RDP_ORDER_DELTA;
out_uint8(self->out_s, order_flags);
if (order_flags & RDP_ORDER_CHANGE)
out_uint8(self->out_s, self->last_order)
present = 0;
present_ptr = self->out_s->p; /* hold 2 byte present pointer, todo */
out_uint8s(self->out_s, 2) /* this can be smaller, */
/* see RDP_ORDER_SMALL and RDP_ORDER_TINY */
if ((order_flags & RDP_ORDER_BOUNDS) &&
!(order_flags & RDP_ORDER_LASTBOUNDS))
xrdp_orders_out_bounds(self, rect);
if (x != self->pat_blt_x)
{
present |= 0x0001;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, x - self->pat_blt_x)
else
out_uint16_le(self->out_s, x)
self->pat_blt_x = x;
}
if (y != self->pat_blt_y)
{
present |= 0x0002;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, y - self->pat_blt_y)
else
out_uint16_le(self->out_s, y)
self->pat_blt_y = y;
}
if (cx != self->pat_blt_cx)
{
present |= 0x0004;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, cx - self->pat_blt_cx)
else
out_uint16_le(self->out_s, cx)
self->pat_blt_cx = cx;
}
if (cy != self->pat_blt_cy)
{
present |= 0x0008;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, cy - self->pat_blt_cy)
else
out_uint16_le(self->out_s, cy)
self->pat_blt_cy = cy;
}
if (rop != self->pat_blt_rop)
{
present |= 0x0010;
/* PATCOPY PATPAINT PATINVERT DSTINVERT BLACKNESS WHITENESS */
out_uint8(self->out_s, rop);
self->pat_blt_rop = rop;
}
if (bg_color != self->pat_blt_bg_color)
{
present |= 0x0020;
out_uint8(self->out_s, bg_color);
out_uint8(self->out_s, bg_color >> 8);
out_uint8(self->out_s, bg_color >> 16);
self->pat_blt_bg_color = bg_color;
}
if (fg_color != self->pat_blt_fg_color)
{
present |= 0x0040;
out_uint8(self->out_s, fg_color);
out_uint8(self->out_s, fg_color >> 8);
out_uint8(self->out_s, fg_color >> 16);
self->pat_blt_fg_color = fg_color;
}
if (brush == 0) /* if nil use blank one */
{ /* todo can we just set style to zero */
g_memset(&blank_brush, 0, sizeof(struct xrdp_brush));
brush = &blank_brush;
}
if (brush->x_orgin != self->pat_blt_brush.x_orgin)
{
present |= 0x0080;
out_uint8(self->out_s, brush->x_orgin);
self->pat_blt_brush.x_orgin = brush->x_orgin;
}
if (brush->y_orgin != self->pat_blt_brush.y_orgin)
{
present |= 0x0100;
out_uint8(self->out_s, brush->y_orgin);
self->pat_blt_brush.y_orgin = brush->y_orgin;
}
if (brush->style != self->pat_blt_brush.style)
{
present |= 0x0200;
out_uint8(self->out_s, brush->style);
self->pat_blt_brush.style = brush->style;
}
if (brush->pattern[0] != self->pat_blt_brush.pattern[0])
{
present |= 0x0400;
out_uint8(self->out_s, brush->pattern[0]);
self->pat_blt_brush.pattern[0] = brush->pattern[0];
}
if (g_memcmp(brush->pattern + 1, self->pat_blt_brush.pattern + 1, 7) != 0)
{
present |= 0x0800;
out_uint8a(self->out_s, brush->pattern + 1, 7);
g_memcpy(self->pat_blt_brush.pattern + 1, brush->pattern + 1, 7);
}
*((short*)present_ptr) = present;
return 0;
}
/*****************************************************************************/
/* returns error */
/* send a dest blt order */
/* max size 21 */
int xrdp_orders_dest_blt(struct xrdp_orders* self, int x, int y,
int cx, int cy, int rop,
struct xrdp_rect* rect)
{
int order_flags;
int vals[8];
int present;
char* present_ptr;
xrdp_orders_check(self, 21);
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
if (self->last_order != RDP_ORDER_DESTBLT)
order_flags |= RDP_ORDER_CHANGE;
self->last_order = RDP_ORDER_DESTBLT;
if (rect != 0)
{
order_flags |= RDP_ORDER_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
order_flags |= RDP_ORDER_LASTBOUNDS;
}
vals[0] = x; vals[1] = self->dest_blt_x;
vals[2] = y; vals[3] = self->dest_blt_y;
vals[4] = cx; vals[5] = self->dest_blt_cx;
vals[6] = cy; vals[7] = self->dest_blt_cy;
if (xrdp_orders_send_delta(self, vals, 8))
order_flags |= RDP_ORDER_DELTA;
out_uint8(self->out_s, order_flags);
if (order_flags & RDP_ORDER_CHANGE)
out_uint8(self->out_s, self->last_order)
present = 0;
present_ptr = self->out_s->p; /* hold 1 byte present pointer */
out_uint8s(self->out_s, 1)
if ((order_flags & RDP_ORDER_BOUNDS) &&
!(order_flags & RDP_ORDER_LASTBOUNDS))
xrdp_orders_out_bounds(self, rect);
if (x != self->dest_blt_x)
{
present |= 0x01;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, x - self->dest_blt_x)
else
out_uint16_le(self->out_s, x)
self->dest_blt_x = x;
}
if (y != self->dest_blt_y)
{
present |= 0x02;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, y - self->dest_blt_y)
else
out_uint16_le(self->out_s, y)
self->dest_blt_y = y;
}
if (cx != self->dest_blt_cx)
{
present |= 0x04;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, cx - self->dest_blt_cx)
else
out_uint16_le(self->out_s, cx)
self->dest_blt_cx = cx;
}
if (cy != self->dest_blt_cy)
{
present |= 0x08;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, cy - self->dest_blt_cy)
else
out_uint16_le(self->out_s, cy)
self->dest_blt_cy = cy;
}
if (rop != self->dest_blt_rop)
{
present |= 0x0010;
out_uint8(self->out_s, rop);
self->dest_blt_rop = rop;
}
*present_ptr = present;
return 0;
}
/*****************************************************************************/
/* returns error */
/* send a line order */
/* max size 32 */
int xrdp_orders_line(struct xrdp_orders* self, int mix_mode,
int startx, int starty,
int endx, int endy, int rop, int bg_color,
struct xrdp_pen* pen,
struct xrdp_rect* rect)
{
int order_flags;
int vals[8];
int present;
char* present_ptr;
struct xrdp_pen blank_pen;
xrdp_orders_check(self, 32);
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
if (self->last_order != RDP_ORDER_LINE)
order_flags |= RDP_ORDER_CHANGE;
self->last_order = RDP_ORDER_LINE;
if (rect != 0)
{
order_flags |= RDP_ORDER_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
order_flags |= RDP_ORDER_LASTBOUNDS;
}
vals[0] = startx; vals[1] = self->line_startx;
vals[2] = starty; vals[3] = self->line_starty;
vals[4] = endx; vals[5] = self->line_endx;
vals[6] = endy; vals[7] = self->line_endy;
if (xrdp_orders_send_delta(self, vals, 8))
order_flags |= RDP_ORDER_DELTA;
out_uint8(self->out_s, order_flags);
if (order_flags & RDP_ORDER_CHANGE)
out_uint8(self->out_s, self->last_order)
present = 0;
present_ptr = self->out_s->p; /* hold 2 byte present pointer */
out_uint8s(self->out_s, 2)
if ((order_flags & RDP_ORDER_BOUNDS) &&
!(order_flags & RDP_ORDER_LASTBOUNDS))
xrdp_orders_out_bounds(self, rect);
if (mix_mode != self->line_mix_mode)
{
present |= 0x0001;
out_uint16_le(self->out_s, mix_mode)
self->line_mix_mode = mix_mode;
}
if (startx != self->line_startx)
{
present |= 0x0002;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, startx - self->line_startx)
else
out_uint16_le(self->out_s, startx)
self->line_startx = startx;
}
if (starty != self->line_starty)
{
present |= 0x0004;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, starty - self->line_starty)
else
out_uint16_le(self->out_s, starty)
self->line_starty = starty;
}
if (endx != self->line_endx)
{
present |= 0x0008;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, endx - self->line_endx)
else
out_uint16_le(self->out_s, endx)
self->line_endx = endx;
}
if (endy != self->line_endy)
{
present |= 0x0010;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, endy - self->line_endy)
else
out_uint16_le(self->out_s, endy)
self->line_endy = endy;
}
if (bg_color != self->line_bg_color)
{
present |= 0x0020;
out_uint8(self->out_s, bg_color)
out_uint8(self->out_s, bg_color >> 8)
out_uint8(self->out_s, bg_color >> 16)
self->line_bg_color = bg_color;
}
if (rop != self->line_rop)
{
present |= 0x0040;
out_uint8(self->out_s, rop)
self->line_rop = rop;
}
if (pen == 0)
{
g_memset(&blank_pen, 0, sizeof(struct xrdp_pen));
pen = &blank_pen;
}
if (pen->style != self->line_pen.style)
{
present |= 0x0080;
out_uint8(self->out_s, pen->style)
self->line_pen.style = pen->style;
}
if (pen->width != self->line_pen.width)
{
present |= 0x0100;
out_uint8(self->out_s, pen->width)
self->line_pen.width = pen->width;
}
if (pen->color != self->line_pen.color)
{
present |= 0x0200;
out_uint8(self->out_s, pen->color)
out_uint8(self->out_s, pen->color >> 8)
out_uint8(self->out_s, pen->color >> 16)
self->line_pen.color = pen->color;
}
*((short*)present_ptr) = present;
return 0;
}
/*****************************************************************************/
/* returns error */
/* send a mem blt order */
/* max size 30 */
int xrdp_orders_mem_blt(struct xrdp_orders* self, int cache_id,
int color_table, int x, int y, int cx, int cy,
int rop, int srcx, int srcy,
int cache_idx, struct xrdp_rect* rect)
{
int order_flags;
int vals[12];
int present;
char* present_ptr;
xrdp_orders_check(self, 30);
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
if (self->last_order != RDP_ORDER_MEMBLT)
order_flags |= RDP_ORDER_CHANGE;
self->last_order = RDP_ORDER_MEMBLT;
if (rect != 0)
{
order_flags |= RDP_ORDER_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
order_flags |= RDP_ORDER_LASTBOUNDS;
}
vals[0] = x; vals[1] = self->mem_blt_x;
vals[2] = y; vals[3] = self->mem_blt_y;
vals[4] = cx; vals[5] = self->mem_blt_cx;
vals[6] = cy; vals[7] = self->mem_blt_cy;
vals[8] = srcx; vals[9] = self->mem_blt_srcx;
vals[10] = srcy; vals[11] = self->mem_blt_srcy;
if (xrdp_orders_send_delta(self, vals, 12))
order_flags |= RDP_ORDER_DELTA;
out_uint8(self->out_s, order_flags);
if (order_flags & RDP_ORDER_CHANGE)
out_uint8(self->out_s, self->last_order)
present = 0;
present_ptr = self->out_s->p; /* hold 2 byte present pointer, todo */
out_uint8s(self->out_s, 2) /* this can be smaller, */
/* see RDP_ORDER_SMALL and RDP_ORDER_TINY */
if ((order_flags & RDP_ORDER_BOUNDS) &&
!(order_flags & RDP_ORDER_LASTBOUNDS))
xrdp_orders_out_bounds(self, rect);
if (cache_id != self->mem_blt_cache_id ||
color_table != self->mem_blt_color_table)
{
present |= 0x0001;
out_uint8(self->out_s, cache_id);
out_uint8(self->out_s, color_table);
self->mem_blt_cache_id = cache_id;
self->mem_blt_color_table = color_table;
}
if (x != self->mem_blt_x)
{
present |= 0x0002;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, x - self->mem_blt_x)
else
out_uint16_le(self->out_s, x)
self->mem_blt_x = x;
}
if (y != self->mem_blt_y)
{
present |= 0x0004;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, y - self->mem_blt_y)
else
out_uint16_le(self->out_s, y)
self->mem_blt_y = y;
}
if (cx != self->mem_blt_cx)
{
present |= 0x0008;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, cx - self->mem_blt_cx)
else
out_uint16_le(self->out_s, cx)
self->mem_blt_cx = cx;
}
if (cy != self->mem_blt_cy)
{
present |= 0x0010;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, cy - self->mem_blt_cy)
else
out_uint16_le(self->out_s, cy)
self->mem_blt_cy = cy;
}
if (rop != self->mem_blt_rop)
{
present |= 0x0020;
out_uint8(self->out_s, rop);
self->mem_blt_rop = rop;
}
if (srcx != self->mem_blt_srcx)
{
present |= 0x0040;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, srcx - self->mem_blt_srcx)
else
out_uint16_le(self->out_s, srcx)
self->mem_blt_srcx = srcx;
}
if (srcy != self->mem_blt_srcy)
{
present |= 0x0080;
if (order_flags & RDP_ORDER_DELTA)
out_uint8(self->out_s, srcy - self->mem_blt_srcy)
else
out_uint16_le(self->out_s, srcy)
self->mem_blt_srcy = srcy;
}
if (cache_idx != self->mem_blt_cache_idx)
{
present |= 0x0100;
out_uint16_le(self->out_s, cache_idx);
self->mem_blt_cache_idx = cache_idx;
}
*((short*)present_ptr) = present;
return 0;
}
/*****************************************************************************/
/* returns error */
/* when a palette gets sent, send the main palette too */
/* don't need max size here */
int xrdp_orders_send_palette(struct xrdp_orders* self, int* palette,
int cache_id)
{
int order_flags;
int len;
int i;
/* gota clear any build up orders and send the main palette */
xrdp_orders_force_send(self);
xrdp_wm_send_palette(self->pro_layer->wm);
xrdp_orders_init(self);
self->order_count++;
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
out_uint8(self->out_s, order_flags);
len = 1027 - 7; /* length after type minus 7 */
out_uint16_le(self->out_s, len);
out_uint16_le(self->out_s, 0); /* flags */
out_uint8(self->out_s, RDP_ORDER_COLCACHE); /* type */
out_uint8(self->out_s, cache_id);
out_uint16_le(self->out_s, 256); /* num colors */
for (i = 0; i < 256; i++)
{
out_uint8(self->out_s, palette[i]);
out_uint8(self->out_s, palette[i] >> 8);
out_uint8(self->out_s, palette[i] >> 16);
out_uint8(self->out_s, 0);
}
return 0;
}
/*****************************************************************************/
/* returns error */
/* max size width * height * Bpp + 16 */
int xrdp_orders_send_raw_bitmap(struct xrdp_orders* self,
struct xrdp_bitmap* bitmap,
int cache_id, int cache_idx)
{
int order_flags;
int len;
int bufsize;
int Bpp;
int i;
int j;
int pixel;
Bpp = (bitmap->bpp + 7) / 8;
bufsize = bitmap->width * bitmap->height * Bpp;
xrdp_orders_check(self, bufsize + 16);
self->order_count++;
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
out_uint8(self->out_s, order_flags);
len = (bufsize + 9) - 7;
out_uint16_le(self->out_s, len);
out_uint16_le(self->out_s, 8); /* flags */
out_uint8(self->out_s, RDP_ORDER_RAW_BMPCACHE); /* type */
out_uint8(self->out_s, cache_id);
out_uint8s(self->out_s, 1); /* pad */
out_uint8(self->out_s, bitmap->width);
out_uint8(self->out_s, bitmap->height);
out_uint8(self->out_s, bitmap->bpp);
out_uint16_le(self->out_s, bufsize);
out_uint16_le(self->out_s, cache_idx);
for (i = bitmap->height - 1; i >= 0; i--)
for (j = 0; j < bitmap->width; j++)
{
pixel = xrdp_bitmap_get_pixel(bitmap, j, i);
if (Bpp == 3)
{
out_uint8(self->out_s, pixel >> 16);
out_uint8(self->out_s, pixel >> 8);
out_uint8(self->out_s, pixel);
}
else if (Bpp == 2)
{
out_uint8(self->out_s, pixel);
out_uint8(self->out_s, pixel >> 8);
}
else if (Bpp == 1)
out_uint8(self->out_s, pixel);
}
return 0;
}

@ -0,0 +1,333 @@
/*
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.
Copyright (C) Jay Sorg 2004
painter, gc
*/
#include "xrdp.h"
/*****************************************************************************/
struct xrdp_painter* xrdp_painter_create(struct xrdp_wm* wm)
{
struct xrdp_painter* self;
self = (struct xrdp_painter*)g_malloc(sizeof(struct xrdp_painter), 1);
self->wm = wm;
self->orders = wm->orders;
self->rop = 0xcc; /* copy */
return self;
}
/*****************************************************************************/
void xrdp_painter_delete(struct xrdp_painter* self)
{
if (self == 0)
return;
g_free(self);
}
/*****************************************************************************/
int xrdp_painter_begin_update(struct xrdp_painter* self)
{
xrdp_orders_init(self->orders);
return 0;
}
/*****************************************************************************/
int xrdp_painter_end_update(struct xrdp_painter* self)
{
xrdp_orders_send(self->orders);
return 0;
}
/*****************************************************************************/
int xrdp_painter_clip_adj(struct xrdp_painter* self, int* x, int* y,
int* cx, int* cy)
{
int dx;
int dy;
if (!self->use_clip)
return 1;
if (self->clip.left > *x)
dx = self->clip.left - *x;
else
dx = 0;
if (self->clip.top > *y)
dy = self->clip.top - *y;
else
dy = 0;
if (*x + *cx > self->clip.right)
*cx = *cx - ((*x + *cx) - self->clip.right);
if (*y + *cy > self->clip.bottom)
*cy = *cy - ((*y + *cy) - self->clip.bottom);
*cx = *cx - dx;
*cy = *cy - dy;
if (*cx <= 0)
return 0;
if (*cy <= 0)
return 0;
*x = *x + dx;
*y = *y + dy;
return 1;
}
/*****************************************************************************/
int xrdp_painter_set_clip(struct xrdp_painter* self,
int x, int y, int cx, int cy)
{
self->use_clip = 1;
self->clip.left = x;
self->clip.top = y;
self->clip.right = x + cx;
self->clip.bottom = y + cy;
return 0;
}
/*****************************************************************************/
int xrdp_painter_clr_clip(struct xrdp_painter* self)
{
self->use_clip = 0;
return 0;
}
/*****************************************************************************/
int xrdp_painter_rop(int rop, int src, int dst)
{
switch (rop & 0x0f)
{
case 0x0: return 0;
case 0x1: return ~(src | dst);
case 0x2: return (~src) & dst;
case 0x3: return ~src;
case 0x4: return src & (~dst);
case 0x5: return ~(dst);
case 0x6: return src ^ dst;
case 0x7: return ~(src & dst);
case 0x8: return src & dst;
case 0x9: return ~(src) ^ dst;
case 0xa: return dst;
case 0xb: return (~src) | dst;
case 0xc: return src;
case 0xd: return src | (~dst);
case 0xe: return src | dst;
case 0xf: return ~0;
}
return dst;
}
/*****************************************************************************/
/* fill in an area of the screen with one color */
int xrdp_painter_fill_rect(struct xrdp_painter* self,
struct xrdp_bitmap* bitmap,
int x, int y, int cx, int cy)
{
int i;
struct xrdp_region* region;
struct xrdp_rect rect;
if (x >= bitmap->width) return 0;
if (y >= bitmap->height) return 0;
if (x < 0) { cx += x; x = 0; }
if (y < 0) { cy += y; y = 0; }
if (cx <= 0) return 0;
if (cy <= 0) return 0;
if (x + cx > bitmap->width) cx = bitmap->width - x;
if (y + cy > bitmap->height) cy = bitmap->height - y;
if (!xrdp_painter_clip_adj(self, &x, &y, &cx, &cy))
return 0;
if (bitmap->type == 0)
return 0;
region = xrdp_region_create(self->wm);
xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region);
i = 0;
while (xrdp_region_get_rect(region, i, &rect) == 0)
{
DEBUG(("sending rect order %d %d %d %d\n\r", rect.left, rect.top,
rect.right, rect.bottom));
xrdp_orders_rect(self->orders, rect.left, rect.top,
rect.right - rect.left,
rect.bottom - rect.top,
self->fg_color, 0);
i++;
}
xrdp_region_delete(region);
return 0;
}
/*****************************************************************************/
/* fill in an area of the screen with opcodes and patterns */
/* todo, this needs work */
int xrdp_painter_fill_rect2(struct xrdp_painter* self,
struct xrdp_bitmap* bitmap,
int x, int y, int cx, int cy)
{
int i;
struct xrdp_region* region;
struct xrdp_rect rect;
if (x >= bitmap->width) return 0;
if (y >= bitmap->height) return 0;
if (x < 0) { cx += x; x = 0; }
if (y < 0) { cy += y; y = 0; }
if (cx <= 0) return 0;
if (cy <= 0) return 0;
if (x + cx > bitmap->width) cx = bitmap->width - x;
if (y + cy > bitmap->height) cy = bitmap->height - y;
if (!xrdp_painter_clip_adj(self, &x, &y, &cx, &cy))
return 0;
if (bitmap->type == 0) /* bitmap */
return 0;
region = xrdp_region_create(self->wm);
xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region);
i = 0;
while (xrdp_region_get_rect(region, i, &rect) == 0)
{
DEBUG(("sending rect order %d %d %d %d\n\r", rect.left, rect.top,
rect.right, rect.bottom));
xrdp_orders_pat_blt(self->orders, rect.left, rect.top,
rect.right - rect.left,
rect.bottom - rect.top,
self->rop, self->bg_color, self->fg_color,
&self->brush, 0);
i++;
}
xrdp_region_delete(region);
return 0;
}
#define SS 16
/*****************************************************************************/
int xrdp_painter_draw_bitmap(struct xrdp_painter* self,
struct xrdp_bitmap* bitmap,
struct xrdp_bitmap* to_draw,
int x, int y, int cx, int cy)
{
int i;
int j;
int k;
int w;
int h;
int x1;
int y1;
int ok;
int srcx;
int srcy;
int bitmap_id;
int cache_id;
int cache_idx;
int palette_id;
struct xrdp_region* region;
struct xrdp_rect rect;
struct xrdp_rect rect1;
struct xrdp_rect rect2;
struct xrdp_bitmap* b;
/* todo data */
if (bitmap->type == 0)
return 0;
region = xrdp_region_create(self->wm);
xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region);
b = bitmap;
while (b != 0)
{
x = x + b->left;
y = y + b->top;
b = b->parent;
}
palette_id = xrdp_cache_add_palette(self->wm->cache, self->wm->palette);
i = 0;
while (i < to_draw->width)
{
j = 0;
while (j < to_draw->height)
{
x1 = x + i;
y1 = y + j;
MIN(w, SS, to_draw->width - i);
MIN(h, SS, to_draw->height - j);
b = xrdp_bitmap_create(w, h, self->wm->screen->bpp, 0);
xrdp_bitmap_copy_box(to_draw, b, i, j, w, h);
bitmap_id = xrdp_cache_add_bitmap(self->wm->cache, b);
HIWORD(cache_id, bitmap_id);
LOWORD(cache_idx, bitmap_id);
k = 0;
while (xrdp_region_get_rect(region, k, &rect) == 0)
{
xrdp_wm_rect(&rect1, x1, y1, w, h);
if (xrdp_wm_rect_intersect(&rect, &rect1, &rect2))
{
ok = 1;
if (self->use_clip)
{
rect = self->clip;
xrdp_wm_rect_offset(&rect, x, y);
if (!xrdp_wm_rect_intersect(&rect2, &rect, &rect1))
ok = 0;
}
else
rect1 = rect2;
if (ok)
{
rect1.right--;
rect1.bottom--;
/* check these so ms client don't crash */
if (x1 + w >= self->wm->screen->width)
w = self->wm->screen->width - x1;
if (y1 + h >= self->wm->screen->height)
h = self->wm->screen->height - y1;
if (w > 0 && h > 0 && x1 + w > 0 && y1 + h > 0)
{
srcx = 0;
srcy = 0;
if (x1 < 0)
{
w = w + x1;
srcx = srcx - x1;
x1 = 0;
}
if (y1 < 0)
{
h = h + y1;
srcy = srcy - y1;
y1 = 0;
}
xrdp_orders_mem_blt(self->orders, cache_id, palette_id,
x1, y1, w, h, self->rop, srcx, srcy,
cache_idx, &rect1);
}
}
}
k++;
}
xrdp_bitmap_delete(b);
j += SS;
}
i += SS;
}
xrdp_region_delete(region);
return 0;
}

@ -28,14 +28,17 @@ struct xrdp_process* xrdp_process_create(struct xrdp_listen* owner)
self = (struct xrdp_process*)g_malloc(sizeof(struct xrdp_process), 1);
self->lis_layer = owner;
self->rdp_layer = xrdp_rdp_create(self);
return self;
}
/*****************************************************************************/
void xrdp_process_delete(struct xrdp_process* self)
{
if (self == 0)
return;
xrdp_rdp_delete(self->rdp_layer);
xrdp_orders_delete(self->orders);
xrdp_wm_delete(self->wm);
g_free(self->in_s.data);
g_free(self->out_s.data);
g_free(self);
@ -63,7 +66,7 @@ int xrdp_process_main_loop(struct xrdp_process* self)
{
if (xrdp_rdp_recv(self->rdp_layer, &code) != 0)
break;
DEBUG(("xrdp_process_main_loop code %d\n", code));
DEBUG(("xrdp_process_main_loop code %d\n\r", code));
switch (code)
{
case -1:
@ -75,23 +78,42 @@ int xrdp_process_main_loop(struct xrdp_process* self)
xrdp_rdp_process_confirm_active(self->rdp_layer); /* 3 */
break;
case RDP_PDU_DATA:
xrdp_rdp_process_data(self->rdp_layer); /* 7 */
if (xrdp_rdp_process_data(self->rdp_layer) != 0) /* 7 */
{
DEBUG(("xrdp_rdp_process_data returned non zero\n\r"));
cont = 0;
self->term = 1;
}
break;
default:
g_printf("unknown in xrdp_process_main_loop\n");
g_printf("unknown in xrdp_process_main_loop\n\r");
break;
}
cont = self->rdp_layer->next_packet < self->rdp_layer->in_s->end;
if (cont)
cont = self->rdp_layer->next_packet < self->rdp_layer->in_s->end;
}
if (cont) /* we must have errored out */
break;
if (self->rdp_layer->up_and_running && self->wm == 0)
{
/* only do this once */
DEBUG(("xrdp_process_main_loop up and running\n\r"));
self->orders = xrdp_orders_create(self);
self->wm = xrdp_wm_create(self);
xrdp_wm_init(self->wm);
}
}
else if (i == 0)
g_sleep(10);
else
break;
}
}
xrdp_rdp_disconnect(self->rdp_layer);
xrdp_rdp_delete(self->rdp_layer);
self->rdp_layer = 0;
g_tcp_close(self->sck);
self->status = -1;
xrdp_listen_delete_pro(self->lis_layer, self);
return 0;
}

@ -63,6 +63,8 @@ struct xrdp_rdp* xrdp_rdp_create(struct xrdp_process* owner)
/*****************************************************************************/
void xrdp_rdp_delete(struct xrdp_rdp* self)
{
if (self == 0)
return;
xrdp_sec_delete(self->sec_layer);
g_free(self);
}
@ -91,16 +93,24 @@ int xrdp_rdp_recv(struct xrdp_rdp* self, int* code)
int error;
int len;
int pdu_code;
int chan;
if (self->next_packet == 0 || self->next_packet >= self->in_s->end)
{
error = xrdp_sec_recv(self->sec_layer);
chan = 0;
error = xrdp_sec_recv(self->sec_layer, &chan);
if (error == -1) /* special code for send demand active */
{
self->next_packet = 0;
*code = -1;
return 0;
}
if (chan != MCS_GLOBAL_CHANNEL && chan > 0)
{
self->next_packet = 0;
*code = 0;
return 0;
}
if (error != 0)
return 1;
self->next_packet = self->in_s->p;
@ -126,6 +136,7 @@ int xrdp_rdp_send(struct xrdp_rdp* self, int pdu_type)
{
int len;
DEBUG(("in xrdp_rdp_send\n\r"));
s_pop_layer(self->out_s, rdp_hdr);
len = self->out_s->end - self->out_s->p;
out_uint16_le(self->out_s, len);
@ -133,6 +144,7 @@ int xrdp_rdp_send(struct xrdp_rdp* self, int pdu_type)
out_uint16_le(self->out_s, self->mcs_channel);
if (xrdp_sec_send(self->sec_layer, 0) != 0)
return 1;
DEBUG(("out xrdp_rdp_send\n\r"));
return 0;
}
@ -141,6 +153,7 @@ int xrdp_rdp_send_data(struct xrdp_rdp* self, int data_pdu_type)
{
int len;
DEBUG(("in xrdp_rdp_send_data\n\r"));
s_pop_layer(self->out_s, rdp_hdr);
len = self->out_s->end - self->out_s->p;
out_uint16_le(self->out_s, len);
@ -155,6 +168,7 @@ int xrdp_rdp_send_data(struct xrdp_rdp* self, int data_pdu_type)
out_uint16_le(self->out_s, 0);
if (xrdp_sec_send(self->sec_layer, 0) != 0)
return 1;
DEBUG(("out xrdp_rdp_send_data\n\r"));
return 0;
}
@ -350,14 +364,20 @@ int xrdp_rdp_process_data_pointer(struct xrdp_rdp* self)
int xrdp_rdp_process_input_sync(struct xrdp_rdp* self, int device_flags,
int key_flags)
{
DEBUG(("sync event flags %d key %d\n\r", device_flags, key_flags))
if (!self->up_and_running)
return 0;
return 0;
}
/*****************************************************************************/
/* RDP_INPUT_SCANCODE */
int xrdp_rdp_process_input_scancode(struct xrdp_rdp* self, int device_flags,
int ext_flags, int scan_code)
int scan_code)
{
DEBUG(("key event flags %d scan_code %d\n\r", device_flags, scan_code))
if (!self->up_and_running)
return 0;
return 0;
}
@ -366,6 +386,25 @@ int xrdp_rdp_process_input_scancode(struct xrdp_rdp* self, int device_flags,
int xrdp_rdp_process_input_mouse(struct xrdp_rdp* self, int device_flags,
int x, int y)
{
DEBUG(("mouse event flags %4.4x x - %d y - %d\n\r", device_flags, x, y));
if (!self->up_and_running)
return 0;
if (device_flags & MOUSE_FLAG_MOVE) /* 0x0800 */
xrdp_wm_mouse_move(self->pro_layer->wm, x, y);
if (device_flags & MOUSE_FLAG_BUTTON1) /* 0x1000 */
{
if (device_flags & MOUSE_FLAG_DOWN) /* 0x8000 */
xrdp_wm_mouse_click(self->pro_layer->wm, x, y, 1, 1);
else
xrdp_wm_mouse_click(self->pro_layer->wm, x, y, 1, 0);
}
if (device_flags & MOUSE_FLAG_BUTTON2) /* 0x2000 */
{
if (device_flags & MOUSE_FLAG_DOWN) /* 0x8000 */
xrdp_wm_mouse_click(self->pro_layer->wm, x, y, 2, 1);
else
xrdp_wm_mouse_click(self->pro_layer->wm, x, y, 2, 0);
}
return 0;
}
@ -382,26 +421,27 @@ int xrdp_rdp_process_data_input(struct xrdp_rdp* self)
in_uint16_le(self->in_s, num_events);
in_uint8s(self->in_s, 2); /* pad */
DEBUG(("xrdp_rdp_process_data_input %d events\n\r", num_events))
for (index = 0; index < num_events; index++)
{
in_uint8s(self->in_s, 4); /* time */
in_uint16_le(self->in_s, msg_type);
in_uint16_le(self->in_s, device_flags);
in_uint16_le(self->in_s, param1);
in_uint16_le(self->in_s, param2);
in_sint16_le(self->in_s, param1);
in_sint16_le(self->in_s, param2);
switch (msg_type)
{
case RDP_INPUT_SYNCHRONIZE: /* 0 */
xrdp_rdp_process_input_sync(self, device_flags, param1);
break;
case RDP_INPUT_SCANCODE: /* 4 */
xrdp_rdp_process_input_scancode(self, device_flags, param1, param2);
xrdp_rdp_process_input_scancode(self, device_flags, param1);
break;
case RDP_INPUT_MOUSE: /* 8001 */
xrdp_rdp_process_input_mouse(self, device_flags, param1, param2);
break;
default:
g_printf("unknown in xrdp_rdp_process_data_input\n");
g_printf("unknown in xrdp_rdp_process_data_input\n\r");
break;
}
}
@ -461,6 +501,21 @@ int xrdp_rdp_process_data_sync(struct xrdp_rdp* self)
/*****************************************************************************/
int xrdp_rdp_process_screen_update(struct xrdp_rdp* self)
{
int op;
int left;
int top;
int right;
int bottom;
struct xrdp_rect rect;
in_uint32_le(self->in_s, op);
in_uint16_le(self->in_s, left);
in_uint16_le(self->in_s, top);
in_uint16_le(self->in_s, right);
in_uint16_le(self->in_s, bottom);
xrdp_wm_rect(&rect, left, top, (right - left) + 1, (bottom - top) + 1);
if (self->up_and_running && self->pro_layer->wm != 0)
xrdp_bitmap_invalidate(self->pro_layer->wm->screen, &rect);
return 0;
}
@ -489,6 +544,7 @@ int xrdp_rdp_process_data_font(struct xrdp_rdp* self)
if (seq == 2 || seq == 3) /* after second font message, we are up and */
{ /* running */
xrdp_rdp_send_unknown1(self);
self->up_and_running = 1;
}
return 0;
}
@ -507,7 +563,7 @@ int xrdp_rdp_process_data(struct xrdp_rdp* self)
in_uint8(self->in_s, data_type);
in_uint8(self->in_s, ctype);
in_uint16_le(self->in_s, clen);
DEBUG(("xrdp_rdp_process_data code %d\n", data_type));
DEBUG(("xrdp_rdp_process_data code %d\n\r", data_type));
switch (data_type)
{
case RDP_DATA_PDU_POINTER: /* 27 */
@ -525,15 +581,24 @@ int xrdp_rdp_process_data(struct xrdp_rdp* self)
case 33: /* 33 ?? */
xrdp_rdp_process_screen_update(self);
break;
case 36: /* 36 ?? */
//case 35: /* 35 ?? this comes when minimuzing a full screen mstsc.exe 2600 */
case 36: /* 36 ?? disconnect? */
return 1;
break;
case RDP_DATA_PDU_FONT2: /* 39 */
xrdp_rdp_process_data_font(self);
break;
default:
g_printf("unknown in xrdp_rdp_process_data\n");
g_printf("unknown in xrdp_rdp_process_data %d\n\r", data_type);
break;
}
return 0;
}
/*****************************************************************************/
int xrdp_rdp_disconnect(struct xrdp_rdp* self)
{
return xrdp_sec_disconnect(self->sec_layer);
}

@ -0,0 +1,286 @@
/*
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.
Copyright (C) Jay Sorg 2004
region
*/
#include "xrdp.h"
/*****************************************************************************/
struct xrdp_region* xrdp_region_create(struct xrdp_wm* wm)
{
struct xrdp_region* self;
self = (struct xrdp_region*)g_malloc(sizeof(struct xrdp_region), 1);
self->wm = wm;
self->rects = xrdp_list_create();
self->rects->auto_free = 1;
return self;
}
/*****************************************************************************/
void xrdp_region_delete(struct xrdp_region* self)
{
if (self == 0)
return;
xrdp_list_delete(self->rects);
g_free(self);
}
/*****************************************************************************/
int xrdp_region_add_rect(struct xrdp_region* self, struct xrdp_rect* rect)
{
struct xrdp_rect* r;
r = (struct xrdp_rect*)g_malloc(sizeof(struct xrdp_rect), 1);
*r = *rect;
xrdp_list_add_item(self->rects, (int)r);
return 0;
}
/*****************************************************************************/
int xrdp_region_insert_rect(struct xrdp_region* self, int i, int left,
int top, int right, int bottom)
{
struct xrdp_rect* r;
r = (struct xrdp_rect*)g_malloc(sizeof(struct xrdp_rect), 1);
r->left = left;
r->top = top;
r->right = right;
r->bottom = bottom;
xrdp_list_insert_item(self->rects, i, (int)r);
return 0;
}
/*****************************************************************************/
int xrdp_region_subtract_rect(struct xrdp_region* self,
struct xrdp_rect* rect)
{
struct xrdp_rect* r;
struct xrdp_rect rect1;
int i;
for (i = self->rects->count - 1; i >= 0; i--)
{
r = (struct xrdp_rect*)xrdp_list_get_item(self->rects, i);
rect1 = *r;
r = &rect1;
//g_printf("r is %d %d %d %d\n", r->left, r->top, r->right, r->bottom);
if (rect->left <= r->left &&
rect->top <= r->top &&
rect->right >= r->right &&
rect->bottom >= r->bottom)
{ /* rect is not visible */
xrdp_list_remove_item(self->rects, i);
}
else if (rect->right < r->left ||
rect->bottom < r->top ||
rect->top > r->bottom ||
rect->left > r->right)
{ /* rect are not related */
}
else if (rect->left <= r->left &&
rect->right >= r->right &&
rect->bottom < r->bottom &&
rect->top <= r->top)
{ /* partially covered(whole top) */
xrdp_list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, rect->bottom,
r->right, r->bottom);
}
else if (rect->top <= r->top &&
rect->bottom >= r->bottom &&
rect->right < r->right &&
rect->left <= r->left)
{ /* partially covered(left) */
xrdp_list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, rect->right, r->top,
r->right, r->bottom);
}
else if (rect->left <= r->left &&
rect->right >= r->right &&
rect->top > r->top &&
rect->bottom >= r->bottom)
{ /* partially covered(bottom) */
xrdp_list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
r->right, rect->top);
}
else if (rect->top <= r->top &&
rect->bottom >= r->bottom &&
rect->left > r->left &&
rect->right >= r->right)
{ /* partially covered(right) */
xrdp_list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
rect->left, r->bottom);
}
else if (rect->left <= r->left &&
rect->top <= r->top &&
rect->right < r->right &&
rect->bottom < r->bottom)
{ /* partially covered(top left) */
xrdp_list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, rect->right, r->top,
r->right, rect->bottom);
xrdp_region_insert_rect(self, i, r->left, rect->bottom,
r->right, r->bottom);
}
else if (rect->left <= r->left &&
rect->bottom >= r->bottom &&
rect->right < r->right &&
rect->top > r->top)
{ /* partially covered(bottom left) */
xrdp_list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
r->right, rect->top);
xrdp_region_insert_rect(self, i, rect->right, rect->top,
r->right, r->bottom);
}
else if (rect->left > r->left &&
rect->right >= r->right &&
rect->top <= r->top &&
rect->bottom < r->bottom)
{ /* partially covered(top right) */
xrdp_list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
rect->left, r->bottom);
xrdp_region_insert_rect(self, i, rect->left, rect->bottom,
r->right, r->bottom);
}
else if (rect->left > r->left &&
rect->right >= r->right &&
rect->top > r->top &&
rect->bottom >= r->bottom)
{ /* partially covered(bottom right) */
xrdp_list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
r->right, rect->top);
xrdp_region_insert_rect(self, i, r->left, rect->top,
rect->left, r->bottom);
}
else if (rect->left > r->left &&
rect->top <= r->top &&
rect->right < r->right &&
rect->bottom >= r->bottom)
{ /* 2 rects, one on each end */
xrdp_list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
rect->left, r->bottom);
xrdp_region_insert_rect(self, i, rect->right, r->top,
r->right, r->bottom);
}
else if (rect->left <= r->left &&
rect->top > r->top &&
rect->right >= r->right &&
rect->bottom < r->bottom)
{ /* 2 rects, one on each end */
xrdp_list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
r->right, rect->top);
xrdp_region_insert_rect(self, i, r->left, rect->bottom,
r->right, r->bottom);
}
else if (rect->left > r->left &&
rect->right < r->right &&
rect->top <= r->top &&
rect->bottom < r->bottom)
{ /* partially covered(top) */
xrdp_list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
rect->left, r->bottom);
xrdp_region_insert_rect(self, i, rect->left, rect->bottom,
rect->right, r->bottom);
xrdp_region_insert_rect(self, i, rect->right, r->top,
r->right, r->bottom);
}
else if (rect->top > r->top &&
rect->bottom < r->bottom &&
rect->left <= r->left &&
rect->right < r->right)
{ /* partially covered(left) */
xrdp_list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
r->right, rect->top);
xrdp_region_insert_rect(self, i, rect->right, rect->top,
r->right, rect->bottom);
xrdp_region_insert_rect(self, i, r->left, rect->bottom,
r->right, r->bottom);
}
else if (rect->left > r->left &&
rect->right < r->right &&
rect->bottom >= r->bottom &&
rect->top > r->top)
{ /* partially covered(bottom) */
xrdp_list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
rect->left, r->bottom);
xrdp_region_insert_rect(self, i, rect->left, r->top,
rect->right, rect->top);
xrdp_region_insert_rect(self, i, rect->right, r->top,
r->right, r->bottom);
}
else if (rect->top > r->top &&
rect->bottom < r->bottom &&
rect->right >= r->right &&
rect->left > r->left)
{ /* partially covered(right) */
xrdp_list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
r->right, rect->top);
xrdp_region_insert_rect(self, i, r->left, rect->top,
rect->left, rect->bottom);
xrdp_region_insert_rect(self, i, r->left, rect->bottom,
r->right, r->bottom);
}
else if (rect->left > r->left &&
rect->top > r->top &&
rect->right < r->right &&
rect->bottom < r->bottom)
{ /* totally contained, 4 rects */
xrdp_list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
r->right, rect->top);
xrdp_region_insert_rect(self, i, r->left, rect->top,
rect->left, rect->bottom);
xrdp_region_insert_rect(self, i, r->left, rect->bottom,
r->right, r->bottom);
xrdp_region_insert_rect(self, i, rect->right, rect->top,
r->right, rect->bottom);
}
else
g_printf("error in xrdp_region_subtract_rect\n\r");
}
return 0;
}
/*****************************************************************************/
int xrdp_region_get_rect(struct xrdp_region* self, int index,
struct xrdp_rect* rect)
{
struct xrdp_rect* r;
r = (struct xrdp_rect*)xrdp_list_get_item(self->rects, index);
if (r == 0)
return 1;
*rect = *r;
return 0;
}

@ -131,6 +131,8 @@ struct xrdp_sec* xrdp_sec_create(struct xrdp_rdp* owner)
/*****************************************************************************/
void xrdp_sec_delete(struct xrdp_sec* self)
{
if (self == 0)
return;
xrdp_mcs_delete(self->mcs_layer);
g_rc4_info_delete(self->decrypt_rc4_info);
g_rc4_info_delete(self->encrypt_rc4_info);
@ -386,48 +388,48 @@ void xrdp_sec_establish_keys(struct xrdp_sec* self)
/*****************************************************************************/
/* returns error */
int xrdp_sec_recv(struct xrdp_sec* self)
int xrdp_sec_recv(struct xrdp_sec* self, int* chan)
{
int flags;
int len;
DEBUG((" in xrdp_sec_recv\n\r"));
while (xrdp_mcs_recv(self->mcs_layer) == 0)
if (xrdp_mcs_recv(self->mcs_layer, chan) != 0)
return 1;
in_uint32_le(self->in_s, flags);
DEBUG((" in xrdp_sec_recv flags $%x\n\r", flags));
if (flags & SEC_ENCRYPT) /* 0x08 */
{
in_uint8s(self->in_s, 8); /* signature */
xrdp_sec_decrypt(self, self->in_s->p, self->in_s->end - self->in_s->p);
}
if (flags & SEC_CLIENT_RANDOM) /* 0x01 */
{
in_uint32_le(self->in_s, len);
in_uint8a(self->in_s, self->client_crypt_random, 64);
xrdp_sec_rsa_op(self->client_random, self->client_crypt_random,
pub_mod, pri_exp);
xrdp_sec_establish_keys(self);
*chan = 1; /* just set a non existing channel and exit */
return 0;
}
if (flags & SEC_LOGON_INFO) /* 0x40 */
{
in_uint32_le(self->in_s, flags);
DEBUG((" in xrdp_sec_recv flags $%x\n\r", flags));
if (flags & SEC_ENCRYPT) /* 0x08 */
{
in_uint8s(self->in_s, 8); /* signature */
xrdp_sec_decrypt(self, self->in_s->p, self->in_s->end - self->in_s->p);
}
if (flags & SEC_CLIENT_RANDOM) /* 0x01 */
{
in_uint32_le(self->in_s, len);
in_uint8a(self->in_s, self->client_crypt_random, 64);
xrdp_sec_rsa_op(self->client_random, self->client_crypt_random,
pub_mod, pri_exp);
xrdp_sec_establish_keys(self);
continue;
}
if (flags & SEC_LOGON_INFO) /* 0x40 */
{
if (xrdp_sec_process_logon_info(self) != 0)
return 1;
if (xrdp_sec_send_lic_initial(self) != 0)
return 1;
continue;
}
if (flags & SEC_LICENCE_NEG) /* 0x80 */
{
if (xrdp_sec_send_lic_response(self) != 0)
return 1;
return -1; /* special error that means send demand active */
}
if (xrdp_sec_process_logon_info(self) != 0)
return 1;
if (xrdp_sec_send_lic_initial(self) != 0)
return 1;
*chan = 1; /* just set a non existing channel and exit */
return 0;
}
if (flags & SEC_LICENCE_NEG) /* 0x80 */
{
if (xrdp_sec_send_lic_response(self) != 0)
return 1;
return -1; /* special error that means send demand active */
}
DEBUG((" out xrdp_sec_recv error\n\r"));
return 1;
return 0;
}
/*****************************************************************************/
@ -435,10 +437,12 @@ int xrdp_sec_recv(struct xrdp_sec* self)
/* TODO needs outgoing encryption */
int xrdp_sec_send(struct xrdp_sec* self, int flags)
{
DEBUG((" in xrdp_sec_send\n\r"));
s_pop_layer(self->out_s, sec_hdr);
out_uint32_le(self->out_s, flags);
if (xrdp_mcs_send(self->mcs_layer) != 0)
return 1;
DEBUG((" out xrdp_sec_send\n\r"));
return 0;
}
@ -528,3 +532,9 @@ int xrdp_sec_incoming(struct xrdp_sec* self)
DEBUG(("out xrdp_sec_incoming\n\r"));
return 0;
}
/*****************************************************************************/
int xrdp_sec_disconnect(struct xrdp_sec* self)
{
return xrdp_mcs_disconnect(self->mcs_layer);
}

@ -96,7 +96,7 @@ int xrdp_tcp_send(struct xrdp_tcp* self)
int sent;
len = self->out_s->end - self->out_s->data;
DEBUG((" in xrdp_tcp_send, gota send %d bytes\n", len))
DEBUG((" in xrdp_tcp_send, gota send %d bytes\n\r", len))
total = 0;
while (total < len)
{
@ -109,17 +109,18 @@ int xrdp_tcp_send(struct xrdp_tcp* self)
g_sleep(1);
else
{
DEBUG((" error = -1 in xrdp_tcp_send socket %d\n", self->sck))
DEBUG((" error = -1 in xrdp_tcp_send socket %d\n\r", self->sck))
return 1;
}
}
else if (sent == 0)
{
DEBUG((" error = 0 in xrdp_tcp_send socket %d\n", self->sck))
DEBUG((" error = 0 in xrdp_tcp_send socket %d\n\r", self->sck))
return 1;
}
else
total = total + sent;
}
DEBUG((" out xrdp_tcp_send, sent %d bytes ok\n\r", len))
return 0;
}

@ -19,13 +19,81 @@
*/
/* for memory debugging */
struct xrdp_mem
{
int size;
int id;
};
/* header for bmp file */
struct xrdp_bmp_header
{
long size;
long image_width;
long image_height;
short planes;
short bit_count;
long compression;
long image_size;
long x_pels_per_meter;
long y_pels_per_meter;
long clr_used;
long clr_important;
};
/* list */
struct xrdp_list
{
int* items;
int count;
int alloc_size;
int grow_by;
int auto_free;
};
/* rect */
struct xrdp_rect
{
int left;
int top;
int right;
int bottom;
};
/* bounds */
struct xrdp_bounds
{
int x;
int y;
int cx;
int cy;
};
/* brush */
struct xrdp_brush
{
int x_orgin;
int y_orgin;
int style;
char pattern[8];
};
/* pen */
struct xrdp_pen
{
int style;
int width;
int color;
};
/* tcp */
struct xrdp_tcp
{
int sck;
struct stream* in_s;
struct stream* out_s;
struct xrdp_iso* iso_layer;
struct xrdp_iso* iso_layer; /* owner */
};
/* iso */
@ -33,7 +101,7 @@ struct xrdp_iso
{
struct stream* in_s;
struct stream* out_s;
struct xrdp_mcs* mcs_layer;
struct xrdp_mcs* mcs_layer; /* owner */
struct xrdp_tcp* tcp_layer;
};
@ -42,7 +110,7 @@ struct xrdp_mcs
{
struct stream* in_s;
struct stream* out_s;
struct xrdp_sec* sec_layer;
struct xrdp_sec* sec_layer; /* owner */
struct xrdp_iso* iso_layer;
int userid;
int chanid;
@ -55,7 +123,7 @@ struct xrdp_sec
{
struct stream* in_s;
struct stream* out_s;
struct xrdp_rdp* rdp_layer;
struct xrdp_rdp* rdp_layer; /* owner */
struct xrdp_mcs* mcs_layer;
char server_random[32];
char client_random[64];
@ -80,7 +148,7 @@ struct xrdp_rdp
{
struct stream* in_s;
struct stream* out_s;
struct xrdp_process* pro_layer;
struct xrdp_process* pro_layer; /* owner */
struct xrdp_sec* sec_layer;
char* next_packet;
int share_id;
@ -88,6 +156,137 @@ struct xrdp_rdp
int bpp;
int width;
int height;
int up_and_running;
};
/* orders */
struct xrdp_orders
{
struct stream* out_s;
struct xrdp_rdp* rdp_layer;
struct xrdp_process* pro_layer; /* owner */
char* order_count_ptr; /* pointer to count, set when sending */
int order_count;
int order_level; /* inc for every call to xrdp_orders_init */
int last_order; /* last order sent */
int clip_left; /* RDP_ORDER_BOUNDS, RDP_ORDER_LASTBOUNDS */
int clip_top;
int clip_right;
int clip_bottom;
int rect_x; /* RDP_ORDER_RECT */
int rect_y;
int rect_cx;
int rect_cy;
int rect_color;
int scr_blt_x; /* RDP_ORDER_SCREENBLT */
int scr_blt_y;
int scr_blt_cx;
int scr_blt_cy;
int scr_blt_rop;
int scr_blt_srcx;
int scr_blt_srcy;
int pat_blt_x; /* RDP_ORDER_PATBLT */
int pat_blt_y;
int pat_blt_cx;
int pat_blt_cy;
int pat_blt_rop;
int pat_blt_bg_color;
int pat_blt_fg_color;
struct xrdp_brush pat_blt_brush;
int dest_blt_x; /* RDP_ORDER_DESTBLT */
int dest_blt_y;
int dest_blt_cx;
int dest_blt_cy;
int dest_blt_rop;
int line_mix_mode; /* RDP_ORDER_LINE */
int line_startx;
int line_starty;
int line_endx;
int line_endy;
int line_bg_color;
int line_rop;
int mem_blt_color_table; /* RDP_ORDER_MEMBLT */
int mem_blt_cache_id;
int mem_blt_x;
int mem_blt_y;
int mem_blt_cx;
int mem_blt_cy;
int mem_blt_rop;
int mem_blt_srcx;
int mem_blt_srcy;
int mem_blt_cache_idx;
struct xrdp_pen line_pen;
};
struct xrdp_palette_item
{
int use_count;
int palette[256];
};
struct xrdp_bitmap_item
{
int use_count;
struct xrdp_bitmap* bitmap;
};
/* differnce caches */
struct xrdp_cache
{
struct xrdp_wm* wm; /* owner */
struct xrdp_orders* orders;
struct xrdp_palette_item palette_items[6];
struct xrdp_bitmap_item bitmap_items[3][600];
};
/* the window manager */
struct xrdp_wm
{
struct xrdp_process* pro_layer; /* owner */
struct xrdp_bitmap* screen;
struct xrdp_orders* orders;
struct xrdp_painter* painter;
struct stream* out_s;
struct xrdp_rdp* rdp_layer;
struct xrdp_cache* cache;
int palette[256];
struct xrdp_bitmap* login_window;
/* generic colors */
int black;
int grey;
int dark_grey;
int blue;
int white;
int red;
int green;
/* dragging info */
int dragging;
int draggingx;
int draggingy;
int draggingcx;
int draggingcy;
int draggingdx;
int draggingdy;
int draggingorgx;
int draggingorgy;
struct xrdp_bitmap* dragging_window;
/* the down(clicked) button */
struct xrdp_bitmap* button_down;
/* focused window */
struct xrdp_bitmap* focused_window;
/* cursor */
int current_cursor;
};
/* rdp process */
@ -98,8 +297,11 @@ struct xrdp_process
int term;
struct stream in_s;
struct stream out_s;
struct xrdp_listen* lis_layer;
struct xrdp_listen* lis_layer; /* owner */
struct xrdp_rdp* rdp_layer;
/* create these when up and running */
struct xrdp_orders* orders;
struct xrdp_wm* wm;
};
/* rdp listener */
@ -112,3 +314,48 @@ struct xrdp_listen
int process_list_count;
int process_list_max;
};
/* region */
struct xrdp_region
{
struct xrdp_wm* wm; /* owner */
struct xrdp_list* rects;
};
/* painter */
struct xrdp_painter
{
int rop;
int use_clip;
struct xrdp_rect clip;
int bg_color;
int fg_color;
struct xrdp_brush brush;
struct xrdp_orders* orders;
struct xrdp_wm* wm; /* owner */
};
/* window or bitmap */
struct xrdp_bitmap
{
int type; /* 0 = bitmap 1 = window 2 = screen 3 = button 4 = image 5 = edit */
int state; /* for button 0 = normal 1 = down */
int id;
char* data;
int width;
int height;
int bpp;
int left;
int top;
int bg_color;
int line_size; /* in bytes */
int focused;
struct xrdp_bitmap* modal_dialog;
struct xrdp_bitmap* owner; /* window that created us */
struct xrdp_bitmap* parent; /* window contained in */
struct xrdp_list* child_list;
struct xrdp_wm* wm;
int cursor;
int (*notify)(struct xrdp_bitmap* wnd, struct xrdp_bitmap* sender,
int msg, int param1, int param2);
};

@ -0,0 +1,886 @@
/*
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.
Copyright (C) Jay Sorg 2004
simple window manager
*/
#include "xrdp.h"
/*****************************************************************************/
struct xrdp_wm* xrdp_wm_create(struct xrdp_process* owner)
{
struct xrdp_wm* self;
self = (struct xrdp_wm*)g_malloc(sizeof(struct xrdp_wm), 1);
self->screen = xrdp_bitmap_create(owner->rdp_layer->width,
owner->rdp_layer->height,
owner->rdp_layer->bpp, 2);
self->screen->wm = self;
self->pro_layer = owner;
self->orders = owner->orders;
self->painter = xrdp_painter_create(self);
self->out_s = &owner->out_s;
self->rdp_layer = owner->rdp_layer;
self->cache = xrdp_cache_create(self, self->orders);
return self;
}
/*****************************************************************************/
void xrdp_wm_delete(struct xrdp_wm* self)
{
if (self == 0)
return;
xrdp_cache_delete(self->cache);
xrdp_painter_delete(self->painter);
xrdp_bitmap_delete(self->screen);
g_free(self);
}
/*****************************************************************************/
int xrdp_wm_send_palette(struct xrdp_wm* self)
{
int i;
int color;
xrdp_rdp_init_data(self->rdp_layer, 776);
out_uint16_le(self->out_s, RDP_UPDATE_PALETTE);
out_uint16_le(self->out_s, 0);
out_uint16_le(self->out_s, 256); /* # of colors */
out_uint16_le(self->out_s, 0);
for (i = 0; i < 256; i++)
{
color = self->palette[i];
out_uint8(self->out_s, color >> 16);
out_uint8(self->out_s, color >> 8);
out_uint8(self->out_s, color);
}
s_mark_end(self->out_s);
xrdp_rdp_send_data(self->rdp_layer, RDP_DATA_PDU_UPDATE);
return 0;
}
/*****************************************************************************/
/* todo */
int xrdp_wm_send_bitmap(struct xrdp_wm* self, struct xrdp_bitmap* bitmap,
int x, int y, int cx, int cy)
{
int data_size;
int line_size;
int i;
int total_lines;
int lines_sending;
char* p;
data_size = bitmap->width * bitmap->height * ((bitmap->bpp + 7) / 8);
line_size = bitmap->width * ((bitmap->bpp + 7) / 8);
total_lines = data_size / line_size;
i = 0;
p = bitmap->data;
lines_sending = 4096 / line_size;
if (lines_sending > total_lines)
lines_sending = total_lines;
while (i < total_lines)
{
xrdp_rdp_init_data(self->rdp_layer, 8192);
out_uint16_le(self->out_s, RDP_UPDATE_BITMAP);
out_uint16_le(self->out_s, 1); /* num updates */
out_uint16_le(self->out_s, x);
out_uint16_le(self->out_s, y + i);
out_uint16_le(self->out_s, (x + cx) - 1);
out_uint16_le(self->out_s, (y + i + cy) - 1);
out_uint16_le(self->out_s, bitmap->width);
out_uint16_le(self->out_s, lines_sending);
out_uint16_le(self->out_s, bitmap->bpp); /* bpp */
out_uint16_le(self->out_s, 0); /* compress */
out_uint16_le(self->out_s, line_size * lines_sending); /* bufsize */
out_uint8a(self->out_s, p, line_size * lines_sending);
s_mark_end(self->out_s);
xrdp_rdp_send_data(self->rdp_layer, RDP_DATA_PDU_UPDATE);
p = p + line_size * lines_sending;
i = i + lines_sending;
if (i + lines_sending > total_lines)
lines_sending = total_lines - i;
if (lines_sending <= 0)
break;
}
return 0;
}
/*****************************************************************************/
int xrdp_wm_color15(int r, int g, int b)
{
r = r >> 3;
g = g >> 3;
b = b >> 3;
return (r << 10) | (g << 5) | b;
}
/*****************************************************************************/
int xrdp_wm_color16(int r, int g, int b)
{
r = r >> 3;
g = g >> 2;
b = b >> 3;
return (r << 11) | (g << 5) | b;
}
/*****************************************************************************/
int xrdp_wm_color24(int r, int g, int b)
{
return r | (g << 8) | (b << 16);
}
/*****************************************************************************/
/* all login help screen events go here */
int xrdp_wm_login_help_notify(struct xrdp_bitmap* wnd,
struct xrdp_bitmap* sender,
int msg, int param1, int param2)
{
if (wnd == 0)
return 0;
if (sender == 0)
return 0;
if (wnd->owner == 0)
return 0;
if (msg == 1) /* click */
{
if (sender->id == 1) /* ok button */
{
if (sender->owner->notify != 0)
{
wnd->owner->notify(wnd->owner, wnd, 100, 1, 0); /* ok */
}
}
}
return 0;
}
/*****************************************************************************/
int xrdp_wm_set_focused(struct xrdp_wm* self, struct xrdp_bitmap* wnd)
{
if (self == 0)
return 0;
if (self->focused_window == wnd)
return 0;
if (self->focused_window != 0)
{
xrdp_bitmap_set_focus(self->focused_window, 0);
}
self->focused_window = wnd;
if (self->focused_window != 0)
{
xrdp_bitmap_set_focus(self->focused_window, 1);
}
return 0;
}
/*****************************************************************************/
/* all login screen events go here */
int xrdp_wm_login_notify(struct xrdp_bitmap* wnd,
struct xrdp_bitmap* sender,
int msg, int param1, int param2)
{
struct xrdp_bitmap* help;
struct xrdp_bitmap* but;
struct xrdp_bitmap* b;
struct xrdp_rect rect;
int i;
if (msg == 1) /* click */
{
if (sender->id == 1) /* help button */
{
/* create help screen */
help = xrdp_bitmap_create(300, 300, wnd->wm->screen->bpp, 1);
xrdp_list_insert_item(wnd->wm->screen->child_list, 0, (int)help);
help->parent = wnd->wm->screen;
help->owner = wnd;
wnd->modal_dialog = help;
help->wm = wnd->wm;
help->bg_color = wnd->wm->grey;
help->left = wnd->wm->screen->width / 2 - help->width / 2;
help->top = wnd->wm->screen->height / 2 - help->height / 2;
help->notify = xrdp_wm_login_help_notify;
/* ok button */
but = xrdp_bitmap_create(60, 25, wnd->wm->screen->bpp, 3);
xrdp_list_insert_item(help->child_list, 0, (int)but);
but->parent = help;
but->owner = help;
but->wm = wnd->wm;
but->left = 120;
but->top = 260;
but->id = 1;
/* draw it */
xrdp_bitmap_invalidate(help, 0);
xrdp_wm_set_focused(wnd->wm, help);
}
else if (sender->id == 2) /* cancel button */
{
/*if (wnd != 0)
if (wnd->wm != 0)
if (wnd->wm->pro_layer != 0)
wnd->wm->pro_layer->term = 1;*/
}
}
else if (msg == 2) /* mouse move */
{
}
else if (msg == 100) /* modal result is done */
{
i = xrdp_list_index_of(wnd->wm->screen->child_list, (int)sender);
if (i >= 0)
{
b = (struct xrdp_bitmap*)
xrdp_list_get_item(wnd->wm->screen->child_list, i);
xrdp_list_remove_item(sender->wm->screen->child_list, i);
xrdp_wm_rect(&rect, b->left, b->top, b->width, b->height);
xrdp_bitmap_invalidate(wnd->wm->screen, &rect);
xrdp_bitmap_delete(sender);
wnd->modal_dialog = 0;
xrdp_wm_set_focused(wnd->wm, wnd);
}
}
return 0;
}
/*****************************************************************************/
int xrdp_set_cursor(struct xrdp_wm* self, int cache_idx)
{
xrdp_rdp_init_data(self->rdp_layer, 8000);
out_uint16_le(self->out_s, RDP_POINTER_CACHED);
out_uint16_le(self->out_s, 0); /* pad */
out_uint16_le(self->out_s, cache_idx); /* cache_idx */
s_mark_end(self->out_s);
xrdp_rdp_send_data(self->rdp_layer, RDP_DATA_PDU_POINTER);
return 0;
}
/*****************************************************************************/
/* send a cursor from a file */
int xrdp_send_cursor(struct xrdp_wm* self, char* file_name, int cache_idx)
{
int v;
int fd;
int w;
int h;
struct stream* s;
s = (struct stream*)g_malloc(sizeof(struct stream), 1);
init_stream(s, 8001);
fd = g_file_open(file_name);
g_file_read(fd, s->data, 8000);
g_file_close(fd);
xrdp_rdp_init_data(self->rdp_layer, 8000);
out_uint16_le(self->out_s, RDP_POINTER_COLOR);
out_uint16_le(self->out_s, 0); /* pad */
out_uint16_le(self->out_s, cache_idx); /* cache_idx */
in_uint32_le(s, v);
out_uint16_le(self->out_s, v); /* x */
in_uint32_le(s, v);
out_uint16_le(self->out_s, v); /* y */
in_uint32_le(s, w);
out_uint16_le(self->out_s, w); /* width */
in_uint32_le(s, h);
out_uint16_le(self->out_s, h); /* height */
v = (w * h) / 8;
out_uint16_le(self->out_s, v); /* mask len */
v = (w * h) * 3;
out_uint16_le(self->out_s, v); /* data len */
v = ((w * h) / 8) + ((w * h) * 3);
out_uint8a(self->out_s, s->p, v);
s_mark_end(self->out_s);
xrdp_rdp_send_data(self->rdp_layer, RDP_DATA_PDU_POINTER);
g_free(s->data);
g_free(s);
return 0;
}
/*****************************************************************************/
int xrdp_wm_init(struct xrdp_wm* self)
{
struct xrdp_bitmap* but;
if (self->screen->bpp == 8)
{
/* rgb */
self->palette[250] = 0x00ff0000;
self->palette[251] = 0x0000ff00;
self->palette[252] = 0x00c0c0c0;
self->palette[253] = 0x00808080;
self->palette[254] = 0x000000ff;
self->palette[255] = 0x00ffffff;
self->black = 0;
self->grey = 252;
self->dark_grey = 253;
self->blue = 254;
self->white = 255;
self->red = 250;
self->green = 251;
xrdp_wm_send_palette(self);
}
else if (self->screen->bpp == 15)
{
self->black = xrdp_wm_color15(0, 0, 0);
self->grey = xrdp_wm_color15(0xc0, 0xc0, 0xc0);
self->dark_grey = xrdp_wm_color15(0x80, 0x80, 0x80);
self->blue = xrdp_wm_color15(0x00, 0x00, 0xff);
self->white = xrdp_wm_color15(0xff, 0xff, 0xff);
self->red = xrdp_wm_color15(0xff, 0x00, 0x00);
self->green = xrdp_wm_color15(0x00, 0xff, 0x00);
}
else if (self->screen->bpp == 16)
{
self->black = xrdp_wm_color16(0, 0, 0);
self->grey = xrdp_wm_color16(0xc0, 0xc0, 0xc0);
self->dark_grey = xrdp_wm_color16(0x80, 0x80, 0x80);
self->blue = xrdp_wm_color16(0x00, 0x00, 0xff);
self->white = xrdp_wm_color16(0xff, 0xff, 0xff);
self->red = xrdp_wm_color16(0xff, 0x00, 0x00);
self->green = xrdp_wm_color16(0x00, 0xff, 0x00);
}
else if (self->screen->bpp == 24)
{
self->black = xrdp_wm_color24(0, 0, 0);
self->grey = xrdp_wm_color24(0xc0, 0xc0, 0xc0);
self->dark_grey = xrdp_wm_color24(0x80, 0x80, 0x80);
self->blue = xrdp_wm_color24(0x00, 0x00, 0xff);
self->white = xrdp_wm_color24(0xff, 0xff, 0xff);
self->red = xrdp_wm_color24(0xff, 0x00, 0x00);
self->green = xrdp_wm_color24(0x00, 0xff, 0x00);
}
/* draw login window */
self->login_window = xrdp_bitmap_create(400, 200, self->screen->bpp, 1);
xrdp_list_add_item(self->screen->child_list, (int)self->login_window);
self->login_window->parent = self->screen;
self->login_window->owner = self->screen;
self->login_window->wm = self;
self->login_window->bg_color = self->grey;
self->login_window->left = self->screen->width / 2 -
self->login_window->width / 2;
self->login_window->top = self->screen->height / 2 -
self->login_window->height / 2;
self->login_window->notify = xrdp_wm_login_notify;
/* image */
but = xrdp_bitmap_create(4, 4, self->screen->bpp, 4);
xrdp_bitmap_load(but, "xrdp256.bmp", self->palette);
but->parent = self->screen;
but->owner = self->screen;
but->wm = self;
but->left = self->screen->width - but->width;
but->top = self->screen->height - but->height;
xrdp_list_add_item(self->screen->child_list, (int)but);
/* image */
but = xrdp_bitmap_create(4, 4, self->screen->bpp, 4);
xrdp_bitmap_load(but, "ad256.bmp", self->palette);
but->parent = self->login_window;
but->owner = self->login_window;
but->wm = self;
but->left = 10;
but->top = 30;
xrdp_list_add_item(self->login_window->child_list, (int)but);
but = xrdp_bitmap_create(60, 25, self->screen->bpp, 3);
xrdp_list_add_item(self->login_window->child_list, (int)but);
but->parent = self->login_window;
but->owner = self->login_window;
but->wm = self;
but->left = 320;
but->top = 160;
but->id = 1;
but = xrdp_bitmap_create(60, 25, self->screen->bpp, 3);
xrdp_list_add_item(self->login_window->child_list, (int)but);
but->parent = self->login_window;
but->owner = self->login_window;
but->wm = self;
but->left = 250;
but->top = 160;
but->id = 2;
but = xrdp_bitmap_create(60, 25, self->screen->bpp, 3);
xrdp_list_add_item(self->login_window->child_list, (int)but);
but->parent = self->login_window;
but->owner = self->login_window;
but->wm = self;
but->left = 180;
but->top = 160;
but->id = 3;
but = xrdp_bitmap_create(140, 20, self->screen->bpp, 5);
xrdp_list_add_item(self->login_window->child_list, (int)but);
but->parent = self->login_window;
but->owner = self->login_window;
but->wm = self;
but->left = 220;
but->top = 50;
but->id = 4;
but->cursor = 1;
but = xrdp_bitmap_create(140, 20, self->screen->bpp, 5);
xrdp_list_add_item(self->login_window->child_list, (int)but);
but->parent = self->login_window;
but->owner = self->login_window;
but->wm = self;
but->left = 220;
but->top = 80;
but->id = 5;
but->cursor = 1;
/* clear screen */
self->screen->bg_color = self->black;
xrdp_bitmap_invalidate(self->screen, 0);
xrdp_wm_set_focused(self, self->login_window);
xrdp_send_cursor(self, "cursor1.cur", 1);
xrdp_send_cursor(self, "cursor0.cur", 0);
//xrdp_set_cursor(self, 1);
return 0;
}
/*****************************************************************************/
/* returns the number for rects visible for an area relative to a drawable */
/* putting the rects in region */
int xrdp_wm_get_vis_region(struct xrdp_wm* self, struct xrdp_bitmap* bitmap,
int x, int y, int cx, int cy,
struct xrdp_region* region)
{
int i;
struct xrdp_bitmap* p;
struct xrdp_rect a;
struct xrdp_rect b;
/* area we are drawing */
xrdp_wm_rect(&a, bitmap->left + x, bitmap->top + y, cx, cy);
p = bitmap->parent;
while (p != 0)
{
xrdp_wm_rect_offset(&a, p->left, p->top);
p = p->parent;
}
xrdp_region_add_rect(region, &a);
if (bitmap == self->screen)
return 0;
/* loop through all windows in z order */
for (i = 0; i < self->screen->child_list->count; i++)
{
p = (struct xrdp_bitmap*)xrdp_list_get_item(self->screen->child_list, i);
if (p == bitmap || p == bitmap->parent)
return 0;
xrdp_wm_rect(&b, p->left, p->top, p->width, p->height);
xrdp_region_subtract_rect(region, &b);
}
return 0;
}
/*****************************************************************************/
/* return the window at x, y on the screen */
struct xrdp_bitmap* xrdp_wm_at_pos(struct xrdp_bitmap* wnd, int x, int y,
struct xrdp_bitmap** wnd1)
{
int i;
struct xrdp_bitmap* p;
struct xrdp_bitmap* q;
/* loop through all windows in z order */
for (i = 0; i < wnd->child_list->count; i++)
{
p = (struct xrdp_bitmap*)xrdp_list_get_item(wnd->child_list, i);
if (x >= p->left && y >= p->top && x < p->left + p->width &&
y < p->top + p->height)
{
if (wnd1 != 0)
*wnd1 = p;
q = xrdp_wm_at_pos(p, x - p->left, y - p->top, 0);
if (q == 0)
return p;
else
return q;
}
}
return 0;
}
/*****************************************************************************/
int xrdp_wm_xor_pat(struct xrdp_wm* self, int x, int y, int cx, int cy)
{
self->painter->rop = 0x5a;
xrdp_painter_begin_update(self->painter);
self->painter->use_clip = 0;
self->painter->brush.pattern[0] = 0xaa;
self->painter->brush.pattern[1] = 0x55;
self->painter->brush.pattern[2] = 0xaa;
self->painter->brush.pattern[3] = 0x55;
self->painter->brush.pattern[4] = 0xaa;
self->painter->brush.pattern[5] = 0x55;
self->painter->brush.pattern[6] = 0xaa;
self->painter->brush.pattern[7] = 0x55;
self->painter->brush.x_orgin = 0;
self->painter->brush.x_orgin = 0;
self->painter->brush.style = 3;
self->painter->bg_color = self->black;
self->painter->fg_color = self->white;
/* top */
xrdp_painter_fill_rect2(self->painter, self->screen, x, y, cx, 5);
/* bottom */
xrdp_painter_fill_rect2(self->painter, self->screen, x, y + (cy - 5), cx, 5);
/* left */
xrdp_painter_fill_rect2(self->painter, self->screen, x, y + 5, 5, cy - 10);
/* right */
xrdp_painter_fill_rect2(self->painter, self->screen, x + (cx - 5), y + 5, 5,
cy - 10);
xrdp_painter_end_update(self->painter);
self->painter->rop = 0xcc;
return 0;
}
/*****************************************************************************/
/* this don't are about nothing, just copy the bits */
/* no clipping rects, no windows in the way, nothing */
int xrdp_wm_bitblt(struct xrdp_wm* self,
struct xrdp_bitmap* dst, int dx, int dy,
struct xrdp_bitmap* src, int sx, int sy,
int sw, int sh, int rop)
{
// int i;
// int line_size;
// int Bpp;
// char* s;
// char* d;
// if (sw <= 0 || sh <= 0)
// return 0;
if (self->screen == dst && self->screen == src)
{ /* send a screen blt */
// Bpp = (dst->bpp + 7) / 8;
// line_size = sw * Bpp;
// s = src->data + (sy * src->width + sx) * Bpp;
// d = dst->data + (dy * dst->width + dx) * Bpp;
// for (i = 0; i < sh; i++)
// {
// //g_memcpy(d, s, line_size);
// s += src->width * Bpp;
// d += dst->width * Bpp;
// }
xrdp_orders_init(self->orders);
xrdp_orders_screen_blt(self->orders, dx, dy, sw, sh, sx, sy, rop, 0);
xrdp_orders_send(self->orders);
}
return 0;
}
/*****************************************************************************/
/* return true is rect is totaly exposed going in reverse z order */
/* from wnd up */
int xrdp_wm_is_rect_vis(struct xrdp_wm* self, struct xrdp_bitmap* wnd,
struct xrdp_rect* rect)
{
struct xrdp_rect rect1;
struct xrdp_rect rect2;
struct xrdp_bitmap* b;
int i;;
/* if rect is part off screen */
if (rect->left < 0)
return 0;
if (rect->top < 0)
return 0;
if (rect->right >= self->screen->width)
return 0;
if (rect->bottom >= self->screen->height)
return 0;
i = xrdp_list_index_of(self->screen->child_list, (int)wnd);
i--;
while (i >= 0)
{
b = (struct xrdp_bitmap*)xrdp_list_get_item(self->screen->child_list, i);
xrdp_wm_rect(&rect1, b->left, b->top, b->width, b->height);
if (xrdp_wm_rect_intersect(rect, &rect1, &rect2))
return 0;
i--;
}
return 1;
}
/*****************************************************************************/
int xrdp_wm_move_window(struct xrdp_wm* self, struct xrdp_bitmap* wnd,
int dx, int dy)
{
struct xrdp_rect rect1;
struct xrdp_rect rect2;
struct xrdp_region* r;
int i;
xrdp_wm_rect(&rect1, wnd->left, wnd->top, wnd->width, wnd->height);
if (xrdp_wm_is_rect_vis(self, wnd, &rect1))
{
rect2 = rect1;
xrdp_wm_rect_offset(&rect2, dx, dy);
if (xrdp_wm_is_rect_vis(self, wnd, &rect2))
{ /* if both src and dst are unobscured, we can do a bitblt move */
xrdp_wm_bitblt(self, self->screen, wnd->left + dx, wnd->top + dy,
self->screen, wnd->left, wnd->top,
wnd->width, wnd->height, 0xcc);
wnd->left += dx;
wnd->top += dy;
r = xrdp_region_create(self);
xrdp_region_add_rect(r, &rect1);
xrdp_region_subtract_rect(r, &rect2);
i = 0;
while (xrdp_region_get_rect(r, i, &rect1) == 0)
{
xrdp_bitmap_invalidate(self->screen, &rect1);
i++;
}
xrdp_region_delete(r);
return 0;
}
}
wnd->left += dx;
wnd->top += dy;
xrdp_bitmap_invalidate(self->screen, &rect1);
xrdp_bitmap_invalidate(wnd, 0);
return 0;
}
/*****************************************************************************/
int xrdp_wm_rect(struct xrdp_rect* r, int x, int y, int cx, int cy)
{
r->left = x;
r->top = y;
r->right = x + cx;
r->bottom = y + cy;
return 0;
}
/*****************************************************************************/
int xrdp_wm_rect_is_empty(struct xrdp_rect* in)
{
return (in->right <= in->left) || (in->bottom <= in->top);
}
/*****************************************************************************/
int xrdp_wm_rect_contains_pt(struct xrdp_rect* in, int x, int y)
{
if (x < in->left)
return 0;
if (y < in->top)
return 0;
if (x >= in->right)
return 0;
if (y >= in->bottom)
return 0;
return 1;
}
/*****************************************************************************/
int xrdp_wm_rect_intersect(struct xrdp_rect* in1, struct xrdp_rect* in2,
struct xrdp_rect* out)
{
int rv;
*out = *in1;
if (in2->left > in1->left)
out->left = in2->left;
if (in2->top > in1->top)
out->top = in2->top;
if (in2->right < in1->right)
out->right = in2->right;
if (in2->bottom < in1->bottom)
out->bottom = in2->bottom;
rv = !xrdp_wm_rect_is_empty(out);
if (!rv)
g_memset(out, 0, sizeof(struct xrdp_rect));
return rv;
}
/*****************************************************************************/
int xrdp_wm_rect_offset(struct xrdp_rect* in, int dx, int dy)
{
in->left += dx;
in->right += dx;
in->top += dy;
in->bottom += dy;
return 0;
}
/*****************************************************************************/
int xrdp_wm_mouse_move(struct xrdp_wm* self, int x, int y)
{
struct xrdp_bitmap* b;
int boxx;
int boxy;
DEBUG(("in mouse move\n\r"));
if (self == 0)
return 0;
if (x < 0)
x = 0;
if (y < 0)
y = 0;
if (x >= self->screen->width)
x = self->screen->width;
if (y >= self->screen->height)
y = self->screen->height;
if (self->dragging)
{
xrdp_painter_begin_update(self->painter);
boxx = self->draggingx - self->draggingdx;
boxy = self->draggingy - self->draggingdy;
xrdp_wm_xor_pat(self, boxx, boxy, self->draggingcx, self->draggingcy);
self->draggingx = x;
self->draggingy = y;
boxx = self->draggingx - self->draggingdx;
boxy = self->draggingy - self->draggingdy;
xrdp_wm_xor_pat(self, boxx, boxy, self->draggingcx, self->draggingcy);
xrdp_painter_end_update(self->painter);
}
b = xrdp_wm_at_pos(self->screen, x, y, 0);
if (self->button_down != 0)
{
if (b == self->button_down && self->button_down->state == 0)
{
self->button_down->state = 1;
xrdp_bitmap_invalidate(self->button_down, 0);
}
else if (b != self->button_down)
{
self->button_down->state = 0;
xrdp_bitmap_invalidate(self->button_down, 0);
}
}
if (b != 0)
{
if (!self->dragging)
{
if (b->cursor != self->current_cursor)
{
xrdp_set_cursor(self, b->cursor);
self->current_cursor = b->cursor;
}
if (self->button_down == 0)
if (b->notify != 0)
b->notify(b->owner, b, 2, x, y);
}
}
DEBUG(("out mouse move\n\r"));
return 0;
}
/*****************************************************************************/
int xrdp_wm_mouse_click(struct xrdp_wm* self, int x, int y, int but, int down)
{
struct xrdp_bitmap* b;
struct xrdp_bitmap* b1;
int newx;
int newy;
int oldx;
int oldy;
if (self == 0)
return 0;
if (x < 0)
x = 0;
if (y < 0)
y = 0;
if (x >= self->screen->width)
x = self->screen->width;
if (y >= self->screen->height)
y = self->screen->height;
if (self->dragging && but == 1 && !down && self->dragging_window != 0)
{ /* if done dragging */
self->draggingx = x;
self->draggingy = y;
newx = self->draggingx - self->draggingdx;
newy = self->draggingy - self->draggingdy;
oldx = self->dragging_window->left;
oldy = self->dragging_window->top;
/* draw xor box one more time */
xrdp_wm_xor_pat(self, newx, newy, self->draggingcx, self->draggingcy);
/* move screen to new location */
xrdp_wm_move_window(self, self->dragging_window, newx - oldx, newy - oldy);
self->dragging_window = 0;
self->dragging = 0;
}
b = xrdp_wm_at_pos(self->screen, x, y, &b1);
if (b != 0)
{
if (b->type == 3 && but == 1 && !down && self->button_down == b)
{ /* if clicking up on a button that was clicked down */
self->button_down = 0;
b->state = 0;
xrdp_bitmap_invalidate(b, 0);
if (b->parent != 0)
if (b->parent->notify != 0)
/* b can be invalid after this */
b->parent->notify(b->owner, b, 1, x, y);
}
else if (b->type == 3 && but == 1 && down)
{ /* if clicking down on a button */
self->button_down = b;
b->state = 1;
xrdp_bitmap_invalidate(b, 0);
}
else if (but == 1 && down)
{
xrdp_wm_set_focused(self, b1);
if (b->type == 1 && y < (b->top + 21))
{ /* if dragging */
if (self->dragging) /* rarely happens */
{
newx = self->draggingx - self->draggingdx;
newy = self->draggingy - self->draggingdy;
xrdp_wm_xor_pat(self, newx, newy, self->draggingcx,
self->draggingcy);
}
self->dragging = 1;
self->dragging_window = b;
self->draggingorgx = b->left;
self->draggingorgy = b->top;
self->draggingx = x;
self->draggingy = y;
self->draggingdx = x - b->left;
self->draggingdy = y - b->top;
self->draggingcx = b->width;
self->draggingcy = b->height;
newx = self->draggingx - self->draggingdx;
newy = self->draggingy - self->draggingdy;
xrdp_wm_xor_pat(self, newx, newy, self->draggingcx, self->draggingcy);
}
}
}
else
xrdp_wm_set_focused(self, 0);
/* no matter what, mouse is up, reset button_down */
if (but == 1 && !down && self->button_down != 0)
self->button_down = 0;
return 0;
}
Loading…
Cancel
Save