diff options
author | Laxmikant Rashinkar <LK.Rashinkar@gmail.com> | 2012-09-19 20:51:34 -0700 |
---|---|---|
committer | Laxmikant Rashinkar <LK.Rashinkar@gmail.com> | 2012-09-19 20:51:34 -0700 |
commit | 1123323fda6d128fb98b0427e0ea5f6a2dc9e632 (patch) | |
tree | 3407a3771a069f812554312ce7c36db625139cc2 /sesman/chansrv | |
parent | 3cedfae76a2351bc8b1e5bd2ee33bbf8630dbacf (diff) | |
download | xrdp-proprietary-1123323fda6d128fb98b0427e0ea5f6a2dc9e632.tar.gz xrdp-proprietary-1123323fda6d128fb98b0427e0ea5f6a2dc9e632.zip |
o moved from GNU General Public License to Apache License, Version 2.0
o applied new coding standards to all .c files
o moved some files around
Diffstat (limited to 'sesman/chansrv')
-rw-r--r-- | sesman/chansrv/chansrv.c | 1722 | ||||
-rw-r--r-- | sesman/chansrv/clipboard.c | 2117 | ||||
-rw-r--r-- | sesman/chansrv/devredir.c | 14 | ||||
-rw-r--r-- | sesman/chansrv/rail.c | 894 | ||||
-rw-r--r-- | sesman/chansrv/sound.c | 820 | ||||
-rw-r--r-- | sesman/chansrv/xcommon.c | 202 |
6 files changed, 3030 insertions, 2739 deletions
diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 10a42ef9..0f69f1f6 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -32,10 +32,10 @@ #include "rail.h" #include "xcommon.h" -static struct trans* g_lis_trans = 0; -static struct trans* g_con_trans = 0; -static struct trans* g_api_lis_trans = 0; -static struct trans* g_api_con_trans = 0; +static struct trans *g_lis_trans = 0; +static struct trans *g_con_trans = 0; +static struct trans *g_api_lis_trans = 0; +static struct trans *g_api_con_trans = 0; static struct chan_item g_chan_items[32]; static int g_num_chan_items = 0; static int g_cliprdr_index = -1; @@ -54,7 +54,7 @@ int g_rdpsnd_chan_id = -1; /* rdpsnd */ int g_rdpdr_chan_id = -1; /* rdpdr */ int g_rail_chan_id = -1; /* rail */ -char* g_exec_name; +char *g_exec_name; tbus g_exec_event; tbus g_exec_mutex; tbus g_exec_sem; @@ -63,97 +63,109 @@ int g_exec_pid = 0; /* data in struct trans::callback_data */ struct xrdp_api_data { - int chan_id; - char header[64]; - int flags; + int chan_id; + char header[64]; + int flags; }; /*****************************************************************************/ /* add data to chan_item, on its way to the client */ /* returns error */ static int APP_CC -add_data_to_chan_item(struct chan_item* chan_item, char* data, int size) +add_data_to_chan_item(struct chan_item *chan_item, char *data, int size) { - struct stream* s; - struct chan_out_data* cod; - - make_stream(s); - init_stream(s, size); - g_memcpy(s->data, data, size); - s->end = s->data + size; - cod = (struct chan_out_data*)g_malloc(sizeof(struct chan_out_data), 1); - cod->s = s; - if (chan_item->tail == 0) - { - chan_item->tail = cod; - chan_item->head = cod; - } - else - { - chan_item->tail->next = cod; - chan_item->tail = cod; - } - return 0; + struct stream *s; + struct chan_out_data *cod; + + make_stream(s); + init_stream(s, size); + g_memcpy(s->data, data, size); + s->end = s->data + size; + cod = (struct chan_out_data *)g_malloc(sizeof(struct chan_out_data), 1); + cod->s = s; + + if (chan_item->tail == 0) + { + chan_item->tail = cod; + chan_item->head = cod; + } + else + { + chan_item->tail->next = cod; + chan_item->tail = cod; + } + + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -send_data_from_chan_item(struct chan_item* chan_item) +send_data_from_chan_item(struct chan_item *chan_item) { - struct stream* s; - struct chan_out_data* cod; - int bytes_left; - int size; - int chan_flags; - int error; - - if (chan_item->head == 0) - { - return 0; - } - cod = chan_item->head; - bytes_left = (int)(cod->s->end - cod->s->p); - size = MIN(1600, bytes_left); - chan_flags = 0; - if (cod->s->p == cod->s->data) - { - chan_flags |= 1; /* first */ - } - if (cod->s->p + size >= cod->s->end) - { - chan_flags |= 2; /* last */ - } - s = trans_get_out_s(g_con_trans, 8192); - out_uint32_le(s, 0); /* version */ - out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + size); /* size */ - out_uint32_le(s, 8); /* msg id */ - out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + size); /* size */ - out_uint16_le(s, chan_item->id); - out_uint16_le(s, chan_flags); - out_uint16_le(s, size); - out_uint32_le(s, cod->s->size); - out_uint8a(s, cod->s->p, size); - s_mark_end(s); - LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: -- " - "size %d chan_flags 0x%8.8x", size, chan_flags)); - error = trans_force_write(g_con_trans); - if (error != 0) - { - return 1; - } - cod->s->p += size; - if (cod->s->p >= cod->s->end) - { - free_stream(cod->s); - chan_item->head = chan_item->head->next; + struct stream *s; + struct chan_out_data *cod; + int bytes_left; + int size; + int chan_flags; + int error; + if (chan_item->head == 0) { - chan_item->tail = 0; + return 0; + } + + cod = chan_item->head; + bytes_left = (int)(cod->s->end - cod->s->p); + size = MIN(1600, bytes_left); + chan_flags = 0; + + if (cod->s->p == cod->s->data) + { + chan_flags |= 1; /* first */ } - g_free(cod); - } - return 0; + + if (cod->s->p + size >= cod->s->end) + { + chan_flags |= 2; /* last */ + } + + s = trans_get_out_s(g_con_trans, 8192); + out_uint32_le(s, 0); /* version */ + out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + size); /* size */ + out_uint32_le(s, 8); /* msg id */ + out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + size); /* size */ + out_uint16_le(s, chan_item->id); + out_uint16_le(s, chan_flags); + out_uint16_le(s, size); + out_uint32_le(s, cod->s->size); + out_uint8a(s, cod->s->p, size); + s_mark_end(s); + LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: -- " + "size %d chan_flags 0x%8.8x", size, chan_flags)); + error = trans_force_write(g_con_trans); + + if (error != 0) + { + return 1; + } + + cod->s->p += size; + + if (cod->s->p >= cod->s->end) + { + free_stream(cod->s); + chan_item->head = chan_item->head->next; + + if (chan_item->head == 0) + { + chan_item->tail = 0; + } + + g_free(cod); + } + + return 0; } /*****************************************************************************/ @@ -161,40 +173,44 @@ send_data_from_chan_item(struct chan_item* chan_item) static int APP_CC check_chan_items(void) { - int index; + int index; - for (index = 0; index < g_num_chan_items; index++) - { - if (g_chan_items[index].head != 0) + for (index = 0; index < g_num_chan_items; index++) { - send_data_from_chan_item(g_chan_items + index); + if (g_chan_items[index].head != 0) + { + send_data_from_chan_item(g_chan_items + index); + } } - } - return 0; + + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -send_channel_data(int chan_id, char* data, int size) +send_channel_data(int chan_id, char *data, int size) { - int index; + int index; - LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: size %d", size)); - if (chan_id == -1) - { - return 1; - } - for (index = 0; index < g_num_chan_items; index++) - { - if (g_chan_items[index].id == chan_id) + LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: size %d", size)); + + if (chan_id == -1) { - add_data_to_chan_item(g_chan_items + index, data, size); - check_chan_items(); - return 0; + return 1; } - } - return 1; + + for (index = 0; index < g_num_chan_items; index++) + { + if (g_chan_items[index].id == chan_id) + { + add_data_to_chan_item(g_chan_items + index, data, size); + check_chan_items(); + return 0; + } + } + + return 1; } /*****************************************************************************/ @@ -202,20 +218,22 @@ send_channel_data(int chan_id, char* data, int size) static int APP_CC send_init_response_message(void) { - struct stream * s = (struct stream *)NULL; + struct stream *s = (struct stream *)NULL; - LOGM((LOG_LEVEL_INFO, "send_init_response_message:")); - s = trans_get_out_s(g_con_trans, 8192); - if (s == 0) - { - return 1; - } - out_uint32_le(s, 0); /* version */ - out_uint32_le(s, 8 + 8); /* size */ - out_uint32_le(s, 2); /* msg id */ - out_uint32_le(s, 8); /* size */ - s_mark_end(s); - return trans_force_write(g_con_trans); + LOGM((LOG_LEVEL_INFO, "send_init_response_message:")); + s = trans_get_out_s(g_con_trans, 8192); + + if (s == 0) + { + return 1; + } + + out_uint32_le(s, 0); /* version */ + out_uint32_le(s, 8 + 8); /* size */ + out_uint32_le(s, 2); /* msg id */ + out_uint32_le(s, 8); /* size */ + s_mark_end(s); + return trans_force_write(g_con_trans); } /*****************************************************************************/ @@ -223,20 +241,22 @@ send_init_response_message(void) static int APP_CC send_channel_setup_response_message(void) { - struct stream * s = (struct stream *)NULL; + struct stream *s = (struct stream *)NULL; - LOGM((LOG_LEVEL_DEBUG, "send_channel_setup_response_message:")); - s = trans_get_out_s(g_con_trans, 8192); - if (s == 0) - { - return 1; - } - out_uint32_le(s, 0); /* version */ - out_uint32_le(s, 8 + 8); /* size */ - out_uint32_le(s, 4); /* msg id */ - out_uint32_le(s, 8); /* size */ - s_mark_end(s); - return trans_force_write(g_con_trans); + LOGM((LOG_LEVEL_DEBUG, "send_channel_setup_response_message:")); + s = trans_get_out_s(g_con_trans, 8192); + + if (s == 0) + { + return 1; + } + + out_uint32_le(s, 0); /* version */ + out_uint32_le(s, 8 + 8); /* size */ + out_uint32_le(s, 4); /* msg id */ + out_uint32_le(s, 8); /* size */ + s_mark_end(s); + return trans_force_write(g_con_trans); } /*****************************************************************************/ @@ -244,176 +264,192 @@ send_channel_setup_response_message(void) static int APP_CC send_channel_data_response_message(void) { - struct stream * s = (struct stream *)NULL; + struct stream *s = (struct stream *)NULL; - LOGM((LOG_LEVEL_DEBUG, "send_channel_data_response_message:")); - s = trans_get_out_s(g_con_trans, 8192); - if (s == 0) - { - return 1; - } - out_uint32_le(s, 0); /* version */ - out_uint32_le(s, 8 + 8); /* size */ - out_uint32_le(s, 6); /* msg id */ - out_uint32_le(s, 8); /* size */ - s_mark_end(s); - return trans_force_write(g_con_trans); + LOGM((LOG_LEVEL_DEBUG, "send_channel_data_response_message:")); + s = trans_get_out_s(g_con_trans, 8192); + + if (s == 0) + { + return 1; + } + + out_uint32_le(s, 0); /* version */ + out_uint32_le(s, 8 + 8); /* size */ + out_uint32_le(s, 6); /* msg id */ + out_uint32_le(s, 8); /* size */ + s_mark_end(s); + return trans_force_write(g_con_trans); } /*****************************************************************************/ /* returns error */ static int APP_CC -process_message_init(struct stream* s) +process_message_init(struct stream *s) { - LOGM((LOG_LEVEL_DEBUG, "process_message_init:")); - return send_init_response_message(); + LOGM((LOG_LEVEL_DEBUG, "process_message_init:")); + return send_init_response_message(); } /*****************************************************************************/ /* returns error */ static int APP_CC -process_message_channel_setup(struct stream* s) +process_message_channel_setup(struct stream *s) { - 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", - num_chans)); - for (index = 0; index < num_chans; index++) - { - ci = &(g_chan_items[g_num_chan_items]); - g_memset(ci->name, 0, sizeof(ci->name)); - in_uint8a(s, ci->name, 8); - in_uint16_le(s, ci->id); - in_uint16_le(s, ci->flags); - LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: chan name '%s' " - "id %d flags %8.8x", ci->name, ci->id, ci->flags)); - if (g_strcasecmp(ci->name, "cliprdr") == 0) + 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", + num_chans)); + + for (index = 0; index < num_chans; index++) { - g_cliprdr_index = g_num_chan_items; - g_cliprdr_chan_id = ci->id; + ci = &(g_chan_items[g_num_chan_items]); + g_memset(ci->name, 0, sizeof(ci->name)); + in_uint8a(s, ci->name, 8); + in_uint16_le(s, ci->id); + in_uint16_le(s, ci->flags); + LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: chan name '%s' " + "id %d flags %8.8x", ci->name, ci->id, ci->flags)); + + if (g_strcasecmp(ci->name, "cliprdr") == 0) + { + g_cliprdr_index = g_num_chan_items; + g_cliprdr_chan_id = ci->id; + } + else if (g_strcasecmp(ci->name, "rdpsnd") == 0) + { + g_rdpsnd_index = g_num_chan_items; + g_rdpsnd_chan_id = ci->id; + } + else if (g_strcasecmp(ci->name, "rdpdr") == 0) + { + 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; + } + else + { + LOG(10, ("other %s", ci->name)); + } + + g_num_chan_items++; } - else if (g_strcasecmp(ci->name, "rdpsnd") == 0) + + rv = send_channel_setup_response_message(); + + if (g_cliprdr_index >= 0) { - g_rdpsnd_index = g_num_chan_items; - g_rdpsnd_chan_id = ci->id; + clipboard_init(); } - else if (g_strcasecmp(ci->name, "rdpdr") == 0) + + if (g_rdpsnd_index >= 0) { - g_rdpdr_index = g_num_chan_items; - g_rdpdr_chan_id = ci->id; + sound_init(); } - else if (g_strcasecmp(ci->name, "rail") == 0) + + if (g_rdpdr_index >= 0) { - g_rail_index = g_num_chan_items; - g_rail_chan_id = ci->id; + dev_redir_init(); } - else + + if (g_rail_index >= 0) { - LOG(10, ("other %s", ci->name)); + rail_init(); } - g_num_chan_items++; - } - rv = send_channel_setup_response_message(); - if (g_cliprdr_index >= 0) - { - clipboard_init(); - } - if (g_rdpsnd_index >= 0) - { - sound_init(); - } - if (g_rdpdr_index >= 0) - { - dev_redir_init(); - } - if (g_rail_index >= 0) - { - rail_init(); - } - return rv; + + return rv; } /*****************************************************************************/ /* returns error */ static int APP_CC -process_message_channel_data(struct stream* s) +process_message_channel_data(struct stream *s) { - int chan_id = 0; - int chan_flags = 0; - int rv = 0; - int length = 0; - int total_length = 0; - struct stream* ls; - - in_uint16_le(s, chan_id); - in_uint16_le(s, chan_flags); - in_uint16_le(s, length); - in_uint32_le(s, total_length); - LOGM((LOG_LEVEL_DEBUG,"process_message_channel_data: chan_id %d " - "chan_flags %d", chan_id, chan_flags)); - LOG(10, ("process_message_channel_data")); - rv = send_channel_data_response_message(); - if (rv == 0) - { - if (chan_id == g_cliprdr_chan_id) - { - rv = clipboard_data_in(s, chan_id, chan_flags, length, total_length); - } - else if (chan_id == g_rdpsnd_chan_id) - { - rv = sound_data_in(s, chan_id, chan_flags, length, total_length); - } - else if (chan_id == g_rdpdr_chan_id) - { - 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); - } - else if (chan_id == ((struct xrdp_api_data*) - (g_api_con_trans->callback_data))->chan_id) + int chan_id = 0; + int chan_flags = 0; + int rv = 0; + int length = 0; + int total_length = 0; + struct stream *ls; + + in_uint16_le(s, chan_id); + in_uint16_le(s, chan_flags); + in_uint16_le(s, length); + in_uint32_le(s, total_length); + LOGM((LOG_LEVEL_DEBUG, "process_message_channel_data: chan_id %d " + "chan_flags %d", chan_id, chan_flags)); + LOG(10, ("process_message_channel_data")); + rv = send_channel_data_response_message(); + + if (rv == 0) { - LOG(10, ("process_message_channel_data length %d total_length %d " - "chan_flags 0x%8.8x", length, total_length, chan_flags)); - ls = g_api_con_trans->out_s; - if (chan_flags & 1) /* first */ - { - init_stream(ls, total_length); - } - out_uint8a(ls, s->p, length); - if (chan_flags & 2) /* last */ - { - s_mark_end(ls); - trans_force_write(g_api_con_trans); - } + if (chan_id == g_cliprdr_chan_id) + { + rv = clipboard_data_in(s, chan_id, chan_flags, length, total_length); + } + else if (chan_id == g_rdpsnd_chan_id) + { + rv = sound_data_in(s, chan_id, chan_flags, length, total_length); + } + else if (chan_id == g_rdpdr_chan_id) + { + 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); + } + else if (chan_id == ((struct xrdp_api_data *) + (g_api_con_trans->callback_data))->chan_id) + { + LOG(10, ("process_message_channel_data length %d total_length %d " + "chan_flags 0x%8.8x", length, total_length, chan_flags)); + ls = g_api_con_trans->out_s; + + if (chan_flags & 1) /* first */ + { + init_stream(ls, total_length); + } + + out_uint8a(ls, s->p, length); + + if (chan_flags & 2) /* last */ + { + s_mark_end(ls); + trans_force_write(g_api_con_trans); + } + } } - } - return rv; + + return rv; } /*****************************************************************************/ /* returns error */ static int APP_CC -process_message_channel_data_response(struct stream* s) +process_message_channel_data_response(struct stream *s) { - LOG(10, ("process_message_channel_data_response:")); - check_chan_items(); - return 0; + LOG(10, ("process_message_channel_data_response:")); + check_chan_items(); + return 0; } /*****************************************************************************/ @@ -421,680 +457,752 @@ process_message_channel_data_response(struct stream* s) static int APP_CC process_message(void) { - struct stream * s = (struct stream *)NULL; - int size = 0; - int id = 0; - int rv = 0; - char* next_msg = (char *)NULL; - - if (g_con_trans == 0) - { - return 1; - } - s = trans_get_in_s(g_con_trans); - if (s == 0) - { - return 1; - } - rv = 0; - while (s_check_rem(s, 8)) - { - next_msg = s->p; - in_uint32_le(s, id); - in_uint32_le(s, size); - next_msg += size; - switch (id) + struct stream *s = (struct stream *)NULL; + int size = 0; + int id = 0; + int rv = 0; + char *next_msg = (char *)NULL; + + if (g_con_trans == 0) { - case 1: /* init */ - rv = process_message_init(s); - break; - case 3: /* channel setup */ - rv = process_message_channel_setup(s); - break; - case 5: /* channel data */ - rv = process_message_channel_data(s); - break; - case 7: /* channel data response */ - rv = process_message_channel_data_response(s); - break; - default: - LOGM((LOG_LEVEL_ERROR, "process_message: error in process_message ", - "unknown msg %d", id)); - break; + return 1; } - if (rv != 0) + + s = trans_get_in_s(g_con_trans); + + if (s == 0) { - break; + return 1; + } + + rv = 0; + + while (s_check_rem(s, 8)) + { + next_msg = s->p; + in_uint32_le(s, id); + in_uint32_le(s, size); + next_msg += size; + + switch (id) + { + case 1: /* init */ + rv = process_message_init(s); + break; + case 3: /* channel setup */ + rv = process_message_channel_setup(s); + break; + case 5: /* channel data */ + rv = process_message_channel_data(s); + break; + case 7: /* channel data response */ + rv = process_message_channel_data_response(s); + break; + default: + LOGM((LOG_LEVEL_ERROR, "process_message: error in process_message ", + "unknown msg %d", id)); + break; + } + + if (rv != 0) + { + break; + } + + s->p = next_msg; } - s->p = next_msg; - } - return rv; + + return rv; } /*****************************************************************************/ /* returns error */ int DEFAULT_CC -my_trans_data_in(struct trans* trans) +my_trans_data_in(struct trans *trans) { - struct stream * s = (struct stream *)NULL; - int id = 0; - int size = 0; - int error = 0; + struct stream *s = (struct stream *)NULL; + int id = 0; + int size = 0; + int error = 0; - if (trans == 0) - { - return 0; - } - if (trans != g_con_trans) - { - return 1; - } - LOGM((LOG_LEVEL_DEBUG, "my_trans_data_in:")); - s = trans_get_in_s(trans); - in_uint32_le(s, id); - in_uint32_le(s, size); - error = trans_force_read(trans, size - 8); - if (error == 0) - { - /* here, the entire message block is read in, process it */ - error = process_message(); - } - return error; + if (trans == 0) + { + return 0; + } + + if (trans != g_con_trans) + { + return 1; + } + + LOGM((LOG_LEVEL_DEBUG, "my_trans_data_in:")); + s = trans_get_in_s(trans); + in_uint32_le(s, id); + in_uint32_le(s, size); + error = trans_force_read(trans, size - 8); + + if (error == 0) + { + /* here, the entire message block is read in, process it */ + error = process_message(); + } + + return error; } /*****************************************************************************/ /* returns error */ int DEFAULT_CC -my_api_trans_data_in(struct trans* trans) +my_api_trans_data_in(struct trans *trans) { - struct stream* s; - int error; - struct xrdp_api_data* ad; + struct stream *s; + int error; + struct xrdp_api_data *ad; - LOG(10, ("my_api_trans_data_in:")); - if (trans == 0) - { - return 0; - } - if (trans != g_api_con_trans) - { - return 1; - } - LOGM((LOG_LEVEL_DEBUG, "my_api_trans_data_in:")); - s = trans_get_in_s(trans); - error = g_tcp_recv(trans->sck, s->data, 8192, 0); - if (error > 0) - { - LOG(10, ("my_api_trans_data_in: got data %d", error)); - ad = (struct xrdp_api_data*)(trans->callback_data); - if (send_channel_data(ad->chan_id, s->data, error) != 0) + LOG(10, ("my_api_trans_data_in:")); + + if (trans == 0) { - LOG(0, ("my_api_trans_data_in: send_channel_data failed")); + return 0; } - } - else - { - LOG(10, ("my_api_trans_data_in: g_tcp_recv failed, or disconnected")); - return 1; - } - return 0; + + if (trans != g_api_con_trans) + { + return 1; + } + + LOGM((LOG_LEVEL_DEBUG, "my_api_trans_data_in:")); + s = trans_get_in_s(trans); + error = g_tcp_recv(trans->sck, s->data, 8192, 0); + + if (error > 0) + { + LOG(10, ("my_api_trans_data_in: got data %d", error)); + ad = (struct xrdp_api_data *)(trans->callback_data); + + if (send_channel_data(ad->chan_id, s->data, error) != 0) + { + LOG(0, ("my_api_trans_data_in: send_channel_data failed")); + } + } + else + { + LOG(10, ("my_api_trans_data_in: g_tcp_recv failed, or disconnected")); + return 1; + } + + return 0; } /*****************************************************************************/ int DEFAULT_CC -my_trans_conn_in(struct trans* trans, struct trans* new_trans) +my_trans_conn_in(struct trans *trans, struct trans *new_trans) { - if (trans == 0) - { - return 1; - } - if (trans != g_lis_trans) - { - return 1; - } - if (g_con_trans != 0) /* if already set, error */ - { - return 1; - } - if (new_trans == 0) - { - return 1; - } - LOGM((LOG_LEVEL_DEBUG, "my_trans_conn_in:")); - g_con_trans = new_trans; - g_con_trans->trans_data_in = my_trans_data_in; - g_con_trans->header_size = 8; - /* stop listening */ - trans_delete(g_lis_trans); - g_lis_trans = 0; - return 0; + if (trans == 0) + { + return 1; + } + + if (trans != g_lis_trans) + { + return 1; + } + + if (g_con_trans != 0) /* if already set, error */ + { + return 1; + } + + if (new_trans == 0) + { + return 1; + } + + LOGM((LOG_LEVEL_DEBUG, "my_trans_conn_in:")); + g_con_trans = new_trans; + g_con_trans->trans_data_in = my_trans_data_in; + g_con_trans->header_size = 8; + /* stop listening */ + trans_delete(g_lis_trans); + g_lis_trans = 0; + return 0; } /*****************************************************************************/ int DEFAULT_CC -my_api_trans_conn_in(struct trans* trans, struct trans* new_trans) +my_api_trans_conn_in(struct trans *trans, struct trans *new_trans) { - struct xrdp_api_data* ad; - int error; - int index; - int found; - struct stream* s; - - if (trans == 0) - { - return 1; - } - if (trans != g_api_lis_trans) - { - return 1; - } - if (new_trans == 0) - { - return 1; - } - LOGM((LOG_LEVEL_DEBUG, "my_api_trans_conn_in:")); + struct xrdp_api_data *ad; + int error; + int index; + int found; + struct stream *s; - LOG(10, ("my_api_trans_conn_in: got incoming")); + if (trans == 0) + { + return 1; + } - s = trans_get_in_s(new_trans); - s->end = s->data; - error = trans_force_read(new_trans, 64); - if (error != 0) - { - LOG(0, ("my_api_trans_conn_in: trans_force_read failed")); - trans_delete(new_trans); - } - s->end = s->data; + if (trans != g_api_lis_trans) + { + return 1; + } + + if (new_trans == 0) + { + return 1; + } - ad = (struct xrdp_api_data*)g_malloc(sizeof(struct xrdp_api_data), 1); + LOGM((LOG_LEVEL_DEBUG, "my_api_trans_conn_in:")); + + LOG(10, ("my_api_trans_conn_in: got incoming")); + + s = trans_get_in_s(new_trans); + s->end = s->data; + error = trans_force_read(new_trans, 64); + + if (error != 0) + { + LOG(0, ("my_api_trans_conn_in: trans_force_read failed")); + trans_delete(new_trans); + } - g_memcpy(ad->header, s->data, 64); + s->end = s->data; - ad->flags = GGET_UINT32(ad->header, 16); + ad = (struct xrdp_api_data *)g_malloc(sizeof(struct xrdp_api_data), 1); + + g_memcpy(ad->header, s->data, 64); + + ad->flags = GGET_UINT32(ad->header, 16); - found = 0; - if (ad->flags | 1) /* WTS_CHANNEL_OPTION_DYNAMIC */ - { - /* TODO */ found = 0; - } - else - { - for (index = 0; index < g_num_chan_items; index++) + + if (ad->flags | 1) /* WTS_CHANNEL_OPTION_DYNAMIC */ + { + /* TODO */ + found = 0; + } + else + { + for (index = 0; index < g_num_chan_items; index++) + { + LOG(10, (" %s %s", ad->header, g_chan_items[index].name)); + + if (g_strcasecmp(ad->header, g_chan_items[index].name) == 0) + { + LOG(10, ("my_api_trans_conn_in: found it at %d", index)); + ad->chan_id = g_chan_items[index].id; + found = 1; + break; + } + } + } + + LOG(10, ("my_api_trans_conn_in: found %d", found)); + + if (!found) { - LOG(10, (" %s %s", ad->header, g_chan_items[index].name)); - if (g_strcasecmp(ad->header, g_chan_items[index].name) == 0) - { - LOG(10, ("my_api_trans_conn_in: found it at %d", index)); - ad->chan_id = g_chan_items[index].id; - found = 1; - break; - } + ad->chan_id = -1; } - } - LOG(10, ("my_api_trans_conn_in: found %d", found)); - if (!found) - { - ad->chan_id = -1; - } - new_trans->callback_data = ad; + new_trans->callback_data = ad; - trans_delete(g_api_con_trans); - g_api_con_trans = new_trans; - g_api_con_trans->trans_data_in = my_api_trans_data_in; - g_api_con_trans->header_size = 0; + trans_delete(g_api_con_trans); + g_api_con_trans = new_trans; + g_api_con_trans->trans_data_in = my_api_trans_data_in; + g_api_con_trans->header_size = 0; - return 0; + return 0; } /*****************************************************************************/ static int APP_CC setup_listen(void) { - char port[256]; - int error = 0; + char port[256]; + int error = 0; - if (g_lis_trans != 0) - { - trans_delete(g_lis_trans); - } - if (g_use_unix_socket) - { - g_lis_trans = trans_create(2, 8192, 8192); - g_snprintf(port, 255, "/tmp/.xrdp/xrdp_chansrv_socket_%d", - 7200 + g_display_num); - } - else - { - g_lis_trans = trans_create(1, 8192, 8192); - g_snprintf(port, 255, "%d", 7200 + g_display_num); - } - g_lis_trans->trans_conn_in = my_trans_conn_in; - error = trans_listen(g_lis_trans, port); - if (error != 0) - { - LOGM((LOG_LEVEL_ERROR, "setup_listen: trans_listen failed for port %s", - port)); - return 1; - } - return 0; + if (g_lis_trans != 0) + { + trans_delete(g_lis_trans); + } + + if (g_use_unix_socket) + { + g_lis_trans = trans_create(2, 8192, 8192); + g_snprintf(port, 255, "/tmp/.xrdp/xrdp_chansrv_socket_%d", + 7200 + g_display_num); + } + else + { + g_lis_trans = trans_create(1, 8192, 8192); + g_snprintf(port, 255, "%d", 7200 + g_display_num); + } + + g_lis_trans->trans_conn_in = my_trans_conn_in; + error = trans_listen(g_lis_trans, port); + + if (error != 0) + { + LOGM((LOG_LEVEL_ERROR, "setup_listen: trans_listen failed for port %s", + port)); + return 1; + } + + return 0; } /*****************************************************************************/ static int APP_CC setup_api_listen(void) { - char port[256]; - int error = 0; - - g_api_lis_trans = trans_create(2, 8192, 8192); - g_snprintf(port, 255, "/tmp/.xrdp/xrdpapi_%d", g_display_num); - g_api_lis_trans->trans_conn_in = my_api_trans_conn_in; - error = trans_listen(g_api_lis_trans, port); - if (error != 0) - { - LOGM((LOG_LEVEL_ERROR, "setup_api_listen: trans_listen failed for port %s", - port)); - return 1; - } - return 0; + char port[256]; + int error = 0; + + g_api_lis_trans = trans_create(2, 8192, 8192); + g_snprintf(port, 255, "/tmp/.xrdp/xrdpapi_%d", g_display_num); + g_api_lis_trans->trans_conn_in = my_api_trans_conn_in; + error = trans_listen(g_api_lis_trans, port); + + if (error != 0) + { + LOGM((LOG_LEVEL_ERROR, "setup_api_listen: trans_listen failed for port %s", + port)); + return 1; + } + + return 0; } /*****************************************************************************/ THREAD_RV THREAD_CC -channel_thread_loop(void* in_val) +channel_thread_loop(void *in_val) { - tbus objs[32]; - int num_objs; - int timeout; - int error; - THREAD_RV rv; - - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start")); - rv = 0; - setup_api_listen(); - error = setup_listen(); - if (error == 0) - { - timeout = -1; - num_objs = 0; - objs[num_objs] = g_term_event; - num_objs++; - trans_get_wait_objs(g_lis_trans, objs, &num_objs); - trans_get_wait_objs(g_api_lis_trans, objs, &num_objs); - while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) + tbus objs[32]; + int num_objs; + int timeout; + int error; + THREAD_RV rv; + + LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start")); + rv = 0; + setup_api_listen(); + error = setup_listen(); + + if (error == 0) { - if (g_is_wait_obj_set(g_term_event)) - { - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: g_term_event set")); - clipboard_deinit(); - sound_deinit(); - dev_redir_deinit(); - rail_deinit(); - break; - } - if (g_lis_trans != 0) - { - if (trans_check_wait_objs(g_lis_trans) != 0) + timeout = -1; + num_objs = 0; + objs[num_objs] = g_term_event; + num_objs++; + trans_get_wait_objs(g_lis_trans, objs, &num_objs); + trans_get_wait_objs(g_api_lis_trans, objs, &num_objs); + + while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) { - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: " - "trans_check_wait_objs error")); + if (g_is_wait_obj_set(g_term_event)) + { + LOGM((LOG_LEVEL_INFO, "channel_thread_loop: g_term_event set")); + clipboard_deinit(); + sound_deinit(); + dev_redir_deinit(); + rail_deinit(); + break; + } + + if (g_lis_trans != 0) + { + if (trans_check_wait_objs(g_lis_trans) != 0) + { + LOGM((LOG_LEVEL_INFO, "channel_thread_loop: " + "trans_check_wait_objs error")); + } + } + + if (g_con_trans != 0) + { + if (trans_check_wait_objs(g_con_trans) != 0) + { + LOGM((LOG_LEVEL_INFO, "channel_thread_loop: " + "trans_check_wait_objs error resetting")); + clipboard_deinit(); + sound_deinit(); + dev_redir_deinit(); + rail_deinit(); + /* delete g_con_trans */ + trans_delete(g_con_trans); + g_con_trans = 0; + /* create new listener */ + error = setup_listen(); + + if (error != 0) + { + break; + } + } + } + + if (g_api_lis_trans != 0) + { + if (trans_check_wait_objs(g_api_lis_trans) != 0) + { + LOG(0, ("channel_thread_loop: trans_check_wait_objs failed")); + } + } + + LOG(10, ("0 %p", g_api_con_trans)); + + if (g_api_con_trans != 0) + { + LOG(10, ("1 %p %d", g_api_con_trans, g_tcp_can_recv(g_api_con_trans->sck, 0))); + + if (trans_check_wait_objs(g_api_con_trans) != 0) + { + LOG(10, ("channel_thread_loop: trans_check_wait_objs failed, " + "or disconnected")); + g_free(g_api_con_trans->callback_data); + trans_delete(g_api_con_trans); + g_api_con_trans = 0; + } + } + + xcommon_check_wait_objs(); + sound_check_wait_objs(); + dev_redir_check_wait_objs(); + timeout = -1; + num_objs = 0; + objs[num_objs] = g_term_event; + num_objs++; + trans_get_wait_objs(g_lis_trans, objs, &num_objs); + trans_get_wait_objs(g_con_trans, objs, &num_objs); + trans_get_wait_objs(g_api_lis_trans, objs, &num_objs); + trans_get_wait_objs(g_api_con_trans, objs, &num_objs); + 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); } - } - if (g_con_trans != 0) - { - if (trans_check_wait_objs(g_con_trans) != 0) - { - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: " - "trans_check_wait_objs error resetting")); - clipboard_deinit(); - sound_deinit(); - dev_redir_deinit(); - rail_deinit(); - /* delete g_con_trans */ - trans_delete(g_con_trans); - g_con_trans = 0; - /* create new listener */ - error = setup_listen(); - if (error != 0) - { - break; - } - } - } - if (g_api_lis_trans != 0) - { - if (trans_check_wait_objs(g_api_lis_trans) != 0) - { - LOG(0, ("channel_thread_loop: trans_check_wait_objs failed")); - } - } - - LOG(10, ("0 %p", g_api_con_trans)); - if (g_api_con_trans != 0) - { - LOG(10, ("1 %p %d", g_api_con_trans, g_tcp_can_recv(g_api_con_trans->sck, 0))); - if (trans_check_wait_objs(g_api_con_trans) != 0) - { - LOG(10, ("channel_thread_loop: trans_check_wait_objs failed, " - "or disconnected")); - g_free(g_api_con_trans->callback_data); - trans_delete(g_api_con_trans); - g_api_con_trans = 0; - } - } - - xcommon_check_wait_objs(); - sound_check_wait_objs(); - dev_redir_check_wait_objs(); - timeout = -1; - num_objs = 0; - objs[num_objs] = g_term_event; - num_objs++; - trans_get_wait_objs(g_lis_trans, objs, &num_objs); - trans_get_wait_objs(g_con_trans, objs, &num_objs); - trans_get_wait_objs(g_api_lis_trans, objs, &num_objs); - trans_get_wait_objs(g_api_con_trans, objs, &num_objs); - 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); } - } - trans_delete(g_lis_trans); - g_lis_trans = 0; - trans_delete(g_con_trans); - g_con_trans = 0; - trans_delete(g_api_lis_trans); - g_api_lis_trans = 0; - trans_delete(g_api_con_trans); - g_api_con_trans = 0; - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread stop")); - g_set_wait_obj(g_thread_done_event); - return rv; + + trans_delete(g_lis_trans); + g_lis_trans = 0; + trans_delete(g_con_trans); + g_con_trans = 0; + trans_delete(g_api_lis_trans); + g_api_lis_trans = 0; + trans_delete(g_api_con_trans); + g_api_con_trans = 0; + LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread stop")); + g_set_wait_obj(g_thread_done_event); + return rv; } /*****************************************************************************/ void DEFAULT_CC term_signal_handler(int sig) { - LOGM((LOG_LEVEL_INFO, "term_signal_handler: got signal %d", sig)); - g_set_wait_obj(g_term_event); + LOGM((LOG_LEVEL_INFO, "term_signal_handler: got signal %d", sig)); + g_set_wait_obj(g_term_event); } /*****************************************************************************/ void DEFAULT_CC nil_signal_handler(int sig) { - LOGM((LOG_LEVEL_INFO, "nil_signal_handler: got signal %d", sig)); + LOGM((LOG_LEVEL_INFO, "nil_signal_handler: got signal %d", sig)); } /*****************************************************************************/ void DEFAULT_CC child_signal_handler(int sig) { - int i1; + int i1; - LOG(10, ("child_signal_handler:")); - do - { - i1 = g_waitchild(); - if (i1 == g_exec_pid) + LOG(10, ("child_signal_handler:")); + + do { - LOG(0, ("child_signal_handler: found pid %d", i1)); - //shutdownx(); + i1 = g_waitchild(); + + if (i1 == g_exec_pid) + { + LOG(0, ("child_signal_handler: found pid %d", i1)); + //shutdownx(); + } + + LOG(10, (" %d", i1)); } - LOG(10, (" %d", i1)); - } while (i1 >= 0); + while (i1 >= 0); } /*****************************************************************************/ static int APP_CC -get_display_num_from_display(char* display_text) +get_display_num_from_display(char *display_text) { - int index; - int mode; - int host_index; - int disp_index; - int scre_index; - char host[256]; - char disp[256]; - char scre[256]; - - g_memset(host, 0, 256); - g_memset(disp, 0, 256); - g_memset(scre, 0, 256); - - index = 0; - host_index = 0; - disp_index = 0; - scre_index = 0; - mode = 0; - while (display_text[index] != 0) - { - if (display_text[index] == ':') - { - mode = 1; - } - else if (display_text[index] == '.') - { - mode = 2; - } - else if (mode == 0) - { - host[host_index] = display_text[index]; - host_index++; - } - else if (mode == 1) - { - disp[disp_index] = display_text[index]; - disp_index++; - } - else if (mode == 2) + int index; + int mode; + int host_index; + int disp_index; + int scre_index; + char host[256]; + char disp[256]; + char scre[256]; + + g_memset(host, 0, 256); + g_memset(disp, 0, 256); + g_memset(scre, 0, 256); + + index = 0; + host_index = 0; + disp_index = 0; + scre_index = 0; + mode = 0; + + while (display_text[index] != 0) { - scre[scre_index] = display_text[index]; - scre_index++; + if (display_text[index] == ':') + { + mode = 1; + } + else if (display_text[index] == '.') + { + mode = 2; + } + else if (mode == 0) + { + host[host_index] = display_text[index]; + host_index++; + } + else if (mode == 1) + { + disp[disp_index] = display_text[index]; + disp_index++; + } + else if (mode == 2) + { + scre[scre_index] = display_text[index]; + scre_index++; + } + + index++; } - index++; - } - host[host_index] = 0; - disp[disp_index] = 0; - scre[scre_index] = 0; - g_display_num = g_atoi(disp); - return 0; + + host[host_index] = 0; + disp[disp_index] = 0; + scre[scre_index] = 0; + g_display_num = g_atoi(disp); + return 0; } /*****************************************************************************/ int APP_CC main_cleanup(void) { - g_delete_wait_obj(g_term_event); - g_delete_wait_obj(g_thread_done_event); - g_delete_wait_obj(g_exec_event); - tc_mutex_delete(g_exec_mutex); - g_deinit(); /* os_calls */ - return 0; + g_delete_wait_obj(g_term_event); + g_delete_wait_obj(g_thread_done_event); + g_delete_wait_obj(g_exec_event); + tc_mutex_delete(g_exec_mutex); + g_deinit(); /* os_calls */ + return 0; } /*****************************************************************************/ static int APP_CC read_ini(void) { - 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(); - values->auto_free = 1; - g_use_unix_socket = 0; - g_snprintf(filename, 255, "%s/sesman.ini", XRDP_CFG_PATH); - if (file_by_name_read_section(filename, "Globals", names, values) == 0) - { - for (index = 0; index < names->count; index++) + 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(); + values->auto_free = 1; + g_use_unix_socket = 0; + g_snprintf(filename, 255, "%s/sesman.ini", XRDP_CFG_PATH); + + if (file_by_name_read_section(filename, "Globals", names, values) == 0) { - name = (char*)list_get_item(names, index); - value = (char*)list_get_item(values, index); - if (g_strcasecmp(name, "ListenAddress") == 0) - { - if (g_strcasecmp(value, "127.0.0.1") == 0) + for (index = 0; index < names->count; index++) { - g_use_unix_socket = 1; + name = (char *)list_get_item(names, index); + value = (char *)list_get_item(values, index); + + if (g_strcasecmp(name, "ListenAddress") == 0) + { + if (g_strcasecmp(value, "127.0.0.1") == 0) + { + g_use_unix_socket = 1; + } + } } - } } - } - list_delete(names); - list_delete(values); - return 0; + + list_delete(names); + list_delete(values); + return 0; } /*****************************************************************************/ static int APP_CC run_exec(void) { - int pid; + int pid; - LOG(10, ("run_exec:")); - pid = g_fork(); - if (pid == 0) - { - trans_delete(g_con_trans); - g_close_wait_obj(g_term_event); - g_close_wait_obj(g_thread_done_event); - g_close_wait_obj(g_exec_event); - tc_mutex_delete(g_exec_mutex); - tc_sem_delete(g_exec_sem); - g_execlp3(g_exec_name, g_exec_name, 0); - g_exit(0); - } - g_exec_pid = pid; - tc_sem_inc(g_exec_sem); - - return 0; + LOG(10, ("run_exec:")); + pid = g_fork(); + + if (pid == 0) + { + trans_delete(g_con_trans); + g_close_wait_obj(g_term_event); + g_close_wait_obj(g_thread_done_event); + g_close_wait_obj(g_exec_event); + tc_mutex_delete(g_exec_mutex); + tc_sem_delete(g_exec_sem); + g_execlp3(g_exec_name, g_exec_name, 0); + g_exit(0); + } + + g_exec_pid = pid; + tc_sem_inc(g_exec_sem); + + return 0; } /*****************************************************************************/ int DEFAULT_CC -main(int argc, char** argv) +main(int argc, char **argv) { - tbus waiters[4]; - int pid = 0; - char text[256]; - char* home_text; - char* display_text; - char log_file[256]; - enum logReturns error; - struct log_config logconfig; - - g_init("xrdp-chansrv"); /* os_calls */ - - home_text = g_getenv("HOME"); - if (home_text == 0) - { - g_writeln("error reading HOME environment variable"); - g_deinit(); - return 1; - } - - read_ini(); - pid = g_getpid(); - - /* starting logging subsystem */ - g_memset(&logconfig, 0, sizeof(struct log_config)); - logconfig.program_name = "XRDP-Chansrv"; - g_snprintf(log_file, 255, "%s/xrdp-chansrv.log", home_text); - g_writeln("chansrv::main: using log file [%s]", log_file); - if (g_file_exist(log_file)) - { - g_file_delete(log_file); - } - logconfig.log_file = log_file; - logconfig.fd = -1; - logconfig.log_level = LOG_LEVEL_ERROR; - logconfig.enable_syslog = 0; - logconfig.syslog_level = 0; - error = log_start_from_param(&logconfig); - if (error != LOG_STARTUP_OK) - { - switch (error) + tbus waiters[4]; + int pid = 0; + char text[256]; + char *home_text; + char *display_text; + char log_file[256]; + enum logReturns error; + struct log_config logconfig; + + g_init("xrdp-chansrv"); /* os_calls */ + + home_text = g_getenv("HOME"); + + if (home_text == 0) { - 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_writeln("error reading HOME environment variable"); + g_deinit(); + return 1; } - g_deinit(); - return 1; - } - LOGM((LOG_LEVEL_ALWAYS, "main: app started pid %d(0x%8.8x)", pid, pid)); - /* set up signal handler */ - g_signal_kill(term_signal_handler); /* SIGKILL */ - g_signal_terminate(term_signal_handler); /* SIGTERM */ - g_signal_user_interrupt(term_signal_handler); /* SIGINT */ - g_signal_pipe(nil_signal_handler); /* SIGPIPE */ - g_signal_child_stop(child_signal_handler); /* SIGCHLD */ - display_text = g_getenv("DISPLAY"); - LOGM((LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text)); - get_display_num_from_display(display_text); - if (g_display_num == 0) - { - LOGM((LOG_LEVEL_ERROR, "main: error, display is zero")); - g_deinit(); - return 1; - } - LOGM((LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num)); - g_snprintf(text, 255, "xrdp_chansrv_%8.8x_main_term", pid); - g_term_event = g_create_wait_obj(text); - g_snprintf(text, 255, "xrdp_chansrv_%8.8x_thread_done", pid); - g_thread_done_event = g_create_wait_obj(text); - g_snprintf(text, 255, "xrdp_chansrv_%8.8x_exec", pid); - g_exec_event = g_create_wait_obj(text); - g_exec_mutex = tc_mutex_create(); - g_exec_sem = tc_sem_create(0); - tc_thread_create(channel_thread_loop, 0); - while (g_term_event > 0 && !g_is_wait_obj_set(g_term_event)) - { - waiters[0] = g_term_event; - waiters[1] = g_exec_event; - if (g_obj_wait(waiters, 2, 0, 0, 0) != 0) + + read_ini(); + pid = g_getpid(); + + /* starting logging subsystem */ + g_memset(&logconfig, 0, sizeof(struct log_config)); + logconfig.program_name = "XRDP-Chansrv"; + g_snprintf(log_file, 255, "%s/xrdp-chansrv.log", home_text); + g_writeln("chansrv::main: using log file [%s]", log_file); + + if (g_file_exist(log_file)) { - LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); - break; + g_file_delete(log_file); } - if (g_is_wait_obj_set(g_term_event)) + + logconfig.log_file = log_file; + logconfig.fd = -1; + logconfig.log_level = LOG_LEVEL_ERROR; + logconfig.enable_syslog = 0; + logconfig.syslog_level = 0; + error = log_start_from_param(&logconfig); + + 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; + } + + g_deinit(); + return 1; + } + + LOGM((LOG_LEVEL_ALWAYS, "main: app started pid %d(0x%8.8x)", pid, pid)); + /* set up signal handler */ + g_signal_kill(term_signal_handler); /* SIGKILL */ + g_signal_terminate(term_signal_handler); /* SIGTERM */ + g_signal_user_interrupt(term_signal_handler); /* SIGINT */ + g_signal_pipe(nil_signal_handler); /* SIGPIPE */ + g_signal_child_stop(child_signal_handler); /* SIGCHLD */ + display_text = g_getenv("DISPLAY"); + LOGM((LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text)); + get_display_num_from_display(display_text); + + if (g_display_num == 0) { - break; + LOGM((LOG_LEVEL_ERROR, "main: error, display is zero")); + g_deinit(); + return 1; } - if (g_is_wait_obj_set(g_exec_event)) + + LOGM((LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num)); + g_snprintf(text, 255, "xrdp_chansrv_%8.8x_main_term", pid); + g_term_event = g_create_wait_obj(text); + g_snprintf(text, 255, "xrdp_chansrv_%8.8x_thread_done", pid); + g_thread_done_event = g_create_wait_obj(text); + g_snprintf(text, 255, "xrdp_chansrv_%8.8x_exec", pid); + g_exec_event = g_create_wait_obj(text); + g_exec_mutex = tc_mutex_create(); + g_exec_sem = tc_sem_create(0); + tc_thread_create(channel_thread_loop, 0); + + while (g_term_event > 0 && !g_is_wait_obj_set(g_term_event)) { - g_reset_wait_obj(g_exec_event); - run_exec(); + waiters[0] = g_term_event; + waiters[1] = g_exec_event; + + if (g_obj_wait(waiters, 2, 0, 0, 0) != 0) + { + LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); + break; + } + + if (g_is_wait_obj_set(g_term_event)) + { + break; + } + + if (g_is_wait_obj_set(g_exec_event)) + { + g_reset_wait_obj(g_exec_event); + run_exec(); + } } - } - while (g_thread_done_event > 0 && !g_is_wait_obj_set(g_thread_done_event)) - { - /* wait for thread to exit */ - if (g_obj_wait(&g_thread_done_event, 1, 0, 0, 0) != 0) + + while (g_thread_done_event > 0 && !g_is_wait_obj_set(g_thread_done_event)) { - LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); - break; + /* wait for thread to exit */ + if (g_obj_wait(&g_thread_done_event, 1, 0, 0, 0) != 0) + { + LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); + break; + } } - } - /* cleanup */ - main_cleanup(); - LOGM((LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid)); - g_deinit(); - return 0; + + /* cleanup */ + main_cleanup(); + LOGM((LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid)); + g_deinit(); + return 0; } diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c index 3bea9704..1541170d 100644 --- a/sesman/chansrv/clipboard.c +++ b/sesman/chansrv/clipboard.c @@ -48,10 +48,10 @@ static char g_bmp_image_header[] = extern int g_cliprdr_chan_id; /* in chansrv.c */ -extern Display* g_display; /* in xcommon.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 Screen *g_screen; /* in xcommon.c */ extern int g_screen_num; /* in xcommon.c */ int g_clip_up = 0; @@ -73,18 +73,18 @@ static Window g_wnd = 0; static int g_xfixes_event_base = 0; static int g_last_clip_size = 0; -static char* g_last_clip_data = 0; +static char *g_last_clip_data = 0; static Atom g_last_clip_type = 0; static int g_got_selection = 0; /* boolean */ static Time g_selection_time = 0; -static struct stream* g_ins = 0; +static struct stream *g_ins = 0; static XSelectionRequestEvent g_selection_request_event[16]; static int g_selection_request_event_count = 0; -static char* g_data_in = 0; +static char *g_data_in = 0; static int g_data_in_size = 0; static int g_data_in_time = 0; static int g_data_in_up_to_date = 0; @@ -98,7 +98,7 @@ static XSelectionRequestEvent g_saved_selection_req_event; static Atom g_incr_atom; static Atom g_incr_atom_type; static Atom g_incr_atom_target; -static char* g_incr_data = 0; +static char *g_incr_data = 0; static int g_incr_data_size = 0; static int g_incr_in_progress = 0; @@ -109,19 +109,22 @@ static int clipboard_format_id = CB_FORMAT_UNICODETEXT; static Time APP_CC clipboard_get_server_time(void) { - XEvent xevent; - unsigned char no_text[4]; - - /* append nothing */ - no_text[0] = 0; - XChangeProperty(g_display, g_wnd, g_get_time_atom, XA_STRING, 8, - PropModeAppend, no_text, 0); - /* wait for PropertyNotify */ - do - { - XMaskEvent(g_display, PropertyChangeMask, &xevent); - } while (xevent.type != PropertyNotify); - return xevent.xproperty.time; + XEvent xevent; + unsigned char no_text[4]; + + /* append nothing */ + no_text[0] = 0; + XChangeProperty(g_display, g_wnd, g_get_time_atom, XA_STRING, 8, + PropModeAppend, no_text, 0); + + /* wait for PropertyNotify */ + do + { + XMaskEvent(g_display, PropertyChangeMask, &xevent); + } + while (xevent.type != PropertyNotify); + + return xevent.xproperty.time; } /*****************************************************************************/ @@ -132,7 +135,7 @@ clipboard_get_server_time(void) static int APP_CC clipboard_get_local_time(void) { - return g_time3(); + return g_time3(); } /*****************************************************************************/ @@ -140,386 +143,416 @@ clipboard_get_local_time(void) int APP_CC clipboard_init(void) { - struct stream* s; - int size; - int rv; - int input_mask; - int dummy; - int ver_maj; - int ver_min; - Status st; - - LOGM((LOG_LEVEL_DEBUG, "xrdp-chansrv: in clipboard_init")); - if (g_clip_up) - { - return 0; - } - xcommon_init(); - clipboard_deinit(); - rv = 0; - if (rv == 0) - { - g_clipboard_atom = XInternAtom(g_display, "CLIPBOARD", False); - if (g_clipboard_atom == None) + struct stream *s; + int size; + int rv; + int input_mask; + int dummy; + int ver_maj; + int ver_min; + Status st; + + LOGM((LOG_LEVEL_DEBUG, "xrdp-chansrv: in clipboard_init")); + + if (g_clip_up) { - LOGM((LOG_LEVEL_ERROR, "clipboard_init: XInternAtom failed")); - rv = 3; + return 0; } - } - if (rv == 0) - { - if (!XFixesQueryExtension(g_display, &g_xfixes_event_base, &dummy)) + + xcommon_init(); + clipboard_deinit(); + rv = 0; + + if (rv == 0) { - LOGM((LOG_LEVEL_ERROR, "clipboard_init: no xfixes")); - rv = 5; + g_clipboard_atom = XInternAtom(g_display, "CLIPBOARD", False); + + if (g_clipboard_atom == None) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_init: XInternAtom failed")); + rv = 3; + } } - } - if (rv == 0) - { - LOGM((LOG_LEVEL_DEBUG, "clipboard_init: g_xfixes_event_base %d", - g_xfixes_event_base)); - st = XFixesQueryVersion(g_display, &ver_maj, &ver_min); - LOGM((LOG_LEVEL_DEBUG, "clipboard_init st %d, maj %d min %d", st, - ver_maj, ver_min)); - g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM", - False); - g_get_time_atom = XInternAtom(g_display, "XRDP_GET_TIME_ATOM", - False); - g_timestamp_atom = XInternAtom(g_display, "TIMESTAMP", False); - g_targets_atom = XInternAtom(g_display, "TARGETS", False); - g_multiple_atom = XInternAtom(g_display, "MULTIPLE", False); - g_primary_atom = XInternAtom(g_display, "PRIMARY", False); - g_secondary_atom = XInternAtom(g_display, "SECONDARY", False); - g_utf8_atom = XInternAtom(g_display, "UTF8_STRING", False); - - g_image_bmp_atom = XInternAtom(g_display, "image/bmp", False); - g_incr_atom = XInternAtom(g_display, "INCR", False); - if (g_image_bmp_atom == None) + + if (rv == 0) { - LOGM((LOG_LEVEL_ERROR, "clipboard_init: g_image_bmp_atom was " - "not allocated")); + if (!XFixesQueryExtension(g_display, &g_xfixes_event_base, &dummy)) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_init: no xfixes")); + rv = 5; + } } - g_wnd = XCreateSimpleWindow(g_display, RootWindowOfScreen(g_screen), - 0, 0, 4, 4, 0, 0, 0); - input_mask = StructureNotifyMask | PropertyChangeMask; - XSelectInput(g_display, g_wnd, input_mask); - //XMapWindow(g_display, g_wnd); - XFixesSelectSelectionInput(g_display, g_wnd, - g_clipboard_atom, - XFixesSetSelectionOwnerNotifyMask | - XFixesSelectionWindowDestroyNotifyMask | - XFixesSelectionClientCloseNotifyMask); - } - if (rv == 0) - { - make_stream(s); - init_stream(s, 8192); - out_uint16_le(s, 1); /* CLIPRDR_CONNECT */ - out_uint16_le(s, 0); /* status */ - out_uint32_le(s, 0); /* length */ - out_uint32_le(s, 0); /* extra 4 bytes ? */ - s_mark_end(s); - size = (int)(s->end - s->data); - LOGM((LOG_LEVEL_DEBUG, "clipboard_init: data out, sending " - "CLIPRDR_CONNECT (clip_msg_id = 1)")); - rv = send_channel_data(g_cliprdr_chan_id, s->data, size); - if (rv != 0) + if (rv == 0) { - LOGM((LOG_LEVEL_ERROR, "clipboard_init: send_channel_data failed " - "rv = %d", rv)); - rv = 4; + LOGM((LOG_LEVEL_DEBUG, "clipboard_init: g_xfixes_event_base %d", + g_xfixes_event_base)); + st = XFixesQueryVersion(g_display, &ver_maj, &ver_min); + LOGM((LOG_LEVEL_DEBUG, "clipboard_init st %d, maj %d min %d", st, + ver_maj, ver_min)); + g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM", + False); + g_get_time_atom = XInternAtom(g_display, "XRDP_GET_TIME_ATOM", + False); + g_timestamp_atom = XInternAtom(g_display, "TIMESTAMP", False); + g_targets_atom = XInternAtom(g_display, "TARGETS", False); + g_multiple_atom = XInternAtom(g_display, "MULTIPLE", False); + g_primary_atom = XInternAtom(g_display, "PRIMARY", False); + g_secondary_atom = XInternAtom(g_display, "SECONDARY", False); + g_utf8_atom = XInternAtom(g_display, "UTF8_STRING", False); + + g_image_bmp_atom = XInternAtom(g_display, "image/bmp", False); + g_incr_atom = XInternAtom(g_display, "INCR", False); + + if (g_image_bmp_atom == None) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_init: g_image_bmp_atom was " + "not allocated")); + } + + g_wnd = XCreateSimpleWindow(g_display, RootWindowOfScreen(g_screen), + 0, 0, 4, 4, 0, 0, 0); + input_mask = StructureNotifyMask | PropertyChangeMask; + XSelectInput(g_display, g_wnd, input_mask); + //XMapWindow(g_display, g_wnd); + XFixesSelectSelectionInput(g_display, g_wnd, + g_clipboard_atom, + XFixesSetSelectionOwnerNotifyMask | + XFixesSelectionWindowDestroyNotifyMask | + XFixesSelectionClientCloseNotifyMask); } - free_stream(s); - } - if (rv == 0) - { - g_clip_up = 1; - make_stream(g_ins); - init_stream(g_ins, 8192); - } - else - { - LOGM((LOG_LEVEL_ERROR, "xrdp-chansrv: clipboard_init: error on exit")); - } - return rv; + + if (rv == 0) + { + make_stream(s); + init_stream(s, 8192); + out_uint16_le(s, 1); /* CLIPRDR_CONNECT */ + out_uint16_le(s, 0); /* status */ + out_uint32_le(s, 0); /* length */ + out_uint32_le(s, 0); /* extra 4 bytes ? */ + s_mark_end(s); + size = (int)(s->end - s->data); + LOGM((LOG_LEVEL_DEBUG, "clipboard_init: data out, sending " + "CLIPRDR_CONNECT (clip_msg_id = 1)")); + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + + if (rv != 0) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_init: send_channel_data failed " + "rv = %d", rv)); + rv = 4; + } + + free_stream(s); + } + + if (rv == 0) + { + g_clip_up = 1; + make_stream(g_ins); + init_stream(g_ins, 8192); + } + else + { + LOGM((LOG_LEVEL_ERROR, "xrdp-chansrv: clipboard_init: error on exit")); + } + + return rv; } /*****************************************************************************/ int APP_CC clipboard_deinit(void) { - if (g_wnd != 0) - { - XDestroyWindow(g_display, g_wnd); - g_wnd = 0; - } - g_free(g_last_clip_data); - g_last_clip_data = 0; - g_last_clip_size = 0; - free_stream(g_ins); - g_ins = 0; - g_clip_up = 0; - return 0; + if (g_wnd != 0) + { + XDestroyWindow(g_display, g_wnd); + g_wnd = 0; + } + + g_free(g_last_clip_data); + g_last_clip_data = 0; + g_last_clip_size = 0; + free_stream(g_ins); + g_ins = 0; + g_clip_up = 0; + return 0; } /*****************************************************************************/ static int APP_CC clipboard_send_data_request(void) { - struct stream* s; - int size; - int rv; - - LOGM((LOG_LEVEL_DEBUG, "clipboard_send_data_request:")); - if (!g_got_format_announce) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_request: error, " - "no format announce")); - return 0; - } - g_got_format_announce = 0; - make_stream(s); - init_stream(s, 8192); - out_uint16_le(s, 4); /* CLIPRDR_DATA_REQUEST */ - out_uint16_le(s, 0); /* status */ - out_uint32_le(s, 4); /* length */ - out_uint32_le(s, clipboard_format_id); - s_mark_end(s); - size = (int)(s->end - s->data); - LOGM((LOG_LEVEL_DEBUG,"clipboard_send_data_request: data out, sending " - "CLIPRDR_DATA_REQUEST (clip_msg_id = 4)")); - rv = send_channel_data(g_cliprdr_chan_id, s->data, size); - free_stream(s); - return rv; + struct stream *s; + int size; + int rv; + + LOGM((LOG_LEVEL_DEBUG, "clipboard_send_data_request:")); + + if (!g_got_format_announce) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_request: error, " + "no format announce")); + return 0; + } + + g_got_format_announce = 0; + make_stream(s); + init_stream(s, 8192); + out_uint16_le(s, 4); /* CLIPRDR_DATA_REQUEST */ + out_uint16_le(s, 0); /* status */ + out_uint32_le(s, 4); /* length */ + out_uint32_le(s, clipboard_format_id); + s_mark_end(s); + size = (int)(s->end - s->data); + LOGM((LOG_LEVEL_DEBUG, "clipboard_send_data_request: data out, sending " + "CLIPRDR_DATA_REQUEST (clip_msg_id = 4)")); + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + free_stream(s); + return rv; } /*****************************************************************************/ static int APP_CC clipboard_send_format_ack(void) { - struct stream* s; - int size; - int rv; - - make_stream(s); - init_stream(s, 8192); - out_uint16_le(s, 3); /* CLIPRDR_FORMAT_ACK */ - out_uint16_le(s, 1); /* status */ - out_uint32_le(s, 0); /* length */ - out_uint32_le(s, 0); /* extra 4 bytes ? */ - s_mark_end(s); - size = (int)(s->end - s->data); - LOGM((LOG_LEVEL_DEBUG,"clipboard_send_format_ack: data out, sending " - "CLIPRDR_FORMAT_ACK (clip_msg_id = 3)")); - rv = send_channel_data(g_cliprdr_chan_id, s->data, size); - free_stream(s); - return rv; + struct stream *s; + int size; + int rv; + + make_stream(s); + init_stream(s, 8192); + out_uint16_le(s, 3); /* CLIPRDR_FORMAT_ACK */ + out_uint16_le(s, 1); /* status */ + out_uint32_le(s, 0); /* length */ + out_uint32_le(s, 0); /* extra 4 bytes ? */ + s_mark_end(s); + size = (int)(s->end - s->data); + LOGM((LOG_LEVEL_DEBUG, "clipboard_send_format_ack: data out, sending " + "CLIPRDR_FORMAT_ACK (clip_msg_id = 3)")); + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + free_stream(s); + return rv; } static char windows_native_format[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /*****************************************************************************/ static int APP_CC -clipboard_send_format_announce(tui32 format_id, char* format_name) +clipboard_send_format_announce(tui32 format_id, char *format_name) { - struct stream* s; - int size; - int rv; - - make_stream(s); - init_stream(s, 8192); - out_uint16_le(s, 2); /* CLIPRDR_FORMAT_ANNOUNCE */ - out_uint16_le(s, 0); /* status */ - out_uint32_le(s, 4 + sizeof(windows_native_format)); /* length */ - out_uint32_le(s, format_id); - out_uint8p(s, windows_native_format, sizeof(windows_native_format)); - s_mark_end(s); - size = (int)(s->end - s->data); - LOGM((LOG_LEVEL_DEBUG,"clipboard_send_format_announce: data out, sending " - "CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)")); - rv = send_channel_data(g_cliprdr_chan_id, s->data, size); - free_stream(s); - return rv; + struct stream *s; + int size; + int rv; + + make_stream(s); + init_stream(s, 8192); + out_uint16_le(s, 2); /* CLIPRDR_FORMAT_ANNOUNCE */ + out_uint16_le(s, 0); /* status */ + out_uint32_le(s, 4 + sizeof(windows_native_format)); /* length */ + out_uint32_le(s, format_id); + out_uint8p(s, windows_native_format, sizeof(windows_native_format)); + s_mark_end(s); + size = (int)(s->end - s->data); + LOGM((LOG_LEVEL_DEBUG, "clipboard_send_format_announce: data out, sending " + "CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)")); + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + free_stream(s); + return rv; } /*****************************************************************************/ /* returns number of bytes written */ static int APP_CC -clipboard_out_unicode(struct stream* s, char* text, int num_chars) +clipboard_out_unicode(struct stream *s, char *text, int num_chars) { - int index; - int lnum_chars; - twchar* ltext; + int index; + int lnum_chars; + twchar *ltext; - if ((num_chars < 1) || (text == 0)) - { - return 0; - } - lnum_chars = g_mbstowcs(0, text, num_chars); - if (lnum_chars < 0) - { - return 0; - } - ltext = g_malloc((num_chars + 1) * sizeof(twchar), 1); - g_mbstowcs(ltext, text, num_chars); - index = 0; - while (index < num_chars) - { - out_uint16_le(s, ltext[index]); - index++; - } - g_free(ltext); - return index * 2; + if ((num_chars < 1) || (text == 0)) + { + return 0; + } + + lnum_chars = g_mbstowcs(0, text, num_chars); + + if (lnum_chars < 0) + { + return 0; + } + + ltext = g_malloc((num_chars + 1) * sizeof(twchar), 1); + g_mbstowcs(ltext, text, num_chars); + index = 0; + + while (index < num_chars) + { + out_uint16_le(s, ltext[index]); + index++; + } + + g_free(ltext); + return index * 2; } /*****************************************************************************/ static int APP_CC clipboard_send_data_response_for_image(void) { - struct stream* s; - int size; - int rv; - - LOG(10, ("clipboard_send_data_response_for_image: g_last_clip_size %d\n", - g_last_clip_size)); - make_stream(s); - init_stream(s, 64 + g_last_clip_size); - out_uint16_le(s, 5); /* CLIPRDR_DATA_RESPONSE */ - out_uint16_le(s, 1); /* status */ - out_uint32_le(s, g_last_clip_size); /* length */ - /* insert image data */ - if (g_last_clip_type == g_image_bmp_atom) - { - /* do not insert first header */ - out_uint8p(s, g_last_clip_data + 14, g_last_clip_size - 14); - } - out_uint16_le(s, 0); /* nil for string */ - out_uint32_le(s, 0); - out_uint32_le(s, 0); - out_uint32_le(s, 0); - s_mark_end(s); - size = (int)(s->end - s->data); - /* HANGING HERE WHEN IMAGE DATA IS TOO BIG!!!! */ - rv = send_channel_data(g_cliprdr_chan_id, s->data, size); - free_stream(s); - return rv; + struct stream *s; + int size; + int rv; + + LOG(10, ("clipboard_send_data_response_for_image: g_last_clip_size %d\n", + g_last_clip_size)); + make_stream(s); + init_stream(s, 64 + g_last_clip_size); + out_uint16_le(s, 5); /* CLIPRDR_DATA_RESPONSE */ + out_uint16_le(s, 1); /* status */ + out_uint32_le(s, g_last_clip_size); /* length */ + + /* insert image data */ + if (g_last_clip_type == g_image_bmp_atom) + { + /* do not insert first header */ + out_uint8p(s, g_last_clip_data + 14, g_last_clip_size - 14); + } + + out_uint16_le(s, 0); /* nil for string */ + out_uint32_le(s, 0); + out_uint32_le(s, 0); + out_uint32_le(s, 0); + s_mark_end(s); + size = (int)(s->end - s->data); + /* HANGING HERE WHEN IMAGE DATA IS TOO BIG!!!! */ + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + free_stream(s); + return rv; } /*****************************************************************************/ static int APP_CC clipboard_send_data_response(void) { - struct stream* s; - int size; - int rv; - int num_chars; - - LOG(10, ("clipboard_send_data_response:")); - num_chars = 0; - if (g_last_clip_data != 0) - { - if (g_last_clip_type == g_image_bmp_atom) + struct stream *s; + int size; + int rv; + int num_chars; + + LOG(10, ("clipboard_send_data_response:")); + num_chars = 0; + + if (g_last_clip_data != 0) { - return clipboard_send_data_response_for_image(); + if (g_last_clip_type == g_image_bmp_atom) + { + return clipboard_send_data_response_for_image(); + } + + if ((g_last_clip_type == XA_STRING) || (g_last_clip_type == g_utf8_atom)) + { + num_chars = g_mbstowcs(0, g_last_clip_data, 0); + + if (num_chars < 0) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_response: bad string")); + num_chars = 0; + } + } } - if ((g_last_clip_type == XA_STRING) || (g_last_clip_type == g_utf8_atom)) + + LOG(10, ("clipboard_send_data_response: g_last_clip_size %d " + "num_chars %d", g_last_clip_size, num_chars)); + make_stream(s); + init_stream(s, 64 + num_chars * 2); + out_uint16_le(s, 5); /* CLIPRDR_DATA_RESPONSE */ + out_uint16_le(s, 1); /* status */ + out_uint32_le(s, num_chars * 2 + 2); /* length */ + + if (clipboard_out_unicode(s, g_last_clip_data, num_chars) != num_chars * 2) { - num_chars = g_mbstowcs(0, g_last_clip_data, 0); - if (num_chars < 0) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_response: bad string")); - num_chars = 0; - } + LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_response: error " + "clipboard_out_unicode didn't write right number of bytes")); } - } - LOG(10, ("clipboard_send_data_response: g_last_clip_size %d " - "num_chars %d", g_last_clip_size, num_chars)); - make_stream(s); - init_stream(s, 64 + num_chars * 2); - out_uint16_le(s, 5); /* CLIPRDR_DATA_RESPONSE */ - out_uint16_le(s, 1); /* status */ - out_uint32_le(s, num_chars * 2 + 2); /* length */ - if (clipboard_out_unicode(s, g_last_clip_data, num_chars) != num_chars * 2) - { - LOGM((LOG_LEVEL_ERROR,"clipboard_send_data_response: error " - "clipboard_out_unicode didn't write right number of bytes")); - } - out_uint16_le(s, 0); /* nil for string */ - out_uint32_le(s, 0); - s_mark_end(s); - size = (int)(s->end - s->data); - LOGM((LOG_LEVEL_DEBUG,"clipboard_send_data_response: data out, sending " - "CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d num_chars %d", - size, num_chars)); - rv = send_channel_data(g_cliprdr_chan_id, s->data, size); - free_stream(s); - return rv; + + out_uint16_le(s, 0); /* nil for string */ + out_uint32_le(s, 0); + s_mark_end(s); + size = (int)(s->end - s->data); + LOGM((LOG_LEVEL_DEBUG, "clipboard_send_data_response: data out, sending " + "CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d num_chars %d", + size, num_chars)); + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + free_stream(s); + return rv; } /*****************************************************************************/ static int APP_CC clipboard_set_selection_owner(void) { - Window owner; + Window owner; - g_selection_time = clipboard_get_server_time(); - XSetSelectionOwner(g_display, g_clipboard_atom, g_wnd, g_selection_time); - owner = XGetSelectionOwner(g_display, g_clipboard_atom); - if (owner != g_wnd) - { - g_got_selection = 0; - return 1; - } - g_got_selection = 1; - return 0; + g_selection_time = clipboard_get_server_time(); + XSetSelectionOwner(g_display, g_clipboard_atom, g_wnd, g_selection_time); + owner = XGetSelectionOwner(g_display, g_clipboard_atom); + + if (owner != g_wnd) + { + g_got_selection = 0; + return 1; + } + + g_got_selection = 1; + return 0; } /*****************************************************************************/ static int APP_CC -clipboard_provide_selection(XSelectionRequestEvent* req, Atom type, int format, - char* data, int length) +clipboard_provide_selection(XSelectionRequestEvent *req, Atom type, int format, + char *data, int length) { - XEvent xev; - - XChangeProperty(g_display, req->requestor, req->property, - type, format, PropModeReplace, (tui8*)data, length); - g_memset(&xev, 0, sizeof(xev)); - xev.xselection.type = SelectionNotify; - xev.xselection.send_event = True; - xev.xselection.display = req->display; - xev.xselection.requestor = req->requestor; - xev.xselection.selection = req->selection; - xev.xselection.target = req->target; - xev.xselection.property = req->property; - xev.xselection.time = req->time; - XSendEvent(g_display, req->requestor, False, NoEventMask, &xev); - return 0; + XEvent xev; + + XChangeProperty(g_display, req->requestor, req->property, + type, format, PropModeReplace, (tui8 *)data, length); + g_memset(&xev, 0, sizeof(xev)); + xev.xselection.type = SelectionNotify; + xev.xselection.send_event = True; + xev.xselection.display = req->display; + xev.xselection.requestor = req->requestor; + xev.xselection.selection = req->selection; + xev.xselection.target = req->target; + xev.xselection.property = req->property; + xev.xselection.time = req->time; + XSendEvent(g_display, req->requestor, False, NoEventMask, &xev); + return 0; } /*****************************************************************************/ static int APP_CC -clipboard_refuse_selection(XSelectionRequestEvent* req) +clipboard_refuse_selection(XSelectionRequestEvent *req) { - XEvent xev; - - g_memset(&xev, 0, sizeof(xev)); - xev.xselection.type = SelectionNotify; - xev.xselection.send_event = True; - xev.xselection.display = req->display; - xev.xselection.requestor = req->requestor; - xev.xselection.selection = req->selection; - xev.xselection.target = req->target; - xev.xselection.property = None; - xev.xselection.time = req->time; - XSendEvent(g_display, req->requestor, False, NoEventMask, &xev); - return 0; + XEvent xev; + + g_memset(&xev, 0, sizeof(xev)); + xev.xselection.type = SelectionNotify; + xev.xselection.send_event = True; + xev.xselection.display = req->display; + xev.xselection.requestor = req->requestor; + xev.xselection.selection = req->selection; + xev.xselection.target = req->target; + xev.xselection.property = None; + xev.xselection.time = req->time; + XSendEvent(g_display, req->requestor, False, NoEventMask, &xev); + return 0; } /*****************************************************************************/ @@ -527,47 +560,49 @@ clipboard_refuse_selection(XSelectionRequestEvent* req) updated with new clipboard data; contains Clipboard Format ID and name pairs of new Clipboard Formats on the clipboard. */ static int APP_CC -clipboard_process_format_announce(struct stream* s, int clip_msg_status, +clipboard_process_format_announce(struct stream *s, int clip_msg_status, int clip_msg_len) { - LOGM((LOG_LEVEL_DEBUG, "clipboard_process_format_announce: " - "CLIPRDR_FORMAT_ANNOUNCE")); - //g_hexdump(s->p, s->end - s->p); - clipboard_send_format_ack(); - g_got_format_announce = 1; - g_data_in_up_to_date = 0; - if (clipboard_set_selection_owner() != 0) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_process_format_announce: " - "XSetSelectionOwner failed")); - } - return 0; + LOGM((LOG_LEVEL_DEBUG, "clipboard_process_format_announce: " + "CLIPRDR_FORMAT_ANNOUNCE")); + //g_hexdump(s->p, s->end - s->p); + clipboard_send_format_ack(); + g_got_format_announce = 1; + g_data_in_up_to_date = 0; + + if (clipboard_set_selection_owner() != 0) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_process_format_announce: " + "XSetSelectionOwner failed")); + } + + return 0; } /*****************************************************************************/ /* response to CB_FORMAT_LIST; used to indicate whether processing of the Format List PDU was successful */ static int APP_CC -clipboard_prcoess_format_ack(struct stream* s, int clip_msg_status, +clipboard_prcoess_format_ack(struct stream *s, int clip_msg_status, int clip_msg_len) { - LOGM((LOG_LEVEL_DEBUG,"clipboard_prcoess_format_ack: CLIPRDR_FORMAT_ACK")); - //g_hexdump(s->p, s->end - s->p); - return 0; + LOGM((LOG_LEVEL_DEBUG, "clipboard_prcoess_format_ack: CLIPRDR_FORMAT_ACK")); + //g_hexdump(s->p, s->end - s->p); + return 0; } /*****************************************************************************/ /* sent by recipient of CB_FORMAT_LIST; used to request data for one of the formats that was listed in CB_FORMAT_LIST */ static int APP_CC -clipboard_process_data_request(struct stream* s, int clip_msg_status, +clipboard_process_data_request(struct stream *s, int clip_msg_status, int clip_msg_len) { - LOGM((LOG_LEVEL_DEBUG,"clipboard_process_data_request: " - "CLIPRDR_DATA_REQUEST")); - //g_hexdump(s->p, s->end - s->p); - clipboard_send_data_response(); - return 0; + LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_request: " + "CLIPRDR_DATA_REQUEST")); + //g_hexdump(s->p, s->end - s->p); + clipboard_send_data_response(); + return 0; } /*****************************************************************************/ @@ -576,54 +611,61 @@ clipboard_process_data_request(struct stream* s, int clip_msg_status, was successful, CB_FORMAT_DATA_RESPONSE includes contents of requested clipboard data. */ static int APP_CC -clipboard_process_data_response_for_image(struct stream * s, - int clip_msg_status, - int clip_msg_len) +clipboard_process_data_response_for_image(struct stream *s, + int clip_msg_status, + int clip_msg_len) { - XSelectionRequestEvent* lxev = &g_saved_selection_req_event; - char* cptr; - char cdata; - int len; - int index; - - LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_response_for_image: " - "CLIPRDR_DATA_RESPONSE_FOR_IMAGE")); - g_waiting_for_data_response = 0; - len = (int)(s->end - s->p); - if (len < 1) - { - return 0; - } - if (g_last_clip_type == g_image_bmp_atom) - { - /* space for inserting bmp image header */ - len += 14; - cptr = (char*)g_malloc(len, 0); - if (cptr == 0) + XSelectionRequestEvent *lxev = &g_saved_selection_req_event; + char *cptr; + char cdata; + int len; + int index; + + LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_response_for_image: " + "CLIPRDR_DATA_RESPONSE_FOR_IMAGE")); + g_waiting_for_data_response = 0; + len = (int)(s->end - s->p); + + if (len < 1) + { + return 0; + } + + if (g_last_clip_type == g_image_bmp_atom) { - return 0; + /* space for inserting bmp image header */ + len += 14; + cptr = (char *)g_malloc(len, 0); + + if (cptr == 0) + { + return 0; + } + + g_memcpy(cptr, g_bmp_image_header, 14); + index = 14; } - g_memcpy(cptr, g_bmp_image_header, 14); - index = 14; - } - else - { + else + { + return 0; + } + + while (s_check(s)) + { + in_uint8(s, cdata); + cptr[index++] = cdata; + } + + if (len >= 0) + { + g_data_in = cptr; + g_data_in_size = len; + g_data_in_time = clipboard_get_local_time(); + g_data_in_up_to_date = 1; + } + + clipboard_provide_selection(lxev, lxev->target, 8, cptr, len); return 0; - } - while (s_check(s)) - { - in_uint8(s, cdata); - cptr[index++] = cdata; - } - if (len >= 0) - { - g_data_in = cptr; - g_data_in_size = len; - g_data_in_time = clipboard_get_local_time(); - g_data_in_up_to_date = 1; - } - clipboard_provide_selection(lxev, lxev->target, 8, cptr, len); - return 0; } /*****************************************************************************/ @@ -633,159 +675,181 @@ clipboard_process_data_response_for_image(struct stream * s, clipboard data. */ /*****************************************************************************/ static int APP_CC -clipboard_process_data_response(struct stream* s, int clip_msg_status, +clipboard_process_data_response(struct stream *s, int clip_msg_status, int clip_msg_len) { - XSelectionRequestEvent* lxev; - twchar* wtext; - twchar wchr; - int len; - int index; - int data_in_len; - - if (g_want_image_data) - { - g_want_image_data = 0; - clipboard_process_data_response_for_image(s, clip_msg_status, clip_msg_len); - return 0; - } - LOGM((LOG_LEVEL_DEBUG,"clipboard_process_data_response: " - "CLIPRDR_DATA_RESPONSE")); - g_waiting_for_data_response = 0; - len = (int)(s->end - s->p); - if (len < 1) - { - return 0; - } - //g_hexdump(s->p, len); - wtext = (twchar*)g_malloc(((len / 2) + 1) * sizeof(twchar), 0); - if (wtext == 0) - { - return 0; - } - index = 0; - while (s_check(s)) - { - in_uint16_le(s, wchr); - wtext[index] = wchr; - if (wchr == 0) + XSelectionRequestEvent *lxev; + twchar *wtext; + twchar wchr; + int len; + int index; + int data_in_len; + + if (g_want_image_data) { - break; + g_want_image_data = 0; + clipboard_process_data_response_for_image(s, clip_msg_status, clip_msg_len); + return 0; } - index++; - } - wtext[index] = 0; - g_free(g_data_in); - g_data_in = 0; - g_data_in_size = 0; - g_data_in_time = 0; - len = g_wcstombs(0, wtext, 0); - if (len >= 0) - { - g_data_in = (char*)g_malloc(len + 16, 0); - if (g_data_in == 0) + + LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_response: " + "CLIPRDR_DATA_RESPONSE")); + g_waiting_for_data_response = 0; + len = (int)(s->end - s->p); + + if (len < 1) { - g_free(wtext); - return 0; + return 0; } - g_data_in_size = len; - g_wcstombs(g_data_in, wtext, len + 1); - g_data_in_time = xcommon_get_local_time(); - g_data_in_up_to_date = 1; - } - if (g_data_in != 0) - { - data_in_len = g_strlen(g_data_in); - for (index = 0; index < g_selection_request_event_count; index++) + + //g_hexdump(s->p, len); + wtext = (twchar *)g_malloc(((len / 2) + 1) * sizeof(twchar), 0); + + if (wtext == 0) + { + return 0; + } + + index = 0; + + while (s_check(s)) { - lxev = &(g_selection_request_event[index]); - clipboard_provide_selection(lxev, lxev->target, 8, g_data_in, - data_in_len); - LOGM((LOG_LEVEL_DEBUG,"clipboard_process_data_response: requestor %d " - "data_in_len %d", lxev->requestor, data_in_len)); + in_uint16_le(s, wchr); + wtext[index] = wchr; + + if (wchr == 0) + { + break; + } + + index++; } - } - g_selection_request_event_count = 0; - g_free(wtext); - return 0; + + wtext[index] = 0; + g_free(g_data_in); + g_data_in = 0; + g_data_in_size = 0; + g_data_in_time = 0; + len = g_wcstombs(0, wtext, 0); + + if (len >= 0) + { + g_data_in = (char *)g_malloc(len + 16, 0); + + if (g_data_in == 0) + { + g_free(wtext); + return 0; + } + + g_data_in_size = len; + g_wcstombs(g_data_in, wtext, len + 1); + g_data_in_time = xcommon_get_local_time(); + g_data_in_up_to_date = 1; + } + + if (g_data_in != 0) + { + data_in_len = g_strlen(g_data_in); + + for (index = 0; index < g_selection_request_event_count; index++) + { + lxev = &(g_selection_request_event[index]); + clipboard_provide_selection(lxev, lxev->target, 8, g_data_in, + data_in_len); + LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_response: requestor %d " + "data_in_len %d", lxev->requestor, data_in_len)); + } + } + + g_selection_request_event_count = 0; + g_free(wtext); + return 0; } /*****************************************************************************/ int APP_CC -clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length, +clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length, int total_length) { - int clip_msg_id; - int clip_msg_len; - int clip_msg_status; - int rv; - struct stream* ls; - - LOG(10, ("clipboard_data_in: chan_is %d " - "chan_flags %d length %d total_length %d", - chan_id, chan_flags, length, total_length)); - if ((chan_flags & 3) == 3) - { - ls = s; - } - else - { - if (chan_flags & 1) + int clip_msg_id; + int clip_msg_len; + int clip_msg_status; + int rv; + struct stream *ls; + + LOG(10, ("clipboard_data_in: chan_is %d " + "chan_flags %d length %d total_length %d", + chan_id, chan_flags, length, total_length)); + + if ((chan_flags & 3) == 3) { - init_stream(g_ins, total_length); + ls = s; } - in_uint8a(s, g_ins->end, length); - g_ins->end += length; - if ((chan_flags & 2) == 0) + else { - return 0; + if (chan_flags & 1) + { + init_stream(g_ins, total_length); + } + + in_uint8a(s, g_ins->end, length); + g_ins->end += length; + + if ((chan_flags & 2) == 0) + { + return 0; + } + + ls = g_ins; } - ls = g_ins; - } - in_uint16_le(ls, clip_msg_id); - in_uint16_le(ls, clip_msg_status); - in_uint32_le(ls, clip_msg_len); - LOG(10, ("clipboard_data_in: clip_msg_id %d " - "clip_msg_status %d clip_msg_len %d", - clip_msg_id, clip_msg_status, clip_msg_len)); - rv = 0; - switch (clip_msg_id) - { - /* sent by client or server when its local system clipboard is */ - /* updated with new clipboard data; contains Clipboard Format ID */ - /* and name pairs of new Clipboard Formats on the clipboard. */ - case CB_FORMAT_LIST: /* CLIPRDR_FORMAT_ANNOUNCE */ - rv = clipboard_process_format_announce(ls, clip_msg_status, - clip_msg_len); - break; - /* response to CB_FORMAT_LIST; used to indicate whether */ - /* processing of the Format List PDU was successful */ - case CB_FORMAT_LIST_RESPONSE: /* CLIPRDR_FORMAT_ACK */ - rv = clipboard_prcoess_format_ack(ls, clip_msg_status, - clip_msg_len); - break; - /* sent by recipient of CB_FORMAT_LIST; used to request data for one */ - /* of the formats that was listed in CB_FORMAT_LIST */ - case CB_FORMAT_DATA_REQUEST: /* CLIPRDR_DATA_REQUEST */ - rv = clipboard_process_data_request(ls, clip_msg_status, - clip_msg_len); - break; - /* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate */ - /* whether processing of the CB_FORMAT_DATA_REQUEST was */ - /* successful; if processing was successful, */ - /* CB_FORMAT_DATA_RESPONSE includes contents of requested */ - /* clipboard data. */ - case CB_FORMAT_DATA_RESPONSE: /* CLIPRDR_DATA_RESPONSE */ - rv = clipboard_process_data_response(ls, clip_msg_status, - clip_msg_len); - break; - default: - LOGM((LOG_LEVEL_ERROR, "clipboard_data_in: unknown clip_msg_id %d", - clip_msg_id)); - break; - } - XFlush(g_display); - return rv; + + in_uint16_le(ls, clip_msg_id); + in_uint16_le(ls, clip_msg_status); + in_uint32_le(ls, clip_msg_len); + LOG(10, ("clipboard_data_in: clip_msg_id %d " + "clip_msg_status %d clip_msg_len %d", + clip_msg_id, clip_msg_status, clip_msg_len)); + rv = 0; + + switch (clip_msg_id) + { + /* sent by client or server when its local system clipboard is */ + /* updated with new clipboard data; contains Clipboard Format ID */ + /* and name pairs of new Clipboard Formats on the clipboard. */ + case CB_FORMAT_LIST: /* CLIPRDR_FORMAT_ANNOUNCE */ + rv = clipboard_process_format_announce(ls, clip_msg_status, + clip_msg_len); + break; + /* response to CB_FORMAT_LIST; used to indicate whether */ + /* processing of the Format List PDU was successful */ + case CB_FORMAT_LIST_RESPONSE: /* CLIPRDR_FORMAT_ACK */ + rv = clipboard_prcoess_format_ack(ls, clip_msg_status, + clip_msg_len); + break; + /* sent by recipient of CB_FORMAT_LIST; used to request data for one */ + /* of the formats that was listed in CB_FORMAT_LIST */ + case CB_FORMAT_DATA_REQUEST: /* CLIPRDR_DATA_REQUEST */ + rv = clipboard_process_data_request(ls, clip_msg_status, + clip_msg_len); + break; + /* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate */ + /* whether processing of the CB_FORMAT_DATA_REQUEST was */ + /* successful; if processing was successful, */ + /* CB_FORMAT_DATA_RESPONSE includes contents of requested */ + /* clipboard data. */ + case CB_FORMAT_DATA_RESPONSE: /* CLIPRDR_DATA_RESPONSE */ + rv = clipboard_process_data_response(ls, clip_msg_status, + clip_msg_len); + break; + default: + LOGM((LOG_LEVEL_ERROR, "clipboard_data_in: unknown clip_msg_id %d", + clip_msg_id)); + break; + } + + XFlush(g_display); + return rv; } /*****************************************************************************/ @@ -805,132 +869,151 @@ clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length, Time selection_timestamp; } XFixesSelectionNotifyEvent; */ static int APP_CC -clipboard_event_selection_owner_notify(XEvent* xevent) +clipboard_event_selection_owner_notify(XEvent *xevent) { - XFixesSelectionNotifyEvent* lxevent; - - lxevent = (XFixesSelectionNotifyEvent*)xevent; - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: " - "window %d subtype %d owner %d g_wnd %d", - lxevent->window, lxevent->subtype, lxevent->owner, g_wnd)); - if (lxevent->owner == g_wnd) - { - LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_owner_notify: skipping, " - "onwer == g_wnd")); - g_got_selection = 1; + XFixesSelectionNotifyEvent *lxevent; + + lxevent = (XFixesSelectionNotifyEvent *)xevent; + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: " + "window %d subtype %d owner %d g_wnd %d", + lxevent->window, lxevent->subtype, lxevent->owner, g_wnd)); + + if (lxevent->owner == g_wnd) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: skipping, " + "onwer == g_wnd")); + g_got_selection = 1; + return 0; + } + + g_got_selection = 0; + XConvertSelection(g_display, g_clipboard_atom, g_targets_atom, + g_clip_property_atom, g_wnd, lxevent->timestamp); return 0; - } - g_got_selection = 0; - XConvertSelection(g_display, g_clipboard_atom, g_targets_atom, - g_clip_property_atom, g_wnd, lxevent->timestamp); - return 0; } /*****************************************************************************/ /* returns error get a window property from wnd */ static int APP_CC -clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt, - int* n_items, char** xdata, int* xdata_size) +clipboard_get_window_property(Window wnd, Atom prop, Atom *type, int *fmt, + int *n_items, char **xdata, int *xdata_size) { - int lfmt; - int lxdata_size; - unsigned long ln_items; - unsigned long llen_after; - tui8* lxdata; - Atom ltype; - - lxdata = 0; - ltype = 0; - XGetWindowProperty(g_display, g_wnd, prop, 0, 0, 0, - AnyPropertyType, <ype, &lfmt, &ln_items, - &llen_after, &lxdata); - if (lxdata != 0) - { - XFree(lxdata); - } - if (ltype == 0) - { - /* XGetWindowProperty failed */ - return 1; - } - - if (ltype == g_incr_atom) - { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR start")); - g_incr_in_progress = 1; - g_incr_atom_type = prop; - g_incr_data_size = 0; - g_free(g_incr_data); - g_incr_data = 0; - XDeleteProperty(g_display, g_wnd, prop); - return 0; - } + int lfmt; + int lxdata_size; + unsigned long ln_items; + unsigned long llen_after; + tui8 *lxdata; + Atom ltype; + + lxdata = 0; + ltype = 0; + XGetWindowProperty(g_display, g_wnd, prop, 0, 0, 0, + AnyPropertyType, <ype, &lfmt, &ln_items, + &llen_after, &lxdata); - if (llen_after < 1) - { - /* no data, ok */ - return 0; - } - lxdata = 0; - ltype = 0; - XGetWindowProperty(g_display, g_wnd, prop, 0, (llen_after + 3) / 4, 0, - AnyPropertyType, <ype, &lfmt, &ln_items, - &llen_after, &lxdata); - if (ltype == 0) - { - /* XGetWindowProperty failed */ if (lxdata != 0) { - XFree(lxdata); + XFree(lxdata); } - return 1; - } - lxdata_size = (lfmt / 8) * ln_items; - if (lxdata_size < 1) - { - /* should not happen */ - if (lxdata != 0) + + if (ltype == 0) + { + /* XGetWindowProperty failed */ + return 1; + } + + if (ltype == g_incr_atom) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR start")); + g_incr_in_progress = 1; + g_incr_atom_type = prop; + g_incr_data_size = 0; + g_free(g_incr_data); + g_incr_data = 0; + XDeleteProperty(g_display, g_wnd, prop); + return 0; + } + + if (llen_after < 1) { - XFree(lxdata); + /* no data, ok */ + return 0; + } + + lxdata = 0; + ltype = 0; + XGetWindowProperty(g_display, g_wnd, prop, 0, (llen_after + 3) / 4, 0, + AnyPropertyType, <ype, &lfmt, &ln_items, + &llen_after, &lxdata); + + if (ltype == 0) + { + /* XGetWindowProperty failed */ + if (lxdata != 0) + { + XFree(lxdata); + } + + return 1; } - return 2; - } - if (llen_after > 0) - { - /* should not happen */ + + lxdata_size = (lfmt / 8) * ln_items; + + if (lxdata_size < 1) + { + /* should not happen */ + if (lxdata != 0) + { + XFree(lxdata); + } + + return 2; + } + + if (llen_after > 0) + { + /* should not happen */ + if (lxdata != 0) + { + XFree(lxdata); + } + + return 3; + } + + if (xdata != 0) + { + *xdata = (char *)g_malloc(lxdata_size, 0); + g_memcpy(*xdata, lxdata, lxdata_size); + } + if (lxdata != 0) { - XFree(lxdata); + XFree(lxdata); + } + + if (xdata_size != 0) + { + *xdata_size = lxdata_size; + } + + if (fmt != 0) + { + *fmt = (int)lfmt; + } + + if (n_items != 0) + { + *n_items = (int)ln_items; } - return 3; - } - if (xdata != 0) - { - *xdata = (char*)g_malloc(lxdata_size, 0); - g_memcpy(*xdata, lxdata, lxdata_size); - } - if (lxdata != 0) - { - XFree(lxdata); - } - if (xdata_size != 0) - { - *xdata_size = lxdata_size; - } - if (fmt != 0) - { - *fmt = (int)lfmt; - } - if (n_items != 0) - { - *n_items = (int)ln_items; - } - if (type != 0) - { - *type = ltype; - } - return 0; + + if (type != 0) + { + *type = ltype; + } + + return 0; } /*****************************************************************************/ @@ -948,178 +1031,188 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt, Time time; } XSelectionEvent; */ static int APP_CC -clipboard_event_selection_notify(XEvent* xevent) +clipboard_event_selection_notify(XEvent *xevent) { - XSelectionEvent* lxevent; - char* data; - int data_size; - int n_items; - int fmt; - int rv; - int index; - int convert_to_string; - int convert_to_utf8; - int convert_to_bmp_image; - int send_format_announce; - int atom; - Atom* atoms; - Atom type; - tui32 format_id; - char format_name[32]; - - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify:")); - data_size = 0; - n_items = 0; - fmt = 0; - convert_to_string = 0; - convert_to_utf8 = 0; - convert_to_bmp_image = 0; - send_format_announce = 0; - format_id = 0; - rv = 0; - data = 0; - type = 0; - lxevent = (XSelectionEvent*)xevent; - g_memset(format_name, 0, 32); - if (lxevent->property == None) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: clip could " - "not be converted")); - rv = 1; - } - if (rv == 0) - { - /* we need this if the call below turns out to be a - clipboard INCR operation */ - if (!g_incr_in_progress) + XSelectionEvent *lxevent; + char *data; + int data_size; + int n_items; + int fmt; + int rv; + int index; + int convert_to_string; + int convert_to_utf8; + int convert_to_bmp_image; + int send_format_announce; + int atom; + Atom *atoms; + Atom type; + tui32 format_id; + char format_name[32]; + + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify:")); + data_size = 0; + n_items = 0; + fmt = 0; + convert_to_string = 0; + convert_to_utf8 = 0; + convert_to_bmp_image = 0; + send_format_announce = 0; + format_id = 0; + rv = 0; + data = 0; + type = 0; + lxevent = (XSelectionEvent *)xevent; + g_memset(format_name, 0, 32); + + if (lxevent->property == None) { - g_incr_atom_target = lxevent->target; + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: clip could " + "not be converted")); + rv = 1; } - rv = clipboard_get_window_property(lxevent->requestor, lxevent->property, - &type, &fmt, - &n_items, &data, &data_size); - if (rv != 0) + if (rv == 0) { - LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: " - "clipboard_get_window_property failed error %d", rv)); + /* we need this if the call below turns out to be a + clipboard INCR operation */ + if (!g_incr_in_progress) + { + g_incr_atom_target = lxevent->target; + } + + rv = clipboard_get_window_property(lxevent->requestor, lxevent->property, + &type, &fmt, + &n_items, &data, &data_size); + + if (rv != 0) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: " + "clipboard_get_window_property failed error %d", rv)); + } + + XDeleteProperty(g_display, lxevent->requestor, lxevent->property); } - XDeleteProperty(g_display, lxevent->requestor, lxevent->property); - } - if (rv == 0) - { - if (lxevent->selection == g_clipboard_atom) + + if (rv == 0) { - if (lxevent->target == g_targets_atom) - { - /* on a 64 bit machine, actual_format_return of 32 implies long */ - if ((type == XA_ATOM) && (fmt == 32)) + if (lxevent->selection == g_clipboard_atom) { - atoms = (Atom*)data; - for (index = 0; index < n_items; index++) - { - atom = atoms[index]; - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: %d %s %d", - atom, XGetAtomName(g_display, atom), XA_STRING)); - if (atom == g_utf8_atom) + if (lxevent->target == g_targets_atom) + { + /* on a 64 bit machine, actual_format_return of 32 implies long */ + if ((type == XA_ATOM) && (fmt == 32)) + { + atoms = (Atom *)data; + + for (index = 0; index < n_items; index++) + { + atom = atoms[index]; + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: %d %s %d", + atom, XGetAtomName(g_display, atom), XA_STRING)); + + if (atom == g_utf8_atom) + { + convert_to_utf8 = 1; + } + else if (atom == XA_STRING) + { + convert_to_string = 1; + } + else if (atom == g_image_bmp_atom) + { + convert_to_bmp_image = 1; + } + } + } + else + { + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: error, " + "target is 'TARGETS' and type[%d] or fmt[%d] not right, " + "should be type[%d], fmt[%d]", type, fmt, XA_ATOM, 32)); + } + } + else if (lxevent->target == g_utf8_atom) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: UTF8_STRING " + "data_size %d", data_size)); + g_free(g_last_clip_data); + g_last_clip_data = 0; + g_last_clip_size = data_size; + g_last_clip_data = g_malloc(g_last_clip_size + 1, 0); + g_last_clip_type = g_utf8_atom; + g_memcpy(g_last_clip_data, data, g_last_clip_size); + g_last_clip_data[g_last_clip_size] = 0; + send_format_announce = 1; + format_id = CB_FORMAT_UNICODETEXT; + } + else if (lxevent->target == XA_STRING) { - convert_to_utf8 = 1; + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: XA_STRING " + "data_size %d", data_size)); + g_free(g_last_clip_data); + g_last_clip_data = 0; + g_last_clip_size = data_size; + g_last_clip_data = g_malloc(g_last_clip_size + 1, 0); + g_last_clip_type = XA_STRING; + g_memcpy(g_last_clip_data, data, g_last_clip_size); + g_last_clip_data[g_last_clip_size] = 0; + send_format_announce = 1; + format_id = CB_FORMAT_UNICODETEXT; } - else if (atom == XA_STRING) + else if (lxevent->target == g_image_bmp_atom) { - convert_to_string = 1; + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: image/bmp " + "data_size %d", data_size)); + g_free(g_last_clip_data); + g_last_clip_data = 0; + g_last_clip_size = data_size; + g_last_clip_data = g_malloc(data_size, 0); + g_last_clip_type = g_image_bmp_atom; + g_memcpy(g_last_clip_data, data, data_size); + send_format_announce = 1; + format_id = CB_FORMAT_DIB; + g_strcpy(format_name, "image/bmp"); } - else if (atom == g_image_bmp_atom) + else { - convert_to_bmp_image = 1; + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: " + "unknown target")); } - } } else { - LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: error, " - "target is 'TARGETS' and type[%d] or fmt[%d] not right, " - "should be type[%d], fmt[%d]", type, fmt, XA_ATOM, 32)); + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: " + "unknown selection")); } - } - else if (lxevent->target == g_utf8_atom) - { - LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_notify: UTF8_STRING " - "data_size %d", data_size)); - g_free(g_last_clip_data); - g_last_clip_data = 0; - g_last_clip_size = data_size; - g_last_clip_data = g_malloc(g_last_clip_size + 1, 0); - g_last_clip_type = g_utf8_atom; - g_memcpy(g_last_clip_data, data, g_last_clip_size); - g_last_clip_data[g_last_clip_size] = 0; - send_format_announce = 1; - format_id = CB_FORMAT_UNICODETEXT; - } - else if (lxevent->target == XA_STRING) - { - LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_notify: XA_STRING " - "data_size %d", data_size)); - g_free(g_last_clip_data); - g_last_clip_data = 0; - g_last_clip_size = data_size; - g_last_clip_data = g_malloc(g_last_clip_size + 1, 0); - g_last_clip_type = XA_STRING; - g_memcpy(g_last_clip_data, data, g_last_clip_size); - g_last_clip_data[g_last_clip_size] = 0; - send_format_announce = 1; - format_id = CB_FORMAT_UNICODETEXT; - } - else if (lxevent->target == g_image_bmp_atom) - { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: image/bmp " - "data_size %d", data_size)); - g_free(g_last_clip_data); - g_last_clip_data = 0; - g_last_clip_size = data_size; - g_last_clip_data = g_malloc(data_size, 0); - g_last_clip_type = g_image_bmp_atom; - g_memcpy(g_last_clip_data, data, data_size); - send_format_announce = 1; - format_id = CB_FORMAT_DIB; - g_strcpy(format_name, "image/bmp"); - } - else - { - LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: " - "unknown target")); - } } - else + + if (convert_to_utf8) { - LOGM((LOG_LEVEL_ERROR,"clipboard_event_selection_notify: " - "unknown selection")); + XConvertSelection(g_display, g_clipboard_atom, g_utf8_atom, + g_clip_property_atom, g_wnd, lxevent->time); } - } - if (convert_to_utf8) - { - XConvertSelection(g_display, g_clipboard_atom, g_utf8_atom, - g_clip_property_atom, g_wnd, lxevent->time); - } - else if (convert_to_string) - { - XConvertSelection(g_display, g_clipboard_atom, XA_STRING, - g_clip_property_atom, g_wnd, lxevent->time); - } - else if (convert_to_bmp_image) - { - XConvertSelection(g_display, g_clipboard_atom, g_image_bmp_atom, - g_clip_property_atom, g_wnd, lxevent->time); - } - if (send_format_announce) - { - if (clipboard_send_format_announce(format_id, format_name) != 0) + else if (convert_to_string) { - rv = 4; + XConvertSelection(g_display, g_clipboard_atom, XA_STRING, + g_clip_property_atom, g_wnd, lxevent->time); } - } - g_free(data); - return rv; + else if (convert_to_bmp_image) + { + XConvertSelection(g_display, g_clipboard_atom, g_image_bmp_atom, + g_clip_property_atom, g_wnd, lxevent->time); + } + + if (send_format_announce) + { + if (clipboard_send_format_announce(format_id, format_name) != 0) + { + rv = 4; + } + } + + g_free(data); + return rv; } /*****************************************************************************/ @@ -1143,113 +1236,120 @@ clipboard_event_selection_notify(XEvent* xevent) * a 32bit machine and 8 bytes on a 64 machine */ static int APP_CC -clipboard_event_selection_request(XEvent* xevent) +clipboard_event_selection_request(XEvent *xevent) { - XSelectionRequestEvent* lxev; - XEvent xev; - Atom atom_buf[10]; - Atom type; - int fmt; - int n_items; - int xdata_size; - char* xdata; - - lxev = (XSelectionRequestEvent*)xevent; - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_wnd %d, " - ".requestor %d .owner %d .selection %d '%s' .target %d .property %d", - g_wnd, lxev->requestor, lxev->owner, lxev->selection, - XGetAtomName(g_display, lxev->selection), - lxev->target, lxev->property)); - if (lxev->property == None) - { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " - "lxev->property is None")); - } - else if (lxev->target == g_targets_atom) - { - /* requestor is asking what the selection can be converted to */ - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " - "g_targets_atom")); - atom_buf[0] = g_targets_atom; - atom_buf[1] = g_timestamp_atom; - atom_buf[2] = g_multiple_atom; - atom_buf[3] = XA_STRING; - atom_buf[4] = g_utf8_atom; - atom_buf[5] = g_image_bmp_atom; - return clipboard_provide_selection(lxev, XA_ATOM, 32, (char*)atom_buf, 6); - } - else if (lxev->target == g_timestamp_atom) - { - /* requestor is asking the time I got the selection */ - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " - "g_timestamp_atom")); - atom_buf[0] = g_selection_time; - return clipboard_provide_selection(lxev, XA_INTEGER, 32, (char*)atom_buf, 1); - } - else if (lxev->target == g_multiple_atom) - { - /* target, property pairs */ - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " - "g_multiple_atom")); - if (clipboard_get_window_property(xev.xselection.requestor, - xev.xselection.property, - &type, &fmt, &n_items, &xdata, - &xdata_size) == 0) + XSelectionRequestEvent *lxev; + XEvent xev; + Atom atom_buf[10]; + Atom type; + int fmt; + int n_items; + int xdata_size; + char *xdata; + + lxev = (XSelectionRequestEvent *)xevent; + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_wnd %d, " + ".requestor %d .owner %d .selection %d '%s' .target %d .property %d", + g_wnd, lxev->requestor, lxev->owner, lxev->selection, + XGetAtomName(g_display, lxev->selection), + lxev->target, lxev->property)); + + if (lxev->property == None) { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_multiple_atom " - "n_items %d", n_items)); - /* todo */ - g_free(xdata); + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " + "lxev->property is None")); } - } - else if ((lxev->target == XA_STRING) || (lxev->target == g_utf8_atom)) - { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: %s", - XGetAtomName(g_display, lxev->target))); - clipboard_format_id = CB_FORMAT_UNICODETEXT; - if (g_data_in_up_to_date) + else if (lxev->target == g_targets_atom) { - return clipboard_provide_selection(lxev, lxev->target, 8, - g_data_in, g_strlen(g_data_in)); + /* requestor is asking what the selection can be converted to */ + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " + "g_targets_atom")); + atom_buf[0] = g_targets_atom; + atom_buf[1] = g_timestamp_atom; + atom_buf[2] = g_multiple_atom; + atom_buf[3] = XA_STRING; + atom_buf[4] = g_utf8_atom; + atom_buf[5] = g_image_bmp_atom; + return clipboard_provide_selection(lxev, XA_ATOM, 32, (char *)atom_buf, 6); } - if (g_selection_request_event_count > 10) + else if (lxev->target == g_timestamp_atom) { - LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_request: error, " - "too many requests")); + /* requestor is asking the time I got the selection */ + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " + "g_timestamp_atom")); + atom_buf[0] = g_selection_time; + return clipboard_provide_selection(lxev, XA_INTEGER, 32, (char *)atom_buf, 1); } - else + else if (lxev->target == g_multiple_atom) { - g_memcpy(&(g_selection_request_event[g_selection_request_event_count]), - lxev, sizeof(g_selection_request_event[0])); - if (g_selection_request_event_count == 0) - { + /* target, property pairs */ + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " + "g_multiple_atom")); + + if (clipboard_get_window_property(xev.xselection.requestor, + xev.xselection.property, + &type, &fmt, &n_items, &xdata, + &xdata_size) == 0) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_multiple_atom " + "n_items %d", n_items)); + /* todo */ + g_free(xdata); + } + } + else if ((lxev->target == XA_STRING) || (lxev->target == g_utf8_atom)) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: %s", + XGetAtomName(g_display, lxev->target))); + clipboard_format_id = CB_FORMAT_UNICODETEXT; + + if (g_data_in_up_to_date) + { + return clipboard_provide_selection(lxev, lxev->target, 8, + g_data_in, g_strlen(g_data_in)); + } + + if (g_selection_request_event_count > 10) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_request: error, " + "too many requests")); + } + else + { + g_memcpy(&(g_selection_request_event[g_selection_request_event_count]), + lxev, sizeof(g_selection_request_event[0])); + + if (g_selection_request_event_count == 0) + { + clipboard_send_data_request(); + g_waiting_for_data_response = 1; + g_waiting_for_data_response_time = xcommon_get_local_time(); + } + + g_selection_request_event_count++; + return 0; + } + } + else if (lxev->target == g_image_bmp_atom) + { + g_memcpy(&g_saved_selection_req_event, lxev, + sizeof(g_saved_selection_req_event)); + g_last_clip_type = g_image_bmp_atom; + g_want_image_data = 1; + clipboard_format_id = CB_FORMAT_DIB; clipboard_send_data_request(); g_waiting_for_data_response = 1; - g_waiting_for_data_response_time = xcommon_get_local_time(); - } - g_selection_request_event_count++; - return 0; + g_waiting_for_data_response_time = clipboard_get_local_time(); + return 0; } - } - else if (lxev->target == g_image_bmp_atom) - { - g_memcpy(&g_saved_selection_req_event, lxev, - sizeof(g_saved_selection_req_event)); - g_last_clip_type = g_image_bmp_atom; - g_want_image_data = 1; - clipboard_format_id = CB_FORMAT_DIB; - clipboard_send_data_request(); - g_waiting_for_data_response = 1; - g_waiting_for_data_response_time = clipboard_get_local_time(); + else + { + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_request: unknown " + "target %s", XGetAtomName(g_display, lxev->target))); + } + + clipboard_refuse_selection(lxev); return 0; - } - else - { - LOGM((LOG_LEVEL_ERROR,"clipboard_event_selection_request: unknown " - "target %s", XGetAtomName(g_display, lxev->target))); - } - clipboard_refuse_selection(lxev); - return 0; } /*****************************************************************************/ @@ -1265,10 +1365,10 @@ clipboard_event_selection_request(XEvent* xevent) Time time; } XSelectionClearEvent; */ static int APP_CC -clipboard_event_selection_clear(XEvent* xevent) +clipboard_event_selection_clear(XEvent *xevent) { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_clear:")); - return 0; + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_clear:")); + return 0; } /*****************************************************************************/ @@ -1284,134 +1384,153 @@ clipboard_event_selection_clear(XEvent* xevent) int state; // PropertyNewValue or PropertyDelete } XPropertyEvent; */ static int APP_CC -clipboard_event_property_notify(XEvent* xevent) +clipboard_event_property_notify(XEvent *xevent) { - Atom actual_type_return; - int actual_format_return; - unsigned long nitems_returned; - unsigned long bytes_left; - unsigned char* data; - int rv; - int format_in_bytes; - int new_data_len; - char* cptr; - char format_name[32]; - - LOG(10, ("clipboard_check_wait_objs: PropertyNotify .window %d " - ".state %d .atom %d", xevent->xproperty.window, - xevent->xproperty.state, xevent->xproperty.atom)); - if (g_incr_in_progress && - (xevent->xproperty.atom == g_incr_atom_type) && - (xevent->xproperty.state == PropertyNewValue)) - { - rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, 0, 0, - AnyPropertyType, &actual_type_return, &actual_format_return, - &nitems_returned, &bytes_left, (unsigned char **) &data); - if (data != 0) - { - XFree(data); - data = 0; - } - if (bytes_left <= 0) - { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR done")); - g_memset(format_name, 0, 32); - /* clipboard INCR cycle has completed */ - g_incr_in_progress = 0; - g_last_clip_size = g_incr_data_size; - g_last_clip_data = g_incr_data; - g_incr_data = 0; - g_last_clip_type = g_incr_atom_target; - if (g_incr_atom_target == g_image_bmp_atom) - { - g_snprintf(format_name, 31, "image/bmp"); - clipboard_send_format_announce(CB_FORMAT_DIB, format_name); - } - XDeleteProperty(g_display, g_wnd, g_incr_atom_type); - } - else + Atom actual_type_return; + int actual_format_return; + unsigned long nitems_returned; + unsigned long bytes_left; + unsigned char *data; + int rv; + int format_in_bytes; + int new_data_len; + char *cptr; + char format_name[32]; + + LOG(10, ("clipboard_check_wait_objs: PropertyNotify .window %d " + ".state %d .atom %d", xevent->xproperty.window, + xevent->xproperty.state, xevent->xproperty.atom)); + + if (g_incr_in_progress && + (xevent->xproperty.atom == g_incr_atom_type) && + (xevent->xproperty.state == PropertyNewValue)) { - rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, bytes_left, 0, - AnyPropertyType, &actual_type_return, &actual_format_return, - &nitems_returned, &bytes_left, (unsigned char **) &data); - - format_in_bytes = actual_format_return / 8; - if ((actual_format_return == 32) && (sizeof(long) == 8)) - { - /* on a 64 bit machine, actual_format_return of 32 implies long */ - format_in_bytes = 8; - } - new_data_len = nitems_returned * format_in_bytes; - cptr = (char*)g_malloc(g_incr_data_size + new_data_len, 0); - g_memcpy(cptr, g_incr_data, g_incr_data_size); - g_free(g_incr_data); - if (cptr == NULL) - { - g_incr_data = 0; - /* cannot add any more data */ + rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, 0, 0, + AnyPropertyType, &actual_type_return, &actual_format_return, + &nitems_returned, &bytes_left, (unsigned char **) &data); + if (data != 0) { - XFree(data); + XFree(data); + data = 0; + } + + if (bytes_left <= 0) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR done")); + g_memset(format_name, 0, 32); + /* clipboard INCR cycle has completed */ + g_incr_in_progress = 0; + g_last_clip_size = g_incr_data_size; + g_last_clip_data = g_incr_data; + g_incr_data = 0; + g_last_clip_type = g_incr_atom_target; + + if (g_incr_atom_target == g_image_bmp_atom) + { + g_snprintf(format_name, 31, "image/bmp"); + clipboard_send_format_announce(CB_FORMAT_DIB, format_name); + } + + XDeleteProperty(g_display, g_wnd, g_incr_atom_type); + } + else + { + rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, bytes_left, 0, + AnyPropertyType, &actual_type_return, &actual_format_return, + &nitems_returned, &bytes_left, (unsigned char **) &data); + + format_in_bytes = actual_format_return / 8; + + if ((actual_format_return == 32) && (sizeof(long) == 8)) + { + /* on a 64 bit machine, actual_format_return of 32 implies long */ + format_in_bytes = 8; + } + + new_data_len = nitems_returned * format_in_bytes; + cptr = (char *)g_malloc(g_incr_data_size + new_data_len, 0); + g_memcpy(cptr, g_incr_data, g_incr_data_size); + g_free(g_incr_data); + + if (cptr == NULL) + { + g_incr_data = 0; + + /* cannot add any more data */ + if (data != 0) + { + XFree(data); + } + + XDeleteProperty(g_display, g_wnd, g_incr_atom_type); + return 0; + } + + g_incr_data = cptr; + g_memcpy(g_incr_data + g_incr_data_size, data, new_data_len); + g_incr_data_size += new_data_len; + + if (data) + { + XFree(data); + } + + XDeleteProperty(g_display, g_wnd, g_incr_atom_type); } - XDeleteProperty(g_display, g_wnd, g_incr_atom_type); - return 0; - } - g_incr_data = cptr; - g_memcpy(g_incr_data + g_incr_data_size, data, new_data_len); - g_incr_data_size += new_data_len; - if (data) - { - XFree(data); - } - XDeleteProperty(g_display, g_wnd, g_incr_atom_type); } - } - return 0; + + return 0; } /*****************************************************************************/ /* returns 0, event handled, 1 unhandled */ int APP_CC -clipboard_xevent(void* xevent) +clipboard_xevent(void *xevent) { - XEvent* lxevent; - - if (!g_clip_up) - { - return 1; - } - lxevent = (XEvent*)xevent; - switch (lxevent->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) - { - clipboard_event_selection_owner_notify(lxevent); - break; - } - /* we didn't handle this message */ - return 1; - } - return 0; + XEvent *lxevent; + + if (!g_clip_up) + { + return 1; + } + + lxevent = (XEvent *)xevent; + + switch (lxevent->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) + { + clipboard_event_selection_owner_notify(lxevent); + break; + } + + /* we didn't handle this message */ + return 1; + } + + return 0; } diff --git a/sesman/chansrv/devredir.c b/sesman/chansrv/devredir.c index dd244572..e6407211 100644 --- a/sesman/chansrv/devredir.c +++ b/sesman/chansrv/devredir.c @@ -26,34 +26,34 @@ extern int g_rdpdr_chan_id; /* in chansrv.c */ int APP_CC dev_redir_init(void) { - return 0; + return 0; } /*****************************************************************************/ int APP_CC dev_redir_deinit(void) { - return 0; + return 0; } /*****************************************************************************/ int APP_CC -dev_redir_data_in(struct stream* s, int chan_id, int chan_flags, int length, +dev_redir_data_in(struct stream *s, int chan_id, int chan_flags, int length, int total_length) { - return 0; + return 0; } /*****************************************************************************/ int APP_CC -dev_redir_get_wait_objs(tbus* objs, int* count, int* timeout) +dev_redir_get_wait_objs(tbus *objs, int *count, int *timeout) { - return 0; + return 0; } /*****************************************************************************/ int APP_CC dev_redir_check_wait_objs(void) { - return 0; + return 0; } diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c index 6b47f867..1ea8d73a 100644 --- a/sesman/chansrv/rail.c +++ b/sesman/chansrv/rail.c @@ -31,13 +31,13 @@ extern int g_rail_chan_id; /* in chansrv.c */ extern int g_display_num; /* in chansrv.c */ -extern char* g_exec_name; /* in chansrv.c */ +extern char *g_exec_name; /* in chansrv.c */ extern tbus g_exec_event; /* in chansrv.c */ extern tbus g_exec_mutex; /* in chansrv.c */ extern tbus g_exec_sem; /* in chansrv.c */ -extern Display* g_display; /* in xcommon.c */ -extern Screen* g_screen; /* in xcommon.c */ +extern Display *g_display; /* in xcommon.c */ +extern Screen *g_screen; /* in xcommon.c */ extern Window g_root_window; /* in xcommon.c */ extern Atom g_wm_delete_window_atom; /* in xcommon.c */ extern Atom g_wm_protocols_atom; /* in xcommon.c */ @@ -105,573 +105,597 @@ static int g_rail_running = 1; static int APP_CC is_window_valid_child_of_root(unsigned int window_id) { - int found; - unsigned int i; - unsigned int nchild; - Window r; - Window p; - Window* children; - - found = 0; - XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild); - for (i = 0; i < nchild; i++) - { - if (window_id == children[i]) + int found; + unsigned int i; + unsigned int nchild; + Window r; + Window p; + Window *children; + + found = 0; + XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild); + + for (i = 0; i < nchild; i++) { - found = 1; - break; + if (window_id == children[i]) + { + found = 1; + break; + } } - } - XFree(children); - return found; + + XFree(children); + return found; } /*****************************************************************************/ static int APP_CC rail_send_init(void) { - struct stream* s; - int bytes; - char* size_ptr; - - LOG(10, ("chansrv::rail_send_init:")); - make_stream(s); - init_stream(s, 8182); - out_uint16_le(s, TS_RAIL_ORDER_HANDSHAKE); - size_ptr = s->p; - out_uint16_le(s, 0); /* size, set later */ - out_uint32_le(s, 1); /* build number */ - s_mark_end(s); - bytes = (int)((s->end - s->data) - 4); - size_ptr[0] = bytes; - size_ptr[1] = bytes >> 8; - bytes = (int)(s->end - s->data); - send_channel_data(g_rail_chan_id, s->data, bytes); - free_stream(s); - return 0; + struct stream *s; + int bytes; + char *size_ptr; + + LOG(10, ("chansrv::rail_send_init:")); + make_stream(s); + init_stream(s, 8182); + out_uint16_le(s, TS_RAIL_ORDER_HANDSHAKE); + size_ptr = s->p; + out_uint16_le(s, 0); /* size, set later */ + out_uint32_le(s, 1); /* build number */ + s_mark_end(s); + bytes = (int)((s->end - s->data) - 4); + size_ptr[0] = bytes; + size_ptr[1] = bytes >> 8; + bytes = (int)(s->end - s->data); + send_channel_data(g_rail_chan_id, s->data, bytes); + free_stream(s); + return 0; } /******************************************************************************/ static int DEFAULT_CC -anotherWMRunning(Display* display, XErrorEvent* xe) +anotherWMRunning(Display *display, XErrorEvent *xe) { - g_rail_running = 0; - return -1; + g_rail_running = 0; + return -1; } /******************************************************************************/ static int APP_CC rail_is_another_wm_running(void) { - XErrorHandler old; - - g_rail_running = 1; - old = XSetErrorHandler((XErrorHandler)anotherWMRunning); - XSelectInput(g_display, g_root_window, - PropertyChangeMask | StructureNotifyMask | - SubstructureRedirectMask | ButtonPressMask | - SubstructureNotifyMask | FocusChangeMask | - EnterWindowMask | LeaveWindowMask); - XSync(g_display, 0); - XSetErrorHandler((XErrorHandler)old); - g_rail_up = g_rail_running; - if (!g_rail_up) - { - return 1; - } - return 0; + XErrorHandler old; + + g_rail_running = 1; + old = XSetErrorHandler((XErrorHandler)anotherWMRunning); + XSelectInput(g_display, g_root_window, + PropertyChangeMask | StructureNotifyMask | + SubstructureRedirectMask | ButtonPressMask | + SubstructureNotifyMask | FocusChangeMask | + EnterWindowMask | LeaveWindowMask); + XSync(g_display, 0); + XSetErrorHandler((XErrorHandler)old); + g_rail_up = g_rail_running; + + if (!g_rail_up) + { + return 1; + } + + return 0; } /*****************************************************************************/ int APP_CC rail_init(void) { - LOG(10, ("chansrv::rail_init:")); - xcommon_init(); - if (rail_is_another_wm_running()) - { - log_message(LOG_LEVEL_ERROR, "rail_init: another window manager " - "is running"); - } - rail_send_init(); - g_rail_up = 1; - return 0; + LOG(10, ("chansrv::rail_init:")); + xcommon_init(); + + if (rail_is_another_wm_running()) + { + log_message(LOG_LEVEL_ERROR, "rail_init: another window manager " + "is running"); + } + + rail_send_init(); + g_rail_up = 1; + return 0; } /*****************************************************************************/ int APP_CC rail_deinit(void) { - if (g_rail_up) - { - /* no longer window manager */ - XSelectInput(g_display, g_root_window, 0); - g_rail_up = 0; - } - return 0; + if (g_rail_up) + { + /* no longer window manager */ + XSelectInput(g_display, g_root_window, 0); + g_rail_up = 0; + } + + return 0; } /*****************************************************************************/ -static char* APP_CC -read_uni(struct stream* s, int num_chars) +static char *APP_CC +read_uni(struct stream *s, int num_chars) { - twchar* rchrs; - char* rv; - int index; - int lchars; - - rchrs = 0; - rv = 0; - if (num_chars > 0) - { - rchrs = (twchar*)g_malloc((num_chars + 1) * sizeof(twchar), 0); - for (index = 0; index < num_chars; index++) - { - in_uint16_le(s, rchrs[index]); - } - rchrs[num_chars] = 0; - lchars = g_wcstombs(0, rchrs, 0); - if (lchars > 0) + twchar *rchrs; + char *rv; + int index; + int lchars; + + rchrs = 0; + rv = 0; + + if (num_chars > 0) { - rv = (char*)g_malloc((lchars + 1) * 4, 0); - g_wcstombs(rv, rchrs, lchars); - rv[lchars] = 0; + rchrs = (twchar *)g_malloc((num_chars + 1) * sizeof(twchar), 0); + + for (index = 0; index < num_chars; index++) + { + in_uint16_le(s, rchrs[index]); + } + + rchrs[num_chars] = 0; + lchars = g_wcstombs(0, rchrs, 0); + + if (lchars > 0) + { + rv = (char *)g_malloc((lchars + 1) * 4, 0); + g_wcstombs(rv, rchrs, lchars); + rv[lchars] = 0; + } } - } - g_free(rchrs); - return rv; + + g_free(rchrs); + return rv; } /*****************************************************************************/ static int APP_CC -rail_process_exec(struct stream* s, int size) +rail_process_exec(struct stream *s, int size) { - int pid; - int flags; - int ExeOrFileLength; - int WorkingDirLength; - int ArgumentsLen; - char* ExeOrFile; - char* WorkingDir; - char* Arguments; - - LOG(0, ("chansrv::rail_process_exec:")); - in_uint16_le(s, flags); - in_uint16_le(s, ExeOrFileLength); - in_uint16_le(s, WorkingDirLength); - in_uint16_le(s, ArgumentsLen); - ExeOrFile = read_uni(s, ExeOrFileLength); - WorkingDir = read_uni(s, WorkingDirLength); - Arguments = read_uni(s, ArgumentsLen); - LOG(10, (" flags 0x%8.8x ExeOrFileLength %d WorkingDirLength %d " - "ArgumentsLen %d ExeOrFile [%s] WorkingDir [%s] " - "Arguments [%s]", flags, ExeOrFileLength, WorkingDirLength, - ArgumentsLen, ExeOrFile, WorkingDir, Arguments)); - if (g_strlen(ExeOrFile) > 0) - { - LOG(10, ("rail_process_exec: pre")); - /* ask main thread to fork */ - tc_mutex_lock(g_exec_mutex); - g_exec_name = ExeOrFile; - g_set_wait_obj(g_exec_event); - tc_sem_dec(g_exec_sem); - tc_mutex_unlock(g_exec_mutex); - LOG(10, ("rail_process_exec: post")); - } - g_free(ExeOrFile); - g_free(WorkingDir); - g_free(Arguments); - return 0; + int pid; + int flags; + int ExeOrFileLength; + int WorkingDirLength; + int ArgumentsLen; + char *ExeOrFile; + char *WorkingDir; + char *Arguments; + + LOG(0, ("chansrv::rail_process_exec:")); + in_uint16_le(s, flags); + in_uint16_le(s, ExeOrFileLength); + in_uint16_le(s, WorkingDirLength); + in_uint16_le(s, ArgumentsLen); + ExeOrFile = read_uni(s, ExeOrFileLength); + WorkingDir = read_uni(s, WorkingDirLength); + Arguments = read_uni(s, ArgumentsLen); + LOG(10, (" flags 0x%8.8x ExeOrFileLength %d WorkingDirLength %d " + "ArgumentsLen %d ExeOrFile [%s] WorkingDir [%s] " + "Arguments [%s]", flags, ExeOrFileLength, WorkingDirLength, + ArgumentsLen, ExeOrFile, WorkingDir, Arguments)); + + if (g_strlen(ExeOrFile) > 0) + { + LOG(10, ("rail_process_exec: pre")); + /* ask main thread to fork */ + tc_mutex_lock(g_exec_mutex); + g_exec_name = ExeOrFile; + g_set_wait_obj(g_exec_event); + tc_sem_dec(g_exec_sem); + tc_mutex_unlock(g_exec_mutex); + LOG(10, ("rail_process_exec: post")); + } + + g_free(ExeOrFile); + g_free(WorkingDir); + g_free(Arguments); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_activate(struct stream* s, int size) +rail_process_activate(struct stream *s, int size) { - int window_id; - int enabled; - - LOG(10, ("chansrv::rail_process_activate:")); - in_uint32_le(s, window_id); - in_uint8(s, enabled); - LOG(10, (" window_id 0x%8.8x enabled %d", window_id, enabled)); - if (enabled) - { - LOG(10, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id)); - XRaiseWindow(g_display, window_id); - LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id)); - XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime); - } - return 0; + int window_id; + int enabled; + + LOG(10, ("chansrv::rail_process_activate:")); + in_uint32_le(s, window_id); + in_uint8(s, enabled); + LOG(10, (" window_id 0x%8.8x enabled %d", window_id, enabled)); + + if (enabled) + { + LOG(10, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id)); + XRaiseWindow(g_display, window_id); + LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id)); + XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime); + } + + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_system_param(struct stream* s, int size) +rail_process_system_param(struct stream *s, int size) { - int system_param; + int system_param; - LOG(10, ("chansrv::rail_process_system_param:")); - in_uint32_le(s, system_param); - LOG(10, (" system_param 0x%8.8x", system_param)); - return 0; + LOG(10, ("chansrv::rail_process_system_param:")); + in_uint32_le(s, system_param); + LOG(10, (" system_param 0x%8.8x", system_param)); + return 0; } /******************************************************************************/ static int APP_CC rail_close_window(int window_id) { - XEvent ce; - - LOG(0, ("chansrv::rail_close_window:")); - g_memset(&ce, 0, sizeof(ce)); - ce.xclient.type = ClientMessage; - ce.xclient.message_type = g_wm_protocols_atom; - ce.xclient.display = g_display; - ce.xclient.window = window_id; - ce.xclient.format = 32; - ce.xclient.data.l[0] = g_wm_delete_window_atom; - ce.xclient.data.l[1] = CurrentTime; - XSendEvent(g_display, window_id, False, NoEventMask, &ce); - return 0; + XEvent ce; + + LOG(0, ("chansrv::rail_close_window:")); + g_memset(&ce, 0, sizeof(ce)); + ce.xclient.type = ClientMessage; + ce.xclient.message_type = g_wm_protocols_atom; + ce.xclient.display = g_display; + ce.xclient.window = window_id; + ce.xclient.format = 32; + ce.xclient.data.l[0] = g_wm_delete_window_atom; + ce.xclient.data.l[1] = CurrentTime; + XSendEvent(g_display, window_id, False, NoEventMask, &ce); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_system_command(struct stream* s, int size) +rail_process_system_command(struct stream *s, int size) { - int window_id; - int command; - - LOG(10, ("chansrv::rail_process_system_command:")); - in_uint32_le(s, window_id); - in_uint16_le(s, command); - switch (command) - { - case SC_SIZE: - LOG(10, (" window_id 0x%8.8x SC_SIZE", window_id)); - break; - case SC_MOVE: - LOG(10, (" window_id 0x%8.8x SC_MOVE", window_id)); - break; - case SC_MINIMIZE: - LOG(10, (" window_id 0x%8.8x SC_MINIMIZE", window_id)); - break; - case SC_MAXIMIZE: - LOG(10, (" window_id 0x%8.8x SC_MAXIMIZE", window_id)); - break; - case SC_CLOSE: - LOG(10, (" window_id 0x%8.8x SC_CLOSE", window_id)); - rail_close_window(window_id); - break; - case SC_KEYMENU: - LOG(10, (" window_id 0x%8.8x SC_KEYMENU", window_id)); - break; - case SC_RESTORE: - LOG(10, (" window_id 0x%8.8x SC_RESTORE", window_id)); - break; - case SC_DEFAULT: - LOG(10, (" window_id 0x%8.8x SC_DEFAULT", window_id)); - break; - default: - LOG(10, (" window_id 0x%8.8x unknown command command %d", - window_id, command)); - break; - } - return 0; + int window_id; + int command; + + LOG(10, ("chansrv::rail_process_system_command:")); + in_uint32_le(s, window_id); + in_uint16_le(s, command); + + switch (command) + { + case SC_SIZE: + LOG(10, (" window_id 0x%8.8x SC_SIZE", window_id)); + break; + case SC_MOVE: + LOG(10, (" window_id 0x%8.8x SC_MOVE", window_id)); + break; + case SC_MINIMIZE: + LOG(10, (" window_id 0x%8.8x SC_MINIMIZE", window_id)); + break; + case SC_MAXIMIZE: + LOG(10, (" window_id 0x%8.8x SC_MAXIMIZE", window_id)); + break; + case SC_CLOSE: + LOG(10, (" window_id 0x%8.8x SC_CLOSE", window_id)); + rail_close_window(window_id); + break; + case SC_KEYMENU: + LOG(10, (" window_id 0x%8.8x SC_KEYMENU", window_id)); + break; + case SC_RESTORE: + LOG(10, (" window_id 0x%8.8x SC_RESTORE", window_id)); + break; + case SC_DEFAULT: + LOG(10, (" window_id 0x%8.8x SC_DEFAULT", window_id)); + break; + default: + LOG(10, (" window_id 0x%8.8x unknown command command %d", + window_id, command)); + break; + } + + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_handshake(struct stream* s, int size) +rail_process_handshake(struct stream *s, int size) { - int build_number; + int build_number; - LOG(10, ("chansrv::rail_process_handshake:")); - in_uint32_le(s, build_number); - LOG(10, (" build_number 0x%8.8x", build_number)); - return 0; + LOG(10, ("chansrv::rail_process_handshake:")); + in_uint32_le(s, build_number); + LOG(10, (" build_number 0x%8.8x", build_number)); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_notify_event(struct stream* s, int size) +rail_process_notify_event(struct stream *s, int size) { - int window_id; - int notify_id; - int message; - - LOG(10, ("chansrv::rail_process_notify_event:")); - in_uint32_le(s, window_id); - in_uint32_le(s, notify_id); - in_uint32_le(s, message); - LOG(10, (" window_id 0x%8.8x notify_id 0x%8.8x message 0x%8.8x", - window_id, notify_id, message)); - return 0; + int window_id; + int notify_id; + int message; + + LOG(10, ("chansrv::rail_process_notify_event:")); + in_uint32_le(s, window_id); + in_uint32_le(s, notify_id); + in_uint32_le(s, message); + LOG(10, (" window_id 0x%8.8x notify_id 0x%8.8x message 0x%8.8x", + window_id, notify_id, message)); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_window_move(struct stream* s, int size) +rail_process_window_move(struct stream *s, int size) { - int window_id; - int left; - int top; - int right; - int bottom; - - LOG(10, ("chansrv::rail_process_window_move:")); - in_uint32_le(s, window_id); - in_uint16_le(s, left); - in_uint16_le(s, top); - in_uint16_le(s, right); - in_uint16_le(s, bottom); - LOG(10, (" window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d", - window_id, left, top, right, bottom, right - left, bottom - top)); - XMoveResizeWindow(g_display, window_id, left, top, right - left, bottom - top); - return 0; + int window_id; + int left; + int top; + int right; + int bottom; + + LOG(10, ("chansrv::rail_process_window_move:")); + in_uint32_le(s, window_id); + in_uint16_le(s, left); + in_uint16_le(s, top); + in_uint16_le(s, right); + in_uint16_le(s, bottom); + LOG(10, (" window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d", + window_id, left, top, right, bottom, right - left, bottom - top)); + XMoveResizeWindow(g_display, window_id, left, top, right - left, bottom - top); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_local_move_size(struct stream* s, int size) +rail_process_local_move_size(struct stream *s, int size) { - int window_id; - int is_move_size_start; - int move_size_type; - int pos_x; - int pos_y; - - LOG(10, ("chansrv::rail_process_local_move_size:")); - in_uint32_le(s, window_id); - in_uint16_le(s, is_move_size_start); - in_uint16_le(s, move_size_type); - in_uint16_le(s, pos_x); - in_uint16_le(s, pos_y); - LOG(10, (" window_id 0x%8.8x is_move_size_start %d move_size_type %d " - "pos_x %d pos_y %d", window_id, is_move_size_start, move_size_type, - pos_x, pos_y)); - return 0; + int window_id; + int is_move_size_start; + int move_size_type; + int pos_x; + int pos_y; + + LOG(10, ("chansrv::rail_process_local_move_size:")); + in_uint32_le(s, window_id); + in_uint16_le(s, is_move_size_start); + in_uint16_le(s, move_size_type); + in_uint16_le(s, pos_x); + in_uint16_le(s, pos_y); + LOG(10, (" window_id 0x%8.8x is_move_size_start %d move_size_type %d " + "pos_x %d pos_y %d", window_id, is_move_size_start, move_size_type, + pos_x, pos_y)); + return 0; } /*****************************************************************************/ /* server to client only */ static int APP_CC -rail_process_min_max_info(struct stream* s, int size) +rail_process_min_max_info(struct stream *s, int size) { - LOG(10, ("chansrv::rail_process_min_max_info:")); - return 0; + LOG(10, ("chansrv::rail_process_min_max_info:")); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_client_status(struct stream* s, int size) +rail_process_client_status(struct stream *s, int size) { - int flags; + int flags; - LOG(10, ("chansrv::rail_process_client_status:")); - in_uint32_le(s, flags); - LOG(10, (" flags 0x%8.8x", flags)); - return 0; + LOG(10, ("chansrv::rail_process_client_status:")); + in_uint32_le(s, flags); + LOG(10, (" flags 0x%8.8x", flags)); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_sys_menu(struct stream* s, int size) +rail_process_sys_menu(struct stream *s, int size) { - int window_id; - int left; - int top; - - LOG(10, ("chansrv::rail_process_sys_menu:")); - in_uint32_le(s, window_id); - in_uint16_le(s, left); - in_uint16_le(s, top); - LOG(10, (" window_id 0x%8.8x left %d top %d", window_id, left, top)); - return 0; + int window_id; + int left; + int top; + + LOG(10, ("chansrv::rail_process_sys_menu:")); + in_uint32_le(s, window_id); + in_uint16_le(s, left); + in_uint16_le(s, top); + LOG(10, (" window_id 0x%8.8x left %d top %d", window_id, left, top)); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_lang_bar_info(struct stream* s, int size) +rail_process_lang_bar_info(struct stream *s, int size) { - int language_bar_status; + int language_bar_status; - LOG(10, ("chansrv::rail_process_lang_bar_info:")); - in_uint32_le(s, language_bar_status); - LOG(10, (" language_bar_status 0x%8.8x", language_bar_status)); - return 0; + LOG(10, ("chansrv::rail_process_lang_bar_info:")); + in_uint32_le(s, language_bar_status); + LOG(10, (" language_bar_status 0x%8.8x", language_bar_status)); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_appid_req(struct stream* s, int size) +rail_process_appid_req(struct stream *s, int size) { - LOG(10, ("chansrv::rail_process_appid_req:")); - return 0; + LOG(10, ("chansrv::rail_process_appid_req:")); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_appid_resp(struct stream* s, int size) +rail_process_appid_resp(struct stream *s, int size) { - LOG(10, ("chansrv::rail_process_appid_resp:")); - return 0; + LOG(10, ("chansrv::rail_process_appid_resp:")); + return 0; } /*****************************************************************************/ /* server to client only */ static int APP_CC -rail_process_exec_result(struct stream* s, int size) +rail_process_exec_result(struct stream *s, int size) { - LOG(10, ("chansrv::rail_process_exec_result:")); - return 0; + LOG(10, ("chansrv::rail_process_exec_result:")); + 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, +rail_data_in(struct stream *s, int chan_id, int chan_flags, int length, int total_length) { - int code; - int size; - - LOG(10, ("chansrv::rail_data_in:")); - in_uint8(s, code); - in_uint8s(s, 1); - in_uint16_le(s, size); - switch (code) - { - case TS_RAIL_ORDER_EXEC: /* 1 */ - rail_process_exec(s, size); - break; - case TS_RAIL_ORDER_ACTIVATE: /* 2 */ - rail_process_activate(s, size); - break; - case TS_RAIL_ORDER_SYSPARAM: /* 3 */ - rail_process_system_param(s, size); - break; - case TS_RAIL_ORDER_SYSCOMMAND: /* 4 */ - rail_process_system_command(s, size); - break; - case TS_RAIL_ORDER_HANDSHAKE: /* 5 */ - rail_process_handshake(s, size); - break; - case TS_RAIL_ORDER_NOTIFY_EVENT: /* 6 */ - rail_process_notify_event(s, size); - break; - case TS_RAIL_ORDER_WINDOWMOVE: /* 8 */ - rail_process_window_move(s, size); - break; - case TS_RAIL_ORDER_LOCALMOVESIZE: /* 9 */ - rail_process_local_move_size(s, size); - break; - case TS_RAIL_ORDER_MINMAXINFO: /* 10 */ - rail_process_min_max_info(s, size); - break; - case TS_RAIL_ORDER_CLIENTSTATUS: /* 11 */ - rail_process_client_status(s, size); - break; - case TS_RAIL_ORDER_SYSMENU: /* 12 */ - rail_process_sys_menu(s, size); - break; - case TS_RAIL_ORDER_LANGBARINFO: /* 13 */ - rail_process_lang_bar_info(s, size); - break; - case TS_RAIL_ORDER_GET_APPID_REQ: /* 14 */ - rail_process_appid_req(s, size); - break; - case TS_RAIL_ORDER_GET_APPID_RESP: /* 15 */ - rail_process_appid_resp(s, size); - break; - case TS_RAIL_ORDER_EXEC_RESULT: /* 128 */ - rail_process_exec_result(s, size); - break; - default: - LOG(10, ("rail_data_in: unknown code %d size %d", code, size)); - break; - } - XFlush(g_display); - return 0; + int code; + int size; + + LOG(10, ("chansrv::rail_data_in:")); + in_uint8(s, code); + in_uint8s(s, 1); + in_uint16_le(s, size); + + switch (code) + { + case TS_RAIL_ORDER_EXEC: /* 1 */ + rail_process_exec(s, size); + break; + case TS_RAIL_ORDER_ACTIVATE: /* 2 */ + rail_process_activate(s, size); + break; + case TS_RAIL_ORDER_SYSPARAM: /* 3 */ + rail_process_system_param(s, size); + break; + case TS_RAIL_ORDER_SYSCOMMAND: /* 4 */ + rail_process_system_command(s, size); + break; + case TS_RAIL_ORDER_HANDSHAKE: /* 5 */ + rail_process_handshake(s, size); + break; + case TS_RAIL_ORDER_NOTIFY_EVENT: /* 6 */ + rail_process_notify_event(s, size); + break; + case TS_RAIL_ORDER_WINDOWMOVE: /* 8 */ + rail_process_window_move(s, size); + break; + case TS_RAIL_ORDER_LOCALMOVESIZE: /* 9 */ + rail_process_local_move_size(s, size); + break; + case TS_RAIL_ORDER_MINMAXINFO: /* 10 */ + rail_process_min_max_info(s, size); + break; + case TS_RAIL_ORDER_CLIENTSTATUS: /* 11 */ + rail_process_client_status(s, size); + break; + case TS_RAIL_ORDER_SYSMENU: /* 12 */ + rail_process_sys_menu(s, size); + break; + case TS_RAIL_ORDER_LANGBARINFO: /* 13 */ + rail_process_lang_bar_info(s, size); + break; + case TS_RAIL_ORDER_GET_APPID_REQ: /* 14 */ + rail_process_appid_req(s, size); + break; + case TS_RAIL_ORDER_GET_APPID_RESP: /* 15 */ + rail_process_appid_resp(s, size); + break; + case TS_RAIL_ORDER_EXEC_RESULT: /* 128 */ + rail_process_exec_result(s, size); + break; + default: + LOG(10, ("rail_data_in: unknown code %d size %d", code, size)); + break; + } + + XFlush(g_display); + return 0; } /*****************************************************************************/ /* returns 0, event handled, 1 unhandled */ int APP_CC -rail_xevent(void* xevent) +rail_xevent(void *xevent) { - XEvent* lxevent; - XWindowChanges xwc; - int rv; - int nchildren_return = 0; - Window root_return; - Window parent_return; - Window *children_return; - Window wreturn; - int revert_to; - XWindowAttributes wnd_attributes; - - LOG(10, ("chansrv::rail_xevent:")); - if (!g_rail_up) - { - return 1; - } - rv = 1; - lxevent = (XEvent*)xevent; - switch (lxevent->type) - { - case ConfigureRequest: - LOG(10, (" got ConfigureRequest window_id 0x%8.8x", lxevent->xconfigurerequest.window)); - g_memset(&xwc, 0, sizeof(xwc)); - xwc.x = lxevent->xconfigurerequest.x; - xwc.y = lxevent->xconfigurerequest.y; - xwc.width = lxevent->xconfigurerequest.width; - xwc.height = lxevent->xconfigurerequest.height; - xwc.border_width = lxevent->xconfigurerequest.border_width; - xwc.sibling = lxevent->xconfigurerequest.above; - xwc.stack_mode = lxevent->xconfigurerequest.detail; - XConfigureWindow(g_display, - lxevent->xconfigurerequest.window, - lxevent->xconfigurerequest.value_mask, - &xwc); - rv = 0; - break; - - case MapRequest: - LOG(10, (" got MapRequest")); - XMapWindow(g_display, lxevent->xmaprequest.window); - rv = 0; - break; - - case MapNotify: - LOG(10, (" got MapNotify")); - break; - - case UnmapNotify: - LOG(10, (" got UnmapNotify")); - break; - - case ConfigureNotify: - LOG(10, (" got ConfigureNotify")); - break; - - case FocusIn: - LOG(10, (" got FocusIn")); - break; - - case ButtonPress: - LOG(10, (" got ButtonPress")); - break; - - case EnterNotify: - LOG(10, (" got EnterNotify")); - break; - - case LeaveNotify: - LOG(10, (" got LeaveNotify")); - break; - - } - return rv; + XEvent *lxevent; + XWindowChanges xwc; + int rv; + int nchildren_return = 0; + Window root_return; + Window parent_return; + Window *children_return; + Window wreturn; + int revert_to; + XWindowAttributes wnd_attributes; + + LOG(10, ("chansrv::rail_xevent:")); + + if (!g_rail_up) + { + return 1; + } + + rv = 1; + lxevent = (XEvent *)xevent; + + switch (lxevent->type) + { + case ConfigureRequest: + LOG(10, (" got ConfigureRequest window_id 0x%8.8x", lxevent->xconfigurerequest.window)); + g_memset(&xwc, 0, sizeof(xwc)); + xwc.x = lxevent->xconfigurerequest.x; + xwc.y = lxevent->xconfigurerequest.y; + xwc.width = lxevent->xconfigurerequest.width; + xwc.height = lxevent->xconfigurerequest.height; + xwc.border_width = lxevent->xconfigurerequest.border_width; + xwc.sibling = lxevent->xconfigurerequest.above; + xwc.stack_mode = lxevent->xconfigurerequest.detail; + XConfigureWindow(g_display, + lxevent->xconfigurerequest.window, + lxevent->xconfigurerequest.value_mask, + &xwc); + rv = 0; + break; + + case MapRequest: + LOG(10, (" got MapRequest")); + XMapWindow(g_display, lxevent->xmaprequest.window); + rv = 0; + break; + + case MapNotify: + LOG(10, (" got MapNotify")); + break; + + case UnmapNotify: + LOG(10, (" got UnmapNotify")); + break; + + case ConfigureNotify: + LOG(10, (" got ConfigureNotify")); + break; + + case FocusIn: + LOG(10, (" got FocusIn")); + break; + + case ButtonPress: + LOG(10, (" got ButtonPress")); + break; + + case EnterNotify: + LOG(10, (" got EnterNotify")); + break; + + case LeaveNotify: + LOG(10, (" got LeaveNotify")); + break; + + } + + return rv; } diff --git a/sesman/chansrv/sound.c b/sesman/chansrv/sound.c index e4d54bb0..e8b801c6 100644 --- a/sesman/chansrv/sound.c +++ b/sesman/chansrv/sound.c @@ -28,100 +28,100 @@ static int g_training_sent_time = 0; static int g_cBlockNo = 0; #if defined(XRDP_SIMPLESOUND) -static void* DEFAULT_CC -read_raw_audio_data(void* arg); +static void *DEFAULT_CC +read_raw_audio_data(void *arg); #endif /*****************************************************************************/ static int APP_CC sound_send_server_formats(void) { - struct stream* s; - int bytes; - char* size_ptr; - - print_got_here(); - - make_stream(s); - init_stream(s, 8182); - out_uint16_le(s, SNDC_FORMATS); - size_ptr = s->p; - out_uint16_le(s, 0); /* size, set later */ - out_uint32_le(s, 0); /* dwFlags */ - out_uint32_le(s, 0); /* dwVolume */ - out_uint32_le(s, 0); /* dwPitch */ - out_uint16_le(s, 0); /* wDGramPort */ - out_uint16_le(s, 1); /* wNumberOfFormats */ - out_uint8(s, g_cBlockNo); /* cLastBlockConfirmed */ - out_uint16_le(s, 2); /* wVersion */ - out_uint8(s, 0); /* bPad */ - - /* sndFormats */ - /* - wFormatTag 2 byte offset 0 - nChannels 2 byte offset 2 - nSamplesPerSec 4 byte offset 4 - nAvgBytesPerSec 4 byte offset 8 - nBlockAlign 2 byte offset 12 - wBitsPerSample 2 byte offset 14 - cbSize 2 byte offset 16 - data variable offset 18 - */ - - /* examples - 01 00 02 00 44 ac 00 00 10 b1 02 00 04 00 10 00 ....D........... - 00 00 - 01 00 02 00 22 56 00 00 88 58 01 00 04 00 10 00 ...."V...X...... - 00 00 - */ - - out_uint16_le(s, 1); // wFormatTag - WAVE_FORMAT_PCM - out_uint16_le(s, 2); // num of channels - out_uint32_le(s, 44100); // samples per sec - out_uint32_le(s, 176400); // avg bytes per sec - out_uint16_le(s, 4); // block align - out_uint16_le(s, 16); // bits per sample - out_uint16_le(s, 0); // size - - s_mark_end(s); - bytes = (int)((s->end - s->data) - 4); - size_ptr[0] = bytes; - size_ptr[1] = bytes >> 8; - bytes = (int)(s->end - s->data); - send_channel_data(g_rdpsnd_chan_id, s->data, bytes); - free_stream(s); - return 0; + struct stream *s; + int bytes; + char *size_ptr; + + print_got_here(); + + make_stream(s); + init_stream(s, 8182); + out_uint16_le(s, SNDC_FORMATS); + size_ptr = s->p; + out_uint16_le(s, 0); /* size, set later */ + out_uint32_le(s, 0); /* dwFlags */ + out_uint32_le(s, 0); /* dwVolume */ + out_uint32_le(s, 0); /* dwPitch */ + out_uint16_le(s, 0); /* wDGramPort */ + out_uint16_le(s, 1); /* wNumberOfFormats */ + out_uint8(s, g_cBlockNo); /* cLastBlockConfirmed */ + out_uint16_le(s, 2); /* wVersion */ + out_uint8(s, 0); /* bPad */ + + /* sndFormats */ + /* + wFormatTag 2 byte offset 0 + nChannels 2 byte offset 2 + nSamplesPerSec 4 byte offset 4 + nAvgBytesPerSec 4 byte offset 8 + nBlockAlign 2 byte offset 12 + wBitsPerSample 2 byte offset 14 + cbSize 2 byte offset 16 + data variable offset 18 + */ + + /* examples + 01 00 02 00 44 ac 00 00 10 b1 02 00 04 00 10 00 ....D........... + 00 00 + 01 00 02 00 22 56 00 00 88 58 01 00 04 00 10 00 ...."V...X...... + 00 00 + */ + + out_uint16_le(s, 1); // wFormatTag - WAVE_FORMAT_PCM + out_uint16_le(s, 2); // num of channels + out_uint32_le(s, 44100); // samples per sec + out_uint32_le(s, 176400); // avg bytes per sec + out_uint16_le(s, 4); // block align + out_uint16_le(s, 16); // bits per sample + out_uint16_le(s, 0); // size + + s_mark_end(s); + bytes = (int)((s->end - s->data) - 4); + size_ptr[0] = bytes; + size_ptr[1] = bytes >> 8; + bytes = (int)(s->end - s->data); + send_channel_data(g_rdpsnd_chan_id, s->data, bytes); + free_stream(s); + return 0; } /*****************************************************************************/ static int sound_send_training(void) { - struct stream* s; - int bytes; - int time; - char* size_ptr; - - print_got_here(); - - make_stream(s); - init_stream(s, 8182); - out_uint16_le(s, SNDC_TRAINING); - size_ptr = s->p; - out_uint16_le(s, 0); /* size, set later */ - time = g_time2(); - g_training_sent_time = time; - out_uint16_le(s, time); - out_uint16_le(s, 1024); - out_uint8s(s, (1024 - 4)); - s_mark_end(s); - bytes = (int)((s->end - s->data) - 4); - size_ptr[0] = bytes; - size_ptr[1] = bytes >> 8; - bytes = (int)(s->end - s->data); - send_channel_data(g_rdpsnd_chan_id, s->data, bytes); - free_stream(s); - return 0; + struct stream *s; + int bytes; + int time; + char *size_ptr; + + print_got_here(); + + make_stream(s); + init_stream(s, 8182); + out_uint16_le(s, SNDC_TRAINING); + size_ptr = s->p; + out_uint16_le(s, 0); /* size, set later */ + time = g_time2(); + g_training_sent_time = time; + out_uint16_le(s, time); + out_uint16_le(s, 1024); + out_uint8s(s, (1024 - 4)); + s_mark_end(s); + bytes = (int)((s->end - s->data) - 4); + size_ptr[0] = bytes; + size_ptr[1] = bytes >> 8; + bytes = (int)(s->end - s->data); + send_channel_data(g_rdpsnd_chan_id, s->data, bytes); + free_stream(s); + return 0; } /*****************************************************************************/ @@ -132,318 +132,339 @@ sound_send_training(void) */ static int APP_CC -sound_process_formats(struct stream* s, int size) +sound_process_formats(struct stream *s, int size) { - int num_formats; - - print_got_here(); - - LOG(0, ("sound_process_formats:")); - if (size < 16) - { - return 1; - } - in_uint8s(s, 14); - in_uint16_le(s, num_formats); - if (num_formats > 0) - { - sound_send_training(); - } - return 0; + int num_formats; + + print_got_here(); + + LOG(0, ("sound_process_formats:")); + + if (size < 16) + { + return 1; + } + + in_uint8s(s, 14); + in_uint16_le(s, num_formats); + + if (num_formats > 0) + { + sound_send_training(); + } + + return 0; } /*****************************************************************************/ static int -sound_send_wave_data(char* data, int data_bytes) +sound_send_wave_data(char *data, int data_bytes) { - struct stream* s; - int bytes; - int time; - char* size_ptr; - - print_got_here(); - - if ((data_bytes < 4) || (data_bytes > 32 * 1024)) - { - LOG(0, ("sound_send_wave_data: bad data_bytes %d", data_bytes)); - } - - /* part one of 2 PDU wave info */ - - LOG(10, ("sound_send_wave_data: sending %d bytes", data_bytes)); - - make_stream(s); - init_stream(s, data_bytes); - out_uint16_le(s, SNDC_WAVE); - size_ptr = s->p; - out_uint16_le(s, 0); /* size, set later */ - time = g_time2(); - out_uint16_le(s, time); - out_uint16_le(s, 0); /* wFormatNo */ - g_cBlockNo++; - out_uint8(s, g_cBlockNo); - - LOG(10, ("sound_send_wave_data: sending time %d, g_cBlockNo %d", - time & 0xffff, g_cBlockNo & 0xff)); - - out_uint8s(s, 3); - out_uint8a(s, data, 4); - s_mark_end(s); - bytes = (int)((s->end - s->data) - 4); - bytes += data_bytes; - bytes -= 4; - size_ptr[0] = bytes; - size_ptr[1] = bytes >> 8; - bytes = (int)(s->end - s->data); - send_channel_data(g_rdpsnd_chan_id, s->data, bytes); - - /* part two of 2 PDU wave info */ - init_stream(s, data_bytes); - out_uint32_le(s, 0); - out_uint8a(s, data + 4, data_bytes - 4); - s_mark_end(s); - bytes = (int)(s->end - s->data); - send_channel_data(g_rdpsnd_chan_id, s->data, bytes); - free_stream(s); - return 0; + struct stream *s; + int bytes; + int time; + char *size_ptr; + + print_got_here(); + + if ((data_bytes < 4) || (data_bytes > 32 * 1024)) + { + LOG(0, ("sound_send_wave_data: bad data_bytes %d", data_bytes)); + } + + /* part one of 2 PDU wave info */ + + LOG(10, ("sound_send_wave_data: sending %d bytes", data_bytes)); + + make_stream(s); + init_stream(s, data_bytes); + out_uint16_le(s, SNDC_WAVE); + size_ptr = s->p; + out_uint16_le(s, 0); /* size, set later */ + time = g_time2(); + out_uint16_le(s, time); + out_uint16_le(s, 0); /* wFormatNo */ + g_cBlockNo++; + out_uint8(s, g_cBlockNo); + + LOG(10, ("sound_send_wave_data: sending time %d, g_cBlockNo %d", + time & 0xffff, g_cBlockNo & 0xff)); + + out_uint8s(s, 3); + out_uint8a(s, data, 4); + s_mark_end(s); + bytes = (int)((s->end - s->data) - 4); + bytes += data_bytes; + bytes -= 4; + size_ptr[0] = bytes; + size_ptr[1] = bytes >> 8; + bytes = (int)(s->end - s->data); + send_channel_data(g_rdpsnd_chan_id, s->data, bytes); + + /* part two of 2 PDU wave info */ + init_stream(s, data_bytes); + out_uint32_le(s, 0); + out_uint8a(s, data + 4, data_bytes - 4); + s_mark_end(s); + bytes = (int)(s->end - s->data); + send_channel_data(g_rdpsnd_chan_id, s->data, bytes); + free_stream(s); + return 0; } /*****************************************************************************/ static int APP_CC -sound_process_training(struct stream* s, int size) +sound_process_training(struct stream *s, int size) { - int time_diff; + int time_diff; - print_got_here(); + print_got_here(); - time_diff = g_time2() - g_training_sent_time; - LOG(0, ("sound_process_training: round trip time %u", time_diff)); - return 0; + time_diff = g_time2() - g_training_sent_time; + LOG(0, ("sound_process_training: round trip time %u", time_diff)); + return 0; } /*****************************************************************************/ static int APP_CC -sound_process_wave_confirm(struct stream* s, int size) +sound_process_wave_confirm(struct stream *s, int size) { - int wTimeStamp; - int cConfirmedBlockNo; + int wTimeStamp; + int cConfirmedBlockNo; - print_got_here(); + print_got_here(); - in_uint16_le(s, wTimeStamp); - in_uint8(s, cConfirmedBlockNo); + in_uint16_le(s, wTimeStamp); + in_uint8(s, cConfirmedBlockNo); - LOG(10, ("sound_process_wave_confirm: wTimeStamp %d, cConfirmedBlockNo %d", - wTimeStamp, cConfirmedBlockNo)); + LOG(10, ("sound_process_wave_confirm: wTimeStamp %d, cConfirmedBlockNo %d", + wTimeStamp, cConfirmedBlockNo)); - return 0; + return 0; } /*****************************************************************************/ static int APP_CC -process_pcm_message(int id, int size, struct stream* s) +process_pcm_message(int id, int size, struct stream *s) { - print_got_here(); + print_got_here(); - sound_send_wave_data(s->p, size); - return 0; + sound_send_wave_data(s->p, size); + return 0; } /*****************************************************************************/ /* data coming in from audio source, eg pulse, alsa */ static int DEFAULT_CC -sound_trans_audio_data_in(struct trans* trans) +sound_trans_audio_data_in(struct trans *trans) { - struct stream *s; - int id; - int size; - int error; + struct stream *s; + int id; + int size; + int error; - if (trans == 0) - { - return 0; - } - if (trans != g_audio_c_trans) - { - return 1; - } - s = trans_get_in_s(trans); - in_uint32_le(s, id); - in_uint32_le(s, size); - if ((id != 0) || (size > 32 * 1024 + 8) || (size < 1)) - { - LOG(0, ("sound_trans_audio_data_in: bad message id %d size %d", id, size)); - return 1; - } - error = trans_force_read(trans, size - 8); - if (error == 0) - { - /* here, the entire message block is read in, process it */ - error = process_pcm_message(id, size - 8, s); - } - return error; + if (trans == 0) + { + return 0; + } + + if (trans != g_audio_c_trans) + { + return 1; + } + + s = trans_get_in_s(trans); + in_uint32_le(s, id); + in_uint32_le(s, size); + + if ((id != 0) || (size > 32 * 1024 + 8) || (size < 1)) + { + LOG(0, ("sound_trans_audio_data_in: bad message id %d size %d", id, size)); + return 1; + } + + error = trans_force_read(trans, size - 8); + + if (error == 0) + { + /* here, the entire message block is read in, process it */ + error = process_pcm_message(id, size - 8, s); + } + + return error; } /*****************************************************************************/ static int DEFAULT_CC sound_trans_audio_conn_in(struct trans *trans, struct trans *new_trans) { - print_got_here(); - - if (trans == 0) - { - return 1; - } - if (trans != g_audio_l_trans) - { - return 1; - } - if (g_audio_c_trans != 0) /* if already set, error */ - { - return 1; - } - if (new_trans == 0) - { - return 1; - } - g_audio_c_trans = new_trans; - g_audio_c_trans->trans_data_in = sound_trans_audio_data_in; - g_audio_c_trans->header_size = 8; - trans_delete(g_audio_l_trans); - g_audio_l_trans = 0; - return 0; + print_got_here(); + + if (trans == 0) + { + return 1; + } + + if (trans != g_audio_l_trans) + { + return 1; + } + + if (g_audio_c_trans != 0) /* if already set, error */ + { + return 1; + } + + if (new_trans == 0) + { + return 1; + } + + g_audio_c_trans = new_trans; + g_audio_c_trans->trans_data_in = sound_trans_audio_data_in; + g_audio_c_trans->header_size = 8; + trans_delete(g_audio_l_trans); + g_audio_l_trans = 0; + return 0; } /*****************************************************************************/ int APP_CC sound_init(void) { - char port[256]; - int error; - - print_got_here(); - LOG(0, ("sound_init:")); - - sound_send_server_formats(); - g_audio_l_trans = trans_create(2, 33 * 1024, 8192); - g_snprintf(port, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num); - g_audio_l_trans->trans_conn_in = sound_trans_audio_conn_in; - error = trans_listen(g_audio_l_trans, port); - if (error != 0) - { - LOG(0, ("sound_init: trans_listen failed")); - } + char port[256]; + int error; + + print_got_here(); + LOG(0, ("sound_init:")); + + sound_send_server_formats(); + g_audio_l_trans = trans_create(2, 33 * 1024, 8192); + g_snprintf(port, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num); + g_audio_l_trans->trans_conn_in = sound_trans_audio_conn_in; + error = trans_listen(g_audio_l_trans, port); + + if (error != 0) + { + LOG(0, ("sound_init: trans_listen failed")); + } #if defined(XRDP_SIMPLESOUND) - /* start thread to read raw audio data from pulseaudio device */ - tc_thread_create(read_raw_audio_data, 0); + /* start thread to read raw audio data from pulseaudio device */ + tc_thread_create(read_raw_audio_data, 0); #endif - return 0; + return 0; } /*****************************************************************************/ int APP_CC sound_deinit(void) { - print_got_here(); + print_got_here(); - if (g_audio_l_trans != 0) - { - trans_delete(g_audio_l_trans); - g_audio_l_trans = 0; - } - if (g_audio_c_trans != 0) - { - trans_delete(g_audio_c_trans); - g_audio_l_trans = 0; - } + if (g_audio_l_trans != 0) + { + trans_delete(g_audio_l_trans); + g_audio_l_trans = 0; + } - return 0; + if (g_audio_c_trans != 0) + { + trans_delete(g_audio_c_trans); + g_audio_l_trans = 0; + } + + return 0; } /*****************************************************************************/ /* data in from client ( clinet -> xrdp -> chansrv ) */ int APP_CC -sound_data_in(struct stream* s, int chan_id, int chan_flags, int length, +sound_data_in(struct stream *s, int chan_id, int chan_flags, int length, int total_length) { - int code; - int size; - - print_got_here(); - - in_uint8(s, code); - in_uint8s(s, 1); - in_uint16_le(s, size); - switch (code) - { - case SNDC_WAVECONFIRM: - sound_process_wave_confirm(s, size); - break; - - case SNDC_TRAINING: - sound_process_training(s, size); - break; - - case SNDC_FORMATS: - sound_process_formats(s, size); - break; - - default: - LOG(0, ("sound_data_in: unknown code %d size %d", code, size)); - break; - } - return 0; + int code; + int size; + + print_got_here(); + + in_uint8(s, code); + in_uint8s(s, 1); + in_uint16_le(s, size); + + switch (code) + { + case SNDC_WAVECONFIRM: + sound_process_wave_confirm(s, size); + break; + + case SNDC_TRAINING: + sound_process_training(s, size); + break; + + case SNDC_FORMATS: + sound_process_formats(s, size); + break; + + default: + LOG(0, ("sound_data_in: unknown code %d size %d", code, size)); + break; + } + + return 0; } /*****************************************************************************/ int APP_CC -sound_get_wait_objs(tbus* objs, int* count, int* timeout) +sound_get_wait_objs(tbus *objs, int *count, int *timeout) { - int lcount; - - lcount = *count; - if (g_audio_l_trans != 0) - { - objs[lcount] = g_audio_l_trans->sck; - lcount++; - } - if (g_audio_c_trans != 0) - { - objs[lcount] = g_audio_c_trans->sck; - lcount++; - } - *count = lcount; - return 0; + int lcount; + + lcount = *count; + + if (g_audio_l_trans != 0) + { + objs[lcount] = g_audio_l_trans->sck; + lcount++; + } + + if (g_audio_c_trans != 0) + { + objs[lcount] = g_audio_c_trans->sck; + lcount++; + } + + *count = lcount; + return 0; } /*****************************************************************************/ int APP_CC sound_check_wait_objs(void) { - if (g_audio_l_trans != 0) - { - trans_check_wait_objs(g_audio_l_trans); - } + if (g_audio_l_trans != 0) + { + trans_check_wait_objs(g_audio_l_trans); + } - if (g_audio_c_trans != 0) - { - trans_check_wait_objs(g_audio_c_trans); - } + if (g_audio_c_trans != 0) + { + trans_check_wait_objs(g_audio_c_trans); + } - return 0; + return 0; } #if defined(XRDP_SIMPLESOUND) static int DEFAULT_CC -sttrans_data_in(struct trans* self) +sttrans_data_in(struct trans *self) { - LOG(0, ("sttrans_data_in:\n")); - return 0; + LOG(0, ("sttrans_data_in:\n")); + return 0; } /** @@ -451,103 +472,112 @@ sttrans_data_in(struct trans* self) * to a unix domain socket on which trans server is listening */ -static void* DEFAULT_CC -read_raw_audio_data(void* arg) +static void *DEFAULT_CC +read_raw_audio_data(void *arg) { - pa_sample_spec samp_spec; - pa_simple* simple = NULL; - uint32_t bytes_read; - char* cptr; - int i; - int error; - struct trans* strans; - char path[256]; - struct stream* outs; - - strans = trans_create(TRANS_MODE_UNIX, 8192, 8192); - if (strans == 0) - { - LOG(0, ("read_raw_audio_data: trans_create failed\n")); - return 0; - } - strans->trans_data_in = sttrans_data_in; - g_snprintf(path, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num); - if (trans_connect(strans, "", path, 100) != 0) - { - LOG(0, ("read_raw_audio_data: trans_connect failed\n")); - trans_delete(strans); - return 0; - } - - /* setup audio format */ - samp_spec.format = PA_SAMPLE_S16LE; - samp_spec.rate = 44100; - samp_spec.channels = 2; - - /* if we are root, then for first 8 seconds connection to pulseaudo server - fails; if we are non-root, then connection succeeds on first attempt; - for now we have changed code to be non-root, but this may change in the - future - so pretend we are root and try connecting to pulseaudio server - for upto one minute */ - for (i = 0; i < 60; i++) - { - simple = pa_simple_new(NULL, "xrdp", PA_STREAM_RECORD, NULL, - "record", &samp_spec, NULL, NULL, &error); - if (simple) + pa_sample_spec samp_spec; + pa_simple *simple = NULL; + uint32_t bytes_read; + char *cptr; + int i; + int error; + struct trans *strans; + char path[256]; + struct stream *outs; + + strans = trans_create(TRANS_MODE_UNIX, 8192, 8192); + + if (strans == 0) { - /* connected to pulseaudio server */ - LOG(0, ("read_raw_audio_data: connected to pulseaudio server\n")); - break; + LOG(0, ("read_raw_audio_data: trans_create failed\n")); + return 0; } - LOG(0, ("read_raw_audio_data: ERROR creating PulseAudio async interface\n")); - LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error))); - g_sleep(1000); - } - - if (i == 60) - { - /* failed to connect to audio server */ - trans_delete(strans); - return NULL; - } - - /* insert header just once */ - outs = trans_get_out_s(strans, 8192); - out_uint32_le(outs, 0); - out_uint32_le(outs, AUDIO_BUF_SIZE + 8); - cptr = outs->p; - out_uint8s(outs, AUDIO_BUF_SIZE); - s_mark_end(outs); - - while (1) - { - /* read a block of raw audio data... */ - g_memset(cptr, 0, 4); - bytes_read = pa_simple_read(simple, cptr, AUDIO_BUF_SIZE, &error); - if (bytes_read < 0) + + strans->trans_data_in = sttrans_data_in; + g_snprintf(path, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num); + + if (trans_connect(strans, "", path, 100) != 0) { - LOG(0, ("read_raw_audio_data: ERROR reading from pulseaudio stream\n")); - LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error))); - break; + LOG(0, ("read_raw_audio_data: trans_connect failed\n")); + trans_delete(strans); + return 0; } - /* bug workaround: - even when there is no audio data, pulseaudio is returning without - errors but the data itself is zero; we use this zero data to - determine that there is no audio data present */ - if (*cptr == 0 && *(cptr + 1) == 0 && *(cptr + 2) == 0 && *(cptr + 3) == 0) + + /* setup audio format */ + samp_spec.format = PA_SAMPLE_S16LE; + samp_spec.rate = 44100; + samp_spec.channels = 2; + + /* if we are root, then for first 8 seconds connection to pulseaudo server + fails; if we are non-root, then connection succeeds on first attempt; + for now we have changed code to be non-root, but this may change in the + future - so pretend we are root and try connecting to pulseaudio server + for upto one minute */ + for (i = 0; i < 60; i++) { - g_sleep(10); - continue; + simple = pa_simple_new(NULL, "xrdp", PA_STREAM_RECORD, NULL, + "record", &samp_spec, NULL, NULL, &error); + + if (simple) + { + /* connected to pulseaudio server */ + LOG(0, ("read_raw_audio_data: connected to pulseaudio server\n")); + break; + } + + LOG(0, ("read_raw_audio_data: ERROR creating PulseAudio async interface\n")); + LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error))); + g_sleep(1000); } - if (trans_force_write_s(strans, outs) != 0) + + if (i == 60) { - LOG(0, ("read_raw_audio_data: ERROR writing audio data to server\n")); - break; + /* failed to connect to audio server */ + trans_delete(strans); + return NULL; } - } - pa_simple_free(simple); - trans_delete(strans); - return NULL; + + /* insert header just once */ + outs = trans_get_out_s(strans, 8192); + out_uint32_le(outs, 0); + out_uint32_le(outs, AUDIO_BUF_SIZE + 8); + cptr = outs->p; + out_uint8s(outs, AUDIO_BUF_SIZE); + s_mark_end(outs); + + while (1) + { + /* read a block of raw audio data... */ + g_memset(cptr, 0, 4); + bytes_read = pa_simple_read(simple, cptr, AUDIO_BUF_SIZE, &error); + + if (bytes_read < 0) + { + LOG(0, ("read_raw_audio_data: ERROR reading from pulseaudio stream\n")); + LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error))); + break; + } + + /* bug workaround: + even when there is no audio data, pulseaudio is returning without + errors but the data itself is zero; we use this zero data to + determine that there is no audio data present */ + if (*cptr == 0 && *(cptr + 1) == 0 && *(cptr + 2) == 0 && *(cptr + 3) == 0) + { + g_sleep(10); + continue; + } + + if (trans_force_write_s(strans, outs) != 0) + { + LOG(0, ("read_raw_audio_data: ERROR writing audio data to server\n")); + break; + } + } + + pa_simple_free(simple); + trans_delete(strans); + return NULL; } #endif diff --git a/sesman/chansrv/xcommon.c b/sesman/chansrv/xcommon.c index 70b52694..f7f95768 100644 --- a/sesman/chansrv/xcommon.c +++ b/sesman/chansrv/xcommon.c @@ -31,10 +31,10 @@ extern int g_waiting_for_data_response_time; /* in clipboard.c */ extern int g_rail_up; /* in rail.c */ -Display* g_display = 0; +Display *g_display = 0; int g_x_socket = 0; tbus g_x_wait_obj = 0; -Screen* g_screen = 0; +Screen *g_screen = 0; int g_screen_num = 0; Window g_root_window = 0; Atom g_wm_delete_window_atom = 0; @@ -42,15 +42,15 @@ Atom g_wm_protocols_atom = 0; /*****************************************************************************/ static int DEFAULT_CC -xcommon_error_handler(Display* dis, XErrorEvent* xer) +xcommon_error_handler(Display *dis, XErrorEvent *xer) { - char text[256]; + char text[256]; - XGetErrorText(dis, xer->error_code, text, 255); - LOGM((LOG_LEVEL_ERROR, "X error [%s](%d) opcodes %d/%d " - "resource 0x%lx", text, xer->error_code, - xer->request_code, xer->minor_code, xer->resourceid)); - return 0; + XGetErrorText(dis, xer->error_code, text, 255); + LOGM((LOG_LEVEL_ERROR, "X error [%s](%d) opcodes %d/%d " + "resource 0x%lx", text, xer->error_code, + xer->request_code, xer->minor_code, xer->resourceid)); + return 0; } /*****************************************************************************/ @@ -58,9 +58,9 @@ xcommon_error_handler(Display* dis, XErrorEvent* xer) 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) +xcommon_fatal_handler(Display *dis) { - return 0; + return 0; } /*****************************************************************************/ @@ -71,7 +71,7 @@ xcommon_fatal_handler(Display* dis) int APP_CC xcommon_get_local_time(void) { - return g_time3(); + return g_time3(); } /******************************************************************************/ @@ -79,42 +79,45 @@ xcommon_get_local_time(void) int APP_CC xcommon_init(void) { - if (g_display != 0) - { - LOG(10, ("xcommon_init: xcommon_init already called")); + if (g_display != 0) + { + LOG(10, ("xcommon_init: xcommon_init already called")); + return 0; + } + + g_display = XOpenDisplay(0); + + if (g_display == 0) + { + LOGM((LOG_LEVEL_ERROR, "xcommon_init: error, XOpenDisplay failed")); + return 1; + } + + LOG(0, ("xcommon_init: connected to display ok")); + + /* 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) + { + LOGM((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; - } - g_display = XOpenDisplay(0); - if (g_display == 0) - { - LOGM((LOG_LEVEL_ERROR, "xcommon_init: error, XOpenDisplay failed")); - return 1; - } - - LOG(0, ("xcommon_init: connected to display ok")); - - /* 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) - { - LOGM((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; } /*****************************************************************************/ @@ -122,66 +125,73 @@ xcommon_init(void) 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) +xcommon_get_wait_objs(tbus *objs, int *count, int *timeout) { - int lcount; + int lcount; + + if (((!g_clip_up) && (!g_rail_up)) || (objs == 0) || (count == 0)) + { + LOG(10, ("xcommon_get_wait_objs: nothing to do")); + return 0; + } - if (((!g_clip_up) && (!g_rail_up)) || (objs == 0) || (count == 0)) - { - LOG(10, ("xcommon_get_wait_objs: nothing to do")); + lcount = *count; + objs[lcount] = g_x_wait_obj; + lcount++; + *count = lcount; 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)) - { - LOG(10, ("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 */ - LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: sck closed")); - return 0; - } - if (g_waiting_for_data_response) + XEvent xevent; + int time_diff; + int clip_rv; + int rail_rv; + + if ((!g_clip_up) && (!g_rail_up)) { - time_diff = xcommon_get_local_time() - - g_waiting_for_data_response_time; - if (time_diff > 10000) - { - LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: warning, " - "waiting for data response too long")); - } + LOG(10, ("xcommon_check_wait_objs: nothing to do")); + return 0; } - while (XPending(g_display) > 0) + + if (g_is_wait_obj_set(g_x_wait_obj)) { - 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(10, ("xcommon_check_wait_objs unknown xevent type %d", xevent.type)); - } + if (XPending(g_display) < 1) + { + /* something is wrong, should not get here */ + LOGM((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 > 10000) + { + LOGM((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(10, ("xcommon_check_wait_objs unknown xevent type %d", xevent.type)); + } + } } - } - return 0; + + return 0; } |