row_col_t beg; /* beginning of selection <= mark */
row_col_t mark; /* point of initial click <= end */
row_col_t end; /* one character past end point */
+ wchar_t *clip_text; /* text copied to the clipboard */
+ unsigned int clip_len; /* length of clipboard text */
};
/* ------------------------------------------------------------------------- */
Atom *xa;
/* ---------- */
Time selection_time,
- selection_request_time;
+ selection_request_time,
+ clipboard_time;
pid_t cmd_pid; /* process id of child */
char * incr_buf;
size_t incr_buf_size, incr_buf_fill;
void selection_property (Window win, Atom prop) NOTHROW;
void selection_request (Time tm, int selnum = Sel_Primary) NOTHROW;
int selection_request_other (Atom target, int selnum) NOTHROW;
- void selection_clear () NOTHROW;
+ void selection_clear (bool clipboard = false) NOTHROW;
+ void clipboard_copy (Time tm);
void selection_make (Time tm);
- bool selection_grab (Time tm) NOTHROW;
+ bool selection_grab (Time tm, bool clipboard = false) NOTHROW;
void selection_start_colrow (int col, int row) NOTHROW;
void selection_delimit_word (enum page_dirn dirn, const row_col_t *mark, row_col_t *ret) NOTHROW;
void selection_extend_colrow (int32_t col, int32_t row, int button3, int buttonpress, int clickchange) NOTHROW;
rxvt_display::rxvt_display (const char *id)
: refcounted (id)
, selection_owner (0)
+, clipboard_owner (0)
{
x_ev .set<rxvt_display, &rxvt_display::x_cb > (this);
flush_ev.set<rxvt_display, &rxvt_display::flush_cb> (this);
}
}
-void rxvt_display::set_selection_owner (rxvt_term *owner)
+void rxvt_display::set_selection_owner (rxvt_term *owner, bool clipboard)
{
- if (selection_owner && selection_owner != owner)
- {
- rxvt_term *owner = selection_owner;
+ rxvt_term * &cur_owner = !clipboard ? selection_owner : clipboard_owner;
- owner->selection_clear ();
- owner->flush ();
+ if (cur_owner && cur_owner != owner)
+ {
+ cur_owner->selection_clear (clipboard);
+ cur_owner->flush ();
}
- selection_owner = owner;
+ cur_owner = owner;
}
#ifdef USE_XIM
selection.op = SELECTION_CLEAR;
selection.screen = PRIMARY;
selection.clicks = 0;
+ selection.clip_text = NULL;
+ selection.clip_len = 0;
}
else
{
* EXT: SelectionClear
*/
void
-rxvt_term::selection_clear () NOTHROW
+rxvt_term::selection_clear (bool clipboard) NOTHROW
{
- want_refresh = 1;
- free (selection.text);
- selection.text = NULL;
- selection.len = 0;
- CLEAR_SELECTION ();
+ if (!clipboard)
+ {
+ want_refresh = 1;
+ free (selection.text);
+ selection.text = NULL;
+ selection.len = 0;
+ CLEAR_SELECTION ();
- if (display->selection_owner == this)
- display->selection_owner = 0;
+ if (display->selection_owner == this)
+ display->selection_owner = 0;
+ }
+ else
+ {
+ free (selection.clip_text);
+ selection.clip_text = NULL;
+ selection.clip_len = 0;
+
+ if (display->clipboard_owner == this)
+ display->clipboard_owner = 0;
+ }
+}
+
+void
+rxvt_term::clipboard_copy (Time tm)
+{
+ if (selection.len > 0)
+ {
+ free (selection.clip_text);
+ selection.clip_len = selection.len;
+ selection.clip_text = (wchar_t *) malloc (sizeof (wchar_t) * selection.clip_len);
+ memcpy (selection.clip_text, selection.text,
+ sizeof (wchar_t) * selection.clip_len);
+ selection_grab (tm, true);
+ }
}
/* ------------------------------------------------------------------------- */
}
bool
-rxvt_term::selection_grab (Time tm) NOTHROW
+rxvt_term::selection_grab (Time tm, bool clipboard) NOTHROW
{
- selection_time = tm;
+ Atom sel;
- XSetSelectionOwner (dpy, XA_PRIMARY, vt, tm);
- if (XGetSelectionOwner (dpy, XA_PRIMARY) == vt)
+ if (!clipboard)
+ {
+ selection_time = tm;
+ sel = XA_PRIMARY;
+ }
+ else
{
- display->set_selection_owner (this);
+ clipboard_time = tm;
+ sel = xa[XA_CLIPBOARD];
+ }
+
+ XSetSelectionOwner (dpy, sel, vt, tm);
+ if (XGetSelectionOwner (dpy, sel) == vt)
+ {
+ display->set_selection_owner (this, clipboard);
return true;
}
else
{
- selection_clear ();
+ selection_clear (clipboard);
return false;
}
/* TODO: Handle MULTIPLE */
}
#endif
- else if (rq.target == xa[XA_TIMESTAMP] && selection.text)
+ else if (rq.target == xa[XA_TIMESTAMP] && rq.selection == XA_PRIMARY && selection.text)
{
XChangeProperty (dpy, rq.requestor, rq.property, rq.target,
32, PropModeReplace, (unsigned char *)&selection_time, 1);
ev.property = rq.property;
}
+ else if (rq.target == xa[XA_TIMESTAMP] && rq.selection == xa[XA_CLIPBOARD] && selection.clip_text)
+ {
+ XChangeProperty (dpy, rq.requestor, rq.property, rq.target,
+ 32, PropModeReplace, (unsigned char *)&clipboard_time, 1);
+ ev.property = rq.property;
+ }
else if (rq.target == XA_STRING
|| rq.target == xa[XA_TEXT]
|| rq.target == xa[XA_COMPOUND_TEXT]
style = enc_compound_text;
}
- if (selection.text)
+ if (rq.selection == XA_PRIMARY && selection.text)
{
cl = selection.text;
selectlen = selection.len;
}
+ else if (rq.selection == xa[XA_CLIPBOARD] && selection.clip_text)
+ {
+ cl = selection.clip_text;
+ selectlen = selection.clip_len;
+ }
else
{
cl = L"";