diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 63cb6f07..2877a376 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -28,6 +28,9 @@ #include "list.h" #include "file.h" #include "file_loc.h" +#include "log.h" +#include "rail.h" +#include "xcommon.h" static struct trans* g_lis_trans = 0; static struct trans* g_con_trans = 0; @@ -36,6 +39,7 @@ static int g_num_chan_items = 0; static int g_cliprdr_index = -1; static int g_rdpsnd_index = -1; static int g_rdpdr_index = -1; +static int g_rail_index = -1; static tbus g_term_event = 0; static tbus g_thread_done_event = 0; @@ -46,17 +50,18 @@ int g_display_num = 0; int g_cliprdr_chan_id = -1; /* cliprdr */ int g_rdpsnd_chan_id = -1; /* rdpsnd */ int g_rdpdr_chan_id = -1; /* rdpdr */ +int g_rail_chan_id = -1; /* rail */ /*****************************************************************************/ /* returns error */ int APP_CC send_channel_data(int chan_id, char* data, int size) { - struct stream * s = (struct stream *)NULL; - int chan_flags = 0; - int total_size = 0; - int sent = 0; - int rv = 0; + struct stream * s; + int chan_flags; + int total_size; + int sent; + int rv; s = trans_get_out_s(g_con_trans, 8192); if (s == 0) @@ -176,18 +181,20 @@ process_message_init(struct stream* s) static int APP_CC process_message_channel_setup(struct stream* s) { - int num_chans = 0; - int index = 0; - int rv = 0; - struct chan_item* ci = (struct chan_item *)NULL; + int num_chans; + int index; + int rv; + struct chan_item* ci; g_num_chan_items = 0; g_cliprdr_index = -1; g_rdpsnd_index = -1; g_rdpdr_index = -1; + g_rail_index = -1; g_cliprdr_chan_id = -1; g_rdpsnd_chan_id = -1; g_rdpdr_chan_id = -1; + g_rail_chan_id = -1; LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup:")); in_uint16_le(s, num_chans); LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: num_chans %d", @@ -216,6 +223,11 @@ process_message_channel_setup(struct stream* s) g_rdpdr_index = g_num_chan_items; g_rdpdr_chan_id = ci->id; } + else if (g_strcasecmp(ci->name, "rail") == 0) + { + g_rail_index = g_num_chan_items; + g_rail_chan_id = ci->id; + } g_num_chan_items++; } rv = send_channel_setup_response_message(); @@ -231,6 +243,10 @@ process_message_channel_setup(struct stream* s) { dev_redir_init(); } + if (g_rail_index >= 0) + { + rail_init(); + } return rv; } @@ -266,6 +282,10 @@ process_message_channel_data(struct stream* s) { rv = dev_redir_data_in(s, chan_id, chan_flags, length, total_length); } + else if (chan_id == g_rail_chan_id) + { + rv = rail_data_in(s, chan_id, chan_flags, length, total_length); + } } return rv; } @@ -433,10 +453,10 @@ THREAD_RV THREAD_CC channel_thread_loop(void* in_val) { tbus objs[32]; - int num_objs = 0; - int timeout = 0; - int error = 0; - THREAD_RV rv = 0; + int num_objs; + int timeout; + int error; + THREAD_RV rv; LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start")); rv = 0; @@ -456,6 +476,7 @@ channel_thread_loop(void* in_val) clipboard_deinit(); sound_deinit(); dev_redir_deinit(); + rail_deinit(); break; } if (g_lis_trans != 0) @@ -475,6 +496,7 @@ channel_thread_loop(void* in_val) clipboard_deinit(); sound_deinit(); dev_redir_deinit(); + rail_deinit(); /* delete g_con_trans */ trans_delete(g_con_trans); g_con_trans = 0; @@ -486,7 +508,7 @@ channel_thread_loop(void* in_val) } } } - clipboard_check_wait_objs(); + xcommon_check_wait_objs(); sound_check_wait_objs(); dev_redir_check_wait_objs(); timeout = -1; @@ -495,7 +517,7 @@ channel_thread_loop(void* in_val) num_objs++; trans_get_wait_objs(g_lis_trans, objs, &num_objs); trans_get_wait_objs(g_con_trans, objs, &num_objs); - clipboard_get_wait_objs(objs, &num_objs, &timeout); + xcommon_get_wait_objs(objs, &num_objs, &timeout); sound_get_wait_objs(objs, &num_objs, &timeout); dev_redir_get_wait_objs(objs, &num_objs, &timeout); } @@ -595,15 +617,14 @@ main_cleanup(void) static int APP_CC read_ini(void) { - char filename[256] = ""; - struct list* names = (struct list *)NULL; - struct list* values = (struct list *)NULL; - char* name = (char *)NULL; - char* value = (char *)NULL; - int index = 0; - - g_memset(filename,0,(sizeof(char)*256)); + char filename[256]; + struct list* names; + struct list* values; + char* name; + char* value; + int index; + g_memset(filename,0,(sizeof(char) * 256)); names = list_create(); names->auto_free = 1; values = list_create(); diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c index f828a173..10d1fed5 100644 --- a/sesman/chansrv/clipboard.c +++ b/sesman/chansrv/clipboard.c @@ -30,6 +30,18 @@ #include "chansrv.h" #include "clipboard.h" +extern int g_cliprdr_chan_id; /* in chansrv.c */ + +extern Display* g_display; /* in xcommon.c */ +extern int g_x_socket; /* in xcommon.c */ +extern tbus g_x_wait_obj; /* in xcommon.c */ +extern Screen* g_screen; /* in xcommon.c */ +extern int g_screen_num; /* in xcommon.c */ + +int g_clip_up = 0; +int g_waiting_for_data_response = 0; +int g_waiting_for_data_response_time = 0; + static Atom g_clipboard_atom = 0; static Atom g_clip_property_atom = 0; static Atom g_timestamp_atom = 0; @@ -39,12 +51,7 @@ static Atom g_primary_atom = 0; static Atom g_secondary_atom = 0; static Atom g_get_time_atom = 0; static Atom g_utf8_atom = 0; -static int g_x_socket = 0; -static tbus g_x_wait_obj = 0; -static int g_clip_up = 0; static Window g_wnd = 0; -static Screen* g_screen = 0; -static int g_screen_num = 0; static int g_xfixes_event_base = 0; static int g_last_clip_size = 0; @@ -64,35 +71,6 @@ static int g_data_in_size = 0; static int g_data_in_time = 0; static int g_data_in_up_to_date = 0; static int g_got_format_announce = 0; -static int g_waiting_for_data_response = 0; -static int g_waiting_for_data_response_time = 0; - -static Display* g_display = 0; - -extern int g_cliprdr_chan_id; /* in chansrv.c */ - -/*****************************************************************************/ -int DEFAULT_CC -clipboard_error_handler(Display* dis, XErrorEvent* xer) -{ - char text[256]; - - XGetErrorText(dis, xer->error_code, text, 255); - LOGM((LOG_LEVEL_ERROR,"error [%s]", text)); - return 0; -} - -/*****************************************************************************/ -/* The X server had an internal error. This is the last function called. - Do any cleanup that needs to be done on exit, like removing temporary files. - Don't worry about memory leaks */ -int DEFAULT_CC -clipboard_fatal_handler(Display* dis) -{ - LOGM((LOG_LEVEL_ALWAYS, "fatal error, exiting")); - main_cleanup(); - return 0; -} /*****************************************************************************/ /* this is one way to get the current time from the x server */ @@ -114,17 +92,6 @@ clipboard_get_server_time(void) return xevent.xproperty.time; } -/*****************************************************************************/ -/* returns time in miliseconds - this is like g_time2 in os_calls, but not miliseconds since machine was - up, something else - this is a time value similar to what the xserver uses */ -static int APP_CC -clipboard_get_local_time(void) -{ - return g_time3(); -} - /*****************************************************************************/ /* returns error */ int APP_CC @@ -146,26 +113,6 @@ clipboard_init(void) } clipboard_deinit(); rv = 0; - /* setting the error handlers can cause problem when shutting down - chansrv on some xlibs */ - //XSetErrorHandler(clipboard_error_handler); - //XSetIOErrorHandler(clipboard_fatal_handler); - g_display = XOpenDisplay(0); - if (g_display == 0) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_init: XOpenDisplay failed")); - rv = 1; - } - if (rv == 0) - { - g_x_socket = XConnectionNumber(g_display); - if (g_x_socket == 0) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_init: XConnectionNumber failed")); - rv = 2; - } - g_x_wait_obj = g_create_wait_obj_from_socket(g_x_socket, 0); - } if (rv == 0) { g_clipboard_atom = XInternAtom(g_display, "CLIPBOARD", False); @@ -190,8 +137,6 @@ clipboard_init(void) st = XFixesQueryVersion(g_display, &ver_maj, &ver_min); LOGM((LOG_LEVEL_ERROR, "clipboard_init st %d, maj %d min %d", st, ver_maj, ver_min)); - g_screen_num = DefaultScreen(g_display); - g_screen = ScreenOfDisplay(g_display, g_screen_num); g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM", False); g_get_time_atom = XInternAtom(g_display, "XRDP_GET_TIME_ATOM", @@ -251,27 +196,16 @@ clipboard_init(void) int APP_CC clipboard_deinit(void) { - if (g_x_wait_obj != 0) - { - g_delete_wait_obj_from_socket(g_x_wait_obj); - g_x_wait_obj = 0; - } if (g_wnd != 0) { XDestroyWindow(g_display, g_wnd); g_wnd = 0; } - g_x_socket = 0; g_free(g_last_clip_data); g_last_clip_data = 0; g_last_clip_size = 0; free_stream(g_ins); g_ins = 0; - if (g_display != 0) - { - XCloseDisplay(g_display); - g_display = 0; - } g_clip_up = 0; return 0; } @@ -584,7 +518,7 @@ clipboard_process_data_response(struct stream* s, int clip_msg_status, } g_data_in_size = len; g_wcstombs(g_data_in, wtext, len + 1); - g_data_in_time = clipboard_get_local_time(); + g_data_in_time = xcommon_get_local_time(); g_data_in_up_to_date = 1; } if (g_data_in != 0) @@ -1032,7 +966,7 @@ clipboard_event_selection_request(XEvent* xevent) { clipboard_send_data_request(); g_waiting_for_data_response = 1; - g_waiting_for_data_response_time = clipboard_get_local_time(); + g_waiting_for_data_response_time = xcommon_get_local_time(); } g_selection_request_event_count++; return 0; @@ -1088,85 +1022,48 @@ clipboard_event_property_notify(XEvent* xevent) } /*****************************************************************************/ -/* returns error - this is called to get any wait objects for the main loop - timeout can be nil */ +/* returns 0, event handled, 1 unhandled */ int APP_CC -clipboard_get_wait_objs(tbus* objs, int* count, int* timeout) +clipboard_xevent(void* xevent) { - int lcount; - - if ((!g_clip_up) || (objs == 0) || (count == 0)) - { - return 0; - } - lcount = *count; - objs[lcount] = g_x_wait_obj; - lcount++; - *count = lcount; - return 0; -} - -/*****************************************************************************/ -int APP_CC -clipboard_check_wait_objs(void) -{ - XEvent xevent; - int time_diff; + XEvent* lxevent; if (!g_clip_up) { - return 0; + return 1; } - if (g_is_wait_obj_set(g_x_wait_obj)) + lxevent = (XEvent*)xevent; + switch (lxevent->type) { - if (XPending(g_display) < 1) - { - /* something is wrong, should not get here */ - LOGM((LOG_LEVEL_ERROR, "clipboard_check_wait_objs: sck closed")); - return 0; - } - if (g_waiting_for_data_response) - { - time_diff = clipboard_get_local_time() - - g_waiting_for_data_response_time; - if (time_diff > 1000) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_check_wait_objs: warning, " - "waiting for data response too long")); - } - } - while (XPending(g_display) > 0) - { - XNextEvent(g_display, &xevent); - switch (xevent.type) + case SelectionNotify: + clipboard_event_selection_notify(lxevent); + break; + case SelectionRequest: + clipboard_event_selection_request(lxevent); + break; + case SelectionClear: + clipboard_event_selection_clear(lxevent); + break; + case MappingNotify: + break; + case PropertyNotify: + clipboard_event_property_notify(lxevent); + break; + case UnmapNotify: + LOG(0, ("chansrv::clipboard_xevent: got UnmapNotify")); + break; + case ClientMessage: + LOG(0, ("chansrv::clipboard_xevent: got ClientMessage")); + break; + default: + if (lxevent->type == g_xfixes_event_base + + XFixesSetSelectionOwnerNotify) { - case SelectionNotify: - clipboard_event_selection_notify(&xevent); - break; - case SelectionRequest: - clipboard_event_selection_request(&xevent); - break; - case SelectionClear: - clipboard_event_selection_clear(&xevent); - break; - case MappingNotify: - break; - case PropertyNotify: - clipboard_event_property_notify(&xevent); - break; - default: - if (xevent.type == g_xfixes_event_base + - XFixesSetSelectionOwnerNotify) - { - clipboard_event_selection_owner_notify(&xevent); - break; - } - LOGM((LOG_LEVEL_ERROR, "clipboard_check_wait_objs unknown type %d", - xevent.type)); - break; + clipboard_event_selection_owner_notify(lxevent); + break; } - } + /* we didn't handle this message */ + return 1; } return 0; } diff --git a/sesman/chansrv/clipboard.h b/sesman/chansrv/clipboard.h index 56467f5b..40b4b0fc 100644 --- a/sesman/chansrv/clipboard.h +++ b/sesman/chansrv/clipboard.h @@ -30,8 +30,6 @@ int APP_CC clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length, int total_length); int APP_CC -clipboard_get_wait_objs(tbus* objs, int* count, int* timeout); -int APP_CC -clipboard_check_wait_objs(void); +clipboard_xevent(void* xevent); #endif diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c index fd480dc1..0d458ec7 100644 --- a/sesman/chansrv/rail.c +++ b/sesman/chansrv/rail.c @@ -25,3 +25,36 @@ #include "rail.h" #include "xcommon.h" #include "log.h" + +int g_rail_up = 0; + +/*****************************************************************************/ +int APP_CC +rail_init(void) +{ + return 0; +} + +/*****************************************************************************/ +int APP_CC +rail_deinit(void) +{ + return 0; +} + +/*****************************************************************************/ +/* data in from client ( client -> xrdp -> chansrv ) */ +int APP_CC +rail_data_in(struct stream* s, int chan_id, int chan_flags, int length, + int total_length) +{ + return 0; +} + +/*****************************************************************************/ +/* returns 0, event handled, 1 unhandled */ +int APP_CC +rail_xevent(void* xevent) +{ + return 1; +} diff --git a/sesman/chansrv/rail.h b/sesman/chansrv/rail.h index 58cce7b7..7dbcbc5a 100644 --- a/sesman/chansrv/rail.h +++ b/sesman/chansrv/rail.h @@ -19,4 +19,17 @@ #ifndef _RAIL_H_ #define _RAIL_H_ +#include "arch.h" +#include "parse.h" + +int APP_CC +rail_init(void); +int APP_CC +rail_deinit(void); +int APP_CC +rail_data_in(struct stream* s, int chan_id, int chan_flags, + int length, int total_length); +int APP_CC +rail_xevent(void* xevent); + #endif diff --git a/sesman/chansrv/xcommon.c b/sesman/chansrv/xcommon.c index 2e36d8ea..f54a531e 100644 --- a/sesman/chansrv/xcommon.c +++ b/sesman/chansrv/xcommon.c @@ -25,3 +25,161 @@ #include "clipboard.h" #include "rail.h" +extern int g_clip_up; /* in clipboard.c */ +extern int g_waiting_for_data_response; /* in clipboard.c */ +extern int g_waiting_for_data_response_time; /* in clipboard.c */ + +extern int g_rail_up; /* in rail.c */ + +Display* g_display = 0; +int g_x_socket = 0; +tbus g_x_wait_obj = 0; +Screen* g_screen = 0; +int g_screen_num = 0; +Window g_root_window = 0; +Atom g_wm_delete_window_atom = 0; +Atom g_wm_protocols_atom = 0; + +/*****************************************************************************/ +static int DEFAULT_CC +xcommon_error_handler(Display* dis, XErrorEvent* xer) +{ + char text[256]; + + XGetErrorText(dis, xer->error_code, text, 255); + log_message(LOG_LEVEL_ERROR, "X error [%s](%d) opcodes %d/%d\n " + "resource 0x%lx", text, xer->error_code, + xer->request_code, xer->minor_code, xer->resourceid); + return 0; +} + +/*****************************************************************************/ +/* The X server had an internal error. This is the last function called. + Do any cleanup that needs to be done on exit, like removing temporary files. + Don't worry about memory leaks */ +static int DEFAULT_CC +xcommon_fatal_handler(Display* dis) +{ + return 0; +} + +/*****************************************************************************/ +/* returns time in miliseconds + this is like g_time2 in os_calls, but not miliseconds since machine was + up, something else + this is a time value similar to what the xserver uses */ +int APP_CC +xcommon_get_local_time(void) +{ + return g_time3(); +} + +/******************************************************************************/ +/* this should be called first */ +int APP_CC +xcommon_init(void) +{ + if (g_display != 0) + { + g_writeln("xcommon_init: xcommon_init already called"); + return 0; + } + g_display = XOpenDisplay(0); + if (g_display == 0) + { + log_message(LOG_LEVEL_ERROR, "xcommon_init: error, XOpenDisplay failed"); + return 1; + } + + /* setting the error handlers can cause problem when shutting down + chansrv on some xlibs */ + XSetErrorHandler(xcommon_error_handler); + //XSetIOErrorHandler(xcommon_fatal_handler); + + g_x_socket = XConnectionNumber(g_display); + if (g_x_socket == 0) + { + log_message(LOG_LEVEL_ERROR, "xcommon_init: XConnectionNumber failed"); + return 1; + } + + g_x_wait_obj = g_create_wait_obj_from_socket(g_x_socket, 0); + g_screen_num = DefaultScreen(g_display); + g_screen = ScreenOfDisplay(g_display, g_screen_num); + + g_root_window = RootWindowOfScreen(g_screen); + + g_wm_delete_window_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", 0); + g_wm_protocols_atom = XInternAtom(g_display, "WM_PROTOCOLS", 0); + + return 0; +} + +/*****************************************************************************/ +/* returns error + this is called to get any wait objects for the main loop + timeout can be nil */ +int APP_CC +xcommon_get_wait_objs(tbus* objs, int* count, int* timeout) +{ + int lcount; + + if (((!g_clip_up) && (!g_rail_up)) || (objs == 0) || (count == 0)) + { + g_writeln("xcommon_get_wait_objs: nothing to do"); + return 0; + } + lcount = *count; + objs[lcount] = g_x_wait_obj; + lcount++; + *count = lcount; + return 0; +} + +/*****************************************************************************/ +int APP_CC +xcommon_check_wait_objs(void) +{ + XEvent xevent; + int time_diff; + int clip_rv; + int rail_rv; + + if ((!g_clip_up) && (!g_rail_up)) + { + g_writeln("xcommon_check_wait_objs: nothing to do"); + return 0; + } + if (g_is_wait_obj_set(g_x_wait_obj)) + { + if (XPending(g_display) < 1) + { + /* something is wrong, should not get here */ + log_message(LOG_LEVEL_ERROR, "xcommon_check_wait_objs: sck closed"); + return 0; + } + if (g_waiting_for_data_response) + { + time_diff = xcommon_get_local_time() - + g_waiting_for_data_response_time; + if (time_diff > 1000) + { + log_message(LOG_LEVEL_ERROR, "xcommon_check_wait_objs: warning, " + "waiting for data response too long"); + } + } + while (XPending(g_display) > 0) + { + g_memset(&xevent, 0, sizeof(xevent)); + XNextEvent(g_display, &xevent); + + clip_rv = clipboard_xevent(&xevent); + rail_rv = rail_xevent(&xevent); + if ((clip_rv == 1) && (rail_rv == 1)) + { + LOG(0, ("xcommon_check_wait_objs unknown xevent type %d", xevent.type)); + } + } + } + return 0; +} diff --git a/sesman/chansrv/xcommon.h b/sesman/chansrv/xcommon.h index 54a74dac..d5aa7e46 100644 --- a/sesman/chansrv/xcommon.h +++ b/sesman/chansrv/xcommon.h @@ -22,11 +22,11 @@ #include "arch.h" #include "parse.h" -int APP_CC -xcommon_init(void); int APP_CC xcommon_get_local_time(void); int APP_CC +xcommon_init(void); +int APP_CC xcommon_get_wait_objs(tbus* objs, int* count, int* timeout); int APP_CC xcommon_check_wait_objs(void);