clipboard work

This commit is contained in:
jsorg71 2009-09-01 20:39:06 +00:00
parent 2293410d7e
commit e0dec1eb02

View File

@ -38,6 +38,7 @@ static Atom g_targets_atom = 0;
static Atom g_primary_atom = 0; static Atom g_primary_atom = 0;
static Atom g_secondary_atom = 0; static Atom g_secondary_atom = 0;
static Atom g_get_time_atom = 0; static Atom g_get_time_atom = 0;
static Atom g_utf8_atom = 0;
static int g_x_socket = 0; static int g_x_socket = 0;
static tbus g_x_wait_obj = 0; static tbus g_x_wait_obj = 0;
static int g_clip_up = 0; static int g_clip_up = 0;
@ -159,6 +160,7 @@ clipboard_init(void)
g_multiple_atom = XInternAtom(g_display, "MULTIPLE", False); g_multiple_atom = XInternAtom(g_display, "MULTIPLE", False);
g_primary_atom = XInternAtom(g_display, "PRIMARY", False); g_primary_atom = XInternAtom(g_display, "PRIMARY", False);
g_secondary_atom = XInternAtom(g_display, "SECONDARY", False); g_secondary_atom = XInternAtom(g_display, "SECONDARY", False);
g_utf8_atom = XInternAtom(g_display, "UTF8_STRING", False);
g_wnd = XCreateSimpleWindow(g_display, RootWindowOfScreen(g_screen), g_wnd = XCreateSimpleWindow(g_display, RootWindowOfScreen(g_screen),
0, 0, 4, 4, 0, 0, 0); 0, 0, 4, 4, 0, 0, 0);
input_mask = StructureNotifyMask | PropertyChangeMask; input_mask = StructureNotifyMask | PropertyChangeMask;
@ -380,6 +382,24 @@ clipboard_send_data_response(void)
return rv; return rv;
} }
/*****************************************************************************/
static int APP_CC
clipboard_set_selection_owner(void)
{
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;
}
/*****************************************************************************/ /*****************************************************************************/
static int APP_CC 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,
@ -392,14 +412,8 @@ clipboard_process_format_announce(struct stream* s, int clip_msg_status,
clipboard_send_format_ack(); clipboard_send_format_ack();
g_got_format_announce = 1; g_got_format_announce = 1;
g_data_in_up_to_date = 0; g_data_in_up_to_date = 0;
g_selection_time = clipboard_get_server_time(); if (clipboard_set_selection_owner() != 0)
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")); LOG(0, ("clipboard_process_format_announce: XSetSelectionOwner failed"));
} }
return 0; return 0;
@ -438,6 +452,7 @@ clipboard_process_data_response(struct stream* s, int clip_msg_status,
int len; int len;
int index; int index;
int wtext_size; int wtext_size;
int data_in_len;
LOG(1, ("clipboard_process_data_response: CLIPRDR_DATA_RESPONSE")); LOG(1, ("clipboard_process_data_response: CLIPRDR_DATA_RESPONSE"));
len = (int)(s->end - s->p); len = (int)(s->end - s->p);
@ -484,12 +499,13 @@ clipboard_process_data_response(struct stream* s, int clip_msg_status,
} }
if (g_data_in != 0) if (g_data_in != 0)
{ {
data_in_len = g_strlen(g_data_in);
for (index = 0; index < g_selection_request_event_count; index++) for (index = 0; index < g_selection_request_event_count; index++)
{ {
lxev = &(g_selection_request_event[index]); lxev = &(g_selection_request_event[index]);
XChangeProperty(g_display, lxev->requestor, lxev->property, XChangeProperty(g_display, lxev->requestor, lxev->property,
XA_STRING, 8, PropModeReplace, g_data_in, lxev->target, 8, PropModeReplace, g_data_in,
g_strlen(g_data_in)); data_in_len);
g_memset(&xev, 0, sizeof(xev)); g_memset(&xev, 0, sizeof(xev));
xev.xselection.type = SelectionNotify; xev.xselection.type = SelectionNotify;
xev.xselection.send_event = True; xev.xselection.send_event = True;
@ -500,8 +516,8 @@ clipboard_process_data_response(struct stream* s, int clip_msg_status,
xev.xselection.property = lxev->property; xev.xselection.property = lxev->property;
xev.xselection.time = lxev->time; xev.xselection.time = lxev->time;
XSendEvent(g_display, lxev->requestor, False, NoEventMask, &xev); XSendEvent(g_display, lxev->requestor, False, NoEventMask, &xev);
//XSelectInput(g_display, lxev->requestor, PropertyChangeMask); LOG(1, ("clipboard_process_data_response: requestor %d data_in_len %d",
LOG(1, ("clipboard_process_data_response: %d", lxev->requestor)); lxev->requestor, data_in_len));
} }
} }
g_selection_request_event_count = 0; g_selection_request_event_count = 0;
@ -570,6 +586,7 @@ clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length,
LOG(0, ("clipboard_data_in: unknown clip_msg_id %d", clip_msg_id)); LOG(0, ("clipboard_data_in: unknown clip_msg_id %d", clip_msg_id));
break; break;
} }
XFlush(g_display);
return rv; return rv;
} }
@ -829,7 +846,7 @@ clipboard_event_selection_request(XEvent* xevent)
{ {
XEvent xev; XEvent xev;
XSelectionRequestEvent* lxev; XSelectionRequestEvent* lxev;
tui32 ui32[4]; tui32 ui32[8];
Atom type; Atom type;
int fmt; int fmt;
int n_items; int n_items;
@ -838,8 +855,9 @@ clipboard_event_selection_request(XEvent* xevent)
lxev = (XSelectionRequestEvent*)xevent; lxev = (XSelectionRequestEvent*)xevent;
LOG(1, ("clipboard_event_selection_request: g_wnd %d, " LOG(1, ("clipboard_event_selection_request: g_wnd %d, "
".requestor %d .owner %d .select %d .target %d .property %d", ".requestor %d .owner %d .selection %d '%s' .target %d .property %d",
g_wnd, lxev->requestor, lxev->owner, lxev->selection, g_wnd, lxev->requestor, lxev->owner, lxev->selection,
XGetAtomName(g_display, lxev->selection),
lxev->target, lxev->property)); lxev->target, lxev->property));
if (lxev->property == None) if (lxev->property == None)
{ {
@ -853,8 +871,9 @@ clipboard_event_selection_request(XEvent* xevent)
ui32[1] = g_timestamp_atom; ui32[1] = g_timestamp_atom;
ui32[2] = g_multiple_atom; ui32[2] = g_multiple_atom;
ui32[3] = XA_STRING; ui32[3] = XA_STRING;
ui32[4] = g_utf8_atom;
XChangeProperty(g_display, lxev->requestor, lxev->property, XChangeProperty(g_display, lxev->requestor, lxev->property,
XA_ATOM, 32, PropModeReplace, (tui8*)ui32, 4); XA_ATOM, 32, PropModeReplace, (tui8*)ui32, 5);
g_memset(&xev, 0, sizeof(xev)); g_memset(&xev, 0, sizeof(xev));
xev.xselection.type = SelectionNotify; xev.xselection.type = SelectionNotify;
xev.xselection.send_event = True; xev.xselection.send_event = True;
@ -865,7 +884,6 @@ clipboard_event_selection_request(XEvent* xevent)
xev.xselection.property = lxev->property; xev.xselection.property = lxev->property;
xev.xselection.time = lxev->time; xev.xselection.time = lxev->time;
XSendEvent(g_display, lxev->requestor, False, NoEventMask, &xev); XSendEvent(g_display, lxev->requestor, False, NoEventMask, &xev);
//XSelectInput(g_display, lxev->requestor, PropertyChangeMask);
return 0; return 0;
} }
else if (lxev->target == g_timestamp_atom) else if (lxev->target == g_timestamp_atom)
@ -885,7 +903,6 @@ clipboard_event_selection_request(XEvent* xevent)
xev.xselection.property = lxev->property; xev.xselection.property = lxev->property;
xev.xselection.time = lxev->time; xev.xselection.time = lxev->time;
XSendEvent(g_display, lxev->requestor, False, NoEventMask, &xev); XSendEvent(g_display, lxev->requestor, False, NoEventMask, &xev);
//XSelectInput(g_display, lxev->requestor, PropertyChangeMask);
return 0; return 0;
} }
else if (lxev->target == g_multiple_atom) else if (lxev->target == g_multiple_atom)
@ -903,13 +920,14 @@ clipboard_event_selection_request(XEvent* xevent)
g_free(xdata); g_free(xdata);
} }
} }
else if (lxev->target == XA_STRING) else if ((lxev->target == XA_STRING) || (lxev->target == g_utf8_atom))
{ {
LOG(1, ("clipboard_event_selection_request: XA_STRING")); LOG(1, ("clipboard_event_selection_request: %s",
XGetAtomName(g_display, lxev->target)));
if (g_data_in_up_to_date) if (g_data_in_up_to_date)
{ {
XChangeProperty(g_display, lxev->requestor, lxev->property, XChangeProperty(g_display, lxev->requestor, lxev->property,
XA_STRING, 8, PropModeReplace, g_data_in, lxev->target, 8, PropModeReplace, g_data_in,
g_strlen(g_data_in)); g_strlen(g_data_in));
g_memset(&xev, 0, sizeof(xev)); g_memset(&xev, 0, sizeof(xev));
xev.xselection.type = SelectionNotify; xev.xselection.type = SelectionNotify;
@ -921,7 +939,6 @@ clipboard_event_selection_request(XEvent* xevent)
xev.xselection.property = lxev->property; xev.xselection.property = lxev->property;
xev.xselection.time = lxev->time; xev.xselection.time = lxev->time;
XSendEvent(g_display, lxev->requestor, False, NoEventMask, &xev); XSendEvent(g_display, lxev->requestor, False, NoEventMask, &xev);
//XSelectInput(g_display, lxev->requestor, PropertyChangeMask);
return 0; return 0;
} }
if (g_selection_request_event_count > 10) if (g_selection_request_event_count > 10)
@ -955,7 +972,6 @@ clipboard_event_selection_request(XEvent* xevent)
xev.xselection.property = None; xev.xselection.property = None;
xev.xselection.time = lxev->time; xev.xselection.time = lxev->time;
XSendEvent(g_display, lxev->requestor, False, NoEventMask, &xev); XSendEvent(g_display, lxev->requestor, False, NoEventMask, &xev);
//XSelectInput(g_display, lxev->requestor, PropertyChangeMask);
return 0; return 0;
} }