/* vi:set ts=8 sts=4 sw=4 noet:
*
* VIM - Vi IMproved by Bram Moolenaar
* Visual Workshop integration by Gordon Prieur
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
* See README.txt for an overview of the Vim source code.
*/
#include "vim.h"
#if defined(FEAT_BEVAL_GUI) || defined(PROTO)
// on Win32 only get_beval_info() is required
#if !defined(FEAT_GUI_MSWIN) || defined(PROTO)
#ifdef FEAT_GUI_GTK
# 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>
# include <Xm/PushB.h>
# include <Xm/Separator.h>
# include <Xm/List.h>
# include <Xm/Label.h>
# include <Xm/AtomMgr.h>
# include <Xm/Protocols.h>
#endif
#ifndef FEAT_GUI_GTK
extern Widget vimShell;
/*
* Currently, we assume that there can be only one BalloonEval showing
* on-screen at any given moment. This variable will hold the currently
* showing BalloonEval or NULL if none is showing.
*/
static BalloonEval *current_beval = NULL;
#endif
#ifdef FEAT_GUI_GTK
static void addEventHandler(GtkWidget *, BalloonEval *);
static void removeEventHandler(BalloonEval *);
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);
static gboolean timeout_cb(gpointer);
# 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 *);
static void pointerEventEH(Widget, XtPointer, XEvent *, Boolean *);
static void pointerEvent(BalloonEval *, XEvent *);
static void timerRoutine(XtPointer, XtIntervalId *);
#endif
static void cancelBalloon(BalloonEval *);
static void requestBalloon(BalloonEval *);
static void drawBalloon(BalloonEval *);
static void undrawBalloon(BalloonEval *beval);
static void createBalloonEvalWindow(BalloonEval *);
/*
* Create a balloon-evaluation area for a Widget.
* There can be either a "mesg" for a fixed string or "mesgCB" to generate a
* message by calling this callback function.
* When "mesg" is not NULL it must remain valid for as long as the balloon is
* used. It is not freed here.
* Returns a pointer to the resulting object (NULL when out of memory).
*/
BalloonEval *
gui_mch_create_beval_area(
void *target,
char_u *mesg,
void (*mesgCB)(BalloonEval *, int),
void *clientData)
{
#ifndef FEAT_GUI_GTK
char *display_name; // get from gui.dpy
int screen_num;
char *p;
#endif
BalloonEval *beval;
if (mesg != NULL && mesgCB != NULL)
{
iemsg(e_cannot_create_ballooneval_with_both_message_and_callback);
return NULL;
}
beval = ALLOC_CLEAR_ONE(BalloonEval);
if (beval != NULL)
{
#ifdef FEAT_GUI_GTK
beval->target = GTK_WIDGET(target);
#else
beval->target = (Widget)target;
beval->appContext = XtWidgetToApplicationContext((Widget)target);
#endif
beval->showState = ShS_NEUTRAL;
vim_free(beval->msg);
beval->msg = mesg == NULL ? NULL : vim_strsave(mesg);
beval->msgCB = mesgCB;
beval-><