major work and login screen
This commit is contained in:
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
|
||||
|
205
xrdp/os_calls.c
205
xrdp/os_calls.c
@ -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
|
||||
|
||||
/*****************************************************************************/
|
||||
void g_printf(char *format, ...)
|
||||
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_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;
|
||||
}
|
||||
|
140
xrdp/xrdp.h
140
xrdp/xrdp.h
@ -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);
|
||||
|
479
xrdp/xrdp_bitmap.c
Normal file
479
xrdp/xrdp_bitmap.c
Normal file
@ -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;
|
||||
}
|
145
xrdp/xrdp_cache.c
Normal file
145
xrdp/xrdp_cache.c
Normal file
@ -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;
|
||||
}
|
||||
|
149
xrdp/xrdp_list.c
Normal file
149
xrdp/xrdp_list.c
Normal file
@ -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;
|
||||
|
976
xrdp/xrdp_orders.c
Normal file
976
xrdp/xrdp_orders.c
Normal file
@ -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;
|
||||
}
|
333
xrdp/xrdp_painter.c
Normal file
333
xrdp/xrdp_painter.c
Normal file
@ -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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
286
xrdp/xrdp_region.c
Normal file
286
xrdp/xrdp_region.c
Normal file
@ -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,14 +388,14 @@ 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 */
|
||||
@ -408,7 +410,8 @@ int xrdp_sec_recv(struct xrdp_sec* self)
|
||||
xrdp_sec_rsa_op(self->client_random, self->client_crypt_random,
|
||||
pub_mod, pri_exp);
|
||||
xrdp_sec_establish_keys(self);
|
||||
continue;
|
||||
*chan = 1; /* just set a non existing channel and exit */
|
||||
return 0;
|
||||
}
|
||||
if (flags & SEC_LOGON_INFO) /* 0x40 */
|
||||
{
|
||||
@ -416,7 +419,8 @@ int xrdp_sec_recv(struct xrdp_sec* self)
|
||||
return 1;
|
||||
if (xrdp_sec_send_lic_initial(self) != 0)
|
||||
return 1;
|
||||
continue;
|
||||
*chan = 1; /* just set a non existing channel and exit */
|
||||
return 0;
|
||||
}
|
||||
if (flags & SEC_LICENCE_NEG) /* 0x80 */
|
||||
{
|
||||
@ -424,10 +428,8 @@ int xrdp_sec_recv(struct xrdp_sec* self)
|
||||
return 1;
|
||||
return -1; /* special error that means send demand active */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
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);
|
||||
};
|
||||
|
886
xrdp/xrdp_wm.c
Normal file
886
xrdp/xrdp_wm.c
Normal file
@ -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…
Reference in New Issue
Block a user