comparison src/gui_gtk_x11.c @ 8218:3456e2ebebd4 v7.4.1402

commit https://github.com/vim/vim/commit/9892189d2e7ab94b750f99e6da4cbfc3c8014517 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Feb 23 17:14:37 2016 +0100 patch 7.4.1402 Problem: GTK 3 is not supported. Solution: Add GTK 3 support. (Kazunobu Kuriyama)
author Christian Brabandt <cb@256bit.org>
date Tue, 23 Feb 2016 17:15:05 +0100
parents fb5ba6fbc843
children 74b15ed0a259
comparison
equal deleted inserted replaced
8217:c52abf35df88 8218:3456e2ebebd4
17 * 17 *
18 * Support for GTK+ 2 was added by: 18 * Support for GTK+ 2 was added by:
19 * 19 *
20 * (C) 2002,2003 Jason Hildebrand <jason@peaceworks.ca> 20 * (C) 2002,2003 Jason Hildebrand <jason@peaceworks.ca>
21 * Daniel Elstner <daniel.elstner@gmx.net> 21 * Daniel Elstner <daniel.elstner@gmx.net>
22 *
23 * Support for GTK+ 3 was added by:
24 *
25 * 2016 Kazunobu Kuriyama <kazunobu.kuriyama@gmail.com>
22 */ 26 */
23 27
24 #include "vim.h" 28 #include "vim.h"
25 #ifdef USE_GRESOURCE 29 #ifdef USE_GRESOURCE
26 #include "auto/gui_gtk_gresources.h" 30 #include "auto/gui_gtk_gresources.h"
73 # define GdkEventButton int 77 # define GdkEventButton int
74 # define GdkDragContext int 78 # define GdkDragContext int
75 # define GdkEventConfigure int 79 # define GdkEventConfigure int
76 # define GdkEventClient int 80 # define GdkEventClient int
77 #else 81 #else
78 # include <gdk/gdkkeysyms.h> 82 # if GTK_CHECK_VERSION(3,0,0)
83 # include <gdk/gdkkeysyms-compat.h>
84 # include <gtk/gtkx.h>
85 # else
86 # include <gdk/gdkkeysyms.h>
87 # endif
79 # include <gdk/gdk.h> 88 # include <gdk/gdk.h>
80 # ifdef WIN3264 89 # ifdef WIN3264
81 # include <gdk/gdkwin32.h> 90 # include <gdk/gdkwin32.h>
82 # else 91 # else
83 # include <gdk/gdkx.h> 92 # include <gdk/gdkx.h>
84 # endif 93 # endif
85
86 # include <gtk/gtk.h> 94 # include <gtk/gtk.h>
87 # include "gui_gtk_f.h" 95 # include "gui_gtk_f.h"
88 #endif 96 #endif
89 97
90 #ifdef HAVE_X11_SUNKEYSYM_H 98 #ifdef HAVE_X11_SUNKEYSYM_H
578 vim_free(abs_restart_command); 586 vim_free(abs_restart_command);
579 #endif 587 #endif
580 } 588 }
581 #endif 589 #endif
582 590
591 #if !GTK_CHECK_VERSION(3,0,0)
583 /* 592 /*
584 * This should be maybe completely removed. 593 * This should be maybe completely removed.
585 * Doesn't seem possible, since check_copy_area() relies on 594 * Doesn't seem possible, since check_copy_area() relies on
586 * this information. --danielk 595 * this information. --danielk
587 */ 596 */
599 if (gui.text_gc != NULL) 608 if (gui.text_gc != NULL)
600 gdk_gc_set_exposures(gui.text_gc, 609 gdk_gc_set_exposures(gui.text_gc,
601 gui.visibility != GDK_VISIBILITY_UNOBSCURED); 610 gui.visibility != GDK_VISIBILITY_UNOBSCURED);
602 return FALSE; 611 return FALSE;
603 } 612 }
613 #endif /* !GTK_CHECK_VERSION(3,0,0) */
604 614
605 /* 615 /*
606 * Redraw the corresponding portions of the screen. 616 * Redraw the corresponding portions of the screen.
607 */ 617 */
618 #if GTK_CHECK_VERSION(3,0,0)
619 static gboolean is_key_pressed = FALSE;
620
621 static gboolean gui_gtk_is_blink_on(void);
622 static gboolean gui_gtk_is_no_blink(void);
623 static void gui_gtk_window_clear(GdkWindow *win);
624
625 static void
626 gui_gtk3_redraw(int x, int y, int width, int height)
627 {
628 gui_redraw_block(Y_2_ROW(y), X_2_COL(x),
629 Y_2_ROW(y + height - 1), X_2_COL(x + width - 1),
630 GUI_MON_NOCLEAR);
631 }
632
633 static void
634 gui_gtk3_update_cursor(cairo_t *cr)
635 {
636 if (gui.row == gui.cursor_row)
637 {
638 gui.by_signal = TRUE;
639 gui_update_cursor(TRUE, TRUE);
640 gui.by_signal = FALSE;
641 cairo_paint(cr);
642 }
643 }
644
645 static gboolean
646 gui_gtk3_should_draw_cursor(void)
647 {
648 unsigned int cond = 0;
649 cond |= gui_gtk_is_blink_on();
650 cond |= is_key_pressed;
651 cond |= gui.in_focus == FALSE;
652 cond |= gui_gtk_is_no_blink();
653 return cond;
654 }
655
656 static gboolean
657 draw_event(GtkWidget *widget,
658 cairo_t *cr,
659 gpointer user_data UNUSED)
660 {
661 /* Skip this when the GUI isn't set up yet, will redraw later. */
662 if (gui.starting)
663 return FALSE;
664
665 out_flush(); /* make sure all output has been processed */
666 /* for GTK+ 3, may induce other draw events. */
667
668 cairo_set_source_surface(cr, gui.surface, 0, 0);
669
670 /* Draw the window without the cursor. */
671 gui.by_signal = TRUE;
672 {
673 cairo_rectangle_list_t *list = NULL;
674
675 gui_gtk_window_clear(gtk_widget_get_window(widget));
676
677 list = cairo_copy_clip_rectangle_list(cr);
678 if (list->status != CAIRO_STATUS_CLIP_NOT_REPRESENTABLE)
679 {
680 int i;
681 for (i = 0; i < list->num_rectangles; i++)
682 {
683 const cairo_rectangle_t rect = list->rectangles[i];
684 gui_gtk3_redraw(rect.x, rect.y, rect.width, rect.height);
685 }
686 }
687 cairo_rectangle_list_destroy(list);
688
689 cairo_paint(cr);
690 }
691 gui.by_signal = FALSE;
692
693 /* Add the cursor to the window if necessary.*/
694 if (gui_gtk3_should_draw_cursor())
695 gui_gtk3_update_cursor(cr);
696
697 return FALSE;
698 }
699 #else /* !GTK_CHECK_VERSION(3,0,0) */
608 static gint 700 static gint
609 expose_event(GtkWidget *widget UNUSED, 701 expose_event(GtkWidget *widget UNUSED,
610 GdkEventExpose *event, 702 GdkEventExpose *event,
611 gpointer data UNUSED) 703 gpointer data UNUSED)
612 { 704 {
629 if (event->area.y > FILL_Y(Rows)) 721 if (event->area.y > FILL_Y(Rows))
630 gdk_window_clear_area(gui.drawarea->window, 0, FILL_Y((int)Rows), 0, 0); 722 gdk_window_clear_area(gui.drawarea->window, 0, FILL_Y((int)Rows), 0, 0);
631 723
632 return FALSE; 724 return FALSE;
633 } 725 }
726 #endif /* !GTK_CHECK_VERSION(3,0,0) */
634 727
635 #ifdef FEAT_CLIENTSERVER 728 #ifdef FEAT_CLIENTSERVER
636 /* 729 /*
637 * Handle changes to the "Comm" property 730 * Handle changes to the "Comm" property
638 */ 731 */
641 GdkEventProperty *event, 734 GdkEventProperty *event,
642 gpointer data UNUSED) 735 gpointer data UNUSED)
643 { 736 {
644 if (event->type == GDK_PROPERTY_NOTIFY 737 if (event->type == GDK_PROPERTY_NOTIFY
645 && event->state == (int)GDK_PROPERTY_NEW_VALUE 738 && event->state == (int)GDK_PROPERTY_NEW_VALUE
739 # if GTK_CHECK_VERSION(3,0,0)
740 && GDK_WINDOW_XID(event->window) == commWindow
741 # else
646 && GDK_WINDOW_XWINDOW(event->window) == commWindow 742 && GDK_WINDOW_XWINDOW(event->window) == commWindow
743 # endif
647 && GET_X_ATOM(event->atom) == commProperty) 744 && GET_X_ATOM(event->atom) == commProperty)
648 { 745 {
649 XEvent xev; 746 XEvent xev;
650 747
651 /* Translate to XLib */ 748 /* Translate to XLib */
652 xev.xproperty.type = PropertyNotify; 749 xev.xproperty.type = PropertyNotify;
653 xev.xproperty.atom = commProperty; 750 xev.xproperty.atom = commProperty;
654 xev.xproperty.window = commWindow; 751 xev.xproperty.window = commWindow;
655 xev.xproperty.state = PropertyNewValue; 752 xev.xproperty.state = PropertyNewValue;
753 # if GTK_CHECK_VERSION(3,0,0)
754 serverEventProc(GDK_WINDOW_XDISPLAY(gtk_widget_get_window(widget)),
755 &xev, 0);
756 # else
656 serverEventProc(GDK_WINDOW_XDISPLAY(widget->window), &xev, 0); 757 serverEventProc(GDK_WINDOW_XDISPLAY(widget->window), &xev, 0);
758 # endif
657 } 759 }
658 return FALSE; 760 return FALSE;
659 } 761 }
660 #endif 762 #endif /* defined(FEAT_CLIENTSERVER) */
661 763
662 764
663 /**************************************************************************** 765 /****************************************************************************
664 * Focus handlers: 766 * Focus handlers:
665 */ 767 */
680 static long_u blink_waittime = 700; 782 static long_u blink_waittime = 700;
681 static long_u blink_ontime = 400; 783 static long_u blink_ontime = 400;
682 static long_u blink_offtime = 250; 784 static long_u blink_offtime = 250;
683 static guint blink_timer = 0; 785 static guint blink_timer = 0;
684 786
787 #if GTK_CHECK_VERSION(3,0,0)
788 static gboolean
789 gui_gtk_is_blink_on(void)
790 {
791 return blink_state == BLINK_ON;
792 }
793
794 static gboolean
795 gui_gtk_is_no_blink(void)
796 {
797 return blink_waittime == 0 || blink_ontime == 0 || blink_offtime == 0;
798 }
799 #endif
800
685 void 801 void
686 gui_mch_set_blinking(long waittime, long on, long off) 802 gui_mch_set_blinking(long waittime, long on, long off)
687 { 803 {
688 blink_waittime = waittime; 804 blink_waittime = waittime;
689 blink_ontime = on; 805 blink_ontime = on;
696 void 812 void
697 gui_mch_stop_blink(void) 813 gui_mch_stop_blink(void)
698 { 814 {
699 if (blink_timer) 815 if (blink_timer)
700 { 816 {
817 #if GTK_CHECK_VERSION(3,0,0)
818 g_source_remove(blink_timer);
819 #else
701 gtk_timeout_remove(blink_timer); 820 gtk_timeout_remove(blink_timer);
821 #endif
702 blink_timer = 0; 822 blink_timer = 0;
703 } 823 }
704 if (blink_state == BLINK_OFF) 824 if (blink_state == BLINK_OFF)
705 gui_update_cursor(TRUE, FALSE); 825 gui_update_cursor(TRUE, FALSE);
706 blink_state = BLINK_NONE; 826 blink_state = BLINK_NONE;
707 } 827 }
708 828
829 #if GTK_CHECK_VERSION(3,0,0)
830 static gboolean
831 #else
709 static gint 832 static gint
833 #endif
710 blink_cb(gpointer data UNUSED) 834 blink_cb(gpointer data UNUSED)
711 { 835 {
712 if (blink_state == BLINK_ON) 836 if (blink_state == BLINK_ON)
713 { 837 {
714 gui_undraw_cursor(); 838 gui_undraw_cursor();
715 blink_state = BLINK_OFF; 839 blink_state = BLINK_OFF;
840 #if GTK_CHECK_VERSION(3,0,0)
841 blink_timer = g_timeout_add((guint)blink_offtime,
842 (GSourceFunc) blink_cb, NULL);
843 #else
716 blink_timer = gtk_timeout_add((guint32)blink_offtime, 844 blink_timer = gtk_timeout_add((guint32)blink_offtime,
717 (GtkFunction) blink_cb, NULL); 845 (GtkFunction) blink_cb, NULL);
846 #endif
718 } 847 }
719 else 848 else
720 { 849 {
721 gui_update_cursor(TRUE, FALSE); 850 gui_update_cursor(TRUE, FALSE);
722 blink_state = BLINK_ON; 851 blink_state = BLINK_ON;
852 #if GTK_CHECK_VERSION(3,0,0)
853 blink_timer = g_timeout_add((guint)blink_ontime,
854 (GSourceFunc) blink_cb, NULL);
855 #else
723 blink_timer = gtk_timeout_add((guint32)blink_ontime, 856 blink_timer = gtk_timeout_add((guint32)blink_ontime,
724 (GtkFunction) blink_cb, NULL); 857 (GtkFunction) blink_cb, NULL);
858 #endif
725 } 859 }
726 860
727 return FALSE; /* don't happen again */ 861 return FALSE; /* don't happen again */
728 } 862 }
729 863
734 void 868 void
735 gui_mch_start_blink(void) 869 gui_mch_start_blink(void)
736 { 870 {
737 if (blink_timer) 871 if (blink_timer)
738 { 872 {
873 #if GTK_CHECK_VERSION(3,0,0)
874 g_source_remove(blink_timer);
875 #else
739 gtk_timeout_remove(blink_timer); 876 gtk_timeout_remove(blink_timer);
877 #endif
740 blink_timer = 0; 878 blink_timer = 0;
741 } 879 }
742 /* Only switch blinking on if none of the times is zero */ 880 /* Only switch blinking on if none of the times is zero */
743 if (blink_waittime && blink_ontime && blink_offtime && gui.in_focus) 881 if (blink_waittime && blink_ontime && blink_offtime && gui.in_focus)
744 { 882 {
883 #if GTK_CHECK_VERSION(3,0,0)
884 blink_timer = g_timeout_add((guint)blink_waittime,
885 (GSourceFunc) blink_cb, NULL);
886 #else
745 blink_timer = gtk_timeout_add((guint32)blink_waittime, 887 blink_timer = gtk_timeout_add((guint32)blink_waittime,
746 (GtkFunction) blink_cb, NULL); 888 (GtkFunction) blink_cb, NULL);
889 #endif
747 blink_state = BLINK_ON; 890 blink_state = BLINK_ON;
748 gui_update_cursor(TRUE, FALSE); 891 gui_update_cursor(TRUE, FALSE);
749 } 892 }
750 } 893 }
751 894
756 { 899 {
757 if (blink_state == BLINK_NONE) 900 if (blink_state == BLINK_NONE)
758 gui_mch_start_blink(); 901 gui_mch_start_blink();
759 902
760 /* make sure keyboard input goes there */ 903 /* make sure keyboard input goes there */
904 #if GTK_CHECK_VERSION(3,0,0)
905 if (gtk_socket_id == 0 || !gtk_widget_has_focus(gui.drawarea))
906 #else
761 if (gtk_socket_id == 0 || !GTK_WIDGET_HAS_FOCUS(gui.drawarea)) 907 if (gtk_socket_id == 0 || !GTK_WIDGET_HAS_FOCUS(gui.drawarea))
908 #endif
762 gtk_widget_grab_focus(gui.drawarea); 909 gtk_widget_grab_focus(gui.drawarea);
763 910
764 return FALSE; 911 return FALSE;
765 } 912 }
766 913
936 int modifiers; 1083 int modifiers;
937 int key; 1084 int key;
938 guint state; 1085 guint state;
939 char_u *s, *d; 1086 char_u *s, *d;
940 1087
1088 #if GTK_CHECK_VERSION(3,0,0)
1089 is_key_pressed = TRUE;
1090 gui_mch_stop_blink();
1091 #endif
1092
941 gui.event_time = event->time; 1093 gui.event_time = event->time;
942 key_sym = event->keyval; 1094 key_sym = event->keyval;
943 state = event->state; 1095 state = event->state;
944 1096
945 #ifdef FEAT_XIM 1097 #ifdef FEAT_XIM
1125 gui_mch_mousehide(TRUE); 1277 gui_mch_mousehide(TRUE);
1126 1278
1127 return TRUE; 1279 return TRUE;
1128 } 1280 }
1129 1281
1130 #if defined(FEAT_XIM) 1282 #if defined(FEAT_XIM) || GTK_CHECK_VERSION(3,0,0)
1131 static gboolean 1283 static gboolean
1132 key_release_event(GtkWidget *widget UNUSED, 1284 key_release_event(GtkWidget *widget UNUSED,
1133 GdkEventKey *event, 1285 GdkEventKey *event,
1134 gpointer data UNUSED) 1286 gpointer data UNUSED)
1135 { 1287 {
1288 # if GTK_CHECK_VERSION(3,0,0)
1289 is_key_pressed = FALSE;
1290 gui_mch_start_blink();
1291 # endif
1292 # if defined(FEAT_XIM)
1136 gui.event_time = event->time; 1293 gui.event_time = event->time;
1137 /* 1294 /*
1138 * GTK+ 2 input methods may do fancy stuff on key release events too. 1295 * GTK+ 2 input methods may do fancy stuff on key release events too.
1139 * With the default IM for instance, you can enter any UCS code point 1296 * With the default IM for instance, you can enter any UCS code point
1140 * by holding down CTRL-SHIFT and typing hexadecimal digits. 1297 * by holding down CTRL-SHIFT and typing hexadecimal digits.
1141 */ 1298 */
1142 return xim_queue_key_press_event(event, FALSE); 1299 return xim_queue_key_press_event(event, FALSE);
1300 # else
1301 return TRUE;
1302 # endif
1143 } 1303 }
1144 #endif 1304 #endif
1145 1305
1146 1306
1147 /**************************************************************************** 1307 /****************************************************************************
1177 char_u *tmpbuf = NULL; 1337 char_u *tmpbuf = NULL;
1178 guchar *tmpbuf_utf8 = NULL; 1338 guchar *tmpbuf_utf8 = NULL;
1179 int len; 1339 int len;
1180 int motion_type = MAUTO; 1340 int motion_type = MAUTO;
1181 1341
1342 #if GTK_CHECK_VERSION(3,0,0)
1343 if (gtk_selection_data_get_selection(data) == clip_plus.gtk_sel_atom)
1344 #else
1182 if (data->selection == clip_plus.gtk_sel_atom) 1345 if (data->selection == clip_plus.gtk_sel_atom)
1346 #endif
1183 cbd = &clip_plus; 1347 cbd = &clip_plus;
1184 else 1348 else
1185 cbd = &clip_star; 1349 cbd = &clip_star;
1186 1350
1351 #if GTK_CHECK_VERSION(3,0,0)
1352 text = (char_u *)gtk_selection_data_get_data(data);
1353 len = gtk_selection_data_get_length(data);
1354 #else
1187 text = (char_u *)data->data; 1355 text = (char_u *)data->data;
1188 len = data->length; 1356 len = data->length;
1357 #endif
1189 1358
1190 if (text == NULL || len <= 0) 1359 if (text == NULL || len <= 0)
1191 { 1360 {
1192 received_selection = RS_FAIL; 1361 received_selection = RS_FAIL;
1193 /* clip_free_selection(cbd); ??? */ 1362 /* clip_free_selection(cbd); ??? */
1194 1363
1195 return; 1364 return;
1196 } 1365 }
1197 1366
1367 #if GTK_CHECK_VERSION(3,0,0)
1368 if (gtk_selection_data_get_data_type(data) == vim_atom)
1369 #else
1198 if (data->type == vim_atom) 1370 if (data->type == vim_atom)
1371 #endif
1199 { 1372 {
1200 motion_type = *text++; 1373 motion_type = *text++;
1201 --len; 1374 --len;
1202 } 1375 }
1203 1376 #if GTK_CHECK_VERSION(3,0,0)
1377 else if (gtk_selection_data_get_data_type(data) == vimenc_atom)
1378 #else
1204 else if (data->type == vimenc_atom) 1379 else if (data->type == vimenc_atom)
1380 #endif
1205 { 1381 {
1206 char_u *enc; 1382 char_u *enc;
1207 vimconv_T conv; 1383 vimconv_T conv;
1208 1384
1209 motion_type = *text++; 1385 motion_type = *text++;
1290 int length; 1466 int length;
1291 int motion_type; 1467 int motion_type;
1292 GdkAtom type; 1468 GdkAtom type;
1293 VimClipboard *cbd; 1469 VimClipboard *cbd;
1294 1470
1471 #if GTK_CHECK_VERSION(3,0,0)
1472 if (gtk_selection_data_get_selection(selection_data)
1473 == clip_plus.gtk_sel_atom)
1474 #else
1295 if (selection_data->selection == clip_plus.gtk_sel_atom) 1475 if (selection_data->selection == clip_plus.gtk_sel_atom)
1476 #endif
1296 cbd = &clip_plus; 1477 cbd = &clip_plus;
1297 else 1478 else
1298 cbd = &clip_star; 1479 cbd = &clip_star;
1299 1480
1300 if (!cbd->owned) 1481 if (!cbd->owned)
1359 mch_memmove(tmpbuf + 2, string, (size_t)length); 1540 mch_memmove(tmpbuf + 2, string, (size_t)length);
1360 vim_free(string); 1541 vim_free(string);
1361 string = tmpbuf; 1542 string = tmpbuf;
1362 length += 2; 1543 length += 2;
1363 1544
1545 #if !GTK_CHECK_VERSION(3,0,0)
1546 /* Looks redandunt even for GTK2 because these values are
1547 * overwritten by gtk_selection_data_set() that follows. */
1364 selection_data->type = selection_data->target; 1548 selection_data->type = selection_data->target;
1365 selection_data->format = 16; /* 16 bits per char */ 1549 selection_data->format = 16; /* 16 bits per char */
1550 #endif
1366 gtk_selection_data_set(selection_data, html_atom, 16, 1551 gtk_selection_data_set(selection_data, html_atom, 16,
1367 string, length); 1552 string, length);
1368 vim_free(string); 1553 vim_free(string);
1369 } 1554 }
1370 return; 1555 return;
1409 return; 1594 return;
1410 } 1595 }
1411 1596
1412 if (string != NULL) 1597 if (string != NULL)
1413 { 1598 {
1599 #if !GTK_CHECK_VERSION(3,0,0)
1600 /* Looks redandunt even for GTK2 because these values are
1601 * overwritten by gtk_selection_data_set() that follows. */
1414 selection_data->type = selection_data->target; 1602 selection_data->type = selection_data->target;
1415 selection_data->format = 8; /* 8 bits per char */ 1603 selection_data->format = 8; /* 8 bits per char */
1416 1604 #endif
1417 gtk_selection_data_set(selection_data, type, 8, string, length); 1605 gtk_selection_data_set(selection_data, type, 8, string, length);
1418 vim_free(string); 1606 vim_free(string);
1419 } 1607 }
1420 } 1608 }
1421 1609
1491 static int mouse_timed_out = TRUE; 1679 static int mouse_timed_out = TRUE;
1492 1680
1493 /* 1681 /*
1494 * Timer used to recognize multiple clicks of the mouse button 1682 * Timer used to recognize multiple clicks of the mouse button
1495 */ 1683 */
1684 #if GTK_CHECK_VERSION(3,0,0)
1685 static gboolean
1686 #else
1496 static gint 1687 static gint
1688 #endif
1497 mouse_click_timer_cb(gpointer data) 1689 mouse_click_timer_cb(gpointer data)
1498 { 1690 {
1499 /* we don't use this information currently */ 1691 /* we don't use this information currently */
1500 int *timed_out = (int *) data; 1692 int *timed_out = (int *) data;
1501 1693
1503 return FALSE; /* don't happen again */ 1695 return FALSE; /* don't happen again */
1504 } 1696 }
1505 1697
1506 static guint motion_repeat_timer = 0; 1698 static guint motion_repeat_timer = 0;
1507 static int motion_repeat_offset = FALSE; 1699 static int motion_repeat_offset = FALSE;
1700 #ifdef GTK_DEST_DEFAULT_ALL
1701 static gboolean motion_repeat_timer_cb(gpointer);
1702 #else
1508 static gint motion_repeat_timer_cb(gpointer); 1703 static gint motion_repeat_timer_cb(gpointer);
1704 #endif
1509 1705
1510 static void 1706 static void
1511 process_motion_notify(int x, int y, GdkModifierType state) 1707 process_motion_notify(int x, int y, GdkModifierType state)
1512 { 1708 {
1513 int button; 1709 int button;
1514 int_u vim_modifiers; 1710 int_u vim_modifiers;
1711 #if GTK_CHECK_VERSION(3,0,0)
1712 GtkAllocation allocation;
1713 #endif
1515 1714
1516 button = (state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | 1715 button = (state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK |
1517 GDK_BUTTON3_MASK | GDK_BUTTON4_MASK | 1716 GDK_BUTTON3_MASK | GDK_BUTTON4_MASK |
1518 GDK_BUTTON5_MASK)) 1717 GDK_BUTTON5_MASK))
1519 ? MOUSE_DRAG : ' '; 1718 ? MOUSE_DRAG : ' ';
1536 gui_send_mouse_event(button, x, y, FALSE, vim_modifiers); 1735 gui_send_mouse_event(button, x, y, FALSE, vim_modifiers);
1537 1736
1538 /* 1737 /*
1539 * Auto repeat timer handling. 1738 * Auto repeat timer handling.
1540 */ 1739 */
1740 #if GTK_CHECK_VERSION(3,0,0)
1741 gtk_widget_get_allocation(gui.drawarea, &allocation);
1742
1743 if (x < 0 || y < 0
1744 || x >= allocation.width
1745 || y >= allocation.height)
1746 #else
1541 if (x < 0 || y < 0 1747 if (x < 0 || y < 0
1542 || x >= gui.drawarea->allocation.width 1748 || x >= gui.drawarea->allocation.width
1543 || y >= gui.drawarea->allocation.height) 1749 || y >= gui.drawarea->allocation.height)
1750 #endif
1544 { 1751 {
1545 1752
1546 int dx; 1753 int dx;
1547 int dy; 1754 int dy;
1548 int offshoot; 1755 int offshoot;
1549 int delay = 10; 1756 int delay = 10;
1550 1757
1551 /* Calculate the maximal distance of the cursor from the drawing area. 1758 /* Calculate the maximal distance of the cursor from the drawing area.
1552 * (offshoot can't become negative here!). 1759 * (offshoot can't become negative here!).
1553 */ 1760 */
1761 #if GTK_CHECK_VERSION(3,0,0)
1762 dx = x < 0 ? -x : x - allocation.width;
1763 dy = y < 0 ? -y : y - allocation.height;
1764 #else
1554 dx = x < 0 ? -x : x - gui.drawarea->allocation.width; 1765 dx = x < 0 ? -x : x - gui.drawarea->allocation.width;
1555 dy = y < 0 ? -y : y - gui.drawarea->allocation.height; 1766 dy = y < 0 ? -y : y - gui.drawarea->allocation.height;
1767 #endif
1556 1768
1557 offshoot = dx > dy ? dx : dy; 1769 offshoot = dx > dy ? dx : dy;
1558 1770
1559 /* Make a linearly decaying timer delay with a threshold of 5 at a 1771 /* Make a linearly decaying timer delay with a threshold of 5 at a
1560 * distance of 127 pixels from the main window. 1772 * distance of 127 pixels from the main window.
1575 delay = (130 * (127 - offshoot)) / 127 + 5; 1787 delay = (130 * (127 - offshoot)) / 127 + 5;
1576 } 1788 }
1577 1789
1578 /* shoot again */ 1790 /* shoot again */
1579 if (!motion_repeat_timer) 1791 if (!motion_repeat_timer)
1792 #if GTK_CHECK_VERSION(3,0,0)
1793 motion_repeat_timer = g_timeout_add((guint)delay,
1794 motion_repeat_timer_cb, NULL);
1795 #else
1580 motion_repeat_timer = gtk_timeout_add((guint32)delay, 1796 motion_repeat_timer = gtk_timeout_add((guint32)delay,
1581 motion_repeat_timer_cb, NULL); 1797 motion_repeat_timer_cb, NULL);
1582 } 1798 #endif
1583 } 1799 }
1800 }
1801
1802 #if GTK_CHECK_VERSION(3,0,0)
1803 static GdkDevice *
1804 gui_gtk_get_pointer_device(GtkWidget *widget)
1805 {
1806 GdkWindow * const win = gtk_widget_get_window(widget);
1807 GdkDisplay * const dpy = gdk_window_get_display(win);
1808 GdkDeviceManager * const mngr = gdk_display_get_device_manager(dpy);
1809 return gdk_device_manager_get_client_pointer(mngr);
1810 }
1811
1812 static GdkWindow *
1813 gui_gtk_get_pointer(GtkWidget *widget,
1814 gint *x,
1815 gint *y,
1816 GdkModifierType *state)
1817 {
1818 GdkWindow * const win = gtk_widget_get_window(widget);
1819 GdkDevice * const dev = gui_gtk_get_pointer_device(widget);
1820 return gdk_window_get_device_position(win, dev , x, y, state);
1821 }
1822
1823 static GdkWindow *
1824 gui_gtk_window_at_position(GtkWidget *widget,
1825 gint *x,
1826 gint *y)
1827 {
1828 GdkDevice * const dev = gui_gtk_get_pointer_device(widget);
1829 return gdk_device_get_window_at_position(dev, x, y);
1830 }
1831 #endif
1584 1832
1585 /* 1833 /*
1586 * Timer used to recognize multiple clicks of the mouse button. 1834 * Timer used to recognize multiple clicks of the mouse button.
1587 */ 1835 */
1836 #if GTK_CHECK_VERSION(3,0,0)
1837 static gboolean
1838 #else
1588 static gint 1839 static gint
1840 #endif
1589 motion_repeat_timer_cb(gpointer data UNUSED) 1841 motion_repeat_timer_cb(gpointer data UNUSED)
1590 { 1842 {
1591 int x; 1843 int x;
1592 int y; 1844 int y;
1593 GdkModifierType state; 1845 GdkModifierType state;
1594 1846
1847 #if GTK_CHECK_VERSION(3,0,0)
1848 gui_gtk_get_pointer(gui.drawarea, &x, &y, &state);
1849 #else
1595 gdk_window_get_pointer(gui.drawarea->window, &x, &y, &state); 1850 gdk_window_get_pointer(gui.drawarea->window, &x, &y, &state);
1851 #endif
1596 1852
1597 if (!(state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | 1853 if (!(state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK |
1598 GDK_BUTTON3_MASK | GDK_BUTTON4_MASK | 1854 GDK_BUTTON3_MASK | GDK_BUTTON4_MASK |
1599 GDK_BUTTON5_MASK))) 1855 GDK_BUTTON5_MASK)))
1600 { 1856 {
1635 { 1891 {
1636 int x; 1892 int x;
1637 int y; 1893 int y;
1638 GdkModifierType state; 1894 GdkModifierType state;
1639 1895
1896 #if GTK_CHECK_VERSION(3,0,0)
1897 gui_gtk_get_pointer(widget, &x, &y, &state);
1898 #else
1640 gdk_window_get_pointer(widget->window, &x, &y, &state); 1899 gdk_window_get_pointer(widget->window, &x, &y, &state);
1900 #endif
1641 process_motion_notify(x, y, state); 1901 process_motion_notify(x, y, state);
1642 } 1902 }
1643 else 1903 else
1644 { 1904 {
1645 process_motion_notify((int)event->x, (int)event->y, 1905 process_motion_notify((int)event->x, (int)event->y,
1666 int_u vim_modifiers; 1926 int_u vim_modifiers;
1667 1927
1668 gui.event_time = event->time; 1928 gui.event_time = event->time;
1669 1929
1670 /* Make sure we have focus now we've been selected */ 1930 /* Make sure we have focus now we've been selected */
1931 #if GTK_CHECK_VERSION(3,0,0)
1932 if (gtk_socket_id != 0 && !gtk_widget_has_focus(widget))
1933 #else
1671 if (gtk_socket_id != 0 && !GTK_WIDGET_HAS_FOCUS(widget)) 1934 if (gtk_socket_id != 0 && !GTK_WIDGET_HAS_FOCUS(widget))
1935 #endif
1672 gtk_widget_grab_focus(widget); 1936 gtk_widget_grab_focus(widget);
1673 1937
1674 /* 1938 /*
1675 * Don't let additional events about multiple clicks send by GTK to us 1939 * Don't let additional events about multiple clicks send by GTK to us
1676 * after the initial button press event confuse us. 1940 * after the initial button press event confuse us.
1682 y = event->y; 1946 y = event->y;
1683 1947
1684 /* Handle multiple clicks */ 1948 /* Handle multiple clicks */
1685 if (!mouse_timed_out && mouse_click_timer) 1949 if (!mouse_timed_out && mouse_click_timer)
1686 { 1950 {
1951 #if GTK_CHECK_VERSION(3,0,0)
1952 g_source_remove(mouse_click_timer);
1953 #else
1687 gtk_timeout_remove(mouse_click_timer); 1954 gtk_timeout_remove(mouse_click_timer);
1955 #endif
1688 mouse_click_timer = 0; 1956 mouse_click_timer = 0;
1689 repeated_click = TRUE; 1957 repeated_click = TRUE;
1690 } 1958 }
1691 1959
1692 mouse_timed_out = FALSE; 1960 mouse_timed_out = FALSE;
1961 #if GTK_CHECK_VERSION(3,0,0)
1962 mouse_click_timer = g_timeout_add((guint)p_mouset,
1963 mouse_click_timer_cb, &mouse_timed_out);
1964 #else
1693 mouse_click_timer = gtk_timeout_add((guint32)p_mouset, 1965 mouse_click_timer = gtk_timeout_add((guint32)p_mouset,
1694 mouse_click_timer_cb, &mouse_timed_out); 1966 mouse_click_timer_cb, &mouse_timed_out);
1967 #endif
1695 1968
1696 switch (event->button) 1969 switch (event->button)
1697 { 1970 {
1698 /* Keep in sync with gui_x11.c. 1971 /* Keep in sync with gui_x11.c.
1699 * Buttons 4-7 are handled in scroll_event() */ 1972 * Buttons 4-7 are handled in scroll_event() */
1728 gpointer data UNUSED) 2001 gpointer data UNUSED)
1729 { 2002 {
1730 int button; 2003 int button;
1731 int_u vim_modifiers; 2004 int_u vim_modifiers;
1732 2005
2006 #if GTK_CHECK_VERSION(3,0,0)
2007 if (gtk_socket_id != 0 && !gtk_widget_has_focus(widget))
2008 #else
1733 if (gtk_socket_id != 0 && !GTK_WIDGET_HAS_FOCUS(widget)) 2009 if (gtk_socket_id != 0 && !GTK_WIDGET_HAS_FOCUS(widget))
2010 #endif
1734 gtk_widget_grab_focus(widget); 2011 gtk_widget_grab_focus(widget);
1735 2012
1736 switch (event->direction) 2013 switch (event->direction)
1737 { 2014 {
1738 case GDK_SCROLL_UP: 2015 case GDK_SCROLL_UP:
1779 /* Remove any motion "machine gun" timers used for automatic further 2056 /* Remove any motion "machine gun" timers used for automatic further
1780 extension of allocation areas if outside of the applications window 2057 extension of allocation areas if outside of the applications window
1781 area .*/ 2058 area .*/
1782 if (motion_repeat_timer) 2059 if (motion_repeat_timer)
1783 { 2060 {
2061 #if GTK_CHECK_VERSION(3,0,0)
2062 g_source_remove(motion_repeat_timer);
2063 #else
1784 gtk_timeout_remove(motion_repeat_timer); 2064 gtk_timeout_remove(motion_repeat_timer);
2065 #endif
1785 motion_repeat_timer = 0; 2066 motion_repeat_timer = 0;
1786 } 2067 }
1787 2068
1788 x = event->x; 2069 x = event->x;
1789 y = event->y; 2070 y = event->y;
1894 gint y) 2175 gint y)
1895 { 2176 {
1896 char_u **fnames; 2177 char_u **fnames;
1897 int nfiles = 0; 2178 int nfiles = 0;
1898 2179
2180 # if GTK_CHECK_VERSION(3,0,0)
2181 fnames = parse_uri_list(&nfiles,
2182 (char_u *)gtk_selection_data_get_data(data),
2183 gtk_selection_data_get_length(data));
2184 # else
1899 fnames = parse_uri_list(&nfiles, data->data, data->length); 2185 fnames = parse_uri_list(&nfiles, data->data, data->length);
2186 # endif
1900 2187
1901 if (fnames != NULL && nfiles > 0) 2188 if (fnames != NULL && nfiles > 0)
1902 { 2189 {
1903 int_u modifiers; 2190 int_u modifiers;
1904 2191
1921 char_u dropkey[6] = {CSI, KS_MODIFIER, 0, CSI, KS_EXTRA, (char_u)KE_DROP}; 2208 char_u dropkey[6] = {CSI, KS_MODIFIER, 0, CSI, KS_EXTRA, (char_u)KE_DROP};
1922 char_u *text; 2209 char_u *text;
1923 int len; 2210 int len;
1924 char_u *tmpbuf = NULL; 2211 char_u *tmpbuf = NULL;
1925 2212
2213 # if GTK_CHECK_VERSION(3,0,0)
2214 text = (char_u *)gtk_selection_data_get_data(data);
2215 len = gtk_selection_data_get_length(data);
2216 # else
1926 text = data->data; 2217 text = data->data;
1927 len = data->length; 2218 len = data->length;
1928 2219 # endif
2220
2221 # if GTK_CHECK_VERSION(3,0,0)
2222 if (gtk_selection_data_get_data_type(data) == utf8_string_atom)
2223 # else
1929 if (data->type == utf8_string_atom) 2224 if (data->type == utf8_string_atom)
2225 # endif
1930 { 2226 {
1931 if (input_conv.vc_type != CONV_NONE) 2227 if (input_conv.vc_type != CONV_NONE)
1932 tmpbuf = string_convert(&input_conv, text, &len); 2228 tmpbuf = string_convert(&input_conv, text, &len);
1933 if (tmpbuf != NULL) 2229 if (tmpbuf != NULL)
1934 text = tmpbuf; 2230 text = tmpbuf;
1960 gpointer user_data UNUSED) 2256 gpointer user_data UNUSED)
1961 { 2257 {
1962 GdkModifierType state; 2258 GdkModifierType state;
1963 2259
1964 /* Guard against trash */ 2260 /* Guard against trash */
2261 # if GTK_CHECK_VERSION(3,0,0)
2262 const guchar * const data_data = gtk_selection_data_get_data(data);
2263 const gint data_length = gtk_selection_data_get_length(data);
2264 const gint data_format = gtk_selection_data_get_format(data);
2265
2266 if (data_data == NULL
2267 || data_length <= 0
2268 || data_format != 8
2269 || data_data[data_length] != '\0')
2270 # else
1965 if (data->data == NULL 2271 if (data->data == NULL
1966 || data->length <= 0 2272 || data->length <= 0
1967 || data->format != 8 2273 || data->format != 8
1968 || data->data[data->length] != '\0') 2274 || data->data[data->length] != '\0')
2275 # endif
1969 { 2276 {
1970 gtk_drag_finish(context, FALSE, FALSE, time_); 2277 gtk_drag_finish(context, FALSE, FALSE, time_);
1971 return; 2278 return;
1972 } 2279 }
1973 2280
1974 /* Get the current modifier state for proper distinguishment between 2281 /* Get the current modifier state for proper distinguishment between
1975 * different operations later. */ 2282 * different operations later. */
2283 #if GTK_CHECK_VERSION(3,0,0)
2284 gui_gtk_get_pointer(widget, NULL, NULL, &state);
2285 # else
1976 gdk_window_get_pointer(widget->window, NULL, NULL, &state); 2286 gdk_window_get_pointer(widget->window, NULL, NULL, &state);
2287 # endif
1977 2288
1978 /* Not sure about the role of "text/plain" here... */ 2289 /* Not sure about the role of "text/plain" here... */
1979 if (info == (guint)TARGET_TEXT_URI_LIST) 2290 if (info == (guint)TARGET_TEXT_URI_LIST)
1980 drag_handle_uri_list(context, data, time_, state, x, y); 2291 drag_handle_uri_list(context, data, time_, state, x, y);
1981 else 2292 else
2251 setup_save_yourself(void) 2562 setup_save_yourself(void)
2252 { 2563 {
2253 Atom *existing_atoms = NULL; 2564 Atom *existing_atoms = NULL;
2254 int count = 0; 2565 int count = 0;
2255 2566
2256 #ifdef USE_XSMP 2567 # ifdef USE_XSMP
2257 if (xsmp_icefd != -1) 2568 if (xsmp_icefd != -1)
2258 { 2569 {
2259 /* 2570 /*
2260 * Use XSMP is preference to legacy WM_SAVE_YOURSELF; 2571 * Use XSMP is preference to legacy WM_SAVE_YOURSELF;
2261 * set up GTK IO monitor 2572 * set up GTK IO monitor
2262 */ 2573 */
2263 GIOChannel *g_io = g_io_channel_unix_new(xsmp_icefd); 2574 GIOChannel *g_io = g_io_channel_unix_new(xsmp_icefd);
2264 2575
2265 g_io_add_watch(g_io, G_IO_IN | G_IO_ERR | G_IO_HUP, 2576 g_io_add_watch(g_io, G_IO_IN | G_IO_ERR | G_IO_HUP,
2266 local_xsmp_handle_requests, (gpointer)g_io); 2577 local_xsmp_handle_requests, (gpointer)g_io);
2578 g_io_channel_unref(g_io);
2267 } 2579 }
2268 else 2580 else
2269 #endif 2581 # endif
2270 { 2582 {
2271 /* Fall back to old method */ 2583 /* Fall back to old method */
2272 2584
2273 /* first get the existing value */ 2585 /* first get the existing value */
2586 # if GTK_CHECK_VERSION(3,0,0)
2587 GdkWindow * const mainwin_win = gtk_widget_get_window(gui.mainwin);
2588
2589 if (XGetWMProtocols(GDK_WINDOW_XDISPLAY(mainwin_win),
2590 GDK_WINDOW_XID(mainwin_win),
2591 &existing_atoms, &count))
2592 # else
2274 if (XGetWMProtocols(GDK_WINDOW_XDISPLAY(gui.mainwin->window), 2593 if (XGetWMProtocols(GDK_WINDOW_XDISPLAY(gui.mainwin->window),
2275 GDK_WINDOW_XWINDOW(gui.mainwin->window), 2594 GDK_WINDOW_XWINDOW(gui.mainwin->window),
2276 &existing_atoms, &count)) 2595 &existing_atoms, &count))
2596 # endif
2277 { 2597 {
2278 Atom *new_atoms; 2598 Atom *new_atoms;
2279 Atom save_yourself_xatom; 2599 Atom save_yourself_xatom;
2280 int i; 2600 int i;
2281 2601
2293 * sizeof(Atom))); 2613 * sizeof(Atom)));
2294 if (new_atoms != NULL) 2614 if (new_atoms != NULL)
2295 { 2615 {
2296 memcpy(new_atoms, existing_atoms, count * sizeof(Atom)); 2616 memcpy(new_atoms, existing_atoms, count * sizeof(Atom));
2297 new_atoms[count] = save_yourself_xatom; 2617 new_atoms[count] = save_yourself_xatom;
2618 # if GTK_CHECK_VERSION(3,0,0)
2619 XSetWMProtocols(GDK_WINDOW_XDISPLAY(mainwin_win),
2620 GDK_WINDOW_XID(mainwin_win),
2621 # else
2298 XSetWMProtocols(GDK_WINDOW_XDISPLAY(gui.mainwin->window), 2622 XSetWMProtocols(GDK_WINDOW_XDISPLAY(gui.mainwin->window),
2299 GDK_WINDOW_XWINDOW(gui.mainwin->window), 2623 GDK_WINDOW_XWINDOW(gui.mainwin->window),
2624 # endif
2300 new_atoms, count + 1); 2625 new_atoms, count + 1);
2301 vim_free(new_atoms); 2626 vim_free(new_atoms);
2302 } 2627 }
2303 } 2628 }
2304 XFree(existing_atoms); 2629 XFree(existing_atoms);
2339 /* 2664 /*
2340 * Set the window's WM_COMMAND property, to let the window manager 2665 * Set the window's WM_COMMAND property, to let the window manager
2341 * know we are done saving ourselves. We don't want to be 2666 * know we are done saving ourselves. We don't want to be
2342 * restarted, thus set argv to NULL. 2667 * restarted, thus set argv to NULL.
2343 */ 2668 */
2669 # if GTK_CHECK_VERSION(3,0,0)
2670 XSetCommand(GDK_WINDOW_XDISPLAY(gtk_widget_get_window(gui.mainwin)),
2671 GDK_WINDOW_XID(gtk_widget_get_window(gui.mainwin)),
2672 # else
2344 XSetCommand(GDK_WINDOW_XDISPLAY(gui.mainwin->window), 2673 XSetCommand(GDK_WINDOW_XDISPLAY(gui.mainwin->window),
2345 GDK_WINDOW_XWINDOW(gui.mainwin->window), 2674 GDK_WINDOW_XWINDOW(gui.mainwin->window),
2675 # endif
2346 NULL, 0); 2676 NULL, 0);
2347 return GDK_FILTER_REMOVE; 2677 return GDK_FILTER_REMOVE;
2348 } 2678 }
2349 2679
2350 return GDK_FILTER_CONTINUE; 2680 return GDK_FILTER_CONTINUE;
2374 #define magick vim48x48 2704 #define magick vim48x48
2375 #include "../runtime/vim48x48.xpm" 2705 #include "../runtime/vim48x48.xpm"
2376 #undef magick 2706 #undef magick
2377 # undef static 2707 # undef static
2378 2708
2709 #if GTK_CHECK_VERSION(3,0,0)
2710 GdkWindow * const mainwin_win = gtk_widget_get_window(gui.mainwin);
2711 #endif
2712
2379 /* When started with "--echo-wid" argument, write window ID on stdout. */ 2713 /* When started with "--echo-wid" argument, write window ID on stdout. */
2380 if (echo_wid_arg) 2714 if (echo_wid_arg)
2381 { 2715 {
2716 #if GTK_CHECK_VERSION(3,0,0)
2717 printf("WID: %ld\n", (long)GDK_WINDOW_XID(mainwin_win));
2718 #else
2382 printf("WID: %ld\n", (long)GDK_WINDOW_XWINDOW(gui.mainwin->window)); 2719 printf("WID: %ld\n", (long)GDK_WINDOW_XWINDOW(gui.mainwin->window));
2720 #endif
2383 fflush(stdout); 2721 fflush(stdout);
2384 } 2722 }
2385 2723
2386 if (vim_strchr(p_go, GO_ICON) != NULL) 2724 if (vim_strchr(p_go, GO_ICON) != NULL)
2387 { 2725 {
2414 2752
2415 #ifdef FEAT_CLIENTSERVER 2753 #ifdef FEAT_CLIENTSERVER
2416 if (serverName == NULL && serverDelayedStartName != NULL) 2754 if (serverName == NULL && serverDelayedStartName != NULL)
2417 { 2755 {
2418 /* This is a :gui command in a plain vim with no previous server */ 2756 /* This is a :gui command in a plain vim with no previous server */
2757 # if GTK_CHECK_VERSION(3,0,0)
2758 commWindow = GDK_WINDOW_XID(mainwin_win);
2759
2760 (void)serverRegisterName(GDK_WINDOW_XDISPLAY(mainwin_win),
2761 serverDelayedStartName);
2762 # else
2419 commWindow = GDK_WINDOW_XWINDOW(gui.mainwin->window); 2763 commWindow = GDK_WINDOW_XWINDOW(gui.mainwin->window);
2420 2764
2421 (void)serverRegisterName(GDK_WINDOW_XDISPLAY(gui.mainwin->window), 2765 (void)serverRegisterName(GDK_WINDOW_XDISPLAY(gui.mainwin->window),
2422 serverDelayedStartName); 2766 serverDelayedStartName);
2767 # endif
2423 } 2768 }
2424 else 2769 else
2425 { 2770 {
2426 /* 2771 /*
2427 * Cannot handle "XLib-only" windows with gtk event routines, we'll 2772 * Cannot handle "XLib-only" windows with gtk event routines, we'll
2428 * have to change the "server" registration to that of the main window 2773 * have to change the "server" registration to that of the main window
2429 * If we have not registered a name yet, remember the window 2774 * If we have not registered a name yet, remember the window
2430 */ 2775 */
2776 # if GTK_CHECK_VERSION(3,0,0)
2777 serverChangeRegisteredWindow(GDK_WINDOW_XDISPLAY(mainwin_win),
2778 GDK_WINDOW_XID(mainwin_win));
2779 # else
2431 serverChangeRegisteredWindow(GDK_WINDOW_XDISPLAY(gui.mainwin->window), 2780 serverChangeRegisteredWindow(GDK_WINDOW_XDISPLAY(gui.mainwin->window),
2432 GDK_WINDOW_XWINDOW(gui.mainwin->window)); 2781 GDK_WINDOW_XWINDOW(gui.mainwin->window));
2782 # endif
2433 } 2783 }
2434 gtk_widget_add_events(gui.mainwin, GDK_PROPERTY_CHANGE_MASK); 2784 gtk_widget_add_events(gui.mainwin, GDK_PROPERTY_CHANGE_MASK);
2785 # if GTK_CHECK_VERSION(3,0,0)
2786 g_signal_connect(G_OBJECT(gui.mainwin), "property-notify-event",
2787 G_CALLBACK(property_event), NULL);
2788 # else
2435 gtk_signal_connect(GTK_OBJECT(gui.mainwin), "property_notify_event", 2789 gtk_signal_connect(GTK_OBJECT(gui.mainwin), "property_notify_event",
2436 GTK_SIGNAL_FUNC(property_event), NULL); 2790 GTK_SIGNAL_FUNC(property_event), NULL);
2791 # endif
2437 #endif 2792 #endif
2438 } 2793 }
2439 2794
2440 static GdkCursor * 2795 static GdkCursor *
2441 create_blank_pointer(void) 2796 create_blank_pointer(void)
2442 { 2797 {
2443 GdkWindow *root_window = NULL; 2798 GdkWindow *root_window = NULL;
2799 #if GTK_CHECK_VERSION(3,0,0)
2800 GdkPixbuf *blank_mask;
2801 #else
2444 GdkPixmap *blank_mask; 2802 GdkPixmap *blank_mask;
2803 #endif
2445 GdkCursor *cursor; 2804 GdkCursor *cursor;
2446 GdkColor color = { 0, 0, 0, 0 }; 2805 GdkColor color = { 0, 0, 0, 0 };
2806 #if !GTK_CHECK_VERSION(3,0,0)
2447 char blank_data[] = { 0x0 }; 2807 char blank_data[] = { 0x0 };
2808 #endif
2448 2809
2449 #ifdef HAVE_GTK_MULTIHEAD 2810 #ifdef HAVE_GTK_MULTIHEAD
2811 # if GTK_CHECK_VERSION(3,12,0)
2812 {
2813 GdkWindow * const win = gtk_widget_get_window(gui.mainwin);
2814 GdkScreen * const scrn = gdk_window_get_screen(win);
2815 root_window = gdk_screen_get_root_window(scrn);
2816 }
2817 # else
2450 root_window = gtk_widget_get_root_window(gui.mainwin); 2818 root_window = gtk_widget_get_root_window(gui.mainwin);
2819 # endif
2451 #endif 2820 #endif
2452 2821
2453 /* Create a pseudo blank pointer, which is in fact one pixel by one pixel 2822 /* Create a pseudo blank pointer, which is in fact one pixel by one pixel
2454 * in size. */ 2823 * in size. */
2824 #if GTK_CHECK_VERSION(3,0,0)
2825 {
2826 cairo_surface_t *surf;
2827 cairo_t *cr;
2828
2829 surf = cairo_image_surface_create(CAIRO_FORMAT_A1, 1, 1);
2830 cr = cairo_create(surf);
2831
2832 cairo_set_source_rgb(cr,
2833 color.red / 65535.0,
2834 color.green / 65535.0,
2835 color.blue / 65535.0);
2836 cairo_rectangle(cr, 0, 0, 1, 1);
2837 cairo_fill(cr);
2838 cairo_destroy(cr);
2839
2840 blank_mask = gdk_pixbuf_get_from_surface(surf, 0, 0, 1, 1);
2841 cairo_surface_destroy(surf);
2842
2843 cursor = gdk_cursor_new_from_pixbuf(gdk_window_get_display(root_window),
2844 blank_mask, 0, 0);
2845 g_object_unref(blank_mask);
2846 }
2847 #else
2455 blank_mask = gdk_bitmap_create_from_data(root_window, blank_data, 1, 1); 2848 blank_mask = gdk_bitmap_create_from_data(root_window, blank_data, 1, 1);
2456 cursor = gdk_cursor_new_from_pixmap(blank_mask, blank_mask, 2849 cursor = gdk_cursor_new_from_pixmap(blank_mask, blank_mask,
2457 &color, &color, 0, 0); 2850 &color, &color, 0, 0);
2458 gdk_bitmap_unref(blank_mask); 2851 gdk_bitmap_unref(blank_mask);
2852 #endif
2459 2853
2460 return cursor; 2854 return cursor;
2461 } 2855 }
2462 2856
2463 #ifdef HAVE_GTK_MULTIHEAD 2857 #ifdef HAVE_GTK_MULTIHEAD
2471 2865
2472 /* 2866 /*
2473 * Recreate the invisible mouse cursor. 2867 * Recreate the invisible mouse cursor.
2474 */ 2868 */
2475 if (gui.blank_pointer != NULL) 2869 if (gui.blank_pointer != NULL)
2870 # if GTK_CHECK_VERSION(3,0,0)
2871 g_object_unref(G_OBJECT(gui.blank_pointer));
2872 # else
2476 gdk_cursor_unref(gui.blank_pointer); 2873 gdk_cursor_unref(gui.blank_pointer);
2874 # endif
2477 2875
2478 gui.blank_pointer = create_blank_pointer(); 2876 gui.blank_pointer = create_blank_pointer();
2479 2877
2878 # if GTK_CHECK_VERSION(3,0,0)
2879 if (gui.pointer_hidden && gtk_widget_get_window(gui.drawarea) != NULL)
2880 gdk_window_set_cursor(gtk_widget_get_window(gui.drawarea),
2881 gui.blank_pointer);
2882 # else
2480 if (gui.pointer_hidden && gui.drawarea->window != NULL) 2883 if (gui.pointer_hidden && gui.drawarea->window != NULL)
2481 gdk_window_set_cursor(gui.drawarea->window, gui.blank_pointer); 2884 gdk_window_set_cursor(gui.drawarea->window, gui.blank_pointer);
2885 # endif
2482 2886
2483 /* 2887 /*
2484 * Create a new PangoContext for this screen, and initialize it 2888 * Create a new PangoContext for this screen, and initialize it
2485 * with the current font if necessary. 2889 * with the current font if necessary.
2486 */ 2890 */
2507 */ 2911 */
2508 static void 2912 static void
2509 drawarea_realize_cb(GtkWidget *widget, gpointer data UNUSED) 2913 drawarea_realize_cb(GtkWidget *widget, gpointer data UNUSED)
2510 { 2914 {
2511 GtkWidget *sbar; 2915 GtkWidget *sbar;
2916 #if GTK_CHECK_VERSION(3,0,0)
2917 GtkAllocation allocation;
2918 #endif
2512 2919
2513 #ifdef FEAT_XIM 2920 #ifdef FEAT_XIM
2514 xim_init(); 2921 xim_init();
2515 #endif 2922 #endif
2516 gui_mch_new_colors(); 2923 gui_mch_new_colors();
2924 #if GTK_CHECK_VERSION(3,0,0)
2925 gui.surface = gdk_window_create_similar_surface(
2926 gtk_widget_get_window(widget),
2927 CAIRO_CONTENT_COLOR_ALPHA,
2928 gtk_widget_get_allocated_width(widget),
2929 gtk_widget_get_allocated_height(widget));
2930 #else
2517 gui.text_gc = gdk_gc_new(gui.drawarea->window); 2931 gui.text_gc = gdk_gc_new(gui.drawarea->window);
2932 #endif
2518 2933
2519 gui.blank_pointer = create_blank_pointer(); 2934 gui.blank_pointer = create_blank_pointer();
2520 if (gui.pointer_hidden) 2935 if (gui.pointer_hidden)
2936 #if GTK_CHECK_VERSION(3,0,0)
2937 gdk_window_set_cursor(gtk_widget_get_window(widget), gui.blank_pointer);
2938 #else
2521 gdk_window_set_cursor(widget->window, gui.blank_pointer); 2939 gdk_window_set_cursor(widget->window, gui.blank_pointer);
2940 #endif
2522 2941
2523 /* get the actual size of the scrollbars, if they are realized */ 2942 /* get the actual size of the scrollbars, if they are realized */
2524 sbar = firstwin->w_scrollbars[SBAR_LEFT].id; 2943 sbar = firstwin->w_scrollbars[SBAR_LEFT].id;
2525 if (!sbar || (!gui.which_scrollbars[SBAR_LEFT] 2944 if (!sbar || (!gui.which_scrollbars[SBAR_LEFT]
2526 && firstwin->w_scrollbars[SBAR_RIGHT].id)) 2945 && firstwin->w_scrollbars[SBAR_RIGHT].id))
2527 sbar = firstwin->w_scrollbars[SBAR_RIGHT].id; 2946 sbar = firstwin->w_scrollbars[SBAR_RIGHT].id;
2947 #if GTK_CHECK_VERSION(3,0,0)
2948 gtk_widget_get_allocation(sbar, &allocation);
2949 if (sbar && gtk_widget_get_realized(sbar) && allocation.width)
2950 gui.scrollbar_width = allocation.width;
2951 #else
2528 if (sbar && GTK_WIDGET_REALIZED(sbar) && sbar->allocation.width) 2952 if (sbar && GTK_WIDGET_REALIZED(sbar) && sbar->allocation.width)
2529 gui.scrollbar_width = sbar->allocation.width; 2953 gui.scrollbar_width = sbar->allocation.width;
2954 #endif
2530 2955
2531 sbar = gui.bottom_sbar.id; 2956 sbar = gui.bottom_sbar.id;
2957 #if GTK_CHECK_VERSION(3,0,0)
2958 if (sbar && gtk_widget_get_realized(sbar) && allocation.height)
2959 gui.scrollbar_height = allocation.height;
2960 #else
2532 if (sbar && GTK_WIDGET_REALIZED(sbar) && sbar->allocation.height) 2961 if (sbar && GTK_WIDGET_REALIZED(sbar) && sbar->allocation.height)
2533 gui.scrollbar_height = sbar->allocation.height; 2962 gui.scrollbar_height = sbar->allocation.height;
2963 #endif
2534 } 2964 }
2535 2965
2536 /* 2966 /*
2537 * Properly clean up on shutdown. 2967 * Properly clean up on shutdown.
2538 */ 2968 */
2556 gui.ascii_font = NULL; 2986 gui.ascii_font = NULL;
2557 } 2987 }
2558 g_object_unref(gui.text_context); 2988 g_object_unref(gui.text_context);
2559 gui.text_context = NULL; 2989 gui.text_context = NULL;
2560 2990
2991 #if GTK_CHECK_VERSION(3,0,0)
2992 if (gui.surface != NULL)
2993 {
2994 cairo_surface_destroy(gui.surface);
2995 gui.surface = NULL;
2996 }
2997 #else
2561 g_object_unref(gui.text_gc); 2998 g_object_unref(gui.text_gc);
2562 gui.text_gc = NULL; 2999 gui.text_gc = NULL;
2563 3000 #endif
3001
3002 #if GTK_CHECK_VERSION(3,0,0)
3003 g_object_unref(G_OBJECT(gui.blank_pointer));
3004 #else
2564 gdk_cursor_unref(gui.blank_pointer); 3005 gdk_cursor_unref(gui.blank_pointer);
3006 #endif
2565 gui.blank_pointer = NULL; 3007 gui.blank_pointer = NULL;
2566 } 3008 }
2567 3009
2568 static void 3010 static void
2569 drawarea_style_set_cb(GtkWidget *widget UNUSED, 3011 drawarea_style_set_cb(GtkWidget *widget UNUSED,
2571 gpointer data UNUSED) 3013 gpointer data UNUSED)
2572 { 3014 {
2573 gui_mch_new_colors(); 3015 gui_mch_new_colors();
2574 } 3016 }
2575 3017
3018 #if GTK_CHECK_VERSION(3,0,0)
3019 static gboolean
3020 drawarea_configure_event_cb(GtkWidget *widget,
3021 GdkEventConfigure *event,
3022 gpointer data UNUSED)
3023 {
3024 static int cur_width = 0;
3025 static int cur_height = 0;
3026
3027 g_return_val_if_fail(event
3028 && event->width >= 1 && event->height >= 1, TRUE);
3029
3030 if (event->width == cur_width && event->height == cur_height)
3031 return TRUE;
3032
3033 cur_width = event->width;
3034 cur_height = event->height;
3035
3036 if (gui.surface != NULL)
3037 cairo_surface_destroy(gui.surface);
3038
3039 gui.surface = gdk_window_create_similar_surface(
3040 gtk_widget_get_window(widget),
3041 CAIRO_CONTENT_COLOR_ALPHA,
3042 event->width, event->height);
3043
3044 gtk_widget_queue_draw(widget);
3045
3046 return TRUE;
3047 }
3048 #endif
3049
2576 /* 3050 /*
2577 * Callback routine for the "delete_event" signal on the toplevel window. 3051 * Callback routine for the "delete_event" signal on the toplevel window.
2578 * Tries to vim gracefully, or refuses to exit with changed buffers. 3052 * Tries to vim gracefully, or refuses to exit with changed buffers.
2579 */ 3053 */
2580 static gint 3054 static gint
2590 static int 3064 static int
2591 get_item_dimensions(GtkWidget *widget, GtkOrientation orientation) 3065 get_item_dimensions(GtkWidget *widget, GtkOrientation orientation)
2592 { 3066 {
2593 GtkOrientation item_orientation = GTK_ORIENTATION_HORIZONTAL; 3067 GtkOrientation item_orientation = GTK_ORIENTATION_HORIZONTAL;
2594 3068
2595 #ifdef FEAT_GUI_GNOME 3069 # ifdef FEAT_GUI_GNOME
2596 if (using_gnome && widget != NULL) 3070 if (using_gnome && widget != NULL)
2597 { 3071 {
2598 GtkWidget *parent; 3072 GtkWidget *parent;
2599 BonoboDockItem *dockitem; 3073 BonoboDockItem *dockitem;
2600 3074
2609 if (dockitem == NULL || dockitem->is_floating) 3083 if (dockitem == NULL || dockitem->is_floating)
2610 return 0; 3084 return 0;
2611 item_orientation = bonobo_dock_item_get_orientation(dockitem); 3085 item_orientation = bonobo_dock_item_get_orientation(dockitem);
2612 } 3086 }
2613 } 3087 }
2614 #endif 3088 # endif
3089 # if GTK_CHECK_VERSION(3,0,0)
3090 if (widget != NULL
3091 && item_orientation == orientation
3092 && gtk_widget_get_realized(widget)
3093 && gtk_widget_get_visible(widget))
3094 # else
2615 if (widget != NULL 3095 if (widget != NULL
2616 && item_orientation == orientation 3096 && item_orientation == orientation
2617 && GTK_WIDGET_REALIZED(widget) 3097 && GTK_WIDGET_REALIZED(widget)
2618 && GTK_WIDGET_VISIBLE(widget)) 3098 && GTK_WIDGET_VISIBLE(widget))
2619 { 3099 # endif
3100 {
3101 # if GTK_CHECK_VERSION(3,0,0)
3102 GtkAllocation allocation;
3103
3104 gtk_widget_get_allocation(widget, &allocation);
3105
3106 if (orientation == GTK_ORIENTATION_HORIZONTAL)
3107 return allocation.height;
3108 else
3109 return allocation.width;
3110 # else
2620 if (orientation == GTK_ORIENTATION_HORIZONTAL) 3111 if (orientation == GTK_ORIENTATION_HORIZONTAL)
2621 return widget->allocation.height; 3112 return widget->allocation.height;
2622 else 3113 else
2623 return widget->allocation.width; 3114 return widget->allocation.width;
3115 # endif
2624 } 3116 }
2625 return 0; 3117 return 0;
2626 } 3118 }
2627 #endif 3119 #endif
2628 3120
2772 { 3264 {
2773 if (GTK_IS_IMAGE(widget)) 3265 if (GTK_IS_IMAGE(widget))
2774 { 3266 {
2775 GtkImage *image = (GtkImage *)widget; 3267 GtkImage *image = (GtkImage *)widget;
2776 3268
3269 # if GTK_CHECK_VERSION(3,10,0)
3270 if (gtk_image_get_storage_type(image) == GTK_IMAGE_ICON_NAME)
3271 {
3272 const GtkIconSize icon_size = GPOINTER_TO_INT(user_data);
3273 const gchar *icon_name;
3274
3275 gtk_image_get_icon_name(image, &icon_name, NULL);
3276
3277 gtk_image_set_from_icon_name(image, icon_name, icon_size);
3278 }
3279 # else
2777 /* User-defined icons are stored in a GtkIconSet */ 3280 /* User-defined icons are stored in a GtkIconSet */
2778 if (gtk_image_get_storage_type(image) == GTK_IMAGE_ICON_SET) 3281 if (gtk_image_get_storage_type(image) == GTK_IMAGE_ICON_SET)
2779 { 3282 {
2780 GtkIconSet *icon_set; 3283 GtkIconSet *icon_set;
2781 GtkIconSize icon_size; 3284 GtkIconSize icon_size;
2785 3288
2786 gtk_icon_set_ref(icon_set); 3289 gtk_icon_set_ref(icon_set);
2787 gtk_image_set_from_icon_set(image, icon_set, icon_size); 3290 gtk_image_set_from_icon_set(image, icon_set, icon_size);
2788 gtk_icon_set_unref(icon_set); 3291 gtk_icon_set_unref(icon_set);
2789 } 3292 }
3293 # endif
2790 } 3294 }
2791 else if (GTK_IS_CONTAINER(widget)) 3295 else if (GTK_IS_CONTAINER(widget))
2792 { 3296 {
2793 gtk_container_foreach((GtkContainer *)widget, 3297 gtk_container_foreach((GtkContainer *)widget,
2794 &icon_size_changed_foreach, 3298 &icon_size_changed_foreach,
2813 style = GTK_TOOLBAR_TEXT; 3317 style = GTK_TOOLBAR_TEXT;
2814 else 3318 else
2815 style = GTK_TOOLBAR_ICONS; 3319 style = GTK_TOOLBAR_ICONS;
2816 3320
2817 gtk_toolbar_set_style(toolbar, style); 3321 gtk_toolbar_set_style(toolbar, style);
3322 # if !GTK_CHECK_VERSION(3,0,0)
2818 gtk_toolbar_set_tooltips(toolbar, (toolbar_flags & TOOLBAR_TOOLTIPS) != 0); 3323 gtk_toolbar_set_tooltips(toolbar, (toolbar_flags & TOOLBAR_TOOLTIPS) != 0);
3324 # endif
2819 3325
2820 switch (tbis_flags) 3326 switch (tbis_flags)
2821 { 3327 {
2822 case TBIS_TINY: size = GTK_ICON_SIZE_MENU; break; 3328 case TBIS_TINY: size = GTK_ICON_SIZE_MENU; break;
2823 case TBIS_SMALL: size = GTK_ICON_SIZE_SMALL_TOOLBAR; break; 3329 case TBIS_SMALL: size = GTK_ICON_SIZE_SMALL_TOOLBAR; break;
2845 #endif /* FEAT_TOOLBAR */ 3351 #endif /* FEAT_TOOLBAR */
2846 3352
2847 #if defined(FEAT_GUI_TABLINE) || defined(PROTO) 3353 #if defined(FEAT_GUI_TABLINE) || defined(PROTO)
2848 static int ignore_tabline_evt = FALSE; 3354 static int ignore_tabline_evt = FALSE;
2849 static GtkWidget *tabline_menu; 3355 static GtkWidget *tabline_menu;
3356 # if !GTK_CHECK_VERSION(3,0,0)
2850 static GtkTooltips *tabline_tooltip; 3357 static GtkTooltips *tabline_tooltip;
3358 # endif
2851 static int clicked_page; /* page clicked in tab line */ 3359 static int clicked_page; /* page clicked in tab line */
2852 3360
2853 /* 3361 /*
2854 * Handle selecting an item in the tab line popup menu. 3362 * Handle selecting an item in the tab line popup menu.
2855 */ 3363 */
2870 item = gtk_menu_item_new_with_label((const char *)utf_text); 3378 item = gtk_menu_item_new_with_label((const char *)utf_text);
2871 gtk_widget_show(item); 3379 gtk_widget_show(item);
2872 CONVERT_TO_UTF8_FREE(utf_text); 3380 CONVERT_TO_UTF8_FREE(utf_text);
2873 3381
2874 gtk_container_add(GTK_CONTAINER(menu), item); 3382 gtk_container_add(GTK_CONTAINER(menu), item);
3383 # if GTK_CHECK_VERSION(3,0,0)
3384 g_signal_connect(G_OBJECT(item), "activate",
3385 G_CALLBACK(tabline_menu_handler),
3386 GINT_TO_POINTER(resp));
3387 # else
2875 gtk_signal_connect(GTK_OBJECT(item), "activate", 3388 gtk_signal_connect(GTK_OBJECT(item), "activate",
2876 GTK_SIGNAL_FUNC(tabline_menu_handler), 3389 GTK_SIGNAL_FUNC(tabline_menu_handler),
2877 (gpointer)(long)resp); 3390 (gpointer)(long)resp);
3391 # endif
2878 } 3392 }
2879 3393
2880 /* 3394 /*
2881 * Create a menu for the tab line. 3395 * Create a menu for the tab line.
2882 */ 3396 */
2914 || cmdwin_type != 0 3428 || cmdwin_type != 0
2915 # endif 3429 # endif
2916 ) 3430 )
2917 return TRUE; 3431 return TRUE;
2918 3432
3433 # if GTK_CHECK_VERSION(3,0,0)
3434 tabwin = gui_gtk_window_at_position(gui.mainwin, &x, &y);
3435 # else
2919 tabwin = gdk_window_at_pointer(&x, &y); 3436 tabwin = gdk_window_at_pointer(&x, &y);
3437 # endif
3438
2920 gdk_window_get_user_data(tabwin, (gpointer)&tabwidget); 3439 gdk_window_get_user_data(tabwin, (gpointer)&tabwidget);
3440 # if GTK_CHECK_VERSION(3,0,0)
3441 clicked_page = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(tabwidget),
3442 "tab_num"));
3443 # else
2921 clicked_page = (int)(long)gtk_object_get_user_data( 3444 clicked_page = (int)(long)gtk_object_get_user_data(
2922 GTK_OBJECT(tabwidget)); 3445 GTK_OBJECT(tabwidget));
3446 # endif
2923 3447
2924 /* If the event was generated for 3rd button popup the menu. */ 3448 /* If the event was generated for 3rd button popup the menu. */
2925 if (bevent->button == 3) 3449 if (bevent->button == 3)
2926 { 3450 {
2927 gtk_menu_popup(GTK_MENU(widget), NULL, NULL, NULL, NULL, 3451 gtk_menu_popup(GTK_MENU(widget), NULL, NULL, NULL, NULL,
2948 * Handle selecting one of the tabs. 3472 * Handle selecting one of the tabs.
2949 */ 3473 */
2950 static void 3474 static void
2951 on_select_tab( 3475 on_select_tab(
2952 GtkNotebook *notebook UNUSED, 3476 GtkNotebook *notebook UNUSED,
3477 # if GTK_CHECK_VERSION(3,0,0)
3478 gpointer *page UNUSED,
3479 # else
2953 GtkNotebookPage *page UNUSED, 3480 GtkNotebookPage *page UNUSED,
3481 # endif
2954 gint idx, 3482 gint idx,
2955 gpointer data UNUSED) 3483 gpointer data UNUSED)
2956 { 3484 {
2957 if (!ignore_tabline_evt) 3485 if (!ignore_tabline_evt)
2958 { 3486 {
2973 { 3501 {
2974 /* Note: this may cause a resize event */ 3502 /* Note: this may cause a resize event */
2975 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), showit); 3503 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), showit);
2976 update_window_manager_hints(0, 0); 3504 update_window_manager_hints(0, 0);
2977 if (showit) 3505 if (showit)
3506 # if GTK_CHECK_VERSION(3,0,0)
3507 gtk_widget_set_can_focus(GTK_WIDGET(gui.tabline), FALSE);
3508 # else
2978 GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(gui.tabline), GTK_CAN_FOCUS); 3509 GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(gui.tabline), GTK_CAN_FOCUS);
3510 # endif
2979 } 3511 }
2980 3512
2981 gui_mch_update(); 3513 gui_mch_update();
2982 } 3514 }
2983 3515
3021 3553
3022 page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(gui.tabline), nr); 3554 page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(gui.tabline), nr);
3023 if (page == NULL) 3555 if (page == NULL)
3024 { 3556 {
3025 /* Add notebook page */ 3557 /* Add notebook page */
3558 # if GTK_CHECK_VERSION(3,2,0)
3559 page = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
3560 gtk_box_set_homogeneous(GTK_BOX(page), FALSE);
3561 # else
3026 page = gtk_vbox_new(FALSE, 0); 3562 page = gtk_vbox_new(FALSE, 0);
3563 # endif
3027 gtk_widget_show(page); 3564 gtk_widget_show(page);
3028 event_box = gtk_event_box_new(); 3565 event_box = gtk_event_box_new();
3029 gtk_widget_show(event_box); 3566 gtk_widget_show(event_box);
3030 label = gtk_label_new("-Empty-"); 3567 label = gtk_label_new("-Empty-");
3568 # if !GTK_CHECK_VERSION(3,14,0)
3031 gtk_misc_set_padding(GTK_MISC(label), 2, 2); 3569 gtk_misc_set_padding(GTK_MISC(label), 2, 2);
3570 # endif
3032 gtk_container_add(GTK_CONTAINER(event_box), label); 3571 gtk_container_add(GTK_CONTAINER(event_box), label);
3033 gtk_widget_show(label); 3572 gtk_widget_show(label);
3034 gtk_notebook_insert_page(GTK_NOTEBOOK(gui.tabline), 3573 gtk_notebook_insert_page(GTK_NOTEBOOK(gui.tabline),
3035 page, 3574 page,
3036 event_box, 3575 event_box,
3037 nr++); 3576 nr++);
3038 } 3577 }
3039 3578
3040 event_box = gtk_notebook_get_tab_label(GTK_NOTEBOOK(gui.tabline), page); 3579 event_box = gtk_notebook_get_tab_label(GTK_NOTEBOOK(gui.tabline), page);
3580 # if GTK_CHECK_VERSION(3,0,0)
3581 g_object_set_data(G_OBJECT(event_box), "tab_num",
3582 GINT_TO_POINTER(tab_num));
3583 # else
3041 gtk_object_set_user_data(GTK_OBJECT(event_box), 3584 gtk_object_set_user_data(GTK_OBJECT(event_box),
3042 (gpointer)(long)tab_num); 3585 (gpointer)(long)tab_num);
3586 # endif
3587 # if GTK_CHECK_VERSION(3,0,0)
3588 label = gtk_bin_get_child(GTK_BIN(event_box));
3589 # else
3043 label = GTK_BIN(event_box)->child; 3590 label = GTK_BIN(event_box)->child;
3591 # endif
3044 get_tabline_label(tp, FALSE); 3592 get_tabline_label(tp, FALSE);
3045 labeltext = CONVERT_TO_UTF8(NameBuff); 3593 labeltext = CONVERT_TO_UTF8(NameBuff);
3046 gtk_label_set_text(GTK_LABEL(label), (const char *)labeltext); 3594 gtk_label_set_text(GTK_LABEL(label), (const char *)labeltext);
3047 CONVERT_TO_UTF8_FREE(labeltext); 3595 CONVERT_TO_UTF8_FREE(labeltext);
3048 3596
3049 get_tabline_label(tp, TRUE); 3597 get_tabline_label(tp, TRUE);
3050 labeltext = CONVERT_TO_UTF8(NameBuff); 3598 labeltext = CONVERT_TO_UTF8(NameBuff);
3599 # if GTK_CHECK_VERSION(3,0,0)
3600 gtk_widget_set_tooltip_text(event_box, (const gchar *)labeltext);
3601 # else
3051 gtk_tooltips_set_tip(GTK_TOOLTIPS(tabline_tooltip), event_box, 3602 gtk_tooltips_set_tip(GTK_TOOLTIPS(tabline_tooltip), event_box,
3052 (const char *)labeltext, NULL); 3603 (const char *)labeltext, NULL);
3604 # endif
3053 CONVERT_TO_UTF8_FREE(labeltext); 3605 CONVERT_TO_UTF8_FREE(labeltext);
3054 } 3606 }
3055 3607
3056 /* Remove any old labels. */ 3608 /* Remove any old labels. */
3057 while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(gui.tabline), nr) != NULL) 3609 while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(gui.tabline), nr) != NULL)
3058 gtk_notebook_remove_page(GTK_NOTEBOOK(gui.tabline), nr); 3610 gtk_notebook_remove_page(GTK_NOTEBOOK(gui.tabline), nr);
3059 3611
3612 # if GTK_CHECK_VERSION(3,0,0)
3613 if (gtk_notebook_get_current_page(GTK_NOTEBOOK(gui.tabline)) != curtabidx)
3614 gtk_notebook_set_current_page(GTK_NOTEBOOK(gui.tabline), curtabidx);
3615 # else
3060 if (gtk_notebook_current_page(GTK_NOTEBOOK(gui.tabline)) != curtabidx) 3616 if (gtk_notebook_current_page(GTK_NOTEBOOK(gui.tabline)) != curtabidx)
3061 gtk_notebook_set_page(GTK_NOTEBOOK(gui.tabline), curtabidx); 3617 gtk_notebook_set_page(GTK_NOTEBOOK(gui.tabline), curtabidx);
3618 # endif
3062 3619
3063 /* Make sure everything is in place before drawing text. */ 3620 /* Make sure everything is in place before drawing text. */
3064 gui_mch_update(); 3621 gui_mch_update();
3065 3622
3066 ignore_tabline_evt = FALSE; 3623 ignore_tabline_evt = FALSE;
3074 { 3631 {
3075 if (gui.tabline == NULL) 3632 if (gui.tabline == NULL)
3076 return; 3633 return;
3077 3634
3078 ignore_tabline_evt = TRUE; 3635 ignore_tabline_evt = TRUE;
3636 # if GTK_CHECK_VERSION(3,0,0)
3637 if (gtk_notebook_get_current_page(GTK_NOTEBOOK(gui.tabline)) != nr - 1)
3638 gtk_notebook_set_current_page(GTK_NOTEBOOK(gui.tabline), nr - 1);
3639 # else
3079 if (gtk_notebook_current_page(GTK_NOTEBOOK(gui.tabline)) != nr - 1) 3640 if (gtk_notebook_current_page(GTK_NOTEBOOK(gui.tabline)) != nr - 1)
3080 gtk_notebook_set_page(GTK_NOTEBOOK(gui.tabline), nr - 1); 3641 gtk_notebook_set_page(GTK_NOTEBOOK(gui.tabline), nr - 1);
3642 # endif
3081 ignore_tabline_evt = FALSE; 3643 ignore_tabline_evt = FALSE;
3082 } 3644 }
3083 3645
3084 #endif /* FEAT_GUI_TABLINE */ 3646 #endif /* FEAT_GUI_TABLINE */
3085 3647
3185 #ifdef FEAT_TOOLBAR 3747 #ifdef FEAT_TOOLBAR
3186 gui_gtk_register_stock_icons(); 3748 gui_gtk_register_stock_icons();
3187 #endif 3749 #endif
3188 /* FIXME: Need to install the classic icons and a gtkrc.classic file. 3750 /* FIXME: Need to install the classic icons and a gtkrc.classic file.
3189 * The hard part is deciding install locations and the Makefile magic. */ 3751 * The hard part is deciding install locations and the Makefile magic. */
3190 #if 0 3752 #if !GTK_CHECK_VERSION(3,0,0)
3753 # if 0
3191 gtk_rc_parse("gtkrc"); 3754 gtk_rc_parse("gtkrc");
3755 # endif
3192 #endif 3756 #endif
3193 3757
3194 /* Initialize values */ 3758 /* Initialize values */
3195 gui.border_width = 2; 3759 gui.border_width = 2;
3196 gui.scrollbar_width = SB_DEFAULT_WIDTH; 3760 gui.scrollbar_width = SB_DEFAULT_WIDTH;
3219 plug = gtk_plug_new_for_display(gdk_display_get_default(), 3783 plug = gtk_plug_new_for_display(gdk_display_get_default(),
3220 gtk_socket_id); 3784 gtk_socket_id);
3221 #else 3785 #else
3222 plug = gtk_plug_new(gtk_socket_id); 3786 plug = gtk_plug_new(gtk_socket_id);
3223 #endif 3787 #endif
3788 #if GTK_CHECK_VERSION(3,0,0)
3789 if (plug != NULL && gtk_plug_get_socket_window(GTK_PLUG(plug)) != NULL)
3790 #else
3224 if (plug != NULL && GTK_PLUG(plug)->socket_window != NULL) 3791 if (plug != NULL && GTK_PLUG(plug)->socket_window != NULL)
3792 #endif
3225 { 3793 {
3226 gui.mainwin = plug; 3794 gui.mainwin = plug;
3227 } 3795 }
3228 else 3796 else
3229 { 3797 {
3254 3822
3255 /* Create the PangoContext used for drawing all text. */ 3823 /* Create the PangoContext used for drawing all text. */
3256 gui.text_context = gtk_widget_create_pango_context(gui.mainwin); 3824 gui.text_context = gtk_widget_create_pango_context(gui.mainwin);
3257 pango_context_set_base_dir(gui.text_context, PANGO_DIRECTION_LTR); 3825 pango_context_set_base_dir(gui.text_context, PANGO_DIRECTION_LTR);
3258 3826
3827 #if GTK_CHECK_VERSION(3,0,0)
3828 gtk_container_set_border_width(GTK_CONTAINER(gui.mainwin), 0);
3829 #else
3259 gtk_container_border_width(GTK_CONTAINER(gui.mainwin), 0); 3830 gtk_container_border_width(GTK_CONTAINER(gui.mainwin), 0);
3831 #endif
3260 gtk_widget_add_events(gui.mainwin, GDK_VISIBILITY_NOTIFY_MASK); 3832 gtk_widget_add_events(gui.mainwin, GDK_VISIBILITY_NOTIFY_MASK);
3261 3833
3834 #if GTK_CHECK_VERSION(3,0,0)
3835 g_signal_connect(G_OBJECT(gui.mainwin), "delete-event",
3836 G_CALLBACK(&delete_event_cb), NULL);
3837
3838 g_signal_connect(G_OBJECT(gui.mainwin), "realize",
3839 G_CALLBACK(&mainwin_realize), NULL);
3840 #else
3262 gtk_signal_connect(GTK_OBJECT(gui.mainwin), "delete_event", 3841 gtk_signal_connect(GTK_OBJECT(gui.mainwin), "delete_event",
3263 GTK_SIGNAL_FUNC(&delete_event_cb), NULL); 3842 GTK_SIGNAL_FUNC(&delete_event_cb), NULL);
3264 3843
3265 gtk_signal_connect(GTK_OBJECT(gui.mainwin), "realize", 3844 gtk_signal_connect(GTK_OBJECT(gui.mainwin), "realize",
3266 GTK_SIGNAL_FUNC(&mainwin_realize), NULL); 3845 GTK_SIGNAL_FUNC(&mainwin_realize), NULL);
3846 #endif
3267 #ifdef HAVE_GTK_MULTIHEAD 3847 #ifdef HAVE_GTK_MULTIHEAD
3268 g_signal_connect(G_OBJECT(gui.mainwin), "screen_changed", 3848 g_signal_connect(G_OBJECT(gui.mainwin), "screen_changed",
3269 G_CALLBACK(&mainwin_screen_changed_cb), NULL); 3849 G_CALLBACK(&mainwin_screen_changed_cb), NULL);
3270 #endif 3850 #endif
3271 gui.accel_group = gtk_accel_group_new(); 3851 gui.accel_group = gtk_accel_group_new();
3272 gtk_window_add_accel_group(GTK_WINDOW(gui.mainwin), gui.accel_group); 3852 gtk_window_add_accel_group(GTK_WINDOW(gui.mainwin), gui.accel_group);
3273 3853
3274 /* A vertical box holds the menubar, toolbar and main text window. */ 3854 /* A vertical box holds the menubar, toolbar and main text window. */
3855 #if GTK_CHECK_VERSION(3,2,0)
3856 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
3857 gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
3858 #else
3275 vbox = gtk_vbox_new(FALSE, 0); 3859 vbox = gtk_vbox_new(FALSE, 0);
3860 #endif
3276 3861
3277 #ifdef FEAT_GUI_GNOME 3862 #ifdef FEAT_GUI_GNOME
3278 if (using_gnome) 3863 if (using_gnome)
3279 { 3864 {
3280 # if defined(FEAT_MENU) 3865 # if defined(FEAT_MENU)
3333 #ifdef FEAT_TOOLBAR 3918 #ifdef FEAT_TOOLBAR
3334 /* 3919 /*
3335 * Create the toolbar and handle 3920 * Create the toolbar and handle
3336 */ 3921 */
3337 /* some aesthetics on the toolbar */ 3922 /* some aesthetics on the toolbar */
3923 # ifdef USE_GTK3
3924 /* TODO: Add GTK+ 3 code here using GtkCssProvider if neccessary. */
3925 /* N.B. Since the default value of GtkToolbar::button-relief is
3926 * GTK_RELIEF_NONE, there's no need to specify that, probably. */
3927 # else
3338 gtk_rc_parse_string( 3928 gtk_rc_parse_string(
3339 "style \"vim-toolbar-style\" {\n" 3929 "style \"vim-toolbar-style\" {\n"
3340 " GtkToolbar::button_relief = GTK_RELIEF_NONE\n" 3930 " GtkToolbar::button_relief = GTK_RELIEF_NONE\n"
3341 "}\n" 3931 "}\n"
3342 "widget \"*.vim-toolbar\" style \"vim-toolbar-style\"\n"); 3932 "widget \"*.vim-toolbar\" style \"vim-toolbar-style\"\n");
3933 # endif
3343 gui.toolbar = gtk_toolbar_new(); 3934 gui.toolbar = gtk_toolbar_new();
3344 gtk_widget_set_name(gui.toolbar, "vim-toolbar"); 3935 gtk_widget_set_name(gui.toolbar, "vim-toolbar");
3345 set_toolbar_style(GTK_TOOLBAR(gui.toolbar)); 3936 set_toolbar_style(GTK_TOOLBAR(gui.toolbar));
3346 3937
3347 # ifdef FEAT_GUI_GNOME 3938 # ifdef FEAT_GUI_GNOME
3379 gtk_widget_show(gui.tabline); 3970 gtk_widget_show(gui.tabline);
3380 gtk_box_pack_start(GTK_BOX(vbox), gui.tabline, FALSE, FALSE, 0); 3971 gtk_box_pack_start(GTK_BOX(vbox), gui.tabline, FALSE, FALSE, 0);
3381 gtk_notebook_set_show_border(GTK_NOTEBOOK(gui.tabline), FALSE); 3972 gtk_notebook_set_show_border(GTK_NOTEBOOK(gui.tabline), FALSE);
3382 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), FALSE); 3973 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), FALSE);
3383 gtk_notebook_set_scrollable(GTK_NOTEBOOK(gui.tabline), TRUE); 3974 gtk_notebook_set_scrollable(GTK_NOTEBOOK(gui.tabline), TRUE);
3975 # if !GTK_CHECK_VERSION(3,0,0)
3384 gtk_notebook_set_tab_border(GTK_NOTEBOOK(gui.tabline), FALSE); 3976 gtk_notebook_set_tab_border(GTK_NOTEBOOK(gui.tabline), FALSE);
3385 3977 # endif
3978
3979 # if !GTK_CHECK_VERSION(3,0,0)
3386 tabline_tooltip = gtk_tooltips_new(); 3980 tabline_tooltip = gtk_tooltips_new();
3387 gtk_tooltips_enable(GTK_TOOLTIPS(tabline_tooltip)); 3981 gtk_tooltips_enable(GTK_TOOLTIPS(tabline_tooltip));
3982 # endif
3388 3983
3389 { 3984 {
3390 GtkWidget *page, *label, *event_box; 3985 GtkWidget *page, *label, *event_box;
3391 3986
3392 /* Add the first tab. */ 3987 /* Add the first tab. */
3988 # if GTK_CHECK_VERSION(3,2,0)
3989 page = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
3990 gtk_box_set_homogeneous(GTK_BOX(page), FALSE);
3991 # else
3393 page = gtk_vbox_new(FALSE, 0); 3992 page = gtk_vbox_new(FALSE, 0);
3993 # endif
3394 gtk_widget_show(page); 3994 gtk_widget_show(page);
3395 gtk_container_add(GTK_CONTAINER(gui.tabline), page); 3995 gtk_container_add(GTK_CONTAINER(gui.tabline), page);
3396 label = gtk_label_new("-Empty-"); 3996 label = gtk_label_new("-Empty-");
3397 gtk_widget_show(label); 3997 gtk_widget_show(label);
3398 event_box = gtk_event_box_new(); 3998 event_box = gtk_event_box_new();
3399 gtk_widget_show(event_box); 3999 gtk_widget_show(event_box);
4000 # if GTK_CHECK_VERSION(3,0,0)
4001 g_object_set_data(G_OBJECT(event_box), "tab_num", GINT_TO_POINTER(1L));
4002 # else
3400 gtk_object_set_user_data(GTK_OBJECT(event_box), (gpointer)1L); 4003 gtk_object_set_user_data(GTK_OBJECT(event_box), (gpointer)1L);
4004 # endif
4005 # if !GTK_CHECK_VERSION(3,14,0)
3401 gtk_misc_set_padding(GTK_MISC(label), 2, 2); 4006 gtk_misc_set_padding(GTK_MISC(label), 2, 2);
4007 # endif
3402 gtk_container_add(GTK_CONTAINER(event_box), label); 4008 gtk_container_add(GTK_CONTAINER(event_box), label);
3403 gtk_notebook_set_tab_label(GTK_NOTEBOOK(gui.tabline), page, event_box); 4009 gtk_notebook_set_tab_label(GTK_NOTEBOOK(gui.tabline), page, event_box);
3404 } 4010 }
3405 4011
4012 # if GTK_CHECK_VERSION(3,0,0)
4013 g_signal_connect(G_OBJECT(gui.tabline), "switch-page",
4014 G_CALLBACK(on_select_tab), NULL);
4015 # else
3406 gtk_signal_connect(GTK_OBJECT(gui.tabline), "switch_page", 4016 gtk_signal_connect(GTK_OBJECT(gui.tabline), "switch_page",
3407 GTK_SIGNAL_FUNC(on_select_tab), NULL); 4017 GTK_SIGNAL_FUNC(on_select_tab), NULL);
4018 # endif
3408 4019
3409 /* Create a popup menu for the tab line and connect it. */ 4020 /* Create a popup menu for the tab line and connect it. */
3410 tabline_menu = create_tabline_menu(); 4021 tabline_menu = create_tabline_menu();
4022 # if GTK_CHECK_VERSION(3,0,0)
4023 g_signal_connect_swapped(G_OBJECT(gui.tabline), "button-press-event",
4024 G_CALLBACK(on_tabline_menu), G_OBJECT(tabline_menu));
4025 # else
3411 gtk_signal_connect_object(GTK_OBJECT(gui.tabline), "button_press_event", 4026 gtk_signal_connect_object(GTK_OBJECT(gui.tabline), "button_press_event",
3412 GTK_SIGNAL_FUNC(on_tabline_menu), GTK_OBJECT(tabline_menu)); 4027 GTK_SIGNAL_FUNC(on_tabline_menu), GTK_OBJECT(tabline_menu));
3413 #endif 4028 # endif
4029 #endif /* FEAT_GUI_TABLINE */
3414 4030
3415 gui.formwin = gtk_form_new(); 4031 gui.formwin = gtk_form_new();
4032 #if GTK_CHECK_VERSION(3,0,0)
4033 gtk_container_set_border_width(GTK_CONTAINER(gui.formwin), 0);
4034 #else
3416 gtk_container_border_width(GTK_CONTAINER(gui.formwin), 0); 4035 gtk_container_border_width(GTK_CONTAINER(gui.formwin), 0);
4036 #endif
4037 #if !GTK_CHECK_VERSION(3,0,0)
3417 gtk_widget_set_events(gui.formwin, GDK_EXPOSURE_MASK); 4038 gtk_widget_set_events(gui.formwin, GDK_EXPOSURE_MASK);
4039 #endif
3418 4040
3419 gui.drawarea = gtk_drawing_area_new(); 4041 gui.drawarea = gtk_drawing_area_new();
4042 #if GTK_CHECK_VERSION(3,0,0)
4043 gui.surface = NULL;
4044 gui.by_signal = FALSE;
4045 #endif
3420 4046
3421 /* Determine which events we will filter. */ 4047 /* Determine which events we will filter. */
3422 gtk_widget_set_events(gui.drawarea, 4048 gtk_widget_set_events(gui.drawarea,
3423 GDK_EXPOSURE_MASK | 4049 GDK_EXPOSURE_MASK |
3424 GDK_ENTER_NOTIFY_MASK | 4050 GDK_ENTER_NOTIFY_MASK |
3436 gtk_widget_show(gui.formwin); 4062 gtk_widget_show(gui.formwin);
3437 gtk_box_pack_start(GTK_BOX(vbox), gui.formwin, TRUE, TRUE, 0); 4063 gtk_box_pack_start(GTK_BOX(vbox), gui.formwin, TRUE, TRUE, 0);
3438 4064
3439 /* For GtkSockets, key-presses must go to the focus widget (drawarea) 4065 /* For GtkSockets, key-presses must go to the focus widget (drawarea)
3440 * and not the window. */ 4066 * and not the window. */
4067 #if GTK_CHECK_VERSION(3,0,0)
4068 g_signal_connect((gtk_socket_id == 0) ? G_OBJECT(gui.mainwin)
4069 : G_OBJECT(gui.drawarea),
4070 "key-press-event",
4071 G_CALLBACK(key_press_event), NULL);
4072 #else
3441 gtk_signal_connect((gtk_socket_id == 0) ? GTK_OBJECT(gui.mainwin) 4073 gtk_signal_connect((gtk_socket_id == 0) ? GTK_OBJECT(gui.mainwin)
3442 : GTK_OBJECT(gui.drawarea), 4074 : GTK_OBJECT(gui.drawarea),
3443 "key_press_event", 4075 "key_press_event",
3444 GTK_SIGNAL_FUNC(key_press_event), NULL); 4076 GTK_SIGNAL_FUNC(key_press_event), NULL);
3445 #if defined(FEAT_XIM) 4077 #endif
4078 #if defined(FEAT_XIM) || GTK_CHECK_VERSION(3,0,0)
3446 /* Also forward key release events for the benefit of GTK+ 2 input 4079 /* Also forward key release events for the benefit of GTK+ 2 input
3447 * modules. Try CTRL-SHIFT-xdigits to enter a Unicode code point. */ 4080 * modules. Try CTRL-SHIFT-xdigits to enter a Unicode code point. */
3448 g_signal_connect((gtk_socket_id == 0) ? G_OBJECT(gui.mainwin) 4081 g_signal_connect((gtk_socket_id == 0) ? G_OBJECT(gui.mainwin)
3449 : G_OBJECT(gui.drawarea), 4082 : G_OBJECT(gui.drawarea),
3450 "key_release_event", 4083 "key-release-event",
3451 G_CALLBACK(&key_release_event), NULL); 4084 G_CALLBACK(&key_release_event), NULL);
3452 #endif 4085 #endif
4086 #if GTK_CHECK_VERSION(3,0,0)
4087 g_signal_connect(G_OBJECT(gui.drawarea), "realize",
4088 G_CALLBACK(drawarea_realize_cb), NULL);
4089 g_signal_connect(G_OBJECT(gui.drawarea), "unrealize",
4090 G_CALLBACK(drawarea_unrealize_cb), NULL);
4091 g_signal_connect(G_OBJECT(gui.drawarea), "configure-event",
4092 G_CALLBACK(drawarea_configure_event_cb), NULL);
4093 g_signal_connect_after(G_OBJECT(gui.drawarea), "style-set",
4094 G_CALLBACK(&drawarea_style_set_cb), NULL);
4095 #else
3453 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "realize", 4096 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "realize",
3454 GTK_SIGNAL_FUNC(drawarea_realize_cb), NULL); 4097 GTK_SIGNAL_FUNC(drawarea_realize_cb), NULL);
3455 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "unrealize", 4098 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "unrealize",
3456 GTK_SIGNAL_FUNC(drawarea_unrealize_cb), NULL); 4099 GTK_SIGNAL_FUNC(drawarea_unrealize_cb), NULL);
3457 4100
3458 gtk_signal_connect_after(GTK_OBJECT(gui.drawarea), "style_set", 4101 gtk_signal_connect_after(GTK_OBJECT(gui.drawarea), "style_set",
3459 GTK_SIGNAL_FUNC(&drawarea_style_set_cb), NULL); 4102 GTK_SIGNAL_FUNC(&drawarea_style_set_cb), NULL);
3460 4103 #endif
4104
4105 #if !GTK_CHECK_VERSION(3,0,0)
3461 gui.visibility = GDK_VISIBILITY_UNOBSCURED; 4106 gui.visibility = GDK_VISIBILITY_UNOBSCURED;
4107 #endif
3462 4108
3463 #if !(defined(FEAT_GUI_GNOME) && defined(FEAT_SESSION)) 4109 #if !(defined(FEAT_GUI_GNOME) && defined(FEAT_SESSION))
3464 wm_protocols_atom = gdk_atom_intern("WM_PROTOCOLS", FALSE); 4110 wm_protocols_atom = gdk_atom_intern("WM_PROTOCOLS", FALSE);
3465 save_yourself_atom = gdk_atom_intern("WM_SAVE_YOURSELF", FALSE); 4111 save_yourself_atom = gdk_atom_intern("WM_SAVE_YOURSELF", FALSE);
3466 #endif 4112 #endif
3467 4113
3468 if (gtk_socket_id != 0) 4114 if (gtk_socket_id != 0)
3469 /* make sure keyboard input can go to the drawarea */ 4115 /* make sure keyboard input can go to the drawarea */
4116 #if GTK_CHECK_VERSION(3,0,0)
4117 gtk_widget_set_can_focus(gui.drawarea, TRUE);
4118 #else
3470 GTK_WIDGET_SET_FLAGS(gui.drawarea, GTK_CAN_FOCUS); 4119 GTK_WIDGET_SET_FLAGS(gui.drawarea, GTK_CAN_FOCUS);
4120 #endif
3471 4121
3472 /* 4122 /*
3473 * Set clipboard specific atoms 4123 * Set clipboard specific atoms
3474 */ 4124 */
3475 vim_atom = gdk_atom_intern(VIM_ATOM_NAME, FALSE); 4125 vim_atom = gdk_atom_intern(VIM_ATOM_NAME, FALSE);
3480 /* 4130 /*
3481 * Start out by adding the configured border width into the border offset. 4131 * Start out by adding the configured border width into the border offset.
3482 */ 4132 */
3483 gui.border_offset = gui.border_width; 4133 gui.border_offset = gui.border_width;
3484 4134
4135 #if GTK_CHECK_VERSION(3,0,0)
4136 g_signal_connect(G_OBJECT(gui.drawarea), "draw",
4137 G_CALLBACK(draw_event), NULL);
4138 #else
3485 gtk_signal_connect(GTK_OBJECT(gui.mainwin), "visibility_notify_event", 4139 gtk_signal_connect(GTK_OBJECT(gui.mainwin), "visibility_notify_event",
3486 GTK_SIGNAL_FUNC(visibility_event), NULL); 4140 GTK_SIGNAL_FUNC(visibility_event), NULL);
3487 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "expose_event", 4141 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "expose_event",
3488 GTK_SIGNAL_FUNC(expose_event), NULL); 4142 GTK_SIGNAL_FUNC(expose_event), NULL);
4143 #endif
3489 4144
3490 /* 4145 /*
3491 * Only install these enter/leave callbacks when 'p' in 'guioptions'. 4146 * Only install these enter/leave callbacks when 'p' in 'guioptions'.
3492 * Only needed for some window managers. 4147 * Only needed for some window managers.
3493 */ 4148 */
3494 if (vim_strchr(p_go, GO_POINTER) != NULL) 4149 if (vim_strchr(p_go, GO_POINTER) != NULL)
3495 { 4150 {
4151 #if GTK_CHECK_VERSION(3,0,0)
4152 g_signal_connect(G_OBJECT(gui.drawarea), "leave-notify-event",
4153 G_CALLBACK(leave_notify_event), NULL);
4154 g_signal_connect(G_OBJECT(gui.drawarea), "enter-notify-event",
4155 G_CALLBACK(enter_notify_event), NULL);
4156 #else
3496 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "leave_notify_event", 4157 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "leave_notify_event",
3497 GTK_SIGNAL_FUNC(leave_notify_event), NULL); 4158 GTK_SIGNAL_FUNC(leave_notify_event), NULL);
3498 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "enter_notify_event", 4159 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "enter_notify_event",
3499 GTK_SIGNAL_FUNC(enter_notify_event), NULL); 4160 GTK_SIGNAL_FUNC(enter_notify_event), NULL);
4161 #endif
3500 } 4162 }
3501 4163
3502 /* Real windows can get focus ... GtkPlug, being a mere container can't, 4164 /* Real windows can get focus ... GtkPlug, being a mere container can't,
3503 * only its widgets. Arguably, this could be common code and we not use 4165 * only its widgets. Arguably, this could be common code and we not use
3504 * the window focus at all, but let's be safe. 4166 * the window focus at all, but let's be safe.
3505 */ 4167 */
3506 if (gtk_socket_id == 0) 4168 if (gtk_socket_id == 0)
3507 { 4169 {
4170 #if GTK_CHECK_VERSION(3,0,0)
4171 g_signal_connect(G_OBJECT(gui.mainwin), "focus-out-event",
4172 G_CALLBACK(focus_out_event), NULL);
4173 g_signal_connect(G_OBJECT(gui.mainwin), "focus-in-event",
4174 G_CALLBACK(focus_in_event), NULL);
4175 #else
3508 gtk_signal_connect(GTK_OBJECT(gui.mainwin), "focus_out_event", 4176 gtk_signal_connect(GTK_OBJECT(gui.mainwin), "focus_out_event",
3509 GTK_SIGNAL_FUNC(focus_out_event), NULL); 4177 GTK_SIGNAL_FUNC(focus_out_event), NULL);
3510 gtk_signal_connect(GTK_OBJECT(gui.mainwin), "focus_in_event", 4178 gtk_signal_connect(GTK_OBJECT(gui.mainwin), "focus_in_event",
3511 GTK_SIGNAL_FUNC(focus_in_event), NULL); 4179 GTK_SIGNAL_FUNC(focus_in_event), NULL);
4180 #endif
3512 } 4181 }
3513 else 4182 else
3514 { 4183 {
4184 #if GTK_CHECK_VERSION(3,0,0)
4185 g_signal_connect(G_OBJECT(gui.drawarea), "focus-out-event",
4186 G_CALLBACK(focus_out_event), NULL);
4187 g_signal_connect(G_OBJECT(gui.drawarea), "focus-in-event",
4188 G_CALLBACK(focus_in_event), NULL);
4189 #else
3515 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "focus_out_event", 4190 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "focus_out_event",
3516 GTK_SIGNAL_FUNC(focus_out_event), NULL); 4191 GTK_SIGNAL_FUNC(focus_out_event), NULL);
3517 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "focus_in_event", 4192 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "focus_in_event",
3518 GTK_SIGNAL_FUNC(focus_in_event), NULL); 4193 GTK_SIGNAL_FUNC(focus_in_event), NULL);
4194 #endif
3519 #ifdef FEAT_GUI_TABLINE 4195 #ifdef FEAT_GUI_TABLINE
4196 # if GTK_CHECK_VERSION(3,0,0)
4197 g_signal_connect(G_OBJECT(gui.tabline), "focus-out-event",
4198 G_CALLBACK(focus_out_event), NULL);
4199 g_signal_connect(G_OBJECT(gui.tabline), "focus-in-event",
4200 G_CALLBACK(focus_in_event), NULL);
4201 # else
3520 gtk_signal_connect(GTK_OBJECT(gui.tabline), "focus_out_event", 4202 gtk_signal_connect(GTK_OBJECT(gui.tabline), "focus_out_event",
3521 GTK_SIGNAL_FUNC(focus_out_event), NULL); 4203 GTK_SIGNAL_FUNC(focus_out_event), NULL);
3522 gtk_signal_connect(GTK_OBJECT(gui.tabline), "focus_in_event", 4204 gtk_signal_connect(GTK_OBJECT(gui.tabline), "focus_in_event",
3523 GTK_SIGNAL_FUNC(focus_in_event), NULL); 4205 GTK_SIGNAL_FUNC(focus_in_event), NULL);
4206 # endif
3524 #endif /* FEAT_GUI_TABLINE */ 4207 #endif /* FEAT_GUI_TABLINE */
3525 } 4208 }
3526 4209
4210 #if GTK_CHECK_VERSION(3,0,0)
4211 g_signal_connect(G_OBJECT(gui.drawarea), "motion-notify-event",
4212 G_CALLBACK(motion_notify_event), NULL);
4213 g_signal_connect(G_OBJECT(gui.drawarea), "button-press-event",
4214 G_CALLBACK(button_press_event), NULL);
4215 g_signal_connect(G_OBJECT(gui.drawarea), "button-release-event",
4216 G_CALLBACK(button_release_event), NULL);
4217 g_signal_connect(G_OBJECT(gui.drawarea), "scroll-event",
4218 G_CALLBACK(&scroll_event), NULL);
4219 #else
3527 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "motion_notify_event", 4220 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "motion_notify_event",
3528 GTK_SIGNAL_FUNC(motion_notify_event), NULL); 4221 GTK_SIGNAL_FUNC(motion_notify_event), NULL);
3529 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "button_press_event", 4222 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "button_press_event",
3530 GTK_SIGNAL_FUNC(button_press_event), NULL); 4223 GTK_SIGNAL_FUNC(button_press_event), NULL);
3531 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "button_release_event", 4224 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "button_release_event",
3532 GTK_SIGNAL_FUNC(button_release_event), NULL); 4225 GTK_SIGNAL_FUNC(button_release_event), NULL);
3533 g_signal_connect(G_OBJECT(gui.drawarea), "scroll_event", 4226 g_signal_connect(G_OBJECT(gui.drawarea), "scroll_event",
3534 G_CALLBACK(&scroll_event), NULL); 4227 G_CALLBACK(&scroll_event), NULL);
4228 #endif
3535 4229
3536 /* 4230 /*
3537 * Add selection handler functions. 4231 * Add selection handler functions.
3538 */ 4232 */
4233 #if GTK_CHECK_VERSION(3,0,0)
4234 g_signal_connect(G_OBJECT(gui.drawarea), "selection-clear-event",
4235 G_CALLBACK(selection_clear_event), NULL);
4236 g_signal_connect(G_OBJECT(gui.drawarea), "selection-received",
4237 G_CALLBACK(selection_received_cb), NULL);
4238 #else
3539 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "selection_clear_event", 4239 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "selection_clear_event",
3540 GTK_SIGNAL_FUNC(selection_clear_event), NULL); 4240 GTK_SIGNAL_FUNC(selection_clear_event), NULL);
3541 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "selection_received", 4241 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "selection_received",
3542 GTK_SIGNAL_FUNC(selection_received_cb), NULL); 4242 GTK_SIGNAL_FUNC(selection_received_cb), NULL);
4243 #endif
3543 4244
3544 gui_gtk_set_selection_targets(); 4245 gui_gtk_set_selection_targets();
3545 4246
4247 #if GTK_CHECK_VERSION(3,0,0)
4248 g_signal_connect(G_OBJECT(gui.drawarea), "selection-get",
4249 G_CALLBACK(selection_get_cb), NULL);
4250 #else
3546 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "selection_get", 4251 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "selection_get",
3547 GTK_SIGNAL_FUNC(selection_get_cb), NULL); 4252 GTK_SIGNAL_FUNC(selection_get_cb), NULL);
4253 #endif
3548 4254
3549 /* Pretend we don't have input focus, we will get an event if we do. */ 4255 /* Pretend we don't have input focus, we will get an event if we do. */
3550 gui.in_focus = FALSE; 4256 gui.in_focus = FALSE;
3551 4257
3552 return OK; 4258 return OK;
3569 if (client != NULL) 4275 if (client != NULL)
3570 gnome_client_set_process_id(client, getpid()); 4276 gnome_client_set_process_id(client, getpid());
3571 } 4277 }
3572 } 4278 }
3573 #endif /* FEAT_GUI_GNOME && FEAT_SESSION */ 4279 #endif /* FEAT_GUI_GNOME && FEAT_SESSION */
4280
4281 #if GTK_CHECK_VERSION(3,0,0)
4282 static void
4283 gui_gtk_get_rgb_from_pixel(guint32 pixel, GdkRGBA *result)
4284 {
4285 GdkVisual * const visual = gtk_widget_get_visual(gui.drawarea);
4286 guint32 r_mask, g_mask, b_mask;
4287 gint r_shift, g_shift, b_shift;
4288
4289 if (visual == NULL)
4290 {
4291 result->red = 0.0;
4292 result->green = 0.0;
4293 result->blue = 0.0;
4294 result->alpha = 0.0;
4295 return;
4296 }
4297
4298 gdk_visual_get_red_pixel_details(visual, &r_mask, &r_shift, NULL);
4299 gdk_visual_get_green_pixel_details(visual, &g_mask, &g_shift, NULL);
4300 gdk_visual_get_blue_pixel_details(visual, &b_mask, &b_shift, NULL);
4301
4302 result->red = ((pixel & r_mask) >> r_shift) / 255.0;
4303 result->green = ((pixel & g_mask) >> g_shift) / 255.0;
4304 result->blue = ((pixel & b_mask) >> b_shift) / 255.0;
4305 result->alpha = 1.0;
4306 }
4307
4308 /* Convert a GdRGBA into a pixel value using drawarea's visual */
4309 static guint32
4310 gui_gtk_get_pixel_from_rgb(const GdkRGBA *rgba)
4311 {
4312 GdkVisual * const visual = gtk_widget_get_visual(gui.drawarea);
4313 guint32 r_mask, g_mask, b_mask;
4314 gint r_shift, g_shift, b_shift;
4315 guint32 r, g, b;
4316
4317 if (visual == NULL)
4318 return 0;
4319
4320 gdk_visual_get_red_pixel_details(visual, &r_mask, &r_shift, NULL);
4321 gdk_visual_get_green_pixel_details(visual, &g_mask, &g_shift, NULL);
4322 gdk_visual_get_blue_pixel_details(visual, &b_mask, &b_shift, NULL);
4323
4324 r = rgba->red * 65535;
4325 g = rgba->green * 65535;
4326 b = rgba->blue * 65535;
4327
4328 return ((r << r_shift) & r_mask) |
4329 ((g << g_shift) & g_mask) |
4330 ((b << b_shift) & b_mask);
4331 }
4332
4333 static void
4334 set_cairo_source_rgb_from_pixel(cairo_t *cr, guint32 pixel)
4335 {
4336 GdkRGBA result;
4337 gui_gtk_get_rgb_from_pixel(pixel, &result);
4338 cairo_set_source_rgb(cr, result.red, result.green, result.blue);
4339 }
4340 #endif /* GTK_CHECK_VERSION(3,0,0) */
3574 4341
3575 /* 4342 /*
3576 * Called when the foreground or background color has been changed. 4343 * Called when the foreground or background color has been changed.
3577 * This used to change the graphics contexts directly but we are 4344 * This used to change the graphics contexts directly but we are
3578 * currently manipulating them where desired. 4345 * currently manipulating them where desired.
3579 */ 4346 */
3580 void 4347 void
3581 gui_mch_new_colors(void) 4348 gui_mch_new_colors(void)
3582 { 4349 {
4350 #if GTK_CHECK_VERSION(3,0,0)
4351 GdkWindow * const da_win = gtk_widget_get_window(gui.drawarea);
4352
4353 if (gui.drawarea != NULL && gtk_widget_get_window(gui.drawarea) != NULL)
4354 #else
3583 if (gui.drawarea != NULL && gui.drawarea->window != NULL) 4355 if (gui.drawarea != NULL && gui.drawarea->window != NULL)
3584 { 4356 #endif
4357 {
4358 #if GTK_CHECK_VERSION(3,4,0)
4359 GdkRGBA color;
4360
4361 gui_gtk_get_rgb_from_pixel(gui.back_pixel, &color);
4362 {
4363 cairo_pattern_t * const pat = cairo_pattern_create_rgba(
4364 color.red, color.green, color.blue, color.alpha);
4365 if (pat != NULL)
4366 {
4367 gdk_window_set_background_pattern(da_win, pat);
4368 cairo_pattern_destroy(pat);
4369 }
4370 else
4371 gdk_window_set_background_rgba(da_win, &color);
4372 }
4373 #else /* !GTK_CHECK_VERSION(3,4,0) */
3585 GdkColor color = { 0, 0, 0, 0 }; 4374 GdkColor color = { 0, 0, 0, 0 };
3586 4375
3587 color.pixel = gui.back_pixel; 4376 color.pixel = gui.back_pixel;
4377 # if GTK_CHECK_VERSION(3,0,0)
4378 gdk_window_set_background(da_win, &color);
4379 # else
3588 gdk_window_set_background(gui.drawarea->window, &color); 4380 gdk_window_set_background(gui.drawarea->window, &color);
4381 # endif
4382 #endif /* !GTK_CHECK_VERSION(3,4,0) */
3589 } 4383 }
3590 } 4384 }
3591 4385
3592 /* 4386 /*
3593 * This signal informs us about the need to rearrange our sub-widgets. 4387 * This signal informs us about the need to rearrange our sub-widgets.
3616 /* 4410 /*
3617 * Function called when window already closed. 4411 * Function called when window already closed.
3618 * We can't do much more here than to trying to preserve what had been done, 4412 * We can't do much more here than to trying to preserve what had been done,
3619 * since the window is already inevitably going away. 4413 * since the window is already inevitably going away.
3620 */ 4414 */
4415 #if GTK_CHECK_VERSION(3,0,0)
4416 static void
4417 mainwin_destroy_cb(GObject *object UNUSED, gpointer data UNUSED)
4418 #else
3621 static void 4419 static void
3622 mainwin_destroy_cb(GtkObject *object UNUSED, gpointer data UNUSED) 4420 mainwin_destroy_cb(GtkObject *object UNUSED, gpointer data UNUSED)
4421 #endif
3623 { 4422 {
3624 /* Don't write messages to the GUI anymore */ 4423 /* Don't write messages to the GUI anymore */
3625 full_screen = FALSE; 4424 full_screen = FALSE;
3626 4425
3627 gui.mainwin = NULL; 4426 gui.mainwin = NULL;
3797 4596
3798 /* Get the colors for the highlight groups (gui_check_colors() might have 4597 /* Get the colors for the highlight groups (gui_check_colors() might have
3799 * changed them). */ 4598 * changed them). */
3800 highlight_gui_started(); /* re-init colors and fonts */ 4599 highlight_gui_started(); /* re-init colors and fonts */
3801 4600
4601 #if GTK_CHECK_VERSION(3,0,0)
4602 g_signal_connect(G_OBJECT(gui.mainwin), "destroy",
4603 G_CALLBACK(mainwin_destroy_cb), NULL);
4604 #else
3802 gtk_signal_connect(GTK_OBJECT(gui.mainwin), "destroy", 4605 gtk_signal_connect(GTK_OBJECT(gui.mainwin), "destroy",
3803 GTK_SIGNAL_FUNC(mainwin_destroy_cb), NULL); 4606 GTK_SIGNAL_FUNC(mainwin_destroy_cb), NULL);
4607 #endif
3804 4608
3805 #ifdef FEAT_HANGULIN 4609 #ifdef FEAT_HANGULIN
3806 hangul_keyboard_set(); 4610 hangul_keyboard_set();
3807 #endif 4611 #endif
3808 4612
3814 * We connect this signal deferred finally after anything is in place, 4618 * We connect this signal deferred finally after anything is in place,
3815 * since this is intended to handle resizements coming from the window 4619 * since this is intended to handle resizements coming from the window
3816 * manager upon us and should not interfere with what VIM is requesting 4620 * manager upon us and should not interfere with what VIM is requesting
3817 * upon startup. 4621 * upon startup.
3818 */ 4622 */
4623 #if GTK_CHECK_VERSION(3,0,0)
4624 g_signal_connect(G_OBJECT(gui.formwin), "configure-event",
4625 G_CALLBACK(form_configure_event), NULL);
4626 #else
3819 gtk_signal_connect(GTK_OBJECT(gui.formwin), "configure_event", 4627 gtk_signal_connect(GTK_OBJECT(gui.formwin), "configure_event",
3820 GTK_SIGNAL_FUNC(form_configure_event), NULL); 4628 GTK_SIGNAL_FUNC(form_configure_event), NULL);
4629 #endif
3821 4630
3822 #ifdef FEAT_DND 4631 #ifdef FEAT_DND
3823 /* Set up for receiving DND items. */ 4632 /* Set up for receiving DND items. */
3824 gui_gtk_set_dnd_targets(); 4633 gui_gtk_set_dnd_targets();
3825 4634
4635 # if GTK_CHECK_VERSION(3,0,0)
4636 g_signal_connect(G_OBJECT(gui.drawarea), "drag-data-received",
4637 G_CALLBACK(drag_data_received_cb), NULL);
4638 # else
3826 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "drag_data_received", 4639 gtk_signal_connect(GTK_OBJECT(gui.drawarea), "drag_data_received",
3827 GTK_SIGNAL_FUNC(drag_data_received_cb), NULL); 4640 GTK_SIGNAL_FUNC(drag_data_received_cb), NULL);
4641 # endif
3828 #endif 4642 #endif
3829 4643
3830 /* With GTK+ 2, we need to iconify the window before calling show() 4644 /* With GTK+ 2, we need to iconify the window before calling show()
3831 * to avoid mapping the window for a short time. */ 4645 * to avoid mapping the window for a short time. */
3832 if (found_iconic_arg && gtk_socket_id == 0) 4646 if (found_iconic_arg && gtk_socket_id == 0)
3899 gui_mch_set_winpos(int x, int y) 4713 gui_mch_set_winpos(int x, int y)
3900 { 4714 {
3901 gtk_window_move(GTK_WINDOW(gui.mainwin), x, y); 4715 gtk_window_move(GTK_WINDOW(gui.mainwin), x, y);
3902 } 4716 }
3903 4717
3904 #if 0 4718 #if !GTK_CHECK_VERSION(3,0,0)
4719 # if 0
3905 static int resize_idle_installed = FALSE; 4720 static int resize_idle_installed = FALSE;
3906 /* 4721 /*
3907 * Idle handler to force resize. Used by gui_mch_set_shellsize() to ensure 4722 * Idle handler to force resize. Used by gui_mch_set_shellsize() to ensure
3908 * the shell size doesn't exceed the window size, i.e. if the window manager 4723 * the shell size doesn't exceed the window size, i.e. if the window manager
3909 * ignored our size request. Usually this happens if the window is maximized. 4724 * ignored our size request. Usually this happens if the window is maximized.
3935 } 4750 }
3936 4751
3937 resize_idle_installed = FALSE; 4752 resize_idle_installed = FALSE;
3938 return FALSE; /* don't call me again */ 4753 return FALSE; /* don't call me again */
3939 } 4754 }
3940 #endif 4755 # endif
4756 #endif /* !GTK_CHECK_VERSION(3,0,0) */
3941 4757
3942 /* 4758 /*
3943 * Return TRUE if the main window is maximized. 4759 * Return TRUE if the main window is maximized.
3944 */ 4760 */
3945 int 4761 int
3946 gui_mch_maximized(void) 4762 gui_mch_maximized(void)
3947 { 4763 {
4764 #if GTK_CHECK_VERSION(3,0,0)
4765 return (gui.mainwin != NULL && gtk_widget_get_window(gui.mainwin) != NULL
4766 && (gdk_window_get_state(gtk_widget_get_window(gui.mainwin))
4767 & GDK_WINDOW_STATE_MAXIMIZED));
4768 #else
3948 return (gui.mainwin != NULL && gui.mainwin->window != NULL 4769 return (gui.mainwin != NULL && gui.mainwin->window != NULL
3949 && (gdk_window_get_state(gui.mainwin->window) 4770 && (gdk_window_get_state(gui.mainwin->window)
3950 & GDK_WINDOW_STATE_MAXIMIZED)); 4771 & GDK_WINDOW_STATE_MAXIMIZED));
4772 #endif
3951 } 4773 }
3952 4774
3953 /* 4775 /*
3954 * Unmaximize the main window 4776 * Unmaximize the main window
3955 */ 4777 */
4000 if (gtk_socket_id == 0) 4822 if (gtk_socket_id == 0)
4001 gtk_window_resize(GTK_WINDOW(gui.mainwin), width, height); 4823 gtk_window_resize(GTK_WINDOW(gui.mainwin), width, height);
4002 else 4824 else
4003 update_window_manager_hints(width, height); 4825 update_window_manager_hints(width, height);
4004 4826
4005 # if 0 4827 # if !GTK_CHECK_VERSION(3,0,0)
4828 # if 0
4006 if (!resize_idle_installed) 4829 if (!resize_idle_installed)
4007 { 4830 {
4008 g_idle_add_full(GDK_PRIORITY_EVENTS + 10, 4831 g_idle_add_full(GDK_PRIORITY_EVENTS + 10,
4009 &force_shell_resize_idle, NULL, NULL); 4832 &force_shell_resize_idle, NULL, NULL);
4010 resize_idle_installed = TRUE; 4833 resize_idle_installed = TRUE;
4011 } 4834 }
4012 # endif 4835 # endif
4836 # endif /* !GTK_CHECK_VERSION(3,0,0) */
4013 /* 4837 /*
4014 * Wait until all events are processed to prevent a crash because the 4838 * Wait until all events are processed to prevent a crash because the
4015 * real size of the drawing area doesn't reflect Vim's internal ideas. 4839 * real size of the drawing area doesn't reflect Vim's internal ideas.
4016 * 4840 *
4017 * This is a bit of a hack, since Vim is a terminal application with a GUI 4841 * This is a bit of a hack, since Vim is a terminal application with a GUI
4082 else 4906 else
4083 # endif 4907 # endif
4084 widget = gui.menubar; 4908 widget = gui.menubar;
4085 4909
4086 /* Do not disable the menu while starting up, otherwise F10 doesn't work. */ 4910 /* Do not disable the menu while starting up, otherwise F10 doesn't work. */
4911 # if GTK_CHECK_VERSION(3,0,0)
4912 if (!showit != !gtk_widget_get_visible(widget) && !gui.starting)
4913 # else
4087 if (!showit != !GTK_WIDGET_VISIBLE(widget) && !gui.starting) 4914 if (!showit != !GTK_WIDGET_VISIBLE(widget) && !gui.starting)
4915 # endif
4088 { 4916 {
4089 if (showit) 4917 if (showit)
4090 gtk_widget_show(widget); 4918 gtk_widget_show(widget);
4091 else 4919 else
4092 gtk_widget_hide(widget); 4920 gtk_widget_hide(widget);
4113 widget = gui.toolbar; 4941 widget = gui.toolbar;
4114 4942
4115 if (showit) 4943 if (showit)
4116 set_toolbar_style(GTK_TOOLBAR(gui.toolbar)); 4944 set_toolbar_style(GTK_TOOLBAR(gui.toolbar));
4117 4945
4946 # if GTK_CHECK_VERSION(3,0,0)
4947 if (!showit != !gtk_widget_get_visible(widget))
4948 # else
4118 if (!showit != !GTK_WIDGET_VISIBLE(widget)) 4949 if (!showit != !GTK_WIDGET_VISIBLE(widget))
4950 # endif
4119 { 4951 {
4120 if (showit) 4952 if (showit)
4121 gtk_widget_show(widget); 4953 gtk_widget_show(widget);
4122 else 4954 else
4123 gtk_widget_hide(widget); 4955 gtk_widget_hide(widget);
4197 gui.char_ascent = MAX(gui.char_ascent, 0); 5029 gui.char_ascent = MAX(gui.char_ascent, 0);
4198 gui.char_height = MAX(gui.char_height, gui.char_ascent + 1); 5030 gui.char_height = MAX(gui.char_height, gui.char_ascent + 1);
4199 5031
4200 return OK; 5032 return OK;
4201 } 5033 }
5034
5035 #if GTK_CHECK_VERSION(3,0,0)
5036 /* Callback function used in gui_mch_font_dialog() */
5037 static gboolean
5038 font_filter(const PangoFontFamily *family,
5039 const PangoFontFace *face UNUSED,
5040 gpointer data UNUSED)
5041 {
5042 return pango_font_family_is_monospace((PangoFontFamily *)family);
5043 }
5044 #endif
4202 5045
4203 /* 5046 /*
4204 * Put up a font dialog and return the selected font name in allocated memory. 5047 * Put up a font dialog and return the selected font name in allocated memory.
4205 * "oldval" is the previous value. Return NULL when cancelled. 5048 * "oldval" is the previous value. Return NULL when cancelled.
4206 * This should probably go into gui_gtk.c. Hmm. 5049 * This should probably go into gui_gtk.c. Hmm.
4215 GtkWidget *dialog; 5058 GtkWidget *dialog;
4216 int response; 5059 int response;
4217 char_u *fontname = NULL; 5060 char_u *fontname = NULL;
4218 char_u *oldname; 5061 char_u *oldname;
4219 5062
5063 #if GTK_CHECK_VERSION(3,2,0)
5064 dialog = gtk_font_chooser_dialog_new(NULL, NULL);
5065 gtk_font_chooser_set_filter_func(GTK_FONT_CHOOSER(dialog), font_filter,
5066 NULL, NULL);
5067 #else
4220 dialog = gtk_font_selection_dialog_new(NULL); 5068 dialog = gtk_font_selection_dialog_new(NULL);
5069 #endif
4221 5070
4222 gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(gui.mainwin)); 5071 gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(gui.mainwin));
4223 gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); 5072 gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE);
4224 5073
4225 if (oldval != NULL && oldval[0] != NUL) 5074 if (oldval != NULL && oldval[0] != NUL)
4242 vim_free(oldname); 5091 vim_free(oldname);
4243 oldname = p; 5092 oldname = p;
4244 } 5093 }
4245 } 5094 }
4246 5095
5096 #if GTK_CHECK_VERSION(3,2,0)
5097 gtk_font_chooser_set_font(
5098 GTK_FONT_CHOOSER(dialog), (const gchar *)oldname);
5099 #else
4247 gtk_font_selection_dialog_set_font_name( 5100 gtk_font_selection_dialog_set_font_name(
4248 GTK_FONT_SELECTION_DIALOG(dialog), (const char *)oldname); 5101 GTK_FONT_SELECTION_DIALOG(dialog), (const char *)oldname);
5102 #endif
4249 5103
4250 if (oldname != oldval) 5104 if (oldname != oldval)
4251 vim_free(oldname); 5105 vim_free(oldname);
4252 } 5106 }
4253 else 5107 else
5108 #if GTK_CHECK_VERSION(3,2,0)
5109 gtk_font_chooser_set_font(
5110 GTK_FONT_CHOOSER(dialog), DEFAULT_FONT);
5111 #else
4254 gtk_font_selection_dialog_set_font_name( 5112 gtk_font_selection_dialog_set_font_name(
4255 GTK_FONT_SELECTION_DIALOG(dialog), DEFAULT_FONT); 5113 GTK_FONT_SELECTION_DIALOG(dialog), DEFAULT_FONT);
5114 #endif
4256 5115
4257 response = gtk_dialog_run(GTK_DIALOG(dialog)); 5116 response = gtk_dialog_run(GTK_DIALOG(dialog));
4258 5117
4259 if (response == GTK_RESPONSE_OK) 5118 if (response == GTK_RESPONSE_OK)
4260 { 5119 {
4261 char *name; 5120 char *name;
4262 5121
5122 #if GTK_CHECK_VERSION(3,2,0)
5123 name = gtk_font_chooser_get_font(GTK_FONT_CHOOSER(dialog));
5124 #else
4263 name = gtk_font_selection_dialog_get_font_name( 5125 name = gtk_font_selection_dialog_get_font_name(
4264 GTK_FONT_SELECTION_DIALOG(dialog)); 5126 GTK_FONT_SELECTION_DIALOG(dialog));
5127 #endif
4265 if (name != NULL) 5128 if (name != NULL)
4266 { 5129 {
4267 char_u *p; 5130 char_u *p;
4268 5131
4269 /* Apparently some font names include a comma, need to escape 5132 /* Apparently some font names include a comma, need to escape
4634 if (!gui.in_use) /* can't do this when GUI not running */ 5497 if (!gui.in_use) /* can't do this when GUI not running */
4635 return INVALCOLOR; 5498 return INVALCOLOR;
4636 5499
4637 while (name != NULL) 5500 while (name != NULL)
4638 { 5501 {
5502 #if GTK_CHECK_VERSION(3,0,0)
5503 GdkRGBA color;
5504 #else
4639 GdkColor color; 5505 GdkColor color;
5506 #endif
4640 int parsed; 5507 int parsed;
4641 int i; 5508 int i;
4642 5509
5510 #if GTK_CHECK_VERSION(3,0,0)
5511 parsed = gdk_rgba_parse(&color, (const gchar *)name);
5512 #else
4643 parsed = gdk_color_parse((const char *)name, &color); 5513 parsed = gdk_color_parse((const char *)name, &color);
5514 #endif
4644 5515
4645 if (parsed) 5516 if (parsed)
4646 { 5517 {
5518 #if GTK_CHECK_VERSION(3,0,0)
5519 return (guicolor_T)gui_gtk_get_pixel_from_rgb(&color);
5520 #else
4647 gdk_colormap_alloc_color(gtk_widget_get_colormap(gui.drawarea), 5521 gdk_colormap_alloc_color(gtk_widget_get_colormap(gui.drawarea),
4648 &color, FALSE, TRUE); 5522 &color, FALSE, TRUE);
4649 return (guicolor_T)color.pixel; 5523 return (guicolor_T)color.pixel;
5524 #endif
4650 } 5525 }
4651 /* add a few builtin names and try again */ 5526 /* add a few builtin names and try again */
4652 for (i = 0; ; ++i) 5527 for (i = 0; ; ++i)
4653 { 5528 {
4654 if (vimnames[i][0] == NULL) 5529 if (vimnames[i][0] == NULL)
4836 /* If the accent width is smaller than the cluster width, position it 5711 /* If the accent width is smaller than the cluster width, position it
4837 * in the middle. */ 5712 * in the middle. */
4838 glyph->geometry.x_offset = -width + MAX(0, width - ink_rect.width) / 2; 5713 glyph->geometry.x_offset = -width + MAX(0, width - ink_rect.width) / 2;
4839 } 5714 }
4840 5715
5716 #if GTK_CHECK_VERSION(3,0,0)
5717 static void
5718 draw_glyph_string(int row, int col, int num_cells, int flags,
5719 PangoFont *font, PangoGlyphString *glyphs,
5720 cairo_t *cr)
5721 #else
4841 static void 5722 static void
4842 draw_glyph_string(int row, int col, int num_cells, int flags, 5723 draw_glyph_string(int row, int col, int num_cells, int flags,
4843 PangoFont *font, PangoGlyphString *glyphs) 5724 PangoFont *font, PangoGlyphString *glyphs)
5725 #endif
4844 { 5726 {
4845 if (!(flags & DRAW_TRANSP)) 5727 if (!(flags & DRAW_TRANSP))
4846 { 5728 {
5729 #if GTK_CHECK_VERSION(3,0,0)
5730 set_cairo_source_rgb_from_pixel(cr, gui.bgcolor->pixel);
5731 cairo_rectangle(cr,
5732 FILL_X(col), FILL_Y(row),
5733 num_cells * gui.char_width, gui.char_height);
5734 cairo_fill(cr);
5735 #else
4847 gdk_gc_set_foreground(gui.text_gc, gui.bgcolor); 5736 gdk_gc_set_foreground(gui.text_gc, gui.bgcolor);
4848 5737
4849 gdk_draw_rectangle(gui.drawarea->window, 5738 gdk_draw_rectangle(gui.drawarea->window,
4850 gui.text_gc, 5739 gui.text_gc,
4851 TRUE, 5740 TRUE,
4852 FILL_X(col), 5741 FILL_X(col),
4853 FILL_Y(row), 5742 FILL_Y(row),
4854 num_cells * gui.char_width, 5743 num_cells * gui.char_width,
4855 gui.char_height); 5744 gui.char_height);
4856 } 5745 #endif
4857 5746 }
5747
5748 #if GTK_CHECK_VERSION(3,0,0)
5749 set_cairo_source_rgb_from_pixel(cr, gui.fgcolor->pixel);
5750 cairo_move_to(cr, TEXT_X(col), TEXT_Y(row));
5751 pango_cairo_show_glyph_string(cr, font, glyphs);
5752 #else
4858 gdk_gc_set_foreground(gui.text_gc, gui.fgcolor); 5753 gdk_gc_set_foreground(gui.text_gc, gui.fgcolor);
4859 5754
4860 gdk_draw_glyphs(gui.drawarea->window, 5755 gdk_draw_glyphs(gui.drawarea->window,
4861 gui.text_gc, 5756 gui.text_gc,
4862 font, 5757 font,
4863 TEXT_X(col), 5758 TEXT_X(col),
4864 TEXT_Y(row), 5759 TEXT_Y(row),
4865 glyphs); 5760 glyphs);
5761 #endif
4866 5762
4867 /* redraw the contents with an offset of 1 to emulate bold */ 5763 /* redraw the contents with an offset of 1 to emulate bold */
4868 if ((flags & DRAW_BOLD) && !gui.font_can_bold) 5764 if ((flags & DRAW_BOLD) && !gui.font_can_bold)
5765 #if GTK_CHECK_VERSION(3,0,0)
5766 {
5767 set_cairo_source_rgb_from_pixel(cr, gui.fgcolor->pixel);
5768 cairo_move_to(cr, TEXT_X(col) + 1, TEXT_Y(row));
5769 pango_cairo_show_glyph_string(cr, font, glyphs);
5770 }
5771 #else
4869 gdk_draw_glyphs(gui.drawarea->window, 5772 gdk_draw_glyphs(gui.drawarea->window,
4870 gui.text_gc, 5773 gui.text_gc,
4871 font, 5774 font,
4872 TEXT_X(col) + 1, 5775 TEXT_X(col) + 1,
4873 TEXT_Y(row), 5776 TEXT_Y(row),
4874 glyphs); 5777 glyphs);
5778 #endif
4875 } 5779 }
4876 5780
4877 /* 5781 /*
4878 * Draw underline and undercurl at the bottom of the character cell. 5782 * Draw underline and undercurl at the bottom of the character cell.
4879 */ 5783 */
5784 #if GTK_CHECK_VERSION(3,0,0)
5785 static void
5786 draw_under(int flags, int row, int col, int cells, cairo_t *cr)
5787 #else
4880 static void 5788 static void
4881 draw_under(int flags, int row, int col, int cells) 5789 draw_under(int flags, int row, int col, int cells)
5790 #endif
4882 { 5791 {
4883 int i; 5792 int i;
4884 int offset; 5793 int offset;
4885 static const int val[8] = {1, 0, 0, 0, 1, 2, 2, 2 }; 5794 static const int val[8] = {1, 0, 0, 0, 1, 2, 2, 2 };
4886 int y = FILL_Y(row + 1) - 1; 5795 int y = FILL_Y(row + 1) - 1;
4887 5796
4888 /* Undercurl: draw curl at the bottom of the character cell. */ 5797 /* Undercurl: draw curl at the bottom of the character cell. */
4889 if (flags & DRAW_UNDERC) 5798 if (flags & DRAW_UNDERC)
4890 { 5799 {
5800 #if GTK_CHECK_VERSION(3,0,0)
5801 cairo_set_line_width(cr, 1.0);
5802 cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT);
5803 set_cairo_source_rgb_from_pixel(cr, gui.spcolor->pixel);
5804 for (i = FILL_X(col); i < FILL_X(col + cells); ++i)
5805 {
5806 offset = val[i % 8];
5807 cairo_line_to(cr, i, y - offset + 0.5);
5808 }
5809 cairo_stroke(cr);
5810 #else
4891 gdk_gc_set_foreground(gui.text_gc, gui.spcolor); 5811 gdk_gc_set_foreground(gui.text_gc, gui.spcolor);
4892 for (i = FILL_X(col); i < FILL_X(col + cells); ++i) 5812 for (i = FILL_X(col); i < FILL_X(col + cells); ++i)
4893 { 5813 {
4894 offset = val[i % 8]; 5814 offset = val[i % 8];
4895 gdk_draw_point(gui.drawarea->window, gui.text_gc, i, y - offset); 5815 gdk_draw_point(gui.drawarea->window, gui.text_gc, i, y - offset);
4896 } 5816 }
4897 gdk_gc_set_foreground(gui.text_gc, gui.fgcolor); 5817 gdk_gc_set_foreground(gui.text_gc, gui.fgcolor);
5818 #endif
4898 } 5819 }
4899 5820
4900 /* Underline: draw a line at the bottom of the character cell. */ 5821 /* Underline: draw a line at the bottom of the character cell. */
4901 if (flags & DRAW_UNDERL) 5822 if (flags & DRAW_UNDERL)
4902 { 5823 {
4903 /* When p_linespace is 0, overwrite the bottom row of pixels. 5824 /* When p_linespace is 0, overwrite the bottom row of pixels.
4904 * Otherwise put the line just below the character. */ 5825 * Otherwise put the line just below the character. */
4905 if (p_linespace > 1) 5826 if (p_linespace > 1)
4906 y -= p_linespace - 1; 5827 y -= p_linespace - 1;
5828 #if GTK_CHECK_VERSION(3,0,0)
5829 {
5830 cairo_set_line_width(cr, 1.0);
5831 cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT);
5832 set_cairo_source_rgb_from_pixel(cr, gui.fgcolor->pixel);
5833 cairo_move_to(cr, FILL_X(col), y + 0.5);
5834 cairo_line_to(cr, FILL_X(col + cells), y + 0.5);
5835 cairo_stroke(cr);
5836 }
5837 #else
4907 gdk_draw_line(gui.drawarea->window, gui.text_gc, 5838 gdk_draw_line(gui.drawarea->window, gui.text_gc,
4908 FILL_X(col), y, 5839 FILL_X(col), y,
4909 FILL_X(col + cells) - 1, y); 5840 FILL_X(col + cells) - 1, y);
5841 #endif
4910 } 5842 }
4911 } 5843 }
4912 5844
4913 int 5845 int
4914 gui_gtk2_draw_string(int row, int col, char_u *s, int len, int flags) 5846 gui_gtk2_draw_string(int row, int col, char_u *s, int len, int flags)
4920 char_u *conv_buf = NULL; /* result of UTF-8 conversion */ 5852 char_u *conv_buf = NULL; /* result of UTF-8 conversion */
4921 char_u *new_conv_buf; 5853 char_u *new_conv_buf;
4922 int convlen; 5854 int convlen;
4923 char_u *sp, *bp; 5855 char_u *sp, *bp;
4924 int plen; 5856 int plen;
4925 5857 #if GTK_CHECK_VERSION(3,0,0)
5858 cairo_t *cr;
5859 #endif
5860
5861 #if GTK_CHECK_VERSION(3,0,0)
5862 if (gui.text_context == NULL || gtk_widget_get_window(gui.drawarea) == NULL)
5863 #else
4926 if (gui.text_context == NULL || gui.drawarea->window == NULL) 5864 if (gui.text_context == NULL || gui.drawarea->window == NULL)
5865 #endif
4927 return len; 5866 return len;
4928 5867
4929 if (output_conv.vc_type != CONV_NONE) 5868 if (output_conv.vc_type != CONV_NONE)
4930 { 5869 {
4931 /* 5870 /*
4974 area.x = gui.border_offset; 5913 area.x = gui.border_offset;
4975 area.y = FILL_Y(row); 5914 area.y = FILL_Y(row);
4976 area.width = gui.num_cols * gui.char_width; 5915 area.width = gui.num_cols * gui.char_width;
4977 area.height = gui.char_height; 5916 area.height = gui.char_height;
4978 5917
5918 #if GTK_CHECK_VERSION(3,0,0)
5919 cr = cairo_create(gui.surface);
5920 cairo_rectangle(cr, area.x, area.y, area.width, area.height);
5921 cairo_clip(cr);
5922 #else
4979 gdk_gc_set_clip_origin(gui.text_gc, 0, 0); 5923 gdk_gc_set_clip_origin(gui.text_gc, 0, 0);
4980 gdk_gc_set_clip_rectangle(gui.text_gc, &area); 5924 gdk_gc_set_clip_rectangle(gui.text_gc, &area);
5925 #endif
4981 5926
4982 glyphs = pango_glyph_string_new(); 5927 glyphs = pango_glyph_string_new();
4983 5928
4984 /* 5929 /*
4985 * Optimization hack: If possible, skip the itemize and shaping process 5930 * Optimization hack: If possible, skip the itemize and shaping process
5002 { 5947 {
5003 glyphs->glyphs[i] = gui.ascii_glyphs->glyphs[s[i]]; 5948 glyphs->glyphs[i] = gui.ascii_glyphs->glyphs[s[i]];
5004 glyphs->log_clusters[i] = i; 5949 glyphs->log_clusters[i] = i;
5005 } 5950 }
5006 5951
5952 #if GTK_CHECK_VERSION(3,0,0)
5953 draw_glyph_string(row, col, len, flags, gui.ascii_font, glyphs, cr);
5954 #else
5007 draw_glyph_string(row, col, len, flags, gui.ascii_font, glyphs); 5955 draw_glyph_string(row, col, len, flags, gui.ascii_font, glyphs);
5956 #endif
5008 5957
5009 column_offset = len; 5958 column_offset = len;
5010 } 5959 }
5011 else 5960 else
5012 not_ascii: 5961 not_ascii:
5160 glyph->geometry.width = 0; 6109 glyph->geometry.width = 0;
5161 } 6110 }
5162 } 6111 }
5163 6112
5164 /*** Aaaaand action! ***/ 6113 /*** Aaaaand action! ***/
6114 #if GTK_CHECK_VERSION(3,0,0)
6115 draw_glyph_string(row, col + column_offset, item_cells,
6116 flags, item->analysis.font, glyphs,
6117 cr);
6118 #else
5165 draw_glyph_string(row, col + column_offset, item_cells, 6119 draw_glyph_string(row, col + column_offset, item_cells,
5166 flags, item->analysis.font, glyphs); 6120 flags, item->analysis.font, glyphs);
6121 #endif
5167 6122
5168 pango_item_free(item); 6123 pango_item_free(item);
5169 6124
5170 column_offset += item_cells; 6125 column_offset += item_cells;
5171 } 6126 }
5173 pango_attr_list_unref(attr_list); 6128 pango_attr_list_unref(attr_list);
5174 } 6129 }
5175 6130
5176 skipitall: 6131 skipitall:
5177 /* Draw underline and undercurl. */ 6132 /* Draw underline and undercurl. */
6133 #if GTK_CHECK_VERSION(3,0,0)
6134 draw_under(flags, row, col, column_offset, cr);
6135 #else
5178 draw_under(flags, row, col, column_offset); 6136 draw_under(flags, row, col, column_offset);
6137 #endif
5179 6138
5180 pango_glyph_string_free(glyphs); 6139 pango_glyph_string_free(glyphs);
5181 vim_free(conv_buf); 6140 vim_free(conv_buf);
5182 6141
6142 #if GTK_CHECK_VERSION(3,0,0)
6143 cairo_destroy(cr);
6144 if (!gui.by_signal)
6145 gdk_window_invalidate_rect(gtk_widget_get_window(gui.drawarea),
6146 &area, FALSE);
6147 #else
5183 gdk_gc_set_clip_rectangle(gui.text_gc, NULL); 6148 gdk_gc_set_clip_rectangle(gui.text_gc, NULL);
6149 #endif
5184 6150
5185 return column_offset; 6151 return column_offset;
5186 } 6152 }
5187 6153
5188 /* 6154 /*
5205 * Return the text window-id and display. Only required for X-based GUI's 6171 * Return the text window-id and display. Only required for X-based GUI's
5206 */ 6172 */
5207 int 6173 int
5208 gui_get_x11_windis(Window *win, Display **dis) 6174 gui_get_x11_windis(Window *win, Display **dis)
5209 { 6175 {
6176 #if GTK_CHECK_VERSION(3,0,0)
6177 if (gui.mainwin != NULL && gtk_widget_get_window(gui.mainwin) != NULL)
6178 #else
5210 if (gui.mainwin != NULL && gui.mainwin->window != NULL) 6179 if (gui.mainwin != NULL && gui.mainwin->window != NULL)
5211 { 6180 #endif
6181 {
6182 #if GTK_CHECK_VERSION(3,0,0)
6183 *dis = GDK_WINDOW_XDISPLAY(gtk_widget_get_window(gui.mainwin));
6184 *win = GDK_WINDOW_XID(gtk_widget_get_window(gui.mainwin));
6185 #else
5212 *dis = GDK_WINDOW_XDISPLAY(gui.mainwin->window); 6186 *dis = GDK_WINDOW_XDISPLAY(gui.mainwin->window);
5213 *win = GDK_WINDOW_XWINDOW(gui.mainwin->window); 6187 *win = GDK_WINDOW_XWINDOW(gui.mainwin->window);
6188 #endif
5214 return OK; 6189 return OK;
5215 } 6190 }
5216 6191
5217 *dis = NULL; 6192 *dis = NULL;
5218 *win = 0; 6193 *win = 0;
5224 || (defined(FEAT_X11) && defined(FEAT_CLIPBOARD)) || defined(PROTO) 6199 || (defined(FEAT_X11) && defined(FEAT_CLIPBOARD)) || defined(PROTO)
5225 6200
5226 Display * 6201 Display *
5227 gui_mch_get_display(void) 6202 gui_mch_get_display(void)
5228 { 6203 {
6204 #if GTK_CHECK_VERSION(3,0,0)
6205 if (gui.mainwin != NULL && gtk_widget_get_window(gui.mainwin) != NULL)
6206 return GDK_WINDOW_XDISPLAY(gtk_widget_get_window(gui.mainwin));
6207 #else
5229 if (gui.mainwin != NULL && gui.mainwin->window != NULL) 6208 if (gui.mainwin != NULL && gui.mainwin->window != NULL)
5230 return GDK_WINDOW_XDISPLAY(gui.mainwin->window); 6209 return GDK_WINDOW_XDISPLAY(gui.mainwin->window);
6210 #endif
5231 else 6211 else
5232 return NULL; 6212 return NULL;
5233 } 6213 }
5234 #endif 6214 #endif
5235 6215
5237 gui_mch_beep(void) 6217 gui_mch_beep(void)
5238 { 6218 {
5239 #ifdef HAVE_GTK_MULTIHEAD 6219 #ifdef HAVE_GTK_MULTIHEAD
5240 GdkDisplay *display; 6220 GdkDisplay *display;
5241 6221
6222 # if GTK_CHECK_VERSION(3,0,0)
6223 if (gui.mainwin != NULL && gtk_widget_get_realized(gui.mainwin))
6224 # else
5242 if (gui.mainwin != NULL && GTK_WIDGET_REALIZED(gui.mainwin)) 6225 if (gui.mainwin != NULL && GTK_WIDGET_REALIZED(gui.mainwin))
6226 # endif
5243 display = gtk_widget_get_display(gui.mainwin); 6227 display = gtk_widget_get_display(gui.mainwin);
5244 else 6228 else
5245 display = gdk_display_get_default(); 6229 display = gdk_display_get_default();
5246 6230
5247 if (display != NULL) 6231 if (display != NULL)
5252 } 6236 }
5253 6237
5254 void 6238 void
5255 gui_mch_flash(int msec) 6239 gui_mch_flash(int msec)
5256 { 6240 {
6241 #if GTK_CHECK_VERSION(3,0,0)
6242 /* TODO Replace GdkGC with Cairo */
6243 (void)msec;
6244 #else
5257 GdkGCValues values; 6245 GdkGCValues values;
5258 GdkGC *invert_gc; 6246 GdkGC *invert_gc;
5259 6247
5260 if (gui.drawarea->window == NULL) 6248 if (gui.drawarea->window == NULL)
5261 return; 6249 return;
5291 0, 0, 6279 0, 0,
5292 FILL_X((int)Columns) + gui.border_offset, 6280 FILL_X((int)Columns) + gui.border_offset,
5293 FILL_Y((int)Rows) + gui.border_offset); 6281 FILL_Y((int)Rows) + gui.border_offset);
5294 6282
5295 gdk_gc_destroy(invert_gc); 6283 gdk_gc_destroy(invert_gc);
6284 #endif
5296 } 6285 }
5297 6286
5298 /* 6287 /*
5299 * Invert a rectangle from row r, column c, for nr rows and nc columns. 6288 * Invert a rectangle from row r, column c, for nr rows and nc columns.
5300 */ 6289 */
5301 void 6290 void
5302 gui_mch_invert_rectangle(int r, int c, int nr, int nc) 6291 gui_mch_invert_rectangle(int r, int c, int nr, int nc)
5303 { 6292 {
6293 #if GTK_CHECK_VERSION(3,0,0)
6294 /* TODO Replace GdkGC with Cairo */
6295 (void)r; (void)c; (void)nr; (void)nc;
6296 #else
5304 GdkGCValues values; 6297 GdkGCValues values;
5305 GdkGC *invert_gc; 6298 GdkGC *invert_gc;
5306 6299
5307 if (gui.drawarea->window == NULL) 6300 if (gui.drawarea->window == NULL)
5308 return; 6301 return;
5320 gdk_draw_rectangle(gui.drawarea->window, invert_gc, 6313 gdk_draw_rectangle(gui.drawarea->window, invert_gc,
5321 TRUE, 6314 TRUE,
5322 FILL_X(c), FILL_Y(r), 6315 FILL_X(c), FILL_Y(r),
5323 (nc) * gui.char_width, (nr) * gui.char_height); 6316 (nc) * gui.char_width, (nr) * gui.char_height);
5324 gdk_gc_destroy(invert_gc); 6317 gdk_gc_destroy(invert_gc);
6318 #endif
5325 } 6319 }
5326 6320
5327 /* 6321 /*
5328 * Iconify the GUI window. 6322 * Iconify the GUI window.
5329 */ 6323 */
5349 */ 6343 */
5350 void 6344 void
5351 gui_mch_draw_hollow_cursor(guicolor_T color) 6345 gui_mch_draw_hollow_cursor(guicolor_T color)
5352 { 6346 {
5353 int i = 1; 6347 int i = 1;
5354 6348 #if GTK_CHECK_VERSION(3,0,0)
6349 cairo_t *cr;
6350 #endif
6351
6352 #if GTK_CHECK_VERSION(3,0,0)
6353 if (gtk_widget_get_window(gui.drawarea) == NULL)
6354 #else
5355 if (gui.drawarea->window == NULL) 6355 if (gui.drawarea->window == NULL)
6356 #endif
5356 return; 6357 return;
5357 6358
6359 #if GTK_CHECK_VERSION(3,0,0)
6360 cr = cairo_create(gui.surface);
6361 #endif
6362
5358 gui_mch_set_fg_color(color); 6363 gui_mch_set_fg_color(color);
5359 6364
6365 #if GTK_CHECK_VERSION(3,0,0)
6366 set_cairo_source_rgb_from_pixel(cr, gui.fgcolor->pixel);
6367 #else
5360 gdk_gc_set_foreground(gui.text_gc, gui.fgcolor); 6368 gdk_gc_set_foreground(gui.text_gc, gui.fgcolor);
6369 #endif
5361 if (mb_lefthalve(gui.row, gui.col)) 6370 if (mb_lefthalve(gui.row, gui.col))
5362 i = 2; 6371 i = 2;
6372 #if GTK_CHECK_VERSION(3,0,0)
6373 cairo_set_line_width(cr, 1.0);
6374 cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT);
6375 cairo_rectangle(cr,
6376 FILL_X(gui.col) + 0.5, FILL_Y(gui.row) + 0.5,
6377 i * gui.char_width - 1, gui.char_height - 1);
6378 cairo_stroke(cr);
6379 cairo_destroy(cr);
6380 #else
5363 gdk_draw_rectangle(gui.drawarea->window, gui.text_gc, 6381 gdk_draw_rectangle(gui.drawarea->window, gui.text_gc,
5364 FALSE, 6382 FALSE,
5365 FILL_X(gui.col), FILL_Y(gui.row), 6383 FILL_X(gui.col), FILL_Y(gui.row),
5366 i * gui.char_width - 1, gui.char_height - 1); 6384 i * gui.char_width - 1, gui.char_height - 1);
6385 #endif
5367 } 6386 }
5368 6387
5369 /* 6388 /*
5370 * Draw part of a cursor, "w" pixels wide, and "h" pixels high, using 6389 * Draw part of a cursor, "w" pixels wide, and "h" pixels high, using
5371 * color "color". 6390 * color "color".
5372 */ 6391 */
5373 void 6392 void
5374 gui_mch_draw_part_cursor(int w, int h, guicolor_T color) 6393 gui_mch_draw_part_cursor(int w, int h, guicolor_T color)
5375 { 6394 {
6395 #if GTK_CHECK_VERSION(3,0,0)
6396 if (gtk_widget_get_window(gui.drawarea) == NULL)
6397 #else
5376 if (gui.drawarea->window == NULL) 6398 if (gui.drawarea->window == NULL)
6399 #endif
5377 return; 6400 return;
5378 6401
5379 gui_mch_set_fg_color(color); 6402 gui_mch_set_fg_color(color);
5380 6403
6404 #if GTK_CHECK_VERSION(3,0,0)
6405 {
6406 cairo_t *cr;
6407
6408 cr = cairo_create(gui.surface);
6409 set_cairo_source_rgb_from_pixel(cr, gui.fgcolor->pixel);
6410 cairo_rectangle(cr,
6411 # ifdef FEAT_RIGHTLEFT
6412 /* vertical line should be on the right of current point */
6413 CURSOR_BAR_RIGHT ? FILL_X(gui.col + 1) - w :
6414 # endif
6415 FILL_X(gui.col), FILL_Y(gui.row) + gui.char_height - h,
6416 w, h);
6417 cairo_fill(cr);
6418 cairo_destroy(cr);
6419 }
6420 #else /* !GTK_CHECK_VERSION(3,0,0) */
5381 gdk_gc_set_foreground(gui.text_gc, gui.fgcolor); 6421 gdk_gc_set_foreground(gui.text_gc, gui.fgcolor);
5382 gdk_draw_rectangle(gui.drawarea->window, gui.text_gc, 6422 gdk_draw_rectangle(gui.drawarea->window, gui.text_gc,
5383 TRUE, 6423 TRUE,
5384 #ifdef FEAT_RIGHTLEFT 6424 # ifdef FEAT_RIGHTLEFT
5385 /* vertical line should be on the right of current point */ 6425 /* vertical line should be on the right of current point */
5386 CURSOR_BAR_RIGHT ? FILL_X(gui.col + 1) - w : 6426 CURSOR_BAR_RIGHT ? FILL_X(gui.col + 1) - w :
5387 #endif 6427 # endif
5388 FILL_X(gui.col), 6428 FILL_X(gui.col),
5389 FILL_Y(gui.row) + gui.char_height - h, 6429 FILL_Y(gui.row) + gui.char_height - h,
5390 w, h); 6430 w, h);
6431 #endif /* !GTK_CHECK_VERSION(3,0,0) */
5391 } 6432 }
5392 6433
5393 6434
5394 /* 6435 /*
5395 * Catch up with any queued X11 events. This may put keyboard input into the 6436 * Catch up with any queued X11 events. This may put keyboard input into the
5402 { 6443 {
5403 while (g_main_context_pending(NULL) && !vim_is_input_buf_full()) 6444 while (g_main_context_pending(NULL) && !vim_is_input_buf_full())
5404 g_main_context_iteration(NULL, TRUE); 6445 g_main_context_iteration(NULL, TRUE);
5405 } 6446 }
5406 6447
6448 #if GTK_CHECK_VERSION(3,0,0)
6449 static gboolean
6450 #else
5407 static gint 6451 static gint
6452 #endif
5408 input_timer_cb(gpointer data) 6453 input_timer_cb(gpointer data)
5409 { 6454 {
5410 int *timed_out = (int *) data; 6455 int *timed_out = (int *) data;
5411 6456
5412 /* Just inform the caller about the occurrence of it */ 6457 /* Just inform the caller about the occurrence of it */
5471 6516
5472 /* this timeout makes sure that we will return if no characters arrived in 6517 /* this timeout makes sure that we will return if no characters arrived in
5473 * time */ 6518 * time */
5474 6519
5475 if (wtime > 0) 6520 if (wtime > 0)
6521 #if GTK_CHECK_VERSION(3,0,0)
6522 timer = g_timeout_add((guint)wtime, input_timer_cb, &timed_out);
6523 #else
5476 timer = gtk_timeout_add((guint32)wtime, input_timer_cb, &timed_out); 6524 timer = gtk_timeout_add((guint32)wtime, input_timer_cb, &timed_out);
6525 #endif
5477 else 6526 else
5478 timer = 0; 6527 timer = 0;
5479 6528
5480 focus = gui.in_focus; 6529 focus = gui.in_focus;
5481 6530
5505 6554
5506 /* Got char, return immediately */ 6555 /* Got char, return immediately */
5507 if (input_available()) 6556 if (input_available())
5508 { 6557 {
5509 if (timer != 0 && !timed_out) 6558 if (timer != 0 && !timed_out)
6559 #if GTK_CHECK_VERSION(3,0,0)
6560 g_source_remove(timer);
6561 #else
5510 gtk_timeout_remove(timer); 6562 gtk_timeout_remove(timer);
6563 #endif
5511 return OK; 6564 return OK;
5512 } 6565 }
5513 } while (wtime < 0 || !timed_out); 6566 } while (wtime < 0 || !timed_out);
5514 6567
5515 /* 6568 /*
5529 /* Flush any output to the screen */ 6582 /* Flush any output to the screen */
5530 void 6583 void
5531 gui_mch_flush(void) 6584 gui_mch_flush(void)
5532 { 6585 {
5533 #ifdef HAVE_GTK_MULTIHEAD 6586 #ifdef HAVE_GTK_MULTIHEAD
6587 # if GTK_CHECK_VERSION(3,0,0)
6588 if (gui.mainwin != NULL && gtk_widget_get_realized(gui.mainwin))
6589 # else
5534 if (gui.mainwin != NULL && GTK_WIDGET_REALIZED(gui.mainwin)) 6590 if (gui.mainwin != NULL && GTK_WIDGET_REALIZED(gui.mainwin))
6591 # endif
5535 gdk_display_sync(gtk_widget_get_display(gui.mainwin)); 6592 gdk_display_sync(gtk_widget_get_display(gui.mainwin));
5536 #else 6593 #else
5537 gdk_flush(); /* historical misnomer: calls XSync(), not XFlush() */ 6594 gdk_flush(); /* historical misnomer: calls XSync(), not XFlush() */
5538 #endif 6595 #endif
5539 /* This happens to actually do what gui_mch_flush() is supposed to do, 6596 /* This happens to actually do what gui_mch_flush() is supposed to do,
5540 * according to the comment above. */ 6597 * according to the comment above. */
6598 #if GTK_CHECK_VERSION(3,0,0)
6599 if (gui.drawarea != NULL && gtk_widget_get_window(gui.drawarea) != NULL)
6600 gdk_window_process_updates(gtk_widget_get_window(gui.drawarea), FALSE);
6601 #else
5541 if (gui.drawarea != NULL && gui.drawarea->window != NULL) 6602 if (gui.drawarea != NULL && gui.drawarea->window != NULL)
5542 gdk_window_process_updates(gui.drawarea->window, FALSE); 6603 gdk_window_process_updates(gui.drawarea->window, FALSE);
6604 #endif
5543 } 6605 }
5544 6606
5545 /* 6607 /*
5546 * Clear a rectangular region of the screen from text pos (row1, col1) to 6608 * Clear a rectangular region of the screen from text pos (row1, col1) to
5547 * (row2, col2) inclusive. 6609 * (row2, col2) inclusive.
5548 */ 6610 */
5549 void 6611 void
5550 gui_mch_clear_block(int row1, int col1, int row2, int col2) 6612 gui_mch_clear_block(int row1, int col1, int row2, int col2)
5551 { 6613 {
6614 #if GTK_CHECK_VERSION(3,0,0)
6615 if (gtk_widget_get_window(gui.drawarea) == NULL)
6616 return;
6617 #else
5552 GdkColor color; 6618 GdkColor color;
5553 6619
5554 if (gui.drawarea->window == NULL) 6620 if (gui.drawarea->window == NULL)
5555 return; 6621 return;
5556 6622
5557 color.pixel = gui.back_pixel; 6623 color.pixel = gui.back_pixel;
5558 6624 #endif
6625
6626 #if GTK_CHECK_VERSION(3,0,0)
6627 {
6628 /* Add one pixel to the far right column in case a double-stroked
6629 * bold glyph may sit there. */
6630 const GdkRectangle rect = {
6631 FILL_X(col1), FILL_Y(row1),
6632 (col2 - col1 + 1) * gui.char_width + (col2 == Columns - 1),
6633 (row2 - row1 + 1) * gui.char_height
6634 };
6635 GdkWindow * const win = gtk_widget_get_window(gui.drawarea);
6636 cairo_t * const cr = cairo_create(gui.surface);
6637 cairo_pattern_t * const pat = gdk_window_get_background_pattern(win);
6638 if (pat != NULL)
6639 cairo_set_source(cr, pat);
6640 else
6641 set_cairo_source_rgb_from_pixel(cr, gui.back_pixel);
6642 gdk_cairo_rectangle(cr, &rect);
6643 cairo_fill(cr);
6644 cairo_destroy(cr);
6645
6646 if (!gui.by_signal)
6647 gdk_window_invalidate_rect(win, &rect, FALSE);
6648 }
6649 #else /* !GTK_CHECK_VERSION(3,0,0) */
5559 gdk_gc_set_foreground(gui.text_gc, &color); 6650 gdk_gc_set_foreground(gui.text_gc, &color);
5560 6651
5561 /* Clear one extra pixel at the far right, for when bold characters have 6652 /* Clear one extra pixel at the far right, for when bold characters have
5562 * spilled over to the window border. */ 6653 * spilled over to the window border. */
5563 gdk_draw_rectangle(gui.drawarea->window, gui.text_gc, TRUE, 6654 gdk_draw_rectangle(gui.drawarea->window, gui.text_gc, TRUE,
5564 FILL_X(col1), FILL_Y(row1), 6655 FILL_X(col1), FILL_Y(row1),
5565 (col2 - col1 + 1) * gui.char_width 6656 (col2 - col1 + 1) * gui.char_width
5566 + (col2 == Columns - 1), 6657 + (col2 == Columns - 1),
5567 (row2 - row1 + 1) * gui.char_height); 6658 (row2 - row1 + 1) * gui.char_height);
5568 } 6659 #endif /* !GTK_CHECK_VERSION(3,0,0) */
6660 }
6661
6662 #if GTK_CHECK_VERSION(3,0,0)
6663 static void
6664 gui_gtk_window_clear(GdkWindow *win)
6665 {
6666 const GdkRectangle rect = {
6667 0, 0, gdk_window_get_width(win), gdk_window_get_height(win)
6668 };
6669 cairo_t * const cr = cairo_create(gui.surface);
6670 cairo_pattern_t * const pat = gdk_window_get_background_pattern(win);
6671 if (pat != NULL)
6672 cairo_set_source(cr, pat);
6673 else
6674 set_cairo_source_rgb_from_pixel(cr, gui.back_pixel);
6675 gdk_cairo_rectangle(cr, &rect);
6676 cairo_fill(cr);
6677 cairo_destroy(cr);
6678
6679 if (!gui.by_signal)
6680 gdk_window_invalidate_rect(win, &rect, FALSE);
6681 }
6682 #endif
5569 6683
5570 void 6684 void
5571 gui_mch_clear_all(void) 6685 gui_mch_clear_all(void)
5572 { 6686 {
6687 #if GTK_CHECK_VERSION(3,0,0)
6688 if (gtk_widget_get_window(gui.drawarea) != NULL)
6689 gui_gtk_window_clear(gtk_widget_get_window(gui.drawarea));
6690 #else
5573 if (gui.drawarea->window != NULL) 6691 if (gui.drawarea->window != NULL)
5574 gdk_window_clear(gui.drawarea->window); 6692 gdk_window_clear(gui.drawarea->window);
5575 } 6693 #endif
5576 6694 }
6695
6696 #if !GTK_CHECK_VERSION(3,0,0)
5577 /* 6697 /*
5578 * Redraw any text revealed by scrolling up/down. 6698 * Redraw any text revealed by scrolling up/down.
5579 */ 6699 */
5580 static void 6700 static void
5581 check_copy_area(void) 6701 check_copy_area(void)
5608 } 6728 }
5609 while (expose_count > 0); /* more events follow */ 6729 while (expose_count > 0); /* more events follow */
5610 6730
5611 gui_can_update_cursor(); 6731 gui_can_update_cursor();
5612 } 6732 }
6733 #endif /* !GTK_CHECK_VERSION(3,0,0) */
6734
6735 #if GTK_CHECK_VERSION(3,0,0)
6736 static void
6737 gui_gtk_surface_copy_rect(int dest_x, int dest_y,
6738 int src_x, int src_y,
6739 int width, int height)
6740 {
6741 cairo_t * const cr = cairo_create(gui.surface);
6742
6743 cairo_rectangle(cr, dest_x, dest_y, width, height);
6744 cairo_clip(cr);
6745 cairo_push_group(cr);
6746 cairo_set_source_surface(cr, gui.surface, dest_x - src_x, dest_y - src_y);
6747 cairo_paint(cr);
6748 cairo_pop_group_to_source(cr);
6749 cairo_paint(cr);
6750
6751 cairo_destroy(cr);
6752 }
6753 #endif
5613 6754
5614 /* 6755 /*
5615 * Delete the given number of lines from the given row, scrolling up any 6756 * Delete the given number of lines from the given row, scrolling up any
5616 * text further down within the scroll region. 6757 * text further down within the scroll region.
5617 */ 6758 */
5618 void 6759 void
5619 gui_mch_delete_lines(int row, int num_lines) 6760 gui_mch_delete_lines(int row, int num_lines)
5620 { 6761 {
6762 #if GTK_CHECK_VERSION(3,0,0)
6763 const int ncols = gui.scroll_region_right - gui.scroll_region_left + 1;
6764 const int nrows = gui.scroll_region_bot - row + 1;
6765 const int src_nrows = nrows - num_lines;
6766
6767 gui_gtk_surface_copy_rect(
6768 FILL_X(gui.scroll_region_left), FILL_Y(row),
6769 FILL_X(gui.scroll_region_left), FILL_Y(row + num_lines),
6770 gui.char_width * ncols + 1, gui.char_height * src_nrows);
6771 gui_clear_block(
6772 gui.scroll_region_bot - num_lines + 1, gui.scroll_region_left,
6773 gui.scroll_region_bot, gui.scroll_region_right);
6774 gui_gtk3_redraw(
6775 FILL_X(gui.scroll_region_left), FILL_Y(row),
6776 gui.char_width * ncols + 1, gui.char_height * nrows);
6777 if (!gui.by_signal)
6778 gtk_widget_queue_draw_area(gui.drawarea,
6779 FILL_X(gui.scroll_region_left), FILL_Y(row),
6780 gui.char_width * ncols + 1, gui.char_height * nrows);
6781 #else
5621 if (gui.visibility == GDK_VISIBILITY_FULLY_OBSCURED) 6782 if (gui.visibility == GDK_VISIBILITY_FULLY_OBSCURED)
5622 return; /* Can't see the window */ 6783 return; /* Can't see the window */
5623 6784
5624 gdk_gc_set_foreground(gui.text_gc, gui.fgcolor); 6785 gdk_gc_set_foreground(gui.text_gc, gui.fgcolor);
5625 gdk_gc_set_background(gui.text_gc, gui.bgcolor); 6786 gdk_gc_set_background(gui.text_gc, gui.bgcolor);
5636 6797
5637 gui_clear_block(gui.scroll_region_bot - num_lines + 1, 6798 gui_clear_block(gui.scroll_region_bot - num_lines + 1,
5638 gui.scroll_region_left, 6799 gui.scroll_region_left,
5639 gui.scroll_region_bot, gui.scroll_region_right); 6800 gui.scroll_region_bot, gui.scroll_region_right);
5640 check_copy_area(); 6801 check_copy_area();
6802 #endif /* !GTK_CHECK_VERSION(3,0,0) */
5641 } 6803 }
5642 6804
5643 /* 6805 /*
5644 * Insert the given number of lines before the given row, scrolling down any 6806 * Insert the given number of lines before the given row, scrolling down any
5645 * following text within the scroll region. 6807 * following text within the scroll region.
5646 */ 6808 */
5647 void 6809 void
5648 gui_mch_insert_lines(int row, int num_lines) 6810 gui_mch_insert_lines(int row, int num_lines)
5649 { 6811 {
6812 #if GTK_CHECK_VERSION(3,0,0)
6813 const int ncols = gui.scroll_region_right - gui.scroll_region_left + 1;
6814 const int nrows = gui.scroll_region_bot - row + 1;
6815 const int src_nrows = nrows - num_lines;
6816
6817 gui_gtk_surface_copy_rect(
6818 FILL_X(gui.scroll_region_left), FILL_Y(row + num_lines),
6819 FILL_X(gui.scroll_region_left), FILL_Y(row),
6820 gui.char_width * ncols + 1, gui.char_height * src_nrows);
6821 gui_mch_clear_block(
6822 row, gui.scroll_region_left,
6823 row + num_lines - 1, gui.scroll_region_right);
6824 gui_gtk3_redraw(
6825 FILL_X(gui.scroll_region_left), FILL_Y(row),
6826 gui.char_width * ncols + 1, gui.char_height * nrows);
6827 if (!gui.by_signal)
6828 gtk_widget_queue_draw_area(gui.drawarea,
6829 FILL_X(gui.scroll_region_left), FILL_Y(row),
6830 gui.char_width * ncols + 1, gui.char_height * nrows);
6831 #else
5650 if (gui.visibility == GDK_VISIBILITY_FULLY_OBSCURED) 6832 if (gui.visibility == GDK_VISIBILITY_FULLY_OBSCURED)
5651 return; /* Can't see the window */ 6833 return; /* Can't see the window */
5652 6834
5653 gdk_gc_set_foreground(gui.text_gc, gui.fgcolor); 6835 gdk_gc_set_foreground(gui.text_gc, gui.fgcolor);
5654 gdk_gc_set_background(gui.text_gc, gui.bgcolor); 6836 gdk_gc_set_background(gui.text_gc, gui.bgcolor);
5663 gui.char_height * (gui.scroll_region_bot - row - num_lines + 1)); 6845 gui.char_height * (gui.scroll_region_bot - row - num_lines + 1));
5664 6846
5665 gui_clear_block(row, gui.scroll_region_left, 6847 gui_clear_block(row, gui.scroll_region_left,
5666 row + num_lines - 1, gui.scroll_region_right); 6848 row + num_lines - 1, gui.scroll_region_right);
5667 check_copy_area(); 6849 check_copy_area();
6850 #endif /* !GTK_CHECK_VERSION(3,0,0) */
5668 } 6851 }
5669 6852
5670 /* 6853 /*
5671 * X Selection stuff, for cutting and pasting text to other windows. 6854 * X Selection stuff, for cutting and pasting text to other windows.
5672 */ 6855 */
5698 if (received_selection != RS_FAIL) 6881 if (received_selection != RS_FAIL)
5699 return; 6882 return;
5700 } 6883 }
5701 6884
5702 /* Final fallback position - use the X CUT_BUFFER0 store */ 6885 /* Final fallback position - use the X CUT_BUFFER0 store */
6886 #if GTK_CHECK_VERSION(3,0,0)
6887 yank_cut_buffer0(GDK_WINDOW_XDISPLAY(gtk_widget_get_window(gui.mainwin)),
6888 cbd);
6889 #else
5703 yank_cut_buffer0(GDK_WINDOW_XDISPLAY(gui.mainwin->window), cbd); 6890 yank_cut_buffer0(GDK_WINDOW_XDISPLAY(gui.mainwin->window), cbd);
6891 #endif
5704 } 6892 }
5705 6893
5706 /* 6894 /*
5707 * Disown the selection. 6895 * Disown the selection.
5708 */ 6896 */
5756 if (menu_is_separator(menu->name)) 6944 if (menu_is_separator(menu->name))
5757 grey = TRUE; 6945 grey = TRUE;
5758 6946
5759 gui_mch_menu_hidden(menu, FALSE); 6947 gui_mch_menu_hidden(menu, FALSE);
5760 /* Be clever about bitfields versus true booleans here! */ 6948 /* Be clever about bitfields versus true booleans here! */
6949 # if GTK_CHECK_VERSION(3,0,0)
6950 if (!gtk_widget_get_sensitive(menu->id) == !grey)
6951 # else
5761 if (!GTK_WIDGET_SENSITIVE(menu->id) == !grey) 6952 if (!GTK_WIDGET_SENSITIVE(menu->id) == !grey)
6953 # endif
5762 { 6954 {
5763 gtk_widget_set_sensitive(menu->id, !grey); 6955 gtk_widget_set_sensitive(menu->id, !grey);
5764 gui_mch_update(); 6956 gui_mch_update();
5765 } 6957 }
5766 } 6958 }
5774 if (menu->id == 0) 6966 if (menu->id == 0)
5775 return; 6967 return;
5776 6968
5777 if (hidden) 6969 if (hidden)
5778 { 6970 {
6971 # if GTK_CHECK_VERSION(3,0,0)
6972 if (gtk_widget_get_visible(menu->id))
6973 # else
5779 if (GTK_WIDGET_VISIBLE(menu->id)) 6974 if (GTK_WIDGET_VISIBLE(menu->id))
6975 # endif
5780 { 6976 {
5781 gtk_widget_hide(menu->id); 6977 gtk_widget_hide(menu->id);
5782 gui_mch_update(); 6978 gui_mch_update();
5783 } 6979 }
5784 } 6980 }
5785 else 6981 else
5786 { 6982 {
6983 # if GTK_CHECK_VERSION(3,0,0)
6984 if (!gtk_widget_get_visible(menu->id))
6985 # else
5787 if (!GTK_WIDGET_VISIBLE(menu->id)) 6986 if (!GTK_WIDGET_VISIBLE(menu->id))
6987 # endif
5788 { 6988 {
5789 gtk_widget_show(menu->id); 6989 gtk_widget_show(menu->id);
5790 gui_mch_update(); 6990 gui_mch_update();
5791 } 6991 }
5792 } 6992 }
5810 gui_mch_enable_scrollbar(scrollbar_T *sb, int flag) 7010 gui_mch_enable_scrollbar(scrollbar_T *sb, int flag)
5811 { 7011 {
5812 if (sb->id == NULL) 7012 if (sb->id == NULL)
5813 return; 7013 return;
5814 7014
7015 #if GTK_CHECK_VERSION(3,0,0)
7016 gtk_widget_set_visible(sb->id, flag);
7017 #else
5815 if (flag) 7018 if (flag)
5816 gtk_widget_show(sb->id); 7019 gtk_widget_show(sb->id);
5817 else 7020 else
5818 gtk_widget_hide(sb->id); 7021 gtk_widget_hide(sb->id);
7022 #endif
5819 7023
5820 update_window_manager_hints(0, 0); 7024 update_window_manager_hints(0, 0);
5821 } 7025 }
5822 7026
5823 7027
5826 */ 7030 */
5827 long_u 7031 long_u
5828 gui_mch_get_rgb(guicolor_T pixel) 7032 gui_mch_get_rgb(guicolor_T pixel)
5829 { 7033 {
5830 GdkColor color; 7034 GdkColor color;
7035 #if GTK_CHECK_VERSION(3,0,0)
7036 GdkRGBA rgba;
7037
7038 gui_gtk_get_rgb_from_pixel(pixel, &rgba);
7039
7040 color.red = rgba.red * 65535;
7041 color.green = rgba.green * 65535;
7042 color.blue = rgba.blue * 65535;
7043 #else
5831 gdk_colormap_query_color(gtk_widget_get_colormap(gui.drawarea), 7044 gdk_colormap_query_color(gtk_widget_get_colormap(gui.drawarea),
5832 (unsigned long)pixel, &color); 7045 (unsigned long)pixel, &color);
7046 #endif
5833 7047
5834 return (((unsigned)color.red & 0xff00) << 8) 7048 return (((unsigned)color.red & 0xff00) << 8)
5835 | ((unsigned)color.green & 0xff00) 7049 | ((unsigned)color.green & 0xff00)
5836 | (((unsigned)color.blue & 0xff00) >> 8); 7050 | (((unsigned)color.blue & 0xff00) >> 8);
5837 } 7051 }
5840 * Get current mouse coordinates in text window. 7054 * Get current mouse coordinates in text window.
5841 */ 7055 */
5842 void 7056 void
5843 gui_mch_getmouse(int *x, int *y) 7057 gui_mch_getmouse(int *x, int *y)
5844 { 7058 {
7059 #if GTK_CHECK_VERSION(3,0,0)
7060 gui_gtk_get_pointer(gui.drawarea, x, y, NULL);
7061 #else
5845 gdk_window_get_pointer(gui.drawarea->window, x, y, NULL); 7062 gdk_window_get_pointer(gui.drawarea->window, x, y, NULL);
7063 #endif
5846 } 7064 }
5847 7065
5848 void 7066 void
5849 gui_mch_setmouse(int x, int y) 7067 gui_mch_setmouse(int x, int y)
5850 { 7068 {
5851 /* Sorry for the Xlib call, but we can't avoid it, since there is no 7069 /* Sorry for the Xlib call, but we can't avoid it, since there is no
5852 * internal GDK mechanism present to accomplish this. (and for good 7070 * internal GDK mechanism present to accomplish this. (and for good
5853 * reason...) */ 7071 * reason...) */
7072 #if GTK_CHECK_VERSION(3,0,0)
7073 XWarpPointer(GDK_WINDOW_XDISPLAY(gtk_widget_get_window(gui.drawarea)),
7074 (Window)0, GDK_WINDOW_XID(gtk_widget_get_window(gui.drawarea)),
7075 0, 0, 0U, 0U, x, y);
7076 #else
5854 XWarpPointer(GDK_WINDOW_XDISPLAY(gui.drawarea->window), 7077 XWarpPointer(GDK_WINDOW_XDISPLAY(gui.drawarea->window),
5855 (Window)0, GDK_WINDOW_XWINDOW(gui.drawarea->window), 7078 (Window)0, GDK_WINDOW_XWINDOW(gui.drawarea->window),
5856 0, 0, 0U, 0U, x, y); 7079 0, 0, 0U, 0U, x, y);
7080 #endif
5857 } 7081 }
5858 7082
5859 7083
5860 #ifdef FEAT_MOUSESHAPE 7084 #ifdef FEAT_MOUSESHAPE
5861 /* The last set mouse pointer shape is remembered, to be used when it goes 7085 /* The last set mouse pointer shape is remembered, to be used when it goes
5872 gui_mch_mousehide(int hide) 7096 gui_mch_mousehide(int hide)
5873 { 7097 {
5874 if (gui.pointer_hidden != hide) 7098 if (gui.pointer_hidden != hide)
5875 { 7099 {
5876 gui.pointer_hidden = hide; 7100 gui.pointer_hidden = hide;
7101 #if GTK_CHECK_VERSION(3,0,0)
7102 if (gtk_widget_get_window(gui.drawarea) && gui.blank_pointer != NULL)
7103 #else
5877 if (gui.drawarea->window && gui.blank_pointer != NULL) 7104 if (gui.drawarea->window && gui.blank_pointer != NULL)
7105 #endif
5878 { 7106 {
5879 if (hide) 7107 if (hide)
7108 #if GTK_CHECK_VERSION(3,0,0)
7109 gdk_window_set_cursor(gtk_widget_get_window(gui.drawarea),
7110 gui.blank_pointer);
7111 #else
5880 gdk_window_set_cursor(gui.drawarea->window, gui.blank_pointer); 7112 gdk_window_set_cursor(gui.drawarea->window, gui.blank_pointer);
7113 #endif
5881 else 7114 else
5882 #ifdef FEAT_MOUSESHAPE 7115 #ifdef FEAT_MOUSESHAPE
5883 mch_set_mouse_shape(last_shape); 7116 mch_set_mouse_shape(last_shape);
5884 #else 7117 #else
5885 gdk_window_set_cursor(gui.drawarea->window, NULL); 7118 gdk_window_set_cursor(gui.drawarea->window, NULL);
5917 mch_set_mouse_shape(int shape) 7150 mch_set_mouse_shape(int shape)
5918 { 7151 {
5919 int id; 7152 int id;
5920 GdkCursor *c; 7153 GdkCursor *c;
5921 7154
7155 # if GTK_CHECK_VERSION(3,0,0)
7156 if (gtk_widget_get_window(gui.drawarea) == NULL)
7157 # else
5922 if (gui.drawarea->window == NULL) 7158 if (gui.drawarea->window == NULL)
7159 # endif
5923 return; 7160 return;
5924 7161
5925 if (shape == MSHAPE_HIDE || gui.pointer_hidden) 7162 if (shape == MSHAPE_HIDE || gui.pointer_hidden)
7163 # if GTK_CHECK_VERSION(3,0,0)
7164 gdk_window_set_cursor(gtk_widget_get_window(gui.drawarea),
7165 gui.blank_pointer);
7166 # else
5926 gdk_window_set_cursor(gui.drawarea->window, gui.blank_pointer); 7167 gdk_window_set_cursor(gui.drawarea->window, gui.blank_pointer);
7168 # endif
5927 else 7169 else
5928 { 7170 {
5929 if (shape >= MSHAPE_NUMBERED) 7171 if (shape >= MSHAPE_NUMBERED)
5930 { 7172 {
5931 id = shape - MSHAPE_NUMBERED; 7173 id = shape - MSHAPE_NUMBERED;
5942 c = gdk_cursor_new_for_display( 7184 c = gdk_cursor_new_for_display(
5943 gtk_widget_get_display(gui.drawarea), (GdkCursorType)id); 7185 gtk_widget_get_display(gui.drawarea), (GdkCursorType)id);
5944 # else 7186 # else
5945 c = gdk_cursor_new((GdkCursorType)id); 7187 c = gdk_cursor_new((GdkCursorType)id);
5946 # endif 7188 # endif
7189 # if GTK_CHECK_VERSION(3,0,0)
7190 gdk_window_set_cursor(gtk_widget_get_window(gui.drawarea), c);
7191 # else
5947 gdk_window_set_cursor(gui.drawarea->window, c); 7192 gdk_window_set_cursor(gui.drawarea->window, c);
7193 # endif
7194 # if GTK_CHECK_VERSION(3,0,0)
7195 g_object_unref(G_OBJECT(c));
7196 # else
5948 gdk_cursor_destroy(c); /* Unref, actually. Bloody GTK+ 1. */ 7197 gdk_cursor_destroy(c); /* Unref, actually. Bloody GTK+ 1. */
7198 # endif
5949 } 7199 }
5950 if (shape != MSHAPE_HIDE) 7200 if (shape != MSHAPE_HIDE)
5951 last_shape = shape; 7201 last_shape = shape;
5952 } 7202 }
5953 #endif /* FEAT_MOUSESHAPE */ 7203 #endif /* FEAT_MOUSESHAPE */
5970 { 7220 {
5971 GdkPixbuf *sign; 7221 GdkPixbuf *sign;
5972 7222
5973 sign = (GdkPixbuf *)sign_get_image(typenr); 7223 sign = (GdkPixbuf *)sign_get_image(typenr);
5974 7224
7225 # if GTK_CHECK_VERSION(3,0,0)
7226 if (sign != NULL && gui.drawarea != NULL
7227 && gtk_widget_get_window(gui.drawarea) != NULL)
7228 # else
5975 if (sign != NULL && gui.drawarea != NULL && gui.drawarea->window != NULL) 7229 if (sign != NULL && gui.drawarea != NULL && gui.drawarea->window != NULL)
7230 # endif
5976 { 7231 {
5977 int width; 7232 int width;
5978 int height; 7233 int height;
5979 int xoffset; 7234 int xoffset;
5980 int yoffset; 7235 int yoffset;
6034 * these offset may become negative if the pixmap is smaller than 7289 * these offset may become negative if the pixmap is smaller than
6035 * the 2x1 cells reserved for the sign icon. */ 7290 * the 2x1 cells reserved for the sign icon. */
6036 xoffset = (width - SIGN_WIDTH) / 2; 7291 xoffset = (width - SIGN_WIDTH) / 2;
6037 yoffset = (height - SIGN_HEIGHT) / 2; 7292 yoffset = (height - SIGN_HEIGHT) / 2;
6038 7293
7294 # if GTK_CHECK_VERSION(3,0,0)
7295 {
7296 cairo_t *cr;
7297 cairo_surface_t *bg_surf;
7298 cairo_t *bg_cr;
7299 cairo_surface_t *sign_surf;
7300 cairo_t *sign_cr;
7301
7302 cr = cairo_create(gui.surface);
7303
7304 bg_surf = cairo_surface_create_similar(gui.surface,
7305 cairo_surface_get_content(gui.surface),
7306 SIGN_WIDTH, SIGN_HEIGHT);
7307 bg_cr = cairo_create(bg_surf);
7308 set_cairo_source_rgb_from_pixel(bg_cr, gui.bgcolor->pixel);
7309 cairo_paint(bg_cr);
7310
7311 sign_surf = cairo_surface_create_similar(gui.surface,
7312 cairo_surface_get_content(gui.surface),
7313 SIGN_WIDTH, SIGN_HEIGHT);
7314 sign_cr = cairo_create(sign_surf);
7315 gdk_cairo_set_source_pixbuf(sign_cr, sign, -xoffset, -yoffset);
7316 cairo_paint(sign_cr);
7317
7318 cairo_set_operator(sign_cr, CAIRO_OPERATOR_DEST_OVER);
7319 cairo_set_source_surface(sign_cr, bg_surf, 0, 0);
7320 cairo_paint(sign_cr);
7321
7322 cairo_set_source_surface(cr, sign_surf, FILL_X(col), FILL_Y(row));
7323 cairo_paint(cr);
7324
7325 cairo_destroy(sign_cr);
7326 cairo_surface_destroy(sign_surf);
7327 cairo_destroy(bg_cr);
7328 cairo_surface_destroy(bg_surf);
7329 cairo_destroy(cr);
7330
7331 if (!gui.by_signal)
7332 gtk_widget_queue_draw_area(gui.drawarea,
7333 FILL_X(col), FILL_Y(col), width, height);
7334
7335 }
7336 # else /* !GTK_CHECK_VERSION(3,0,0) */
6039 gdk_gc_set_foreground(gui.text_gc, gui.bgcolor); 7337 gdk_gc_set_foreground(gui.text_gc, gui.bgcolor);
6040 7338
6041 gdk_draw_rectangle(gui.drawarea->window, 7339 gdk_draw_rectangle(gui.drawarea->window,
6042 gui.text_gc, 7340 gui.text_gc,
6043 TRUE, 7341 TRUE,
6056 MIN(height, SIGN_HEIGHT), 7354 MIN(height, SIGN_HEIGHT),
6057 GDK_PIXBUF_ALPHA_BILEVEL, 7355 GDK_PIXBUF_ALPHA_BILEVEL,
6058 127, 7356 127,
6059 GDK_RGB_DITHER_NORMAL, 7357 GDK_RGB_DITHER_NORMAL,
6060 0, 0); 7358 0, 0);
7359 # endif /* !GTK_CHECK_VERSION(3,0,0) */
6061 if (need_scale) 7360 if (need_scale)
6062 g_object_unref(sign); 7361 g_object_unref(sign);
6063 } 7362 }
6064 } 7363 }
6065 7364