aboutsummaryrefslogtreecommitdiffstats
path: root/src/xdisp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xdisp.c')
-rw-r--r--src/xdisp.c248
1 files changed, 243 insertions, 5 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index d730a0bf1b6..89385c0e172 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -318,6 +318,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
318#include TERM_HEADER 318#include TERM_HEADER
319#endif /* HAVE_WINDOW_SYSTEM */ 319#endif /* HAVE_WINDOW_SYSTEM */
320 320
321#ifdef HAVE_XWIDGETS
322# include "xwidget.h"
323#endif
321#ifndef FRAME_X_OUTPUT 324#ifndef FRAME_X_OUTPUT
322#define FRAME_X_OUTPUT(f) ((f)->output_data.x) 325#define FRAME_X_OUTPUT(f) ((f)->output_data.x)
323#endif 326#endif
@@ -854,6 +857,9 @@ static bool next_element_from_buffer (struct it *);
854static bool next_element_from_composition (struct it *); 857static bool next_element_from_composition (struct it *);
855static bool next_element_from_image (struct it *); 858static bool next_element_from_image (struct it *);
856static bool next_element_from_stretch (struct it *); 859static bool next_element_from_stretch (struct it *);
860#ifdef HAVE_XWIDGETS
861static bool next_element_from_xwidget (struct it *);
862#endif
857static void load_overlay_strings (struct it *, ptrdiff_t); 863static void load_overlay_strings (struct it *, ptrdiff_t);
858static bool get_next_display_element (struct it *); 864static bool get_next_display_element (struct it *);
859static enum move_it_result 865static enum move_it_result
@@ -4690,6 +4696,9 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4690 if (CONSP (spec) 4696 if (CONSP (spec)
4691 /* Simple specifications. */ 4697 /* Simple specifications. */
4692 && !EQ (XCAR (spec), Qimage) 4698 && !EQ (XCAR (spec), Qimage)
4699#ifdef HAVE_XWIDGETS
4700 && !EQ (XCAR (spec), Qxwidget)
4701#endif
4693 && !EQ (XCAR (spec), Qspace) 4702 && !EQ (XCAR (spec), Qspace)
4694 && !EQ (XCAR (spec), Qwhen) 4703 && !EQ (XCAR (spec), Qwhen)
4695 && !EQ (XCAR (spec), Qslice) 4704 && !EQ (XCAR (spec), Qslice)
@@ -5137,7 +5146,12 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
5137 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p) 5146 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5138 && valid_image_p (value)) 5147 && valid_image_p (value))
5139#endif /* not HAVE_WINDOW_SYSTEM */ 5148#endif /* not HAVE_WINDOW_SYSTEM */
5140 || (CONSP (value) && EQ (XCAR (value), Qspace))); 5149 || (CONSP (value) && EQ (XCAR (value), Qspace))
5150#ifdef HAVE_XWIDGETS
5151 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5152 && valid_xwidget_spec_p (value))
5153#endif
5154 );
5141 5155
5142 if (valid_p && display_replaced == 0) 5156 if (valid_p && display_replaced == 0)
5143 { 5157 {
@@ -5212,6 +5226,17 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
5212 *position = it->position = start_pos; 5226 *position = it->position = start_pos;
5213 retval = 1 + (it->area == TEXT_AREA); 5227 retval = 1 + (it->area == TEXT_AREA);
5214 } 5228 }
5229#ifdef HAVE_XWIDGETS
5230 else if (valid_xwidget_spec_p(value))
5231 {
5232 it->what = IT_XWIDGET;
5233 it->method = GET_FROM_XWIDGET;
5234 it->position = start_pos;
5235 it->object = NILP (object) ? it->w->contents : object;
5236 *position = start_pos;
5237 it->xwidget = lookup_xwidget(value);
5238 }
5239#endif
5215#ifdef HAVE_WINDOW_SYSTEM 5240#ifdef HAVE_WINDOW_SYSTEM
5216 else 5241 else
5217 { 5242 {
@@ -5964,6 +5989,11 @@ push_it (struct it *it, struct text_pos *position)
5964 case GET_FROM_STRETCH: 5989 case GET_FROM_STRETCH:
5965 p->u.stretch.object = it->object; 5990 p->u.stretch.object = it->object;
5966 break; 5991 break;
5992#ifdef HAVE_XWIDGETS
5993 case GET_FROM_XWIDGET:
5994 p->u.xwidget.object = it->object;
5995 break;
5996#endif
5967 case GET_FROM_BUFFER: 5997 case GET_FROM_BUFFER:
5968 case GET_FROM_DISPLAY_VECTOR: 5998 case GET_FROM_DISPLAY_VECTOR:
5969 case GET_FROM_STRING: 5999 case GET_FROM_STRING:
@@ -6065,6 +6095,11 @@ pop_it (struct it *it)
6065 it->object = p->u.image.object; 6095 it->object = p->u.image.object;
6066 it->slice = p->u.image.slice; 6096 it->slice = p->u.image.slice;
6067 break; 6097 break;
6098#ifdef HAVE_XWIDGETS
6099 case GET_FROM_XWIDGET:
6100 it->object = p->u.xwidget.object;
6101 break;
6102#endif
6068 case GET_FROM_STRETCH: 6103 case GET_FROM_STRETCH:
6069 it->object = p->u.stretch.object; 6104 it->object = p->u.stretch.object;
6070 break; 6105 break;
@@ -6739,7 +6774,10 @@ static next_element_function const get_next_element[NUM_IT_METHODS] =
6739 next_element_from_string, 6774 next_element_from_string,
6740 next_element_from_c_string, 6775 next_element_from_c_string,
6741 next_element_from_image, 6776 next_element_from_image,
6742 next_element_from_stretch 6777 next_element_from_stretch,
6778#ifdef HAVE_XWIDGETS
6779 next_element_from_xwidget,
6780#endif
6743}; 6781};
6744 6782
6745#define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it) 6783#define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
@@ -7600,6 +7638,10 @@ set_iterator_to_next (struct it *it, bool reseat_p)
7600 7638
7601 case GET_FROM_IMAGE: 7639 case GET_FROM_IMAGE:
7602 case GET_FROM_STRETCH: 7640 case GET_FROM_STRETCH:
7641#ifdef HAVE_XWIDGETS
7642 case GET_FROM_XWIDGET:
7643#endif
7644
7603 /* The position etc with which we have to proceed are on 7645 /* The position etc with which we have to proceed are on
7604 the stack. The position may be at the end of a string, 7646 the stack. The position may be at the end of a string,
7605 if the `display' property takes up the whole string. */ 7647 if the `display' property takes up the whole string. */
@@ -8061,6 +8103,15 @@ next_element_from_image (struct it *it)
8061 return true; 8103 return true;
8062} 8104}
8063 8105
8106#ifdef HAVE_XWIDGETS
8107static bool
8108next_element_from_xwidget (struct it *it)
8109{
8110 it->what = IT_XWIDGET;
8111 return true;
8112}
8113#endif
8114
8064 8115
8065/* Fill iterator IT with next display element from a stretch glyph 8116/* Fill iterator IT with next display element from a stretch glyph
8066 property. IT->object is the value of the text property. Value is 8117 property. IT->object is the value of the text property. Value is
@@ -18793,6 +18844,28 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
18793 glyph->left_box_line_p, 18844 glyph->left_box_line_p,
18794 glyph->right_box_line_p); 18845 glyph->right_box_line_p);
18795 } 18846 }
18847#ifdef HAVE_XWIDGETS
18848 else if (glyph->type == XWIDGET_GLYPH)
18849 {
18850 fprintf (stderr,
18851 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
18852 glyph - row->glyphs[TEXT_AREA],
18853 'X',
18854 glyph->charpos,
18855 (BUFFERP (glyph->object)
18856 ? 'B'
18857 : (STRINGP (glyph->object)
18858 ? 'S'
18859 : '-')),
18860 glyph->pixel_width,
18861 glyph->u.xwidget,
18862 '.',
18863 glyph->face_id,
18864 glyph->left_box_line_p,
18865 glyph->right_box_line_p);
18866
18867 }
18868#endif
18796} 18869}
18797 18870
18798 18871
@@ -24291,6 +24364,13 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
24291 24364
24292 return OK_PIXELS (width_p ? img->width : img->height); 24365 return OK_PIXELS (width_p ? img->width : img->height);
24293 } 24366 }
24367# ifdef HAVE_XWIDGETS
24368 if (FRAME_WINDOW_P (it->f) && valid_xwidget_spec_p (prop))
24369 {
24370 // TODO: Don't return dummy size.
24371 return OK_PIXELS (100);
24372 }
24373# endif
24294#endif 24374#endif
24295 if (EQ (car, Qplus) || EQ (car, Qminus)) 24375 if (EQ (car, Qplus) || EQ (car, Qminus))
24296 { 24376 {
@@ -24796,6 +24876,18 @@ fill_image_glyph_string (struct glyph_string *s)
24796} 24876}
24797 24877
24798 24878
24879#ifdef HAVE_XWIDGETS
24880static void
24881fill_xwidget_glyph_string (struct glyph_string *s)
24882{
24883 eassert (s->first_glyph->type == XWIDGET_GLYPH);
24884 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
24885 s->font = s->face->font;
24886 s->width = s->first_glyph->pixel_width;
24887 s->ybase += s->first_glyph->voffset;
24888 s->xwidget = s->first_glyph->u.xwidget;
24889}
24890#endif
24799/* Fill glyph string S from a sequence of stretch glyphs. 24891/* Fill glyph string S from a sequence of stretch glyphs.
24800 24892
24801 START is the index of the first glyph to consider, 24893 START is the index of the first glyph to consider,
@@ -25181,6 +25273,20 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
25181 } \ 25273 } \
25182 while (false) 25274 while (false)
25183 25275
25276#ifdef HAVE_XWIDGETS
25277#define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
25278 do \
25279 { \
25280 s = alloca (sizeof *s); \
25281 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
25282 fill_xwidget_glyph_string (s); \
25283 append_glyph_string (&(HEAD), &(TAIL), s); \
25284 ++(START); \
25285 s->x = (X); \
25286 } \
25287 while (false)
25288#endif
25289
25184 25290
25185/* Add a glyph string for a sequence of character glyphs to the list 25291/* Add a glyph string for a sequence of character glyphs to the list
25186 of strings between HEAD and TAIL. START is the index of the first 25292 of strings between HEAD and TAIL. START is the index of the first
@@ -25302,7 +25408,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
25302 to allocate glyph strings (because draw_glyphs can be called 25408 to allocate glyph strings (because draw_glyphs can be called
25303 asynchronously). */ 25409 asynchronously). */
25304 25410
25305#define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \ 25411#define BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
25306 do \ 25412 do \
25307 { \ 25413 { \
25308 HEAD = TAIL = NULL; \ 25414 HEAD = TAIL = NULL; \
@@ -25333,8 +25439,17 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
25333 case IMAGE_GLYPH: \ 25439 case IMAGE_GLYPH: \
25334 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \ 25440 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
25335 HL, X, LAST_X); \ 25441 HL, X, LAST_X); \
25336 break; \ 25442 break;
25337 \ 25443
25444#ifdef HAVE_XWIDGETS
25445# define BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
25446 case XWIDGET_GLYPH: \
25447 BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL, \
25448 HL, X, LAST_X); \
25449 break;
25450#endif
25451
25452#define BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X) \
25338 case GLYPHLESS_GLYPH: \ 25453 case GLYPHLESS_GLYPH: \
25339 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \ 25454 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
25340 HL, X, LAST_X); \ 25455 HL, X, LAST_X); \
@@ -25353,6 +25468,18 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
25353 } while (false) 25468 } while (false)
25354 25469
25355 25470
25471#ifdef HAVE_XWIDGETS
25472# define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
25473 BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
25474 BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
25475 BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
25476#else
25477# define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
25478 BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
25479 BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
25480#endif
25481
25482
25356/* Draw glyphs between START and END in AREA of ROW on window W, 25483/* Draw glyphs between START and END in AREA of ROW on window W,
25357 starting at x-position X. X is relative to AREA in W. HL is a 25484 starting at x-position X. X is relative to AREA in W. HL is a
25358 face-override with the following meaning: 25485 face-override with the following meaning:
@@ -25991,6 +26118,109 @@ produce_image_glyph (struct it *it)
25991 } 26118 }
25992} 26119}
25993 26120
26121#ifdef HAVE_XWIDGETS
26122static void
26123produce_xwidget_glyph (struct it *it)
26124{
26125 struct xwidget *xw;
26126 int glyph_ascent, crop;
26127 eassert (it->what == IT_XWIDGET);
26128
26129 struct face *face = FACE_FROM_ID (it->f, it->face_id);
26130 eassert (face);
26131 /* Make sure X resources of the face is loaded. */
26132 prepare_face_for_display (it->f, face);
26133
26134 xw = it->xwidget;
26135 it->ascent = it->phys_ascent = glyph_ascent = xw->height/2;
26136 it->descent = xw->height/2;
26137 it->phys_descent = it->descent;
26138 it->pixel_width = xw->width;
26139 /* It's quite possible for images to have an ascent greater than
26140 their height, so don't get confused in that case. */
26141 if (it->descent < 0)
26142 it->descent = 0;
26143
26144 it->nglyphs = 1;
26145
26146 if (face->box != FACE_NO_BOX)
26147 {
26148 if (face->box_line_width > 0)
26149 {
26150 it->ascent += face->box_line_width;
26151 it->descent += face->box_line_width;
26152 }
26153
26154 if (it->start_of_box_run_p)
26155 it->pixel_width += eabs (face->box_line_width);
26156 it->pixel_width += eabs (face->box_line_width);
26157 }
26158
26159 take_vertical_position_into_account (it);
26160
26161 /* Automatically crop wide image glyphs at right edge so we can
26162 draw the cursor on same display row. */
26163 crop = it->pixel_width - (it->last_visible_x - it->current_x);
26164 if (crop > 0 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
26165 it->pixel_width -= crop;
26166
26167 if (it->glyph_row)
26168 {
26169 enum glyph_row_area area = it->area;
26170 struct glyph *glyph
26171 = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
26172
26173 if (it->glyph_row->reversed_p)
26174 {
26175 struct glyph *g;
26176
26177 /* Make room for the new glyph. */
26178 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
26179 g[1] = *g;
26180 glyph = it->glyph_row->glyphs[it->area];
26181 }
26182 if (glyph < it->glyph_row->glyphs[area + 1])
26183 {
26184 glyph->charpos = CHARPOS (it->position);
26185 glyph->object = it->object;
26186 glyph->pixel_width = it->pixel_width;
26187 glyph->ascent = glyph_ascent;
26188 glyph->descent = it->descent;
26189 glyph->voffset = it->voffset;
26190 glyph->type = XWIDGET_GLYPH;
26191 glyph->avoid_cursor_p = it->avoid_cursor_p;
26192 glyph->multibyte_p = it->multibyte_p;
26193 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26194 {
26195 /* In R2L rows, the left and the right box edges need to be
26196 drawn in reverse direction. */
26197 glyph->right_box_line_p = it->start_of_box_run_p;
26198 glyph->left_box_line_p = it->end_of_box_run_p;
26199 }
26200 else
26201 {
26202 glyph->left_box_line_p = it->start_of_box_run_p;
26203 glyph->right_box_line_p = it->end_of_box_run_p;
26204 }
26205 glyph->overlaps_vertically_p = 0;
26206 glyph->padding_p = 0;
26207 glyph->glyph_not_available_p = 0;
26208 glyph->face_id = it->face_id;
26209 glyph->u.xwidget = it->xwidget;
26210 glyph->font_type = FONT_TYPE_UNKNOWN;
26211 if (it->bidi_p)
26212 {
26213 glyph->resolved_level = it->bidi_it.resolved_level;
26214 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
26215 glyph->bidi_type = it->bidi_it.type;
26216 }
26217 ++it->glyph_row->used[area];
26218 }
26219 else
26220 IT_EXPAND_MATRIX_WIDTH (it, area);
26221 }
26222}
26223#endif
25994 26224
25995/* Append a stretch glyph to IT->glyph_row. OBJECT is the source 26225/* Append a stretch glyph to IT->glyph_row. OBJECT is the source
25996 of the glyph, WIDTH and HEIGHT are the width and height of the 26226 of the glyph, WIDTH and HEIGHT are the width and height of the
@@ -27401,6 +27631,10 @@ x_produce_glyphs (struct it *it)
27401 produce_image_glyph (it); 27631 produce_image_glyph (it);
27402 else if (it->what == IT_STRETCH) 27632 else if (it->what == IT_STRETCH)
27403 produce_stretch_glyph (it); 27633 produce_stretch_glyph (it);
27634#ifdef HAVE_XWIDGETS
27635 else if (it->what == IT_XWIDGET)
27636 produce_xwidget_glyph (it);
27637#endif
27404 27638
27405 done: 27639 done:
27406 /* Accumulate dimensions. Note: can't assume that it->descent > 0 27640 /* Accumulate dimensions. Note: can't assume that it->descent > 0
@@ -27770,6 +28004,10 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
27770 /* Use normal cursor if not blinked off. */ 28004 /* Use normal cursor if not blinked off. */
27771 if (!w->cursor_off_p) 28005 if (!w->cursor_off_p)
27772 { 28006 {
28007#ifdef HAVE_XWIDGETS
28008 if (glyph != NULL && glyph->type == XWIDGET_GLYPH)
28009 return NO_CURSOR;
28010#endif
27773 if (glyph != NULL && glyph->type == IMAGE_GLYPH) 28011 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
27774 { 28012 {
27775 if (cursor_type == FILLED_BOX_CURSOR) 28013 if (cursor_type == FILLED_BOX_CURSOR)