summaryrefslogtreecommitdiff
path: root/src/gui_beval.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-02-23 17:14:37 +0100
committerBram Moolenaar <Bram@vim.org>2016-02-23 17:14:37 +0100
commit9892189d2e7ab94b750f99e6da4cbfc3c8014517 (patch)
tree18634bacebb9e922feceff40c924cdc48550d7ac /src/gui_beval.c
parent6bd364e08461159ad3c153ffba4def5b896486a1 (diff)
downloadvim-git-9892189d2e7ab94b750f99e6da4cbfc3c8014517.tar.gz
patch 7.4.1402v7.4.1402
Problem: GTK 3 is not supported. Solution: Add GTK 3 support. (Kazunobu Kuriyama)
Diffstat (limited to 'src/gui_beval.c')
-rw-r--r--src/gui_beval.c163
1 files changed, 161 insertions, 2 deletions
diff --git a/src/gui_beval.c b/src/gui_beval.c
index e96e67d3f..258ba8aeb 100644
--- a/src/gui_beval.c
+++ b/src/gui_beval.c
@@ -122,7 +122,11 @@ general_beval_cb(BalloonEval *beval, int state UNUSED)
#if !defined(FEAT_GUI_W32) || defined(PROTO)
#ifdef FEAT_GUI_GTK
-# include <gdk/gdkkeysyms.h>
+# if GTK_CHECK_VERSION(3,0,0)
+# include <gdk/gdkkeysyms-compat.h>
+# else
+# include <gdk/gdkkeysyms.h>
+# endif
# include <gtk/gtk.h>
#else
# include <X11/keysym.h>
@@ -164,8 +168,16 @@ static gint target_event_cb(GtkWidget *, GdkEvent *, gpointer);
static gint mainwin_event_cb(GtkWidget *, GdkEvent *, gpointer);
static void pointer_event(BalloonEval *, int, int, unsigned);
static void key_event(BalloonEval *, unsigned, int);
+# if GTK_CHECK_VERSION(3,0,0)
+static gboolean timeout_cb(gpointer);
+# else
static gint timeout_cb(gpointer);
-static gint balloon_expose_event_cb(GtkWidget *, GdkEventExpose *, gpointer);
+# endif
+# if GTK_CHECK_VERSION(3,0,0)
+static gboolean balloon_draw_event_cb (GtkWidget *, cairo_t *, gpointer);
+# else
+static gint balloon_expose_event_cb (GtkWidget *, GdkEventExpose *, gpointer);
+# endif
#else
static void addEventHandler(Widget, BalloonEval *);
static void removeEventHandler(BalloonEval *);
@@ -459,10 +471,16 @@ addEventHandler(GtkWidget *target, BalloonEval *beval)
* This allows us to catch events independently of the signal handlers
* in gui_gtk_x11.c.
*/
+# if GTK_CHECK_VERSION(3,0,0)
+ g_signal_connect(G_OBJECT(target), "event",
+ G_CALLBACK(target_event_cb),
+ beval);
+# else
/* Should use GTK_OBJECT() here, but that causes a lint warning... */
gtk_signal_connect((GtkObject*)(target), "event",
GTK_SIGNAL_FUNC(target_event_cb),
beval);
+# endif
/*
* Nasty: Key press events go to the main window thus the drawing area
* will never see them. This means we have to connect to the main window
@@ -471,9 +489,15 @@ addEventHandler(GtkWidget *target, BalloonEval *beval)
if (gtk_socket_id == 0 && gui.mainwin != NULL
&& gtk_widget_is_ancestor(target, gui.mainwin))
{
+# if GTK_CHECK_VERSION(3,0,0)
+ g_signal_connect(G_OBJECT(gui.mainwin), "event",
+ G_CALLBACK(mainwin_event_cb),
+ beval);
+# else
gtk_signal_connect((GtkObject*)(gui.mainwin), "event",
GTK_SIGNAL_FUNC(mainwin_event_cb),
beval);
+# endif
}
}
@@ -481,17 +505,29 @@ addEventHandler(GtkWidget *target, BalloonEval *beval)
removeEventHandler(BalloonEval *beval)
{
/* LINTED: avoid warning: dubious operation on enum */
+# if GTK_CHECK_VERSION(3,0,0)
+ g_signal_handlers_disconnect_by_func(G_OBJECT(beval->target),
+ G_CALLBACK(target_event_cb),
+ beval);
+# else
gtk_signal_disconnect_by_func((GtkObject*)(beval->target),
GTK_SIGNAL_FUNC(target_event_cb),
beval);
+# endif
if (gtk_socket_id == 0 && gui.mainwin != NULL
&& gtk_widget_is_ancestor(beval->target, gui.mainwin))
{
/* LINTED: avoid warning: dubious operation on enum */
+# if GTK_CHECK_VERSION(3,0,0)
+ g_signal_handlers_disconnect_by_func(G_OBJECT(gui.mainwin),
+ G_CALLBACK(mainwin_event_cb),
+ beval);
+# else
gtk_signal_disconnect_by_func((GtkObject*)(gui.mainwin),
GTK_SIGNAL_FUNC(mainwin_event_cb),
beval);
+# endif
}
}
@@ -517,7 +553,17 @@ target_event_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
* GDK_POINTER_MOTION_HINT_MASK is set, thus we cannot obtain
* the coordinates from the GdkEventMotion struct directly.
*/
+# if GTK_CHECK_VERSION(3,0,0)
+ {
+ GdkWindow * const win = gtk_widget_get_window(widget);
+ GdkDisplay * const dpy = gdk_window_get_display(win);
+ GdkDeviceManager * const mngr = gdk_display_get_device_manager(dpy);
+ GdkDevice * const dev = gdk_device_manager_get_client_pointer(mngr);
+ gdk_window_get_device_position(win, dev , &x, &y, &state);
+ }
+# else
gdk_window_get_pointer(widget->window, &x, &y, &state);
+# endif
pointer_event(beval, x, y, (unsigned int)state);
}
else
@@ -609,8 +655,13 @@ pointer_event(BalloonEval *beval, int x, int y, unsigned state)
}
else
{
+# if GTK_CHECK_VERSION(3,0,0)
+ beval->timerID = g_timeout_add((guint)p_bdlay,
+ &timeout_cb, beval);
+# else
beval->timerID = gtk_timeout_add((guint32)p_bdlay,
&timeout_cb, beval);
+# endif
}
}
}
@@ -647,7 +698,11 @@ key_event(BalloonEval *beval, unsigned keyval, int is_keypress)
cancelBalloon(beval);
}
+# if GTK_CHECK_VERSION(3,0,0)
+ static gboolean
+# else
static gint
+# endif
timeout_cb(gpointer data)
{
BalloonEval *beval = (BalloonEval *)data;
@@ -663,6 +718,37 @@ timeout_cb(gpointer data)
return FALSE; /* don't call me again */
}
+# if GTK_CHECK_VERSION(3,0,0)
+ static gboolean
+balloon_draw_event_cb(GtkWidget *widget,
+ cairo_t *cr,
+ gpointer data UNUSED)
+{
+ GtkStyleContext *context = NULL;
+ gint width = -1, height = -1;
+
+ if (widget == NULL)
+ return TRUE;
+
+ context = gtk_widget_get_style_context(widget);
+ width = gtk_widget_get_allocated_width(widget);
+ height = gtk_widget_get_allocated_height(widget);
+
+ gtk_style_context_save(context);
+
+ gtk_style_context_add_class(context, "tooltip");
+ gtk_style_context_set_state(context, GTK_STATE_FLAG_NORMAL);
+
+ cairo_save(cr);
+ gtk_render_frame(context, cr, 0, 0, width, height);
+ gtk_render_background(context, cr, 0, 0, width, height);
+ cairo_restore(cr);
+
+ gtk_style_context_restore(context);
+
+ return FALSE;
+}
+# else
static gint
balloon_expose_event_cb(GtkWidget *widget,
GdkEventExpose *event,
@@ -675,6 +761,7 @@ balloon_expose_event_cb(GtkWidget *widget,
return FALSE; /* continue emission */
}
+# endif /* !GTK_CHECK_VERSION(3,0,0) */
#else /* !FEAT_GUI_GTK */
@@ -957,8 +1044,37 @@ set_printable_label_text(GtkLabel *label, char_u *text)
aep = syn_gui_attr2entry(hl_attr(HLF_8));
pixel = (aep != NULL) ? aep->ae_u.gui.fg_color : INVALCOLOR;
if (pixel != INVALCOLOR)
+# if GTK_CHECK_VERSION(3,0,0)
+ {
+ GdkVisual * const visual = gtk_widget_get_visual(gui.drawarea);
+
+ if (visual == NULL)
+ {
+ color.red = 0;
+ color.green = 0;
+ color.blue = 0;
+ }
+ else
+ {
+ guint32 r_mask, g_mask, b_mask;
+ gint r_shift, g_shift, b_shift;
+
+ gdk_visual_get_red_pixel_details(visual, &r_mask, &r_shift,
+ NULL);
+ gdk_visual_get_green_pixel_details(visual, &g_mask, &g_shift,
+ NULL);
+ gdk_visual_get_blue_pixel_details(visual, &b_mask, &b_shift,
+ NULL);
+
+ color.red = ((pixel & r_mask) >> r_shift) / 255.0 * 65535;
+ color.green = ((pixel & g_mask) >> g_shift) / 255.0 * 65535;
+ color.blue = ((pixel & b_mask) >> b_shift) / 255.0 * 65535;
+ }
+ }
+# else
gdk_colormap_query_color(gtk_widget_get_colormap(gui.drawarea),
(unsigned long)pixel, &color);
+# endif
pdest = buf;
p = text;
@@ -1059,8 +1175,10 @@ drawBalloon(BalloonEval *beval)
screen_w = gdk_screen_width();
screen_h = gdk_screen_height();
# endif
+# if !GTK_CHECK_VERSION(3,0,0)
gtk_widget_ensure_style(beval->balloonShell);
gtk_widget_ensure_style(beval->balloonLabel);
+# endif
set_printable_label_text(GTK_LABEL(beval->balloonLabel), beval->msg);
/*
@@ -1081,10 +1199,18 @@ drawBalloon(BalloonEval *beval)
MAX(20, screen_w - 20)));
/* Calculate the balloon's width and height. */
+# if GTK_CHECK_VERSION(3,0,0)
+ gtk_widget_get_preferred_size(beval->balloonShell, &requisition, NULL);
+# else
gtk_widget_size_request(beval->balloonShell, &requisition);
+# endif
/* Compute position of the balloon area */
+# if GTK_CHECK_VERSION(3,0,0)
+ gdk_window_get_origin(gtk_widget_get_window(beval->target), &x, &y);
+# else
gdk_window_get_origin(beval->target->window, &x, &y);
+# endif
x += beval->x;
y += beval->y;
@@ -1099,7 +1225,11 @@ drawBalloon(BalloonEval *beval)
y = CLAMP(y + y_offset, 0, MAX(0, screen_h - requisition.height));
/* Show the balloon */
+# if GTK_CHECK_VERSION(3,0,0)
+ gtk_window_move(GTK_WINDOW(beval->balloonShell), x, y);
+# else
gtk_widget_set_uposition(beval->balloonShell, x, y);
+# endif
gtk_widget_show(beval->balloonShell);
beval->showState = ShS_SHOWING;
@@ -1126,7 +1256,11 @@ cancelBalloon(BalloonEval *beval)
if (beval->timerID != 0)
{
+# if GTK_CHECK_VERSION(3,0,0)
+ g_source_remove(beval->timerID);
+# else
gtk_timeout_remove(beval->timerID);
+# endif
beval->timerID = 0;
}
beval->showState = ShS_NEUTRAL;
@@ -1138,17 +1272,42 @@ createBalloonEvalWindow(BalloonEval *beval)
beval->balloonShell = gtk_window_new(GTK_WINDOW_POPUP);
gtk_widget_set_app_paintable(beval->balloonShell, TRUE);
+# if GTK_CHECK_VERSION(3,0,0)
+ gtk_window_set_resizable(GTK_WINDOW(beval->balloonShell), FALSE);
+# else
gtk_window_set_policy(GTK_WINDOW(beval->balloonShell), FALSE, FALSE, TRUE);
+# endif
gtk_widget_set_name(beval->balloonShell, "gtk-tooltips");
+# if GTK_CHECK_VERSION(3,0,0)
+ gtk_container_set_border_width(GTK_CONTAINER(beval->balloonShell), 4);
+# else
gtk_container_border_width(GTK_CONTAINER(beval->balloonShell), 4);
+# endif
+# if GTK_CHECK_VERSION(3,0,0)
+ g_signal_connect(G_OBJECT(beval->balloonShell), "draw",
+ G_CALLBACK(balloon_draw_event_cb), NULL);
+# else
gtk_signal_connect((GtkObject*)(beval->balloonShell), "expose_event",
GTK_SIGNAL_FUNC(balloon_expose_event_cb), NULL);
+# endif
beval->balloonLabel = gtk_label_new(NULL);
gtk_label_set_line_wrap(GTK_LABEL(beval->balloonLabel), FALSE);
gtk_label_set_justify(GTK_LABEL(beval->balloonLabel), GTK_JUSTIFY_LEFT);
+# if GTK_CHECK_VERSION(3,16,0)
+ gtk_label_set_xalign(GTK_LABEL(beval->balloonLabel), 0.5);
+ gtk_label_set_yalign(GTK_LABEL(beval->balloonLabel), 0.5);
+# elif GTK_CHECK_VERSION(3,14,0)
+ GValue align_val = G_VALUE_INIT;
+ g_value_init(&align_val, G_TYPE_FLOAT);
+ g_value_set_float(&align_val, 0.5);
+ g_object_set_property(G_OBJECT(beval->balloonLabel), "xalign", &align_val);
+ g_object_set_property(G_OBJECT(beval->balloonLabel), "yalign", &align_val);
+ g_value_unset(&align_val);
+# else
gtk_misc_set_alignment(GTK_MISC(beval->balloonLabel), 0.5f, 0.5f);
+# endif
gtk_widget_set_name(beval->balloonLabel, "vim-balloon-label");
gtk_widget_show(beval->balloonLabel);