diff options
author | speidy <speidy@gmail.com> | 2016-12-22 12:04:29 -0500 |
---|---|---|
committer | speidy <speidy@gmail.com> | 2016-12-22 12:04:29 -0500 |
commit | 93c55e58a884270850794c29bd0f4e2df22e22d6 (patch) | |
tree | 0eeece185f648a2ddf14d522c54c75c70986afda /xrdp | |
parent | f4224615c97668236826d115fa37b6ce805bea96 (diff) | |
parent | 38253f1371b5e01e05ba995f28b6451ee57b613c (diff) | |
download | xrdp-proprietary-93c55e58a884270850794c29bd0f4e2df22e22d6.tar.gz xrdp-proprietary-93c55e58a884270850794c29bd0f4e2df22e22d6.zip |
Merge branch 'devel' of https://github.com/neutrinolabs/xrdp
Conflicts:
xorgxrdp
Diffstat (limited to 'xrdp')
-rw-r--r-- | xrdp/Makefile.am | 74 | ||||
-rw-r--r--[-rwxr-xr-x] | xrdp/ad256.bmp | bin | 19766 -> 19766 bytes | |||
-rw-r--r-- | xrdp/lang.c | 22 | ||||
-rw-r--r-- | xrdp/rdp-scan-codes.txt | 2 | ||||
-rw-r--r-- | xrdp/rsakeys.ini | 5 | ||||
-rw-r--r--[-rwxr-xr-x] | xrdp/sans-10.fv1 | bin | 658956 -> 658956 bytes | |||
-rw-r--r-- | xrdp/xrdp.c | 204 | ||||
-rw-r--r-- | xrdp/xrdp.h | 28 | ||||
-rw-r--r-- | xrdp/xrdp.ini | 194 | ||||
-rw-r--r--[-rwxr-xr-x] | xrdp/xrdp256.bmp | bin | 49278 -> 49278 bytes | |||
-rw-r--r-- | xrdp/xrdp_bitmap.c | 55 | ||||
-rw-r--r-- | xrdp/xrdp_cache.c | 6 | ||||
-rw-r--r-- | xrdp/xrdp_encoder.c | 209 | ||||
-rw-r--r-- | xrdp/xrdp_encoder.h | 62 | ||||
-rw-r--r-- | xrdp/xrdp_keyboard.ini | 117 | ||||
-rw-r--r-- | xrdp/xrdp_listen.c | 6 | ||||
-rw-r--r-- | xrdp/xrdp_login_wnd.c | 73 | ||||
-rw-r--r-- | xrdp/xrdp_mm.c | 485 | ||||
-rw-r--r-- | xrdp/xrdp_painter.c | 561 | ||||
-rw-r--r-- | xrdp/xrdp_process.c | 57 | ||||
-rw-r--r-- | xrdp/xrdp_region.c | 295 | ||||
-rw-r--r-- | xrdp/xrdp_types.h | 86 | ||||
-rw-r--r-- | xrdp/xrdp_wm.c | 246 | ||||
-rw-r--r-- | xrdp/xrdpwin.c | 41 |
24 files changed, 1805 insertions, 1023 deletions
diff --git a/xrdp/Makefile.am b/xrdp/Makefile.am index 4fd9a689..f39610a0 100644 --- a/xrdp/Makefile.am +++ b/xrdp/Makefile.am @@ -1,39 +1,43 @@ -EXTRA_DIST = xrdp.ini ad24b.bmp ad256.bmp xrdp24b.bmp xrdp256.bmp xrdp_logo.bmp sans-10.fv1 cursor0.cur cursor1.cur xrdp.h xrdp_types.h +EXTRA_DIST = \ + czech.txt \ + rdp-scan-codes.txt \ + xrdpwin.c -EXTRA_INCLUDES = -EXTRA_LIBS = -EXTRA_FLAGS = +AM_CPPFLAGS = \ + -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \ + -DXRDP_SBIN_PATH=\"${sbindir}\" \ + -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \ + -DXRDP_PID_PATH=\"${localstatedir}/run\" \ + -DXRDP_MODULE_PATH=\"${moduledir}\" \ + -I$(top_builddir) \ + -I$(top_srcdir)/common \ + -I$(top_srcdir)/libxrdp + +XRDP_EXTRA_LIBS = if XRDP_DEBUG -EXTRA_DEFINES = -DXRDP_DEBUG +AM_CPPFLAGS += -DXRDP_DEBUG else -EXTRA_DEFINES = -DXRDP_NODEBUG -endif - -if GOT_PREFIX -EXTRA_INCLUDES += -I$(prefix)/include -EXTRA_FLAGS += -L$(prefix)/lib -Wl,-rpath -Wl,$(prefix)/lib +AM_CPPFLAGS += -DXRDP_NODEBUG endif if XRDP_RFXCODEC -EXTRA_DEFINES += -DXRDP_RFXCODEC -EXTRA_INCLUDES += -I$(top_srcdir)/librfxcodec/include -EXTRA_LIBS += $(top_srcdir)/librfxcodec/src/librfxencode.a +AM_CPPFLAGS += -DXRDP_RFXCODEC +AM_CPPFLAGS += -I$(top_srcdir)/librfxcodec/include +XRDP_EXTRA_LIBS += $(top_builddir)/librfxcodec/src/.libs/librfxencode.a endif -AM_CFLAGS = \ - -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \ - -DXRDP_SBIN_PATH=\"${sbindir}\" \ - -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \ - -DXRDP_PID_PATH=\"${localstatedir}/run\" \ - -DXRDP_LIB_PATH=\"${libdir}\" \ - $(EXTRA_DEFINES) +if XRDP_PIXMAN +AM_CPPFLAGS += -DXRDP_PIXMAN +AM_CPPFLAGS += $(PIXMAN_CFLAGS) +XRDP_EXTRA_LIBS += $(PIXMAN_LIBS) +endif -INCLUDES = \ - -I$(top_builddir) \ - -I$(top_srcdir)/common \ - -I$(top_srcdir)/libxrdp \ - $(EXTRA_INCLUDES) +if XRDP_PAINTER +AM_CPPFLAGS += -DXRDP_PAINTER +AM_CPPFLAGS += -I$(top_srcdir)/libpainter/include +XRDP_EXTRA_LIBS += $(top_builddir)/libpainter/src/.libs/libpainter.a +endif sbin_PROGRAMS = \ xrdp @@ -41,9 +45,12 @@ sbin_PROGRAMS = \ xrdp_SOURCES = \ funcs.c \ lang.c \ - xrdp_bitmap.c \ xrdp.c \ + xrdp.h \ + xrdp_bitmap.c \ xrdp_cache.c \ + xrdp_encoder.c \ + xrdp_encoder.h \ xrdp_font.c \ xrdp_listen.c \ xrdp_login_wnd.c \ @@ -51,26 +58,23 @@ xrdp_SOURCES = \ xrdp_painter.c \ xrdp_process.c \ xrdp_region.c \ - xrdp_wm.c \ - xrdp_encoder.c + xrdp_types.h \ + xrdp_wm.c xrdp_LDADD = \ $(top_builddir)/common/libcommon.la \ $(top_builddir)/libxrdp/libxrdp.la \ - $(EXTRA_LIBS) - -xrdp_LDFLAGS = \ - $(EXTRA_FLAGS) + $(XRDP_EXTRA_LIBS) xrdpsysconfdir=$(sysconfdir)/xrdp -xrdpsysconf_DATA = \ +dist_xrdpsysconf_DATA = \ xrdp.ini \ xrdp_keyboard.ini xrdppkgdatadir=$(datadir)/xrdp -xrdppkgdata_DATA = \ +dist_xrdppkgdata_DATA = \ ad24b.bmp \ ad256.bmp \ xrdp24b.bmp \ diff --git a/xrdp/ad256.bmp b/xrdp/ad256.bmp Binary files differindex 5e1946c0..5e1946c0 100755..100644 --- a/xrdp/ad256.bmp +++ b/xrdp/ad256.bmp diff --git a/xrdp/lang.c b/xrdp/lang.c index de81c681..1dede6f6 100644 --- a/xrdp/lang.c +++ b/xrdp/lang.c @@ -226,22 +226,34 @@ int APP_CC get_keymaps(int keylayout, struct xrdp_keymap *keymap) { int fd; + int basic_key_layout = keylayout & 0x0000ffff; char *filename; struct xrdp_keymap *lkeymap; filename = (char *)g_malloc(256, 0); - /* check if there is a keymap file */ - g_snprintf(filename, 255, "%s/km-%4.4x.ini", XRDP_CFG_PATH, keylayout); - /* if the file does not exist, try again with 'en-us' as fallback */ + /* check if there is a keymap file e.g. km-e00100411.ini */ + g_snprintf(filename, 255, "%s/km-%08x.ini", XRDP_CFG_PATH, keylayout); + + /* if the file does not exist, use only lower 16 bits instead */ + if (!g_file_exist(filename)) + { + log_message(LOG_LEVEL_INFO, "Cannot find keymap file %s", filename); + /* e.g. km-00000411.ini */ + g_snprintf(filename, 255, "%s/km-%08x.ini", XRDP_CFG_PATH, basic_key_layout); + } + + /* finally, use 'en-us' */ if (!g_file_exist(filename)) { - g_snprintf(filename, 255, "%s/km-0409.ini", XRDP_CFG_PATH); + log_message(LOG_LEVEL_INFO, "Cannot find keymap file %s", filename); + g_snprintf(filename, 255, "%s/km-00000409.ini", XRDP_CFG_PATH); } if (g_file_exist(filename)) { fd = g_file_open(filename); + log_message(LOG_LEVEL_INFO, "Loading keymap file %s", filename); if (fd != -1) { @@ -263,7 +275,7 @@ get_keymaps(int keylayout, struct xrdp_keymap *keymap) if (g_memcmp(lkeymap, keymap, sizeof(struct xrdp_keymap)) != 0) { log_message(LOG_LEVEL_WARNING, - "local keymap file for 0x%4.4x found and dosen't match " + "local keymap file for 0x%08x found and doesn't match " "built in keymap, using local keymap file", keylayout); } diff --git a/xrdp/rdp-scan-codes.txt b/xrdp/rdp-scan-codes.txt index 938ce4c5..5fe06e53 100644 --- a/xrdp/rdp-scan-codes.txt +++ b/xrdp/rdp-scan-codes.txt @@ -3,7 +3,7 @@ complete rdp key code listing en-us -4000s in the down flags columm is from repeating keys(holding a key down) +4000s in the down flags column is from repeating keys(holding a key down) When holding a key down, the down flags repeat but the up flags only come once at the end. Rdesktop does not do this as of yet. It always sends down and up diff --git a/xrdp/rsakeys.ini b/xrdp/rsakeys.ini deleted file mode 100644 index ee79a3ec..00000000 --- a/xrdp/rsakeys.ini +++ /dev/null @@ -1,5 +0,0 @@ -[keys] -pub_exp=0x01,0x00,0x01,0x00 -pub_mod=0x67,0xab,0x0e,0x6a,0x9f,0xd6,0x2b,0xa3,0x32,0x2f,0x41,0xd1,0xce,0xee,0x61,0xc3,0x76,0x0b,0x26,0x11,0x70,0x48,0x8a,0x8d,0x23,0x81,0x95,0xa0,0x39,0xf7,0x5b,0xaa,0x3e,0xf1,0xed,0xb8,0xc4,0xee,0xce,0x5f,0x6a,0xf5,0x43,0xce,0x5f,0x60,0xca,0x6c,0x06,0x75,0xae,0xc0,0xd6,0xa4,0x0c,0x92,0xa4,0xc6,0x75,0xea,0x64,0xb2,0x50,0x5b -pub_sig=0x6a,0x41,0xb1,0x43,0xcf,0x47,0x6f,0xf1,0xe6,0xcc,0xa1,0x72,0x97,0xd9,0xe1,0x85,0x15,0xb3,0xc2,0x39,0xa0,0xa6,0x26,0x1a,0xb6,0x49,0x01,0xfa,0xa6,0xda,0x60,0xd7,0x45,0xf7,0x2c,0xee,0xe4,0x8e,0x64,0x2e,0x37,0x49,0xf0,0x4c,0x94,0x6f,0x08,0xf5,0x63,0x4c,0x56,0x29,0x55,0x5a,0x63,0x41,0x2c,0x20,0x65,0x95,0x99,0xb1,0x15,0x7c -pri_exp=0x41,0x93,0x05,0xB1,0xF4,0x38,0xFC,0x47,0x88,0xC4,0x7F,0x83,0x8C,0xEC,0x90,0xDA,0x0C,0x8A,0xB5,0xAE,0x61,0x32,0x72,0xF5,0x2B,0xD1,0x7B,0x5F,0x44,0xC0,0x7C,0xBD,0x8A,0x35,0xFA,0xAE,0x30,0xF6,0xC4,0x6B,0x55,0xA7,0x65,0xEF,0xF4,0xB2,0xAB,0x18,0x4E,0xAA,0xE6,0xDC,0x71,0x17,0x3B,0x4C,0xC2,0x15,0x4C,0xF7,0x81,0xBB,0xF0,0x03 diff --git a/xrdp/sans-10.fv1 b/xrdp/sans-10.fv1 Binary files differindex 047870fa..047870fa 100755..100644 --- a/xrdp/sans-10.fv1 +++ b/xrdp/sans-10.fv1 diff --git a/xrdp/xrdp.c b/xrdp/xrdp.c index a80687b1..b55a90cc 100644 --- a/xrdp/xrdp.c +++ b/xrdp/xrdp.c @@ -34,7 +34,7 @@ static long g_sync_mutex = 0; static long g_sync1_mutex = 0; static tbus g_term_event = 0; static tbus g_sync_event = 0; -/* syncronize stuff */ +/* synchronize stuff */ static int g_sync_command = 0; static long g_sync_result = 0; static long g_sync_param1 = 0; @@ -107,7 +107,7 @@ xrdp_shutdown(int sig) threadid = tc_get_threadid(); g_writeln("shutting down"); - g_writeln("signal %d threadid %p", sig, threadid); + g_writeln("signal %d threadid %lld", sig, (long long)threadid); if (!g_is_wait_obj_set(g_term_event)) { @@ -293,93 +293,91 @@ xrdp_process_params(int argc, char **argv, } /*****************************************************************************/ -int DEFAULT_CC -main(int argc, char **argv) +/* Basic sanity checks before any forking */ +int +xrdp_sanity_check(void) { - int test; + int intval = 1; int host_be; - char cfg_file[256]; - enum logReturns error; - struct xrdp_startup_params *startup_params; - int pid; - int fd; - int no_daemon; - char text[256]; - char pid_file[256]; - - g_init("xrdp"); - ssl_init(); - - for (test = 0; test < argc; test++) - { - DEBUG(("Argument %i - %s", test, argv[test])); - } + char key_file[256]; /* check compiled endian with actual endian */ - test = 1; - host_be = !((int)(*(unsigned char *)(&test))); -#if defined(B_ENDIAN) + host_be = !((int)(*(unsigned char *)(&intval))); +#if defined(B_ENDIAN) if (!host_be) + { + g_writeln("Not a big endian machine, edit arch.h"); + return 1; + } #endif #if defined(L_ENDIAN) - if (host_be) + if (host_be) + { + g_writeln("Not a little endian machine, edit arch.h"); + return 1; + } #endif - { - g_writeln("endian wrong, edit arch.h"); - return 0; - } /* check long, int and void* sizes */ if (sizeof(int) != 4) { g_writeln("unusable int size, must be 4"); - return 0; + return 1; } if (sizeof(long) != sizeof(void *)) { g_writeln("long size must match void* size"); - return 0; + return 1; } if (sizeof(long) != 4 && sizeof(long) != 8) { g_writeln("unusable long size, must be 4 or 8"); - return 0; + return 1; } if (sizeof(tui64) != 8) { g_writeln("unusable tui64 size, must be 8"); - return 0; + return 1; } - g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); + g_snprintf(key_file, 255, "%s/rsakeys.ini", XRDP_CFG_PATH); + if (!g_file_exist(key_file)) + { + g_writeln("File %s is missing, create it using xrdp-keygen", key_file); + return 1; + } - /* starting logging subsystem */ - error = log_start(cfg_file, "XRDP"); + return 0; +} - if (error != LOG_STARTUP_OK) - { - switch (error) - { - case LOG_ERROR_MALLOC: - g_writeln("error on malloc. cannot start logging. quitting."); - break; - case LOG_ERROR_FILE_OPEN: - g_writeln("error opening log file [%s]. quitting.", - getLogFile(text, 255)); - break; - default: - g_writeln("log_start error"); - break; - } +/*****************************************************************************/ +int DEFAULT_CC +main(int argc, char **argv) +{ + int test; + char cfg_file[256]; + enum logReturns error; + struct xrdp_startup_params *startup_params; + int pid; + int fd; + int no_daemon; + char text[256]; + char pid_file[256]; - g_deinit(); - g_exit(1); + g_init("xrdp"); + ssl_init(); + + for (test = 0; test < argc; test++) + { + DEBUG(("Argument %i - %s", test, argv[test])); } + g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); + startup_params = (struct xrdp_startup_params *) g_malloc(sizeof(struct xrdp_startup_params), 1); @@ -387,7 +385,7 @@ main(int argc, char **argv) { g_writeln("Unknown Parameter"); g_writeln("xrdp -h for help"); - g_writeln(""); + g_writeln("%s", ""); g_deinit(); g_exit(0); } @@ -395,6 +393,43 @@ main(int argc, char **argv) g_snprintf(pid_file, 255, "%s/xrdp.pid", XRDP_PID_PATH); no_daemon = 0; + if (startup_params->help) + { + g_writeln("%s", ""); + g_writeln("xrdp: A Remote Desktop Protocol server."); + g_writeln("Copyright (C) Jay Sorg 2004-2014"); + g_writeln("See http://www.xrdp.org for more information."); + g_writeln("%s", ""); + g_writeln("Usage: xrdp [options]"); + g_writeln(" --help: show help"); + g_writeln(" --nodaemon: don't fork into background"); + g_writeln(" --kill: shut down xrdp"); + g_writeln(" --port: tcp listen port"); + g_writeln(" --fork: fork on new connection"); + g_writeln("%s", ""); + g_deinit(); + g_exit(0); + } + + if (startup_params->version) + { + g_writeln("%s", ""); + g_writeln("xrdp: A Remote Desktop Protocol server."); + g_writeln("Copyright (C) Jay Sorg 2004-2014"); + g_writeln("See http://www.xrdp.org for more information."); + g_writeln("Version %s", PACKAGE_VERSION); + g_writeln("%s", ""); + g_deinit(); + g_exit(0); + } + + if (xrdp_sanity_check() != 0) + { + g_writeln("Fatal error occurred, exiting"); + g_deinit(); + g_exit(1); + } + if (startup_params->kill) { g_writeln("stopping xrdp"); @@ -408,8 +443,7 @@ main(int argc, char **argv) if (fd == -1) { - g_writeln("problem opening to xrdp.pid [%s]", pid_file); - g_writeln("maybe its not running"); + g_writeln("cannot open %s, maybe xrdp is not running", pid_file); } else { @@ -430,49 +464,45 @@ main(int argc, char **argv) g_exit(0); } - if (startup_params->no_daemon) - { - no_daemon = 1; - } + /* starting logging subsystem */ + error = log_start(cfg_file, "xrdp"); - if (startup_params->help) + if (error != LOG_STARTUP_OK) { - g_writeln(""); - g_writeln("xrdp: A Remote Desktop Protocol server."); - g_writeln("Copyright (C) Jay Sorg 2004-2014"); - g_writeln("See http://www.xrdp.org for more information."); - g_writeln(""); - g_writeln("Usage: xrdp [options]"); - g_writeln(" --help: show help"); - g_writeln(" --nodaemon: don't fork into background"); - g_writeln(" --kill: shut down xrdp"); - g_writeln(" --port: tcp listen port"); - g_writeln(" --fork: fork on new connection"); - g_writeln(""); + switch (error) + { + case LOG_ERROR_MALLOC: + g_writeln("error on malloc. cannot start logging. quitting."); + break; + case LOG_ERROR_FILE_OPEN: + g_writeln("error opening log file [%s]. quitting.", + getLogFile(text, 255)); + break; + default: + g_writeln("log_start error"); + break; + } + g_deinit(); - g_exit(0); + g_exit(1); } - if (startup_params->version) + + + if (g_file_exist(pid_file)) /* xrdp.pid */ { - g_writeln(""); - g_writeln("xrdp: A Remote Desktop Protocol server."); - g_writeln("Copyright (C) Jay Sorg 2004-2014"); - g_writeln("See http://www.xrdp.org for more information."); - g_writeln("Version %s", PACKAGE_VERSION); - g_writeln(""); + g_writeln("It looks like xrdp is already running."); + g_writeln("If not, delete %s and try again.", pid_file); g_deinit(); g_exit(0); } - if (g_file_exist(pid_file)) /* xrdp.pid */ + if (startup_params->no_daemon) { - g_writeln("It looks like xrdp is allready running,"); - g_writeln("if not delete the xrdp.pid file and try again"); - g_deinit(); - g_exit(0); + no_daemon = 1; } + if (!no_daemon) { @@ -561,13 +591,13 @@ main(int argc, char **argv) g_threadid = tc_get_threadid(); g_listen = xrdp_listen_create(); g_signal_user_interrupt(xrdp_shutdown); /* SIGINT */ - g_signal_kill(xrdp_shutdown); /* SIGKILL */ g_signal_pipe(pipe_sig); /* SIGPIPE */ g_signal_terminate(xrdp_shutdown); /* SIGTERM */ g_signal_child_stop(xrdp_child); /* SIGCHLD */ g_sync_mutex = tc_mutex_create(); g_sync1_mutex = tc_mutex_create(); pid = g_getpid(); + log_message(LOG_LEVEL_INFO, "starting xrdp with pid %d", pid); g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid); g_term_event = g_create_wait_obj(text); diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index 67488a60..edf88cc4 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -37,6 +37,7 @@ #include "file.h" #include "file_loc.h" #include "xrdp_client_info.h" +#include "log.h" /* xrdp.c */ long APP_CC @@ -136,11 +137,12 @@ xrdp_wm_pointer(struct xrdp_wm* self, char* data, char* mask, int x, int y, int callback(long id, int msg, long param1, long param2, long param3, long param4); int APP_CC -xrdp_wm_delete_all_childs(struct xrdp_wm* self); +xrdp_wm_delete_all_children(struct xrdp_wm* self); int APP_CC xrdp_wm_show_log(struct xrdp_wm *self); int APP_CC -xrdp_wm_log_msg(struct xrdp_wm* self, char* msg); +xrdp_wm_log_msg(struct xrdp_wm *self, enum logLevels loglevel, + const char *fmt, ...) printflike(3, 4); int APP_CC xrdp_wm_get_wait_objs(struct xrdp_wm* self, tbus* robjs, int* rc, tbus* wobjs, int* wc, int* timeout); @@ -173,11 +175,9 @@ xrdp_region_delete(struct xrdp_region* self); int APP_CC xrdp_region_add_rect(struct xrdp_region* self, struct xrdp_rect* rect); int APP_CC -xrdp_region_insert_rect(struct xrdp_region* self, int i, int left, - int top, int right, int bottom); +xrdp_region_subtract_rect(struct xrdp_region* self, struct xrdp_rect* rect); int APP_CC -xrdp_region_subtract_rect(struct xrdp_region* self, - struct xrdp_rect* rect); +xrdp_region_intersect_rect(struct xrdp_region* self, struct xrdp_rect* rect); int APP_CC xrdp_region_get_rect(struct xrdp_region* self, int index, struct xrdp_rect* rect); @@ -264,9 +264,9 @@ xrdp_painter_draw_bitmap(struct xrdp_painter* self, struct xrdp_bitmap* to_draw, int x, int y, int cx, int cy); int APP_CC -xrdp_painter_text_width(struct xrdp_painter* self, char* text); +xrdp_painter_text_width(struct xrdp_painter* self, const char *text); int APP_CC -xrdp_painter_text_height(struct xrdp_painter* self, char* text); +xrdp_painter_text_height(struct xrdp_painter* self, const char *text); int APP_CC xrdp_painter_draw_text(struct xrdp_painter* self, struct xrdp_bitmap* bitmap, @@ -378,7 +378,11 @@ xrdp_mm_get_wait_objs(struct xrdp_mm* self, tbus* read_objs, int* rcount, tbus* write_objs, int* wcount, int* timeout); int APP_CC +xrdp_mm_check_chan(struct xrdp_mm *self); +int APP_CC xrdp_mm_check_wait_objs(struct xrdp_mm* self); +int APP_CC +xrdp_mm_frame_ack(struct xrdp_mm *self, int frame_id); int DEFAULT_CC server_begin_update(struct xrdp_mod* mod); int DEFAULT_CC @@ -435,14 +439,14 @@ 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, +server_set_brush(struct xrdp_mod* mod, int x_origin, int y_origin, 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, +server_add_char(struct xrdp_mod* mod, int font, int character, int offset, int baseline, int width, int height, char* data); int DEFAULT_CC @@ -460,7 +464,7 @@ int DEFAULT_CC server_query_channel(struct xrdp_mod* mod, int index, char* channel_name, int* channel_flags); int DEFAULT_CC -server_get_channel_id(struct xrdp_mod* mod, char* name); +server_get_channel_id(struct xrdp_mod* mod, const char *name); int DEFAULT_CC server_send_to_channel(struct xrdp_mod* mod, int channel_id, char* data, int data_len, @@ -507,6 +511,6 @@ server_monitored_desktop(struct xrdp_mod* mod, struct rail_monitored_desktop_order* mdo, int flags); int DEFAULT_CC -server_add_char_alpha(struct xrdp_mod* mod, int font, int charactor, +server_add_char_alpha(struct xrdp_mod* mod, int font, int character, int offset, int baseline, int width, int height, char* data); diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini index 34adb077..242641ff 100644 --- a/xrdp/xrdp.ini +++ b/xrdp/xrdp.ini @@ -1,39 +1,59 @@ -[globals] -# xrdp.ini file version number +[Globals] +; xrdp.ini file version number ini_version=1 -bitmap_cache=yes -bitmap_compression=yes +; fork a new process for each incoming connection +fork=true +; tcp port to listen port=3389 -allow_channels=true -max_bpp=32 -fork=yes -# minimum security level allowed for client -# can be 'none', 'low', 'medium', 'high', 'fips' +; regulate if the listening socket use socket option tcp_nodelay +; no buffering will be performed in the TCP stack +tcp_nodelay=true +; regulate if the listening socket use socket option keepalive +; if the network connection disappear without close messages the connection will be closed +tcp_keepalive=true +#tcp_send_buffer_bytes=32768 +#tcp_recv_buffer_bytes=32768 + +; security layer can be 'tls', 'rdp' or 'negotiate' +; for client compatible layer +security_layer=negotiate +; minimum security level allowed for client +; can be 'none', 'low', 'medium', 'high', 'fips' crypt_level=high -# security layer can be 'tls', 'rdp' or 'negotiate' -# for client compatible layer -security_layer=rdp -# X.509 certificate and private key -# openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 365 +; X.509 certificate and private key +; openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 365 certificate= key_file= +; specify whether SSLv3 should be disabled +#disableSSLv3=true +; set TLS cipher suites +#tls_ciphers=HIGH -# regulate if the listening socket use socket option tcp_nodelay -# no buffering will be performed in the TCP stack -tcp_nodelay=yes +; Section name to use for automatic login if the client sends username +; and password. If empty, the domain name sent by the client is used. +; If empty and no domain name is given, the first suitable section in +; this file will be used. +autorun= -# regulate if the listening socket use socket option keepalive -# if the network connection disappear without close messages the connection will be closed -tcp_keepalive=yes - -#tcp_send_buffer_bytes=32768 -#tcp_recv_buffer_bytes=32768 - -# -# colors used by windows in RGB format -# +allow_channels=true +allow_multimon=true +bitmap_cache=true +bitmap_compression=true +bulk_compression=true +#hidelogwindow=true +max_bpp=32 +new_cursors=true +; fastpath - can be 'input', 'output', 'both', 'none' +use_fastpath=both +; when true, userid/password *must* be passed on cmd line +#require_credentials=true +; You can set the PAM error text in a gateway setup (MAX 256 chars) +#pamerrortxt=change your password according to policy at http://url +; +; colors used by windows in RGB format +; blue=009cb5 grey=dedede #black=000000 @@ -44,68 +64,51 @@ grey=dedede #red=ff0000 #green=00ff00 #background=626c72 -#autorun=xrdp1 -#hidelogwindow=yes - -# when true, userid/password *must* be passed on cmd line -# require_credentials=yes - -# set a default entry for autorun if the client send login and pass directly -autorun=xrdp1 - -bulk_compression=yes - -# You can set the PAM error text in a gateway setup (MAX 256 chars) -#pamerrortxt=change your password according to policy at http://url -new_cursors=yes -allow_multimon=true -# fastpath - can be set to input / output / both / none -use_fastpath=both -# -# configure login screen -# +; +; configure login screen +; -# Login Screen Window Title +; Login Screen Window Title #ls_title=My Login Title -# top level window background color in RGB format +; top level window background color in RGB format ls_top_window_bg_color=009cb5 -# width and height of login screen +; width and height of login screen ls_width=350 ls_height=430 -# login screen background color in RGB format +; login screen background color in RGB format ls_bg_color=dedede -# optional background image filename (bmp format). +; optional background image filename (bmp format). #ls_background_image= -# logo -# full path to bmp-file or file in shared folder +; logo +; full path to bmp-file or file in shared folder ls_logo_filename= ls_logo_x_pos=55 ls_logo_y_pos=50 -# for positioning labels such as username, password etc +; for positioning labels such as username, password etc ls_label_x_pos=30 ls_label_width=60 -# for positioning text and combo boxes next to above labels +; for positioning text and combo boxes next to above labels ls_input_x_pos=110 ls_input_width=210 -# y pos for first label and combo box +; y pos for first label and combo box ls_input_y_pos=220 -# OK button +; OK button ls_btn_ok_x_pos=142 ls_btn_ok_y_pos=370 ls_btn_ok_width=85 ls_btn_ok_height=30 -# Cancel button +; Cancel button ls_btn_cancel_x_pos=237 ls_btn_cancel_y_pos=370 ls_btn_cancel_width=85 @@ -114,17 +117,17 @@ ls_btn_cancel_height=30 [Logging] LogFile=xrdp.log LogLevel=DEBUG -EnableSyslog=1 +EnableSyslog=true SyslogLevel=DEBUG -# LogLevel and SysLogLevel could by any of: core, error, warning, info or debug - -[channels] -# Channel names not listed here will be blocked by XRDP. -# You can block any channel by setting its value to false. -# IMPORTANT! All channels are not supported in all use -# cases even if you set all values to true. -# You can override these settings on each session type -# These settings are only used if allow_channels=true +; LogLevel and SysLogLevel could by any of: core, error, warning, info or debug + +[Channels] +; Channel names not listed here will be blocked by XRDP. +; You can block any channel by setting its value to false. +; IMPORTANT! All channels are not supported in all use +; cases even if you set all values to true. +; You can override these settings on each session type +; These settings are only used if allow_channels=true rdpdr=true rdpsnd=true drdynvc=true @@ -133,14 +136,19 @@ rail=true xrdpvr=true tcutils=true -# for debugging xrdp, in section xrdp1, change port=-1 to this: -# port=/tmp/.xrdp/xrdp_display_10 +; for debugging xrdp, in section xrdp1, change port=-1 to this: +#port=/tmp/.xrdp/xrdp_display_10 + +; for debugging xrdp, add following line to section xrdp1 +#chansrvport=/tmp/.xrdp/xrdp_chansrv_socket_7210 -# for debugging xrdp, add following line to section xrdp1 -# chansrvport=/tmp/.xrdp/xrdp_chansrv_socket_7210 -[xrdp1] -name=sesman-X11rdp +; +; Session types +; + +[X11rdp] +name=X11rdp lib=libxup.so username=ask password=ask @@ -149,16 +157,26 @@ port=-1 xserverbpp=24 code=10 -[xrdp2] -name=sesman-Xvnc +[Xorg] +name=Xorg +lib=libxup.so +username=ask +password=ask +ip=127.0.0.1 +port=-1 +code=20 + +[Xvnc] +name=Xvnc lib=libvnc.so username=ask password=ask ip=127.0.0.1 port=-1 +#xserverbpp=24 #delay_ms=2000 -[xrdp3] +[console] name=console lib=libvnc.so ip=127.0.0.1 @@ -167,7 +185,7 @@ username=na password=ask #delay_ms=2000 -[xrdp4] +[vnc-any] name=vnc-any lib=libvnc.so ip=ask @@ -179,7 +197,7 @@ password=ask #pamsessionmng=127.0.0.1 #delay_ms=2000 -[xrdp5] +[sesman-any] name=sesman-any lib=libvnc.so ip=ask @@ -188,13 +206,13 @@ username=ask password=ask #delay_ms=2000 -[xrdp6] +[rdp-any] name=rdp-any lib=librdp.so ip=ask port=ask3389 -[xrdp7] +[neutrinordp-any] name=neutrinordp-any lib=libxrdpneutrinordp.so ip=ask @@ -202,17 +220,7 @@ port=ask3389 username=ask password=ask -[Session manager] -name=Session manager -lib=libxup.so -username=ask -password=ask -ip=127.0.0.1 -port=-1 -xserverbpp=24 -code=20 - -# You can override the common channel settings for each session type +; You can override the common channel settings for each session type #channel.rdpdr=true #channel.rdpsnd=true #channel.drdynvc=true diff --git a/xrdp/xrdp256.bmp b/xrdp/xrdp256.bmp Binary files differindex 6191514e..6191514e 100755..100644 --- a/xrdp/xrdp256.bmp +++ b/xrdp/xrdp256.bmp diff --git a/xrdp/xrdp_bitmap.c b/xrdp/xrdp_bitmap.c index aafc19f2..deb56a2c 100644 --- a/xrdp/xrdp_bitmap.c +++ b/xrdp/xrdp_bitmap.c @@ -38,7 +38,7 @@ while (0) -static const int g_crc_table[256] = +static const unsigned int g_crc_table[256] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, @@ -123,6 +123,14 @@ xrdp_bitmap_create(int width, int height, int bpp, self->data = (char *)g_malloc(width * height * Bpp, 0); } +#if defined(XRDP_PAINTER) + if (self->type == WND_TYPE_SCREEN) /* noorders */ + { + LLOGLN(0, ("xrdp_bitmap_create: noorders")); + self->data = (char *) g_malloc(width * height * Bpp, 0); + } +#endif + if (self->type != WND_TYPE_BITMAP) { self->child_list = list_create(); @@ -149,9 +157,9 @@ xrdp_bitmap_create_with_data(int width, int height, struct xrdp_wm *wm) { struct xrdp_bitmap *self = (struct xrdp_bitmap *)NULL; + int Bpp; #if defined(NEED_ALIGN) tintptr data_as_int; - int Bpp; #endif self = (struct xrdp_bitmap *)g_malloc(sizeof(struct xrdp_bitmap), 1); @@ -160,26 +168,29 @@ xrdp_bitmap_create_with_data(int width, int height, self->height = height; self->bpp = bpp; self->wm = wm; + + Bpp = 4; + switch (bpp) + { + case 8: + Bpp = 1; + break; + case 15: + Bpp = 2; + break; + case 16: + Bpp = 2; + break; + } + self->line_size = width * Bpp; + #if defined(NEED_ALIGN) data_as_int = (tintptr) data; if (((bpp >= 24) && (data_as_int & 3)) || (((bpp == 15) || (bpp == 16)) && (data_as_int & 1))) { - /* got to copy data here, it's not alligned + /* got to copy data here, it's not aligned other calls in this file assume alignment */ - 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, 0); g_memcpy(self->data, data, width * height * Bpp); return self; @@ -471,7 +482,7 @@ xrdp_bitmap_load(struct xrdp_bitmap *self, const char *filename, int *palette) /* read bmp header */ if (g_file_seek(fd, 14) < 0) { - log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s\n", + log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s", filename); free_stream(s); g_file_close(fd); @@ -505,7 +516,7 @@ xrdp_bitmap_load(struct xrdp_bitmap *self, const char *filename, int *palette) { if (g_file_seek(fd, 14 + header.size) < 0) { - log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s\n", + log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s", filename); } xrdp_bitmap_resize(self, header.image_width, header.image_height); @@ -562,7 +573,7 @@ xrdp_bitmap_load(struct xrdp_bitmap *self, const char *filename, int *palette) /* read palette */ if (g_file_seek(fd, 14 + header.size) < 0) { - log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s\n", + log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s", filename); } init_stream(s, 8192); @@ -623,7 +634,7 @@ xrdp_bitmap_load(struct xrdp_bitmap *self, const char *filename, int *palette) /* read palette */ if (g_file_seek(fd, 14 + header.size) < 0) { - log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s\n", + log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s", filename); } init_stream(s, 8192); @@ -1254,8 +1265,8 @@ xrdp_bitmap_draw_focus_box(struct xrdp_bitmap *self, painter->brush.pattern[5] = 0x55; painter->brush.pattern[6] = 0xaa; painter->brush.pattern[7] = 0x55; - painter->brush.x_orgin = x; - painter->brush.x_orgin = x; + painter->brush.x_origin = x; + painter->brush.x_origin = x; painter->brush.style = 3; painter->fg_color = self->wm->black; painter->bg_color = self->parent->bg_color; diff --git a/xrdp/xrdp_cache.c b/xrdp/xrdp_cache.c index 834271db..d4133325 100644 --- a/xrdp/xrdp_cache.c +++ b/xrdp/xrdp_cache.c @@ -79,7 +79,7 @@ xrdp_cache_reset_crc(struct xrdp_cache *self) { for (jndex = 0; jndex < 64 * 1024; jndex++) { - /* it's ok to deinit a zero'ed out struct list16 */ + /* it's ok to deinit a zeroed out struct list16 */ list16_deinit(&(self->crc16[index][jndex])); list16_init(&(self->crc16[index][jndex])); } @@ -684,7 +684,7 @@ xrdp_cache_add_pointer(struct xrdp_cache *self, } /*****************************************************************************/ -/* this does not take owership of pointer_item, it makes a copy */ +/* this does not take ownership of pointer_item, it makes a copy */ int APP_CC xrdp_cache_add_pointer_static(struct xrdp_cache *self, struct xrdp_pointer_item *pointer_item, @@ -716,7 +716,7 @@ xrdp_cache_add_pointer_static(struct xrdp_cache *self, } /*****************************************************************************/ -/* this does not take owership of brush_item_data, it makes a copy */ +/* this does not take ownership of brush_item_data, it makes a copy */ int APP_CC xrdp_cache_add_brush(struct xrdp_cache *self, char *brush_item_data) diff --git a/xrdp/xrdp_encoder.c b/xrdp/xrdp_encoder.c index 78d1b52e..0af0b85e 100644 --- a/xrdp/xrdp_encoder.c +++ b/xrdp/xrdp_encoder.c @@ -39,33 +39,82 @@ } \ while (0) -#define JPG_CODEC 0 -#define RFX_CODEC 1 - /*****************************************************************************/ static int -process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc); +process_enc_jpg(struct xrdp_encoder *self, XRDP_ENC_DATA *enc); +#ifdef XRDP_RFXCODEC static int -process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc); +process_enc_rfx(struct xrdp_encoder *self, XRDP_ENC_DATA *enc); +#endif +static int +process_enc_h264(struct xrdp_encoder *self, XRDP_ENC_DATA *enc); -/** - * Init encoder - * - * @return 0 on success, -1 on failure - *****************************************************************************/ -/* called from main thread */ -int APP_CC -init_xrdp_encoder(struct xrdp_mm *self) +/*****************************************************************************/ +struct xrdp_encoder *APP_CC +xrdp_encoder_create(struct xrdp_mm *mm) { + struct xrdp_encoder *self; + struct xrdp_client_info *client_info; char buf[1024]; int pid; - if (self == 0) + client_info = mm->wm->client_info; + + if (client_info->mcs_connection_type != 6) /* LAN */ { - return -1; + return 0; + } + if (client_info->bpp < 24) + { + return 0; } - LLOGLN(0, ("init_xrdp_encoder: initing encoder codec_id %d", self->codec_id)); + self = (struct xrdp_encoder *)g_malloc(sizeof(struct xrdp_encoder), 1); + self->mm = mm; + + if (client_info->jpeg_codec_id != 0) + { + LLOGLN(0, ("xrdp_encoder_create: starting jpeg codec session")); + self->codec_id = client_info->jpeg_codec_id; + self->in_codec_mode = 1; + self->codec_quality = client_info->jpeg_prop[0]; + client_info->capture_code = 0; + client_info->capture_format = + /* XRDP_a8b8g8r8 */ + (32 << 24) | (3 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8; + self->process_enc = process_enc_jpg; + } +#ifdef XRDP_RFXCODEC + else if (client_info->rfx_codec_id != 0) + { + LLOGLN(0, ("xrdp_encoder_create: starting rfx codec session")); + self->codec_id = client_info->rfx_codec_id; + self->in_codec_mode = 1; + client_info->capture_code = 2; + self->process_enc = process_enc_rfx; + self->codec_handle = rfxcodec_encode_create(mm->wm->screen->width, + mm->wm->screen->height, + RFX_FORMAT_YUV, 0); + } +#endif + else if (client_info->h264_codec_id != 0) + { + LLOGLN(0, ("xrdp_encoder_create: starting h264 codec session")); + self->codec_id = client_info->h264_codec_id; + self->in_codec_mode = 1; + client_info->capture_code = 3; + client_info->capture_format = + /* XRDP_nv12 */ + (12 << 24) | (64 << 16) | (0 << 12) | (0 << 8) | (0 << 4) | 0; + self->process_enc = process_enc_h264; + } + else + { + g_free(self); + return 0; + } + + LLOGLN(0, ("init_xrdp_encoder: initializing encoder codec_id %d", self->codec_id)); /* setup required FIFOs */ self->fifo_to_proc = fifo_create(); @@ -81,52 +130,25 @@ init_xrdp_encoder(struct xrdp_mm *self) g_snprintf(buf, 1024, "xrdp_%8.8x_encoder_term", pid); self->xrdp_encoder_term = g_create_wait_obj(buf); - switch (self->codec_id) - { - case 2: - self->process_enc = process_enc_jpg; - break; - case 3: - self->process_enc = process_enc_rfx; -#ifdef XRDP_RFXCODEC - self->codec_handle = - rfxcodec_encode_create(self->wm->screen->width, - self->wm->screen->height, - RFX_FORMAT_YUV, 0); - //RFX_FORMAT_BGRA, 0); -#endif - break; - default: - LLOGLN(0, ("init_xrdp_encoder: unknown codec_id %d", - self->codec_id)); - break; - - } - /* create thread to process messages */ tc_thread_create(proc_enc_msg, self); - return 0; + return self; } -/** - * Deinit xrdp encoder - *****************************************************************************/ -/* called from main thread */ +/*****************************************************************************/ void APP_CC -deinit_xrdp_encoder(struct xrdp_mm *self) +xrdp_encoder_delete(struct xrdp_encoder *self) { XRDP_ENC_DATA *enc; XRDP_ENC_DATA_DONE *enc_done; - FIFO *fifo; - - LLOGLN(0, ("deinit_xrdp_encoder: deiniting encoder")); + FIFO *fifo; + LLOGLN(0, ("xrdp_encoder_delete:")); if (self == 0) { return; } - if (self->in_codec_mode == 0) { return; @@ -135,12 +157,7 @@ deinit_xrdp_encoder(struct xrdp_mm *self) g_set_wait_obj(self->xrdp_encoder_term); g_sleep(1000); - if (self->codec_id == 3) - { -#ifdef XRDP_RFXCODEC - rfxcodec_encode_destroy(self->codec_handle); -#endif - } + /* todo delete specific encoder */ /* destroy wait objects used for signalling */ g_delete_wait_obj(self->xrdp_encoder_event_to_proc); @@ -153,7 +170,7 @@ deinit_xrdp_encoder(struct xrdp_mm *self) { while (!fifo_is_empty(fifo)) { - enc = fifo_remove_item(fifo); + enc = (XRDP_ENC_DATA *) fifo_remove_item(fifo); if (enc == 0) { continue; @@ -162,7 +179,6 @@ deinit_xrdp_encoder(struct xrdp_mm *self) g_free(enc->crects); g_free(enc); } - fifo_delete(fifo); } @@ -172,8 +188,8 @@ deinit_xrdp_encoder(struct xrdp_mm *self) { while (!fifo_is_empty(fifo)) { - enc_done = fifo_remove_item(fifo); - if (enc == 0) + enc_done = (XRDP_ENC_DATA_DONE *) fifo_remove_item(fifo); + if (enc_done == 0) { continue; } @@ -182,27 +198,28 @@ deinit_xrdp_encoder(struct xrdp_mm *self) } fifo_delete(fifo); } + g_free(self); } /*****************************************************************************/ /* called from encoder thread */ static int -process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc) +process_enc_jpg(struct xrdp_encoder *self, XRDP_ENC_DATA *enc) { - int index; - int x; - int y; - int cx; - int cy; - int quality; - int error; - int out_data_bytes; - int count; - char *out_data; - XRDP_ENC_DATA_DONE *enc_done; - FIFO *fifo_processed; - tbus mutex; - tbus event_processed; + int index; + int x; + int y; + int cx; + int cy; + int quality; + int error; + int out_data_bytes; + int count; + char *out_data; + XRDP_ENC_DATA_DONE *enc_done; + FIFO *fifo_processed; + tbus mutex; + tbus event_processed; LLOGLN(10, ("process_enc_jpg:")); quality = self->codec_quality; @@ -236,9 +253,10 @@ process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc) LLOGLN(0, ("process_enc_jpg: error 3")); return 1; } + out_data[256] = 0; /* header bytes */ out_data[257] = 0; - error = libxrdp_codec_jpeg_compress(self->wm->session, 0, enc->data, + error = libxrdp_codec_jpeg_compress(self->mm->wm->session, 0, enc->data, enc->width, enc->height, enc->width * 4, x, y, cx, cy, quality, @@ -274,11 +292,10 @@ process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc) } #ifdef XRDP_RFXCODEC - /*****************************************************************************/ /* called from encoder thread */ static int -process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc) +process_enc_rfx(struct xrdp_encoder *self, XRDP_ENC_DATA *enc) { int index; int x; @@ -364,8 +381,8 @@ process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc) enc_done->comp_pad_data = out_data; enc_done->enc = enc; enc_done->last = 1; - enc_done->cx = self->wm->screen->width; - enc_done->cy = self->wm->screen->height; + enc_done->cx = self->mm->wm->screen->width; + enc_done->cy = self->mm->wm->screen->height; /* done with msg */ /* inform main thread done */ @@ -377,42 +394,40 @@ process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc) return 0; } - -#else +#endif /*****************************************************************************/ /* called from encoder thread */ static int -process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc) +process_enc_h264(struct xrdp_encoder *self, XRDP_ENC_DATA *enc) { + LLOGLN(0, ("process_enc_x264:")); return 0; } -#endif - /** * Encoder thread main loop *****************************************************************************/ THREAD_RV THREAD_CC proc_enc_msg(void *arg) { - XRDP_ENC_DATA *enc; - FIFO *fifo_to_proc; - tbus mutex; - tbus event_to_proc; - tbus term_obj; - tbus lterm_obj; - int robjs_count; - int wobjs_count; - int cont; - int timeout; - tbus robjs[32]; - tbus wobjs[32]; - struct xrdp_mm *self; + XRDP_ENC_DATA *enc; + FIFO *fifo_to_proc; + tbus mutex; + tbus event_to_proc; + tbus term_obj; + tbus lterm_obj; + int robjs_count; + int wobjs_count; + int cont; + int timeout; + tbus robjs[32]; + tbus wobjs[32]; + struct xrdp_encoder *self; LLOGLN(0, ("proc_enc_msg: thread is running")); - self = (struct xrdp_mm *) arg; + self = (struct xrdp_encoder *) arg; if (self == 0) { LLOGLN(0, ("proc_enc_msg: self nil")); diff --git a/xrdp/xrdp_encoder.h b/xrdp/xrdp_encoder.h index 1d525f12..f138d749 100644 --- a/xrdp/xrdp_encoder.h +++ b/xrdp/xrdp_encoder.h @@ -3,13 +3,67 @@ #define _XRDP_ENCODER_H #include "arch.h" +#include "fifo.h" -struct xrdp_mm; +struct xrdp_enc_data; -int APP_CC -init_xrdp_encoder(struct xrdp_mm *self); +/* for codec mode operations */ +struct xrdp_encoder +{ + struct xrdp_mm *mm; + int in_codec_mode; + int codec_id; + int codec_quality; + tbus xrdp_encoder_event_to_proc; + tbus xrdp_encoder_event_processed; + tbus xrdp_encoder_term; + FIFO *fifo_to_proc; + FIFO *fifo_processed; + tbus mutex; + int (*process_enc)(struct xrdp_encoder *self, struct xrdp_enc_data *enc); + void *codec_handle; + int frame_id_client; /* last frame id received from client */ + int frame_id_server; /* last frame id received from Xorg */ + int frame_id_server_sent; +}; + +/* used when scheduling tasks in xrdp_encoder.c */ +struct xrdp_enc_data +{ + struct xrdp_mod *mod; + int num_drects; + short *drects; /* 4 * num_drects */ + int num_crects; + short *crects; /* 4 * num_crects */ + char *data; + int width; + int height; + int flags; + int frame_id; +}; + +typedef struct xrdp_enc_data XRDP_ENC_DATA; + +/* used when scheduling tasks from xrdp_encoder.c */ +struct xrdp_enc_data_done +{ + int comp_bytes; + int pad_bytes; + char *comp_pad_data; + struct xrdp_enc_data *enc; + int last; /* true is this is last message for enc */ + int x; + int y; + int cx; + int cy; +}; + +typedef struct xrdp_enc_data_done XRDP_ENC_DATA_DONE; + +struct xrdp_encoder *APP_CC +xrdp_encoder_create(struct xrdp_mm *mm); void APP_CC -deinit_xrdp_encoder(struct xrdp_mm *self); +xrdp_encoder_delete(struct xrdp_encoder *self); THREAD_RV THREAD_CC proc_enc_msg(void *arg); diff --git a/xrdp/xrdp_keyboard.ini b/xrdp/xrdp_keyboard.ini index f3a5298a..3ce7644a 100644 --- a/xrdp/xrdp_keyboard.ini +++ b/xrdp/xrdp_keyboard.ini @@ -1,59 +1,59 @@ -# -# RDP Keyboard <-> X11 Keyboard layout map -# -# How this file works: -# 1. load the file and scan each section to find matching "keyboard_type" -# and "keyboard_subtype" based on the values received from the client. -# If not found, then jump to default section. -# 2. in the selected section, look for "rdp_layouts" and "layouts_map". -# Based on the "keylayout" value from the client, find the right x11 -# layout value. -# 3. model/variant are inferred based on the "keyboard_type" and -# "keyboard_subtype", but they can be overridden. -# +; +; RDP Keyboard <-> X11 Keyboard layout map +; +; How this file works: +; 1. load the file and scan each section to find matching "keyboard_type" +; and "keyboard_subtype" based on the values received from the client. +; If not found, then jump to default section. +; 2. in the selected section, look for "rdp_layouts" and "layouts_map". +; Based on the "keylayout" value from the client, find the right x11 +; layout value. +; 3. model/variant are inferred based on the "keyboard_type" and +; "keyboard_subtype", but they can be overridden. +; -# -# RDP Keyboard Type (http://msdn.microsoft.com/en-us/library/cc240563.aspx) -# -# 0 is not a valid value -# -# 1 - IBM PC/XT or compatible (83-key) keyboard -# 2 - Olivetti "ICO" (102-key) keyboard -# 3 - IBM PC/AT (84-key) or similar keyboard -# 4 - IBM enhanced (101- or 102-key) keyboard -# 5 - Nokia 1050 and similar keyboards -# 6 - Nokia 9140 and similar keyboards -# 7 - Japanese keyboard -# -# RDP Keyboard Subtype is vendor dependent. XRDP defines as follows: -# -# 0 is not a valid value -# -# 1 - Standard -# 2 - FreeRDP JP keyboard -# 3 - Macintosh -# ... - < any vendor dependent subtype > -# -# The list can be augmented. -# +; +; RDP Keyboard Type (http://msdn.microsoft.com/en-us/library/cc240563.aspx) +; +; 0 is not a valid value +; +; 1 - IBM PC/XT or compatible (83-key) keyboard +; 2 - Olivetti "ICO" (102-key) keyboard +; 3 - IBM PC/AT (84-key) or similar keyboard +; 4 - IBM enhanced (101- or 102-key) keyboard +; 5 - Nokia 1050 and similar keyboards +; 6 - Nokia 9140 and similar keyboards +; 7 - Japanese keyboard +; +; RDP Keyboard Subtype is vendor dependent. XRDP defines as follows: +; +; 0 is not a valid value +; +; 1 - Standard +; 2 - FreeRDP JP keyboard +; 3 - Macintosh +; ... - < any vendor dependent subtype > +; +; The list can be augmented. +; -# default +; default [default] -# keyboard_type and keyboard_subtype is not readed for default section. It -# is only as a place holder to keep consistency. Default model/variant are -# platform dependent, and could be overridden if needed. +; keyboard_type and keyboard_subtype is not read for default section. It +; is only a placeholder to keep consistency. Default model/variant are +; platform dependent, and could be overridden if needed. keyboard_type=0 keyboard_subtype=0 -# user could override variant and model, but generally they should be inferred -# automatically based on keyboard type and subtype -#variant= -#model= +; user could override variant and model, but generally they should be inferred +; automatically based on keyboard type and subtype +;variant= +;model= -# A list of supported RDP keyboard layouts +; A list of supported RDP keyboard layouts rdp_layouts=default_rdp_layouts -# The map from RDP keyboard layout to X11 keyboard layout +; The map from RDP keyboard layout to X11 keyboard layout layouts_map=default_layouts_map [default_rdp_layouts] @@ -62,33 +62,31 @@ rdp_layout_de=0x00000407 rdp_layout_fr=0x0000040C rdp_layout_it=0x00000410 rdp_layout_jp=0x00000411 -rdp_layout_jp2=0xe0010411 -rdp_layout_jp3=0xe0200411 -rdp_layout_jp4=0xe0210411 +rdp_layout_kr=0x00000412 rdp_layout_ru=0x00000419 rdp_layout_se=0x0000041D +rdp_layout_ch=0x00000807 rdp_layout_pt=0x00000816 rdp_layout_br=0x00000416 rdp_layout_pl=0x00000415 -# <rdp layout name> = <X11 keyboard layout value> +; <rdp layout name> = <X11 keyboard layout value> [default_layouts_map] rdp_layout_us=us rdp_layout_de=de rdp_layout_fr=fr rdp_layout_it=it rdp_layout_jp=jp -rdp_layout_jp2=jp -rdp_layout_jp3=jp -rdp_layout_jp4=jp +rdp_layout_kr=kr rdp_layout_ru=ru rdp_layout_se=se +rdp_layout_ch=ch rdp_layout_pt=pt rdp_layout_br=br(abnt2) rdp_layout_pl=pl -# if two sections have the same keyboard_type and keyboard_subtype, then -# the latter could override the former. +; if two sections have the same keyboard_type and keyboard_subtype, then +; the latter could override the former. [rdp_keyboard_mac] keyboard_type=4 keyboard_subtype=3 @@ -98,7 +96,7 @@ layouts_map=rdp_layouts_map_mac [rdp_keyboard_jp] keyboard_type=7 keyboard_subtype=2 -model=jp106 +model=pc105 rdp_layouts=default_rdp_layouts layouts_map=default_layouts_map @@ -107,12 +105,11 @@ rdp_layout_us=us rdp_layout_de=de rdp_layout_fr=fr rdp_layout_jp=jp -rdp_layout_jp2=jp -rdp_layout_jp3=jp -rdp_layout_jp4=jp +rdp_layout_kr=kr rdp_layout_it=it rdp_layout_ru=ru rdp_layout_se=se +rdp_layout_ch=ch rdp_layout_pt=pt rdp_layout_br=br(abnt2) rdp_layout_pl=pl diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c index b2b19ca2..c563d5fd 100644 --- a/xrdp/xrdp_listen.c +++ b/xrdp/xrdp_listen.c @@ -370,6 +370,8 @@ xrdp_listen_main_loop(struct xrdp_listen *self) if (error == 0) { + log_message(LOG_LEVEL_INFO, "listening to port %s on %s", + port, address); if (tcp_nodelay) { if (g_tcp_set_no_delay(self->listen_trans->sck)) @@ -455,8 +457,8 @@ xrdp_listen_main_loop(struct xrdp_listen *self) if (trans_get_wait_objs(self->listen_trans, robjs, &robjs_count) != 0) { - log_message(LOG_LEVEL_ERROR,"Listening socket is in wrong state we " - "terminate listener"); + log_message(LOG_LEVEL_ERROR,"Listening socket is in wrong state, " + "terminating listener"); break; } } diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c index 357b4e2a..37cd1e00 100644 --- a/xrdp/xrdp_login_wnd.c +++ b/xrdp/xrdp_login_wnd.c @@ -96,7 +96,7 @@ xrdp_wm_popup_notify(struct xrdp_bitmap *wnd, /*****************************************************************************/ int APP_CC -xrdp_wm_delete_all_childs(struct xrdp_wm *self) +xrdp_wm_delete_all_children(struct xrdp_wm *self) { int index; struct xrdp_bitmap *b; @@ -228,7 +228,7 @@ xrdp_wm_ok_clicked(struct xrdp_bitmap *wnd) wm->mm->login_names->auto_free = 1; wm->mm->login_values = list_create(); wm->mm->login_values->auto_free = 1; - /* gota copy these cause dialog gets freed */ + /* will copy these cause dialog gets freed */ list_append_list_strdup(mod_data->names, wm->mm->login_names, 0); list_append_list_strdup(mod_data->values, wm->mm->login_values, 0); xrdp_wm_set_login_mode(wm, 2); @@ -257,7 +257,7 @@ xrdp_wm_ok_clicked(struct xrdp_bitmap *wnd) * * Users can create shortcuts where this information is configured. These * shortcuts simplifies login. -* @param orginalDomainInfo indata to this function +* @param originalDomainInfo indata to this function * @param comboMax the max number of combo choices * @param decode if true then we perform decoding of combo choice * @param resultBuffer must be pre allocated before calling this function. @@ -266,21 +266,20 @@ xrdp_wm_ok_clicked(struct xrdp_bitmap *wnd) * 0 if the user does not prefer any choice. */ static int APP_CC -xrdp_wm_parse_domain_information(char *orginalDomainInfo, int comboMax, +xrdp_wm_parse_domain_information(char *originalDomainInfo, int comboMax, int decode, char *resultBuffer) { int ret; int pos; int comboxindex; char index[2]; - char debugstr[256]; /* If the first char in the domain name is '_' we use the domain name as IP*/ ret = 0; /* default return value */ /* resultBuffer assumed to be 256 chars */ g_memset(resultBuffer, 0, 256); - if (orginalDomainInfo[0] == '_') + if (originalDomainInfo[0] == '_') { /* we try to locate a number indicating what combobox index the user * prefer the information is loaded from domain field, from the client @@ -289,7 +288,7 @@ xrdp_wm_parse_domain_information(char *orginalDomainInfo, int comboMax, * Underscore is a valid name in the domain. * Invalid chars are ignored in microsoft client therefore we use '_' * again. this sec '__' contains the split for index.*/ - pos = g_pos(&orginalDomainInfo[1], "__"); + pos = g_pos(&originalDomainInfo[1], "__"); if (pos > 0) { /* an index is found we try to use it @@ -298,13 +297,11 @@ xrdp_wm_parse_domain_information(char *orginalDomainInfo, int comboMax, { g_memset(index, 0, 2); /* we just accept values 0-9 (one figure) */ - g_strncpy(index, &orginalDomainInfo[pos + 3], 1); + g_strncpy(index, &originalDomainInfo[pos + 3], 1); comboxindex = g_htoi(index); - g_snprintf(debugstr, 255, "Value of index (as char): %s " - "(converted) : %d (max) : %d", index, comboxindex, - comboMax - 1); - debugstr[255] = 0; - log_message(LOG_LEVEL_DEBUG, debugstr); + log_message(LOG_LEVEL_DEBUG, + "index value as string: %s, as int: %d, max: %d", + index, comboxindex, comboMax - 1); /* limit to max number of items in combo box */ if ((comboxindex > 0) && (comboxindex < comboMax)) { @@ -314,12 +311,12 @@ xrdp_wm_parse_domain_information(char *orginalDomainInfo, int comboMax, } } /* pos limit the String to only contain the IP */ - g_strncpy(resultBuffer, &orginalDomainInfo[1], pos); + g_strncpy(resultBuffer, &originalDomainInfo[1], pos); } else { /* log_message(LOG_LEVEL_DEBUG, "domain does not contain _"); */ - g_strncpy(resultBuffer, &orginalDomainInfo[1], 255); + g_strncpy(resultBuffer, &originalDomainInfo[1], 255); } } return ret; @@ -344,7 +341,7 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo) username_set = 0; - /* free labels and edits, cause we gota create them */ + /* free labels and edits, cause we will create them */ /* creation or combo changed */ for (index = 100; index < 200; index++) { @@ -563,9 +560,9 @@ xrdp_wm_login_fill_in_combo(struct xrdp_wm *self, struct xrdp_bitmap *b) p = (char *)list_get_item(sections, i); file_read_section(fd, p, section_names, section_values); - if ((g_strncmp(p, "globals", 255) == 0) - || (g_strncmp(p, "channels", 255) == 0) - || (g_strncmp(p, "Logging", 255) == 0)) + if ((g_strncasecmp(p, "globals", 255) == 0) + || (g_strncasecmp(p, "channels", 255) == 0) + || (g_strncasecmp(p, "Logging", 255) == 0)) { } else @@ -618,9 +615,19 @@ xrdp_login_wnd_create(struct xrdp_wm *self) int log_width; int log_height; int regular; + int primary_x_offset; + int primary_y_offset; + int index; + int x; + int y; + int cx; + int cy; globals = &self->xrdp_config->cfg_globals; + primary_x_offset = self->screen->width / 2; + primary_y_offset = self->screen->height / 2; + log_width = globals->ls_width; log_height = globals->ls_height; regular = 1; @@ -639,6 +646,25 @@ xrdp_login_wnd_create(struct xrdp_wm *self) regular = 0; } + /* multimon scenario, draw login window on primary monitor */ + if (self->client_info->monitorCount > 1) + { + for (index = 0; index < self->client_info->monitorCount; index++) + { + if (self->client_info->minfo_wm[index].is_primary) + { + x = self->client_info->minfo_wm[index].left; + y = self->client_info->minfo_wm[index].top; + cx = self->client_info->minfo_wm[index].right; + cy = self->client_info->minfo_wm[index].bottom; + + primary_x_offset = x + ((cx - x) / 2); + primary_y_offset = y + ((cy - y) / 2); + break; + } + } + } + /* draw login window */ self->login_window = xrdp_bitmap_create(log_width, log_height, self->screen->bpp, WND_TYPE_WND, self); @@ -647,11 +673,9 @@ xrdp_login_wnd_create(struct xrdp_wm *self) self->login_window->owner = self->screen; self->login_window->bg_color = globals->ls_bg_color; - self->login_window->left = self->screen->width / 2 - - self->login_window->width / 2; + self->login_window->left = primary_x_offset - self->login_window->width / 2; + self->login_window->top = primary_y_offset - self->login_window->height / 2; - self->login_window->top = self->screen->height / 2 - - self->login_window->height / 2; self->login_window->notify = xrdp_wm_login_notify; @@ -791,13 +815,12 @@ load_xrdp_config(struct xrdp_config *config, int bpp) globals = &config->cfg_globals; - /* set default values incase we can't get them from xrdp.ini file */ + /* set default values in case we can't get them from xrdp.ini file */ globals->ini_version = 1; globals->ls_top_window_bg_color = HCOLOR(bpp, xrdp_wm_htoi("009cb5")); globals->ls_bg_color = HCOLOR(bpp, xrdp_wm_htoi("dedede")); globals->ls_width = 350; globals->ls_height = 350; - globals->ls_bg_color = 0xdedede; globals->ls_logo_x_pos = 63; globals->ls_logo_y_pos = 50; globals->ls_label_x_pos = 30; diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 76957ad6..bb6bc5d8 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -24,11 +24,18 @@ #define ACCESS #include "xrdp.h" #include "log.h" + #ifdef ACCESS #ifndef USE_NOPAM +#if defined(HAVE__PAM_TYPES_H) +#define LINUXPAM 1 #include "security/_pam_types.h" +#elif defined(HAVE_PAM_CONSTANTS_H) +#define OPENPAM 1 +#include <security/pam_constants.h> #endif -#endif +#endif /* USE_NOPAM */ +#endif /* ACCESS */ #include "xrdp_encoder.h" @@ -58,46 +65,16 @@ xrdp_mm_create(struct xrdp_wm *owner) self->login_values->auto_free = 1; LLOGLN(0, ("xrdp_mm_create: bpp %d mcs_connection_type %d " - "jpeg_codec_id %d v3_codec_id %d rfx_codec_id %d", + "jpeg_codec_id %d v3_codec_id %d rfx_codec_id %d " + "h264_codec_id %d", self->wm->client_info->bpp, self->wm->client_info->mcs_connection_type, self->wm->client_info->jpeg_codec_id, self->wm->client_info->v3_codec_id, - self->wm->client_info->rfx_codec_id)); - /* go into jpeg codec mode if jpeg set, lan set */ - if (self->wm->client_info->mcs_connection_type == 6) /* LAN */ - { - if (self->wm->client_info->jpeg_codec_id == 2) /* JPEG */ - { - if (self->wm->client_info->bpp > 16) - { - LLOGLN(0, ("xrdp_mm_create: starting jpeg codec session")); - self->codec_id = 2; - self->in_codec_mode = 1; - self->codec_quality = self->wm->client_info->jpeg_prop[0]; - self->wm->client_info->capture_code = 0; - self->wm->client_info->capture_format = - /* PIXMAN_a8b8g8r8 */ - (32 << 24) | (3 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8; - } - } - else if (self->wm->client_info->rfx_codec_id == 3) /* RFX */ - { - if (self->wm->client_info->bpp > 16) - { - LLOGLN(0, ("xrdp_mm_create: starting rfx codec session")); - self->codec_id = 3; - self->in_codec_mode = 1; - self->wm->client_info->capture_code = 2; - } - } - } + self->wm->client_info->rfx_codec_id, + self->wm->client_info->h264_codec_id)); - if (self->in_codec_mode) - { - /* setup thread to handle codec mode messages */ - init_xrdp_encoder(self); - } + self->encoder = xrdp_encoder_create(self); return self; } @@ -174,7 +151,7 @@ xrdp_mm_delete(struct xrdp_mm *self) xrdp_mm_module_cleanup(self); /* shutdown thread */ - deinit_xrdp_encoder(self); + xrdp_encoder_delete(self->encoder); trans_delete(self->sesman_trans); self->sesman_trans = 0; @@ -199,8 +176,8 @@ xrdp_mm_send_login(struct xrdp_mm *self) char *name; char *value; - xrdp_wm_log_msg(self->wm, "sending login info to session manager, " - "please wait..."); + xrdp_wm_log_msg(self->wm, LOG_LEVEL_DEBUG, + "sending login info to session manager, please wait..."); username = 0; password = 0; self->code = 0; @@ -233,7 +210,8 @@ xrdp_mm_send_login(struct xrdp_mm *self) if ((username == 0) || (password == 0)) { - xrdp_wm_log_msg(self->wm, "Error finding username and password"); + xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, + "Error finding username and password"); return 1; } @@ -251,14 +229,19 @@ xrdp_mm_send_login(struct xrdp_mm *self) out_uint16_be(s, self->wm->screen->width); out_uint16_be(s, self->wm->screen->height); - if (xserverbpp > 0) - { - out_uint16_be(s, xserverbpp); - } - else + /* select and send X server bpp */ + if (xserverbpp == 0) { - out_uint16_be(s, self->wm->screen->bpp); + if (self->code == 20) + { + xserverbpp = 24; /* xorgxrdp is always at 24 bpp */ + } + else + { + xserverbpp = self->wm->screen->bpp; /* use client's bpp */ + } } + out_uint16_be(s, xserverbpp); /* send domain */ if(self->wm->client_info->domain[0]!='_') @@ -300,7 +283,8 @@ xrdp_mm_send_login(struct xrdp_mm *self) if (rv != 0) { - xrdp_wm_log_msg(self->wm, "xrdp_mm_send_login: xrdp_mm_send_login failed"); + xrdp_wm_log_msg(self->wm, LOG_LEVEL_WARNING, + "xrdp_mm_send_login: xrdp_mm_send_login failed"); } return rv; @@ -312,7 +296,8 @@ xrdp_mm_send_login(struct xrdp_mm *self) then it copies the corresponding login_values item into 'dest' 'dest' must be at least 'dest_len' + 1 bytes in size */ static int APP_CC -xrdp_mm_get_value(struct xrdp_mm *self, char *aname, char *dest, int dest_len) +xrdp_mm_get_value(struct xrdp_mm *self, const char *aname, char *dest, + int dest_len) { char *name; char *value; @@ -362,25 +347,25 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self) if (xrdp_mm_get_value(self, "lib", lib, 255) != 0) { - g_snprintf(text, 255, "no library name specified in xrdp.ini, please add " - "lib=libxrdp-vnc.so or similar"); - xrdp_wm_log_msg(self->wm, text); + xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, + "no library name specified in xrdp.ini, please add " + "lib=libxrdp-vnc.so or similar"); return 1; } if (lib[0] == 0) { - g_snprintf(text, 255, "empty library name specified in xrdp.ini, please " - "add lib=libxrdp-vnc.so or similar"); - xrdp_wm_log_msg(self->wm, text); + xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, + "empty library name specified in xrdp.ini, please " + "add lib=libxrdp-vnc.so or similar"); return 1; } if (self->mod_handle == 0) { - g_snprintf(text, 255, "%s/%s", XRDP_LIB_PATH, lib); + g_snprintf(text, 255, "%s/%s", XRDP_MODULE_PATH, lib); /* Let the main thread load the lib,*/ self->mod_handle = g_xrdp_sync(xrdp_mm_sync_load, (tintptr)text, 0); @@ -395,10 +380,9 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self) if (func == 0) { - g_snprintf(text, 255, "error finding proc mod_init in %s, not a valid " - "xrdp backend", lib); - xrdp_wm_log_msg(self->wm, text); - log_message(LOG_LEVEL_ERROR,text); + xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, + "error finding proc mod_init in %s, " + "not a valid xrdp backend", lib); } self->mod_init = (struct xrdp_mod * ( *)(void))func; @@ -411,10 +395,9 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self) if (func == 0) { - g_snprintf(text, 255, "error finding proc mod_exit in %s, not a valid " - "xrdp backend", lib); - xrdp_wm_log_msg(self->wm, text); - log_message(LOG_LEVEL_ERROR,text); + xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, + "error finding proc mod_exit in %s, " + "not a valid xrdp backend", lib); } self->mod_exit = (int ( *)(struct xrdp_mod *))func; @@ -436,10 +419,10 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self) } else { - g_snprintf(text, 255, "error loading %s specified in xrdp.ini, please " - "add a valid entry like lib=libxrdp-vnc.so or similar", lib); - xrdp_wm_log_msg(self->wm, text); - log_message(LOG_LEVEL_ERROR,text); + xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, + "error loading %s specified in xrdp.ini, please " + "add a valid entry like lib=libxrdp-vnc.so or " + "similar", lib); return 1; } @@ -489,6 +472,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self) self->mod->server_paint_rect_bpp = server_paint_rect_bpp; self->mod->server_composite = server_composite; self->mod->server_paint_rects = server_paint_rects; + self->mod->si = (tintptr) &(self->wm->session->si); } } @@ -504,7 +488,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self) /*****************************************************************************/ static int APP_CC -xrdp_mm_setup_mod2(struct xrdp_mm *self) +xrdp_mm_setup_mod2(struct xrdp_mm *self, tui8 *guid) { char text[256]; char *name; @@ -584,6 +568,10 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self) self->mod->mod_set_param(self->mod, "hostname", name); g_snprintf(text, 255, "%d", self->wm->session->client_info->keylayout); self->mod->mod_set_param(self->mod, "keylayout", text); + if (guid != 0) + { + self->mod->mod_set_param(self->mod, "guid", (char *) guid); + } for (i = 0; i < self->login_names->count; i++) { @@ -600,6 +588,10 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self) else { xrdp_wm_show_log(self->wm); + if (self->wm->hide_log_window) + { + rv = 1; + } } } @@ -781,7 +773,7 @@ xrdp_mm_process_rail_create_window(struct xrdp_mm* self, struct stream* s) in_uint16_le(s, title_bytes); if (title_bytes > 0) { - rwso.title_info = g_malloc(title_bytes + 1, 0); + rwso.title_info = g_new(char, title_bytes + 1); in_uint8a(s, rwso.title_info, title_bytes); rwso.title_info[title_bytes] = 0; } @@ -835,6 +827,7 @@ xrdp_mm_process_rail_create_window(struct xrdp_mm* self, struct stream* s) return rv; } +#if 0 /*****************************************************************************/ /* returns error process rail configure window order */ @@ -901,6 +894,7 @@ xrdp_mm_process_rail_configure_window(struct xrdp_mm* self, struct stream* s) g_free(rwso.visibility_rects); return rv; } +#endif /*****************************************************************************/ /* returns error @@ -962,7 +956,7 @@ xrdp_mm_process_rail_update_window_text(struct xrdp_mm* self, struct stream* s) g_memset(&rwso, 0, sizeof(rwso)); in_uint32_le(s, size); /* title size */ - rwso.title_info = g_malloc(size + 1, 0); + rwso.title_info = g_new(char, size + 1); in_uint8a(s, rwso.title_info, size); rwso.title_info[size] = 0; g_writeln(" set window title %s size %d 0x%8.8x", rwso.title_info, size, flags); @@ -1074,7 +1068,6 @@ xrdp_mm_chan_data_in(struct trans *trans) { struct xrdp_mm *self; struct stream *s; - int id; int size; int error; @@ -1091,7 +1084,7 @@ xrdp_mm_chan_data_in(struct trans *trans) return 1; } - in_uint32_le(s, id); + in_uint8s(s, 4); /* id */ in_uint32_le(s, size); error = trans_force_read(trans, size - 8); @@ -1128,7 +1121,7 @@ xrdp_mm_chan_send_init(struct xrdp_mm *self) /*****************************************************************************/ /* connect to chansrv */ static int APP_CC -xrdp_mm_connect_chansrv(struct xrdp_mm *self, char *ip, char *port) +xrdp_mm_connect_chansrv(struct xrdp_mm *self, const char *ip, const char *port) { int index; @@ -1139,15 +1132,16 @@ xrdp_mm_connect_chansrv(struct xrdp_mm *self, char *ip, char *port) { /* unix socket */ self->chan_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192); - self->chan_trans->is_term = g_is_term; } else { /* tcp */ self->chan_trans = trans_create(TRANS_MODE_TCP, 8192, 8192); - self->chan_trans->is_term = g_is_term; } + self->chan_trans->is_term = g_is_term; + self->chan_trans->si = &(self->wm->session->si); + self->chan_trans->my_source = XRDP_SOURCE_CHANSRV; self->chan_trans->trans_data_in = xrdp_mm_chan_data_in; self->chan_trans->header_size = 8; self->chan_trans->callback_data = self; @@ -1168,7 +1162,7 @@ xrdp_mm_connect_chansrv(struct xrdp_mm *self, char *ip, char *port) if (!(self->chan_trans_up)) { - log_message(LOG_LEVEL_ERROR,"xrdp_mm_connect_chansrv: error in" + log_message(LOG_LEVEL_ERROR,"xrdp_mm_connect_chansrv: error in " "trans_connect chan"); } @@ -1181,7 +1175,7 @@ xrdp_mm_connect_chansrv(struct xrdp_mm *self, char *ip, char *port) } else { - log_message(LOG_LEVEL_DEBUG,"xrdp_mm_connect_chansrv: chansrv" + log_message(LOG_LEVEL_DEBUG,"xrdp_mm_connect_chansrv: chansrv " "connect successful"); } } @@ -1208,24 +1202,29 @@ xrdp_mm_process_login_response(struct xrdp_mm *self, struct stream *s) int ok; int display; int rv; - char text[256]; char ip[256]; char port[256]; + tui8 guid[16]; + tui8* pguid; rv = 0; in_uint16_be(s, ok); in_uint16_be(s, display); - + pguid = 0; + if (s_check_rem(s, 16)) + { + in_uint8a(s, guid, 16); + pguid = guid; + } if (ok) { self->display = display; - g_snprintf(text, 255, "xrdp_mm_process_login_response: login successful " - "for display %d", display); - xrdp_wm_log_msg(self->wm, text); + xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, + "login successful for display %d", display); if (xrdp_mm_setup_mod1(self) == 0) { - if (xrdp_mm_setup_mod2(self) == 0) + if (xrdp_mm_setup_mod2(self, pguid) == 0) { xrdp_mm_get_value(self, "ip", ip, 255); xrdp_wm_set_login_mode(self->wm, 10); @@ -1247,11 +1246,13 @@ xrdp_mm_process_login_response(struct xrdp_mm *self, struct stream *s) } else { - xrdp_wm_log_msg(self->wm, "xrdp_mm_process_login_response: " - "login failed"); - log_message(LOG_LEVEL_INFO,"xrdp_mm_process_login_response: " - "login failed"); + xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, + "login failed for display %d", display); xrdp_wm_show_log(self->wm); + if (self->wm->hide_log_window) + { + rv = 1; + } } cleanup_sesman_connection(self); @@ -1410,8 +1411,9 @@ xrdp_mm_sesman_data_in(struct trans *trans) error = xrdp_mm_process_login_response(self, s); break; default: - xrdp_wm_log_msg(self->wm, "An undefined reply code was received from sesman"); - log_message(LOG_LEVEL_ERROR,"Fatal xrdp_mm_sesman_data_in: unknown cmd code %d", code); + xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, + "Undefined reply code %d received from sesman", + code); cleanup_sesman_connection(self); break; } @@ -1471,7 +1473,7 @@ access_control(char *username, char *password, char *srv) if (reply > 0) { /* We wait in 5 sec for a reply from sesman*/ - if (g_tcp_can_recv(socket, 5000)) + if (g_sck_can_recv(socket, 5000)) { reply = g_tcp_recv(socket, in_s->end, 500, 0); @@ -1501,7 +1503,7 @@ access_control(char *username, char *password, char *srv) else { log_message(LOG_LEVEL_ERROR, "Corrupt reply size or " - "version from sesman: %d", size); + "version from sesman: %ld", size); } } else @@ -1570,6 +1572,7 @@ getPAMError(const int pamError, char *text, int text_bytes) { switch (pamError) { +#if defined(LINUXPAM) case PAM_SUCCESS: return "Success"; case PAM_OPEN_ERR: @@ -1635,6 +1638,71 @@ getPAMError(const int pamError, char *text, int text_bytes) default: g_snprintf(text, text_bytes, "Not defined PAM error:%d", pamError); return text; +#elif defined(OPENPAM) + case PAM_SUCCESS: /* 0 */ + return "Success"; + case PAM_OPEN_ERR: + return "dlopen() failure"; + case PAM_SYMBOL_ERR: + return "Symbol not found"; + case PAM_SERVICE_ERR: + return "Error in service module"; + case PAM_SYSTEM_ERR: + return "System error"; + case PAM_BUF_ERR: + return "Memory buffer error"; + case PAM_CONV_ERR: + return "Conversation error"; + case PAM_PERM_DENIED: + return "Permission denied"; + case PAM_MAXTRIES: + return "Have exhausted maximum number of retries for service."; + case PAM_AUTH_ERR: + return "Authentication failure"; + case PAM_NEW_AUTHTOK_REQD: /* 10 */ + return "Authentication token is no longer valid; new one required."; + case PAM_CRED_INSUFFICIENT: + return "Insufficient credentials to access authentication data"; + case PAM_AUTHINFO_UNAVAIL: + return "Authentication service cannot retrieve authentication info."; + case PAM_USER_UNKNOWN: + return "User not known to the underlying authentication module"; + case PAM_CRED_UNAVAIL: + return "Authentication service cannot retrieve user credentials"; + case PAM_CRED_EXPIRED: + return "User credentials expired"; + case PAM_CRED_ERR: + return "Failure setting user credentials"; + case PAM_ACCT_EXPIRED: + return "User account has expired"; + case PAM_AUTHTOK_EXPIRED: + return "Authentication token expired"; + case PAM_SESSION_ERR: + return "Session failure"; + case PAM_AUTHTOK_ERR: /* 20 */ + return "Authentication token manipulation error"; + case PAM_AUTHTOK_RECOVERY_ERR: + return "Failed to recover old authentication token"; + case PAM_AUTHTOK_LOCK_BUSY: + return "Authentication token lock busy"; + case PAM_AUTHTOK_DISABLE_AGING: + return "Authentication token aging disabled"; + case PAM_NO_MODULE_DATA: + return "No module specific data is present"; + case PAM_IGNORE: + return "Please ignore underlying account module"; + case PAM_ABORT: + return "General failure"; + case PAM_TRY_AGAIN: + return "Failed preliminary check by password service"; + case PAM_MODULE_UNKNOWN: + return "Module is unknown"; + case PAM_DOMAIN_UNKNOWN: /* 29 */ + return "Unknown authentication domain"; + default: + g_snprintf(text, text_bytes, "Not defined PAM error:%d", pamError); + return text; +#endif } } @@ -1643,6 +1711,7 @@ getPAMAdditionalErrorInfo(const int pamError, struct xrdp_mm *self) { switch (pamError) { +#if defined(LINUXPAM) case PAM_SUCCESS: return NULL; case PAM_OPEN_ERR: @@ -1686,6 +1755,49 @@ getPAMAdditionalErrorInfo(const int pamError, struct xrdp_mm *self) } default: return "No expected error"; +#elif defined(OPENPAM) + case PAM_SUCCESS: /* 0 */ + return NULL; + case PAM_OPEN_ERR: + case PAM_SYMBOL_ERR: + case PAM_SERVICE_ERR: + case PAM_SYSTEM_ERR: + case PAM_BUF_ERR: + case PAM_CONV_ERR: + case PAM_PERM_DENIED: + case PAM_MAXTRIES: + case PAM_AUTH_ERR: + case PAM_NEW_AUTHTOK_REQD: /* 10 */ + case PAM_CRED_INSUFFICIENT: + case PAM_AUTHINFO_UNAVAIL: + case PAM_USER_UNKNOWN: + case PAM_CRED_UNAVAIL: + case PAM_CRED_EXPIRED: + case PAM_CRED_ERR: + case PAM_ACCT_EXPIRED: + case PAM_AUTHTOK_EXPIRED: + case PAM_SESSION_ERR: + case PAM_AUTHTOK_ERR: /* 20 */ + case PAM_AUTHTOK_RECOVERY_ERR: + case PAM_AUTHTOK_LOCK_BUSY: + case PAM_AUTHTOK_DISABLE_AGING: + case PAM_NO_MODULE_DATA: + case PAM_IGNORE: + case PAM_ABORT: + case PAM_TRY_AGAIN: + case PAM_MODULE_UNKNOWN: + case PAM_DOMAIN_UNKNOWN: /* 29 */ + if (self->wm->pamerrortxt[0]) + { + return self->wm->pamerrortxt; + } + else + { + return "Authentication error - Verify that user/password is valid"; + } + default: + return "No expected error"; +#endif } } #endif @@ -1703,8 +1815,6 @@ xrdp_mm_connect(struct xrdp_mm *self) char *name; char *value; char ip[256]; - char errstr[256]; - char text[256]; char port[8]; char chansrvport[256]; #ifdef ACCESS @@ -1722,8 +1832,6 @@ xrdp_mm_connect(struct xrdp_mm *self) /* make sure we start in correct state */ cleanup_states(self); g_memset(ip, 0, sizeof(ip)); - g_memset(errstr, 0, sizeof(errstr)); - g_memset(text, 0, sizeof(text)); g_memset(port, 0, sizeof(port)); g_memset(chansrvport, 0, sizeof(chansrvport)); rv = 0; /* success */ @@ -1786,10 +1894,10 @@ xrdp_mm_connect(struct xrdp_mm *self) if (use_pam_auth) { int reply; - char replytxt[128]; char pam_error[128]; const char *additionalError; - xrdp_wm_log_msg(self->wm, "Please wait, we now perform access control..."); + xrdp_wm_log_msg(self->wm, LOG_LEVEL_DEBUG, + "Please wait, we now perform access control..."); /* g_writeln("we use pam modules to check if we can approve this user"); */ if (!g_strncmp(pam_auth_username, "same", 255)) @@ -1807,19 +1915,14 @@ xrdp_mm_connect(struct xrdp_mm *self) /* access_control return 0 on success */ reply = access_control(pam_auth_username, pam_auth_password, pam_auth_sessionIP); - g_sprintf(replytxt, "Reply from access control: %s", - getPAMError(reply, pam_error, 127)); + xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, + "Reply from access control: %s", + getPAMError(reply, pam_error, 127)); - xrdp_wm_log_msg(self->wm, replytxt); - log_message(LOG_LEVEL_INFO, replytxt); additionalError = getPAMAdditionalErrorInfo(reply, self); - if (additionalError) + if (additionalError && additionalError[0]) { - g_snprintf(replytxt, 127, "%s", additionalError); - if (replytxt[0]) - { - xrdp_wm_log_msg(self->wm, replytxt); - } + xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "%s", additionalError); } if (reply != 0) @@ -1838,8 +1941,8 @@ xrdp_mm_connect(struct xrdp_mm *self) self->sesman_trans = trans_create(TRANS_MODE_TCP, 8192, 8192); self->sesman_trans->is_term = g_is_term; xrdp_mm_get_sesman_port(port, sizeof(port)); - g_snprintf(text, 255, "connecting to sesman ip %s port %s", ip, port); - xrdp_wm_log_msg(self->wm, text); + xrdp_wm_log_msg(self->wm, LOG_LEVEL_DEBUG, + "connecting to sesman ip %s port %s", ip, port); /* xrdp_mm_sesman_data_in is the callback that is called when data arrives */ self->sesman_trans->trans_data_in = xrdp_mm_sesman_data_in; self->sesman_trans->header_size = 8; @@ -1863,16 +1966,15 @@ xrdp_mm_connect(struct xrdp_mm *self) if (ok) { /* fully connect */ - xrdp_wm_log_msg(self->wm, "sesman connect ok"); + xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "sesman connect ok"); self->connected_state = 1; rv = xrdp_mm_send_login(self); } else { - g_snprintf(errstr, 255, "Failure to connect to sesman: %s port: %s", - ip, port); - xrdp_wm_log_msg(self->wm, errstr); - log_message(LOG_LEVEL_ERROR,errstr); + xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, + "Error connecting to sesman: %s port: %s", + ip, port); trans_delete(self->sesman_trans); self->sesman_trans = 0; self->sesman_trans_up = 0; @@ -1883,17 +1985,16 @@ xrdp_mm_connect(struct xrdp_mm *self) { if (xrdp_mm_setup_mod1(self) == 0) { - if (xrdp_mm_setup_mod2(self) == 0) + if (xrdp_mm_setup_mod2(self, 0) == 0) { xrdp_wm_set_login_mode(self->wm, 10); - rv = 0; /*sucess*/ + rv = 0; /*success*/ } else { /* connect error */ - g_snprintf(errstr, 255, "Failure to connect to: %s", ip); - log_message(LOG_LEVEL_ERROR,errstr); - xrdp_wm_log_msg(self->wm, errstr); + xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, + "Error connecting to: %s", ip); rv = 1; /* failure */ } } @@ -1917,7 +2018,7 @@ xrdp_mm_connect(struct xrdp_mm *self) xrdp_mm_connect_chansrv(self, "", chansrvport); } - log_message(LOG_LEVEL_DEBUG,"returnvalue from xrdp_mm_connect %d", rv); + log_message(LOG_LEVEL_DEBUG,"return value from xrdp_mm_connect %d", rv); return rv; } @@ -1956,9 +2057,9 @@ xrdp_mm_get_wait_objs(struct xrdp_mm *self, } } - if (self->in_codec_mode) + if (self->encoder != 0) { - read_objs[(*rcount)++] = self->xrdp_encoder_event_processed; + read_objs[(*rcount)++] = self->encoder->xrdp_encoder_event_processed; } return rv; @@ -2021,6 +2122,28 @@ xrdp_mm_dump_jpeg(struct xrdp_mm *self, XRDP_ENC_DATA_DONE *enc_done) /*****************************************************************************/ int APP_CC +xrdp_mm_check_chan(struct xrdp_mm *self) +{ + //g_writeln("xrdp_mm_check_chan:"); + if ((self->chan_trans != 0) && self->chan_trans_up) + { + if (trans_check_wait_objs(self->chan_trans) != 0) + { + self->delete_chan_trans = 1; + } + } + if (self->delete_chan_trans) + { + trans_delete(self->chan_trans); + self->chan_trans = 0; + self->chan_trans_up = 0; + self->delete_chan_trans = 0; + } + return 0; +} + +/*****************************************************************************/ +int APP_CC xrdp_mm_check_wait_objs(struct xrdp_mm *self) { XRDP_ENC_DATA_DONE *enc_done; @@ -2029,6 +2152,8 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self) int y; int cx; int cy; + int use_frame_acks; + int ex; if (self == 0) { @@ -2042,6 +2167,11 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self) if (trans_check_wait_objs(self->sesman_trans) != 0) { self->delete_sesman_trans = 1; + if (self->wm->hide_log_window) + { + /* if hide_log_window, this is fatal */ + rv = 1; + } } } @@ -2077,15 +2207,18 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self) self->delete_chan_trans = 0; } - if (self->in_codec_mode) + if (self->encoder != 0) { - if (g_is_wait_obj_set(self->xrdp_encoder_event_processed)) + + use_frame_acks = self->wm->client_info->use_frame_acks; + + if (g_is_wait_obj_set(self->encoder->xrdp_encoder_event_processed)) { - g_reset_wait_obj(self->xrdp_encoder_event_processed); - tc_mutex_lock(self->mutex); + g_reset_wait_obj(self->encoder->xrdp_encoder_event_processed); + tc_mutex_lock(self->encoder->mutex); enc_done = (XRDP_ENC_DATA_DONE*) - fifo_remove_item(self->fifo_processed); - tc_mutex_unlock(self->mutex); + fifo_remove_item(self->encoder->fifo_processed); + tc_mutex_unlock(self->encoder->mutex); while (enc_done != 0) { /* do something with msg */ @@ -2103,36 +2236,85 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self) if (enc_done->comp_bytes > 0) { + libxrdp_fastpath_send_frame_marker(self->wm->session, 0, + enc_done->enc->frame_id); libxrdp_fastpath_send_surface(self->wm->session, enc_done->comp_pad_data, enc_done->pad_bytes, enc_done->comp_bytes, x, y, x + cx, y + cy, - 32, self->codec_id, cx, cy); + 32, self->encoder->codec_id, cx, cy); + libxrdp_fastpath_send_frame_marker(self->wm->session, 1, + enc_done->enc->frame_id); } /* free enc_done */ if (enc_done->last) { LLOGLN(10, ("xrdp_mm_check_wait_objs: last set")); - self->mod->mod_frame_ack(self->mod, - enc_done->enc->flags, enc_done->enc->frame_id); + if (use_frame_acks == 0) + { + self->mod->mod_frame_ack(self->mod, + enc_done->enc->flags, + enc_done->enc->frame_id); + } + else + { +#if 1 + ex = self->wm->client_info->max_unacknowledged_frame_count; + if (self->encoder->frame_id_client + ex > self->encoder->frame_id_server) + { + if (self->encoder->frame_id_server > self->encoder->frame_id_server_sent) + { + LLOGLN(10, ("xrdp_mm_check_wait_objs: 1 -- %d", self->encoder->frame_id_server)); + self->encoder->frame_id_server_sent = self->encoder->frame_id_server; + self->mod->mod_frame_ack(self->mod, 0, self->encoder->frame_id_server); + } + } +#endif + } g_free(enc_done->enc->drects); g_free(enc_done->enc->crects); g_free(enc_done->enc); } g_free(enc_done->comp_pad_data); g_free(enc_done); - tc_mutex_lock(self->mutex); + tc_mutex_lock(self->encoder->mutex); enc_done = (XRDP_ENC_DATA_DONE*) - fifo_remove_item(self->fifo_processed); - tc_mutex_unlock(self->mutex); + fifo_remove_item(self->encoder->fifo_processed); + tc_mutex_unlock(self->encoder->mutex); } } } return rv; } +/*****************************************************************************/ +/* frame ack from client */ +int APP_CC +xrdp_mm_frame_ack(struct xrdp_mm *self, int frame_id) +{ + int ex; + + LLOGLN(10, ("xrdp_mm_frame_ack:")); + self->encoder->frame_id_client = frame_id; + if (self->wm->client_info->use_frame_acks == 0) + { + return 1; + } + ex = self->wm->client_info->max_unacknowledged_frame_count; + if (self->encoder->frame_id_client + ex > self->encoder->frame_id_server) + { + if (self->encoder->frame_id_server > self->encoder->frame_id_server_sent) + { + LLOGLN(10, ("xrdp_mm_frame_ack: frame_id_server %d", self->encoder->frame_id_server)); + self->encoder->frame_id_server_sent = self->encoder->frame_id_server; + self->mod->mod_frame_ack(self->mod, 0, self->encoder->frame_id_server); + } + } + return 0; +} + #if 0 /*****************************************************************************/ struct xrdp_painter *APP_CC @@ -2354,9 +2536,9 @@ server_paint_rects(struct xrdp_mod* mod, int num_drects, short *drects, mm = wm->mm; LLOGLN(10, ("server_paint_rects:")); - LLOGLN(10, ("server_paint_rects: %d", mm->in_codec_mode)); + LLOGLN(10, ("server_paint_rects: %p", mm->encoder)); - if (mm->in_codec_mode) + if (mm->encoder != 0) { /* copy formal params to XRDP_ENC_DATA */ enc_data = (XRDP_ENC_DATA *) g_malloc(sizeof(XRDP_ENC_DATA), 1); @@ -2393,18 +2575,19 @@ server_paint_rects(struct xrdp_mod* mod, int num_drects, short *drects, enc_data->height = height; enc_data->flags = flags; enc_data->frame_id = frame_id; + mm->encoder->frame_id_server = frame_id; if (width == 0 || height == 0) { LLOGLN(10, ("server_paint_rects: error")); } /* insert into fifo for encoder thread to process */ - tc_mutex_lock(mm->mutex); - fifo_add_item(mm->fifo_to_proc, (void *) enc_data); - tc_mutex_unlock(mm->mutex); + tc_mutex_lock(mm->encoder->mutex); + fifo_add_item(mm->encoder->fifo_to_proc, (void *) enc_data); + tc_mutex_unlock(mm->encoder->mutex); /* signal xrdp_encoder thread */ - g_set_wait_obj(mm->xrdp_encoder_event_to_proc); + g_set_wait_obj(mm->encoder->xrdp_encoder_event_to_proc); return 0; } @@ -2479,12 +2662,12 @@ server_msg(struct xrdp_mod *mod, char *msg, int code) if (code == 1) { - g_writeln(msg); + g_writeln("%s",msg); return 0; } wm = (struct xrdp_wm *)(mod->wm); - return xrdp_wm_log_msg(wm, msg); + return xrdp_wm_log_msg(wm, LOG_LEVEL_DEBUG, "%s", msg); } /*****************************************************************************/ @@ -2597,7 +2780,7 @@ 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, +server_set_brush(struct xrdp_mod *mod, int x_origin, int y_origin, int style, char *pattern) { struct xrdp_painter *p; @@ -2609,8 +2792,8 @@ server_set_brush(struct xrdp_mod *mod, int x_orgin, int y_orgin, return 0; } - p->brush.x_orgin = x_orgin; - p->brush.y_orgin = y_orgin; + p->brush.x_origin = x_origin; + p->brush.y_origin = y_origin; p->brush.style = style; g_memcpy(p->brush.pattern, pattern, 8); return 0; @@ -2654,7 +2837,7 @@ 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, +server_add_char(struct xrdp_mod *mod, int font, int character, int offset, int baseline, int width, int height, char *data) { @@ -2668,7 +2851,7 @@ server_add_char(struct xrdp_mod *mod, int font, int charactor, fi.data = data; fi.bpp = 1; return libxrdp_orders_send_font(((struct xrdp_wm *)mod->wm)->session, - &fi, font, charactor); + &fi, font, character); } /*****************************************************************************/ @@ -2750,7 +2933,6 @@ int read_allowed_channel_names(struct list *names, struct list *values) int fd; int ret = 0; char cfg_file[256]; - int pos; g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); fd = g_file_open(cfg_file); @@ -2759,7 +2941,6 @@ int read_allowed_channel_names(struct list *names, struct list *values) { names->auto_free = 1; values->auto_free = 1; - pos = 0; /* all values in this section can be valid channel names */ if (file_read_section(fd, "channels", names, values) == 0) @@ -2981,7 +3162,7 @@ server_query_channel(struct xrdp_mod *mod, int index, char *channel_name, /*****************************************************************************/ /* returns -1 on error */ int DEFAULT_CC -server_get_channel_id(struct xrdp_mod *mod, char *name) +server_get_channel_id(struct xrdp_mod *mod, const char *name) { struct xrdp_wm *wm; @@ -3291,7 +3472,7 @@ server_monitored_desktop(struct xrdp_mod *mod, /*****************************************************************************/ int DEFAULT_CC -server_add_char_alpha(struct xrdp_mod* mod, int font, int charactor, +server_add_char_alpha(struct xrdp_mod* mod, int font, int character, int offset, int baseline, int width, int height, char* data) { @@ -3305,5 +3486,5 @@ server_add_char_alpha(struct xrdp_mod* mod, int font, int charactor, fi.data = data; fi.bpp = 8; return libxrdp_orders_send_font(((struct xrdp_wm*)mod->wm)->session, - &fi, font, charactor); + &fi, font, character); } diff --git a/xrdp/xrdp_painter.c b/xrdp/xrdp_painter.c index e47f36ed..361a6a74 100644 --- a/xrdp/xrdp_painter.c +++ b/xrdp/xrdp_painter.c @@ -20,17 +20,152 @@ #include "xrdp.h" +#if defined(XRDP_PAINTER) +#include <painter.h> /* libpainter */ +#endif + +#define LLOG_LEVEL 1 +#define LLOGLN(_level, _args) \ + do \ + { \ + if (_level < LLOG_LEVEL) \ + { \ + g_write("xrdp:xrdp_painter [%10.10u]: ", g_time3()); \ + g_writeln _args ; \ + } \ + } \ + while (0) + +#if defined(XRDP_PAINTER) + +/*****************************************************************************/ +static int APP_CC +xrdp_painter_add_dirty_rect(struct xrdp_painter *self, int x, int y, + int cx, int cy, struct xrdp_rect *clip_rect) +{ + int x2; + int y2; + struct xrdp_rect rect; + + if (clip_rect != 0) + { + x2 = x + cx; + y2 = y + cy; + x = MAX(x, clip_rect->left); + y = MAX(y, clip_rect->top); + x2 = MIN(x2, clip_rect->right); + y2 = MIN(y2, clip_rect->bottom); + cx = x2 - x; + cy = y2 - y; + } + if (cx < 1 || cy < 1) + { + return 0; + } + rect.left = x; + rect.top = y; + rect.right = x + cx; + rect.bottom = y + cy; + xrdp_region_add_rect(self->dirty_region, &rect); + LLOGLN(10, ("xrdp_painter_add_dirty_rect: x %d y %d cx %d cy %d", + x, y, cx, cy)); + return 0; +} + +/*****************************************************************************/ +static int +xrdp_painter_send_dirty(struct xrdp_painter *self) +{ + int cx; + int cy; + int bpp; + int Bpp; + int index; + int jndex; + int error; + char *ldata; + char *src; + char *dst; + struct xrdp_rect rect; + + LLOGLN(10, ("xrdp_painter_send_dirty:")); + + bpp = self->wm->screen->bpp; + Bpp = (bpp + 7) / 8; + if (Bpp == 3) + { + Bpp = 4; + } + + jndex = 0; + error = xrdp_region_get_rect(self->dirty_region, jndex, &rect); + while (error == 0) + { + cx = rect.right - rect.left; + cy = rect.bottom - rect.top; + ldata = (char *)g_malloc(cx * cy * Bpp, 0); + if (ldata == 0) + { + return 1; + } + src = self->wm->screen->data; + src += self->wm->screen->line_size * rect.top; + src += rect.left * Bpp; + dst = ldata; + for (index = 0; index < cy; index++) + { + g_memcpy(dst, src, cx * Bpp); + src += self->wm->screen->line_size; + dst += cx * Bpp; + } + LLOGLN(10, ("xrdp_painter_send_dirty: x %d y %d cx %d cy %d", + rect.left, rect.top, cx, cy)); + libxrdp_send_bitmap(self->session, cx, cy, bpp, + ldata, rect.left, rect.top, cx, cy); + g_free(ldata); + + jndex++; + error = xrdp_region_get_rect(self->dirty_region, jndex, &rect); + } + + xrdp_region_delete(self->dirty_region); + self->dirty_region = xrdp_region_create(self->wm); + + return 0; +} + +#endif + /*****************************************************************************/ struct xrdp_painter *APP_CC xrdp_painter_create(struct xrdp_wm *wm, struct xrdp_session *session) { struct xrdp_painter *self; + LLOGLN(10, ("xrdp_painter_create:")); self = (struct xrdp_painter *)g_malloc(sizeof(struct xrdp_painter), 1); self->wm = wm; self->session = session; - self->rop = 0xcc; /* copy gota use 0xcc*/ + self->rop = 0xcc; /* copy will use 0xcc */ self->clip_children = 1; + + + if (self->session->client_info->no_orders_supported) + { +#if defined(XRDP_PAINTER) + if (painter_create(&(self->painter)) != PT_ERROR_NONE) + { + self->painter = 0; + LLOGLN(0, ("xrdp_painter_create: painter_create failed")); + } + else + { + LLOGLN(10, ("xrdp_painter_create: painter_create success")); + } + self->dirty_region = xrdp_region_create(wm); +#endif + } + return self; } @@ -38,11 +173,17 @@ xrdp_painter_create(struct xrdp_wm *wm, struct xrdp_session *session) void APP_CC xrdp_painter_delete(struct xrdp_painter *self) { + LLOGLN(10, ("xrdp_painter_delete:")); if (self == 0) { return; } +#if defined(XRDP_PAINTER) + painter_delete(self->painter); + xrdp_region_delete(self->dirty_region); +#endif + g_free(self); } @@ -54,6 +195,13 @@ wm_painter_set_target(struct xrdp_painter *self) int index; struct list *del_list; + LLOGLN(10, ("wm_painter_set_target:")); + + if (self->painter != 0) + { + return 0; + } + if (self->wm->target_surface->type == WND_TYPE_SCREEN) { if (self->wm->current_surface_index != 0xffff) @@ -97,11 +245,19 @@ wm_painter_set_target(struct xrdp_painter *self) int APP_CC xrdp_painter_begin_update(struct xrdp_painter *self) { + LLOGLN(10, ("xrdp_painter_begin_update:")); if (self == 0) { return 0; } + self->begin_end_level++; + + if (self->painter != 0) + { + return 0; + } + libxrdp_orders_init(self->session); wm_painter_set_target(self); return 0; @@ -111,11 +267,25 @@ xrdp_painter_begin_update(struct xrdp_painter *self) int APP_CC xrdp_painter_end_update(struct xrdp_painter *self) { + LLOGLN(10, ("xrdp_painter_end_update:")); if (self == 0) { return 0; } + self->begin_end_level--; + + if (self->painter != 0) + { +#if defined(XRDP_PAINTER) + if (self->begin_end_level == 0) + { + xrdp_painter_send_dirty(self); + return 0; + } +#endif + } + libxrdp_orders_send(self->session); return 0; } @@ -262,7 +432,7 @@ xrdp_painter_rop(int rop, int src, int dst) /*****************************************************************************/ int APP_CC -xrdp_painter_text_width(struct xrdp_painter *self, char *text) +xrdp_painter_text_width(struct xrdp_painter *self, const char *text) { int index; int rv; @@ -270,6 +440,7 @@ xrdp_painter_text_width(struct xrdp_painter *self, char *text) struct xrdp_font_char *font_item; twchar *wstr; + LLOGLN(10, ("xrdp_painter_text_width:")); xrdp_painter_font_needed(self); if (self->font == 0) @@ -299,7 +470,7 @@ xrdp_painter_text_width(struct xrdp_painter *self, char *text) /*****************************************************************************/ int APP_CC -xrdp_painter_text_height(struct xrdp_painter *self, char *text) +xrdp_painter_text_height(struct xrdp_painter *self, const char *text) { int index; int rv; @@ -307,6 +478,7 @@ xrdp_painter_text_height(struct xrdp_painter *self, char *text) struct xrdp_font_char *font_item; twchar *wstr; + LLOGLN(10, ("xrdp_painter_text_height:")); xrdp_painter_font_needed(self); if (self->font == 0) @@ -342,6 +514,13 @@ xrdp_painter_setup_brush(struct xrdp_painter *self, { int cache_id; + LLOGLN(10, ("xrdp_painter_setup_brush:")); + + if (self->painter != 0) + { + return 0; + } + g_memcpy(out_brush, in_brush, sizeof(struct xrdp_brush)); if (in_brush->style == 3) @@ -358,6 +537,38 @@ xrdp_painter_setup_brush(struct xrdp_painter *self, return 0; } +#if defined(XRDP_PAINTER) + +/*****************************************************************************/ +static int APP_CC +get_pt_format(struct xrdp_painter *self) +{ + switch (self->wm->screen->bpp) + { + case 8: + return PT_FORMAT_r3g3b2; + case 15: + return PT_FORMAT_a1r5g5b5; + case 16: + return PT_FORMAT_r5g6b5; + } + return PT_FORMAT_a8r8g8b8; +} + +/*****************************************************************************/ +static int +get_rgb_from_rdp_color(struct xrdp_painter *self, int rdp_color) +{ + if (self->wm->screen->bpp < 24) + { + return rdp_color; + } + /* well, this is really BGR2RGB */ + return XR_RGB2BGR(rdp_color); +} + +#endif + /*****************************************************************************/ /* fill in an area of the screen with one color */ int APP_CC @@ -375,11 +586,120 @@ xrdp_painter_fill_rect(struct xrdp_painter *self, int dy; int rop; + LLOGLN(10, ("xrdp_painter_fill_rect:")); + if (self == 0) { return 0; } + dx = 0; + dy = 0; + + if (self->painter != 0) + { +#if defined(XRDP_PAINTER) + struct painter_bitmap dst_pb; + struct xrdp_bitmap *ldst; + struct painter_bitmap pat; + + LLOGLN(10, ("xrdp_painter_fill_rect: dst->type %d", dst->type)); + if (dst->type != WND_TYPE_OFFSCREEN) + { + LLOGLN(10, ("xrdp_painter_fill_rect: using painter")); + + ldst = self->wm->screen; + + g_memset(&dst_pb, 0, sizeof(dst_pb)); + dst_pb.format = get_pt_format(self); + dst_pb.width = ldst->width; + dst_pb.stride_bytes = ldst->line_size; + dst_pb.height = ldst->height; + dst_pb.data = ldst->data; + + LLOGLN(10, ("xrdp_painter_fill_rect: ldst->width %d ldst->height %d " + "dst->data %p self->fg_color %d", + ldst->width, ldst->height, ldst->data, self->fg_color)); + + 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; + + rop = self->rop; + switch (self->rop) + { + case 0x5a: + rop = PT_ROP_DSx; + break; + case 0xf0: + rop = PT_ROP_S; + break; + case 0xfb: + rop = PT_ROP_D; + break; + case 0xc0: + rop = PT_ROP_DSa; + break; + } + painter_set_rop(self->painter, rop); + + if (self->mix_mode == 0) + { + painter_set_pattern_mode(self->painter, PT_PATTERN_MODE_OPAQUE); + painter_set_fgcolor(self->painter, get_rgb_from_rdp_color(self, self->fg_color)); + k = 0; + while (xrdp_region_get_rect(region, k, &rect) == 0) + { + if (rect_intersect(&rect, &clip_rect, &draw_rect)) + { + painter_set_clip(self->painter, + draw_rect.left, draw_rect.top, + draw_rect.right - draw_rect.left, + draw_rect.bottom - draw_rect.top); + painter_fill_rect(self->painter, &dst_pb, x, y, cx, cy); + xrdp_painter_add_dirty_rect(self, x, y, cx, cy, &draw_rect); + } + k++; + } + } + else + { + painter_set_pattern_mode(self->painter, PT_PATTERN_MODE_OPAQUE); + painter_set_fgcolor(self->painter, get_rgb_from_rdp_color(self, self->fg_color)); + painter_set_bgcolor(self->painter, get_rgb_from_rdp_color(self, self->bg_color)); + painter_set_pattern_origin(self->painter, self->brush.x_origin, self->brush.y_origin); + g_memset(&pat, 0, sizeof(pat)); + pat.format = PT_FORMAT_c1; + pat.width = 8; + pat.stride_bytes = 1; + pat.height = 8; + pat.data = self->brush.pattern; + k = 0; + while (xrdp_region_get_rect(region, k, &rect) == 0) + { + if (rect_intersect(&rect, &clip_rect, &draw_rect)) + { + painter_set_clip(self->painter, + draw_rect.left, draw_rect.top, + draw_rect.right - draw_rect.left, + draw_rect.bottom - draw_rect.top); + painter_fill_pattern(self->painter, &dst_pb, &pat, + x, y, x, y, cx, cy); + xrdp_painter_add_dirty_rect(self, x, y, cx, cy, &draw_rect); + } + k++; + } + } + painter_clear_clip(self->painter); + xrdp_region_delete(region); + } + return 0; +#endif + } + /* todo data */ if (dst->type == WND_TYPE_BITMAP) /* 0 */ @@ -508,11 +828,14 @@ xrdp_painter_draw_text(struct xrdp_painter *self, struct xrdp_font_char *font_item; twchar *wstr; + LLOGLN(10, ("xrdp_painter_draw_text:")); + if (self == 0) { return 0; } + len = g_mbstowcs(0, text, 0); if (len < 1) @@ -534,6 +857,88 @@ xrdp_painter_draw_text(struct xrdp_painter *self, return 0; } + if (self->painter != 0) + { +#if defined(XRDP_PAINTER) + struct painter_bitmap pat; + struct painter_bitmap dst_pb; + struct xrdp_bitmap *ldst; + + if (dst->type != WND_TYPE_OFFSCREEN) + { + ldst = self->wm->screen; + /* convert to wide char */ + wstr = (twchar *)g_malloc((len + 2) * sizeof(twchar), 0); + g_mbstowcs(wstr, text, len + 1); + font = self->font; + total_width = 0; + total_height = 0; + for (index = 0; index < len; index++) + { + font_item = font->font_items + wstr[index]; + k = font_item->incby; + total_width += k; + total_height = MAX(total_height, font_item->height); + } + 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, + total_width, total_height, + region, self->clip_children); + x += dx; + y += dy; + g_memset(&dst_pb, 0, sizeof(dst_pb)); + dst_pb.format = get_pt_format(self); + dst_pb.width = ldst->width; + dst_pb.stride_bytes = ldst->line_size; + dst_pb.height = ldst->height; + dst_pb.data = ldst->data; + painter_set_rop(self->painter, PT_ROP_S); + painter_set_pattern_origin(self->painter, 0, 0); + painter_set_pattern_mode(self->painter, PT_PATTERN_MODE_NORMAL); + painter_set_fgcolor(self->painter, + get_rgb_from_rdp_color(self, self->fg_color)); + k = 0; + while (xrdp_region_get_rect(region, k, &rect) == 0) + { + if (rect_intersect(&rect, &clip_rect, &draw_rect)) + { + painter_set_clip(self->painter, + draw_rect.left, draw_rect.top, + draw_rect.right - draw_rect.left, + draw_rect.bottom - draw_rect.top); + for (index = 0; index < len; index++) + { + font_item = font->font_items + wstr[index]; + g_memset(&pat, 0, sizeof(pat)); + pat.format = PT_FORMAT_c1; + pat.width = font_item->width; + pat.stride_bytes = (font_item->width + 7) / 8; + pat.height = font_item->height; + pat.data = font_item->data; + x1 = x + font_item->offset; + y1 = y + (font_item->height + font_item->baseline); + painter_fill_pattern(self->painter, &dst_pb, &pat, + 0, 0, x1, y1, + font_item->width, + font_item->height); + xrdp_painter_add_dirty_rect(self, x, y, + font_item->width, + font_item->height, + &draw_rect); + x += font_item->incby; + } + } + k++; + } + painter_clear_clip(self->painter); + xrdp_region_delete(region); + g_free(wstr); + } + return 0; +#endif + } + /* convert to wide char */ wstr = (twchar *)g_malloc((len + 2) * sizeof(twchar), 0); g_mbstowcs(wstr, text, len + 1); @@ -616,11 +1021,18 @@ xrdp_painter_draw_text2(struct xrdp_painter *self, int dx; int dy; + LLOGLN(0, ("xrdp_painter_draw_text2:")); + if (self == 0) { return 0; } + if (self->painter != 0) + { + return 0; + } + /* todo data */ if (dst->type == WND_TYPE_BITMAP) @@ -711,11 +1123,76 @@ xrdp_painter_copy(struct xrdp_painter *self, int index; struct list *del_list; + LLOGLN(10, ("xrdp_painter_copy:")); + if (self == 0 || src == 0 || dst == 0) { return 0; } + if (self->painter != 0) + { +#if defined(XRDP_PAINTER) + struct painter_bitmap src_pb; + struct painter_bitmap dst_pb; + struct xrdp_bitmap *ldst; + + LLOGLN(10, ("xrdp_painter_copy: src->type %d dst->type %d", src->type, dst->type)); + LLOGLN(10, ("xrdp_painter_copy: self->rop 0x%2.2x", self->rop)); + + if (dst->type != WND_TYPE_OFFSCREEN) + { + LLOGLN(10, ("xrdp_painter_copy: using painter")); + ldst = self->wm->screen; + + g_memset(&dst_pb, 0, sizeof(dst_pb)); + dst_pb.format = get_pt_format(self); + dst_pb.width = ldst->width; + dst_pb.stride_bytes = ldst->line_size; + dst_pb.height = ldst->height; + dst_pb.data = ldst->data; + + g_memset(&src_pb, 0, sizeof(src_pb)); + src_pb.format = get_pt_format(self); + src_pb.width = src->width; + src_pb.stride_bytes = src->line_size; + src_pb.height = src->height; + src_pb.data = src->data; + + 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; + k = 0; + + painter_set_rop(self->painter, self->rop); + while (xrdp_region_get_rect(region, k, &rect1) == 0) + { + if (rect_intersect(&rect1, &clip_rect, &draw_rect)) + { + painter_set_clip(self->painter, + draw_rect.left, draw_rect.top, + draw_rect.right - draw_rect.left, + draw_rect.bottom - draw_rect.top); + LLOGLN(10, (" x %d y %d cx %d cy %d srcx %d srcy %d", + x, y, cx, cy, srcx, srcy)); + painter_copy(self->painter, &dst_pb, x, y, cx, cy, + &src_pb, srcx, srcy); + xrdp_painter_add_dirty_rect(self, x, y, cx, cy, + &draw_rect); + } + k++; + } + painter_clear_clip(self->painter); + xrdp_region_delete(region); + } + + return 0; +#endif + } + /* todo data */ if (dst->type == WND_TYPE_BITMAP) @@ -848,7 +1325,7 @@ xrdp_painter_copy(struct xrdp_painter *self, while (i < (srcx + cx)) { w = MIN(64, ((srcx + cx) - i)); - h = MIN(63, ((srcy + cy) - j)); + h = MIN(64, ((srcy + cy) - j)); b = xrdp_bitmap_create(w, h, src->bpp, 0, self->wm); #if 1 xrdp_bitmap_copy_box_with_crc(src, b, i, j, w, h); @@ -883,7 +1360,7 @@ xrdp_painter_copy(struct xrdp_painter *self, i += 64; } - j += 63; + j += 64; } xrdp_region_delete(region); @@ -915,15 +1392,21 @@ xrdp_painter_composite(struct xrdp_painter* self, int k; int dx; int dy; - int palette_id; int cache_srcidx; int cache_mskidx; + LLOGLN(0, ("xrdp_painter_composite:")); + if (self == 0 || src == 0 || dst == 0) { return 0; } + if (self->painter != 0) + { + return 0; + } + /* todo data */ if (dst->type == WND_TYPE_BITMAP) @@ -939,7 +1422,6 @@ xrdp_painter_composite(struct xrdp_painter* self, dstx += dx; dsty += dy; - palette_id = 0; cache_srcidx = src->item_index; cache_mskidx = -1; if (mskflags & 1) @@ -987,10 +1469,75 @@ xrdp_painter_line(struct xrdp_painter *self, int dy; int rop; + LLOGLN(10, ("xrdp_painter_line:")); if (self == 0) { return 0; } + if (self->painter != 0) + { +#if defined(XRDP_PAINTER) + int x; + int y; + int cx; + int cy; + struct painter_bitmap dst_pb; + struct xrdp_bitmap *ldst; + + LLOGLN(10, ("xrdp_painter_line: dst->type %d", dst->type)); + LLOGLN(10, ("xrdp_painter_line: self->rop 0x%2.2x", self->rop)); + + if (dst->type != WND_TYPE_OFFSCREEN) + { + LLOGLN(10, ("xrdp_painter_line: using painter")); + ldst = self->wm->screen; + + g_memset(&dst_pb, 0, sizeof(dst_pb)); + dst_pb.format = get_pt_format(self); + dst_pb.width = ldst->width; + dst_pb.stride_bytes = ldst->line_size; + dst_pb.height = ldst->height; + dst_pb.data = ldst->data; + + xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); + region = xrdp_region_create(self->wm); + x = MIN(x1, x2); + y = MIN(y1, y2); + cx = g_abs(x1 - x2) + 1; + cy = g_abs(y1 - y2) + 1; + xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, + region, self->clip_children); + x1 += dx; + y1 += dy; + x2 += dx; + y2 += dy; + k = 0; + rop = self->rop; + + painter_set_rop(self->painter, rop); + painter_set_fgcolor(self->painter, self->pen.color); + while (xrdp_region_get_rect(region, k, &rect) == 0) + { + if (rect_intersect(&rect, &clip_rect, &draw_rect)) + { + painter_set_clip(self->painter, + draw_rect.left, draw_rect.top, + draw_rect.right - draw_rect.left, + draw_rect.bottom - draw_rect.top); + painter_line(self->painter, &dst_pb, x1, y1, x2, x2, + self->pen.width, 0); + xrdp_painter_add_dirty_rect(self, x, y, cx, cy, + &draw_rect); + } + k++; + } + painter_clear_clip(self->painter); + xrdp_region_delete(region); + } + + return 0; +#endif + } /* todo data */ diff --git a/xrdp/xrdp_process.c b/xrdp/xrdp_process.c index 5a7cd1d8..45e2acc6 100644 --- a/xrdp/xrdp_process.c +++ b/xrdp/xrdp_process.c @@ -138,13 +138,43 @@ xrdp_process_data_in(struct trans *self) } if (pro->session->up_and_running) { + pro->server_trans->header_size = 2; pro->server_trans->extra_flags = 1; - pro->server_trans->header_size = 4; init_stream(s, 0); } break; case 1: + /* we got 2 bytes */ + if (s->p[0] == 3) + { + pro->server_trans->header_size = 4; + pro->server_trans->extra_flags = 2; + } + else + { + if (s->p[1] & 0x80) + { + pro->server_trans->header_size = 3; + pro->server_trans->extra_flags = 2; + } + else + { + len = (tui8)(s->p[1]); + pro->server_trans->header_size = len; + pro->server_trans->extra_flags = 3; + } + } + + len = (int) (s->end - s->data); + if (pro->server_trans->header_size > len) + { + /* not enough data read yet */ + break; + } + /* FALLTHROUGH */ + + case 2: /* we have enough now to get the PDU bytes */ len = libxrdp_get_pdu_bytes(s->p); if (len == -1) @@ -154,10 +184,17 @@ xrdp_process_data_in(struct trans *self) return 1; } pro->server_trans->header_size = len; - pro->server_trans->extra_flags = 2; - break; + pro->server_trans->extra_flags = 3; - case 2: + len = (int) (s->end - s->data); + if (pro->server_trans->header_size > len) + { + /* not enough data read yet */ + break; + } + /* FALLTHROUGH */ + + case 3: /* the whole PDU is read in now process */ s->p = s->data; if (xrdp_process_loop(pro, s) != 0) @@ -167,7 +204,7 @@ xrdp_process_data_in(struct trans *self) return 1; } init_stream(s, 0); - pro->server_trans->header_size = 4; + pro->server_trans->header_size = 2; pro->server_trans->extra_flags = 1; break; } @@ -195,12 +232,14 @@ xrdp_process_main_loop(struct xrdp_process *self) self->server_trans->callback_data = self; init_stream(self->server_trans->in_s, 8192 * 4); self->session = libxrdp_init((tbus)self, self->server_trans); + self->server_trans->si = &(self->session->si); + self->server_trans->my_source = XRDP_SOURCE_CLIENT; /* this callback function is in xrdp_wm.c */ self->session->callback = callback; /* this function is just above */ self->session->is_term = xrdp_is_term; - if (libxrdp_process_incomming(self->session) == 0) + if (libxrdp_process_incoming(self->session) == 0) { init_stream(self->server_trans->in_s, 32 * 1024); @@ -217,8 +256,8 @@ xrdp_process_main_loop(struct xrdp_process *self) robjs[robjs_count++] = self->self_term_event; xrdp_wm_get_wait_objs(self->wm, robjs, &robjs_count, wobjs, &wobjs_count, &timeout); - trans_get_wait_objs(self->server_trans, robjs, &robjs_count); - + trans_get_wait_objs_rw(self->server_trans, robjs, &robjs_count, + wobjs, &wobjs_count, &timeout); /* wait */ if (g_obj_wait(robjs, robjs_count, wobjs, wobjs_count, timeout) != 0) { @@ -251,7 +290,7 @@ xrdp_process_main_loop(struct xrdp_process *self) } else { - g_writeln("xrdp_process_main_loop: libxrdp_process_incomming failed"); + g_writeln("xrdp_process_main_loop: libxrdp_process_incoming failed"); /* this will try to send a disconnect, maybe should check that connection got far enough */ libxrdp_disconnect(self->session); diff --git a/xrdp/xrdp_region.c b/xrdp/xrdp_region.c index c9b6a820..4da30f9d 100644 --- a/xrdp/xrdp_region.c +++ b/xrdp/xrdp_region.c @@ -20,6 +20,12 @@ #include "xrdp.h" +#if defined(XRDP_PIXMAN) +#include <pixman.h> +#else +#include "pixman-region.h" +#endif + /*****************************************************************************/ struct xrdp_region *APP_CC xrdp_region_create(struct xrdp_wm *wm) @@ -28,8 +34,9 @@ xrdp_region_create(struct xrdp_wm *wm) self = (struct xrdp_region *)g_malloc(sizeof(struct xrdp_region), 1); self->wm = wm; - self->rects = list_create(); - self->rects->auto_free = 1; + self->reg = (struct pixman_region16 *) + g_malloc(sizeof(struct pixman_region16), 1); + pixman_region_init(self->reg); return self; } @@ -41,276 +48,86 @@ xrdp_region_delete(struct xrdp_region *self) { return; } - - list_delete(self->rects); + pixman_region_fini(self->reg); + g_free(self->reg); g_free(self); } /*****************************************************************************/ +/* returns error */ int APP_CC xrdp_region_add_rect(struct xrdp_region *self, struct xrdp_rect *rect) { - struct xrdp_rect *r; + struct pixman_region16 lreg; - r = (struct xrdp_rect *)g_malloc(sizeof(struct xrdp_rect), 1); - *r = *rect; - list_add_item(self->rects, (long)r); + pixman_region_init_rect(&lreg, rect->left, rect->top, + rect->right - rect->left, + rect->bottom - rect->top); + if (!pixman_region_union(self->reg, self->reg, &lreg)) + { + pixman_region_fini(&lreg); + return 1; + } + pixman_region_fini(&lreg); return 0; } /*****************************************************************************/ +/* returns error */ int APP_CC -xrdp_region_insert_rect(struct xrdp_region *self, int i, int left, - int top, int right, int bottom) +xrdp_region_subtract_rect(struct xrdp_region *self, struct xrdp_rect *rect) { - struct xrdp_rect *r; + struct pixman_region16 lreg; - r = (struct xrdp_rect *)g_malloc(sizeof(struct xrdp_rect), 1); - r->left = left; - r->top = top; - r->right = right; - r->bottom = bottom; - list_insert_item(self->rects, i, (long)r); + pixman_region_init_rect(&lreg, rect->left, rect->top, + rect->right - rect->left, + rect->bottom - rect->top); + if (!pixman_region_subtract(self->reg, self->reg, &lreg)) + { + pixman_region_fini(&lreg); + return 1; + } + pixman_region_fini(&lreg); return 0; } /*****************************************************************************/ +/* returns error */ int APP_CC -xrdp_region_subtract_rect(struct xrdp_region *self, - struct xrdp_rect *rect) +xrdp_region_intersect_rect(struct xrdp_region* self, struct xrdp_rect* rect) { - struct xrdp_rect *r; - struct xrdp_rect rect1; - int i; + struct pixman_region16 lreg; - for (i = self->rects->count - 1; i >= 0; i--) + pixman_region_init_rect(&lreg, rect->left, rect->top, + rect->right - rect->left, + rect->bottom - rect->top); + if (!pixman_region_intersect(self->reg, self->reg, &lreg)) { - r = (struct xrdp_rect *)list_get_item(self->rects, i); - rect1 = *r; - r = &rect1; - - if (rect->left <= r->left && - rect->top <= r->top && - rect->right >= r->right && - rect->bottom >= r->bottom) - { - /* rect is not visible */ - 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) */ - 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) */ - 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) */ - 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) */ - 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) */ - 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) */ - 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) */ - 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) */ - 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 */ - 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 */ - 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) */ - 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) */ - 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) */ - 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) */ - 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 */ - 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_writeln("error in xrdp_region_subtract_rect"); - } + pixman_region_fini(&lreg); + return 1; } - + pixman_region_fini(&lreg); return 0; } + /*****************************************************************************/ +/* returns error */ int APP_CC xrdp_region_get_rect(struct xrdp_region *self, int index, struct xrdp_rect *rect) { - struct xrdp_rect *r; + struct pixman_box16 *box; + int count; - r = (struct xrdp_rect *)list_get_item(self->rects, index); - - if (r == 0) + box = pixman_region_rectangles(self->reg, &count); + if ((box != 0) && (index >= 0) && (index < count)) { - return 1; + rect->left = box[index].x1; + rect->top = box[index].y1; + rect->right = box[index].x2; + rect->bottom = box[index].y2; + return 0; } - - *rect = *r; - return 0; + return 1; } diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index 29aaac84..cc0eaa3c 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -42,14 +42,14 @@ struct xrdp_mod long param3, long param4); int (*mod_signal)(struct xrdp_mod* v); int (*mod_end)(struct xrdp_mod* v); - int (*mod_set_param)(struct xrdp_mod* v, char* name, char* value); + int (*mod_set_param)(struct xrdp_mod* v, const char *name, char* value); int (*mod_session_change)(struct xrdp_mod* v, int, int); int (*mod_get_wait_objs)(struct xrdp_mod* v, tbus* read_objs, int* rcount, tbus* write_objs, int* wcount, int* timeout); int (*mod_check_wait_objs)(struct xrdp_mod* v); int (*mod_frame_ack)(struct xrdp_mod* v, int flags, int frame_id); - long mod_dumby[100 - 10]; /* align, 100 minus the number of mod - functions above */ + tintptr mod_dumby[100 - 10]; /* align, 100 minus the number of mod + functions above */ /* server functions */ int (*server_begin_update)(struct xrdp_mod* v); int (*server_end_update)(struct xrdp_mod* v); @@ -70,12 +70,12 @@ struct xrdp_mod 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 (*server_set_brush)(struct xrdp_mod* v, int x_origin, int y_origin, 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 (*server_add_char)(struct xrdp_mod* v, int font, int character, int offset, int baseline, int width, int height, char* data); int (*server_draw_text)(struct xrdp_mod* v, int font, @@ -88,7 +88,7 @@ struct xrdp_mod int (*server_query_channel)(struct xrdp_mod* v, int index, char* channel_name, int* channel_flags); - int (*server_get_channel_id)(struct xrdp_mod* v, char* name); + int (*server_get_channel_id)(struct xrdp_mod* v, const char *name); int (*server_send_to_channel)(struct xrdp_mod* v, int channel_id, char* data, int data_len, int total_data_len, int flags); @@ -125,7 +125,7 @@ struct xrdp_mod int flags); int (*server_set_pointer_ex)(struct xrdp_mod* v, int x, int y, char* data, char* mask, int bpp); - int (*server_add_char_alpha)(struct xrdp_mod* mod, int font, int charactor, + int (*server_add_char_alpha)(struct xrdp_mod* mod, int font, int character, int offset, int baseline, int width, int height, char* data); @@ -146,13 +146,13 @@ struct xrdp_mod int num_crects, short *crects, char *data, int width, int height, int flags, int frame_id); - long server_dumby[100 - 43]; /* align, 100 minus the number of server - functions above */ + tintptr server_dumby[100 - 43]; /* align, 100 minus the number of server + functions above */ /* common */ - long handle; /* pointer to self as int */ - long wm; /* struct xrdp_wm* */ - long painter; - int sck; + tintptr handle; /* pointer to self as int */ + tintptr wm; /* struct xrdp_wm* */ + tintptr painter; + tintptr si; }; /* header for bmp file */ @@ -216,14 +216,14 @@ struct xrdp_brush_item { int stamp; /* expand this to a structure to handle more complicated brushes - for now its 8x8 1bpp brushes only */ + for now it's 8x8 1bpp brushes only */ char pattern[8]; }; /* moved to xrdp_constants.h #define XRDP_BITMAP_CACHE_ENTRIES 2048 */ -/* differnce caches */ +/* difference caches */ struct xrdp_cache { struct xrdp_wm* wm; /* owner */ @@ -292,19 +292,7 @@ struct xrdp_mm int chan_trans_up; /* true once connected to chansrv */ int delete_chan_trans; /* boolean set when done with channel connection */ int usechansrv; /* true if chansrvport is set in xrdp.ini or using sesman */ - - /* for codec mode operations */ - int in_codec_mode; - int codec_id; - int codec_quality; - tbus xrdp_encoder_event_to_proc; - tbus xrdp_encoder_event_processed; - tbus xrdp_encoder_term; - FIFO *fifo_to_proc; - FIFO *fifo_processed; - tbus mutex; - int (*process_enc)(struct xrdp_mm *self, struct xrdp_enc_data *enc); - void *codec_handle; + struct xrdp_encoder *encoder; }; struct xrdp_key_info @@ -423,7 +411,7 @@ struct xrdp_listen struct xrdp_region { struct xrdp_wm* wm; /* owner */ - struct list* rects; + struct pixman_region16 *reg; }; /* painter */ @@ -441,6 +429,9 @@ struct xrdp_painter struct xrdp_session* session; struct xrdp_wm* wm; /* owner */ struct xrdp_font* font; + void *painter; + struct xrdp_region *dirty_region; + int begin_end_level; }; /* window or bitmap */ @@ -604,7 +595,7 @@ struct xrdp_cfg_globals int ls_btn_cancel_y_pos; /* y pos for Cancel button */ int ls_btn_cancel_width; /* width of Cancel button */ int ls_btn_cancel_height; /* height of Cancel button */ - char ls_title[256]; /* loginscreen window title */ + char ls_title[256]; /* loginscreen window title */ }; struct xrdp_cfg_logging @@ -624,39 +615,4 @@ struct xrdp_config struct xrdp_cfg_channels cfg_channels; }; -/* used when scheduling tasks in xrdp_encoder.c */ -struct xrdp_enc_data -{ - struct xrdp_mod *mod; - int num_drects; - short *drects; /* 4 * num_drects */ - int num_crects; - short *crects; /* 4 * num_crects */ - char *data; - int width; - int height; - int flags; - int frame_id; -}; - -typedef struct xrdp_enc_data XRDP_ENC_DATA; - -/* used when scheduling tasks from xrdp_encoder.c */ -struct xrdp_enc_data_done -{ - int comp_bytes; - int pad_bytes; - char *comp_pad_data; - struct xrdp_enc_data *enc; - int last; /* true is this is last message for enc */ - int x; - int y; - int cx; - int cy; -}; - -typedef struct xrdp_enc_data_done XRDP_ENC_DATA_DONE; - - - #endif diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index 591c8a51..065bca5c 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -18,6 +18,8 @@ * simple window manager */ +#include <stdarg.h> +#include <stdio.h> #include "xrdp.h" #include "log.h" @@ -45,7 +47,7 @@ xrdp_wm_create(struct xrdp_process *owner, pid = g_getpid(); g_snprintf(event_name, 255, "xrdp_%8.8x_wm_login_mode_event_%8.8x", pid, owner->session_id); - log_message(LOG_LEVEL_DEBUG,event_name); + log_message(LOG_LEVEL_DEBUG, "%s", event_name); self->login_mode_event = g_create_wait_obj(event_name); self->painter = xrdp_painter_create(self, self->session); self->cache = xrdp_cache_create(self, self->session, self->client_info); @@ -60,7 +62,7 @@ xrdp_wm_create(struct xrdp_process *owner, self->current_surface_index = 0xffff; /* screen */ /* to store configuration from xrdp.ini */ - self->xrdp_config = g_malloc(sizeof(struct xrdp_config), 1); + self->xrdp_config = g_new0(struct xrdp_config, 1); return self; } @@ -546,7 +548,7 @@ xrdp_wm_init(struct xrdp_wm *self) struct list *names; struct list *values; char *q; - char *r; + const char *r; char param[256]; char section_name[256]; char cfg_file[256]; @@ -560,7 +562,7 @@ xrdp_wm_init(struct xrdp_wm *self) xrdp_wm_load_static_pointers(self); self->screen->bg_color = self->xrdp_config->cfg_globals.ls_top_window_bg_color; - if (self->session->client_info->rdp_autologin) + if (self->session->client_info->rdp_autologin || self->hide_log_window) { /* * NOTE: this should eventually be accessed from self->xrdp_config @@ -576,11 +578,13 @@ xrdp_wm_init(struct xrdp_wm *self) values->auto_free = 1; /* look for module name to be loaded */ - if (autorun_name[0] != 0) { + if (autorun_name[0] != 0) + { /* if autorun is configured in xrdp.ini, we enforce that module to be loaded */ g_strncpy(section_name, autorun_name, 255); } - else if (self->session->client_info->domain[0] != '_') + else if (self->session->client_info->domain[0] != '\0' && + self->session->client_info->domain[0] != '_') { /* domain names that starts with '_' are reserved for IP/DNS to * simplify for the user in a proxy setup */ @@ -593,9 +597,9 @@ xrdp_wm_init(struct xrdp_wm *self) { /* if no domain is passed, and no autorun in xrdp.ini, use the first item in the xrdp.ini - file thats not named + file that's not named 'globals' or 'Logging' or 'channels' */ - /* TODO: change this and have a 'autologin' + /* TODO: change this and have an 'autologin' line in globals section */ file_read_sections(fd, names); for (index = 0; index < names->count; index++) @@ -676,9 +680,9 @@ xrdp_wm_init(struct xrdp_wm *self) else { /* requested module name not found in xrdp.ini */ - g_writeln(" xrdp_wm_init: file_read_section returned non-zero, requested section not found in xrdp.ini"); - xrdp_wm_log_msg(self, "ERROR: The requested xrdp module not found in xrdp.ini," - " falling back to login window"); + xrdp_wm_log_msg(self, LOG_LEVEL_ERROR, + "Section \"%s\" not configured in xrdp.ini", + section_name); } list_delete(names); @@ -809,8 +813,8 @@ xrdp_wm_xor_pat(struct xrdp_wm *self, int x, int y, int cx, int cy) 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.x_origin = 0; + self->painter->brush.x_origin = 0; self->painter->brush.style = 3; self->painter->bg_color = self->black; self->painter->fg_color = self->white; @@ -831,45 +835,7 @@ xrdp_wm_xor_pat(struct xrdp_wm *self, int x, int y, int cx, int cy) } /*****************************************************************************/ -/* this don't are about nothing, just copy the bits */ -/* no clipping rects, no windows in the way, nothing */ -static int APP_CC -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; - // } - libxrdp_orders_init(self->session); - libxrdp_orders_screen_blt(self->session, dx, dy, sw, sh, sx, sy, rop, 0); - libxrdp_orders_send(self->session); - } - - return 0; -} - -/*****************************************************************************/ -/* return true is rect is totaly exposed going in reverse z order */ +/* return true if rect is totally exposed going in reverse z order */ /* from wnd up */ static int APP_CC xrdp_wm_is_rect_vis(struct xrdp_wm *self, struct xrdp_bitmap *wnd, @@ -931,6 +897,7 @@ xrdp_wm_move_window(struct xrdp_wm *self, struct xrdp_bitmap *wnd, MAKERECT(rect1, wnd->left, wnd->top, wnd->width, wnd->height); + self->painter->clip_children = 0; if (xrdp_wm_is_rect_vis(self, wnd, &rect1)) { rect2 = rect1; @@ -938,10 +905,13 @@ xrdp_wm_move_window(struct xrdp_wm *self, struct xrdp_bitmap *wnd, 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); + xrdp_painter_begin_update(self->painter); + xrdp_painter_copy(self->painter, self->screen, self->screen, + wnd->left + dx, wnd->top + dy, + wnd->width, wnd->height, + wnd->left, wnd->top); + xrdp_painter_end_update(self->painter); + wnd->left += dx; wnd->top += dy; r = xrdp_region_create(self); @@ -956,9 +926,11 @@ xrdp_wm_move_window(struct xrdp_wm *self, struct xrdp_bitmap *wnd, } xrdp_region_delete(r); + self->painter->clip_children = 1; return 0; } } + self->painter->clip_children = 1; wnd->left += dx; wnd->top += dy; @@ -967,6 +939,7 @@ xrdp_wm_move_window(struct xrdp_wm *self, struct xrdp_bitmap *wnd, return 0; } + /*****************************************************************************/ static int APP_CC xrdp_wm_undraw_dragging_box(struct xrdp_wm *self, int do_begin_end) @@ -1523,6 +1496,83 @@ xrdp_wm_key_sync(struct xrdp_wm *self, int device_flags, int key_flags) /*****************************************************************************/ int APP_CC +xrdp_wm_key_unicode(struct xrdp_wm *self, int device_flags, int unicode) +{ + int index; + + for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++) + { + if (unicode == self->keymap.keys_noshift[index].chr) + { + xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE); + return 0; + } + } + + for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++) + { + if (unicode == self->keymap.keys_shift[index].chr) + { + if (device_flags & KBD_FLAG_UP) + { + xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE); + xrdp_wm_key(self, KBD_FLAG_UP, XR_RDP_SCAN_LSHIFT); + } + else + { + xrdp_wm_key(self, KBD_FLAG_DOWN, XR_RDP_SCAN_LSHIFT); + xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE); + } + return 0; + } + } + + for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++) + { + if (unicode == self->keymap.keys_altgr[index].chr) + { + if (device_flags & KBD_FLAG_UP) + { + xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE); + xrdp_wm_key(self, KBD_FLAG_UP | KBD_FLAG_EXT, + XR_RDP_SCAN_ALT); + } + else + { + xrdp_wm_key(self, KBD_FLAG_DOWN | KBD_FLAG_EXT, + XR_RDP_SCAN_ALT); + xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE); + } + return 0; + } + } + + for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++) + { + if (unicode == self->keymap.keys_shiftaltgr[index].chr) + { + if (device_flags & KBD_FLAG_UP) + { + xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE); + xrdp_wm_key(self, KBD_FLAG_UP | KBD_FLAG_EXT, XR_RDP_SCAN_ALT); + xrdp_wm_key(self, KBD_FLAG_UP, XR_RDP_SCAN_LSHIFT); + } + else + { + xrdp_wm_key(self, KBD_FLAG_DOWN, XR_RDP_SCAN_LSHIFT); + xrdp_wm_key(self, KBD_FLAG_DOWN | KBD_FLAG_EXT, + XR_RDP_SCAN_ALT); + xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE); + } + return 0; + } + } + + return 0; +} + +/*****************************************************************************/ +int APP_CC xrdp_wm_pu(struct xrdp_wm *self, struct xrdp_bitmap *control) { int x; @@ -1687,7 +1737,7 @@ xrdp_wm_process_channel_data(struct xrdp_wm *self, } /******************************************************************************/ -/* this is the callbacks comming from libxrdp.so */ +/* this is the callbacks coming from libxrdp.so */ int DEFAULT_CC callback(long id, int msg, long param1, long param2, long param3, long param4) { @@ -1717,6 +1767,9 @@ callback(long id, int msg, long param1, long param2, long param3, long param4) case 4: /* RDP_INPUT_SCANCODE */ rv = xrdp_wm_key(wm, param3, param1); break; + case 5: /* RDP_INPUT_UNICODE */ + rv = xrdp_wm_key_unicode(wm, param3, param1); + break; case 0x8001: /* RDP_INPUT_MOUSE */ rv = xrdp_wm_process_input_mouse(wm, param3, param1, param2); break; @@ -1724,8 +1777,8 @@ callback(long id, int msg, long param1, long param2, long param3, long param4) rv = xrdp_wm_process_input_mousex(wm, param3, param1, param2); break; case 0x4444: /* invalidate, this is not from RDP_DATA_PDU_INPUT */ - /* like the rest, its from RDP_PDU_DATA with code 33 */ - /* its the rdp client asking for a screen update */ + /* like the rest, it's from RDP_PDU_DATA with code 33 */ + /* it's the rdp client asking for a screen update */ MAKERECT(rect, param1, param2, param3, param4); rv = xrdp_bitmap_invalidate(wm->screen, &rect); break; @@ -1733,8 +1786,14 @@ callback(long id, int msg, long param1, long param2, long param3, long param4) pass it to module if there is one */ rv = xrdp_wm_process_channel_data(wm, param1, param2, param3, param4); break; + case 0x5556: + rv = xrdp_mm_check_chan(wm->mm); + break; + case 0x5557: + //g_writeln("callback: frame ack %d", param1); + xrdp_mm_frame_ack(wm->mm, param1); + break; } - return rv; } @@ -1753,10 +1812,10 @@ xrdp_wm_login_mode_changed(struct xrdp_wm *self) if (self->login_mode == 0) { - /* this is the inital state of the login window */ + /* this is the initial state of the login window */ xrdp_wm_set_login_mode(self, 1); /* put the wm in login mode */ list_clear(self->log); - xrdp_wm_delete_all_childs(self); + xrdp_wm_delete_all_children(self); self->dragging = 0; xrdp_wm_init(self); } @@ -1765,7 +1824,7 @@ xrdp_wm_login_mode_changed(struct xrdp_wm *self) if (xrdp_mm_connect(self->mm) == 0) { xrdp_wm_set_login_mode(self, 3); /* put the wm in connected mode */ - xrdp_wm_delete_all_childs(self); + xrdp_wm_delete_all_children(self); self->dragging = 0; } else @@ -1775,7 +1834,7 @@ xrdp_wm_login_mode_changed(struct xrdp_wm *self) } else if (self->login_mode == 10) { - xrdp_wm_delete_all_childs(self); + xrdp_wm_delete_all_children(self); self->dragging = 0; xrdp_wm_set_login_mode(self, 11); } @@ -1850,22 +1909,21 @@ xrdp_wm_log_wnd_notify(struct xrdp_bitmap *wnd, return 0; } -void add_string_to_logwindow(char *msg, struct list *log) +static void +add_string_to_logwindow(const char *msg, struct list *log) { - - char *new_part_message; - char *current_pointer = msg ; - int processedlen = 0; + const char *new_part_message; + const char *current_pointer = msg; + int len_done = 0; do { - new_part_message = g_strndup(current_pointer, LOG_WINDOW_CHAR_PER_LINE) ; - g_writeln(new_part_message); - list_add_item(log, (long)new_part_message); - processedlen = processedlen + g_strlen(new_part_message); - current_pointer = current_pointer + g_strlen(new_part_message) ; - } - while ((processedlen < g_strlen(msg)) && (processedlen < DEFAULT_STRING_LEN)); + new_part_message = g_strndup(current_pointer, LOG_WINDOW_CHAR_PER_LINE); + g_writeln("%s", new_part_message); + list_add_item(log, (tintptr) new_part_message); + len_done += g_strlen(new_part_message); + current_pointer += g_strlen(new_part_message); + } while ((len_done < g_strlen(msg)) && (len_done < DEFAULT_STRING_LEN)); } /*****************************************************************************/ @@ -1877,6 +1935,10 @@ xrdp_wm_show_log(struct xrdp_wm *self) int h; int xoffset; int yoffset; + int index; + int primary_x_offset; + int primary_y_offset; + if (self->hide_log_window) { @@ -1905,6 +1967,23 @@ xrdp_wm_show_log(struct xrdp_wm *self) yoffset = 2; } + primary_x_offset = 0; + primary_y_offset = 0; + + /* multimon scenario, draw log window on primary monitor */ + if (self->client_info->monitorCount > 1) + { + for (index = 0; index < self->client_info->monitorCount; index++) + { + if (self->client_info->minfo_wm[index].is_primary) + { + primary_x_offset = self->client_info->minfo_wm[index].left; + primary_y_offset = self->client_info->minfo_wm[index].top; + break; + } + } + } + /* log window */ self->log_wnd = xrdp_bitmap_create(w, h, self->screen->bpp, WND_TYPE_WND, self); @@ -1912,8 +1991,8 @@ xrdp_wm_show_log(struct xrdp_wm *self) self->log_wnd->parent = self->screen; self->log_wnd->owner = self->screen; self->log_wnd->bg_color = self->grey; - self->log_wnd->left = xoffset; - self->log_wnd->top = yoffset; + self->log_wnd->left = primary_x_offset + xoffset; + self->log_wnd->top = primary_y_offset + yoffset; set_string(&(self->log_wnd->caption1), "Connection Log"); /* ok button */ but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self); @@ -1938,8 +2017,17 @@ xrdp_wm_show_log(struct xrdp_wm *self) /*****************************************************************************/ int APP_CC -xrdp_wm_log_msg(struct xrdp_wm *self, char *msg) +xrdp_wm_log_msg(struct xrdp_wm *self, enum logLevels loglevel, + const char *fmt, ...) { + va_list ap; + char msg[256]; + + va_start(ap, fmt); + vsnprintf(msg, sizeof(msg), fmt, ap); + va_end(ap); + + log_message(loglevel, "xrdp_wm_log_msg: %s", msg); add_string_to_logwindow(msg, self->log); return 0; } diff --git a/xrdp/xrdpwin.c b/xrdp/xrdpwin.c index ee78273b..25ca6048 100644 --- a/xrdp/xrdpwin.c +++ b/xrdp/xrdpwin.c @@ -34,7 +34,7 @@ static long g_sync_mutex = 0; static long g_sync1_mutex = 0; static tbus g_term_event = 0; static tbus g_sync_event = 0; -/* syncronize stuff */ +/* synchronize stuff */ static int g_sync_command = 0; static long g_sync_result = 0; static long g_sync_param1 = 0; @@ -344,16 +344,16 @@ main(int argc, char **argv) g_strncasecmp(argv[1], "--help", 255) == 0 || g_strncasecmp(argv[1], "-h", 255) == 0) { - g_writeln(""); + g_writeln("%s", ""); g_writeln("xrdp: A Remote Desktop Protocol server."); g_writeln("Copyright (C) Jay Sorg 2004-2011"); g_writeln("See http://xrdp.sourceforge.net for more information."); - g_writeln(""); + g_writeln("%s", ""); g_writeln("Usage: xrdp [options]"); g_writeln(" -h: show help"); g_writeln(" -install: install service"); g_writeln(" -remove: remove service"); - g_writeln(""); + g_writeln("%s", ""); g_exit(0); } else if (g_strncasecmp(argv[1], "-install", 255) == 0 || @@ -369,7 +369,7 @@ main(int argc, char **argv) g_exit(0); } - /* check if service is allready installed */ + /* check if service is already installed */ sc_ser = OpenService(sc_man, "xrdp", SERVICE_ALL_ACCESS); if (sc_ser == 0) @@ -383,7 +383,7 @@ main(int argc, char **argv) } else { - g_writeln("error service is allready installed"); + g_writeln("error service is already installed"); CloseServiceHandle(sc_ser); CloseServiceHandle(sc_man); g_exit(0); @@ -405,7 +405,7 @@ main(int argc, char **argv) g_exit(0); } - /* check if service is allready installed */ + /* check if service is already installed */ sc_ser = OpenService(sc_man, "xrdp", SERVICE_ALL_ACCESS); if (sc_ser == 0) @@ -423,7 +423,7 @@ main(int argc, char **argv) { g_writeln("Unknown Parameter"); g_writeln("xrdp -h for help"); - g_writeln(""); + g_writeln("%s", ""); g_exit(0); } } @@ -431,7 +431,7 @@ main(int argc, char **argv) { g_writeln("Unknown Parameter"); g_writeln("xrdp -h for help"); - g_writeln(""); + g_writeln("%s", ""); g_exit(0); } @@ -466,8 +466,8 @@ main(int argc, char **argv) if (fd == -1) { - g_writeln("problem opening to xrdp.pid"); - g_writeln("maybe its not running"); + g_writeln("cannot open %s, maybe xrdp is not running", + pid_file); } else { @@ -499,34 +499,34 @@ main(int argc, char **argv) g_strncasecmp(argv[1], "--help", 255) == 0 || g_strncasecmp(argv[1], "-h", 255) == 0) { - g_writeln(""); + g_writeln("%s", ""); g_writeln("xrdp: A Remote Desktop Protocol server."); g_writeln("Copyright (C) Jay Sorg 2004-2011"); g_writeln("See http://xrdp.sourceforge.net for more information."); - g_writeln(""); + g_writeln("%s", ""); g_writeln("Usage: xrdp [options]"); g_writeln(" -h: show help"); g_writeln(" -nodaemon: don't fork into background"); g_writeln(" -kill: shut down xrdp"); - g_writeln(""); + g_writeln("%s", ""); g_exit(0); } else if ((g_strncasecmp(argv[1], "-v", 255) == 0) || (g_strncasecmp(argv[1], "--version", 255) == 0)) { - g_writeln(""); + g_writeln("%s", ""); g_writeln("xrdp: A Remote Desktop Protocol server."); g_writeln("Copyright (C) Jay Sorg 2004-2011"); g_writeln("See http://xrdp.sourceforge.net for more information."); g_writeln("Version %s", PACKAGE_VERSION); - g_writeln(""); + g_writeln("%s", ""); g_exit(0); } else { g_writeln("Unknown Parameter"); g_writeln("xrdp -h for help"); - g_writeln(""); + g_writeln("%s", ""); g_exit(0); } } @@ -534,14 +534,14 @@ main(int argc, char **argv) { g_writeln("Unknown Parameter"); g_writeln("xrdp -h for help"); - g_writeln(""); + g_writeln("%s", ""); g_exit(0); } if (g_file_exist(pid_file)) /* xrdp.pid */ { - g_writeln("It looks like xrdp is allready running,"); - g_writeln("if not delete the xrdp.pid file and try again"); + g_writeln("It looks like xrdp is already running."); + g_writeln("If not, delete %s and try again.", pid_file); g_exit(0); } @@ -618,7 +618,6 @@ main(int argc, char **argv) g_threadid = tc_get_threadid(); g_listen = xrdp_listen_create(); g_signal_user_interrupt(xrdp_shutdown); /* SIGINT */ - g_signal_kill(xrdp_shutdown); /* SIGKILL */ g_signal_pipe(pipe_sig); /* SIGPIPE */ g_signal_terminate(xrdp_shutdown); /* SIGTERM */ g_sync_mutex = tc_mutex_create(); |