diff --git a/xrdp/Makefile b/xrdp/Makefile index d39fad86..69cb95b0 100644 --- a/xrdp/Makefile +++ b/xrdp/Makefile @@ -1,7 +1,7 @@ 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 xrdp_orders.o xrdp_bitmap.o xrdp_wm.o \ - xrdp_painter.o xrdp_list.o xrdp_region.o xrdp_cache.o + xrdp_painter.o xrdp_list.o xrdp_region.o xrdp_cache.o xrdp_font.o #CFLAGS = -Wall -O2 -DXRDP_DEBUG CFLAGS = -Wall -O2 CC = gcc diff --git a/xrdp/Tahoma-10.fv1 b/xrdp/Tahoma-10.fv1 new file mode 100755 index 00000000..48e44cec Binary files /dev/null and b/xrdp/Tahoma-10.fv1 differ diff --git a/xrdp/os_calls.c b/xrdp/os_calls.c index f6d8e48a..05e05dac 100644 --- a/xrdp/os_calls.c +++ b/xrdp/os_calls.c @@ -13,6 +13,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2004 generic operating system calls @@ -522,3 +523,15 @@ int g_file_lock(int fd, int start, int len) return 0; return 1; } + +/*****************************************************************************/ +int g_strlen(char* text) +{ + return strlen(text); +} + +/*****************************************************************************/ +char* g_strcpy(char* dest, char* src) +{ + return strcpy(dest, src); +} diff --git a/xrdp/xrdp.c b/xrdp/xrdp.c index ad486782..47434b35 100644 --- a/xrdp/xrdp.c +++ b/xrdp/xrdp.c @@ -13,6 +13,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2004 main program diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index 3d303a07..7d538840 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -29,11 +29,18 @@ #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)) +#undef MIN +#define MIN(x1, x2) ((x1) < (x2) ? (x1) : (x2)) +#undef MAX +#define MAX(x1, x2) ((x1) > (x2) ? (x1) : (x2)) +#undef HIWORD +#define HIWORD(in) (((in) & 0xffff0000) >> 16) +#undef LOWORD +#define LOWORD(in) ((in) & 0x0000ffff) +#undef MAKELONG +#define MAKELONG(hi, lo) ((((hi) & 0xffff) << 16) | ((lo) & 0xffff)) + +#define FONT_DATASIZE(f) ((((f)->height * (((f)->width + 7) / 8)) + 3) & ~3); /* os_calls.c */ int g_init_system(void); @@ -85,6 +92,8 @@ 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); +int g_strlen(char* text); +char* g_strcpy(char* dest, char* src); /* xrdp_tcp.c */ struct xrdp_tcp* xrdp_tcp_create(struct xrdp_iso* owner); @@ -160,11 +169,23 @@ 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_text(struct xrdp_orders* self, + int font, int flags, int mixmode, + int fg_color, int bg_color, + 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* 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); +int xrdp_orders_send_font(struct xrdp_orders* self, + struct xrdp_font_item* font_item, + int font_index, int char_index); /* xrdp_cache.c */ struct xrdp_cache* xrdp_cache_create(struct xrdp_wm* owner, @@ -172,6 +193,8 @@ struct xrdp_cache* xrdp_cache_create(struct xrdp_wm* owner, 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); +int xrdp_cache_add_char(struct xrdp_cache* self, + struct xrdp_font_item* font_item); /* xrdp_wm.c */ struct xrdp_wm* xrdp_wm_create(struct xrdp_process* owner); @@ -248,6 +271,11 @@ 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 xrdp_painter_text_width(struct xrdp_painter* self, char* text); +int xrdp_painter_text_height(struct xrdp_painter* self, char* text); +int xrdp_painter_draw_text(struct xrdp_painter* self, + struct xrdp_bitmap* bitmap, + int x, int y, char* text); /* xrdp_list.c */ struct xrdp_list* xrdp_list_create(void); @@ -258,3 +286,9 @@ 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); + +/* xrdp_font.c */ +struct xrdp_font* xrdp_font_create(struct xrdp_wm* wm); +void xrdp_font_delete(struct xrdp_font* self); +int xrdp_font_item_compare(struct xrdp_font_item* font1, + struct xrdp_font_item* font2); diff --git a/xrdp/xrdp_bitmap.c b/xrdp/xrdp_bitmap.c index 2f965a2f..3b8cff33 100644 --- a/xrdp/xrdp_bitmap.c +++ b/xrdp/xrdp_bitmap.c @@ -14,6 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2004 bitmap, drawable @@ -87,18 +88,18 @@ int xrdp_bitmap_set_focus(struct xrdp_bitmap* self, int focused) /* active title bar */ painter->fg_color = self->wm->blue; xrdp_painter_fill_rect(painter, self, 3, 3, self->width - 5, 18); + painter->font->color = self->wm->white; } else { /* inactive title bar */ painter->fg_color = self->wm->dark_grey; xrdp_painter_fill_rect(painter, self, 3, 3, self->width - 5, 18); + painter->font->color = self->wm->black; } - DEBUG(("1\n\r")); + xrdp_painter_draw_text(painter, self, 4, 4, self->title); xrdp_painter_end_update(painter); - DEBUG(("2\n\r")); xrdp_painter_delete(painter); - DEBUG(("3\n\r")); return 0; } @@ -289,6 +290,7 @@ int xrdp_bitmap_copy_box(struct xrdp_bitmap* self, struct xrdp_bitmap* dest, } /*****************************************************************************/ +/* returns true if they are the same, else returns false */ int xrdp_bitmap_compare(struct xrdp_bitmap* self, struct xrdp_bitmap* b) { if (self == 0) @@ -311,6 +313,8 @@ int xrdp_bitmap_compare(struct xrdp_bitmap* self, struct xrdp_bitmap* b) int xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect) { int i; + int w; + int h; struct xrdp_bitmap* b; struct xrdp_rect r1; struct xrdp_rect r2; @@ -367,13 +371,16 @@ int xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect) /* active title bar */ painter->fg_color = self->wm->blue; xrdp_painter_fill_rect(painter, self, 3, 3, self->width - 5, 18); + painter->font->color = self->wm->white; } else { /* inactive title bar */ painter->fg_color = self->wm->dark_grey; xrdp_painter_fill_rect(painter, self, 3, 3, self->width - 5, 18); + painter->font->color = self->wm->black; } + xrdp_painter_draw_text(painter, self, 4, 4, self->title); } else if (self->type == 2) /* screen */ { @@ -407,9 +414,17 @@ int xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect) /* black right line */ painter->fg_color = self->wm->black; xrdp_painter_fill_rect(painter, self, self->width - 1, 0, 1, self->height); + w = xrdp_painter_text_width(painter, self->title); + h = xrdp_painter_text_height(painter, self->title); + painter->font->color = self->wm->black; + xrdp_painter_draw_text(painter, self, self->width / 2 - w / 2, + self->height / 2 - h / 2, self->title); } else if (self->state == 1) /* button down */ { + /* gray box */ + painter->fg_color = self->wm->grey; + xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height); /* black top line */ painter->fg_color = self->wm->black; xrdp_painter_fill_rect(painter, self, 0, 0, self->width, 1); @@ -422,6 +437,25 @@ int xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect) /* dark grey left line */ painter->fg_color = self->wm->dark_grey; xrdp_painter_fill_rect(painter, self, 1, 1, 1, self->height - 2); + /* 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); + w = xrdp_painter_text_width(painter, self->title); + h = xrdp_painter_text_height(painter, self->title); + painter->font->color = self->wm->black; + xrdp_painter_draw_text(painter, self, (self->width / 2 - w / 2) + 1, + (self->height / 2 - h / 2) + 1, self->title); } } else if (self->type == 4) /* image */ @@ -457,6 +491,14 @@ int xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect) painter->fg_color = self->wm->black; xrdp_painter_fill_rect(painter, self, 1, 1, self->width - 2, 1); } + else if (self->type == 6) /* label */ + { + painter->font->color = self->wm->black; + xrdp_painter_draw_text(painter, self, 0, 0, self->title); + } + /* notify */ + if (self->notify != 0) + self->notify(self, self, 3, (int)painter, 0); /* draw any child windows in the area */ for (i = 0; i < self->child_list->count; i++) { diff --git a/xrdp/xrdp_cache.c b/xrdp/xrdp_cache.c index a62ae6f2..20445b63 100644 --- a/xrdp/xrdp_cache.c +++ b/xrdp/xrdp_cache.c @@ -14,6 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2004 cache @@ -46,6 +47,10 @@ void xrdp_cache_delete(struct xrdp_cache* self) for (i = 0; i < 3; i++) for (j = 0; j < 600; j++) xrdp_bitmap_delete(self->bitmap_items[i][j].bitmap); + /* free all the cached font items */ + for (i = 0; i < 12; i++) + for (j = 0; j < 256; j++) + g_free(self->char_items[i][j].font_item.data); g_free(self); } @@ -56,8 +61,8 @@ 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; + int cache_id; + int cache_idx; struct xrdp_bitmap* b; /* look for match */ @@ -69,13 +74,13 @@ int xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap) { self->bitmap_items[i][j].use_count++; DEBUG(("found bitmap at %d %d\n", i, j)); - return (i << 16) | j; + return MAKELONG(i, j); } } } /* look for least used */ - min_use_index1 = 0; - min_use_index2 = 0; + cache_id = 0; + cache_idx = 0; min_use = 999999; for (i = 0; i < 3; i++) { @@ -84,22 +89,20 @@ int xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap) 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; + cache_id = i; + cache_idx = j; } } } - DEBUG(("adding bitmap at %d %d\n", min_use_index1, min_use_index2)); + DEBUG(("adding bitmap at %d %d\n", cache_id, cache_idx)); /* set, send bitmap and return */ - xrdp_bitmap_delete(self->bitmap_items[min_use_index1] - [min_use_index2].bitmap); + xrdp_bitmap_delete(self->bitmap_items[cache_id][cache_idx].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; + self->bitmap_items[cache_id][cache_idx].bitmap = b; + self->bitmap_items[cache_id][cache_idx].use_count++; + xrdp_orders_send_raw_bitmap(self->orders, b, cache_id, cache_idx); + return MAKELONG(cache_id, cache_idx); } /*****************************************************************************/ @@ -143,3 +146,60 @@ int xrdp_cache_add_palette(struct xrdp_cache* self, int* palette) xrdp_orders_send_palette(self->orders, palette, min_use_index); return min_use_index; } + +/*****************************************************************************/ +int xrdp_cache_add_char(struct xrdp_cache* self, + struct xrdp_font_item* font_item) +{ + int i; + int j; + int min_use; + int f; + int c; + int datasize; + struct xrdp_font_item* fi; + + /* look for match */ + for (i = 7; i < 12; i++) + { + for (j = 0; j < 250; j++) + { + if (xrdp_font_item_compare(&self->char_items[i][j].font_item, font_item)) + { + self->char_items[i][j].use_count++; + DEBUG(("found font at %d %d\n\r", i, j)); + return MAKELONG(i, j); + } + } + } + /* look for least used */ + f = 0; + c = 0; + min_use = 999999; + for (i = 7; i < 12; i++) + { + for (j = 0; j < 250; j++) + { + if (self->char_items[i][j].use_count < min_use) + { + min_use = self->char_items[i][j].use_count; + f = i; + c = j; + } + } + } + DEBUG(("adding char at %d %d\n\r", f, c)); + /* set, send char and return */ + fi = &self->char_items[f][c].font_item; + g_free(fi->data); + datasize = FONT_DATASIZE(font_item); + fi->data = (char*)g_malloc(datasize, 1); + g_memcpy(fi->data, font_item->data, datasize); + fi->offset = font_item->offset; + fi->baseline = font_item->baseline; + fi->width = font_item->width; + fi->height = font_item->height; + self->char_items[f][c].use_count++; + xrdp_orders_send_font(self->orders, fi, f, c); + return MAKELONG(f, c); +} diff --git a/xrdp/xrdp_font.c b/xrdp/xrdp_font.c new file mode 100644 index 00000000..e4471927 --- /dev/null +++ b/xrdp/xrdp_font.c @@ -0,0 +1,167 @@ + +/* + 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. + + xrdp: A Remote Desktop Protocol server. + Copyright (C) Jay Sorg 2004 + + fonts + +*/ +/* + The fv1 files contain + Font File Header (just one) + FNT1 4 bytes + Font Name 32 bytes + Font Size 2 bytes + Font Style 2 bytes + Pad 8 bytes + Font Data (repeats) + Width 2 bytes + Height 2 bytes + Baseline 2 bytes + Offset 2 bytes + Incby 2 bytes + Pad 6 bytes + Glyph Data var, see FONT_DATASIZE macro +*/ + +#include "xrdp.h" + +char w_char[] = +{ + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x08, 0x20, 0x80, + 0x08, 0x50, 0x80, + 0x04, 0x51, 0x00, + 0x04, 0x51, 0x00, + 0x04, 0x51, 0x00, + 0x02, 0x8a, 0x00, + 0x02, 0x8a, 0x00, + 0x02, 0x8a, 0x00, + 0x01, 0x04, 0x00, + 0x01, 0x04, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, +}; + + +/*****************************************************************************/ +struct xrdp_font* xrdp_font_create(struct xrdp_wm* wm) +{ + struct xrdp_font* self; + struct stream* s; + int fd; + int b; + int i; + int index; + int datasize; + struct xrdp_font_item* f; + + self = (struct xrdp_font*)g_malloc(sizeof(struct xrdp_font), 1); + self->wm = wm; + make_stream(s); + init_stream(s, 8192); +// fd = g_file_open("Arial-10.fv1"); + fd = g_file_open("Tahoma-10.fv1"); +// fd = g_file_open("Serif-10.fv1"); + if (fd != -1) + { + b = g_file_read(fd, s->data, 8192); + g_file_close(fd); + if (b > 0) + { + s->end = s->data + b; + in_uint8s(s, 4); + in_uint8a(s, self->name, 32); + in_uint16_le(s, self->size); + in_uint16_le(s, self->style); + in_uint8s(s, 8); + //g_printf("%s %d %d %d\n", self->name, self->size, self->style, b); + index = 32; + while (!s_check_end(s)) + { + f = self->font_items + index; + in_sint16_le(s, i); + f->width = i; + in_sint16_le(s, i); + f->height = i; + in_sint16_le(s, i); + f->baseline = i; + in_sint16_le(s, i); + f->offset = i; + in_sint16_le(s, i); + f->incby = i; + in_uint8s(s, 6); + datasize = FONT_DATASIZE(f); + //g_printf("%d %d %d %d %d\n", f->width, f->height, datasize, f->baseline, f->offset); + f->data = (char*)g_malloc(datasize, 0); + in_uint8a(s, f->data, datasize); + index++; + } + } + } + free_stream(s); +/* + self->font_items[0].offset = -4; + self->font_items[0].baseline = -16; + self->font_items[0].width = 24; + self->font_items[0].height = 16; + self->font_items[0].data = g_malloc(3 * 16, 0); + g_memcpy(self->font_items[0].data, w_char, 3 * 16); +*/ + return self; +} + +/*****************************************************************************/ +/* free the font and all the items */ +void xrdp_font_delete(struct xrdp_font* self) +{ + int i; + + if (self == 0) + return; + for (i = 0; i < 256; i++) + g_free(self->font_items[i].data); + g_free(self); +} + +/*****************************************************************************/ +/* compare the two font items returns 1 if they match */ +int xrdp_font_item_compare(struct xrdp_font_item* font1, + struct xrdp_font_item* font2) +{ + int datasize; + + if (font1 == 0) + return 0; + if (font2 == 0) + return 0; + if (font1->offset != font2->offset) + return 0; + if (font1->baseline != font2->baseline) + return 0; + if (font1->width != font2->width) + return 0; + if (font1->height != font2->height) + return 0; + datasize = FONT_DATASIZE(font1); + if (g_memcmp(font1->data, font2->data, datasize) == 0) + return 1; + return 0; +} diff --git a/xrdp/xrdp_iso.c b/xrdp/xrdp_iso.c index 9a4ac10f..3932cae4 100644 --- a/xrdp/xrdp_iso.c +++ b/xrdp/xrdp_iso.c @@ -13,6 +13,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2004 iso layer diff --git a/xrdp/xrdp_list.c b/xrdp/xrdp_list.c index 6a3cd12d..498cedd9 100644 --- a/xrdp/xrdp_list.c +++ b/xrdp/xrdp_list.c @@ -13,6 +13,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2004 simple list diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c index 1d1a5f7f..69124e9b 100644 --- a/xrdp/xrdp_listen.c +++ b/xrdp/xrdp_listen.c @@ -13,6 +13,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2004 listen for incoming connection diff --git a/xrdp/xrdp_mcs.c b/xrdp/xrdp_mcs.c index c7aa8667..8d47955f 100644 --- a/xrdp/xrdp_mcs.c +++ b/xrdp/xrdp_mcs.c @@ -13,6 +13,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2004 mcs layer diff --git a/xrdp/xrdp_orders.c b/xrdp/xrdp_orders.c index 541d12a7..ba9a953d 100644 --- a/xrdp/xrdp_orders.c +++ b/xrdp/xrdp_orders.c @@ -14,6 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2004 orders @@ -893,6 +894,153 @@ int xrdp_orders_mem_blt(struct xrdp_orders* self, int cache_id, return 0; } +/*****************************************************************************/ +/* returns error */ +int xrdp_orders_text(struct xrdp_orders* self, + int font, int flags, int mixmode, + int fg_color, int bg_color, + 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* rect) +{ + int order_flags; + int present; + char* present_ptr; + + xrdp_orders_check(self, 100); + self->order_count++; + order_flags = RDP_ORDER_STANDARD; + if (self->last_order != RDP_ORDER_TEXT2) + order_flags |= RDP_ORDER_CHANGE; + self->last_order = RDP_ORDER_TEXT2; + if (rect != 0) + { + order_flags |= RDP_ORDER_BOUNDS; + if (xrdp_orders_last_bounds(self, rect)) + order_flags |= RDP_ORDER_LASTBOUNDS; + } + 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 3 byte present pointer, todo */ + out_uint8s(self->out_s, 3) /* 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 (font != self->text_font) + { + present |= 0x000001; + out_uint8(self->out_s, font); + self->text_font = font; + } + if (flags != self->text_flags) + { + present |= 0x000002; + out_uint8(self->out_s, flags); + self->text_flags = flags; + } + /* unknown */ + if (mixmode != self->text_mixmode) + { + present |= 0x000008; + out_uint8(self->out_s, mixmode); + self->text_mixmode = mixmode; + } + if (fg_color != self->text_fg_color) + { + present |= 0x000010; + out_uint8(self->out_s, fg_color) + out_uint8(self->out_s, fg_color >> 8) + out_uint8(self->out_s, fg_color >> 16) + self->text_fg_color = fg_color; + } + if (bg_color != self->text_bg_color) + { + present |= 0x000020; + out_uint8(self->out_s, bg_color) + out_uint8(self->out_s, bg_color >> 8) + out_uint8(self->out_s, bg_color >> 16) + self->text_bg_color = bg_color; + } + if (clip_left != self->text_clip_left) + { + present |= 0x000040; + out_uint16_le(self->out_s, clip_left); + self->text_clip_left = clip_left; + } + if (clip_top != self->text_clip_top) + { + present |= 0x000080; + out_uint16_le(self->out_s, clip_top); + self->text_clip_top = clip_top; + } + if (clip_right != self->text_clip_right) + { + present |= 0x000100; + out_uint16_le(self->out_s, clip_right); + self->text_clip_right = clip_right; + } + if (clip_bottom != self->text_clip_bottom) + { + present |= 0x000200; + out_uint16_le(self->out_s, clip_bottom); + self->text_clip_bottom = clip_bottom; + } + if (box_left != self->text_box_left) + { + present |= 0x000400; + out_uint16_le(self->out_s, box_left); + self->text_box_left = box_left; + } + if (box_top != self->text_box_top) + { + present |= 0x000800; + out_uint16_le(self->out_s, box_top); + self->text_box_top = box_top; + } + if (box_right != self->text_box_right) + { + present |= 0x001000; + out_uint16_le(self->out_s, box_right); + self->text_box_right = box_right; + } + if (box_bottom != self->text_box_bottom) + { + present |= 0x002000; + out_uint16_le(self->out_s, box_bottom); + self->text_box_bottom = box_bottom; + } + if (x != self->text_x) + { + present |= 0x080000; + out_uint16_le(self->out_s, x); + self->text_x = x; + } + if (y != self->text_y) + { + present |= 0x100000; + out_uint16_le(self->out_s, y); + self->text_y = y; + } + /* always send text */ + present |= 0x200000; + out_uint8(self->out_s, data_len); + out_uint8a(self->out_s, data, data_len); + /* send 3 byte present */ + *present_ptr = present; + present_ptr++; + *present_ptr = present >> 8; + present_ptr++; + *present_ptr = present >> 16; + return 0; +} + /*****************************************************************************/ /* returns error */ /* when a palette gets sent, send the main palette too */ @@ -945,7 +1093,7 @@ int xrdp_orders_send_raw_bitmap(struct xrdp_orders* self, self->order_count++; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; out_uint8(self->out_s, order_flags); - len = (bufsize + 9) - 7; + len = (bufsize + 9) - 7; /* length after type minus 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 */ @@ -957,6 +1105,7 @@ int xrdp_orders_send_raw_bitmap(struct xrdp_orders* self, 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); @@ -974,5 +1123,38 @@ int xrdp_orders_send_raw_bitmap(struct xrdp_orders* self, else if (Bpp == 1) out_uint8(self->out_s, pixel); } + } + return 0; +} + +/*****************************************************************************/ +/* returns error */ +/* max size datasize + 18*/ +/* todo, only sends one for now */ +int xrdp_orders_send_font(struct xrdp_orders* self, + struct xrdp_font_item* font_item, + int font_index, int char_index) +{ + int order_flags; + int datasize; + int len; + + datasize = FONT_DATASIZE(font_item); + xrdp_orders_check(self, datasize + 18); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + len = (datasize + 12) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + out_uint16_le(self->out_s, 8); /* flags */ + out_uint8(self->out_s, RDP_ORDER_FONTCACHE); /* type */ + out_uint8(self->out_s, font_index); + out_uint8(self->out_s, 1); /* num of chars */ + out_uint16_le(self->out_s, char_index); + out_uint16_le(self->out_s, font_item->offset); + out_uint16_le(self->out_s, font_item->baseline); + out_uint16_le(self->out_s, font_item->width); + out_uint16_le(self->out_s, font_item->height); + out_uint8a(self->out_s, font_item->data, datasize); return 0; } diff --git a/xrdp/xrdp_painter.c b/xrdp/xrdp_painter.c index b09df176..731a94c0 100644 --- a/xrdp/xrdp_painter.c +++ b/xrdp/xrdp_painter.c @@ -14,6 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2004 painter, gc @@ -31,6 +32,7 @@ struct xrdp_painter* xrdp_painter_create(struct xrdp_wm* wm) self->wm = wm; self->orders = wm->orders; self->rop = 0xcc; /* copy */ + self->font = xrdp_font_create(wm); return self; } @@ -39,6 +41,7 @@ void xrdp_painter_delete(struct xrdp_painter* self) { if (self == 0) return; + xrdp_font_delete(self->font); g_free(self); } @@ -259,21 +262,21 @@ int xrdp_painter_draw_bitmap(struct xrdp_painter* self, 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) { - j = 0; - while (j < to_draw->height) + i = 0; + while (i < to_draw->width) { x1 = x + i; y1 = y + j; - MIN(w, SS, to_draw->width - i); - MIN(h, SS, to_draw->height - j); + w = MIN(SS, to_draw->width - i); + h = MIN(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); + cache_id = HIWORD(bitmap_id); + cache_idx = LOWORD(bitmap_id); k = 0; while (xrdp_region_get_rect(region, k, &rect) == 0) { @@ -324,10 +327,125 @@ int xrdp_painter_draw_bitmap(struct xrdp_painter* self, k++; } xrdp_bitmap_delete(b); - j += SS; + i += SS; } - i += SS; + j += SS; + } + xrdp_region_delete(region); + return 0; +} + +/*****************************************************************************/ +int xrdp_painter_text_width(struct xrdp_painter* self, char* text) +{ + int index; + int rv; + int len; + struct xrdp_font_item* font_item; + + rv = 0; + len = g_strlen(text); + for (index = 0; index < len; index++) + { + font_item = self->font->font_items + text[index]; + rv = rv + font_item->incby; + } + return rv; +} + +/*****************************************************************************/ +int xrdp_painter_text_height(struct xrdp_painter* self, char* text) +{ + int index; + int rv; + int len; + struct xrdp_font_item* font_item; + + rv = 0; + len = g_strlen(text); + for (index = 0; index < len; index++) + { + font_item = self->font->font_items + text[index]; + rv = MAX(rv, font_item->height); + } + return rv; +} + +/*****************************************************************************/ +int xrdp_painter_draw_text(struct xrdp_painter* self, + struct xrdp_bitmap* bitmap, + int x, int y, char* text) +{ + int i; + int f; + int c; + int k; + int x1; + int y1; + int flags; + int len; + int index; + int total_width; + int total_height; + char* data; + struct xrdp_region* region; + struct xrdp_rect rect; + struct xrdp_bitmap* b; + struct xrdp_font* font; + struct xrdp_font_item* font_item; + + len = g_strlen(text); + if (len < 1) + return 0; + + /* todo data */ + + if (bitmap->type == 0) + return 0; + font = self->font; + f = 0; + k = 0; + total_width = 0; + total_height = 0; + data = (char*)g_malloc(len * 4, 1); + for (index = 0; index < len; index++) + { + font_item = font->font_items + text[index]; + i = xrdp_cache_add_char(self->wm->cache, font_item); + f = HIWORD(i); + c = LOWORD(i); + data[index * 2] = c; + data[index * 2 + 1] = k; + k = font_item->incby; + total_width += k; + total_height = MAX(total_height, font_item->height); + } + region = xrdp_region_create(self->wm); + xrdp_wm_get_vis_region(self->wm, bitmap, x, y, total_width, total_height, + region); + b = bitmap; + while (b != 0) + { + x = x + b->left; + y = y + b->top; + b = b->parent; + } + k = 0; + while (xrdp_region_get_rect(region, k, &rect) == 0) + { + x1 = x; + y1 = y; + rect.right--; + rect.bottom--; + flags = 0x03; /* 0x73; TEXT2_IMPLICIT_X and something else */ + xrdp_orders_text(self->orders, f, flags, 0, + font->color, 0, + x1, y1, x1 + total_width, y1 + total_height, + 0, 0, 0, 0, + x1, y1 + total_height, data, len * 2, &rect); + k++; } xrdp_region_delete(region); + g_free(data); return 0; } diff --git a/xrdp/xrdp_process.c b/xrdp/xrdp_process.c index 7129948d..8694f19d 100644 --- a/xrdp/xrdp_process.c +++ b/xrdp/xrdp_process.c @@ -13,6 +13,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2004 main rdp process diff --git a/xrdp/xrdp_rdp.c b/xrdp/xrdp_rdp.c index 25769a77..2da9de87 100644 --- a/xrdp/xrdp_rdp.c +++ b/xrdp/xrdp_rdp.c @@ -13,6 +13,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2004 rdp layer diff --git a/xrdp/xrdp_region.c b/xrdp/xrdp_region.c index 63627b6d..bc63371f 100644 --- a/xrdp/xrdp_region.c +++ b/xrdp/xrdp_region.c @@ -14,6 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2004 region diff --git a/xrdp/xrdp_sec.c b/xrdp/xrdp_sec.c index dcab595e..f3fba3e0 100644 --- a/xrdp/xrdp_sec.c +++ b/xrdp/xrdp_sec.c @@ -13,6 +13,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2004 secure layer diff --git a/xrdp/xrdp_tcp.c b/xrdp/xrdp_tcp.c index eb2a4b87..23ff2338 100644 --- a/xrdp/xrdp_tcp.c +++ b/xrdp/xrdp_tcp.c @@ -13,6 +13,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2004 tcp layer diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index 11cf7747..383bc3b3 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -13,6 +13,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2004 types @@ -202,6 +203,7 @@ struct xrdp_orders int line_endy; int line_bg_color; int line_rop; + struct xrdp_pen line_pen; int mem_blt_color_table; /* RDP_ORDER_MEMBLT */ int mem_blt_cache_id; @@ -214,7 +216,24 @@ struct xrdp_orders int mem_blt_srcy; int mem_blt_cache_idx; - struct xrdp_pen line_pen; + int text_font; /* RDP_ORDER_TEXT2 */ + int text_flags; + int text_unknown; + int text_mixmode; + int text_fg_color; + int text_bg_color; + int text_clip_left; + int text_clip_top; + int text_clip_right; + int text_clip_bottom; + int text_box_left; + int text_box_top; + int text_box_right; + int text_box_bottom; + int text_x; + int text_y; + int text_len; + char* text_data; }; @@ -230,6 +249,22 @@ struct xrdp_bitmap_item struct xrdp_bitmap* bitmap; }; +struct xrdp_font_item +{ + int offset; + int baseline; + int width; + int height; + int incby; + char* data; +}; + +struct xrdp_char_item +{ + int use_count; + struct xrdp_font_item font_item; +}; + /* differnce caches */ struct xrdp_cache { @@ -237,6 +272,7 @@ struct xrdp_cache struct xrdp_orders* orders; struct xrdp_palette_item palette_items[6]; struct xrdp_bitmap_item bitmap_items[3][600]; + struct xrdp_char_item char_items[12][256]; }; /* the window manager */ @@ -320,12 +356,13 @@ struct xrdp_painter struct xrdp_brush brush; struct xrdp_orders* orders; struct xrdp_wm* wm; /* owner */ + struct xrdp_font* font; }; /* window or bitmap */ struct xrdp_bitmap { - int type; /* 0 = bitmap 1 = window 2 = screen 3 = button 4 = image 5 = edit */ + int type; /* 0 = bitmap 1 = window 2 = screen 3 = button 4 = image 5 = edit 6 = label */ int state; /* for button 0 = normal 1 = down */ int id; char* data; @@ -337,12 +374,25 @@ struct xrdp_bitmap int bg_color; int line_size; /* in bytes */ int focused; + char title[256]; 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; + /* msg 1 = click 2 = mouse move 3 = paint 100 = modal result */ int (*notify)(struct xrdp_bitmap* wnd, struct xrdp_bitmap* sender, int msg, int param1, int param2); }; + +/* font */ +struct xrdp_font +{ + struct xrdp_wm* wm; + struct xrdp_font_item font_items[256]; + int color; + char name[32]; + int size; + int style; +}; diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index da5aa62e..504cfd10 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -14,8 +14,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2004 + xrdp: A Remote Desktop Protocol server. simple window manager */ @@ -159,6 +161,8 @@ int xrdp_wm_login_help_notify(struct xrdp_bitmap* wnd, struct xrdp_bitmap* sender, int msg, int param1, int param2) { + struct xrdp_painter* p; + if (wnd == 0) return 0; if (sender == 0) @@ -175,6 +179,23 @@ int xrdp_wm_login_help_notify(struct xrdp_bitmap* wnd, } } } + else if (msg == 3) /* paint */ + { + p = (struct xrdp_painter*)param1; + if (p != 0) + { + xrdp_painter_draw_text(p, wnd, 10, 30, "You must be authenticated \ +before using this"); + xrdp_painter_draw_text(p, wnd, 10, 46, "session."); + xrdp_painter_draw_text(p, wnd, 10, 78, "Enter a valid username in \ +the username edit box."); + xrdp_painter_draw_text(p, wnd, 10, 94, "Enter the password in \ +the password edit box."); + xrdp_painter_draw_text(p, wnd, 10, 110, "Both the username and \ +password are case"); + xrdp_painter_draw_text(p, wnd, 10, 126, "sensitive."); + } + } return 0; } @@ -224,6 +245,7 @@ int xrdp_wm_login_notify(struct xrdp_bitmap* wnd, 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; + g_strcpy(help->title, "Logon help"); /* ok button */ but = xrdp_bitmap_create(60, 25, wnd->wm->screen->bpp, 3); xrdp_list_insert_item(help->child_list, 0, (int)but); @@ -233,6 +255,7 @@ int xrdp_wm_login_notify(struct xrdp_bitmap* wnd, but->left = 120; but->top = 260; but->id = 1; + g_strcpy(but->title, "OK"); /* draw it */ xrdp_bitmap_invalidate(help, 0); xrdp_wm_set_focused(wnd->wm, help); @@ -463,6 +486,7 @@ int xrdp_wm_init(struct xrdp_wm* self) self->login_window->top = self->screen->height / 2 - self->login_window->height / 2; self->login_window->notify = xrdp_wm_login_notify; + strcpy(self->login_window->title, "Logon to xrdp"); /* image */ but = xrdp_bitmap_create(4, 4, self->screen->bpp, 4); @@ -492,6 +516,7 @@ int xrdp_wm_init(struct xrdp_wm* self) but->left = 320; but->top = 160; but->id = 1; + g_strcpy(but->title, "Help"); but = xrdp_bitmap_create(60, 25, self->screen->bpp, 3); xrdp_list_add_item(self->login_window->child_list, (int)but); @@ -501,6 +526,7 @@ int xrdp_wm_init(struct xrdp_wm* self) but->left = 250; but->top = 160; but->id = 2; + g_strcpy(but->title, "Cancel"); but = xrdp_bitmap_create(60, 25, self->screen->bpp, 3); xrdp_list_add_item(self->login_window->child_list, (int)but); @@ -510,6 +536,16 @@ int xrdp_wm_init(struct xrdp_wm* self) but->left = 180; but->top = 160; but->id = 3; + g_strcpy(but->title, "OK"); + + but = xrdp_bitmap_create(50, 20, self->screen->bpp, 6); /* label */ + 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 = 155; + but->top = 50; + g_strcpy(but->title, "Username"); but = xrdp_bitmap_create(140, 20, self->screen->bpp, 5); xrdp_list_add_item(self->login_window->child_list, (int)but); @@ -521,6 +557,15 @@ int xrdp_wm_init(struct xrdp_wm* self) but->id = 4; but->cursor = 1; + but = xrdp_bitmap_create(50, 20, self->screen->bpp, 6); /* label */ + 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 = 155; + but->top = 80; + g_strcpy(but->title, "Password"); + 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;