clipboard work
This commit is contained in:
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)
|
||||
{
|
||||
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 "
|
||||
"clipboard data type %d", type));
|
||||
rv = 3;
|
||||
LOG(0, ("clipboard_process_selection_notify: unknown target"));
|
||||
}
|
||||
}
|
||||
if (rv == 0)
|
||||
else
|
||||
{
|
||||
LOG(0, ("clipboard_process_selection_notify: unknown selection"));
|
||||
}
|
||||
}
|
||||
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,17 @@ 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, "test", 5);
|
||||
XA_STRING, 8, PropModeReplace, g_data_in,
|
||||
g_strlen(g_data_in));
|
||||
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;
|
||||
@ -757,6 +897,38 @@ clipboard_process_selection_request(XEvent* xevent)
|
||||
XSendEvent(g_display, lxevent->requestor, False, NoEventMask, &xev);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
XChangeProperty(g_display, lxevent->requestor, lxevent->property,
|
||||
XA_STRING, 8, PropModeReplace, "Jay--", 5);
|
||||
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;
|
||||
*/
|
||||
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
|
||||
{
|
||||
LOG(1, ("clipboard_process_selection_request: unknown "
|
||||
@ -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…
Reference in New Issue
Block a user