Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Filelist
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,8 @@ SRC_UNIX = \
src/gui_gtk4.c \
src/gui_gtk4_f.c \
src/gui_gtk4_f.h \
src/gui_gtk4_cb.c \
src/gui_gtk4_cb.h \
src/gui_gtk_res.xml \
src/gui_motif.c \
src/gui_xmdlg.c \
Expand Down
12 changes: 11 additions & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1234,9 +1234,11 @@ GTK_BUNDLE =

### GTK4 GUI
GTK4_SRC = gui.c gui_gtk4.c gui_gtk4_f.c \
gui_gtk4_cb.c \
$(GRESOURCE_SRC)
GTK4_OBJ = objects/gui.o objects/gui_gtk4.o \
objects/gui_gtk4_f.o \
objects/gui_gtk4_cb.o \
$(GRESOURCE_OBJ)
GTK4_DEFS = -DFEAT_GUI_GTK $(NARROW_PROTO)
GTK4_IPATH = $(GUI_INC_LOC)
Expand Down Expand Up @@ -1306,7 +1308,7 @@ HAIKUGUI_TESTTARGET = gui
HAIKUGUI_BUNDLE =

# All GUI files
ALL_GUI_SRC = gui.c gui_gtk.c gui_gtk_f.c gui_gtk4.c gui_gtk4_f.c gui_motif.c gui_xmdlg.c gui_xmebw.c gui_gtk_x11.c gui_x11.c gui_haiku.cc
ALL_GUI_SRC = gui.c gui_gtk.c gui_gtk_f.c gui_gtk4.c gui_gtk4_f.c gui_gtk4_cb.c gui_motif.c gui_xmdlg.c gui_xmebw.c gui_gtk_x11.c gui_x11.c gui_haiku.cc
ALL_GUI_PRO = proto/gui.pro proto/gui_gtk.pro proto/gui_gtk4.pro proto/gui_motif.pro proto/gui_xmdlg.pro proto/gui_gtk_x11.pro proto/gui_x11.pro proto/gui_w32.pro proto/gui_photon.pro

# }}}
Expand Down Expand Up @@ -3389,6 +3391,9 @@ objects/gui_gtk4.o: gui_gtk4.c
objects/gui_gtk4_f.o: gui_gtk4_f.c
$(CCC) -o $@ gui_gtk4_f.c

objects/gui_gtk4_cb.o: gui_gtk4_cb.c
$(CCC) -o $@ gui_gtk4_cb.c


