xwidgets style cleanup

Adjust the newly-added Xwidgets code so that it uses a more-typical
Emacs style.  This should not affect behavior, except that in
a few places it adds runtime checks that Lisp arguments are of
the proper type, and in one place it uses more-precise arithmetic.
* src/buffer.c, src/dispnew.c, src/emacs.c, src/emacsgtkfixed.c:
* src/emacs.c, src/print.c, src/window.c, src/xdisp.c, src/xterm.c:
Include xwidget.h unconditionally.
* src/buffer.c (Fkill_buffer):
* src/dispnew.c (update_window):
* src/emacs.c (main):
* src/print.c (print_object):
* src/window.c (Fdelete_window_internal):
* src/xdisp.c (handle_single_display_spec, push_it, pop_it)
(get_next_element, set_iterator_to_next, next_element_from_xwidget)
(dump_glyph, calc_pixel_width_or_height, BUILD_GLYPH_STRINGS_XW)
(BUILD_GLYPH_STRINGS, x_produce_glyphs, get_window_cursor_type):
* src/xterm.c (x_draw_glyph_string, x_draw_bar_cursor):
Call xwidget functions and macros without worrying about
HAVE_XWIDGETS when the code is a no-op on non-xwidget
platforms.
* src/dispextern.h (XWIDGET_GLYPH, struct glyph_string.xwidget)
(IT_XWIDGET, GET_FROM_XWIDGET, struct it.u.xwidget)
(struct it.xwidget):
* src/lisp.h (PVEC_XWIDGET, PVEC_XWIDGET_VIEW):
Always define.
* src/emacsgtkfixed.h: Omit unnecessary comment.
* src/keyboard.c: Fix spacing.
* src/xdisp.c (BUILD_XWIDGET_GLYPH_STRING, produce_xwidget_glyph):
Define to be a no-op if not HAVE_XWIDGETS.
* src/xwidget.c: Include xwidget.h first (after config.h)
to make sure that it can stand by itself.
(Fmake_xwidget, Fxwidget_webkit_execute_script):
Fix typo in doc string.
(Fmake_xwidget): Check type of args.
(Fmake_xwidget, offscreen_damage_event)
(webkit_document_load_finished_cb, webkit_download_cb)
(webkit_new_window_policy_decision_requested_cb)
(webkit_navigation_policy_decision_requested_cb)
(xwidget_osr_draw_cb, xwidget_osr_event_forward)
(xwidget_osr_event_set_embedder, xwidget_init_view):
Omit unnecessary casts.
* src/xwidget.c (Fmake_xwidget, xwidget_hidden)
(xwidget_show_view, xwidget_hide_view)
(x_draw_xwidget_glyph_string, xwidget_start_redisplay, xwidget_touch)
(xwidget_touched):
* src/xwidget.h (struct xwidget.kill_without_query)
(struct xwidget_view.redisplayed, struct xwidget_view.hidden):
Use bool for boolean.
* src/xwidget.c (store_xwidget_event_string, Fxwidget_size_request):
Simplify by using list functions.
(WEBKIT_FN_INIT): Omit unnecessary test for nil.
(Fxwidget_resize): Check type of integer args
before doing any work.  Check that they are nonnegative.
(Fxwidget_set_adjustment): Check type of integer arg.
Avoid redundant call to gtk_scrolled_window_get_vadjustment.
Simplify.  Use double, not float.
(Fxwidget_info, Fxwidget_view_info): Simplify by using CALLN.
(valid_xwidget_spec_p): Simplify.
(xwidget_spec_value): Omit unused arg FOUND.  All callers changed.
* src/xwidget.h: Include lisp.h first, so that includers do
not need to worry about doing that before including this file.
Make this .h file safe to include even on non-HAVE_XWIDGETS
configurations, to simplify the includers.
(x_draw_xwidget_glyph_string, syms_of_xwidget, valid_xwidget_spec_p)
(xwidget_end_redisplay, lookup_xwidget)
(xwidget_view_delete_all_in_window, kill_buffer_xwidgets):
Now a no-op if !HAVE_XWIDGETS, to simplify callers.
(struct glyph_matrix, struct glyph_string, struct xwidget)
(struct xwidget_view, struct window):
New forward or incomplete decls, so that includers need not
assume the corresponding .h files are already included, or that
HAVE_XWIDGETS is defined.
(struct xwidget_type, xwidget_from_id): Remove; unused.
This commit is contained in:
Paul Eggert 2016-01-22 11:15:05 -08:00
parent 7bf54d0115
commit 7c3d742c35
14 changed files with 328 additions and 538 deletions

View file

@ -42,10 +42,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "blockinput.h"
#include "keymap.h"
#include "frame.h"
#include "xwidget.h"
#ifdef HAVE_XWIDGETS
# include "xwidget.h"
#endif
#ifdef WINDOWSNT
#include "w32heap.h" /* for mmap_* */
#endif
@ -1749,10 +1747,8 @@ cleaning up all windows currently displaying the buffer to be killed. */)
unlock_buffer (b);
kill_buffer_processes (buffer);
#ifdef HAVE_XWIDGETS
kill_buffer_xwidgets (buffer);
#endif
/* Killing buffer processes may run sentinels which may have killed
our buffer. */
if (!BUFFER_LIVE_P (b))

View file

@ -347,11 +347,10 @@ enum glyph_type
IMAGE_GLYPH,
/* Glyph is a space of fractional width and/or height. */
STRETCH_GLYPH
#ifdef HAVE_XWIDGETS
/* Glyph is an external widget drawn by the GUI toolkit. */
,XWIDGET_GLYPH
#endif
STRETCH_GLYPH,
/* Glyph is an external widget drawn by the GUI toolkit. */
XWIDGET_GLYPH
};
@ -504,8 +503,10 @@ struct glyph
int img_id;
#ifdef HAVE_XWIDGETS
/* Xwidget reference (type == XWIDGET_GLYPH). */
struct xwidget *xwidget;
#endif
/* Sub-structure for type == STRETCH_GLYPH. */
struct
{
@ -1357,9 +1358,9 @@ struct glyph_string
/* Image, if any. */
struct image *img;
#ifdef HAVE_XWIDGETS
/* Xwidget. */
struct xwidget *xwidget;
#endif
/* Slice */
struct glyph_slice slice;
@ -2111,11 +2112,10 @@ enum display_element_type
IT_TRUNCATION,
/* Continuation glyphs. See the comment for IT_TRUNCATION. */
IT_CONTINUATION
IT_CONTINUATION,
#ifdef HAVE_XWIDGETS
,IT_XWIDGET
#endif
/* Xwidget. */
IT_XWIDGET
};
@ -2179,9 +2179,7 @@ enum it_method {
GET_FROM_C_STRING,
GET_FROM_IMAGE,
GET_FROM_STRETCH,
#ifdef HAVE_XWIDGETS
GET_FROM_XWIDGET,
#endif
NUM_IT_METHODS
};
@ -2399,12 +2397,10 @@ struct it
struct {
Lisp_Object object;
} stretch;
#ifdef HAVE_XWIDGETS
/* method == GET_FROM_XWIDGET */
struct {
Lisp_Object object;
} xwidget;
#endif
} u;
/* Current text and display positions. */
@ -2529,10 +2525,8 @@ struct it
/* If what == IT_IMAGE, the id of the image to display. */
ptrdiff_t image_id;
#ifdef HAVE_XWIDGETS
/* If what == IT_XWIDGET. */
struct xwidget *xwidget;
#endif
/* Values from `slice' property. */
struct it_slice slice;

View file

@ -39,15 +39,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "syssignal.h"
#include "systime.h"
#include "tparam.h"
#include "xwidget.h"
#ifdef HAVE_WINDOW_SYSTEM
#include TERM_HEADER
#endif /* HAVE_WINDOW_SYSTEM */
#ifdef HAVE_XWIDGETS
# include "xwidget.h"
#endif
#include <errno.h>
#include <fpending.h>
@ -3549,9 +3546,7 @@ update_window (struct window *w, bool force_p)
add_window_display_history (w, w->current_matrix->method, paused_p);
#endif
#ifdef HAVE_XWIDGETS
xwidget_end_redisplay (w, w->current_matrix);
#endif
clear_glyph_matrix (desired_matrix);
return paused_p;

View file

