diff --git a/vnc/vnc.c b/vnc/vnc.c index 02e1c0b0..b0fef05c 100644 --- a/vnc/vnc.c +++ b/vnc/vnc.c @@ -712,7 +712,8 @@ int DEFAULT_CC lib_mod_start(struct vnc* v, int w, int h, int bpp) { v->server_begin_update(v); - v->server_fill_rect(v, 0, 0, w, h, 0); + v->server_set_fgcolor(v, 0); + v->server_fill_rect(v, 0, 0, w, h); v->server_end_update(v); v->server_width = w; v->server_height = h; @@ -742,17 +743,17 @@ lib_mod_connect(struct vnc* v) int ok; int display; - v->server_msg(v, "started connecting"); + v->server_msg(v, "started connecting", 0); check_sec_result = 1; /* only support 8 and 16 bpp connections from rdp client */ if (v->server_bpp != 8 && v->server_bpp != 16) { - v->server_msg(v, "error - only supporting 8 and 16 bpp rdp connections"); + v->server_msg(v, "error - only supporting 8 and 16 bpp rdp connections", 0); return 1; } if (g_strcmp(v->ip, "") == 0) { - v->server_msg(v, "error - no ip set"); + v->server_msg(v, "error - no ip set", 0); return 1; } make_stream(s); @@ -764,7 +765,7 @@ lib_mod_connect(struct vnc* v) init_stream(s, 8192); v->sck = g_tcp_socket(); v->sck_closed = 0; - v->server_msg(v, "connecting to sesman"); + v->server_msg(v, "connecting to sesman", 0); if (g_tcp_connect(v->sck, v->ip, "3350") == 0) { g_tcp_set_non_blocking(v->sck); @@ -784,12 +785,12 @@ lib_mod_connect(struct vnc* v) s_pop_layer(s, channel_hdr); out_uint32_be(s, 0); // version out_uint32_be(s, s->end - s->data); // size - v->server_msg(v, "sending login info to sesman"); + v->server_msg(v, "sending login info to sesman", 0); error = lib_send(v, s->data, s->end - s->data); if (error == 0) { init_stream(s, 8192); - v->server_msg(v, "receiving sesman header"); + v->server_msg(v, "receiving sesman header", 0); error = lib_recv(v, s->data, 8); } if (error == 0) @@ -797,7 +798,7 @@ lib_mod_connect(struct vnc* v) in_uint32_be(s, version); in_uint32_be(s, size); init_stream(s, 8192); - v->server_msg(v, "receiving sesman data"); + v->server_msg(v, "receiving sesman data", 0); error = lib_recv(v, s->data, size - 8); } if (error == 0) @@ -815,7 +816,7 @@ lib_mod_connect(struct vnc* v) else { in_uint8s(s, 2); - v->server_msg(v, "error - sesman returned no"); + v->server_msg(v, "error - sesman returned no", 0); } } } @@ -823,16 +824,16 @@ lib_mod_connect(struct vnc* v) } else { - v->server_msg(v, "error - connecting to sesman"); + v->server_msg(v, "error - connecting to sesman", 0); } g_tcp_close(v->sck); if (error != 0 || display == 0) { - v->server_msg(v, "error - connection failed"); + v->server_msg(v, "error - connection failed", 0); free_stream(s); return 1; } - v->server_msg(v, "sesman started a session"); + v->server_msg(v, "sesman started a session", 0); g_sprintf(con_port, "%d", 5900 + display); v->vnc_desktop = display; } @@ -844,11 +845,11 @@ lib_mod_connect(struct vnc* v) v->sck = g_tcp_socket(); v->sck_closed = 0; g_sprintf(text, "connecting to %s %s", v->ip, con_port); - v->server_msg(v, text); + v->server_msg(v, text, 0); error = g_tcp_connect(v->sck, v->ip, con_port); if (error == 0) { - v->server_msg(v, "tcp connected"); + v->server_msg(v, "tcp connected", 0); g_tcp_set_non_blocking(v->sck); g_tcp_set_no_delay(v->sck); /* protocal version */ @@ -868,7 +869,7 @@ lib_mod_connect(struct vnc* v) { in_uint32_be(s, i); g_sprintf(text, "security level is %d (1 = none, 2 = standard)", i); - v->server_msg(v, text); + v->server_msg(v, text, 0); if (i == 1) /* none */ { check_sec_result = 0; @@ -899,25 +900,25 @@ lib_mod_connect(struct vnc* v) in_uint32_be(s, i); if (i != 0) { - v->server_msg(v, "password failed"); + v->server_msg(v, "password failed", 0); error = 2; } else { - v->server_msg(v, "password ok"); + v->server_msg(v, "password ok", 0); } } } if (error == 0) { - v->server_msg(v, "sending share flag"); + v->server_msg(v, "sending share flag", 0); init_stream(s, 8192); s->data[0] = 1; error = lib_send(v, s->data, 1); /* share flag */ } if (error == 0) { - v->server_msg(v, "receiving server init"); + v->server_msg(v, "receiving server init", 0); error = lib_recv(v, s->data, 4); /* server init */ } if (error == 0) @@ -925,14 +926,14 @@ lib_mod_connect(struct vnc* v) in_uint16_be(s, v->mod_width); in_uint16_be(s, v->mod_height); init_stream(pixel_format, 8192); - v->server_msg(v, "receiving pixel format"); + v->server_msg(v, "receiving pixel format", 0); error = lib_recv(v, pixel_format->data, 16); } if (error == 0) { v->mod_bpp = v->server_bpp; init_stream(s, 8192); - v->server_msg(v, "receiving name length"); + v->server_msg(v, "receiving name length", 0); error = lib_recv(v, s->data, 4); /* name len */ } if (error == 0) @@ -944,7 +945,7 @@ lib_mod_connect(struct vnc* v) } else { - v->server_msg(v, "receiving name"); + v->server_msg(v, "receiving name", 0); error = lib_recv(v, v->mod_name, i); v->mod_name[i] = 0; } @@ -996,7 +997,7 @@ lib_mod_connect(struct vnc* v) out_uint8s(pixel_format, 3); /* pad */ } out_uint8a(s, pixel_format->data, 16); - v->server_msg(v, "sending pixel format"); + v->server_msg(v, "sending pixel format", 0); error = lib_send(v, s->data, 20); } if (error == 0) @@ -1009,7 +1010,7 @@ lib_mod_connect(struct vnc* v) out_uint32_be(s, 0); /* raw */ out_uint32_be(s, 1); /* copy rect */ out_uint32_be(s, 0xffffff11); /* cursor */ - v->server_msg(v, "sending encodings"); + v->server_msg(v, "sending encodings", 0); error = lib_send(v, s->data, 4 + 3 * 4); } if (error == 0) @@ -1022,14 +1023,14 @@ lib_mod_connect(struct vnc* v) out_uint16_be(s, 0); out_uint16_be(s, v->mod_width); out_uint16_be(s, v->mod_height); - v->server_msg(v, "sending framebuffer update request"); + v->server_msg(v, "sending framebuffer update request", 0); error = lib_send(v, s->data, 10); } if (error == 0) { if (v->server_bpp != v->mod_bpp) { - v->server_msg(v, "error - server and client bpp don't match"); + v->server_msg(v, "error - server and client bpp don't match", 0); error = 1; } } @@ -1041,18 +1042,18 @@ lib_mod_connect(struct vnc* v) g_memset(cursor_data + (32 * (32 * 3) - 2 * 32 * 3), 0xff, 9); g_memset(cursor_data + (32 * (32 * 3) - 3 * 32 * 3), 0xff, 9); g_memset(cursor_mask, 0xff, 32 * (32 / 8)); - v->server_msg(v, "sending cursor"); + v->server_msg(v, "sending cursor", 0); error = v->server_set_cursor(v, 3, 3, cursor_data, cursor_mask); } free_stream(s); free_stream(pixel_format); if (error == 0) { - v->server_msg(v, "connection complete, connected ok"); + v->server_msg(v, "connection complete, connected ok", 0); } else { - v->server_msg(v, "error - problem connecting"); + v->server_msg(v, "error - problem connecting", 0); } return error; } diff --git a/vnc/vnc.h b/vnc/vnc.h index 92ba5f70..0fad0d3a 100644 --- a/vnc/vnc.h +++ b/vnc/vnc.h @@ -40,18 +40,35 @@ struct vnc /* server functions */ int (*server_begin_update)(struct vnc* v); int (*server_end_update)(struct vnc* v); - int (*server_fill_rect)(struct vnc* v, int x, int y, int cx, int cy, - int color); + int (*server_fill_rect)(struct vnc* v, int x, int y, int cx, int cy); int (*server_screen_blt)(struct vnc* v, int x, int y, int cx, int cy, int srcx, int srcy); int (*server_paint_rect)(struct vnc* v, int x, int y, int cx, int cy, char* data); int (*server_set_cursor)(struct vnc* v, int x, int y, char* data, char* mask); int (*server_palette)(struct vnc* v, int* palette); - int (*server_msg)(struct vnc* v, char* msg); + int (*server_msg)(struct vnc* v, char* msg, int code); int (*server_is_term)(struct vnc* v); int (*server_set_clip)(struct vnc* v, int x, int y, int cx, int cy); int (*server_reset_clip)(struct vnc* v); + int (*server_set_fgcolor)(struct vnc* v, int fgcolor); + int (*server_set_bgcolor)(struct vnc* v, int bgcolor); + int (*server_set_opcode)(struct vnc* v, int opcode); + int (*server_set_mixmode)(struct vnc* v, int mixmode); + int (*server_set_brush)(struct vnc* v, int x_orgin, int y_orgin, + int style, char* pattern); + int (*server_set_pen)(struct vnc* v, int style, + int width); + int (*server_draw_line)(struct vnc* v, int x1, int y1, int x2, int y2); + int (*server_add_char)(struct vnc* v, int font, int charactor, + int offset, int baseline, + int width, int height, char* data); + int (*server_draw_text)(struct vnc* v, int font, + int flags, int mixmode, int clip_left, int clip_top, + int clip_right, int clip_bottom, + int box_left, int box_top, + int box_right, int box_bottom, + int x, int y, char* data, int data_len); /* common */ long handle; /* pointer to self as long */ long wm; diff --git a/xrdp/funcs.c b/xrdp/funcs.c index 65f40908..a4683cd9 100644 --- a/xrdp/funcs.c +++ b/xrdp/funcs.c @@ -83,6 +83,23 @@ rect_intersect(struct xrdp_rect* in1, struct xrdp_rect* in2, return rv; } +/*****************************************************************************/ +/* returns boolean */ +int APP_CC +rect_contained_by(struct xrdp_rect* in1, int left, int top, + int right, int bottom) +{ + if (left < in1->left || top < in1->top || + right > in1->right || bottom > in1->bottom) + { + return 0; + } + else + { + return 1; + } +} + /*****************************************************************************/ /* adjust the bounds to fit in the bitmap */ /* return false if there is nothing to draw else return true */ diff --git a/xrdp/xrdp.c b/xrdp/xrdp.c index 52f8ac5a..28118d6d 100644 --- a/xrdp/xrdp.c +++ b/xrdp/xrdp.c @@ -32,13 +32,59 @@ static int g_threadid = 0; /* main threadid */ #if defined(_WIN32) static CRITICAL_SECTION g_term_mutex; +static CRITICAL_SECTION g_sync_mutex; +static CRITICAL_SECTION g_sync1_mutex; #else static pthread_mutex_t g_term_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t g_sync_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t g_sync1_mutex = PTHREAD_MUTEX_INITIALIZER; #endif static int g_term = 0; +/* syncronize stuff */ +static int g_sync_command = 0; +static long g_sync_result = 0; +static long g_sync_param1 = 0; +static long g_sync_param2 = 0; +static long (*g_sync_func)(long param1, long param2); /*****************************************************************************/ -void +long APP_CC +g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1, + long sync_param2) +{ + long sync_result; + int sync_command; + +#if defined(_WIN32) + EnterCriticalSection(&g_sync1_mutex); +#else + pthread_mutex_lock(&g_sync1_mutex); +#endif + g_lock(); + g_sync_param1 = sync_param1; + g_sync_param2 = sync_param2; + g_sync_func = sync_func; + g_sync_command = 100; + g_unlock(); + do + { + g_sleep(100); + g_lock(); + sync_command = g_sync_command; + sync_result = g_sync_result; + g_unlock(); + } + while (sync_command != 0); +#if defined(_WIN32) + LeaveCriticalSection(&g_sync1_mutex); +#else + pthread_mutex_unlock(&g_sync1_mutex); +#endif + return sync_result; +} + +/*****************************************************************************/ +void DEFAULT_CC xrdp_shutdown(int sig) { struct xrdp_listen* listen; @@ -56,15 +102,11 @@ xrdp_shutdown(int sig) g_set_term(1); g_sleep(1000); xrdp_listen_delete(listen); -#if defined(_WIN32) - WSACleanup(); - DeleteCriticalSection(&g_term_mutex); -#endif } } /*****************************************************************************/ -int +int APP_CC g_is_term(void) { int rv; @@ -82,7 +124,29 @@ g_is_term(void) } /*****************************************************************************/ -void +void APP_CC +g_lock(void) +{ +#if defined(_WIN32) + EnterCriticalSection(&g_sync_mutex); +#else + pthread_mutex_lock(&g_sync_mutex); +#endif +} + +/*****************************************************************************/ +void APP_CC +g_unlock(void) +{ +#if defined(_WIN32) + LeaveCriticalSection(&g_sync_mutex); +#else + pthread_mutex_unlock(&g_sync_mutex); +#endif +} + +/*****************************************************************************/ +void APP_CC g_set_term(int in_val) { #if defined(_WIN32) @@ -97,7 +161,7 @@ g_set_term(int in_val) } /*****************************************************************************/ -void +void DEFAULT_CC pipe_sig(int sig_num) { /* do nothing */ @@ -105,7 +169,26 @@ pipe_sig(int sig_num) } /*****************************************************************************/ -int +void APP_CC +g_loop(void) +{ + g_lock(); + if (g_sync_command != 0) + { + if (g_sync_func != 0) + { + if (g_sync_command == 100) + { + g_sync_result = g_sync_func(g_sync_param1, g_sync_param2); + } + } + g_sync_command = 0; + } + g_unlock(); +} + +/*****************************************************************************/ +int DEFAULT_CC main(int argc, char** argv) { int test; @@ -113,7 +196,7 @@ main(int argc, char** argv) #if defined(_WIN32) WSADATA w; #endif - + /* check compiled endian with actual edian */ test = 1; host_be = !((int)(*(unsigned char*)(&test))); @@ -141,6 +224,8 @@ main(int argc, char** argv) #if defined(_WIN32) WSAStartup(2, &w); InitializeCriticalSection(&g_term_mutex); + InitializeCriticalSection(&g_sync_mutex); + InitializeCriticalSection(&g_sync1_mutex); #endif g_threadid = g_get_threadid(); g_listen = xrdp_listen_create(); @@ -149,5 +234,13 @@ main(int argc, char** argv) g_signal(13, pipe_sig); /* sig pipe */ g_signal(15, xrdp_shutdown); /* SIGTERM */ xrdp_listen_main_loop(g_listen); +#if defined(_WIN32) + /* I don't think it ever gets here */ + WSACleanup(); + DeleteCriticalSection(&g_term_mutex); + DeleteCriticalSection(&g_sync_mutex); + DeleteCriticalSection(&g_sync1_mutex); + xrdp_listen_delete(g_listen); +#endif return 0; } diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index c37a8e06..76012409 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -34,10 +34,19 @@ #include "file.h" /* xrdp.c */ -int +long APP_CC +g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1, + long sync_param2); +int APP_CC g_is_term(void); -void +void APP_CC g_set_term(int in_val); +void APP_CC +g_lock(void); +void APP_CC +g_unlock(void); +void APP_CC +g_loop(void); /* xrdp_cache.c */ struct xrdp_cache* APP_CC @@ -183,6 +192,11 @@ int APP_CC xrdp_bitmap_from_screenx(struct xrdp_bitmap* self, int x); int APP_CC xrdp_bitmap_from_screeny(struct xrdp_bitmap* self, int y); +int APP_CC +xrdp_bitmap_get_screen_clip(struct xrdp_bitmap* self, + struct xrdp_painter* painter, + struct xrdp_rect* rect, + int* dx, int* dy); /* xrdp_painter.c */ struct xrdp_painter* APP_CC @@ -205,10 +219,6 @@ xrdp_painter_fill_rect(struct xrdp_painter* self, struct xrdp_bitmap* bitmap, int x, int y, int cx, int cy); int APP_CC -xrdp_painter_fill_rect2(struct xrdp_painter* self, - struct xrdp_bitmap* bitmap, - int x, int y, int cx, int cy); -int APP_CC xrdp_painter_draw_bitmap(struct xrdp_painter* self, struct xrdp_bitmap* bitmap, struct xrdp_bitmap* to_draw, @@ -222,11 +232,24 @@ xrdp_painter_draw_text(struct xrdp_painter* self, struct xrdp_bitmap* bitmap, int x, int y, char* text); int APP_CC +xrdp_painter_draw_text2(struct xrdp_painter* self, + struct xrdp_bitmap* bitmap, + int font, int flags, int mixmode, + int clip_left, int clip_top, + int clip_right, int clip_bottom, + int box_left, int box_top, + int box_right, int box_bottom, + int x, int y, char* data, int data_len); +int APP_CC xrdp_painter_copy(struct xrdp_painter* self, struct xrdp_bitmap* src, struct xrdp_bitmap* dst, int x, int y, int cx, int cy, int srcx, int srcy); +int APP_CC +xrdp_painter_line(struct xrdp_painter* self, + struct xrdp_bitmap* bitmap, + int x1, int y1, int x2, int y2); /* xrdp_font.c */ struct xrdp_font* APP_CC @@ -244,6 +267,9 @@ int APP_CC rect_intersect(struct xrdp_rect* in1, struct xrdp_rect* in2, struct xrdp_rect* out); int APP_CC +rect_contained_by(struct xrdp_rect* in1, int left, int top, + int right, int bottom); +int APP_CC check_bounds(struct xrdp_bitmap* b, int* x, int* y, int* cx, int* cy); char APP_CC get_char_from_scan_code(int device_flags, int scan_code, int* keys, @@ -271,8 +297,7 @@ server_begin_update(struct xrdp_mod* mod); int DEFAULT_CC server_end_update(struct xrdp_mod* mod); int DEFAULT_CC -server_fill_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy, - int color); +server_fill_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy); int DEFAULT_CC server_screen_blt(struct xrdp_mod* mod, int x, int y, int cx, int cy, int srcx, int srcy); @@ -285,10 +310,36 @@ server_set_pointer(struct xrdp_mod* mod, int x, int y, int DEFAULT_CC server_palette(struct xrdp_mod* mod, int* palette); int DEFAULT_CC -server_msg(struct xrdp_mod* mod, char* msg); +server_msg(struct xrdp_mod* mod, char* msg, int code); int DEFAULT_CC server_is_term(struct xrdp_mod* mod); int DEFAULT_CC server_set_clip(struct xrdp_mod* mod, int x, int y, int cx, int cy); int DEFAULT_CC server_reset_clip(struct xrdp_mod* mod); +int DEFAULT_CC +server_set_fgcolor(struct xrdp_mod* mod, int fgcolor); +int DEFAULT_CC +server_set_bgcolor(struct xrdp_mod* mod, int bgcolor); +int DEFAULT_CC +server_set_opcode(struct xrdp_mod* mod, int opcode); +int DEFAULT_CC +server_set_mixmode(struct xrdp_mod* mod, int mixmode); +int DEFAULT_CC +server_set_brush(struct xrdp_mod* mod, int x_orgin, int y_orgin, + int style, char* pattern); +int DEFAULT_CC +server_set_pen(struct xrdp_mod* mod, int style, int width); +int DEFAULT_CC +server_draw_line(struct xrdp_mod* mod, int x1, int y1, int x2, int y2); +int DEFAULT_CC +server_add_char(struct xrdp_mod* mod, int font, int charactor, + int offset, int baseline, + int width, int height, char* data); +int DEFAULT_CC +server_draw_text(struct xrdp_mod* mod, int font, + int flags, int mixmode, int clip_left, int clip_top, + int clip_right, int clip_bottom, + int box_left, int box_top, + int box_right, int box_bottom, + int x, int y, char* data, int data_len); diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini index ef72bb46..0e0f1b67 100644 --- a/xrdp/xrdp.ini +++ b/xrdp/xrdp.ini @@ -34,3 +34,9 @@ ip=ask port=-1 username=ask password=ask + +[vnc5] +name=rdp-any +lib=../libradop/libradop.so +ip=ask205.5.61.3 +port=ask3389 diff --git a/xrdp/xrdp_bitmap.c b/xrdp/xrdp_bitmap.c index ac25a23d..bc1a2c46 100644 --- a/xrdp/xrdp_bitmap.c +++ b/xrdp/xrdp_bitmap.c @@ -773,6 +773,7 @@ xrdp_bitmap_draw_focus_box(struct xrdp_bitmap* self, painter->rop = 0xf0; xrdp_painter_begin_update(painter); painter->use_clip = 0; + painter->mix_mode = 1; painter->brush.pattern[0] = 0xaa; painter->brush.pattern[1] = 0x55; painter->brush.pattern[2] = 0xaa; @@ -787,15 +788,16 @@ xrdp_bitmap_draw_focus_box(struct xrdp_bitmap* self, painter->fg_color = self->wm->black; painter->bg_color = self->parent->bg_color; /* top */ - xrdp_painter_fill_rect2(painter, self, x, y, cx, 1); + xrdp_painter_fill_rect(painter, self, x, y, cx, 1); /* bottom */ - xrdp_painter_fill_rect2(painter, self, x, y + (cy - 1), cx, 1); + xrdp_painter_fill_rect(painter, self, x, y + (cy - 1), cx, 1); /* left */ - xrdp_painter_fill_rect2(painter, self, x, y + 1, 1, cy - 2); + xrdp_painter_fill_rect(painter, self, x, y + 1, 1, cy - 2); /* right */ - xrdp_painter_fill_rect2(painter, self, x + (cx - 1), y + 1, 1, cy - 2); + xrdp_painter_fill_rect(painter, self, x + (cx - 1), y + 1, 1, cy - 2); xrdp_painter_end_update(painter); painter->rop = 0xcc; + painter->mix_mode = 0; return 0; } @@ -905,7 +907,7 @@ xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect) return 0; } painter->clip = *rect; - painter->use_clip = 1; + painter->use_clip = &painter->clip; } xrdp_painter_begin_update(painter); if (self->type == WND_TYPE_WND) /* 1 */ @@ -1012,8 +1014,8 @@ xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect) } else if (self->type == WND_TYPE_IMAGE) /* 4 */ { - xrdp_painter_draw_bitmap(painter, self, self, 0, 0, self->width, - self->height); + xrdp_painter_copy(painter, self, self, 0, 0, self->width, + self->height, 0, 0); } else if (self->type == WND_TYPE_EDIT) /* 5 */ { @@ -1066,7 +1068,7 @@ xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect) else g_strncpy(text, self->caption1, self->edit_pos); w = xrdp_painter_text_width(painter, text); - painter->fg_color = self->wm->black; + painter->fg_color = self->wm->white; painter->rop = 0x5a; xrdp_painter_fill_rect(painter, self, 4 + w, 3, 2, self->height - 6); } @@ -1517,3 +1519,41 @@ xrdp_bitmap_from_screeny(struct xrdp_bitmap* self, int y) } return i; } + +/*****************************************************************************/ +int APP_CC +xrdp_bitmap_get_screen_clip(struct xrdp_bitmap* self, + struct xrdp_painter* painter, + struct xrdp_rect* rect, + int* dx, int* dy) +{ + int ldx; + int ldy; + + if (painter->use_clip) + { + *rect = painter->clip; + } + else + { + rect->left = 0; + rect->top = 0; + rect->right = self->width; + rect->bottom = self->height; + } + ldx = xrdp_bitmap_to_screenx(self, 0); + ldy = xrdp_bitmap_to_screeny(self, 0); + rect->left += ldx; + rect->top += ldy; + rect->right += ldx; + rect->bottom += ldy; + if (dx != 0) + { + *dx = ldx; + } + if (dy != 0) + { + *dy = ldy; + } + return 0; +} diff --git a/xrdp/xrdp_interface.c b/xrdp/xrdp_interface.c index 88011c1b..bea08cbc 100644 --- a/xrdp/xrdp_interface.c +++ b/xrdp/xrdp_interface.c @@ -107,15 +107,13 @@ server_end_update(struct xrdp_mod* mod) /*****************************************************************************/ int DEFAULT_CC -server_fill_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy, - int color) +server_fill_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy) { struct xrdp_wm* wm; struct xrdp_painter* p; wm = (struct xrdp_wm*)mod->wm; p = (struct xrdp_painter*)mod->painter; - p->fg_color = color; xrdp_painter_fill_rect(p, wm->screen, x, y, cx, cy); return 0; } @@ -147,7 +145,7 @@ server_paint_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy, wm = (struct xrdp_wm*)mod->wm; p = (struct xrdp_painter*)mod->painter; b = xrdp_bitmap_create_with_data(cx, cy, wm->screen->bpp, data, wm); - xrdp_painter_draw_bitmap(p, wm->screen, b, x, y, cx, cy); + xrdp_painter_copy(p, b, wm->screen, x, y, cx, cy, 0, 0); xrdp_bitmap_delete(b); return 0; } @@ -181,11 +179,17 @@ server_palette(struct xrdp_mod* mod, int* palette) /*****************************************************************************/ int DEFAULT_CC -server_msg(struct xrdp_mod* mod, char* msg) +server_msg(struct xrdp_mod* mod, char* msg, int code) { struct xrdp_wm* wm; struct xrdp_bitmap* but; + if (code == 1) + { + g_printf(msg); + g_printf("\n\r"); + return 0; + } wm = (struct xrdp_wm*)mod->wm; list_add_item(wm->log, (long)g_strdup(msg)); if (wm->log_wnd == 0) @@ -244,3 +248,127 @@ server_reset_clip(struct xrdp_mod* mod) p = (struct xrdp_painter*)mod->painter; return xrdp_painter_clr_clip(p); } + +/*****************************************************************************/ +int DEFAULT_CC +server_set_fgcolor(struct xrdp_mod* mod, int fgcolor) +{ + struct xrdp_painter* p; + + p = (struct xrdp_painter*)mod->painter; + p->fg_color = fgcolor; + p->pen.color = p->fg_color; + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_set_bgcolor(struct xrdp_mod* mod, int bgcolor) +{ + struct xrdp_painter* p; + + p = (struct xrdp_painter*)mod->painter; + p->bg_color = bgcolor; + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_set_opcode(struct xrdp_mod* mod, int opcode) +{ + struct xrdp_painter* p; + + p = (struct xrdp_painter*)mod->painter; + p->rop = opcode; + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_set_mixmode(struct xrdp_mod* mod, int mixmode) +{ + struct xrdp_painter* p; + + p = (struct xrdp_painter*)mod->painter; + p->mix_mode = mixmode; + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_set_brush(struct xrdp_mod* mod, int x_orgin, int y_orgin, + int style, char* pattern) +{ + struct xrdp_painter* p; + + p = (struct xrdp_painter*)mod->painter; + p->brush.x_orgin = x_orgin; + p->brush.y_orgin = y_orgin; + p->brush.style = style; + g_memcpy(p->brush.pattern, pattern, 8); + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_set_pen(struct xrdp_mod* mod, int style, int width) +{ + struct xrdp_painter* p; + + p = (struct xrdp_painter*)mod->painter; + p->pen.style = style; + p->pen.width = width; + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_draw_line(struct xrdp_mod* mod, int x1, int y1, int x2, int y2) +{ + struct xrdp_wm* wm; + struct xrdp_painter* p; + + wm = (struct xrdp_wm*)mod->wm; + p = (struct xrdp_painter*)mod->painter; + return xrdp_painter_line(p, wm->screen, x1, y1, x2, y2); +} + +/*****************************************************************************/ +int DEFAULT_CC +server_add_char(struct xrdp_mod* mod, int font, int charactor, + int offset, int baseline, + int width, int height, char* data) +{ + struct xrdp_font_char fi; + + fi.offset = offset; + fi.baseline = baseline; + fi.width = width; + fi.height = height; + fi.incby = 0; + fi.data = data; + return libxrdp_orders_send_font(((struct xrdp_wm*)mod->wm)->session, + &fi, font, charactor); +} + +/*****************************************************************************/ +int DEFAULT_CC +server_draw_text(struct xrdp_mod* mod, int font, + int flags, int mixmode, int clip_left, int clip_top, + int clip_right, int clip_bottom, + int box_left, int box_top, + int box_right, int box_bottom, + int x, int y, char* data, int data_len) +{ + struct xrdp_wm* wm; + struct xrdp_painter* p; + + wm = (struct xrdp_wm*)mod->wm; + p = (struct xrdp_painter*)mod->painter; + return xrdp_painter_draw_text2(p, wm->screen, font, flags, + mixmode, clip_left, clip_top, + clip_right, clip_bottom, + box_left, box_top, + box_right, box_bottom, + x, y, data, data_len); +} diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c index 1e399368..a78b15a4 100644 --- a/xrdp/xrdp_listen.c +++ b/xrdp/xrdp_listen.c @@ -149,6 +149,7 @@ xrdp_listen_main_loop(struct xrdp_listen* self) error = g_tcp_bind(self->sck, "3389"); if (error != 0) { + g_printf("listening on 3390\n\r"); error = g_tcp_bind(self->sck, "3390"); } if (error != 0) @@ -167,6 +168,7 @@ xrdp_listen_main_loop(struct xrdp_listen* self) if (error == -1 && g_tcp_last_error_would_block(self->sck)) { g_sleep(100); + g_loop(); } else if (error == -1) { diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c index cdc1b7d6..57b84e66 100644 --- a/xrdp/xrdp_login_wnd.c +++ b/xrdp/xrdp_login_wnd.c @@ -89,6 +89,22 @@ xrdp_wm_popup_notify(struct xrdp_bitmap* wnd, } #endif +/*****************************************************************************/ +/* called from main thread */ +static long DEFAULT_CC +sync_unload(long param1, long param2) +{ + return g_free_library(param1); +} + +/*****************************************************************************/ +/* called from main thread */ +static long DEFAULT_CC +sync_load(long param1, long param2) +{ + return g_load_library((char*)param1); +} + /*****************************************************************************/ static int APP_CC xrdp_wm_setup_mod(struct xrdp_wm* self, @@ -102,7 +118,7 @@ xrdp_wm_setup_mod(struct xrdp_wm* self, } if (self->mod_handle == 0) { - self->mod_handle = g_load_library(mod_data->lib); + self->mod_handle = g_xrdp_sync(sync_load, (long)mod_data->lib, 0); if (self->mod_handle != 0) { func = g_get_proc_address(self->mod_handle, "mod_init"); @@ -136,6 +152,15 @@ xrdp_wm_setup_mod(struct xrdp_wm* self, self->mod->server_is_term = server_is_term; self->mod->server_set_clip = server_set_clip; self->mod->server_reset_clip = server_reset_clip; + self->mod->server_set_fgcolor = server_set_fgcolor; + self->mod->server_set_bgcolor = server_set_bgcolor; + self->mod->server_set_opcode = server_set_opcode; + self->mod->server_set_mixmode = server_set_mixmode; + self->mod->server_set_brush = server_set_brush; + self->mod->server_set_pen = server_set_pen; + self->mod->server_draw_line = server_draw_line; + self->mod->server_add_char = server_add_char; + self->mod->server_draw_text = server_draw_text; } } /* id self->mod is null, there must be a problem */ @@ -306,7 +331,7 @@ xrdp_wm_ok_clicked(struct xrdp_bitmap* wnd) { /* totaly free mod */ wm->mod_exit(wm->mod); - g_free_library(wm->mod_handle); + g_xrdp_sync(sync_unload, wm->mod_handle, 0); wm->mod = 0; wm->mod_handle = 0; wm->mod_init = 0; diff --git a/xrdp/xrdp_painter.c b/xrdp/xrdp_painter.c index f9e2630b..3800277c 100644 --- a/xrdp/xrdp_painter.c +++ b/xrdp/xrdp_painter.c @@ -132,7 +132,7 @@ int APP_CC xrdp_painter_set_clip(struct xrdp_painter* self, int x, int y, int cx, int cy) { - self->use_clip = 1; + self->use_clip = &self->clip; self->clip.left = x; self->clip.top = y; self->clip.right = x + cx; @@ -175,70 +175,69 @@ xrdp_painter_rop(int rop, int src, int dst) } /*****************************************************************************/ -/* fill in an area of the screen with one color */ int APP_CC -xrdp_painter_fill_rect(struct xrdp_painter* self, - struct xrdp_bitmap* bitmap, - int x, int y, int cx, int cy) +xrdp_painter_text_width(struct xrdp_painter* self, char* text) { - int i; - struct xrdp_region* region; - struct xrdp_rect rect; + int index; + int rv; + int len; + struct xrdp_font_char* font_item; - if (!check_bounds(bitmap, &x, &y, &cx, &cy)) + xrdp_painter_font_needed(self); + if (text == 0) { return 0; } - if (!xrdp_painter_clip_adj(self, &x, &y, &cx, &cy)) + rv = 0; + len = g_strlen(text); + for (index = 0; index < len; index++) { - return 0; + font_item = self->font->font_items + (unsigned char)text[index]; + rv = rv + font_item->incby; } + return rv; +} - /* todo data */ +/*****************************************************************************/ +int APP_CC +xrdp_painter_text_height(struct xrdp_painter* self, char* text) +{ + int index; + int rv; + int len; + struct xrdp_font_char* font_item; - if (bitmap->type == WND_TYPE_BITMAP) /* 0 */ + xrdp_painter_font_needed(self); + if (text == 0) { return 0; } - region = xrdp_region_create(self->wm); - xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region, - self->clip_children); - i = 0; - while (xrdp_region_get_rect(region, i, &rect) == 0) + rv = 0; + len = g_strlen(text); + for (index = 0; index < len; index++) { - if (!ISRECTEMPTY(rect)) - { - DEBUG(("sending rect order %d %d %d %d\n\r", - rect.left, rect.top, - rect.right, rect.bottom)); - libxrdp_orders_rect(self->session, rect.left, rect.top, - rect.right - rect.left, - rect.bottom - rect.top, - self->fg_color, 0); - } - i++; + font_item = self->font->font_items + (unsigned char)text[index]; + rv = MAX(rv, font_item->height); } - xrdp_region_delete(region); - return 0; + return rv; } /*****************************************************************************/ -/* fill in an area of the screen with opcodes and patterns */ -/* todo, this needs work */ +/* fill in an area of the screen with one color */ int APP_CC -xrdp_painter_fill_rect2(struct xrdp_painter* self, - struct xrdp_bitmap* bitmap, - int x, int y, int cx, int cy) +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 clip_rect; + struct xrdp_rect draw_rect; struct xrdp_rect rect; + struct xrdp_region* region; + int k; + int dx; + int dy; - if (!check_bounds(bitmap, &x, &y, &cx, &cy)) - { - return 0; - } - if (!xrdp_painter_clip_adj(self, &x, &y, &cx, &cy)) + if (self == 0) { return 0; } @@ -249,193 +248,52 @@ xrdp_painter_fill_rect2(struct xrdp_painter* self, { return 0; } + xrdp_bitmap_get_screen_clip(bitmap, self, &clip_rect, &dx, &dy); region = xrdp_region_create(self->wm); xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region, self->clip_children); - i = 0; - while (xrdp_region_get_rect(region, i, &rect) == 0) + x += dx; + y += dy; + if (self->mix_mode == 0 && self->rop == 0xcc) { - if (!ISRECTEMPTY(rect)) + k = 0; + while (xrdp_region_get_rect(region, k, &rect) == 0) { - DEBUG(("sending rect2 order %d %d %d %d\n\r", - rect.left, rect.top, - rect.right, rect.bottom)); - libxrdp_orders_pat_blt(self->session, rect.left, rect.top, - rect.right - rect.left, - rect.bottom - rect.top, - self->rop, self->bg_color, self->fg_color, - &self->brush, 0); + if (rect_intersect(&rect, &clip_rect, &draw_rect)) + { + libxrdp_orders_rect(self->session, x, y, cx, cy, + self->fg_color, &draw_rect); + } + k++; } - i++; } - xrdp_region_delete(region); - return 0; -} - -#define SSW 64 -#define SSH 60 - -/*****************************************************************************/ -int APP_CC -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 == WND_TYPE_BITMAP) - { - return 0; - } - region = xrdp_region_create(self->wm); - xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region, - self->clip_children); - b = bitmap; - while (b != 0) - { - x = x + b->left; - y = y + b->top; - b = b->parent; - } - if (self->wm->client_info->use_bitmap_cache) + else if (self->mix_mode == 0 && + ((self->rop & 0xf) == 0x0 || /* black */ + (self->rop & 0xf) == 0xf || /* white */ + (self->rop & 0xf) == 0x5)) /* DSTINVERT */ { - /*palette_id = xrdp_cache_add_palette(self->wm->cache, self->wm->palette);*/ - palette_id = 0; - j = 0; - while (j < to_draw->height) + k = 0; + while (xrdp_region_get_rect(region, k, &rect) == 0) { - i = 0; - while (i < to_draw->width) + if (rect_intersect(&rect, &clip_rect, &draw_rect)) { - x1 = x + i; - y1 = y + j; - w = MIN(SSW, to_draw->width - i); - h = MIN(SSH, to_draw->height - j); - b = xrdp_bitmap_create(w, h, self->wm->screen->bpp, 0, self->wm); -#ifdef USE_CRC - xrdp_bitmap_copy_box_with_crc(to_draw, b, i, j, w, h); -#else - xrdp_bitmap_copy_box(to_draw, b, i, j, w, h); -#endif - bitmap_id = xrdp_cache_add_bitmap(self->wm->cache, b); - cache_id = HIWORD(bitmap_id); - cache_idx = LOWORD(bitmap_id); - k = 0; - while (xrdp_region_get_rect(region, k, &rect) == 0) - { - if (!ISRECTEMPTY(rect)) - { - MAKERECT(rect1, x1, y1, w, h); - if (rect_intersect(&rect, &rect1, &rect2)) - { - ok = 1; - if (self->use_clip) - { - rect = self->clip; - RECTOFFSET(rect, x, y); - if (!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; - } - //g_printf("%d %d %d %d %d %d\n", x1, y1, w, h, srcx, srcy); - DEBUG(("sending memblt order \n\r\ - cache_id %d\n\r\ - palette_id %d\n\r\ - x %d\n\r\ - y %d\n\r\ - cx %d\n\r\ - cy %d\n\r\ - rop %d\n\r\ - srcx %d\n\r\ - srcy %d\n\r\ - cache_idx %d\n\r", - cache_id, palette_id, - x1, y1, w, h, self->rop, srcx, srcy, - cache_idx)); - libxrdp_orders_mem_blt(self->session, cache_id, palette_id, - x1, y1, w, h, self->rop, srcx, srcy, - cache_idx, &rect1); - } - } - } - } - k++; - } - i += SSW; + libxrdp_orders_dest_blt(self->session, x, y, cx, cy, + self->rop, &draw_rect); } - j += SSH; + k++; } } - else /* no bitmap cache */ + else { - /* make sure there is no waiting orders */ - libxrdp_orders_force_send(self->session); k = 0; while (xrdp_region_get_rect(region, k, &rect) == 0) { - x1 = rect.left; - y1 = rect.top; - w = rect.right - rect.left; - h = rect.bottom - rect.top; - b = xrdp_bitmap_create(w, h, self->wm->screen->bpp, 0, self->wm); - xrdp_bitmap_copy_box(to_draw, b, x1 - x, y1 - y, w, h); - xrdp_wm_send_bitmap(self->wm, b, x1, y1, w, h); - xrdp_bitmap_delete(b); + if (rect_intersect(&rect, &clip_rect, &draw_rect)) + { + libxrdp_orders_pat_blt(self->session, x, y, cx, cy, + self->rop, self->bg_color, self->fg_color, + &self->brush, &draw_rect); + } k++; } } @@ -443,54 +301,6 @@ xrdp_painter_draw_bitmap(struct xrdp_painter* self, return 0; } -/*****************************************************************************/ -int APP_CC -xrdp_painter_text_width(struct xrdp_painter* self, char* text) -{ - int index; - int rv; - int len; - struct xrdp_font_char* font_item; - - xrdp_painter_font_needed(self); - if (text == 0) - { - return 0; - } - rv = 0; - len = g_strlen(text); - for (index = 0; index < len; index++) - { - font_item = self->font->font_items + (unsigned char)text[index]; - rv = rv + font_item->incby; - } - return rv; -} - -/*****************************************************************************/ -int APP_CC -xrdp_painter_text_height(struct xrdp_painter* self, char* text) -{ - int index; - int rv; - int len; - struct xrdp_font_char* font_item; - - xrdp_painter_font_needed(self); - if (text == 0) - { - return 0; - } - rv = 0; - len = g_strlen(text); - for (index = 0; index < len; index++) - { - font_item = self->font->font_items + (unsigned char)text[index]; - rv = MAX(rv, font_item->height); - } - return rv; -} - /*****************************************************************************/ int APP_CC xrdp_painter_draw_text(struct xrdp_painter* self, @@ -508,15 +318,20 @@ xrdp_painter_draw_text(struct xrdp_painter* self, int index; int total_width; int total_height; + int dx; + int dy; char* data; struct xrdp_region* region; struct xrdp_rect rect; struct xrdp_rect clip_rect; struct xrdp_rect draw_rect; - struct xrdp_bitmap* b; struct xrdp_font* font; struct xrdp_font_char* font_item; + if (self == 0) + { + return 0; + } len = g_strlen(text); if (len < 1) { @@ -548,70 +363,103 @@ xrdp_painter_draw_text(struct xrdp_painter* self, total_width += k; total_height = MAX(total_height, font_item->height); } + xrdp_bitmap_get_screen_clip(bitmap, self, &clip_rect, &dx, &dy); region = xrdp_region_create(self->wm); xrdp_wm_get_vis_region(self->wm, bitmap, x, y, total_width, total_height, region, self->clip_children); - b = bitmap; - while (b != 0) + x += dx; + y += dy; + k = 0; + while (xrdp_region_get_rect(region, k, &rect) == 0) { - x = x + b->left; - y = y + b->top; - b = b->parent; + if (rect_intersect(&rect, &clip_rect, &draw_rect)) + { + x1 = x; + y1 = y + total_height; + draw_rect.right--; + draw_rect.bottom--; + flags = 0x03; /* 0x03 0x73; TEXT2_IMPLICIT_X and something else */ + libxrdp_orders_text(self->session, f, flags, 0, + font->color, 0, + x - 1, y - 1, x + total_width, y + total_height, + 0, 0, 0, 0, + x1, y1, data, len * 2, &draw_rect); + } + k++; } - if (self->use_clip) + xrdp_region_delete(region); + g_free(data); + return 0; +} + +/*****************************************************************************/ +int APP_CC +xrdp_painter_draw_text2(struct xrdp_painter* self, + struct xrdp_bitmap* bitmap, + int font, int flags, int mixmode, + int clip_left, int clip_top, + int clip_right, int clip_bottom, + int box_left, int box_top, + int box_right, int box_bottom, + int x, int y, char* data, int data_len) +{ + struct xrdp_rect clip_rect; + struct xrdp_rect draw_rect; + struct xrdp_rect rect; + struct xrdp_region* region; + int k; + int dx; + int dy; + + if (self == 0) { - clip_rect = self->clip; + return 0; } - else + + /* todo data */ + + if (bitmap->type == WND_TYPE_BITMAP) { - MAKERECT(clip_rect, 0, 0, bitmap->width, bitmap->height); + return 0; } - b = bitmap; - while (b != 0) + xrdp_bitmap_get_screen_clip(bitmap, self, &clip_rect, &dx, &dy); + region = xrdp_region_create(self->wm); + if (box_right - box_left > 1) { - RECTOFFSET(clip_rect, b->left, b->top); - b = b->parent; + xrdp_wm_get_vis_region(self->wm, bitmap, box_left, box_top, + box_right - box_left, box_bottom - box_top, + region, self->clip_children); } + else + { + xrdp_wm_get_vis_region(self->wm, bitmap, clip_left, clip_top, + clip_right - clip_left, clip_bottom - clip_top, + region, self->clip_children); + } + clip_left += dx; + clip_top += dy; + clip_right += dx; + clip_bottom += dy; + box_left += dx; + box_top += dy; + box_right += dx; + box_bottom += dy; + x += dx; + y += dy; k = 0; while (xrdp_region_get_rect(region, k, &rect) == 0) { - if (!ISRECTEMPTY(rect)) + if (rect_intersect(&rect, &clip_rect, &draw_rect)) { - if (rect_intersect(&rect, &clip_rect, &draw_rect)) - { - x1 = x; - y1 = y + total_height; - draw_rect.right--; - draw_rect.bottom--; - flags = 0x03; /* 0x03 0x73; TEXT2_IMPLICIT_X and something else */ - DEBUG(("sending text order\n\r\ - font %d\n\r\ - flags %d\n\r\ - mixmode %d\n\r\ - color1 %d\n\r\ - color2 %d\n\r\ - clip box %d %d %d %d\n\r\ - box box %d %d %d %d\n\r\ - x %d\n\r\ - y %d\n\r\ - len %d\n\r\ - rect %d %d %d %d\n\r", - f, flags, 0, font->color, 0, x, y, - x + total_width, y + total_height, - 0, 0, 0, 0, x1, y1, len, - draw_rect.left, draw_rect.top, - draw_rect.right, draw_rect.bottom)); - libxrdp_orders_text(self->session, f, flags, 0, - font->color, 0, - x - 1, y - 1, x + total_width, y + total_height, - 0, 0, 0, 0, - x1, y1, data, len * 2, &draw_rect); - } + libxrdp_orders_text(self->session, font, flags, mixmode, + self->fg_color, self->bg_color, + clip_left, clip_top, clip_right, clip_bottom, + box_left, box_top, box_right, box_bottom, + x, y, data, data_len, &draw_rect); } k++; } xrdp_region_delete(region); - g_free(data); return 0; } @@ -623,6 +471,26 @@ xrdp_painter_copy(struct xrdp_painter* self, int x, int y, int cx, int cy, int srcx, int srcy) { + struct xrdp_rect clip_rect; + struct xrdp_rect draw_rect; + struct xrdp_rect rect1; + struct xrdp_rect rect2; + struct xrdp_region* region; + struct xrdp_bitmap* b; + int i; + int j; + int k; + int dx; + int dy; + int palette_id; + int bitmap_id; + int cache_id; + int cache_idx; + int walkx; + int walky; + int w; + int h; + if (self == 0 || src == 0 || dst == 0) { return 0; @@ -636,8 +504,120 @@ xrdp_painter_copy(struct xrdp_painter* self, } if (src == dst && src->wm->screen == src) { - libxrdp_orders_screen_blt(dst->wm->session, x, y, cx, cy, - srcx, srcy, self->rop, 0); + xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); + region = xrdp_region_create(self->wm); + xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, + region, self->clip_children); + x += dx; + y += dy; + srcx += dx; + srcy += dy; + k = 0; + while (xrdp_region_get_rect(region, k, &rect1) == 0) + { + if (rect_intersect(&rect1, &clip_rect, &draw_rect)) + { + libxrdp_orders_screen_blt(self->session, x, y, cx, cy, + srcx, srcy, self->rop, &draw_rect); + } + k++; + } + xrdp_region_delete(region); + } + else if (src->data != 0) + /* todo, the non bitmap cache part is gone, it should be put back */ + { + xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); + region = xrdp_region_create(self->wm); + xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, + region, self->clip_children); + x += dx; + y += dy; + palette_id = 0; + j = srcy; + while (j < src->height) + { + i = srcx; + while (i < src->width) + { + walkx = x + i; + walky = y + j; + w = MIN(64, src->width - i); + h = MIN(64, src->height - j); + b = xrdp_bitmap_create(w, h, self->wm->screen->bpp, 0, self->wm); + xrdp_bitmap_copy_box_with_crc(src, b, i, j, w, h); + bitmap_id = xrdp_cache_add_bitmap(self->wm->cache, b); + cache_id = HIWORD(bitmap_id); + cache_idx = LOWORD(bitmap_id); + k = 0; + while (xrdp_region_get_rect(region, k, &rect1) == 0) + { + if (rect_intersect(&rect1, &clip_rect, &rect2)) + { + MAKERECT(rect1, walkx, walky, w, h); + if (rect_intersect(&rect2, &rect1, &draw_rect)) + { + libxrdp_orders_mem_blt(self->session, cache_id, palette_id, + walkx, walky, w, h, self->rop, 0, 0, + cache_idx, &draw_rect); + } + } + k++; + } + i += 64; + } + j += 64; + } + xrdp_region_delete(region); + } + return 0; +} + +/*****************************************************************************/ +int APP_CC +xrdp_painter_line(struct xrdp_painter* self, + struct xrdp_bitmap* bitmap, + int x1, int y1, int x2, int y2) +{ + struct xrdp_rect clip_rect; + struct xrdp_rect draw_rect; + struct xrdp_rect rect; + struct xrdp_region* region; + int k; + int dx; + int dy; + + if (self == 0) + { + return 0; + } + + /* todo data */ + + if (bitmap->type == WND_TYPE_BITMAP) + { + return 0; + } + xrdp_bitmap_get_screen_clip(bitmap, self, &clip_rect, &dx, &dy); + region = xrdp_region_create(self->wm); + xrdp_wm_get_vis_region(self->wm, bitmap, MIN(x1, x2), MIN(y1, y2), + g_abs(x1 - x2) + 1, g_abs(y1 - y2) + 1, + region, self->clip_children); + x1 += dx; + y1 += dy; + x2 += dx; + y2 += dy; + k = 0; + while (xrdp_region_get_rect(region, k, &rect) == 0) + { + if (rect_intersect(&rect, &clip_rect, &draw_rect)) + { + libxrdp_orders_line(self->session, 0, x1, y1, x2, y2, + self->rop, self->bg_color, + &self->pen, &draw_rect); + } + k++; } + xrdp_region_delete(region); return 0; } diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index 1a7e4b8e..5bf632cc 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -35,18 +35,35 @@ struct xrdp_mod /* server functions */ int (*server_begin_update)(struct xrdp_mod* v); int (*server_end_update)(struct xrdp_mod* v); - int (*server_fill_rect)(struct xrdp_mod* v, int x, int y, int cx, int cy, - int color); + int (*server_fill_rect)(struct xrdp_mod* v, int x, int y, int cx, int cy); int (*server_screen_blt)(struct xrdp_mod* v, int x, int y, int cx, int cy, int srcx, int srcy); int (*server_paint_rect)(struct xrdp_mod* v, int x, int y, int cx, int cy, char* data); int (*server_set_pointer)(struct xrdp_mod* v, int x, int y, char* data, char* mask); int (*server_palette)(struct xrdp_mod* v, int* palette); - int (*server_msg)(struct xrdp_mod* v, char* msg); + int (*server_msg)(struct xrdp_mod* v, char* msg, int code); int (*server_is_term)(struct xrdp_mod* v); int (*server_set_clip)(struct xrdp_mod* v, int x, int y, int cx, int cy); int (*server_reset_clip)(struct xrdp_mod* v); + int (*server_set_fgcolor)(struct xrdp_mod* v, int fgcolor); + int (*server_set_bgcolor)(struct xrdp_mod* v, int bgcolor); + int (*server_set_opcode)(struct xrdp_mod* v, int opcode); + int (*server_set_mixmode)(struct xrdp_mod* v, int mixmode); + int (*server_set_brush)(struct xrdp_mod* v, int x_orgin, int y_orgin, + int style, char* pattern); + int (*server_set_pen)(struct xrdp_mod* v, int style, + int width); + int (*server_draw_line)(struct xrdp_mod* v, int x1, int y1, int x2, int y2); + int (*server_add_char)(struct xrdp_mod* v, int font, int charactor, + int offset, int baseline, + int width, int height, char* data); + int (*server_draw_text)(struct xrdp_mod* v, int font, + int flags, int mixmode, int clip_left, int clip_top, + int clip_right, int clip_bottom, + int box_left, int box_top, + int box_right, int box_bottom, + int x, int y, char* data, int data_len); /* common */ long handle; /* pointer to self as int */ long wm; /* struct xrdp_wm* */ @@ -217,12 +234,14 @@ struct xrdp_region struct xrdp_painter { int rop; - int use_clip; + struct xrdp_rect* use_clip; /* nil if not using clip */ struct xrdp_rect clip; int clip_children; int bg_color; int fg_color; + int mix_mode; struct xrdp_brush brush; + struct xrdp_pen pen; struct xrdp_session* session; struct xrdp_wm* wm; /* owner */ struct xrdp_font* font; diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index 75d6ff51..50f7caf3 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -45,6 +45,15 @@ xrdp_wm_create(struct xrdp_process* owner, return self; } +/*****************************************************************************/ +/* called from main thread */ +static long DEFAULT_CC +sync_unload(long param1, long param2) +{ + g_free_library(param1); + return 0; +} + /*****************************************************************************/ void APP_CC xrdp_wm_delete(struct xrdp_wm* self) @@ -66,7 +75,7 @@ xrdp_wm_delete(struct xrdp_wm* self) } if (self->mod_handle != 0) { - g_free_library(self->mod_handle); + g_xrdp_sync(sync_unload, self->mod_handle, 0); } /* free the log */ list_delete(self->log); @@ -123,7 +132,7 @@ xrdp_wm_set_focused(struct xrdp_wm* self, struct xrdp_bitmap* wnd) return 0; } -//****************************************************************************** +/******************************************************************************/ int APP_CC xrdp_wm_get_pixel(char* data, int x, int y, int width, int bpp) { @@ -429,6 +438,7 @@ 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->mix_mode = 1; self->painter->brush.pattern[0] = 0xaa; self->painter->brush.pattern[1] = 0x55; self->painter->brush.pattern[2] = 0xaa; @@ -443,17 +453,18 @@ xrdp_wm_xor_pat(struct xrdp_wm* self, int x, int y, int cx, int cy) 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); + xrdp_painter_fill_rect(self->painter, self->screen, x, y, cx, 5); /* bottom */ - xrdp_painter_fill_rect2(self->painter, self->screen, x, y + (cy - 5), cx, 5); + xrdp_painter_fill_rect(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); + xrdp_painter_fill_rect(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, + xrdp_painter_fill_rect(self->painter, self->screen, x + (cx - 5), y + 5, 5, cy - 10); xrdp_painter_end_update(self->painter); self->painter->rop = 0xcc; self->painter->clip_children = 1; + self->painter->mix_mode = 0; return 0; } @@ -949,11 +960,13 @@ xrdp_wm_key(struct xrdp_wm* self, int device_flags, int scan_code) self->scroll_lock); if (c != 0) { - self->mod->mod_event(self->mod, msg, c, 0xffff, 0, 0); + self->mod->mod_event(self->mod, msg, c, 0xffff, + scan_code, device_flags); } else { - self->mod->mod_event(self->mod, msg, scan_code, device_flags, 0, 0); + self->mod->mod_event(self->mod, msg, scan_code, device_flags, + scan_code, device_flags); } } } @@ -985,6 +998,14 @@ xrdp_wm_key_sync(struct xrdp_wm* self, int device_flags, int key_flags) { self->caps_lock = 1; } + if (self->mod != 0) + { + if (self->mod->mod_event != 0) + { + self->mod->mod_event(self->mod, 17, key_flags, device_flags, + key_flags, device_flags); + } + } return 0; }