rail: work on splitting X11 calls out to xcommon

ulab-next
Jay Sorg 12 years ago
parent cddcee4929
commit eafef9cd09

@ -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();

@ -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;
}

@ -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

@ -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;
}

@ -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

@ -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;
}

@ -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);

Loading…
Cancel
Save