@ -65,10 +65,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "character.h"
#include "buffer.h"
#include "window.h"
#ifdef HAVE_XWIDGETS
# include "xwidget.h"
#endif
#include "xwidget.h"
#include "atimer.h"
#include "blockinput.h"
#include "syssignal.h"
@ -1492,9 +1489,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
syms_of_xfns ();
syms_of_xmenu ();
syms_of_fontset ();
#ifdef HAVE_XWIDGETS
syms_of_xwidget ();
#endif
syms_of_xsettings ();
#ifdef HAVE_X_SM
syms_of_xsmfns ();

View file

@ -23,9 +23,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "lisp.h"
#include "frame.h"
#include "xterm.h"
#ifdef HAVE_XWIDGETS
# include "xwidget.h"
#endif
#include "xwidget.h"
#include "emacsgtkfixed.h"
/* Silence a bogus diagnostic; see GNOME bug 683906. */
@ -50,7 +48,6 @@ static void emacs_fixed_get_preferred_width (GtkWidget *widget,
static void emacs_fixed_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural);
static GType emacs_fixed_get_type (void);
G_DEFINE_TYPE (EmacsFixed, emacs_fixed, GTK_TYPE_FIXED)
@ -75,28 +72,28 @@ struct GtkFixedPrivateL
GList *children;
};
static void emacs_fixed_gtk_widget_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
static void
emacs_fixed_gtk_widget_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
// For xwidgets.
/* For xwidgets.
// This basically re-implements the base class method and adds an
// additional case for an xwidget view.
This basically re-implements the base class method and adds an
additional case for an xwidget view.
// It would be nicer if the bse class method could be called first,
// and the the xview modification only would remain here. It wasn't
// possible to solve it that way yet.
It would be nicer if the bse class method could be called first,
and the the xview modification only would remain here. It wasn't
possible to solve it that way yet. */
EmacsFixedClass *klass;
GtkWidgetClass *parent_class;
struct GtkFixedPrivateL* priv;
struct GtkFixedPrivateL *priv;
klass = EMACS_FIXED_GET_CLASS (widget);
parent_class = g_type_class_peek_parent (klass);
parent_class->size_allocate (widget, allocation);
priv = G_TYPE_INSTANCE_GET_PRIVATE (widget,
GTK_TYPE_FIXED,
struct GtkFixedPrivateL);
priv = G_TYPE_INSTANCE_GET_PRIVATE (widget, GTK_TYPE_FIXED,
struct GtkFixedPrivateL);
gtk_widget_set_allocation (widget, allocation);
@ -154,7 +151,6 @@ emacs_fixed_class_init (EmacsFixedClass *klass)
widget_class = (GtkWidgetClass*) klass;
widget_class->get_preferred_width = emacs_fixed_get_preferred_width;
widget_class->get_preferred_height = emacs_fixed_get_preferred_height;
#ifdef HAVE_XWIDGETS
@ -163,7 +159,6 @@ emacs_fixed_class_init (EmacsFixedClass *klass)
g_type_class_add_private (klass, sizeof (EmacsFixedPrivate));
}
static void
emacs_fixed_init (EmacsFixed *fixed)
{
@ -172,14 +167,7 @@ emacs_fixed_init (EmacsFixed *fixed)
fixed->priv->f = 0;
}
/**
* emacs_fixed_new:
*
* Creates a new #EmacsFixed.
*
* Returns: a new #EmacsFixed.
*/
GtkWidget*
GtkWidget *
emacs_fixed_new (struct frame *f)
{
EmacsFixed *fixed = g_object_new (emacs_fixed_get_type (), NULL);

View file

@ -29,7 +29,6 @@ G_BEGIN_DECLS
struct frame;
//typedef struct _EmacsFixed EmacsFixed;
typedef struct _EmacsFixedPrivate EmacsFixedPrivate;
typedef struct _EmacsFixedClass EmacsFixedClass;
@ -41,7 +40,6 @@ struct _EmacsFixed
EmacsFixedPrivate *priv;
};
struct _EmacsFixedClass
{
GtkFixedClass parent_class;

View file

@ -5960,7 +5960,7 @@ make_lispy_event (struct input_event *event)
#ifdef HAVE_XWIDGETS
case XWIDGET_EVENT:
{
return Fcons (Qxwidget_event,event->arg);
return Fcons (Qxwidget_event, event->arg);
}
#endif
@ -10972,7 +10972,7 @@ syms_of_keyboard (void)
#endif
#ifdef HAVE_XWIDGETS
DEFSYM (Qxwidget_event,"xwidget-event");
DEFSYM (Qxwidget_event, "xwidget-event");
#endif
#ifdef USE_FILE_NOTIFY

View file

@ -799,11 +799,8 @@ enum pvec_type
PVEC_WINDOW_CONFIGURATION,
PVEC_SUBR,
PVEC_OTHER,
#ifdef HAVE_XWIDGETS
PVEC_XWIDGET,
PVEC_XWIDGET_VIEW,
#endif
/* These should be last, check internal_equal to see why. */
PVEC_COMPILED,

View file

@ -32,10 +32,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "disptab.h"
#include "intervals.h"
#include "blockinput.h"
#ifdef HAVE_XWIDGETS
# include "xwidget.h"
#endif
#include "xwidget.h"
#include <c-ctype.h>
#include <float.h>
@ -1740,18 +1737,11 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
print_c_string (XSUBR (obj)->symbol_name, printcharfun);
printchar ('>', printcharfun);
}
#ifdef HAVE_XWIDGETS
else if (XWIDGETP (obj))
else if (XWIDGETP (obj) || XWIDGET_VIEW_P (obj))
{
print_c_string ("#<xwidget ", printcharfun);
printchar ('>', printcharfun);
}
else if (XWIDGET_VIEW_P (obj))
{
print_c_string ("#<xwidget ", printcharfun);
printchar ('>', printcharfun);
}
#endif
else if (WINDOWP (obj))
{
int len = sprintf (buf, "#<window %"pI"d",

View file

@ -35,15 +35,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "dispextern.h"
#include "blockinput.h"
#include "termhooks.h" /* For FRAME_TERMINAL. */
#include "xwidget.h"
#ifdef HAVE_WINDOW_SYSTEM
#include TERM_HEADER
#endif /* HAVE_WINDOW_SYSTEM */
#ifdef MSDOS
#include "msdos.h"
#endif
#ifdef HAVE_XWIDGETS
# include "xwidget.h"
#endif
static ptrdiff_t count_windows (struct window *);
static ptrdiff_t get_leaf_windows (struct window *, struct window **,
@ -4373,9 +4371,7 @@ Signal an error when WINDOW is the only window on its frame. */)
/* Block input. */
block_input ();
#ifdef HAVE_XWIDGETS
xwidget_view_delete_all_in_window (w);
#endif
window_resize_apply (p, horflag);
/* If this window is referred to by the dpyinfo's mouse
highlight, invalidate that slot to be safe (Bug#9904). */

View file

@ -314,13 +314,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "font.h"
#include "fontset.h"
#include "blockinput.h"
#include "xwidget.h"
#ifdef HAVE_WINDOW_SYSTEM
#include TERM_HEADER
#endif /* HAVE_WINDOW_SYSTEM */
#ifdef HAVE_XWIDGETS
# include "xwidget.h"
#endif
#ifndef FRAME_X_OUTPUT
#define FRAME_X_OUTPUT(f) ((f)->output_data.x)
#endif
@ -857,9 +855,7 @@ static bool next_element_from_buffer (struct it *);
static bool next_element_from_composition (struct it *);
static bool next_element_from_image (struct it *);
static bool next_element_from_stretch (struct it *);
#ifdef HAVE_XWIDGETS
static bool next_element_from_xwidget (struct it *);
#endif
static void load_overlay_strings (struct it *, ptrdiff_t);
static bool get_next_display_element (struct it *);
static enum move_it_result
@ -5147,11 +5143,8 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
&& valid_image_p (value))
#endif /* not HAVE_WINDOW_SYSTEM */
|| (CONSP (value) && EQ (XCAR (value), Qspace))
#ifdef HAVE_XWIDGETS
|| ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
&& valid_xwidget_spec_p (value))
#endif
);
&& valid_xwidget_spec_p (value)));
if (valid_p && display_replaced == 0)
{
@ -5226,17 +5219,15 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
*position = it->position = start_pos;
retval = 1 + (it->area == TEXT_AREA);
}
#ifdef HAVE_XWIDGETS
else if (valid_xwidget_spec_p(value))
else if (valid_xwidget_spec_p (value))
{
it->what = IT_XWIDGET;
it->method = GET_FROM_XWIDGET;
it->position = start_pos;
it->object = NILP (object) ? it->w->contents : object;
*position = start_pos;
it->xwidget = lookup_xwidget(value);
it->xwidget = lookup_xwidget (value);
}
#endif
#ifdef HAVE_WINDOW_SYSTEM
else
{
@ -5989,11 +5980,9 @@ push_it (struct it *it, struct text_pos *position)
case GET_FROM_STRETCH:
p->u.stretch.object = it->object;
break;
#ifdef HAVE_XWIDGETS
case GET_FROM_XWIDGET:
p->u.xwidget.object = it->object;
break;
#endif
case GET_FROM_BUFFER:
case GET_FROM_DISPLAY_VECTOR:
case GET_FROM_STRING:
@ -6095,11 +6084,9 @@ pop_it (struct it *it)
it->object = p->u.image.object;
it->slice = p->u.image.slice;
break;
#ifdef HAVE_XWIDGETS
case GET_FROM_XWIDGET:
it->object = p->u.xwidget.object;
break;
#endif
case GET_FROM_STRETCH:
it->object = p->u.stretch.object;
break;
@ -6775,9 +6762,7 @@ static next_element_function const get_next_element[NUM_IT_METHODS] =
next_element_from_c_string,
next_element_from_image,
next_element_from_stretch,
#ifdef HAVE_XWIDGETS
next_element_from_xwidget,
#endif
};
#define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
@ -7638,9 +7623,7 @@ set_iterator_to_next (struct it *it, bool reseat_p)
case GET_FROM_IMAGE:
case GET_FROM_STRETCH:
#ifdef HAVE_XWIDGETS
case GET_FROM_XWIDGET:
#endif
/* The position etc with which we have to proceed are on
the stack. The position may be at the end of a string,
@ -8103,14 +8086,12 @@ next_element_from_image (struct it *it)
return true;
}
#ifdef HAVE_XWIDGETS
static bool
next_element_from_xwidget (struct it *it)
{
it->what = IT_XWIDGET;
return true;
}
#endif
/* Fill iterator IT with next display element from a stretch glyph
@ -18844,7 +18825,6 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
glyph->left_box_line_p,
glyph->right_box_line_p);
}
#ifdef HAVE_XWIDGETS
else if (glyph->type == XWIDGET_GLYPH)
{
fprintf (stderr,
@ -18865,7 +18845,6 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
glyph->right_box_line_p);
}
#endif
}
@ -24364,13 +24343,11 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
return OK_PIXELS (width_p ? img->width : img->height);
}
# ifdef HAVE_XWIDGETS
if (FRAME_WINDOW_P (it->f) && valid_xwidget_spec_p (prop))
{
// TODO: Don't return dummy size.
return OK_PIXELS (100);
}
# endif
#endif
if (EQ (car, Qplus) || EQ (car, Qminus))
{
@ -25273,8 +25250,11 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
} \
while (false)
#ifdef HAVE_XWIDGETS
#define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
#ifndef HAVE_XWIDGETS
# define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
eassume (false)
#else
# define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
do \
{ \
s = alloca (sizeof *s); \
@ -25287,7 +25267,6 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
while (false)
#endif
/* Add a glyph string for a sequence of character glyphs to the list
of strings between HEAD and TAIL. START is the index of the first
glyph in row area AREA of glyph row ROW that is part of the new
@ -25441,13 +25420,11 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
HL, X, LAST_X); \
break;
#ifdef HAVE_XWIDGETS
# define BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
#define BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
case XWIDGET_GLYPH: \
BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL, \
HL, X, LAST_X); \
break;
#endif
#define BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X) \
case GLYPHLESS_GLYPH: \
@ -25456,7 +25433,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
break; \
\
default: \
emacs_abort (); \
emacs_abort (); \
} \
\
if (s) \
@ -25468,16 +25445,10 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
} while (false)
#ifdef HAVE_XWIDGETS
# define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
#define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
#else
# define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
#endif
/* Draw glyphs between START and END in AREA of ROW on window W,
@ -26118,10 +26089,10 @@ produce_image_glyph (struct it *it)
}
}
#ifdef HAVE_XWIDGETS
static void
produce_xwidget_glyph (struct it *it)
{
#ifdef HAVE_XWIDGETS
struct xwidget *xw;
int glyph_ascent, crop;
eassert (it->what == IT_XWIDGET);
@ -26219,8 +26190,8 @@ produce_xwidget_glyph (struct it *it)
else
IT_EXPAND_MATRIX_WIDTH (it, area);
}
}
#endif
}
/* Append a stretch glyph to IT->glyph_row. OBJECT is the source
of the glyph, WIDTH and HEIGHT are the width and height of the
@ -27631,10 +27602,8 @@ x_produce_glyphs (struct it *it)
produce_image_glyph (it);
else if (it->what == IT_STRETCH)
produce_stretch_glyph (it);
#ifdef HAVE_XWIDGETS
else if (it->what == IT_XWIDGET)
produce_xwidget_glyph (it);
#endif
done:
/* Accumulate dimensions. Note: can't assume that it->descent > 0
@ -28004,10 +27973,8 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
/* Use normal cursor if not blinked off. */
if (!w->cursor_off_p)
{
#ifdef HAVE_XWIDGETS
if (glyph != NULL && glyph->type == XWIDGET_GLYPH)
return NO_CURSOR;
#endif
if (glyph != NULL && glyph->type == IMAGE_GLYPH)
{
if (cursor_type == FILLED_BOX_CURSOR)

View file

@ -62,9 +62,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "composite.h"
#include "frame.h"
#include "dispextern.h"
#ifdef HAVE_XWIDGETS
# include "xwidget.h"
#endif
#include "xwidget.h"
#include "fontset.h"
#include "termhooks.h"
#include "termopts.h"
@ -3514,11 +3512,9 @@ x_draw_glyph_string (struct glyph_string *s)
x_draw_image_glyph_string (s);
break;
#ifdef HAVE_XWIDGETS
case XWIDGET_GLYPH:
x_draw_xwidget_glyph_string (s);
break;
#endif
case STRETCH_GLYPH:
x_draw_stretch_glyph_string (s);
@ -8929,10 +8925,9 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text
if (cursor_glyph == NULL)
return;
#ifdef HAVE_XWIDGETS
/* Experimental avoidance of cursor on xwidget. */
if (cursor_glyph->type == XWIDGET_GLYPH)
return; // Experimental avoidance of cursor on xwidget.
#endif
return;
/* If on an image, draw like a normal cursor. That's usually better
visible than drawing a bar, esp. if the image is large so that

View file

@ -19,6 +19,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include "xwidget.h"
#include <signal.h>
@ -105,8 +106,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <webkit/webkitdownload.h>
#include <webkit/webkitwebpolicydecision.h>
#include "xwidget.h"
static struct xwidget *
allocate_xwidget (void)
{
@ -120,8 +119,8 @@ allocate_xwidget_view (void)
PVEC_XWIDGET_VIEW);
}
#define XSETXWIDGET(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_XWIDGET))
#define XSETXWIDGET_VIEW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_XWIDGET_VIEW))
#define XSETXWIDGET(a, b) XSETPSEUDOVECTOR (a, b, PVEC_XWIDGET)
#define XSETXWIDGET_VIEW(a, b) XSETPSEUDOVECTOR (a, b, PVEC_XWIDGET_VIEW)
static struct xwidget_view *xwidget_view_lookup (struct xwidget *,
struct window *);
@ -163,67 +162,57 @@ If BUFFER is nil, use the current buffer.
If BUFFER is a string and no such buffer exists, create it.
TYPE is a symbol which can take one of the following values:
- webkit_osr
- webkit-osr
Returns the newly constructed xwidget, or nil if construction fails. */)
(Lisp_Object beg, Lisp_Object end,
Lisp_Object type,
Lisp_Object title,
Lisp_Object width, Lisp_Object height,
Lisp_Object arguments, Lisp_Object buffer)
(Lisp_Object beg, Lisp_Object end, Lisp_Object type,
Lisp_Object title, Lisp_Object width, Lisp_Object height,
Lisp_Object arguments, Lisp_Object buffer)
{
//should work a bit like "make-button"(make-button BEG END &rest PROPERTIES)
// arg "type" and fwd should be keyword args eventually
//(make-xwidget 3 3 'button "oei" 31 31 nil)
//(xwidget-info (car xwidget-list))
CHECK_SYMBOL (type);
CHECK_NATNUM (width);
CHECK_NATNUM (height);
/* This should work a bit like "make-button"
(make-button BEG END &rest PROPERTIES)
TYPE etc. should be keyword args eventually.
(make-xwidget 3 3 'button "oei" 31 31 nil)
(xwidget-info (car xwidget-list)) */
struct xwidget *xw = allocate_xwidget ();
Lisp_Object val;
xw->type = type;
xw->title = title;
if (NILP (buffer))
buffer = Fcurrent_buffer (); // no need to gcpro because
// Fcurrent_buffer doesn't
// call Feval/eval_sub.
else
buffer = Fget_buffer_create (buffer);
xw->buffer = buffer;
xw->buffer = NILP (buffer) ? Fcurrent_buffer () : Fget_buffer_create (buffer);
xw->height = XFASTINT (height);
xw->width = XFASTINT (width);
xw->kill_without_query = 0;
XSETXWIDGET (val, xw); // set the vectorlike_header of VAL
// with the correct value
xw->kill_without_query = false;
XSETXWIDGET (val, xw);
Vxwidget_list = Fcons (val, Vxwidget_list);
xw->widgetwindow_osr = NULL;
xw->widget_osr = NULL;
xw->plist = Qnil;
if (EQ (xw->type, Qwebkit_osr))
{
block_input ();
xw->widgetwindow_osr = gtk_offscreen_window_new ();
gtk_window_resize (GTK_WINDOW (xw->widgetwindow_osr), xw->width,
xw->height);
xw->widgetscrolledwindow_osr = NULL; //webkit osr is the
//only scrolled
//component atm
/* WebKit OSR is the only scrolled component at the moment. */
xw->widgetscrolledwindow_osr = NULL;
if (EQ (xw->type, Qwebkit_osr))
{
xw->widgetscrolledwindow_osr = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW
(xw->
widgetscrolledwindow_osr),
xw->height);
gtk_scrolled_window_set_min_content_width (GTK_SCROLLED_WINDOW
(xw->
widgetscrolledwindow_osr),
xw->width);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW
(xw->widgetscrolledwindow_osr),
GTK_POLICY_ALWAYS,
GTK_POLICY_ALWAYS);
gtk_scrolled_window_set_min_content_height
(GTK_SCROLLED_WINDOW (xw->widgetscrolledwindow_osr),
xw->height);
gtk_scrolled_window_set_min_content_width
(GTK_SCROLLED_WINDOW (xw->widgetscrolledwindow_osr),
xw->width);
gtk_scrolled_window_set_policy
(GTK_SCROLLED_WINDOW (xw->widgetscrolledwindow_osr),
GTK_POLICY_ALWAYS, GTK_POLICY_ALWAYS);
xw->widget_osr = webkit_web_view_new ();
gtk_container_add (GTK_CONTAINER (xw->widgetscrolledwindow_osr),
@ -248,12 +237,10 @@ Returns the newly constructed xwidget, or nil if construction fails. */)
gtk_widget_show (xw->widgetwindow_osr);
gtk_widget_show (xw->widgetscrolledwindow_osr);
/* store some xwidget data in the gtk widgets for convenient
/* Store some xwidget data in the gtk widgets for convenient
retrieval in the event handlers. */
g_object_set_data (G_OBJECT (xw->widget_osr), XG_XWIDGET,
(gpointer) (xw));
g_object_set_data (G_OBJECT (xw->widgetwindow_osr), XG_XWIDGET,
(gpointer) (xw));
g_object_set_data (G_OBJECT (xw->widget_osr), XG_XWIDGET, xw);
g_object_set_data (G_OBJECT (xw->widgetwindow_osr), XG_XWIDGET, xw);
/* signals */
if (EQ (xw->type, Qwebkit_osr))
@ -286,7 +273,6 @@ Returns the newly constructed xwidget, or nil if construction fails. */)
}
unblock_input ();
}
return val;
@ -317,18 +303,16 @@ BUFFER may be a buffer or the name of one. */)
return xw_list;
}
static int
static bool
xwidget_hidden (struct xwidget_view *xv)
{
return xv->hidden;
}
static void
xwidget_show_view (struct xwidget_view *xv)
{
xv->hidden = 0;
xv->hidden = false;
gtk_widget_show (xv->widgetwindow);
gtk_fixed_move (GTK_FIXED (xv->emacswindow),
xv->widgetwindow,
@ -336,33 +320,30 @@ xwidget_show_view (struct xwidget_view *xv)
xv->y + xv->clip_top);
}
/* Hide an xvidget view. */
static void
xwidget_hide_view (struct xwidget_view *xv)
{
xv->hidden = 1;
xv->hidden = true;
gtk_fixed_move (GTK_FIXED (xv->emacswindow), xv->widgetwindow,
10000, 10000);
}
/* When the off-screen webkit master view changes this signal is called.
It copies the bitmap from the off-screen instance. */
static gboolean
offscreen_damage_event (GtkWidget * widget, GdkEvent * event,
offscreen_damage_event (GtkWidget *widget, GdkEvent *event,
gpointer xv_widget)
{
// Queue a redraw of onscreen widget.
// There is a guard against receiving an invalid widget,
// which should only happen if we failed to remove the
// specific signal handler for the damage event.
/* Queue a redraw of onscreen widget.
There is a guard against receiving an invalid widget,
which should only happen if we failed to remove the
specific signal handler for the damage event. */
if (GTK_IS_WIDGET (xv_widget))
gtk_widget_queue_draw (GTK_WIDGET (xv_widget));
else
printf ("Warning, offscreen_damage_event received invalid xv pointer:%p\n",
(void *) xv_widget);
xv_widget);
return FALSE;
}
@ -377,75 +358,58 @@ store_xwidget_event_string (struct xwidget *xw, const char *eventname,
EVENT_INIT (event);
event.kind = XWIDGET_EVENT;
event.frame_or_window = Qnil;
event.arg = Qnil;
event.arg = Fcons (build_string (eventstr), event.arg);
event.arg = Fcons (xwl, event.arg);
event.arg = Fcons (intern (eventname), event.arg);
event.arg = list3 (intern (eventname), xwl, build_string (eventstr));
kbd_buffer_store_event (&event);
}
//TODO deprecated, use load-status
/* TODO deprecated, use load-status. */
void
webkit_document_load_finished_cb (WebKitWebView * webkitwebview,
WebKitWebFrame * arg1,
webkit_document_load_finished_cb (WebKitWebView *webkitwebview,
WebKitWebFrame *arg1,
gpointer data)
{
struct xwidget *xw =
(struct xwidget *) g_object_get_data (G_OBJECT (webkitwebview),
struct xwidget *xw = g_object_get_data (G_OBJECT (webkitwebview),
XG_XWIDGET);
store_xwidget_event_string (xw, "document-load-finished", "");
}
gboolean
webkit_download_cb (WebKitWebView * webkitwebview,
WebKitDownload * arg1,
webkit_download_cb (WebKitWebView *webkitwebview,
WebKitDownload *arg1,
gpointer data)
{
struct xwidget *xw =
(struct xwidget *) g_object_get_data (G_OBJECT (webkitwebview),
struct xwidget *xw = g_object_get_data (G_OBJECT (webkitwebview),
XG_XWIDGET);
store_xwidget_event_string (xw, "download-requested",
webkit_download_get_uri (arg1));
return FALSE;
}
static gboolean
webkit_mime_type_policy_typedecision_requested_cb (WebKitWebView *webView,
WebKitWebFrame *frame,
WebKitNetworkRequest * request,
gchar * mimetype,
WebKitWebPolicyDecision *policy_decision,
gpointer user_data)
webkit_mime_type_policy_typedecision_requested_cb
(WebKitWebView *webView, WebKitWebFrame *frame, WebKitNetworkRequest *request,
gchar *mimetype, WebKitWebPolicyDecision *policy_decision, gpointer user_data)
{
// This function makes webkit send a download signal for all unknown
// mime types. TODO Defer the decision to lisp, so that its possible
// to make Emacs handle teext mime for instance.xs
/* This function makes webkit send a download signal for all unknown
mime types. TODO: Defer the decision to Lisp, so that it's
possible to make Emacs handle teext mime for instance.xs. */
if (!webkit_web_view_can_show_mime_type (webView, mimetype))
{
webkit_web_policy_decision_download (policy_decision);
return TRUE;
}
else
{
return FALSE;
}
return FALSE;
}
static gboolean
webkit_new_window_policy_decision_requested_cb (WebKitWebView *webView,
WebKitWebFrame *frame,
WebKitNetworkRequest *request,
WebKitWebNavigationAction *navigation_action,
WebKitWebPolicyDecision *policy_decision,
gpointer user_data)
webkit_new_window_policy_decision_requested_cb
(WebKitWebView *webView, WebKitWebFrame *frame, WebKitNetworkRequest *request,
WebKitWebNavigationAction *navigation_action,
WebKitWebPolicyDecision *policy_decision, gpointer user_data)
{
struct xwidget *xw =
(struct xwidget *) g_object_get_data (G_OBJECT (webView), XG_XWIDGET);
struct xwidget *xw = g_object_get_data (G_OBJECT (webView), XG_XWIDGET);
webkit_web_navigation_action_get_original_uri (navigation_action);
store_xwidget_event_string (xw, "new-window-policy-decision-requested",
@ -455,29 +419,24 @@ webkit_new_window_policy_decision_requested_cb (WebKitWebView *webView,
}
static gboolean
webkit_navigation_policy_decision_requested_cb (WebKitWebView *webView,
WebKitWebFrame *frame,
WebKitNetworkRequest *request,
WebKitWebNavigationAction *navigation_action,
WebKitWebPolicyDecision * policy_decision,
gpointer user_data)
webkit_navigation_policy_decision_requested_cb
(WebKitWebView *webView, WebKitWebFrame *frame, WebKitNetworkRequest *request,
WebKitWebNavigationAction *navigation_action,
WebKitWebPolicyDecision *policy_decision, gpointer user_data)
{
struct xwidget *xw =
(struct xwidget *) g_object_get_data (G_OBJECT (webView), XG_XWIDGET);
struct xwidget *xw = g_object_get_data (G_OBJECT (webView), XG_XWIDGET);
store_xwidget_event_string (xw, "navigation-policy-decision-requested",
webkit_web_navigation_action_get_original_uri
(navigation_action));
return FALSE;
}
// For gtk3 offscreen rendered widgets.
/* For gtk3 offscreen rendered widgets. */
static gboolean
xwidget_osr_draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data)
xwidget_osr_draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data)
{
struct xwidget *xw =
(struct xwidget *) g_object_get_data (G_OBJECT (widget), XG_XWIDGET);
struct xwidget_view *xv =
(struct xwidget_view *) g_object_get_data (G_OBJECT (widget),
struct xwidget *xw = g_object_get_data (G_OBJECT (widget), XG_XWIDGET);
struct xwidget_view *xv = g_object_get_data (G_OBJECT (widget),
XG_XWIDGET_VIEW);
cairo_rectangle (cr, 0, 0, xv->clip_right, xv->clip_bottom);
@ -491,31 +450,30 @@ xwidget_osr_draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data)
}
static gboolean
xwidget_osr_event_forward (GtkWidget * widget,
GdkEvent * event,
gpointer user_data)
xwidget_osr_event_forward (GtkWidget *widget, GdkEvent *event,
gpointer user_data)
{
/* Copy events that arrive at the outer widget to the offscreen widget. */
struct xwidget *xw =
(struct xwidget *) g_object_get_data (G_OBJECT (widget), XG_XWIDGET);
struct xwidget *xw = g_object_get_data (G_OBJECT (widget), XG_XWIDGET);
GdkEvent *eventcopy = gdk_event_copy (event);
eventcopy->any.window = gtk_widget_get_window (xw->widget_osr);
//TODO This might leak events. They should be deallocated later,
//perhaps in xwgir_event_cb
/* TODO: This might leak events. They should be deallocated later,
perhaps in xwgir_event_cb. */
gtk_main_do_event (eventcopy);
return TRUE; //dont propagate this event furter
/* Don't propagate this event further. */
return TRUE;
}
static gboolean
xwidget_osr_event_set_embedder (GtkWidget * widget,
GdkEvent * event, gpointer data)
xwidget_osr_event_set_embedder (GtkWidget *widget, GdkEvent *event,
gpointer data)
{
struct xwidget_view *xv = (struct xwidget_view *) data;
struct xwidget_view *xv = data;
struct xwidget *xww = XXWIDGET (xv->model);
gdk_offscreen_window_set_embedder (gtk_widget_get_window
(xww->widgetwindow_osr),
(xww->widgetwindow_osr),
gtk_widget_get_window (xv->widget));
return FALSE;
}
@ -539,11 +497,11 @@ xwidget_init_view (struct xwidget *xww,
if (EQ (xww->type, Qwebkit_osr))
{
xv->widget = gtk_drawing_area_new ();
// Expose event handling.
/* Expose event handling. */
gtk_widget_set_app_paintable (xv->widget, TRUE);
gtk_widget_add_events (xv->widget, GDK_ALL_EVENTS_MASK);
/* Draw the view on damage-event */
/* Draw the view on damage-event. */
g_signal_connect (G_OBJECT (xww->widgetwindow_osr), "damage-event",
G_CALLBACK (offscreen_damage_event), xv->widget);
@ -558,38 +516,33 @@ xwidget_init_view (struct xwidget *xww,
}
else
{
// xwgir debug , orthogonal to forwarding
/* xwgir debug, orthogonal to forwarding. */
g_signal_connect (G_OBJECT (xv->widget), "enter-notify-event",
G_CALLBACK (xwidget_osr_event_set_embedder), xv);
}
g_signal_connect (G_OBJECT (xv->widget), "draw",
G_CALLBACK (xwidget_osr_draw_cb), NULL);
}
// Widget realization.
// Make container widget 1st, and put the actual widget inside the
// container later. Drawing should crop container window if necessary
// to handle case where xwidget is partially obscured by other Emacs
// windows. Other containers than gtk_fixed where explored, but
// gtk_fixed had the most predictable behaviour so far.
/* Widget realization.
Make container widget first, and put the actual widget inside the
container later. Drawing should crop container window if necessary
to handle case where xwidget is partially obscured by other Emacs
windows. Other containers than gtk_fixed where explored, but
gtk_fixed had the most predictable behaviour so far. */
xv->emacswindow = FRAME_GTK_WIDGET (s->f);
xv->widgetwindow = gtk_fixed_new ();
gtk_widget_set_has_window (xv->widgetwindow, TRUE);
gtk_container_add (GTK_CONTAINER (xv->widgetwindow), xv->widget);
// Store some xwidget data in the gtk widgets.
// The emacs frame.
g_object_set_data (G_OBJECT (xv->widget), XG_FRAME_DATA, (gpointer) (s->f));
// The xwidget.
g_object_set_data (G_OBJECT (xv->widget), XG_XWIDGET, (gpointer) (xww));
// The xwidget.
g_object_set_data (G_OBJECT (xv->widget), XG_XWIDGET_VIEW, (gpointer) (xv));
// The xwidget window.
g_object_set_data (G_OBJECT (xv->widgetwindow), XG_XWIDGET, (gpointer) (xww));
// the xwidget view.
g_object_set_data (G_OBJECT (xv->widgetwindow), XG_XWIDGET_VIEW,
(gpointer) (xv));
/* Store some xwidget data in the gtk widgets. */
g_object_set_data (G_OBJECT (xv->widget), XG_FRAME_DATA, s->f);
g_object_set_data (G_OBJECT (xv->widget), XG_XWIDGET, xww);
g_object_set_data (G_OBJECT (xv->widget), XG_XWIDGET_VIEW, xv);
g_object_set_data (G_OBJECT (xv->widgetwindow), XG_XWIDGET, xww);
g_object_set_data (G_OBJECT (xv->widgetwindow), XG_XWIDGET_VIEW, xv);
gtk_widget_set_size_request (GTK_WIDGET (xv->widget), xww->width,
xww->height);
@ -599,18 +552,15 @@ xwidget_init_view (struct xwidget *xww,
xv->y = y;
gtk_widget_show_all (xv->widgetwindow);
return xv;
}
void
x_draw_xwidget_glyph_string (struct glyph_string *s)
{
/* This method is called by the redisplay engine and places the
xwidget on screen. Moving and clipping is done here. Also view
initialization.
*/
initialization. */
struct xwidget *xww = s->xwidget;
struct xwidget_view *xv = xwidget_view_lookup (xww, s->w);
int clip_right;
@ -620,16 +570,14 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
int x = s->x;
int y = s->y + (s->height / 2) - (xww->height / 2);
int moved = 0;
/* We do initialization here in the display loop because there is no
other time to know things like window placement etc.
*/
/* Do initialization here in the display loop because there is no
other time to know things like window placement etc. */
xv = xwidget_init_view (xww, s, x, y);
// Calculate clipping, which is used for all manner of onscreen
// xwidget views. Each widget border can get clipped by other emacs
// objects so there are four clipping variables.
/* Calculate clipping, which is used for all manner of onscreen
xwidget views. Each widget border can get clipped by other emacs
objects so there are four clipping variables. */
clip_right =
min (xww->width,
WINDOW_RIGHT_EDGE_X (s->w) - x -
@ -646,31 +594,32 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
WINDOW_BOTTOM_EDGE_Y (s->w) - WINDOW_MODE_LINE_HEIGHT (s->w) - y);
clip_top = max (0, WINDOW_TOP_EDGE_Y (s->w) - y);
// We are conserned with movement of the onscreen area. The area
// might sit still when the widget actually moves. This happens
// when an Emacs window border moves across a widget window. So, if
// any corner of the outer widget clipping window moves, that counts
// as movement here, even if it looks like no movement happens
// because the widget sits still inside the clipping area. The
// widget can also move inside the clipping area, which happens
// later
moved = (xv->x + xv->clip_left != x + clip_left)
|| ((xv->y + xv->clip_top) != (y + clip_top));
/* We are conserned with movement of the onscreen area. The area
might sit still when the widget actually moves. This happens
when an Emacs window border moves across a widget window. So, if
any corner of the outer widget clipping window moves, that counts
as movement here, even if it looks like no movement happens
because the widget sits still inside the clipping area. The
widget can also move inside the clipping area, which happens
later. */
bool moved = (xv->x + xv->clip_left != x + clip_left
|| xv->y + xv->clip_top != y + clip_top);
xv->x = x;
xv->y = y;
if (moved) // Has it moved?
{
gtk_fixed_move (GTK_FIXED (FRAME_GTK_WIDGET (s->f)),
xv->widgetwindow, x + clip_left, y + clip_top);
}
// Clip the widget window if some parts happen to be outside
// drawable area. An Emacs window is not a gtk window. A gtk window
// covers the entire frame. Clipping might have changed even if we
// havent actualy moved, we try figure out when we need to reclip
// for real.
if ((xv->clip_right != clip_right)
|| (xv->clip_bottom != clip_bottom)
|| (xv->clip_top != clip_top) || (xv->clip_left != clip_left))
/* Has it moved? */
if (moved)
gtk_fixed_move (GTK_FIXED (FRAME_GTK_WIDGET (s->f)),
xv->widgetwindow, x + clip_left, y + clip_top);
/* Clip the widget window if some parts happen to be outside
drawable area. An Emacs window is not a gtk window. A gtk window
covers the entire frame. Clipping might have changed even if we
havent actualy moved, we try figure out when we need to reclip
for real. */
if (xv->clip_right != clip_right
|| xv->clip_bottom != clip_bottom
|| xv->clip_top != clip_top || xv->clip_left != clip_left)
{
gtk_widget_set_size_request (xv->widgetwindow, clip_right + clip_left,
clip_bottom + clip_top);
@ -682,10 +631,11 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
xv->clip_top = clip_top;
xv->clip_left = clip_left;
}
// If emacs wants to repaint the area where the widget lives, queue
// a redraw. It seems its possible to get out of sync with emacs
// redraws so emacs background sometimes shows up instead of the
// xwidgets background. It's just a visual glitch though.
/* If emacs wants to repaint the area where the widget lives, queue
a redraw. It seems its possible to get out of sync with emacs
redraws so emacs background sometimes shows up instead of the
xwidgets background. It's just a visual glitch though. */
if (!xwidget_hidden (xv))
{
gtk_widget_queue_draw (xv->widgetwindow);
@ -693,19 +643,15 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
}
}
// Macro that checks WEBKIT_IS_WEB_VIEW(xw->widget_osr) first
#define WEBKIT_FN_INIT() \
struct xwidget* xw; \
CHECK_XWIDGET (xwidget); \
if (NILP (xwidget)) {printf("ERROR xwidget nil\n"); return Qnil;}; \
xw = XXWIDGET (xwidget); \
if (NULL == xw) printf("ERROR xw is 0\n"); \
if ((NULL == xw->widget_osr) || !WEBKIT_IS_WEB_VIEW(xw->widget_osr)){ \
printf ("ERROR xw->widget_osr does not hold a webkit instance\n");\
return Qnil;\
};
/* Macro that checks WEBKIT_IS_WEB_VIEW (xw->widget_osr) first. */
#define WEBKIT_FN_INIT() \
CHECK_XWIDGET (xwidget); \
struct xwidget *xw = XXWIDGET (xwidget); \
if (!xw->widget_osr || !WEBKIT_IS_WEB_VIEW (xw->widget_osr)) \
{ \
printf ("ERROR xw->widget_osr does not hold a webkit instance\n"); \
return Qnil; \
}
DEFUN ("xwidget-webkit-goto-uri",
Fxwidget_webkit_goto_uri, Sxwidget_webkit_goto_uri,
@ -723,7 +669,7 @@ DEFUN ("xwidget-webkit-goto-uri",
DEFUN ("xwidget-webkit-execute-script",
Fxwidget_webkit_execute_script, Sxwidget_webkit_execute_script,
2, 2, 0,
doc: /* Make the Webkit XWIDGET execute javascript SCRIPT. */)
doc: /* Make the Webkit XWIDGET execute JavaScript SCRIPT. */)
(Lisp_Object xwidget, Lisp_Object script)
{
WEBKIT_FN_INIT ();
@ -741,14 +687,14 @@ This can be used to work around the lack of a return value from the
exec method. */ )
(Lisp_Object xwidget)
{
// TODO support multibyte strings
/* TODO support multibyte strings. */
WEBKIT_FN_INIT ();
const gchar *str =
webkit_web_view_get_title (WEBKIT_WEB_VIEW (xw->widget_osr));
if (str == 0)
{
// TODO maybe return Qnil instead. I suppose webkit returns
// nullpointer when doc is not properly loaded or something
/* TODO maybe return Qnil instead. I suppose webkit returns
null pointer when doc is not properly loaded or something. */
return build_string ("");
}
return build_string (str);
@ -759,32 +705,30 @@ DEFUN ("xwidget-resize", Fxwidget_resize, Sxwidget_resize, 3, 3, 0,
(Lisp_Object xwidget, Lisp_Object new_width, Lisp_Object new_height)
{
CHECK_XWIDGET (xwidget);
CHECK_NATNUM (new_width);
CHECK_NATNUM (new_height);
struct xwidget *xw = XXWIDGET (xwidget);
struct xwidget_view *xv;
int w, h;
CHECK_NUMBER (new_width);
CHECK_NUMBER (new_height);
w = XFASTINT (new_width);
h = XFASTINT (new_height);
int w = XFASTINT (new_width);
int h = XFASTINT (new_height);
xw->width = w;
xw->height = h;
// If there is a offscreen widget resize it 1st.
/* If there is an offscreen widget resize it first. */
if (xw->widget_osr)
{
/* Use minimum size. */
gtk_widget_set_size_request (GTK_WIDGET (xw->widget_osr),
xw->width, xw->height); //minimum size
xw->width, xw->height);
gtk_window_resize (GTK_WINDOW (xw->widgetwindow_osr), xw->width,
xw->height);
gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW
(xw->
widgetscrolledwindow_osr),
xw->height);
gtk_scrolled_window_set_min_content_width (GTK_SCROLLED_WINDOW
(xw->
widgetscrolledwindow_osr),
xw->width);
gtk_scrolled_window_set_min_content_height
(GTK_SCROLLED_WINDOW (xw->widgetscrolledwindow_osr),
xw->height);
gtk_scrolled_window_set_min_content_width
(GTK_SCROLLED_WINDOW (xw->widgetscrolledwindow_osr),
xw->width);
gtk_container_resize_children (GTK_CONTAINER (xw->widgetwindow_osr));
@ -794,7 +738,7 @@ DEFUN ("xwidget-resize", Fxwidget_resize, Sxwidget_resize, 3, 3, 0,
{
if (XWIDGET_VIEW_P (XCAR (tail)))
{
xv = XXWIDGET_VIEW (XCAR (tail));
struct xwidget_view *xv = XXWIDGET_VIEW (XCAR (tail));
if (XXWIDGET (xv->model) == xw)
gtk_widget_set_size_request (GTK_WIDGET (xv->widget), xw->width,
xw->height);
@ -816,37 +760,17 @@ VALUE is the amount to scroll, either relatively or absolutely. */)
Lisp_Object value)
{
CHECK_XWIDGET (xwidget);
CHECK_NATNUM (value);
struct xwidget *xw = XXWIDGET (xwidget);
GtkAdjustment *adjustment;
float final_value = 0.0;
adjustment =
gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW
(xw->widgetscrolledwindow_osr));
if (EQ (Qvertical, axis))
{
adjustment =
gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW
(xw->widgetscrolledwindow_osr));
}
if (EQ (Qhorizontal, axis))
{
adjustment =
gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW
(xw->widgetscrolledwindow_osr));
}
GtkAdjustment *adjustment
= ((EQ (Qhorizontal, axis)
? gtk_scrolled_window_get_hadjustment
: gtk_scrolled_window_get_vadjustment)
(GTK_SCROLLED_WINDOW (xw->widgetscrolledwindow_osr)));
double final_value = XFASTINT (value);
if (EQ (Qt, relative))
{
final_value = gtk_adjustment_get_value (adjustment) + XFASTINT (value);
}
else
{
final_value = 0.0 + XFASTINT (value);
}
final_value += gtk_adjustment_get_value (adjustment);
gtk_adjustment_set_value (adjustment, final_value);
return Qnil;
}
@ -861,13 +785,9 @@ Emacs allocated area accordingly. */)
{
CHECK_XWIDGET (xwidget);
GtkRequisition requisition;
Lisp_Object rv;
gtk_widget_size_request (XXWIDGET (xwidget)->widget_osr, &requisition);
rv = Qnil;
rv = Fcons (make_number (requisition.height), rv);
rv = Fcons (make_number (requisition.width), rv);
return rv;
return list2 (make_number (requisition.width),
make_number (requisition.height));
}
DEFUN ("xwidgetp",
@ -896,18 +816,9 @@ Currently [TYPE TITLE WIDTH HEIGHT]. */)
(Lisp_Object xwidget)
{
CHECK_XWIDGET (xwidget);
Lisp_Object info, n;
struct xwidget *xw = XXWIDGET (xwidget);
info = Fmake_vector (make_number (4), Qnil);
ASET (info, 0, xw->type);
ASET (info, 1, xw->title);
XSETFASTINT (n, xw->width);
ASET (info, 2, n);
XSETFASTINT (n, xw->height);
ASET (info, 3, n);
return info;
return CALLN (Fvector, xw->type, xw->title,
make_natnum (xw->width), make_natnum (xw->height));
}
DEFUN ("xwidget-view-info",
@ -919,17 +830,9 @@ Currently [X Y CLIP_RIGHT CLIP_BOTTOM CLIP_TOP CLIP_LEFT]. */)
{
CHECK_XWIDGET_VIEW (xwidget_view);
struct xwidget_view *xv = XXWIDGET_VIEW (xwidget_view);
Lisp_Object info;
info = Fmake_vector (make_number (6), Qnil);
ASET (info, 0, make_number (xv->x));
ASET (info, 1, make_number (xv->y));
ASET (info, 2, make_number (xv->clip_right));
ASET (info, 3, make_number (xv->clip_bottom));
ASET (info, 4, make_number (xv->clip_top));
ASET (info, 5, make_number (xv->clip_left));
return info;
return CALLN (Fvector, make_number (xv->x), make_number (xv->y),
make_number (xv->clip_right), make_number (xv->clip_bottom),
make_number (xv->clip_top), make_number (xv->clip_left));
}
DEFUN ("xwidget-view-model",
@ -963,8 +866,8 @@ DEFUN ("delete-xwidget-view",
struct xwidget_view *xv = XXWIDGET_VIEW (xwidget_view);
gtk_widget_destroy (xv->widgetwindow);
Vxwidget_view_list = Fdelq (xwidget_view, Vxwidget_view_list);
// xv->model still has signals pointing to the view. There can be
// several views. Find the matching signals and delete them all.
/* xv->model still has signals pointing to the view. There can be
several views. Find the matching signals and delete them all. */
g_signal_handlers_disconnect_matched (XXWIDGET (xv->model)->widgetwindow_osr,
G_SIGNAL_MATCH_DATA,
0, 0, 0, 0,
@ -1002,7 +905,7 @@ DEFUN ("xwidget-plist",
Fxwidget_plist, Sxwidget_plist,
1, 1, 0,
doc: /* Return the plist of XWIDGET. */)
(register Lisp_Object xwidget)
(Lisp_Object xwidget)
{
CHECK_XWIDGET (xwidget);
return XXWIDGET (xwidget)->plist;
@ -1012,7 +915,7 @@ DEFUN ("xwidget-buffer",
Fxwidget_buffer, Sxwidget_buffer,
1, 1, 0,
doc: /* Return the buffer of XWIDGET. */)
(register Lisp_Object xwidget)
(Lisp_Object xwidget)
{
CHECK_XWIDGET (xwidget);
return XXWIDGET (xwidget)->buffer;
@ -1023,7 +926,7 @@ DEFUN ("set-xwidget-plist",
2, 2, 0,
doc: /* Replace the plist of XWIDGET with PLIST.
Returns PLIST. */)
(register Lisp_Object xwidget, Lisp_Object plist)
(Lisp_Object xwidget, Lisp_Object plist)
{
CHECK_XWIDGET (xwidget);
CHECK_LIST (plist);
@ -1059,7 +962,6 @@ DEFUN ("xwidget-query-on-exit-flag",
void
syms_of_xwidget (void)
{
defsubr (&Smake_xwidget);
defsubr (&Sxwidgetp);
DEFSYM (Qxwidgetp, "xwidgetp");
@ -1111,7 +1013,6 @@ syms_of_xwidget (void)
Vxwidget_view_list = Qnil;
Fprovide (intern ("xwidget-internal"), Qnil);
}
@ -1125,19 +1026,13 @@ syms_of_xwidget (void)
bool
valid_xwidget_spec_p (Lisp_Object object)
{
int valid_p = false;
if (CONSP (object) && EQ (XCAR (object), Qxwidget))
valid_p = true;
return valid_p;
return CONSP (object) && EQ (XCAR (object), Qxwidget);
}
/* Find a value associated with key in spec. */
static Lisp_Object
xwidget_spec_value (Lisp_Object spec, Lisp_Object key, int *found)
xwidget_spec_value (Lisp_Object spec, Lisp_Object key)
{
Lisp_Object tail;
@ -1147,15 +1042,9 @@ xwidget_spec_value (Lisp_Object spec, Lisp_Object key, int *found)
CONSP (tail) && CONSP (XCDR (tail)); tail = XCDR (XCDR (tail)))
{
if (EQ (XCAR (tail), key))
{
if (found)
*found = 1;
return XCAR (XCDR (tail));
}
return XCAR (XCDR (tail));
}
if (found)
*found = 0;
return Qnil;
}
@ -1195,19 +1084,17 @@ lookup_xwidget (Lisp_Object spec)
{
/* When a xwidget lisp spec is found initialize the C struct that is
used in the C code. This is done by redisplay so values change
if the spec changes. So, take special care of one-shot events.
*/
int found = 0;
if the spec changes. So, take special care of one-shot events. */
Lisp_Object value;
struct xwidget *xw;
value = xwidget_spec_value (spec, QCxwidget, &found);
value = xwidget_spec_value (spec, QCxwidget);
xw = XXWIDGET (value);
return xw;
}
/* Set up detection of touched xwidget */
/* Set up detection of touched xwidget. */
static void
xwidget_start_redisplay (void)
{
@ -1215,7 +1102,7 @@ xwidget_start_redisplay (void)
tail = XCDR (tail))
{
if (XWIDGET_VIEW_P (XCAR (tail)))
XXWIDGET_VIEW (XCAR (tail))->redisplayed = 0;
XXWIDGET_VIEW (XCAR (tail))->redisplayed = false;
}
}
@ -1224,57 +1111,48 @@ xwidget_start_redisplay (void)
static void
xwidget_touch (struct xwidget_view *xv)
{
xv->redisplayed = 1;
xv->redisplayed = true;
}
static int
static bool
xwidget_touched (struct xwidget_view *xv)
{
return xv->redisplayed;
}
/* Redisplay has ended, now we should hide untouched xwidgets
*/
/* Redisplay has ended, now we should hide untouched xwidgets. */
void
xwidget_end_redisplay (struct window *w, struct glyph_matrix *matrix)
{
int i;
int area;
xwidget_start_redisplay ();
// Iterate desired glyph matrix of window here, hide gtk widgets
// not in the desired matrix.
/* Iterate desired glyph matrix of window here, hide gtk widgets
not in the desired matrix.
// This only takes care of xwidgets in active windows. If a window
// goes away from screen xwidget views wust be deleted
This only takes care of xwidgets in active windows. If a window
goes away from screen xwidget views wust be deleted.
// dump_glyph_matrix (matrix, 2);
dump_glyph_matrix (matrix, 2); */
for (i = 0; i < matrix->nrows; ++i)
{
// dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
/* dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs); */
struct glyph_row *row;
row = MATRIX_ROW (matrix, i);
if (row->enabled_p != 0)
{
for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
{
struct glyph *glyph = row->glyphs[area];
struct glyph *glyph_end = glyph + row->used[area];
for (; glyph < glyph_end; ++glyph)
{
if (glyph->type == XWIDGET_GLYPH)
{
/*
The only call to xwidget_end_redisplay is in dispnew
xwidget_end_redisplay (w->current_matrix);
*/
xwidget_touch (xwidget_view_lookup (glyph->u.xwidget,
w));
}
}
}
}
if (row->enabled_p)
for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
{
struct glyph *glyph = row->glyphs[area];
struct glyph *glyph_end = glyph + row->used[area];
for (; glyph < glyph_end; ++glyph)
if (glyph->type == XWIDGET_GLYPH)
{
/* The only call to xwidget_end_redisplay is in dispnew.
xwidget_end_redisplay (w->current_matrix); */
xwidget_touch (xwidget_view_lookup (glyph->u.xwidget, w));
}
}
}
for (Lisp_Object tail = Vxwidget_view_list; CONSP (tail);
@ -1284,8 +1162,8 @@ xwidget_end_redisplay (struct window *w, struct glyph_matrix *matrix)
{
struct xwidget_view *xv = XXWIDGET_VIEW (XCAR (tail));
// "touched" is only meaningful for the current window, so
// disregard other views.
/* "touched" is only meaningful for the current window, so
disregard other views. */
if (XWINDOW (xv->w) == w)
{
if (xwidget_touched (xv))
@ -1306,7 +1184,7 @@ kill_buffer_xwidgets (Lisp_Object buffer)
{
xwidget = XCAR (tail);
Vxwidget_list = Fdelq (xwidget, Vxwidget_list);
/* TODO free the GTK things in xw */
/* TODO free the GTK things in xw. */
{
CHECK_XWIDGET (xwidget);
struct xwidget *xw = XXWIDGET (xwidget);

View file

@ -20,60 +20,62 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#ifndef XWIDGET_H_INCLUDED
#define XWIDGET_H_INCLUDED
void x_draw_xwidget_glyph_string (struct glyph_string *s);
void syms_of_xwidget (void);
#include "lisp.h"
//extern Lisp_Object Qxwidget;
struct glyph_matrix;
struct glyph_string;
struct xwidget;
struct xwidget_view;
struct window;
#ifdef HAVE_XWIDGETS
# include <gtk/gtk.h>
bool valid_xwidget_spec_p (Lisp_Object object);
#include <gtk/gtk.h>
/*
each xwidget instance/model is described by this struct.
lisp pseudovector.
*/
struct xwidget
{
struct vectorlike_header header;
Lisp_Object plist; //auxilliary data
Lisp_Object type; //the widget type
Lisp_Object buffer; //buffer where xwidget lives
Lisp_Object title; //a title that is used for button labels for instance
//here ends the lisp part.
//"height" is the marker field
/* Auxiliary data. */
Lisp_Object plist;
/* The widget type. */
Lisp_Object type;
/* The buffer where the xwidget lives. */
Lisp_Object buffer;
/* A title used for button labels, for instance. */
Lisp_Object title;
/* Here ends the Lisp part. "height" is the marker field. */
int height;
int width;
//for offscreen widgets, unused if not osr
/* For offscreen widgets, unused if not osr. */
GtkWidget *widget_osr;
GtkWidget *widgetwindow_osr;
//this is used if the widget (webkit) is to be wrapped in a scrolled window,
GtkWidget *widgetscrolledwindow_osr;
/* Non-nil means kill silently if Emacs is exited. */
unsigned int kill_without_query:1;
/* Used if the widget (webkit) is to be wrapped in a scrolled window. */
GtkWidget *widgetscrolledwindow_osr;
/* Kill silently if Emacs is exited. */
bool_bf kill_without_query : 1;
};
//struct for each xwidget view
struct xwidget_view
{
struct vectorlike_header header;
Lisp_Object model;
Lisp_Object w;
//here ends the lisp part.
//"redisplayed" is the marker field
int redisplayed; //if touched by redisplay
/* Here ends the lisp part. "redisplayed" is the marker field. */
int hidden; //if the "live" instance isnt drawn
/* If touched by redisplay. */
bool redisplayed;
/* The "live" instance isn't drawn. */
bool hidden;
GtkWidget *widget;
GtkWidget *widgetwindow;
@ -85,48 +87,47 @@ struct xwidget_view
int clip_top;
int clip_left;
long handler_id;
};
#endif
/* Test for xwidget pseudovector*/
/* Test for xwidget pseudovector. */
#define XWIDGETP(x) PSEUDOVECTORP (x, PVEC_XWIDGET)
#define XXWIDGET(a) (eassert (XWIDGETP(a)), \
(struct xwidget *) XUNTAG(a, Lisp_Vectorlike))
#define XXWIDGET(a) (eassert (XWIDGETP (a)), \
(struct xwidget *) XUNTAG (a, Lisp_Vectorlike))
#define CHECK_XWIDGET(x) \
CHECK_TYPE (XWIDGETP (x), Qxwidgetp, x)
/* Test for xwidget_view pseudovector */
/* Test for xwidget_view pseudovector. */
#define XWIDGET_VIEW_P(x) PSEUDOVECTORP (x, PVEC_XWIDGET_VIEW)
#define XXWIDGET_VIEW(a) (eassert (XWIDGET_VIEW_P(a)), \
(struct xwidget_view *) XUNTAG(a, Lisp_Vectorlike))
#define XXWIDGET_VIEW(a) (eassert (XWIDGET_VIEW_P (a)), \
(struct xwidget_view *) XUNTAG (a, Lisp_Vectorlike))
#define CHECK_XWIDGET_VIEW(x) \
CHECK_TYPE (XWIDGET_VIEW_P (x), Qxwidget_view_p, x)
struct xwidget_type
{
/* A symbol uniquely identifying the xwidget type, */
Lisp_Object *type;
/* Check that SPEC is a valid image specification for the given
image type. Value is non-zero if SPEC is valid. */
int (*valid_p) (Lisp_Object spec);
/* Next in list of all supported image types. */
struct xwidget_type *next;
};
struct xwidget *xwidget_from_id (int id);
void xwidget_end_redisplay (struct window *w, struct glyph_matrix *matrix);
struct xwidget *lookup_xwidget (Lisp_Object spec);
#define XG_XWIDGET "emacs_xwidget"
#define XG_XWIDGET_VIEW "emacs_xwidget_view"
void xwidget_view_delete_all_in_window (struct window *w);
void kill_buffer_xwidgets (Lisp_Object buffer);
#ifdef HAVE_XWIDGETS
void syms_of_xwidget (void);
bool valid_xwidget_spec_p (Lisp_Object);
void xwidget_view_delete_all_in_window (struct window *);
void x_draw_xwidget_glyph_string (struct glyph_string *);
struct xwidget *lookup_xwidget (Lisp_Object spec);
void xwidget_end_redisplay (struct window *, struct glyph_matrix *);
void kill_buffer_xwidgets (Lisp_Object);
#else
INLINE_HEADER_BEGIN
INLINE void syms_of_xwidget (void) {}
INLINE bool valid_xwidget_spec_p (Lisp_Object obj) { return false; }
INLINE void xwidget_view_delete_all_in_window (struct window *w) {}
INLINE void x_draw_xwidget_glyph_string (struct glyph_string *s) { eassume (0); }
INLINE struct xwidget *lookup_xwidget (Lisp_Object obj) { eassume (0); }
INLINE void xwidget_end_redisplay (struct window *w, struct glyph_matrix *m) {}
INLINE void kill_buffer_xwidgets (Lisp_Object buf) {}
INLINE_HEADER_END
#endif
#endif /* XWIDGET_H_INCLUDED */