diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.in | 2 | ||||
| -rw-r--r-- | src/dispextern.h | 30 | ||||
| -rw-r--r-- | src/dispnew.c | 5 | ||||
| -rw-r--r-- | src/emacs.c | 3 | ||||
| -rw-r--r-- | src/frame.h | 4 | ||||
| -rw-r--r-- | src/gtkutil.c | 6 | ||||
| -rw-r--r-- | src/insdel.c | 3 | ||||
| -rw-r--r-- | src/keyboard.c | 15 | ||||
| -rw-r--r-- | src/termhooks.h | 2 | ||||
| -rw-r--r-- | src/window.c | 2 | ||||
| -rw-r--r-- | src/xdisp.c | 236 | ||||
| -rw-r--r-- | src/xfns.c | 7 | ||||
| -rw-r--r-- | src/xterm.c | 30 | ||||
| -rw-r--r-- | src/xwidget.c | 808 | ||||
| -rw-r--r-- | src/xwidget.h | 61 |
15 files changed, 1197 insertions, 17 deletions
diff --git a/src/Makefile.in b/src/Makefile.in index b2fec7eb085..578173747c9 100644 --- a/src/Makefile.in +++ b/src/Makefile.in | |||
| @@ -337,8 +337,10 @@ obj= dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \ | |||
| 337 | process.o callproc.o \ | 337 | process.o callproc.o \ |
| 338 | region-cache.o sound.o atimer.o \ | 338 | region-cache.o sound.o atimer.o \ |
| 339 | doprnt.o strftime.o intervals.o textprop.o composite.o md5.o \ | 339 | doprnt.o strftime.o intervals.o textprop.o composite.o md5.o \ |
| 340 | xwidget.o \ | ||
| 340 | $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) | 341 | $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) |
| 341 | 342 | ||
| 343 | xwidget.o: xwidget.c xwidget.h | ||
| 342 | ## Object files used on some machine or other. | 344 | ## Object files used on some machine or other. |
| 343 | ## These go in the DOC file on all machines in case they are needed. | 345 | ## These go in the DOC file on all machines in case they are needed. |
| 344 | SOME_MACHINE_OBJECTS = dosfns.o msdos.o \ | 346 | SOME_MACHINE_OBJECTS = dosfns.o msdos.o \ |
diff --git a/src/dispextern.h b/src/dispextern.h index f0d14c0e487..d1724adca01 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -24,7 +24,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 24 | #define DISPEXTERN_H_INCLUDED | 24 | #define DISPEXTERN_H_INCLUDED |
| 25 | 25 | ||
| 26 | #ifdef HAVE_X_WINDOWS | 26 | #ifdef HAVE_X_WINDOWS |
| 27 | |||
| 28 | #include <X11/Xlib.h> | 27 | #include <X11/Xlib.h> |
| 29 | #ifdef USE_X_TOOLKIT | 28 | #ifdef USE_X_TOOLKIT |
| 30 | #include <X11/Intrinsic.h> | 29 | #include <X11/Intrinsic.h> |
| @@ -113,7 +112,7 @@ enum window_part | |||
| 113 | 112 | ||
| 114 | /* If GLYPH_DEBUG is non-zero, additional checks are activated. Turn | 113 | /* If GLYPH_DEBUG is non-zero, additional checks are activated. Turn |
| 115 | it off by defining the macro GLYPH_DEBUG to zero. */ | 114 | it off by defining the macro GLYPH_DEBUG to zero. */ |
| 116 | 115 | #define GLYPH_DEBUG 1 | |
| 117 | #ifndef GLYPH_DEBUG | 116 | #ifndef GLYPH_DEBUG |
| 118 | #define GLYPH_DEBUG 0 | 117 | #define GLYPH_DEBUG 0 |
| 119 | #endif | 118 | #endif |
| @@ -281,7 +280,10 @@ enum glyph_type | |||
| 281 | IMAGE_GLYPH, | 280 | IMAGE_GLYPH, |
| 282 | 281 | ||
| 283 | /* Glyph is a space of fractional width and/or height. */ | 282 | /* Glyph is a space of fractional width and/or height. */ |
| 284 | STRETCH_GLYPH | 283 | STRETCH_GLYPH, |
| 284 | |||
| 285 | /* Glyph is an external widget drawn by the GUI toolkit. */ | ||
| 286 | XWIDGET_GLYPH | ||
| 285 | }; | 287 | }; |
| 286 | 288 | ||
| 287 | 289 | ||
| @@ -331,7 +333,7 @@ struct glyph | |||
| 331 | 333 | ||
| 332 | /* Which kind of glyph this is---character, image etc. Value | 334 | /* Which kind of glyph this is---character, image etc. Value |
| 333 | should be an enumerator of type enum glyph_type. */ | 335 | should be an enumerator of type enum glyph_type. */ |
| 334 | unsigned type : 2; | 336 | unsigned type : 3; |
| 335 | 337 | ||
| 336 | /* 1 means this glyph was produced from multibyte text. Zero | 338 | /* 1 means this glyph was produced from multibyte text. Zero |
| 337 | means it was produced from unibyte text, i.e. charsets aren't | 339 | means it was produced from unibyte text, i.e. charsets aren't |
| @@ -415,6 +417,8 @@ struct glyph | |||
| 415 | /* Image ID for image glyphs (type == IMAGE_GLYPH). */ | 417 | /* Image ID for image glyphs (type == IMAGE_GLYPH). */ |
| 416 | unsigned img_id; | 418 | unsigned img_id; |
| 417 | 419 | ||
| 420 | unsigned xwidget_id; | ||
| 421 | |||
| 418 | /* Sub-structure for type == STRETCH_GLYPH. */ | 422 | /* Sub-structure for type == STRETCH_GLYPH. */ |
| 419 | struct | 423 | struct |
| 420 | { | 424 | { |
| @@ -1262,6 +1266,8 @@ struct glyph_string | |||
| 1262 | /* Image, if any. */ | 1266 | /* Image, if any. */ |
| 1263 | struct image *img; | 1267 | struct image *img; |
| 1264 | 1268 | ||
| 1269 | int xwidget_id; | ||
| 1270 | |||
| 1265 | /* Slice */ | 1271 | /* Slice */ |
| 1266 | struct glyph_slice slice; | 1272 | struct glyph_slice slice; |
| 1267 | 1273 | ||
| @@ -1912,7 +1918,9 @@ enum display_element_type | |||
| 1912 | IT_TRUNCATION, | 1918 | IT_TRUNCATION, |
| 1913 | 1919 | ||
| 1914 | /* Continuation glyphs. See the comment for IT_TRUNCATION. */ | 1920 | /* Continuation glyphs. See the comment for IT_TRUNCATION. */ |
| 1915 | IT_CONTINUATION | 1921 | IT_CONTINUATION, |
| 1922 | |||
| 1923 | IT_XWIDGET | ||
| 1916 | }; | 1924 | }; |
| 1917 | 1925 | ||
| 1918 | 1926 | ||
| @@ -1961,6 +1969,7 @@ enum it_method { | |||
| 1961 | GET_FROM_C_STRING, | 1969 | GET_FROM_C_STRING, |
| 1962 | GET_FROM_IMAGE, | 1970 | GET_FROM_IMAGE, |
| 1963 | GET_FROM_STRETCH, | 1971 | GET_FROM_STRETCH, |
| 1972 | GET_FROM_XWIDGET, | ||
| 1964 | NUM_IT_METHODS | 1973 | NUM_IT_METHODS |
| 1965 | }; | 1974 | }; |
| 1966 | 1975 | ||
| @@ -2162,6 +2171,12 @@ struct it | |||
| 2162 | struct { | 2171 | struct { |
| 2163 | Lisp_Object object; | 2172 | Lisp_Object object; |
| 2164 | } stretch; | 2173 | } stretch; |
| 2174 | /* method == GET_FROM_XWIDGET */ | ||
| 2175 | struct { | ||
| 2176 | Lisp_Object object; | ||
| 2177 | int xwidget_lalala; | ||
| 2178 | } xwidget; | ||
| 2179 | |||
| 2165 | } u; | 2180 | } u; |
| 2166 | 2181 | ||
| 2167 | /* current text and display positions. */ | 2182 | /* current text and display positions. */ |
| @@ -2275,6 +2290,10 @@ struct it | |||
| 2275 | /* If what == IT_IMAGE, the id of the image to display. */ | 2290 | /* If what == IT_IMAGE, the id of the image to display. */ |
| 2276 | int image_id; | 2291 | int image_id; |
| 2277 | 2292 | ||
| 2293 | /* If what == IT_XWIDGET*/ | ||
| 2294 | int xwidget_id; | ||
| 2295 | |||
| 2296 | |||
| 2278 | /* Values from `slice' property. */ | 2297 | /* Values from `slice' property. */ |
| 2279 | struct it_slice slice; | 2298 | struct it_slice slice; |
| 2280 | 2299 | ||
| @@ -3334,3 +3353,4 @@ extern Lisp_Object x_default_parameter P_ ((struct frame *, Lisp_Object, | |||
| 3334 | 3353 | ||
| 3335 | /* arch-tag: c65c475f-1c1e-4534-8795-990b8509fd65 | 3354 | /* arch-tag: c65c475f-1c1e-4534-8795-990b8509fd65 |
| 3336 | (do not change this comment) */ | 3355 | (do not change this comment) */ |
| 3356 | |||
diff --git a/src/dispnew.c b/src/dispnew.c index a8ba1995435..e1c537e877c 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -3638,6 +3638,7 @@ update_single_window (w, force_p) | |||
| 3638 | { | 3638 | { |
| 3639 | if (w->must_be_updated_p) | 3639 | if (w->must_be_updated_p) |
| 3640 | { | 3640 | { |
| 3641 | printf("window %d must be updated\n"); | ||
| 3641 | struct frame *f = XFRAME (WINDOW_FRAME (w)); | 3642 | struct frame *f = XFRAME (WINDOW_FRAME (w)); |
| 3642 | 3643 | ||
| 3643 | /* Record that this is not a frame-based redisplay. */ | 3644 | /* Record that this is not a frame-based redisplay. */ |
| @@ -4000,6 +4001,10 @@ update_window (w, force_p) | |||
| 4000 | add_window_display_history (w, w->current_matrix->method, paused_p); | 4001 | add_window_display_history (w, w->current_matrix->method, paused_p); |
| 4001 | #endif | 4002 | #endif |
| 4002 | 4003 | ||
| 4004 | |||
| 4005 | if ((XWINDOW(FRAME_SELECTED_WINDOW (SELECTED_FRAME()))) == (w)) | ||
| 4006 | xwidget_end_redisplay(w->current_matrix); | ||
| 4007 | |||
| 4003 | clear_glyph_matrix (desired_matrix); | 4008 | clear_glyph_matrix (desired_matrix); |
| 4004 | 4009 | ||
| 4005 | return paused_p; | 4010 | return paused_p; |
diff --git a/src/emacs.c b/src/emacs.c index 7e778e2e5fd..33e982ef066 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -54,6 +54,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 54 | #include "buffer.h" | 54 | #include "buffer.h" |
| 55 | #include "window.h" | 55 | #include "window.h" |
| 56 | 56 | ||
| 57 | #include "xwidget.h" | ||
| 58 | |||
| 57 | #include "systty.h" | 59 | #include "systty.h" |
| 58 | #include "blockinput.h" | 60 | #include "blockinput.h" |
| 59 | #include "syssignal.h" | 61 | #include "syssignal.h" |
| @@ -1642,6 +1644,7 @@ main (int argc, char **argv) | |||
| 1642 | syms_of_xfns (); | 1644 | syms_of_xfns (); |
| 1643 | syms_of_xmenu (); | 1645 | syms_of_xmenu (); |
| 1644 | syms_of_fontset (); | 1646 | syms_of_fontset (); |
| 1647 | syms_of_xwidget(); | ||
| 1645 | syms_of_xsettings (); | 1648 | syms_of_xsettings (); |
| 1646 | #ifdef HAVE_X_SM | 1649 | #ifdef HAVE_X_SM |
| 1647 | syms_of_xsmfns (); | 1650 | syms_of_xsmfns (); |
diff --git a/src/frame.h b/src/frame.h index 887d47eff21..b0d338be5a6 100644 --- a/src/frame.h +++ b/src/frame.h | |||
| @@ -500,6 +500,10 @@ struct frame | |||
| 500 | /* All display backends seem to need these two pixel values. */ | 500 | /* All display backends seem to need these two pixel values. */ |
| 501 | unsigned long background_pixel; | 501 | unsigned long background_pixel; |
| 502 | unsigned long foreground_pixel; | 502 | unsigned long foreground_pixel; |
| 503 | |||
| 504 | /* xwidgets need the gtk container to place gtk widgets*/ | ||
| 505 | //GtkWidget *gwfixed; | ||
| 506 | void *gwfixed;//JAVE TODO i dont feel like fixing all compilation errors right now | ||
| 503 | }; | 507 | }; |
| 504 | 508 | ||
| 505 | #define FRAME_KBOARD(f) ((f)->terminal->kboard) | 509 | #define FRAME_KBOARD(f) ((f)->terminal->kboard) |
diff --git a/src/gtkutil.c b/src/gtkutil.c index c8800817b68..f77669c419d 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c | |||
| @@ -754,6 +754,10 @@ xg_pix_to_gcolor (w, pixel, c) | |||
| 754 | /* Create and set up the GTK widgets for frame F. | 754 | /* Create and set up the GTK widgets for frame F. |
| 755 | Return 0 if creation failed, non-zero otherwise. */ | 755 | Return 0 if creation failed, non-zero otherwise. */ |
| 756 | 756 | ||
| 757 | |||
| 758 | |||
| 759 | |||
| 760 | |||
| 757 | int | 761 | int |
| 758 | xg_create_frame_widgets (f) | 762 | xg_create_frame_widgets (f) |
| 759 | FRAME_PTR f; | 763 | FRAME_PTR f; |
| @@ -775,7 +779,7 @@ xg_create_frame_widgets (f) | |||
| 775 | xg_set_screen (wtop, f); | 779 | xg_set_screen (wtop, f); |
| 776 | 780 | ||
| 777 | wvbox = gtk_vbox_new (FALSE, 0); | 781 | wvbox = gtk_vbox_new (FALSE, 0); |
| 778 | wfixed = gtk_fixed_new (); /* Must have this to place scroll bars */ | 782 | f->gwfixed = wfixed = gtk_fixed_new (); /* Must have this to place scroll bars */ |
| 779 | 783 | ||
| 780 | if (! wtop || ! wvbox || ! wfixed) | 784 | if (! wtop || ! wvbox || ! wfixed) |
| 781 | { | 785 | { |
diff --git a/src/insdel.c b/src/insdel.c index 2b00de88711..a4363e8b1fe 100644 --- a/src/insdel.c +++ b/src/insdel.c | |||
| @@ -28,6 +28,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 28 | #include "window.h" | 28 | #include "window.h" |
| 29 | #include "blockinput.h" | 29 | #include "blockinput.h" |
| 30 | #include "region-cache.h" | 30 | #include "region-cache.h" |
| 31 | #include "xwidget.h" | ||
| 31 | 32 | ||
| 32 | #ifndef NULL | 33 | #ifndef NULL |
| 33 | #define NULL 0 | 34 | #define NULL 0 |
| @@ -2001,6 +2002,8 @@ void | |||
| 2001 | modify_region (struct buffer *buffer, EMACS_INT start, EMACS_INT end, | 2002 | modify_region (struct buffer *buffer, EMACS_INT start, EMACS_INT end, |
| 2002 | int preserve_chars_modiff) | 2003 | int preserve_chars_modiff) |
| 2003 | { | 2004 | { |
| 2005 | // printf("modify region\n"); | ||
| 2006 | xwidget_modify_region(); | ||
| 2004 | struct buffer *old_buffer = current_buffer; | 2007 | struct buffer *old_buffer = current_buffer; |
| 2005 | 2008 | ||
| 2006 | if (buffer != old_buffer) | 2009 | if (buffer != old_buffer) |
diff --git a/src/keyboard.c b/src/keyboard.c index 63372d600e3..ddb81ff0237 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -485,6 +485,7 @@ Lisp_Object Qsave_session; | |||
| 485 | #ifdef HAVE_DBUS | 485 | #ifdef HAVE_DBUS |
| 486 | Lisp_Object Qdbus_event; | 486 | Lisp_Object Qdbus_event; |
| 487 | #endif | 487 | #endif |
| 488 | Lisp_Object Qxwidget_event; | ||
| 488 | Lisp_Object Qconfig_changed_event; | 489 | Lisp_Object Qconfig_changed_event; |
| 489 | 490 | ||
| 490 | /* Lisp_Object Qmouse_movement; - also an event header */ | 491 | /* Lisp_Object Qmouse_movement; - also an event header */ |
| @@ -4161,7 +4162,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time) | |||
| 4161 | kbd_fetch_ptr = event + 1; | 4162 | kbd_fetch_ptr = event + 1; |
| 4162 | } | 4163 | } |
| 4163 | #endif | 4164 | #endif |
| 4164 | else if (event->kind == CONFIG_CHANGED_EVENT) | 4165 | else if (event->kind == CONFIG_CHANGED_EVENT || event->kind == XWIDGET_EVENT) |
| 4165 | { | 4166 | { |
| 4166 | obj = make_lispy_event (event); | 4167 | obj = make_lispy_event (event); |
| 4167 | kbd_fetch_ptr = event + 1; | 4168 | kbd_fetch_ptr = event + 1; |
| @@ -6060,6 +6061,8 @@ make_lispy_event (event) | |||
| 6060 | return apply_modifiers (event->modifiers, event->arg); | 6061 | return apply_modifiers (event->modifiers, event->arg); |
| 6061 | return event->arg; | 6062 | return event->arg; |
| 6062 | 6063 | ||
| 6064 | |||
| 6065 | |||
| 6063 | case USER_SIGNAL_EVENT: | 6066 | case USER_SIGNAL_EVENT: |
| 6064 | /* A user signal. */ | 6067 | /* A user signal. */ |
| 6065 | { | 6068 | { |
| @@ -6078,6 +6081,11 @@ make_lispy_event (event) | |||
| 6078 | return Fcons (Qdbus_event, event->arg); | 6081 | return Fcons (Qdbus_event, event->arg); |
| 6079 | } | 6082 | } |
| 6080 | #endif /* HAVE_DBUS */ | 6083 | #endif /* HAVE_DBUS */ |
| 6084 | case XWIDGET_EVENT: | ||
| 6085 | { | ||
| 6086 | printf("cool, an xwidget event arrived in make_lispy_event!\n"); | ||
| 6087 | return Fcons (Qxwidget_event,event->arg); | ||
| 6088 | } | ||
| 6081 | 6089 | ||
| 6082 | case CONFIG_CHANGED_EVENT: | 6090 | case CONFIG_CHANGED_EVENT: |
| 6083 | return Fcons (Qconfig_changed_event, | 6091 | return Fcons (Qconfig_changed_event, |
| @@ -11729,6 +11737,11 @@ syms_of_keyboard () | |||
| 11729 | staticpro (&Qdbus_event); | 11737 | staticpro (&Qdbus_event); |
| 11730 | #endif | 11738 | #endif |
| 11731 | 11739 | ||
| 11740 | Qxwidget_event = intern ("xwidget-event"); | ||
| 11741 | staticpro (&Qxwidget_event); | ||
| 11742 | |||
| 11743 | |||
| 11744 | Qmenu_enable = intern ("menu-enable"); | ||
| 11732 | Qconfig_changed_event = intern_c_string ("config-changed-event"); | 11745 | Qconfig_changed_event = intern_c_string ("config-changed-event"); |
| 11733 | staticpro (&Qconfig_changed_event); | 11746 | staticpro (&Qconfig_changed_event); |
| 11734 | 11747 | ||
diff --git a/src/termhooks.h b/src/termhooks.h index 2b4011627c8..311917df4d0 100644 --- a/src/termhooks.h +++ b/src/termhooks.h | |||
| @@ -208,6 +208,8 @@ enum event_kind | |||
| 208 | /* Non-key system events (e.g. application menu events) */ | 208 | /* Non-key system events (e.g. application menu events) */ |
| 209 | , NS_NONKEY_EVENT | 209 | , NS_NONKEY_EVENT |
| 210 | #endif | 210 | #endif |
| 211 | /* events generated by xwidgets*/ | ||
| 212 | , XWIDGET_EVENT | ||
| 211 | 213 | ||
| 212 | }; | 214 | }; |
| 213 | 215 | ||
diff --git a/src/window.c b/src/window.c index c105e37c462..193f7eecd0e 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -51,6 +51,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 51 | #include "nsterm.h" | 51 | #include "nsterm.h" |
| 52 | #endif | 52 | #endif |
| 53 | 53 | ||
| 54 | #include "xwidget.h" | ||
| 54 | 55 | ||
| 55 | Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p; | 56 | Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p; |
| 56 | Lisp_Object Qdisplay_buffer; | 57 | Lisp_Object Qdisplay_buffer; |
| @@ -3666,6 +3667,7 @@ selected window before each command. */) | |||
| 3666 | SET_PT (new_point); | 3667 | SET_PT (new_point); |
| 3667 | } | 3668 | } |
| 3668 | 3669 | ||
| 3670 | xwidget_invalidate(); | ||
| 3669 | windows_or_buffers_changed++; | 3671 | windows_or_buffers_changed++; |
| 3670 | return window; | 3672 | return window; |
| 3671 | } | 3673 | } |
diff --git a/src/xdisp.c b/src/xdisp.c index c8043308ec8..7e1869bc963 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -247,6 +247,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 247 | #include "fontset.h" | 247 | #include "fontset.h" |
| 248 | #include "blockinput.h" | 248 | #include "blockinput.h" |
| 249 | 249 | ||
| 250 | |||
| 250 | #ifdef HAVE_X_WINDOWS | 251 | #ifdef HAVE_X_WINDOWS |
| 251 | #include "xterm.h" | 252 | #include "xterm.h" |
| 252 | #endif | 253 | #endif |
| @@ -262,6 +263,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 262 | 263 | ||
| 263 | #include "font.h" | 264 | #include "font.h" |
| 264 | 265 | ||
| 266 | #include "xwidget.h" | ||
| 267 | |||
| 265 | #ifndef FRAME_X_OUTPUT | 268 | #ifndef FRAME_X_OUTPUT |
| 266 | #define FRAME_X_OUTPUT(f) ((f)->output_data.x) | 269 | #define FRAME_X_OUTPUT(f) ((f)->output_data.x) |
| 267 | #endif | 270 | #endif |
| @@ -1045,6 +1048,7 @@ static int next_element_from_c_string P_ ((struct it *)); | |||
| 1045 | static int next_element_from_buffer P_ ((struct it *)); | 1048 | static int next_element_from_buffer P_ ((struct it *)); |
| 1046 | static int next_element_from_composition P_ ((struct it *)); | 1049 | static int next_element_from_composition P_ ((struct it *)); |
| 1047 | static int next_element_from_image P_ ((struct it *)); | 1050 | static int next_element_from_image P_ ((struct it *)); |
| 1051 | static int next_element_from_xwidget P_ ((struct it *)); | ||
| 1048 | static int next_element_from_stretch P_ ((struct it *)); | 1052 | static int next_element_from_stretch P_ ((struct it *)); |
| 1049 | static void load_overlay_strings P_ ((struct it *, int)); | 1053 | static void load_overlay_strings P_ ((struct it *, int)); |
| 1050 | static int init_from_display_pos P_ ((struct it *, struct window *, | 1054 | static int init_from_display_pos P_ ((struct it *, struct window *, |
| @@ -4075,6 +4079,7 @@ handle_display_prop (it) | |||
| 4075 | if (CONSP (prop) | 4079 | if (CONSP (prop) |
| 4076 | /* Simple properties. */ | 4080 | /* Simple properties. */ |
| 4077 | && !EQ (XCAR (prop), Qimage) | 4081 | && !EQ (XCAR (prop), Qimage) |
| 4082 | && !EQ (XCAR (prop), Qxwidget) | ||
| 4078 | && !EQ (XCAR (prop), Qspace) | 4083 | && !EQ (XCAR (prop), Qspace) |
| 4079 | && !EQ (XCAR (prop), Qwhen) | 4084 | && !EQ (XCAR (prop), Qwhen) |
| 4080 | && !EQ (XCAR (prop), Qslice) | 4085 | && !EQ (XCAR (prop), Qslice) |
| @@ -4180,6 +4185,7 @@ handle_single_display_spec (it, spec, object, overlay, position, | |||
| 4180 | Lisp_Object location, value; | 4185 | Lisp_Object location, value; |
| 4181 | struct text_pos start_pos, save_pos; | 4186 | struct text_pos start_pos, save_pos; |
| 4182 | int valid_p; | 4187 | int valid_p; |
| 4188 | printf("handle_single_display_spec:\n"); | ||
| 4183 | 4189 | ||
| 4184 | /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM. | 4190 | /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM. |
| 4185 | If the result is non-nil, use VALUE instead of SPEC. */ | 4191 | If the result is non-nil, use VALUE instead of SPEC. */ |
| @@ -4464,11 +4470,22 @@ handle_single_display_spec (it, spec, object, overlay, position, | |||
| 4464 | LOCATION specifies where to display: `left-margin', | 4470 | LOCATION specifies where to display: `left-margin', |
| 4465 | `right-margin' or nil. */ | 4471 | `right-margin' or nil. */ |
| 4466 | 4472 | ||
| 4473 | |||
| 4474 | printf("handle_single_display_spec xwidgetp:%d imagep:%d spacep:%d display_replaced_before_p:%d stringp:%d\n", | ||
| 4475 | XWIDGETP(value), | ||
| 4476 | valid_image_p (value), | ||
| 4477 | (CONSP (value) && EQ (XCAR (value), Qspace)), | ||
| 4478 | display_replaced_before_p, | ||
| 4479 | STRINGP (value)); | ||
| 4480 | |||
| 4467 | valid_p = (STRINGP (value) | 4481 | valid_p = (STRINGP (value) |
| 4482 | |||
| 4468 | #ifdef HAVE_WINDOW_SYSTEM | 4483 | #ifdef HAVE_WINDOW_SYSTEM |
| 4469 | || (FRAME_WINDOW_P (it->f) && valid_image_p (value)) | 4484 | || (FRAME_WINDOW_P (it->f) && valid_image_p (value)) |
| 4470 | #endif /* not HAVE_WINDOW_SYSTEM */ | 4485 | #endif /* not HAVE_WINDOW_SYSTEM */ |
| 4471 | || (CONSP (value) && EQ (XCAR (value), Qspace))); | 4486 | || (CONSP (value) && EQ (XCAR (value), Qspace)) |
| 4487 | || XWIDGETP(value) | ||
| 4488 | ); | ||
| 4472 | 4489 | ||
| 4473 | if (valid_p && !display_replaced_before_p) | 4490 | if (valid_p && !display_replaced_before_p) |
| 4474 | { | 4491 | { |
| @@ -4509,8 +4526,20 @@ handle_single_display_spec (it, spec, object, overlay, position, | |||
| 4509 | it->object = value; | 4526 | it->object = value; |
| 4510 | *position = it->position = start_pos; | 4527 | *position = it->position = start_pos; |
| 4511 | } | 4528 | } |
| 4529 | else if (XWIDGETP(value)) | ||
| 4530 | { | ||
| 4531 | printf("handle_single_display_spec: im an xwidget!!\n"); | ||
| 4532 | it->what = IT_XWIDGET; | ||
| 4533 | it->method = GET_FROM_XWIDGET; | ||
| 4534 | it->position = start_pos; | ||
| 4535 | it->object = NILP (object) ? it->w->buffer : object; | ||
| 4536 | *position = start_pos; | ||
| 4537 | |||
| 4538 | it->xwidget_id=lookup_xwidget(value); | ||
| 4539 | assert_valid_xwidget_id(it->xwidget_id,"handle_single_display_spec"); | ||
| 4540 | } | ||
| 4512 | #ifdef HAVE_WINDOW_SYSTEM | 4541 | #ifdef HAVE_WINDOW_SYSTEM |
| 4513 | else | 4542 | else //if nothing else, its an image |
| 4514 | { | 4543 | { |
| 4515 | it->what = IT_IMAGE; | 4544 | it->what = IT_IMAGE; |
| 4516 | it->image_id = lookup_image (it->f, value); | 4545 | it->image_id = lookup_image (it->f, value); |
| @@ -4574,7 +4603,8 @@ single_display_spec_intangible_p (prop) | |||
| 4574 | 4603 | ||
| 4575 | return (CONSP (prop) | 4604 | return (CONSP (prop) |
| 4576 | && (EQ (XCAR (prop), Qimage) | 4605 | && (EQ (XCAR (prop), Qimage) |
| 4577 | || EQ (XCAR (prop), Qspace))); | 4606 | || EQ (XCAR (prop), Qspace) |
| 4607 | || XWIDGETP(prop))); | ||
| 4578 | } | 4608 | } |
| 4579 | 4609 | ||
| 4580 | 4610 | ||
| @@ -5246,6 +5276,10 @@ push_it (it) | |||
| 5246 | case GET_FROM_STRETCH: | 5276 | case GET_FROM_STRETCH: |
| 5247 | p->u.stretch.object = it->object; | 5277 | p->u.stretch.object = it->object; |
| 5248 | break; | 5278 | break; |
| 5279 | case GET_FROM_XWIDGET: | ||
| 5280 | p->u.xwidget.object = it->object; | ||
| 5281 | break; | ||
| 5282 | |||
| 5249 | } | 5283 | } |
| 5250 | p->position = it->position; | 5284 | p->position = it->position; |
| 5251 | p->current = it->current; | 5285 | p->current = it->current; |
| @@ -5325,6 +5359,9 @@ pop_it (it) | |||
| 5325 | it->object = p->u.image.object; | 5359 | it->object = p->u.image.object; |
| 5326 | it->slice = p->u.image.slice; | 5360 | it->slice = p->u.image.slice; |
| 5327 | break; | 5361 | break; |
| 5362 | case GET_FROM_XWIDGET: | ||
| 5363 | it->object = p->u.xwidget.object; | ||
| 5364 | break; | ||
| 5328 | case GET_FROM_STRETCH: | 5365 | case GET_FROM_STRETCH: |
| 5329 | it->object = p->u.comp.object; | 5366 | it->object = p->u.comp.object; |
| 5330 | break; | 5367 | break; |
| @@ -5846,7 +5883,8 @@ static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) = | |||
| 5846 | next_element_from_string, | 5883 | next_element_from_string, |
| 5847 | next_element_from_c_string, | 5884 | next_element_from_c_string, |
| 5848 | next_element_from_image, | 5885 | next_element_from_image, |
| 5849 | next_element_from_stretch | 5886 | next_element_from_stretch, |
| 5887 | next_element_from_xwidget | ||
| 5850 | }; | 5888 | }; |
| 5851 | 5889 | ||
| 5852 | #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it) | 5890 | #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it) |
| @@ -6504,6 +6542,7 @@ set_iterator_to_next (it, reseat_p) | |||
| 6504 | 6542 | ||
| 6505 | case GET_FROM_IMAGE: | 6543 | case GET_FROM_IMAGE: |
| 6506 | case GET_FROM_STRETCH: | 6544 | case GET_FROM_STRETCH: |
| 6545 | case GET_FROM_XWIDGET: | ||
| 6507 | /* The position etc with which we have to proceed are on | 6546 | /* The position etc with which we have to proceed are on |
| 6508 | the stack. The position may be at the end of a string, | 6547 | the stack. The position may be at the end of a string, |
| 6509 | if the `display' property takes up the whole string. */ | 6548 | if the `display' property takes up the whole string. */ |
| @@ -6766,6 +6805,19 @@ next_element_from_image (it) | |||
| 6766 | return 1; | 6805 | return 1; |
| 6767 | } | 6806 | } |
| 6768 | 6807 | ||
| 6808 | /* im not sure about this FIXME JAVE*/ | ||
| 6809 | static int | ||
| 6810 | next_element_from_xwidget (it) | ||
| 6811 | struct it *it; | ||
| 6812 | { | ||
| 6813 | it->what = IT_XWIDGET; | ||
| 6814 | assert_valid_xwidget_id(it->xwidget_id,"next_element_from_xwidget"); | ||
| 6815 | //this is shaky because why do we set "what" if we dont set the other parts?? | ||
| 6816 | printf("xwidget_id %d: in next_element_from_xwidget: FIXME \n", it->xwidget_id); | ||
| 6817 | return 1; | ||
| 6818 | } | ||
| 6819 | |||
| 6820 | |||
| 6769 | 6821 | ||
| 6770 | /* Fill iterator IT with next display element from a stretch glyph | 6822 | /* Fill iterator IT with next display element from a stretch glyph |
| 6771 | property. IT->object is the value of the text property. Value is | 6823 | property. IT->object is the value of the text property. Value is |
| @@ -11793,6 +11845,7 @@ static void | |||
| 11793 | redisplay_internal (preserve_echo_area) | 11845 | redisplay_internal (preserve_echo_area) |
| 11794 | int preserve_echo_area; | 11846 | int preserve_echo_area; |
| 11795 | { | 11847 | { |
| 11848 | |||
| 11796 | struct window *w = XWINDOW (selected_window); | 11849 | struct window *w = XWINDOW (selected_window); |
| 11797 | struct frame *f; | 11850 | struct frame *f; |
| 11798 | int pause; | 11851 | int pause; |
| @@ -11808,6 +11861,9 @@ redisplay_internal (preserve_echo_area) | |||
| 11808 | frames. Zero means, only selected_window is considered. */ | 11861 | frames. Zero means, only selected_window is considered. */ |
| 11809 | int consider_all_windows_p; | 11862 | int consider_all_windows_p; |
| 11810 | 11863 | ||
| 11864 | printf(">>>>redisplay\n"); | ||
| 11865 | // xwidget_start_redisplay(); | ||
| 11866 | |||
| 11811 | TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p)); | 11867 | TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p)); |
| 11812 | 11868 | ||
| 11813 | /* No redisplay if running in batch mode or frame is not yet fully | 11869 | /* No redisplay if running in batch mode or frame is not yet fully |
| @@ -12509,6 +12565,9 @@ redisplay_internal (preserve_echo_area) | |||
| 12509 | end_of_redisplay: | 12565 | end_of_redisplay: |
| 12510 | unbind_to (count, Qnil); | 12566 | unbind_to (count, Qnil); |
| 12511 | RESUME_POLLING; | 12567 | RESUME_POLLING; |
| 12568 | //xwidget_end_redisplay(); | ||
| 12569 | |||
| 12570 | printf("<<<<redisplay\n"); | ||
| 12512 | } | 12571 | } |
| 12513 | 12572 | ||
| 12514 | 12573 | ||
| @@ -16533,6 +16592,27 @@ dump_glyph (row, glyph, area) | |||
| 16533 | glyph->left_box_line_p, | 16592 | glyph->left_box_line_p, |
| 16534 | glyph->right_box_line_p); | 16593 | glyph->right_box_line_p); |
| 16535 | } | 16594 | } |
| 16595 | else if (glyph->type == XWIDGET_GLYPH) | ||
| 16596 | { | ||
| 16597 | fprintf (stderr, | ||
| 16598 | " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n", | ||
| 16599 | glyph - row->glyphs[TEXT_AREA], | ||
| 16600 | 'X', | ||
| 16601 | glyph->charpos, | ||
| 16602 | (BUFFERP (glyph->object) | ||
| 16603 | ? 'B' | ||
| 16604 | : (STRINGP (glyph->object) | ||
| 16605 | ? 'S' | ||
| 16606 | : '-')), | ||
| 16607 | glyph->pixel_width, | ||
| 16608 | glyph->u.xwidget_id, | ||
| 16609 | '.', | ||
| 16610 | glyph->face_id, | ||
| 16611 | glyph->left_box_line_p, | ||
| 16612 | glyph->right_box_line_p); | ||
| 16613 | |||
| 16614 | // printf("dump xwidget glyph\n"); | ||
| 16615 | } | ||
| 16536 | } | 16616 | } |
| 16537 | 16617 | ||
| 16538 | 16618 | ||
| @@ -20614,6 +20694,13 @@ calc_pixel_width_or_height (res, it, prop, font, width_p, align_to) | |||
| 20614 | 20694 | ||
| 20615 | return OK_PIXELS (width_p ? img->width : img->height); | 20695 | return OK_PIXELS (width_p ? img->width : img->height); |
| 20616 | } | 20696 | } |
| 20697 | |||
| 20698 | if (FRAME_WINDOW_P (it->f) | ||
| 20699 | && valid_xwidget_p (prop)) | ||
| 20700 | { | ||
| 20701 | printf("calc_pixel_width_or_height: return dummy size FIXME\n"); | ||
| 20702 | return OK_PIXELS (width_p ? 100 : 100); | ||
| 20703 | } | ||
| 20617 | #endif | 20704 | #endif |
| 20618 | if (EQ (car, Qplus) || EQ (car, Qminus)) | 20705 | if (EQ (car, Qplus) || EQ (car, Qminus)) |
| 20619 | { | 20706 | { |
| @@ -21070,6 +21157,20 @@ fill_image_glyph_string (s) | |||
| 21070 | s->ybase += s->first_glyph->voffset; | 21157 | s->ybase += s->first_glyph->voffset; |
| 21071 | } | 21158 | } |
| 21072 | 21159 | ||
| 21160 | static void | ||
| 21161 | fill_xwidget_glyph_string (s) | ||
| 21162 | struct glyph_string *s; | ||
| 21163 | { | ||
| 21164 | xassert (s->first_glyph->type == XWIDGET_GLYPH); | ||
| 21165 | printf("fill_xwidget_glyph_string: width:%d \n",s->first_glyph->pixel_width); | ||
| 21166 | s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id); | ||
| 21167 | s->font = s->face->font; | ||
| 21168 | s->width = s->first_glyph->pixel_width; | ||
| 21169 | s->ybase += s->first_glyph->voffset; | ||
| 21170 | s->xwidget_id=s->first_glyph->u.xwidget_id; | ||
| 21171 | assert_valid_xwidget_id(s->xwidget_id,"fill_xwidget_glyph_string"); | ||
| 21172 | } | ||
| 21173 | |||
| 21073 | 21174 | ||
| 21074 | /* Fill glyph string S from a sequence of stretch glyphs. | 21175 | /* Fill glyph string S from a sequence of stretch glyphs. |
| 21075 | 21176 | ||
| @@ -21423,6 +21524,20 @@ compute_overhangs_and_x (s, x, backward_p) | |||
| 21423 | } \ | 21524 | } \ |
| 21424 | while (0) | 21525 | while (0) |
| 21425 | 21526 | ||
| 21527 | #define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \ | ||
| 21528 | do \ | ||
| 21529 | { \ | ||
| 21530 | printf("BUILD_XWIDGET_GLYPH_STRING\n"); \ | ||
| 21531 | s = (struct glyph_string *) alloca (sizeof *s); \ | ||
| 21532 | INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \ | ||
| 21533 | fill_xwidget_glyph_string (s); \ | ||
| 21534 | append_glyph_string (&HEAD, &TAIL, s); \ | ||
| 21535 | ++START; \ | ||
| 21536 | s->x = (X); \ | ||
| 21537 | } \ | ||
| 21538 | while (0) | ||
| 21539 | |||
| 21540 | |||
| 21426 | 21541 | ||
| 21427 | /* Add a glyph string for a sequence of character glyphs to the list | 21542 | /* Add a glyph string for a sequence of character glyphs to the list |
| 21428 | of strings between HEAD and TAIL. START is the index of the first | 21543 | of strings between HEAD and TAIL. START is the index of the first |
| @@ -21551,11 +21666,14 @@ compute_overhangs_and_x (s, x, backward_p) | |||
| 21551 | BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \ | 21666 | BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \ |
| 21552 | HL, X, LAST_X); \ | 21667 | HL, X, LAST_X); \ |
| 21553 | break; \ | 21668 | break; \ |
| 21554 | \ | ||
| 21555 | case IMAGE_GLYPH: \ | 21669 | case IMAGE_GLYPH: \ |
| 21556 | BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \ | 21670 | BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \ |
| 21557 | HL, X, LAST_X); \ | 21671 | HL, X, LAST_X); \ |
| 21558 | break; \ | 21672 | break; \ |
| 21673 | case XWIDGET_GLYPH: \ | ||
| 21674 | BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL, \ | ||
| 21675 | HL, X, LAST_X); \ | ||
| 21676 | break; \ | ||
| 21559 | \ | 21677 | \ |
| 21560 | default: \ | 21678 | default: \ |
| 21561 | abort (); \ | 21679 | abort (); \ |
| @@ -22170,6 +22288,112 @@ produce_image_glyph (it) | |||
| 22170 | } | 22288 | } |
| 22171 | } | 22289 | } |
| 22172 | 22290 | ||
| 22291 | static void | ||
| 22292 | produce_xwidget_glyph (it) | ||
| 22293 | struct it *it; | ||
| 22294 | { | ||
| 22295 | // struct image *img; | ||
| 22296 | struct face *face; | ||
| 22297 | int glyph_ascent, crop; | ||
| 22298 | // struct glyph_slice slice; | ||
| 22299 | |||
| 22300 | printf("produce_xwidget_glyph:\n"); | ||
| 22301 | xassert (it->what == IT_XWIDGET); | ||
| 22302 | |||
| 22303 | face = FACE_FROM_ID (it->f, it->face_id); | ||
| 22304 | xassert (face); | ||
| 22305 | /* Make sure X resources of the face is loaded. */ | ||
| 22306 | PREPARE_FACE_FOR_DISPLAY (it->f, face); | ||
| 22307 | |||
| 22308 | ///////////////////////////////////////////// | ||
| 22309 | |||
| 22310 | // img = IMAGE_FROM_ID (it->f, it->image_id); | ||
| 22311 | //xassert (img); | ||
| 22312 | /* Make sure X resources of the image is loaded. */ | ||
| 22313 | //prepare_image_for_display (it->f, img); | ||
| 22314 | |||
| 22315 | struct xwidget* xw=xwidget_from_id(it->xwidget_id); | ||
| 22316 | //xwidget_touch(xw); | ||
| 22317 | |||
| 22318 | it->ascent = it->phys_ascent = glyph_ascent = xw->height/2;//image_ascent (img, face, &slice); | ||
| 22319 | it->descent = xw->height/2;//slice.height - glyph_ascent; | ||
| 22320 | |||
| 22321 | //it->descent += img->vmargin; | ||
| 22322 | //it->descent += img->vmargin; | ||
| 22323 | it->phys_descent = it->descent; | ||
| 22324 | |||
| 22325 | it->pixel_width = xw->width; | ||
| 22326 | |||
| 22327 | //it->pixel_width += img->hmargin; | ||
| 22328 | //it->pixel_width += img->hmargin; | ||
| 22329 | |||
| 22330 | ///////////////////////////////////////// | ||
| 22331 | |||
| 22332 | /* It's quite possible for images to have an ascent greater than | ||
| 22333 | their height, so don't get confused in that case. */ | ||
| 22334 | if (it->descent < 0) | ||
| 22335 | it->descent = 0; | ||
| 22336 | |||
| 22337 | it->nglyphs = 1; | ||
| 22338 | |||
| 22339 | if (face->box != FACE_NO_BOX) | ||
| 22340 | { | ||
| 22341 | if (face->box_line_width > 0) | ||
| 22342 | { | ||
| 22343 | it->ascent += face->box_line_width; | ||
| 22344 | it->descent += face->box_line_width; | ||
| 22345 | } | ||
| 22346 | |||
| 22347 | if (it->start_of_box_run_p) | ||
| 22348 | it->pixel_width += eabs (face->box_line_width); | ||
| 22349 | it->pixel_width += eabs (face->box_line_width); | ||
| 22350 | } | ||
| 22351 | |||
| 22352 | take_vertical_position_into_account (it); | ||
| 22353 | |||
| 22354 | /* Automatically crop wide image glyphs at right edge so we can | ||
| 22355 | draw the cursor on same display row. */ | ||
| 22356 | if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0) | ||
| 22357 | && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4)) | ||
| 22358 | { | ||
| 22359 | it->pixel_width -= crop; | ||
| 22360 | } | ||
| 22361 | |||
| 22362 | if (it->glyph_row) | ||
| 22363 | { | ||
| 22364 | struct glyph *glyph; | ||
| 22365 | enum glyph_row_area area = it->area; | ||
| 22366 | |||
| 22367 | glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | ||
| 22368 | if (glyph < it->glyph_row->glyphs[area + 1]) | ||
| 22369 | { | ||
| 22370 | glyph->charpos = CHARPOS (it->position); | ||
| 22371 | glyph->object = it->object; | ||
| 22372 | glyph->pixel_width = it->pixel_width; | ||
| 22373 | glyph->ascent = glyph_ascent; | ||
| 22374 | glyph->descent = it->descent; | ||
| 22375 | glyph->voffset = it->voffset; | ||
| 22376 | // glyph->type = IMAGE_GLYPH; | ||
| 22377 | glyph->type = XWIDGET_GLYPH; | ||
| 22378 | |||
| 22379 | glyph->multibyte_p = it->multibyte_p; | ||
| 22380 | glyph->left_box_line_p = it->start_of_box_run_p; | ||
| 22381 | glyph->right_box_line_p = it->end_of_box_run_p; | ||
| 22382 | glyph->overlaps_vertically_p = 0; | ||
| 22383 | glyph->padding_p = 0; | ||
| 22384 | glyph->glyph_not_available_p = 0; | ||
| 22385 | glyph->face_id = it->face_id; | ||
| 22386 | glyph->u.xwidget_id = it->xwidget_id; | ||
| 22387 | assert_valid_xwidget_id(glyph->u.xwidget_id,"produce_xwidget_glyph"); | ||
| 22388 | // glyph->slice = slice; | ||
| 22389 | glyph->font_type = FONT_TYPE_UNKNOWN; | ||
| 22390 | ++it->glyph_row->used[area]; | ||
| 22391 | } | ||
| 22392 | else | ||
| 22393 | IT_EXPAND_MATRIX_WIDTH (it, area); | ||
| 22394 | } | ||
| 22395 | } | ||
| 22396 | |||
| 22173 | 22397 | ||
| 22174 | /* Append a stretch glyph to IT->glyph_row. OBJECT is the source | 22398 | /* Append a stretch glyph to IT->glyph_row. OBJECT is the source |
| 22175 | of the glyph, WIDTH and HEIGHT are the width and height of the | 22399 | of the glyph, WIDTH and HEIGHT are the width and height of the |
| @@ -23237,6 +23461,8 @@ x_produce_glyphs (it) | |||
| 23237 | produce_image_glyph (it); | 23461 | produce_image_glyph (it); |
| 23238 | else if (it->what == IT_STRETCH) | 23462 | else if (it->what == IT_STRETCH) |
| 23239 | produce_stretch_glyph (it); | 23463 | produce_stretch_glyph (it); |
| 23464 | else if (it->what == IT_XWIDGET) | ||
| 23465 | produce_xwidget_glyph (it); | ||
| 23240 | 23466 | ||
| 23241 | /* Accumulate dimensions. Note: can't assume that it->descent > 0 | 23467 | /* Accumulate dimensions. Note: can't assume that it->descent > 0 |
| 23242 | because this isn't true for images with `:ascent 100'. */ | 23468 | because this isn't true for images with `:ascent 100'. */ |
diff --git a/src/xfns.c b/src/xfns.c index d19914e8dec..9072dabf355 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -3047,7 +3047,7 @@ unwind_create_frame (frame) | |||
| 3047 | #if GLYPH_DEBUG | 3047 | #if GLYPH_DEBUG |
| 3048 | /* Check that reference counts are indeed correct. */ | 3048 | /* Check that reference counts are indeed correct. */ |
| 3049 | xassert (dpyinfo->reference_count == dpyinfo_refcount); | 3049 | xassert (dpyinfo->reference_count == dpyinfo_refcount); |
| 3050 | xassert (dpyinfo->image_cache->refcount == image_cache_refcount); | 3050 | //xassert (dpyinfo->image_cache->refcount == image_cache_refcount); //FIXME doesnt compilex |
| 3051 | #endif | 3051 | #endif |
| 3052 | return Qt; | 3052 | return Qt; |
| 3053 | } | 3053 | } |
| @@ -3285,8 +3285,9 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 3285 | /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */ | 3285 | /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */ |
| 3286 | record_unwind_protect (unwind_create_frame, frame); | 3286 | record_unwind_protect (unwind_create_frame, frame); |
| 3287 | #if GLYPH_DEBUG | 3287 | #if GLYPH_DEBUG |
| 3288 | image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount; | 3288 | //JAVE TODO crashes |
| 3289 | dpyinfo_refcount = dpyinfo->reference_count; | 3289 | //image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount; |
| 3290 | //dpyinfo_refcount = dpyinfo->reference_count; | ||
| 3290 | #endif /* GLYPH_DEBUG */ | 3291 | #endif /* GLYPH_DEBUG */ |
| 3291 | 3292 | ||
| 3292 | /* These colors will be set anyway later, but it's important | 3293 | /* These colors will be set anyway later, but it's important |
diff --git a/src/xterm.c b/src/xterm.c index f195c4fbbd5..519ece2a2d3 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -69,6 +69,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 69 | #include "coding.h" | 69 | #include "coding.h" |
| 70 | #include "frame.h" | 70 | #include "frame.h" |
| 71 | #include "dispextern.h" | 71 | #include "dispextern.h" |
| 72 | #include "xwidget.h" | ||
| 72 | #include "fontset.h" | 73 | #include "fontset.h" |
| 73 | #include "termhooks.h" | 74 | #include "termhooks.h" |
| 74 | #include "termopts.h" | 75 | #include "termopts.h" |
| @@ -2419,7 +2420,7 @@ x_draw_image_foreground_1 (s, pixmap) | |||
| 2419 | /* Draw part of the background of glyph string S. X, Y, W, and H | 2420 | /* Draw part of the background of glyph string S. X, Y, W, and H |
| 2420 | give the rectangle to draw. */ | 2421 | give the rectangle to draw. */ |
| 2421 | 2422 | ||
| 2422 | static void | 2423 | void |
| 2423 | x_draw_glyph_string_bg_rect (s, x, y, w, h) | 2424 | x_draw_glyph_string_bg_rect (s, x, y, w, h) |
| 2424 | struct glyph_string *s; | 2425 | struct glyph_string *s; |
| 2425 | int x, y, w, h; | 2426 | int x, y, w, h; |
| @@ -2645,6 +2646,7 @@ x_draw_glyph_string (s) | |||
| 2645 | { | 2646 | { |
| 2646 | int relief_drawn_p = 0; | 2647 | int relief_drawn_p = 0; |
| 2647 | 2648 | ||
| 2649 | //printf("x_draw_glyph_string: %d\n",s->first_glyph->type); | ||
| 2648 | /* If S draws into the background of its successors, draw the | 2650 | /* If S draws into the background of its successors, draw the |
| 2649 | background of the successors first so that S can draw into it. | 2651 | background of the successors first so that S can draw into it. |
| 2650 | This makes S->next use XDrawString instead of XDrawImageString. */ | 2652 | This makes S->next use XDrawString instead of XDrawImageString. */ |
| @@ -2702,6 +2704,11 @@ x_draw_glyph_string (s) | |||
| 2702 | x_draw_image_glyph_string (s); | 2704 | x_draw_image_glyph_string (s); |
| 2703 | break; | 2705 | break; |
| 2704 | 2706 | ||
| 2707 | case XWIDGET_GLYPH: | ||
| 2708 | x_draw_glyph_string_background (s, 0); | ||
| 2709 | x_draw_xwidget_glyph_string (s); | ||
| 2710 | break; | ||
| 2711 | |||
| 2705 | case STRETCH_GLYPH: | 2712 | case STRETCH_GLYPH: |
| 2706 | x_draw_stretch_glyph_string (s); | 2713 | x_draw_stretch_glyph_string (s); |
| 2707 | break; | 2714 | break; |
| @@ -5889,6 +5896,21 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 5889 | EVENT_INIT (inev.ie); | 5896 | EVENT_INIT (inev.ie); |
| 5890 | inev.ie.kind = NO_EVENT; | 5897 | inev.ie.kind = NO_EVENT; |
| 5891 | inev.ie.arg = Qnil; | 5898 | inev.ie.arg = Qnil; |
| 5899 | |||
| 5900 | /*try to let events escape to xwidgets if xwidget_owns_kbd. not as easy as it sounds... */ | ||
| 5901 | if(xwidget_owns_kbd){ | ||
| 5902 | printf("xwidgets own events now!\n"); | ||
| 5903 | //according to xembed spec it seems like the toolkit is responsible for forwarding of events, so | ||
| 5904 | //try to let gtk have the event now | ||
| 5905 | *finish = 0; | ||
| 5906 | |||
| 5907 | /*FINISH is X_EVENT_GOTO_OUT if caller should stop reading events. | ||
| 5908 | *FINISH is zero if caller should continue reading events. | ||
| 5909 | *FINISH is X_EVENT_DROP if event should not be passed to the toolkit.*/ | ||
| 5910 | goto OTHER; | ||
| 5911 | } | ||
| 5912 | |||
| 5913 | |||
| 5892 | 5914 | ||
| 5893 | if (pending_event_wait.eventtype == event.type) | 5915 | if (pending_event_wait.eventtype == event.type) |
| 5894 | pending_event_wait.eventtype = 0; /* Indicates we got it. */ | 5916 | pending_event_wait.eventtype = 0; /* Indicates we got it. */ |
| @@ -6377,11 +6399,15 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6377 | Lisp_Object c; | 6399 | Lisp_Object c; |
| 6378 | 6400 | ||
| 6379 | #ifdef USE_GTK | 6401 | #ifdef USE_GTK |
| 6402 | |||
| 6380 | /* Don't pass keys to GTK. A Tab will shift focus to the | 6403 | /* Don't pass keys to GTK. A Tab will shift focus to the |
| 6381 | tool bar in GTK 2.4. Keys will still go to menus and | 6404 | tool bar in GTK 2.4. Keys will still go to menus and |
| 6382 | dialogs because in that case popup_activated is TRUE | 6405 | dialogs because in that case popup_activated is TRUE |
| 6383 | (see above). */ | 6406 | (see above). |
| 6407 | */ | ||
| 6384 | *finish = X_EVENT_DROP; | 6408 | *finish = X_EVENT_DROP; |
| 6409 | |||
| 6410 | |||
| 6385 | #endif | 6411 | #endif |
| 6386 | 6412 | ||
| 6387 | event.xkey.state | 6413 | event.xkey.state |
diff --git a/src/xwidget.c b/src/xwidget.c new file mode 100644 index 00000000000..6e6ae466b4d --- /dev/null +++ b/src/xwidget.c | |||
| @@ -0,0 +1,808 @@ | |||
| 1 | #include <config.h> | ||
| 2 | |||
| 3 | #include <signal.h> | ||
| 4 | |||
| 5 | #include <stdio.h> | ||
| 6 | |||
| 7 | #ifdef HAVE_X_WINDOWS | ||
| 8 | |||
| 9 | #include "lisp.h" | ||
| 10 | #include "blockinput.h" | ||
| 11 | #include "syssignal.h" | ||
| 12 | |||
| 13 | #include "xterm.h" | ||
| 14 | #include <X11/cursorfont.h> | ||
| 15 | |||
| 16 | #ifndef makedev | ||
| 17 | #include <sys/types.h> | ||
| 18 | #endif /* makedev */ | ||
| 19 | |||
| 20 | #ifdef BSD_SYSTEM | ||
| 21 | #include <sys/ioctl.h> | ||
| 22 | #endif /* ! defined (BSD_SYSTEM) */ | ||
| 23 | |||
| 24 | #include "systime.h" | ||
| 25 | |||
| 26 | #ifndef INCLUDED_FCNTL | ||
| 27 | #include <fcntl.h> | ||
| 28 | #endif | ||
| 29 | #include <ctype.h> | ||
| 30 | #include <errno.h> | ||
| 31 | #include <setjmp.h> | ||
| 32 | #include <sys/stat.h> | ||
| 33 | |||
| 34 | #include "charset.h" | ||
| 35 | #include "character.h" | ||
| 36 | #include "coding.h" | ||
| 37 | #include "ccl.h" | ||
| 38 | #include "frame.h" | ||
| 39 | #include "dispextern.h" | ||
| 40 | #include "fontset.h" | ||
| 41 | #include "termhooks.h" | ||
| 42 | #include "termopts.h" | ||
| 43 | #include "termchar.h" | ||
| 44 | #include "emacs-icon.h" | ||
| 45 | #include "disptab.h" | ||
| 46 | #include "buffer.h" | ||
| 47 | #include "window.h" | ||
| 48 | #include "keyboard.h" | ||
| 49 | #include "intervals.h" | ||
| 50 | #include "process.h" | ||
| 51 | #include "atimer.h" | ||
| 52 | #include "keymap.h" | ||
| 53 | |||
| 54 | |||
| 55 | #ifdef USE_X_TOOLKIT | ||
| 56 | #include <X11/Shell.h> | ||
| 57 | #endif | ||
| 58 | |||
| 59 | #ifdef HAVE_SYS_TIME_H | ||
| 60 | #include <sys/time.h> | ||
| 61 | #endif | ||
| 62 | #ifdef HAVE_UNISTD_H | ||
| 63 | #include <unistd.h> | ||
| 64 | #endif | ||
| 65 | |||
| 66 | #include "gtkutil.h" | ||
| 67 | #include "font.h" | ||
| 68 | #endif | ||
| 69 | |||
| 70 | #include <gtk/gtk.h> | ||
| 71 | #include <gdk/gdk.h> | ||
| 72 | |||
| 73 | #include "xwidget.h" | ||
| 74 | |||
| 75 | //just a fixed array of xwidgets for now | ||
| 76 | #define MAX_XWIDGETS 100 | ||
| 77 | struct xwidget xwidgets[MAX_XWIDGETS]; | ||
| 78 | |||
| 79 | static int once = 0; | ||
| 80 | |||
| 81 | |||
| 82 | Lisp_Object Qxwidget; | ||
| 83 | Lisp_Object Qxwidget_id; | ||
| 84 | Lisp_Object Qtitle; | ||
| 85 | Lisp_Object Qxwidget_set_keyboard_grab; | ||
| 86 | Lisp_Object Qxwidget_embed_steal_window; | ||
| 87 | Lisp_Object Qxwidget_resize_internal; | ||
| 88 | Lisp_Object Qxwidget_send_keyboard_event; | ||
| 89 | |||
| 90 | extern Lisp_Object QCdata, QCtype; | ||
| 91 | extern Lisp_Object QCwidth, QCheight; | ||
| 92 | |||
| 93 | |||
| 94 | |||
| 95 | |||
| 96 | |||
| 97 | |||
| 98 | static void | ||
| 99 | buttonclick_handler (GtkWidget * widget, gpointer data) | ||
| 100 | { | ||
| 101 | struct xwidget *xw = (struct xwidget *) data; | ||
| 102 | Lisp_Object frame; | ||
| 103 | printf ("button clicked xw:%d id:%d\n", xw, xw->id); | ||
| 104 | |||
| 105 | struct input_event event; | ||
| 106 | EVENT_INIT (event); | ||
| 107 | event.kind = XWIDGET_EVENT; | ||
| 108 | |||
| 109 | FRAME_PTR f = | ||
| 110 | (FRAME_PTR) g_object_get_data (G_OBJECT (xw->widget), XG_FRAME_DATA); | ||
| 111 | XSETFRAME (frame, f); | ||
| 112 | |||
| 113 | event.frame_or_window = Qnil; //frame; //how to get the frame here? | ||
| 114 | |||
| 115 | |||
| 116 | event.arg = Qnil; | ||
| 117 | event.arg = Fcons (make_number (xw->id), event.arg); | ||
| 118 | event.arg = Fcons (intern ("buttonclick"), event.arg); | ||
| 119 | |||
| 120 | kbd_buffer_store_event (&event); | ||
| 121 | |||
| 122 | |||
| 123 | } | ||
| 124 | |||
| 125 | |||
| 126 | static void | ||
| 127 | send_xembed_ready_event (int xwid, int xembedid) | ||
| 128 | { | ||
| 129 | struct input_event event; | ||
| 130 | EVENT_INIT (event); | ||
| 131 | event.kind = XWIDGET_EVENT; | ||
| 132 | event.frame_or_window = Qnil; //frame; //how to get the frame here? //TODO i store it in the xwidget now | ||
| 133 | |||
| 134 | event.arg = Qnil; | ||
| 135 | event.arg = Fcons (make_number (xembedid), event.arg); | ||
| 136 | event.arg = Fcons (intern ("xembed-ready"), event.arg); | ||
| 137 | event.arg = Fcons (make_number (xwid), event.arg); | ||
| 138 | |||
| 139 | |||
| 140 | kbd_buffer_store_event (&event); | ||
| 141 | |||
| 142 | } | ||
| 143 | |||
| 144 | |||
| 145 | void | ||
| 146 | xwidget_init (struct xwidget *xw, struct glyph_string *s, int x, int y) | ||
| 147 | { | ||
| 148 | xw->initialized = 1; | ||
| 149 | xw->id = s->xwidget_id; | ||
| 150 | xw->hidden = 0; | ||
| 151 | |||
| 152 | //widget creation | ||
| 153 | switch (xw->type) | ||
| 154 | { | ||
| 155 | case 1: | ||
| 156 | xw->widget = gtk_button_new_with_label (xw->title); | ||
| 157 | g_signal_connect (G_OBJECT (xw->widget), "clicked", | ||
| 158 | G_CALLBACK (buttonclick_handler), xw); | ||
| 159 | break; | ||
| 160 | case 2: | ||
| 161 | xw->widget = gtk_toggle_button_new_with_label (xw->title); | ||
| 162 | break; | ||
| 163 | case 3: | ||
| 164 | xw->widget = gtk_socket_new (); | ||
| 165 | break; | ||
| 166 | case 4: | ||
| 167 | xw->widget = | ||
| 168 | gtk_hscale_new (GTK_ADJUSTMENT | ||
| 169 | (gtk_adjustment_new (0, 0, 100, 1, 1, 0))); | ||
| 170 | gtk_scale_set_draw_value (GTK_SCALE (xw->widget), FALSE); //i think its emacs role to show text and stuff, so disable the widgets own text | ||
| 171 | } | ||
| 172 | //widget realization | ||
| 173 | // mk container widget 1st, and put the widget inside | ||
| 174 | //later, drawing should crop container window if necessary to handle case where xwidget | ||
| 175 | //is partially obscured by other emacs windows | ||
| 176 | xw->emacswindow = GTK_CONTAINER (s->f->gwfixed); | ||
| 177 | xw->widgetwindow = GTK_CONTAINER (gtk_layout_new (NULL, NULL)); | ||
| 178 | gtk_layout_set_size (GTK_LAYOUT (xw->widgetwindow), xw->width, xw->height); | ||
| 179 | gtk_container_add (xw->widgetwindow, xw->widget); | ||
| 180 | gtk_widget_set_size_request (GTK_WIDGET (xw->widget), xw->width, | ||
| 181 | xw->height); | ||
| 182 | gtk_fixed_put (GTK_FIXED (s->f->gwfixed), GTK_WIDGET (xw->widgetwindow), x, | ||
| 183 | y); | ||
| 184 | gtk_widget_show_all (GTK_WIDGET (xw->widgetwindow)); | ||
| 185 | |||
| 186 | //a bit inconsistent, but the rest of emacs stores stuff in the widgets, | ||
| 187 | //like frame data. in my case it might as well reside in the xwidget struct i think | ||
| 188 | g_object_set_data (G_OBJECT (xw->widget), XG_FRAME_DATA, (gpointer) (s->f)); | ||
| 189 | |||
| 190 | //widgettype specific initialization only possible after realization | ||
| 191 | switch (xw->type) | ||
| 192 | { | ||
| 193 | case 3: | ||
| 194 | printf ("socket id:%x %d\n", | ||
| 195 | gtk_socket_get_id (GTK_SOCKET (xw->widget)), | ||
| 196 | gtk_socket_get_id (GTK_SOCKET (xw->widget))); | ||
| 197 | send_xembed_ready_event (xw->id, | ||
| 198 | gtk_socket_get_id (GTK_SOCKET (xw->widget))); | ||
| 199 | break; | ||
| 200 | } | ||
| 201 | } | ||
| 202 | |||
| 203 | void | ||
| 204 | xwidget_draw_phantom (struct xwidget *xw, int x, int y, int clipx, int clipy, | ||
| 205 | struct glyph_string *s) | ||
| 206 | { | ||
| 207 | //we cant always get real widgets, so here we try to fetch a snapshot of | ||
| 208 | //the real xwidget and paint that as a phantom image. if that fails, we | ||
| 209 | //get an even simpler phantom(grey rectangle currently) | ||
| 210 | |||
| 211 | //this annoyingly doesnt work for gtk_sockets(but gtk_plug then? TODO research (probably doesnt work)) | ||
| 212 | //another way is composition: http://ktown.kde.org/~fredrik/composite_howto.html | ||
| 213 | //but XCopyArea() might be sufficient for our needs here | ||
| 214 | |||
| 215 | |||
| 216 | GdkPixmap *xw_snapshot = gtk_widget_get_snapshot (xw->widget, NULL); | ||
| 217 | GdkGC *gdkgc = gdk_gc_new (xw_snapshot); | ||
| 218 | |||
| 219 | //currently a phanotm gets a line drawn across it to denote phantomness | ||
| 220 | //dimming or such would be more elegant | ||
| 221 | gdk_draw_line (xw_snapshot, gdkgc, 0, 0, xw->width, xw->height); | ||
| 222 | gdk_draw_drawable (gtk_widget_get_window (s->f->gwfixed), //convert to GdkWindow from gtkWindow | ||
| 223 | gdkgc, xw_snapshot, 0, 0, x, y, clipx, clipy); | ||
| 224 | } | ||
| 225 | |||
| 226 | |||
| 227 | |||
| 228 | void | ||
| 229 | x_draw_xwidget_glyph_string (s) | ||
| 230 | struct glyph_string *s; | ||
| 231 | { | ||
| 232 | int box_line_hwidth = eabs (s->face->box_line_width); | ||
| 233 | int box_line_vwidth = max (s->face->box_line_width, 0); | ||
| 234 | int height = s->height; | ||
| 235 | Pixmap pixmap = None; | ||
| 236 | |||
| 237 | int drawing_in_selected_window = (XWINDOW (FRAME_SELECTED_WINDOW (s->f))) == (s->w); | ||
| 238 | |||
| 239 | // printf("x_draw_xwidget_glyph_string: id:%d %d %d (%d,%d,%d,%d) selected win:%d\n", | ||
| 240 | // s->xwidget_id, box_line_hwidth, box_line_vwidth, s->x,s->y,s->height,s->width, drawing_in_selected_window); | ||
| 241 | struct xwidget *xw = &xwidgets[s->xwidget_id]; | ||
| 242 | |||
| 243 | int x = s->x; | ||
| 244 | int y = s->y + (s->height / 2) - (xw->height / 2); | ||
| 245 | int doingsocket = 0; | ||
| 246 | if (!xw->initialized) | ||
| 247 | { | ||
| 248 | xwidget_init (xw, s, x, y); | ||
| 249 | } | ||
| 250 | |||
| 251 | //calculate clip widht and height, which is used both for the xwidget | ||
| 252 | //and its phantom counterpart | ||
| 253 | int clipx = min (xw->width, WINDOW_RIGHT_EDGE_X (s->w) - x); | ||
| 254 | int clipy = | ||
| 255 | min (xw->height, | ||
| 256 | WINDOW_BOTTOM_EDGE_Y (s->w) - WINDOW_MODE_LINE_HEIGHT (s->w) - y); | ||
| 257 | |||
| 258 | |||
| 259 | //TODO: | ||
| 260 | // 1) always draw live xwidget in slected window | ||
| 261 | // 2) if there were no live instances of the xwidget in selected window, also draw it live | ||
| 262 | // 3) if there was a live xwidget previously, now phantom it. | ||
| 263 | if (drawing_in_selected_window) | ||
| 264 | { | ||
| 265 | if ((xw->x != x) || (xw->y != y)) //has it moved? | ||
| 266 | { | ||
| 267 | printf ("xwidget moved: id:%d (%d,%d)->(%d,%d)\n", xw->id, xw->x, xw->y, x, y); | ||
| 268 | } | ||
| 269 | else | ||
| 270 | { | ||
| 271 | } | ||
| 272 | if (xw->hidden == 0) //hidden equals not being seen in the live window | ||
| 273 | { | ||
| 274 | gtk_fixed_move (GTK_FIXED (s->f->gwfixed), | ||
| 275 | GTK_WIDGET (xw->widgetwindow), x, y); | ||
| 276 | //adjust size of the widget window if some parts happen to be outside drawable area | ||
| 277 | //that is, we should clip | ||
| 278 | //an emacs window is not a gtk window, a gtk window covers the entire frame | ||
| 279 | gtk_widget_set_size_request (GTK_WIDGET (xw->widgetwindow), clipx, | ||
| 280 | clipy); | ||
| 281 | } | ||
| 282 | else | ||
| 283 | { | ||
| 284 | //xwidget is hidden, hide it offscreen somewhere, still realized, so we may snapshot it | ||
| 285 | //gtk_fixed_move(GTK_FIXED(s->f->gwfixed),GTK_WIDGET(xw->widgetwindow) ,10000,10000); | ||
| 286 | } | ||
| 287 | //xw is (aparently) supposed to refer to the *live* instance of the xwidget | ||
| 288 | xw->x = x; | ||
| 289 | xw->y = y; | ||
| 290 | |||
| 291 | |||
| 292 | } | ||
| 293 | else | ||
| 294 | { | ||
| 295 | //ok, we are painting the xwidgets in non-selected window | ||
| 296 | |||
| 297 | //so draw a phantom | ||
| 298 | xwidget_draw_phantom (xw, x, y, clipx, clipy, s); | ||
| 299 | |||
| 300 | } | ||
| 301 | |||
| 302 | } | ||
| 303 | |||
| 304 | |||
| 305 | |||
| 306 | |||
| 307 | DEFUN ("xwidget-embed-steal-window", Fxwidget_embed_steal_window, Sxwidget_embed_steal_window, 2, 2, 0, doc: /* tell existing embed xwidget to steal other window id. */ | ||
| 308 | ) | ||
| 309 | (xwidget_id, window_id) | ||
| 310 | Lisp_Object xwidget_id, window_id; | ||
| 311 | { | ||
| 312 | struct xwidget *xw; | ||
| 313 | int xid = XFASTINT (xwidget_id); | ||
| 314 | xw = &xwidgets[xid]; | ||
| 315 | int iwindow_id = XFASTINT (window_id); | ||
| 316 | printf (" gtk_socket_add_id: %d %d\n", xid, iwindow_id); | ||
| 317 | // gtk_socket_steal(GTK_SOCKET(xw->widget),iwindow_id); | ||
| 318 | //try adding proper gtk plugs instead, i never once had "steal" work | ||
| 319 | gtk_socket_add_id (GTK_SOCKET (xw->widget), iwindow_id); | ||
| 320 | //add_id annoyingly odesnt work either. the only working option | ||
| 321 | //seems to be clients that plug into the sockets, and so far only emacs and mplayer | ||
| 322 | //oenvrml | ||
| 323 | return Qnil; | ||
| 324 | } | ||
| 325 | |||
| 326 | |||
| 327 | DEFUN ("xwidget-resize-internal", Fxwidget_resize_internal, Sxwidget_resize_internal, 3, 3, 0, doc: | ||
| 328 | /* tell existing embed xwidget to steal other window id. */ | ||
| 329 | ) | ||
| 330 | (xwidget_id, new_width, new_height) | ||
| 331 | Lisp_Object xwidget_id, new_width, new_height; | ||
| 332 | { | ||
| 333 | struct xwidget *xw; | ||
| 334 | int xid = XFASTINT (xwidget_id); | ||
| 335 | xw = &xwidgets[xid]; | ||
| 336 | int w = XFASTINT (new_width); | ||
| 337 | int h = XFASTINT (new_height); | ||
| 338 | printf("resize xwidget %d (%d,%d)->(%d,%d)",xid,xw->width,xw->height,w,h); | ||
| 339 | xw->width=w; | ||
| 340 | xw->height=h; | ||
| 341 | gtk_layout_set_size (GTK_LAYOUT (xw->widgetwindow), xw->width, xw->height); | ||
| 342 | gtk_widget_set_size_request (GTK_WIDGET (xw->widget), xw->width, | ||
| 343 | xw->height); | ||
| 344 | return Qnil; | ||
| 345 | } | ||
| 346 | |||
| 347 | |||
| 348 | |||
| 349 | //xterm.c listens to xwidget_owns_kbd and tries to not eat events when its set | ||
| 350 | int xwidget_owns_kbd = 0; | ||
| 351 | DEFUN ("xwidget-set-keyboard-grab", Fxwidget_set_keyboard_grab, Sxwidget_set_keyboard_grab, 2, 2, 0, doc: /* set unset kbd grab for xwidget. */ | ||
| 352 | ) | ||
| 353 | (xwidget_id, kbd_grab) | ||
| 354 | Lisp_Object xwidget_id, kbd_grab; | ||
| 355 | { | ||
| 356 | struct xwidget *xw; | ||
| 357 | int xid = XFASTINT (xwidget_id); | ||
| 358 | xw = &xwidgets[xid]; | ||
| 359 | int kbd_flag = XFASTINT (kbd_grab); | ||
| 360 | printf ("kbd grab: %d %d\n", xid, kbd_flag); | ||
| 361 | if (kbd_flag) | ||
| 362 | { | ||
| 363 | //int rv=gtk_widget_activate(xw->widget); //ok, but how deactivate? | ||
| 364 | //printf("activation:%d\n",rv); | ||
| 365 | // gtk_window_present(GTK_WINDOW(xw->widget)); | ||
| 366 | //gtk_widget_grab_focus(xw->widget); | ||
| 367 | // gtk_socket_windowing_update_active (xw->widget,1); | ||
| 368 | // GDK_WINDOW_XWINDOW (GTK_WIDGET (socket)->window) | ||
| 369 | //FRAME_X_OUTPUT (f)->widget | ||
| 370 | // gdk_keyboard_grab(xw->widget,TRUE,GDK_CURRENT_TIME); | ||
| 371 | |||
| 372 | /* GtkWidget *parent = gtk_widget_get_parent (xw->widget); */ | ||
| 373 | /* GtkWidget *lastparent; */ | ||
| 374 | /* for (lastparent = parent; parent = gtk_widget_get_parent (parent); */ | ||
| 375 | /* parent == NULL); */ | ||
| 376 | |||
| 377 | /* gtk_container_set_focus_child (GTK_CONTAINER (lastparent), xw->widget); */ | ||
| 378 | |||
| 379 | gtk_container_set_focus_child (GTK_CONTAINER (xw->widgetwindow), xw->widget); | ||
| 380 | |||
| 381 | xwidget_owns_kbd = TRUE; | ||
| 382 | } | ||
| 383 | else | ||
| 384 | { | ||
| 385 | xwidget_owns_kbd = FALSE; | ||
| 386 | } | ||
| 387 | /* | ||
| 388 | gdk_keyboard_grab(xw->widget,TRUE,GDK_CURRENT_TIME); | ||
| 389 | else | ||
| 390 | gdk_keyboard_ungrab(GDK_CURRENT_TIME); | ||
| 391 | */ | ||
| 392 | return Qnil; | ||
| 393 | } | ||
| 394 | |||
| 395 | |||
| 396 | //lowlevel fn mostly cloned from xembed_send_message() | ||
| 397 | void | ||
| 398 | xwidget_key_send_message (f, destination_window, keycode, keypress, modifiers) | ||
| 399 | struct frame *f; | ||
| 400 | Window destination_window; | ||
| 401 | int keypress; | ||
| 402 | { | ||
| 403 | |||
| 404 | XKeyEvent event; | ||
| 405 | //segfaults: | ||
| 406 | /* xwidget_key_send_message (f=0x0, destination_window=0, keycode=65, keypress=1, */ | ||
| 407 | /* modifiers=0) at xwidget.c:332 */ | ||
| 408 | /* 332 event.display = FRAME_X_DISPLAY (f); */ | ||
| 409 | |||
| 410 | event.display = FRAME_X_DISPLAY (f); | ||
| 411 | event.window = destination_window; | ||
| 412 | event.root = FRAME_ROOT_WINDOW (f); | ||
| 413 | event.subwindow = None; | ||
| 414 | event.time = CurrentTime; | ||
| 415 | event.x = 1; | ||
| 416 | event.y = 1; | ||
| 417 | event.x_root = 1; | ||
| 418 | event.y_root = 1; | ||
| 419 | event.same_screen = TRUE; | ||
| 420 | |||
| 421 | event.type = keypress ? KeyPress : KeyRelease; | ||
| 422 | event.keycode = keycode; | ||
| 423 | event.state = modifiers; | ||
| 424 | |||
| 425 | XSendEvent (event.display, event.window, TRUE, KeyPressMask, | ||
| 426 | (XEvent *) & event); | ||
| 427 | } | ||
| 428 | |||
| 429 | //using "accessible" interfaces seems expensive | ||
| 430 | //pkg-config --cflags cspi-1.0 | ||
| 431 | //#include <at-spi-1.0/cspi/spi.h> | ||
| 432 | |||
| 433 | DEFUN ("xwidget-send-keyboard-event", Fxwidget_send_keyboard_event, Sxwidget_send_keyboard_event, 2, 2, 0, doc:/* synthesize a kbd event for a xwidget. */ | ||
| 434 | ) | ||
| 435 | (xwidget_id, keydescriptor) | ||
| 436 | Lisp_Object xwidget_id, keydescriptor; | ||
| 437 | { | ||
| 438 | int keyval; | ||
| 439 | char *keystring = ""; | ||
| 440 | |||
| 441 | struct xwidget *xw; | ||
| 442 | int xwid = XFASTINT (xwidget_id); | ||
| 443 | xw = &xwidgets[xwid]; | ||
| 444 | |||
| 445 | FRAME_PTR f = | ||
| 446 | (FRAME_PTR) g_object_get_data (G_OBJECT (xw->widget), XG_FRAME_DATA); | ||
| 447 | |||
| 448 | //GdkWindow* window=gtk_widget_get_window(xw->widget); //event winds up in emacs | ||
| 449 | |||
| 450 | //TODO assert xw is a gtk_socket or THIS WILL FAIL GLORIOUSLY | ||
| 451 | GdkWindow *window = gtk_socket_get_plug_window (GTK_SOCKET (xw->widget)); | ||
| 452 | //the event gets eaten somewhere. | ||
| 453 | //i suspect you just cant send an event to a child window and not have emacs eat it. | ||
| 454 | //but if this were true the event should pop to emacs right? | ||
| 455 | |||
| 456 | |||
| 457 | XID xid = gdk_x11_drawable_get_xid (window); | ||
| 458 | |||
| 459 | printf ("xwidget-send-keyboard-event %d %d\n", window, xid); | ||
| 460 | |||
| 461 | xwidget_key_send_message (f, xid, 38, 1, 0); //38 is 'a' HACK for now | ||
| 462 | xwidget_key_send_message (f, xid, 38, 0, 0); | ||
| 463 | |||
| 464 | return Qnil; | ||
| 465 | } | ||
| 466 | |||
| 467 | void | ||
| 468 | syms_of_xwidget () | ||
| 469 | { | ||
| 470 | int i; | ||
| 471 | |||
| 472 | Qxwidget_set_keyboard_grab = intern ("xwidget-set-keyboard-grab"); | ||
| 473 | staticpro (&Qxwidget_set_keyboard_grab); | ||
| 474 | defsubr (&Sxwidget_set_keyboard_grab); | ||
| 475 | |||
| 476 | Qxwidget_send_keyboard_event = intern ("xwidget-send-keyboard-event"); | ||
| 477 | staticpro (&Qxwidget_send_keyboard_event); | ||
| 478 | defsubr (&Sxwidget_send_keyboard_event); | ||
| 479 | |||
| 480 | Qxwidget_embed_steal_window = intern ("xwidget-embed-steal-window"); | ||
| 481 | staticpro (&Qxwidget_embed_steal_window); | ||
| 482 | defsubr (&Sxwidget_embed_steal_window); | ||
| 483 | |||
| 484 | |||
| 485 | Qxwidget_resize_internal = intern ("xwidget-resize-internal"); | ||
| 486 | staticpro (&Qxwidget_resize_internal); | ||
| 487 | defsubr (&Sxwidget_resize_internal); | ||
| 488 | |||
| 489 | |||
| 490 | Qxwidget_embed_steal_window = intern ("xwidget-embed-steal-window"); | ||
| 491 | staticpro (&Qxwidget_embed_steal_window); | ||
| 492 | defsubr (&Sxwidget_embed_steal_window); | ||
| 493 | |||
| 494 | |||
| 495 | Qxwidget = intern ("xwidget"); | ||
| 496 | staticpro (&Qxwidget); | ||
| 497 | |||
| 498 | Qxwidget_id = intern (":xwidget-id"); | ||
| 499 | staticpro (&Qxwidget_id); | ||
| 500 | |||
| 501 | Qtitle = intern (":title"); | ||
| 502 | staticpro (&Qtitle); | ||
| 503 | |||
| 504 | Fprovide (intern ("xwidget-internal"), Qnil); | ||
| 505 | |||
| 506 | for (i = 0; i < MAX_XWIDGETS; i++) | ||
| 507 | xwidgets[i].initialized = 0; | ||
| 508 | } | ||
| 509 | |||
| 510 | |||
| 511 | /* Value is non-zero if OBJECT is a valid Lisp xwidget specification. A | ||
| 512 | valid xwidget specification is a list whose car is the symbol | ||
| 513 | `xwidget', and whose rest is a property list. The property list must | ||
| 514 | contain a value for key `:type'. That value must be the name of a | ||
| 515 | supported xwidget type. The rest of the property list depends on the | ||
| 516 | xwidget type. */ | ||
| 517 | |||
| 518 | int | ||
| 519 | valid_xwidget_p (object) | ||
| 520 | Lisp_Object object; | ||
| 521 | { | ||
| 522 | int valid_p = 0; | ||
| 523 | |||
| 524 | if (XWIDGETP (object)) | ||
| 525 | { | ||
| 526 | /* Lisp_Object tem; */ | ||
| 527 | |||
| 528 | /* for (tem = XCDR (object); CONSP (tem); tem = XCDR (tem)) */ | ||
| 529 | /* if (EQ (XCAR (tem), QCtype)) */ | ||
| 530 | /* { */ | ||
| 531 | /* tem = XCDR (tem); */ | ||
| 532 | /* if (CONSP (tem) && SYMBOLP (XCAR (tem))) */ | ||
| 533 | /* { */ | ||
| 534 | /* struct xwidget_type *type; */ | ||
| 535 | /* type = lookup_xwidget_type (XCAR (tem)); */ | ||
| 536 | /* if (type) */ | ||
| 537 | /* valid_p = type->valid_p (object); */ | ||
| 538 | /* } */ | ||
| 539 | |||
| 540 | /* break; */ | ||
| 541 | /* } */ | ||
| 542 | //never mind type support for now | ||
| 543 | valid_p = 1; | ||
| 544 | } | ||
| 545 | |||
| 546 | return valid_p; | ||
| 547 | } | ||
| 548 | |||
| 549 | //type support nevermind for now | ||
| 550 | |||
| 551 | /* /\* List of supported image types. Use define_image_type to add new */ | ||
| 552 | /* types. Use lookup_image_type to find a type for a given symbol. *\/ */ | ||
| 553 | |||
| 554 | /* static struct wxidget_type *wxidget_types; */ | ||
| 555 | |||
| 556 | /* /\* Look up xwidget type SYMBOL, and return a pointer to its xwidget_type */ | ||
| 557 | /* structure. Value is null if SYMBOL is not a known image type. *\/ */ | ||
| 558 | |||
| 559 | /* static INLINE struct xwidget_type *lookup_xwidget_type (Lisp_Object symbol) */ | ||
| 560 | /* { */ | ||
| 561 | /* struct xwidget_type *type; */ | ||
| 562 | |||
| 563 | /* for (type = xwidget_types; type; type = type->next) */ | ||
| 564 | /* if (EQ (symbol, *type->type)) */ | ||
| 565 | /* break; */ | ||
| 566 | |||
| 567 | /* return type; */ | ||
| 568 | /* } */ | ||
| 569 | |||
| 570 | |||
| 571 | /* hidden means not being seen in the "live" window. | ||
| 572 | a phantom might be seen somewhere though */ | ||
| 573 | void | ||
| 574 | xwidget_hide (struct xwidget *xw) | ||
| 575 | { | ||
| 576 | //printf("xwidget %d hidden\n",xw->id); | ||
| 577 | xw->hidden = 1; | ||
| 578 | //gtk_widget_hide(GTK_WIDGET(xw->widgetwindow)); | ||
| 579 | gtk_fixed_move (GTK_FIXED (xw->emacswindow), GTK_WIDGET (xw->widgetwindow), | ||
| 580 | 10000, 10000); | ||
| 581 | } | ||
| 582 | |||
| 583 | void | ||
| 584 | xwidget_show (struct xwidget *xw) | ||
| 585 | { | ||
| 586 | //printf("xwidget %d shown\n",xw->id); | ||
| 587 | xw->hidden = 0; | ||
| 588 | //gtk_widget_show(GTK_WIDGET(xw->widgetwindow)); | ||
| 589 | gtk_fixed_move (GTK_FIXED (xw->emacswindow), GTK_WIDGET (xw->widgetwindow), | ||
| 590 | xw->x, xw->y); | ||
| 591 | } | ||
| 592 | |||
| 593 | |||
| 594 | Lisp_Object | ||
| 595 | xwidget_spec_value (spec, key, found) | ||
| 596 | Lisp_Object spec, key; | ||
| 597 | int *found; | ||
| 598 | { | ||
| 599 | Lisp_Object tail; | ||
| 600 | |||
| 601 | xassert (valid_xwidget_p (spec)); | ||
| 602 | |||
| 603 | for (tail = XCDR (spec); | ||
| 604 | CONSP (tail) && CONSP (XCDR (tail)); tail = XCDR (XCDR (tail))) | ||
| 605 | { | ||
| 606 | if (EQ (XCAR (tail), key)) | ||
| 607 | { | ||
| 608 | if (found) | ||
| 609 | *found = 1; | ||
| 610 | return XCAR (XCDR (tail)); | ||
| 611 | } | ||
| 612 | } | ||
| 613 | |||
| 614 | if (found) | ||
| 615 | *found = 0; | ||
| 616 | return Qnil; | ||
| 617 | } | ||
| 618 | |||
| 619 | void | ||
| 620 | assert_valid_xwidget_id (int id, char *str) | ||
| 621 | { | ||
| 622 | if (id < 0 || id > MAX_XWIDGETS) | ||
| 623 | { | ||
| 624 | printf ("broken xwidgetid:%d %s\n", id, str); | ||
| 625 | abort (); | ||
| 626 | } | ||
| 627 | } | ||
| 628 | |||
| 629 | struct xwidget * | ||
| 630 | xwidget_from_id (int id) | ||
| 631 | { | ||
| 632 | assert_valid_xwidget_id (id, "xwidget_from_id"); | ||
| 633 | return &xwidgets[id]; | ||
| 634 | } | ||
| 635 | |||
| 636 | int | ||
| 637 | lookup_xwidget (spec) | ||
| 638 | Lisp_Object spec; | ||
| 639 | { | ||
| 640 | |||
| 641 | int found = 0, found1 = 0, found2 = 0; | ||
| 642 | Lisp_Object value; | ||
| 643 | value = xwidget_spec_value (spec, Qxwidget_id, &found1); | ||
| 644 | int id = INTEGERP (value) ? XFASTINT (value) : 0; //id 0 by default, but id must be unique so this is dumb | ||
| 645 | |||
| 646 | struct xwidget *xw = &xwidgets[id]; | ||
| 647 | value = xwidget_spec_value (spec, QCtype, &found); | ||
| 648 | xw->type = INTEGERP (value) ? XFASTINT (value) : 1; //default to button | ||
| 649 | value = xwidget_spec_value (spec, Qtitle, &found2); | ||
| 650 | xw->title = STRINGP (value) ? (char *) SDATA (value) : "?"; //funky cast FIXME | ||
| 651 | |||
| 652 | value = xwidget_spec_value (spec, QCheight, NULL); | ||
| 653 | xw->height = INTEGERP (value) ? XFASTINT (value) : 50; //ok | ||
| 654 | value = xwidget_spec_value (spec, QCwidth, NULL); | ||
| 655 | xw->width = INTEGERP (value) ? XFASTINT (value) : 50; //ok | ||
| 656 | |||
| 657 | |||
| 658 | printf ("xwidget_id:%d type:%d found:%d %d %d title:%s (%d,%d)\n", id, | ||
| 659 | xw->type, found, found1, found2, xw->title, xw->height, xw->width); | ||
| 660 | |||
| 661 | |||
| 662 | assert_valid_xwidget_id (id, "lookup_xwidget"); | ||
| 663 | |||
| 664 | return id; | ||
| 665 | } | ||
| 666 | |||
| 667 | ////////////////////////////////// | ||
| 668 | int region_modified = 0; | ||
| 669 | |||
| 670 | /*set up detection of touched xwidget*/ | ||
| 671 | void | ||
| 672 | xwidget_start_redisplay () | ||
| 673 | { | ||
| 674 | int i; | ||
| 675 | for (i = 0; i < MAX_XWIDGETS; i++) | ||
| 676 | xwidgets[i].redisplayed = 0; | ||
| 677 | |||
| 678 | } | ||
| 679 | |||
| 680 | /* the xwidget was touched during redisplay, so it isnt a candidate for hiding*/ | ||
| 681 | void | ||
| 682 | xwidget_touch (struct xwidget *xw) | ||
| 683 | { | ||
| 684 | //printf("touch xwidget %d\n", xw->id); | ||
| 685 | xw->redisplayed = 1; | ||
| 686 | } | ||
| 687 | |||
| 688 | /* redisplay has ended, now we should hide untouched xwidgets | ||
| 689 | |||
| 690 | atm this works as follows: only check if xwidgets are displayed in the | ||
| 691 | "selected window". if not, hide them or phantom them. | ||
| 692 | |||
| 693 | this means valid cases like xwidgets being displayed only once in | ||
| 694 | non-selected windows, does not work well. they should also be visible | ||
| 695 | in that case not phantomed. | ||
| 696 | |||
| 697 | */ | ||
| 698 | void | ||
| 699 | xwidget_end_redisplay (struct glyph_matrix *matrix) | ||
| 700 | { | ||
| 701 | //dont change anything if minibuffer is selected this redisplay | ||
| 702 | //this is mostly a workaround to reduce the phantoming of xwidgets | ||
| 703 | if( (XWINDOW (FRAME_MINIBUF_WINDOW (SELECTED_FRAME()))) == | ||
| 704 | (XWINDOW (FRAME_SELECTED_WINDOW (SELECTED_FRAME())))) | ||
| 705 | return; | ||
| 706 | |||
| 707 | int i; | ||
| 708 | struct xwidget *xw; | ||
| 709 | region_modified = 0; | ||
| 710 | xwidget_start_redisplay (); | ||
| 711 | //iterate desired glyph matrix of "live" window here, hide gtk widgets | ||
| 712 | //not in the desired matrix. | ||
| 713 | int area; | ||
| 714 | //the current scheme will fail on the case of several buffers showing xwidgets | ||
| 715 | |||
| 716 | // dump_glyph_matrix(matrix, 2); | ||
| 717 | for (i = 0; i < matrix->nrows; ++i) | ||
| 718 | { | ||
| 719 | // dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs); | ||
| 720 | struct glyph_row *row; | ||
| 721 | row = MATRIX_ROW (matrix, i); | ||
| 722 | if (row->enabled_p != 0) | ||
| 723 | { | ||
| 724 | for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) | ||
| 725 | { | ||
| 726 | struct glyph *glyph = row->glyphs[area]; | ||
| 727 | struct glyph *glyph_end = glyph + row->used[area]; | ||
| 728 | for (; glyph < glyph_end; ++glyph) | ||
| 729 | { | ||
| 730 | if (glyph->type == XWIDGET_GLYPH) | ||
| 731 | { | ||
| 732 | //printf("(%d)",glyph->u.xwidget_id); | ||
| 733 | //here the id sometimes sucks, so maybe the desired glyph matrix isnt ready here? | ||
| 734 | //also, it appears the desired matrix is not the entire window, but only the changed part. wtf? | ||
| 735 | int id = glyph->u.xwidget_id; | ||
| 736 | if (id < 0 || id > MAX_XWIDGETS) | ||
| 737 | { | ||
| 738 | printf | ||
| 739 | ("glyph matrix contains crap, abort xwidget handling and wait for better times\n "); | ||
| 740 | //dump_glyph_matrix(matrix, 2); | ||
| 741 | return; | ||
| 742 | } | ||
| 743 | else | ||
| 744 | { | ||
| 745 | // printf("row %d not enabled\n", i); | ||
| 746 | } | ||
| 747 | xwidget_touch (&xwidgets[glyph->u.xwidget_id]); | ||
| 748 | } | ||
| 749 | } | ||
| 750 | } | ||
| 751 | } | ||
| 752 | } | ||
| 753 | |||
| 754 | for (i = 0; i < MAX_XWIDGETS; i++) | ||
| 755 | { | ||
| 756 | xw = &xwidgets[i]; | ||
| 757 | if (xw->initialized) | ||
| 758 | { | ||
| 759 | if (xw->redisplayed) | ||
| 760 | xwidget_show (xw); | ||
| 761 | else | ||
| 762 | xwidget_hide (xw); | ||
| 763 | } | ||
| 764 | } | ||
| 765 | |||
| 766 | } | ||
| 767 | |||
| 768 | /* some type of modification was made to the buffers*/ | ||
| 769 | void | ||
| 770 | xwidget_modify_region () | ||
| 771 | { | ||
| 772 | region_modified = 1; | ||
| 773 | } | ||
| 774 | |||
| 775 | //////////////////////////////////////////////////////////////// | ||
| 776 | |||
| 777 | /* delete the xwidget and its native widget peer */ | ||
| 778 | void | ||
| 779 | xwidget_delete (struct xwidget *xw) | ||
| 780 | { | ||
| 781 | printf ("xwidget %d deleted\n", xw->id); | ||
| 782 | xw->initialized = 0; | ||
| 783 | gtk_widget_destroy (xw->widget); | ||
| 784 | |||
| 785 | } | ||
| 786 | |||
| 787 | |||
| 788 | |||
| 789 | |||
| 790 | /* redraw all xwidgets */ | ||
| 791 | void | ||
| 792 | xwidget_invalidate () | ||
| 793 | { | ||
| 794 | int i; | ||
| 795 | struct xwidget *xw; | ||
| 796 | printf ("invalidate "); | ||
| 797 | for (i = 0; i < MAX_XWIDGETS; i++) | ||
| 798 | { | ||
| 799 | xw = &xwidgets[i]; | ||
| 800 | if (xw->initialized) | ||
| 801 | { | ||
| 802 | printf ("%d,", i); | ||
| 803 | gtk_widget_queue_draw_area (xw->widget, 0, 0, xw->width, | ||
| 804 | xw->height); | ||
| 805 | } | ||
| 806 | } | ||
| 807 | printf ("\n"); | ||
| 808 | } | ||
diff --git a/src/xwidget.h b/src/xwidget.h new file mode 100644 index 00000000000..acceb720108 --- /dev/null +++ b/src/xwidget.h | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | void x_draw_xwidget_glyph_string P_ ((struct glyph_string *s)); | ||
| 2 | void syms_of_xwidget (); | ||
| 3 | |||
| 4 | extern Lisp_Object Qxwidget; | ||
| 5 | /* Test for xwidget (xwidget . spec) (car must be the symbol xwidget)*/ | ||
| 6 | #define XWIDGETP(x) (CONSP (x) && EQ (XCAR (x), Qxwidget)) | ||
| 7 | |||
| 8 | int valid_xwidget_p (Lisp_Object object) ; | ||
| 9 | |||
| 10 | #include <gtk/gtk.h> | ||
| 11 | |||
| 12 | /* | ||
| 13 | each xwidget instance is described by this struct. | ||
| 14 | */ | ||
| 15 | struct xwidget{ | ||
| 16 | int id; | ||
| 17 | int type; | ||
| 18 | int hidden; | ||
| 19 | GtkWidget* widget; | ||
| 20 | GtkContainer* widgetwindow; | ||
| 21 | |||
| 22 | char* title; | ||
| 23 | int initialized; | ||
| 24 | int height; | ||
| 25 | int width; | ||
| 26 | int x; int y; | ||
| 27 | Lisp_Object message_hook; | ||
| 28 | int redisplayed; | ||
| 29 | GtkContainer* emacswindow; | ||
| 30 | }; | ||
| 31 | |||
| 32 | |||
| 33 | struct xwidget_type | ||
| 34 | { | ||
| 35 | /* A symbol uniquely identifying the xwidget type, */ | ||
| 36 | Lisp_Object *type; | ||
| 37 | |||
| 38 | /* Check that SPEC is a valid image specification for the given | ||
| 39 | image type. Value is non-zero if SPEC is valid. */ | ||
| 40 | int (* valid_p) P_ ((Lisp_Object spec)); | ||
| 41 | |||
| 42 | /* Next in list of all supported image types. */ | ||
| 43 | struct xwidget_type *next; | ||
| 44 | }; | ||
| 45 | |||
| 46 | |||
| 47 | static INLINE struct xwidget_type *lookup_xwidget_type (Lisp_Object symbol); | ||
| 48 | |||
| 49 | |||
| 50 | |||
| 51 | struct xwidget* xwidget_from_id(int id); | ||
| 52 | |||
| 53 | extern int xwidget_owns_kbd; | ||
| 54 | |||
| 55 | void xwidget_start_redisplay(); | ||
| 56 | void xwidget_end_redisplay(struct glyph_matrix* matrix); | ||
| 57 | void xwidget_modify_region(); | ||
| 58 | |||
| 59 | void xwidget_touch(struct xwidget* xw); | ||
| 60 | void xwidget_delete(struct xwidget* xw); | ||
| 61 | void assert_valid_xwidget_id(int id,char *str); | ||