objects/gui_haiku.o: gui_haiku.cc
$(CCC) -o $@ gui_haiku.cc
Expand Down Expand Up @@ -4467,6 +4472,11 @@ objects/gui_gtk4_f.o: auto/osdef.h gui_gtk4_f.c vim.h protodef.h auto/config.h f
beval.h structs.h regexp.h gui.h \
libvterm/include/vterm.h libvterm/include/vterm_keycodes.h alloc.h \
ex_cmds.h spell.h proto.h globals.h errors.h gui_gtk4_f.h
objects/gui_gtk4_cb.o: auto/osdef.h gui_gtk4_cb.c vim.h protodef.h auto/config.h feature.h \
os_unix.h ascii.h keymap.h termdefs.h macros.h option.h \
beval.h structs.h regexp.h gui.h \
libvterm/include/vterm.h libvterm/include/vterm_keycodes.h alloc.h \
ex_cmds.h spell.h proto.h globals.h errors.h gui_gtk4_cb.h
objects/gui_gtk_f.o: auto/osdef.h gui_gtk_f.c vim.h protodef.h auto/config.h feature.h \
os_unix.h ascii.h keymap.h termdefs.h macros.h option.h \
beval.h structs.h regexp.h gui.h \
Expand Down
163 changes: 107 additions & 56 deletions src/clipboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ typedef struct {
// Mimes with a lower index in the array are prioritized first when we are
// receiving data.
static const char *supported_mimes[] = {
VIMENC_MIMETYPE_NAME,
VIMENC_ATOM_NAME,
VIM_MIMETYPE_NAME,
VIM_ATOM_NAME,
"text/plain;charset=utf-8",
"text/plain",
Expand Down Expand Up @@ -1424,6 +1426,10 @@ open_app_context(void)

static Atom vim_atom; // Vim's own special selection format
static Atom vimenc_atom; // Vim's extended selection format
static Atom vim_mt_atom; // Vim's own special selection format (in mime
// type format)
static Atom vimenc_mt_atom; // Vim's extended selection format (in mime type
// format)
static Atom utf8_atom;
static Atom compound_text_atom;
static Atom text_atom;
Expand All @@ -1435,6 +1441,8 @@ x11_setup_atoms(Display *dpy)
{
vim_atom = XInternAtom(dpy, VIM_ATOM_NAME, False);
vimenc_atom = XInternAtom(dpy, VIMENC_ATOM_NAME,False);
vim_mt_atom = XInternAtom(dpy, VIM_MIMETYPE_NAME, False);
vimenc_mt_atom = XInternAtom(dpy, VIMENC_MIMETYPE_NAME,False);
utf8_atom = XInternAtom(dpy, "UTF8_STRING", False);
compound_text_atom = XInternAtom(dpy, "COMPOUND_TEXT", False);
text_atom = XInternAtom(dpy, "TEXT", False);
Expand Down Expand Up @@ -1476,13 +1484,15 @@ clip_x11_convert_selection_cb(
// requestor wants to know what target types we support
if (*target == targets_atom)
{
static Atom array[7];
static Atom array[9];

*value = (XtPointer)array;
i = 0;
array[i++] = targets_atom;
array[i++] = vimenc_atom;
array[i++] = vim_atom;
array[i++] = vimenc_mt_atom;
array[i++] = vim_mt_atom;
if (enc_utf8)
array[i++] = utf8_atom;
array[i++] = XA_STRING;
Expand All @@ -1499,8 +1509,10 @@ clip_x11_convert_selection_cb(

if ( *target != XA_STRING
&& *target != vimenc_atom
&& *target != vimenc_mt_atom
&& (*target != utf8_atom || !enc_utf8)
&& *target != vim_atom
&& *target != vim_mt_atom
&& *target != text_atom
&& *target != compound_text_atom)
return False;
Expand All @@ -1511,11 +1523,11 @@ clip_x11_convert_selection_cb(
return False;

// For our own format, the first byte contains the motion type
if (*target == vim_atom)
if (*target == vim_atom || *target == vim_mt_atom)
(*length)++;

// Our own format with encoding: motion 'encoding' NUL text
if (*target == vimenc_atom)
if (*target == vimenc_atom || *target == vimenc_mt_atom)
*length += STRLEN(p_enc) + 2;

if (save_length < *length || save_length / 2 >= *length)
Expand Down Expand Up @@ -1558,20 +1570,26 @@ clip_x11_convert_selection_cb(
save_result = (char_u *)*value;
save_length = *length;
}
else if (*target == vimenc_atom)
else if (*target == vimenc_atom || *target == vimenc_mt_atom)
{
int l = STRLEN(p_enc);

save_result[0] = motion_type;
STRCPY(save_result + 1, p_enc);
mch_memmove(save_result + l + 2, string, (size_t)(*length - l - 2));
*type = vimenc_atom;
if (*target == vimenc_atom)
*type = vimenc_atom;
else
*type = vimenc_mt_atom;
}
else
{
save_result[0] = motion_type;
mch_memmove(save_result + 1, string, (size_t)(*length - 1));
*type = vim_atom;
if (*target == vim_atom)
*type = vim_atom;
else
*type = vim_mt_atom;
}
*format = 8; // 8 bits per char
vim_free(string);
Expand Down Expand Up @@ -1681,13 +1699,13 @@ clip_x11_request_selection_cb(
}
p = (char_u *)value;
len = *length;
if (*type == vim_atom)
if (*type == vim_atom || *type == vim_mt_atom)
{
motion_type = *p++;
len--;
}

else if (*type == vimenc_atom)
else if (*type == vimenc_atom || *type == vimenc_mt_atom)
{
char_u *enc;
vimconv_T conv;
Expand Down Expand Up @@ -1765,15 +1783,17 @@ clip_x11_request_selection(
time_t start_time;
int timed_out = FALSE;

for (i = 0; i < 6; i++)
for (i = 0; i < 8; i++)
{
switch (i)
{
case 0: type = vimenc_atom; break;
case 1: type = vim_atom; break;
case 2: type = utf8_atom; break;
case 3: type = compound_text_atom; break;
case 4: type = text_atom; break;
case 0: type = vimenc_mt_atom; break;
case 1: type = vimenc_atom; break;
case 2: type = vim_mt_atom; break;
case 3: type = vim_atom; break;
case 4: type = utf8_atom; break;
case 5: type = compound_text_atom; break;
case 6: type = text_atom; break;
default: type = XA_STRING;
}
if (type == utf8_atom
Expand Down Expand Up @@ -2155,7 +2175,7 @@ clip_yank_selection(
str_to_reg(y_ptr, type, str, len, -1, FALSE);
}

static int
int
clip_convert_selection_offset(
char_u **str,
long_u *len,
Expand Down Expand Up @@ -2554,13 +2574,73 @@ clip_reset_wayland(void)
return OK;
}

/*
* If "vim" is TRUE, then get the motion type. If "vimenc" is TRUE, then get the
* motion type and also convert "*buf". "buf" and "len_store" will be updated to
* reflect the actual contents, but should be set beforehand with the initial
* contents.
*/
void
clip_convert_data(
char_u **buf,
long *len_store,
int *motion,
bool vim,
bool vimenc)
{
char_u *final = *buf;
char_u *enc;
long len = *len_store;

if (vim && len >= 2)
{
*motion = *final++;
len--;
}
Comment on lines +2595 to +2599
if (vimenc && len >= 3)
{
vimconv_T conv;
int convlen;

// first byte is motion type
*motion = *final++;
len--;

// Get encoding of selection
enc = final;

// Skip the encoding type including null terminator in final text
final += STRLEN(final) + 1;

// Subtract pointers to get length of encoding;
len -= final - enc;

conv.vc_type = CONV_NONE;
convert_setup(&conv, enc, p_enc);
if (conv.vc_type != CONV_NONE)
{
char_u *tmp;

convlen = len;
tmp = string_convert(&conv, final, &convlen);
len = convlen;
if (tmp != NULL)
final = tmp;
convert_setup(&conv, NULL, NULL);
Comment on lines +2622 to +2629
}
}
*buf = final;
*len_store = len;
}

/*
* Read data from a file descriptor and write it to the given clipboard.
*/
static void
clip_wl_receive_data(Clipboard_T *cbd, const char *mime_type, int fd)
{
char_u *start, *final, *enc;
char_u *start, *final;
long len;
garray_T buf;
int motion_type = MAUTO;
ssize_t r = 0;
Expand Down Expand Up @@ -2628,46 +2708,15 @@ clip_wl_receive_data(Clipboard_T *cbd, const char *mime_type, int fd)
}

final = buf.ga_data;
len = buf.ga_len;

if (STRCMP(mime_type, VIM_ATOM_NAME) == 0 && buf.ga_len >= 2)
{
motion_type = *final++;
buf.ga_len--;
}
else if (STRCMP(mime_type, VIMENC_ATOM_NAME) == 0 && buf.ga_len >= 3)
{
vimconv_T conv;
int convlen;

// first byte is motion type
motion_type = *final++;
buf.ga_len--;

// Get encoding of selection
enc = final;

// Skip the encoding type including null terminator in final text
final += STRLEN(final) + 1;

// Subtract pointers to get length of encoding;
buf.ga_len -= final - enc;

conv.vc_type = CONV_NONE;
convert_setup(&conv, enc, p_enc);
if (conv.vc_type != CONV_NONE)
{
char_u *tmp;

convlen = buf.ga_len;
tmp = string_convert(&conv, final, &convlen);
buf.ga_len = convlen;
if (tmp != NULL)
final = tmp;
convert_setup(&conv, NULL, NULL);
}
}
clip_convert_data(&final, &len, &motion_type,
STRCMP(mime_type, VIM_ATOM_NAME) == 0
|| STRCMP(mime_type, VIM_MIMETYPE_NAME) == 0,
STRCMP(mime_type, VIMENC_ATOM_NAME) == 0
|| STRCMP(mime_type, VIMENC_MIMETYPE_NAME) == 0);

clip_yank_selection(motion_type, final, (long)buf.ga_len, cbd);
clip_yank_selection(motion_type, final, len, cbd);
ga_clear(&buf);
}

Expand Down Expand Up @@ -2772,8 +2821,10 @@ vwl_data_source_listener_event_send(
// format, after the first byte is the encoding type, which is null
// terminated.

is_vimenc = STRCMP(mime_type, VIMENC_ATOM_NAME) == 0;
is_vim = STRCMP(mime_type, VIM_ATOM_NAME) == 0;
is_vimenc = STRCMP(mime_type, VIMENC_ATOM_NAME) == 0
|| STRCMP(mime_type, VIMENC_MIMETYPE_NAME) == 0;
is_vim = STRCMP(mime_type, VIM_ATOM_NAME) == 0
|| STRCMP(mime_type, VIM_MIMETYPE_NAME) == 0;

if (is_vimenc)
offset += 2 + STRLEN(p_enc);
Expand Down
4 changes: 4 additions & 0 deletions src/gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,10 @@ typedef struct Gui
#endif
#if defined(FEAT_GUI_GTK) && defined(USE_GTK4)
int decor_height;

// Used for clipboard functionality in GTK4 GUI
GdkContentProvider *regular_provider;
GdkContentProvider *primary_provider;
#endif
} gui_T;

Expand Down
Loading
Loading