clipboard work

ulab-original
jsorg71 15 years ago
parent 185414584d
commit 64fde0e24f

@ -55,6 +55,13 @@ static Time g_selection_time = 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;
static int g_data_in_size;
static int g_data_in_time;
extern int g_cliprdr_chan_id; /* in chansrv.c */
extern Display* g_display; /* in chansrv.c */
@ -199,6 +206,7 @@ clipboard_deinit(void)
g_x_socket = 0;
g_free(g_last_clip_data);
g_last_clip_data = 0;
g_last_clip_size = 0;
free_stream(g_ins);
g_clip_up = 0;
return 0;
@ -358,11 +366,20 @@ static int APP_CC
clipboard_process_format_announce(struct stream* s, int clip_msg_status,
int clip_msg_len)
{
Window owner;
LOG(1, ("clipboard_process_format_announce: CLIPRDR_FORMAT_ANNOUNCE"));
//g_hexdump(s->p, s->end - s->p);
clipboard_send_format_ack();
g_selection_time = clipboard_get_time();
XSetSelectionOwner(g_display, g_clipboard_atom, g_wnd, g_selection_time);
//XSetSelectionOwner(g_display, XA_PRIMARY, g_wnd, g_selection_time);
g_got_selection = 1;
owner = XGetSelectionOwner(g_display, g_clipboard_atom);
if (owner != g_wnd)
{
g_got_selection = 0;
LOG(0, ("clipboard_process_format_announce: XSetSelectionOwner failed"));
}
return 0;
}
@ -392,8 +409,77 @@ static int APP_CC
clipboard_process_data_response(struct stream* s, int clip_msg_status,
int clip_msg_len)
{
XEvent xev;
XSelectionRequestEvent* lev;
twchar* wtext;
twchar wchr;
int len;
int index;
int wtext_size;
LOG(1, ("clipboard_process_data_response: CLIPRDR_DATA_RESPONSE"));
//g_hexdump(s->p, s->end - s->p);
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)
{
break;
}
index++;
}
wtext[index] = 0;
len = g_wcstombs(0, wtext, 0);
if (len >= 0)
{
g_free(g_data_in);
g_data_in_size = 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);
len = g_strlen(g_data_in);
g_data_in_time = g_time3();
}
if (g_data_in != 0)
{
for (index = 0; index < g_selection_request_event_count; index++)
{
lev = &(g_selection_request_event[index]);
XChangeProperty(g_display, lev->requestor, lev->property,
XA_STRING, 8, PropModeReplace, g_data_in,
g_strlen(g_data_in));
g_memset(&xev, 0, sizeof(xev));
xev.xselection.type = SelectionNotify;
xev.xselection.send_event = True;
xev.xselection.display = lev->display;
xev.xselection.requestor = lev->requestor;
xev.xselection.selection = lev->selection;
xev.xselection.target = lev->target;
xev.xselection.property = lev->property;
xev.xselection.time = CurrentTime;
XSendEvent(g_display, lev->requestor, False, NoEventMask, &xev);
LOG(1, ("clipboard_process_data_response: %d", lev->requestor));
}
}
g_selection_request_event_count = 0;
g_free(wtext);
return 0;
}
@ -483,13 +569,18 @@ clipboard_process_selection_owner_notify(XEvent* xevent)
lxevent = (XFixesSelectionNotifyEvent*)xevent;
LOG(1, ("clipboard_process_selection_owner_notify: "
"window %d subtype %d owner %d",
lxevent->window, lxevent->subtype, lxevent->owner));
if (lxevent->subtype == 0)
"window %d subtype %d owner %d g_wnd %d",
lxevent->window, lxevent->subtype, lxevent->owner, g_wnd));
if (lxevent->owner == g_wnd)
{
XConvertSelection(g_display, g_clipboard_atom, XA_STRING,
g_clip_property_atom, g_wnd, CurrentTime);
LOG(1, ("clipboard_process_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;
}
@ -595,9 +686,16 @@ clipboard_process_selection_notify(XEvent* xevent)
int n_items;
int fmt;
int rv;
int index;
int convert_to_string;
int send_format_announce;
int atom;
int* atoms;
Atom type;
LOG(1, ("clipboard_process_selection_notify:"));
convert_to_string = 0;
send_format_announce = 0;
rv = 0;
data = 0;
type = 0;
@ -610,34 +708,71 @@ clipboard_process_selection_notify(XEvent* xevent)
}
if (rv == 0)
{
rv = clipboard_get_window_property(g_wnd, lxevent->property, &type, &fmt,
rv = clipboard_get_window_property(lxevent->requestor, lxevent->property,
&type, &fmt,
&n_items, &data, &data_size);
if (rv != 0)
{
LOG(0, ("clipboard_process_selection_notify: "
"clipboard_get_window_property failed error %d", rv));
}
XDeleteProperty(g_display, g_wnd, g_clip_property_atom);
XDeleteProperty(g_display, lxevent->requestor, lxevent->property);
}
if (rv == 0)
{
if (type == XA_STRING)
if (lxevent->selection == g_clipboard_atom)
{
g_free(g_last_clip_data);
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;
if (lxevent->target == g_targets_atom)
{
if ((type == XA_ATOM) && (fmt == 32))
{
atoms = (int*)data;
for (index = 0; index < n_items; index++)
{
atom = atoms[index];
LOG(1, ("clipboard_process_selection_notify: %d %s %d", atom,
XGetAtomName(g_display, atom), XA_STRING));
if (atom == XA_STRING)
{
convert_to_string = 1;
}
}
}
else
{
LOG(0, ("clipboard_process_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 == XA_STRING)
{
LOG(10, ("clipboard_process_selection_notify: XA_STRING data_size %d",
data_size));
g_free(g_last_clip_data);
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;
}
else
{
LOG(0, ("clipboard_process_selection_notify: unknown target"));
}
}
else
{
LOG(0, ("clipboard_process_selection_notify: unknown "
"clipboard data type %d", type));
rv = 3;
LOG(0, ("clipboard_process_selection_notify: unknown selection"));
}
}
if (rv == 0)
if (convert_to_string)
{
XConvertSelection(g_display, g_clipboard_atom, XA_STRING,
g_clip_property_atom, g_wnd, CurrentTime);
}
if (send_format_announce)
{
if (clipboard_send_format_announce() != 0)
{
@ -696,8 +831,8 @@ clipboard_process_selection_request(XEvent* xevent)
XA_ATOM, 32, PropModeReplace, (tui8*)ui32, 4);
g_memset(&xev, 0, sizeof(xev));
xev.xselection.type = SelectionNotify;
xev.xselection.serial = 0;
xev.xselection.send_event = True;
xev.xselection.display = lxevent->display;
xev.xselection.requestor = lxevent->requestor;
xev.xselection.selection = lxevent->selection;
xev.xselection.target = lxevent->target;
@ -715,8 +850,8 @@ clipboard_process_selection_request(XEvent* xevent)
XA_INTEGER, 32, PropModeReplace, (tui8*)ui32, 1);
g_memset(&xev, 0, sizeof(xev));
xev.xselection.type = SelectionNotify;
xev.xselection.serial = 0;
xev.xselection.send_event = True;
xev.xselection.display = lxevent->display;
xev.xselection.requestor = lxevent->requestor;
xev.xselection.selection = lxevent->selection;
xev.xselection.target = lxevent->target;
@ -743,12 +878,33 @@ clipboard_process_selection_request(XEvent* xevent)
else if (lxevent->target == XA_STRING)
{
LOG(1, ("clipboard_process_selection_request: XA_STRING"));
/*
if (g_abs((g_time3() - g_data_in_time)) < 1000)
{
LOG(1, ("clipboard_process_selection_request: XA_STRING---------------------------"));
XChangeProperty(g_display, lxevent->requestor, lxevent->property,
XA_STRING, 8, PropModeReplace, g_data_in,
g_strlen(g_data_in));
g_memset(&xev, 0, sizeof(xev));
xev.xselection.type = SelectionNotify;
xev.xselection.send_event = True;
xev.xselection.display = lxevent->display;
xev.xselection.requestor = lxevent->requestor;
xev.xselection.selection = lxevent->selection;
xev.xselection.target = lxevent->target;
xev.xselection.property = lxevent->property;
xev.xselection.time = lxevent->time;
XSendEvent(g_display, lxevent->requestor, False, NoEventMask, &xev);
return 0;
}
*/
/*
XChangeProperty(g_display, lxevent->requestor, lxevent->property,
XA_STRING, 8, PropModeReplace, "test", 5);
XA_STRING, 8, PropModeReplace, "Jay--", 5);
g_memset(&xev, 0, sizeof(xev));
xev.xselection.type = SelectionNotify;
xev.xselection.serial = 0;
xev.xselection.send_event = True;
xev.xselection.display = lxevent->display;
xev.xselection.requestor = lxevent->requestor;
xev.xselection.selection = lxevent->selection;
xev.xselection.target = lxevent->target;
@ -756,6 +912,22 @@ clipboard_process_selection_request(XEvent* xevent)
xev.xselection.time = lxevent->time;
XSendEvent(g_display, lxevent->requestor, False, NoEventMask, &xev);
return 0;
*/
if (g_selection_request_event_count > 10)
{
LOG(0, ("clipboard_process_selection_request: error, too many requests"));
}
else
{
g_memcpy(&(g_selection_request_event[g_selection_request_event_count]),
lxevent, sizeof(g_selection_request_event[0]));
if (g_selection_request_event_count == 0)
{
clipboard_send_data_request();
}
g_selection_request_event_count++;
return 0;
}
}
else
{
@ -764,8 +936,8 @@ clipboard_process_selection_request(XEvent* xevent)
}
g_memset(&xev, 0, sizeof(xev));
xev.xselection.type = SelectionNotify;
xev.xselection.serial = 0;
xev.xselection.send_event = True;
xev.xselection.display = lxevent->display;
xev.xselection.requestor = lxevent->requestor;
xev.xselection.selection = lxevent->selection;
xev.xselection.target = lxevent->target;
@ -791,7 +963,6 @@ static int APP_CC
clipboard_process_selection_clear(XEvent* xevent)
{
LOG(1, ("clipboard_process_selection_clear:"));
g_got_selection = 0;
return 0;
}
@ -850,6 +1021,7 @@ clipboard_check_wait_objs(void)
case MappingNotify:
break;
case PropertyNotify:
LOG(1, ("clipboard_check_wait_objs: PropertyNotify .window %d .state %d", xevent.xproperty.window, xevent.xproperty.state));
break;
default:
if (xevent.type == g_xfixes_event_base +

Loading…
Cancel
Save