aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/xwidget-test.el4
-rw-r--r--src/xwidget.c143
2 files changed, 112 insertions, 35 deletions
diff --git a/lisp/xwidget-test.el b/lisp/xwidget-test.el
index 29c98684df1..16084c6188e 100644
--- a/lisp/xwidget-test.el
+++ b/lisp/xwidget-test.el
@@ -34,7 +34,7 @@
34 (xwidget-insert 15 2 "toggle" 60 30 2) 34 (xwidget-insert 15 2 "toggle" 60 30 2)
35 (xwidget-insert 30 3 "emacs" 400 200 3) 35 (xwidget-insert 30 3 "emacs" 400 200 3)
36 (xwidget-insert 20 4 "slider" 100 50 4) 36 (xwidget-insert 20 4 "slider" 100 50 4)
37 (xwidget-insert 40 3 "uzbl" 400 400 5) 37;; (xwidget-insert 40 3 "uzbl" 400 400 5)
38 (define-key (current-local-map) [xwidget-event] 'xwidget-handler-demo-basic) 38 (define-key (current-local-map) [xwidget-event] 'xwidget-handler-demo-basic)
39) 39)
40 40
@@ -105,4 +105,4 @@
105 105
106; (xwidget-resize-hack 1 200 200) 106; (xwidget-resize-hack 1 200 200)
107 107
108;(xwidget-demo-basic) \ No newline at end of file 108;(xwidget-demo-basic)
diff --git a/src/xwidget.c b/src/xwidget.c
index dc103601e5c..9d977ced256 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -56,6 +56,7 @@
56#include <X11/Shell.h> 56#include <X11/Shell.h>
57#endif 57#endif
58#include <X11/extensions/Xcomposite.h> 58#include <X11/extensions/Xcomposite.h>
59#include <X11/extensions/Xrender.h>
59 60
60#ifdef HAVE_SYS_TIME_H 61#ifdef HAVE_SYS_TIME_H
61#include <sys/time.h> 62#include <sys/time.h>
@@ -141,6 +142,78 @@ send_xembed_ready_event (int xwid, int xembedid)
141 142
142} 143}
143 144
145int xwidget_query_composition_called = 0;
146int hasNamePixmap = 0;
147
148
149int
150xwidget_has_composition(void){
151int event_base, error_base;
152Display* dpy = GDK_DISPLAY ();
153int i;
154 if(xwidget_query_composition_called)
155 return hasNamePixmap;
156 xwidget_query_composition_called = 1;
157
158 //do this once in an emacs session
159
160 if(gdk_display_supports_composite(gdk_display_get_default ())){
161 hasNamePixmap = 1;
162}else{
163 return 0;
164}
165
166 //redirect all toplevel windows to backing store.
167 //this should probably be optimized so only the gtk sockets we care for get redirected
168 //otoh, the wm might quite possibly already have requested backing store so the code is
169 //probably noop anyway
170 printf("enabling composition\n");
171 for ( i = 0; i < ScreenCount( dpy ); i++ )
172 XCompositeRedirectSubwindows( dpy, RootWindow( dpy, i ),
173 CompositeRedirectAutomatic );
174 return 1;
175
176
177}
178
179void
180xwidget_setup_socket_composition(struct xwidget* xw)
181{
182 //do this for every gtk_socket
183 //XCompositeRedirectWindow(); should probably replace the global backing request
184 //now residing in xwidget_has_composition()
185
186// int xid = gtk_socket_get_plug_window (GTK_SOCKET (xw->widget));
187// Display* dpy = GDK_DISPLAY ();
188
189/*
190 XWindowAttributes attr;
191 XGetWindowAttributes( dpy, xid, &attr );
192
193 XRenderPictFormat *format = XRenderFindVisualFormat( dpy, attr.visual );
194 int hasAlpha = ( format->type == PictTypeDirect && format->direct.alphaMask );
195 int x = attr.x;
196 int y = attr.y;
197 int width = attr.width;
198 int height = attr.height;
199
200
201 XRenderPictureAttributes pa;
202 pa.subwindow_mode = IncludeInferiors; // Don't clip child widgets
203
204 Picture picture = XRenderCreatePicture( dpy, xid, format, CPSubwindowMode, &pa );
205 // p_xid = XCompositeNameWindowPixmap( GDK_DISPLAY (), GDK_WINDOW_XID(xid)) ;
206
207 //this is the actual drawing call that probably should be somewhere else:
208 XRenderComposite( dpy, hasAlpha ? PictOpOver : PictOpSrc, picture, None,
209 dest.x11RenderHandle(), 0, 0, 0, 0, destX, destY, width, height );
210*/
211}
212
213void
214xwidget_end_composition(struct xwidget* w){
215 //XCompositeUnredirectWindow(); stop redirecting, should be called when the socket is destroyed
216}
144 217
145void 218void
146xwidget_init (struct xwidget *xw, struct glyph_string *s, int x, int y) 219xwidget_init (struct xwidget *xw, struct glyph_string *s, int x, int y)
@@ -196,10 +269,14 @@ xwidget_init (struct xwidget *xw, struct glyph_string *s, int x, int y)
196 gtk_socket_get_id (GTK_SOCKET (xw->widget))); 269 gtk_socket_get_id (GTK_SOCKET (xw->widget)));
197 send_xembed_ready_event (xw->id, 270 send_xembed_ready_event (xw->id,
198 gtk_socket_get_id (GTK_SOCKET (xw->widget))); 271 gtk_socket_get_id (GTK_SOCKET (xw->widget)));
272 if(xwidget_has_composition())
273 xwidget_setup_socket_composition(xw);
199 break; 274 break;
200 } 275 }
201} 276}
202 277
278
279
203void 280void
204xwidget_draw_phantom (struct xwidget *xw, int x, int y, int clipx, int clipy, 281xwidget_draw_phantom (struct xwidget *xw, int x, int y, int clipx, int clipy,
205 struct glyph_string *s) 282 struct glyph_string *s)
@@ -216,20 +293,21 @@ xwidget_draw_phantom (struct xwidget *xw, int x, int y, int clipx, int clipy,
216 GdkPixmap *xw_snapshot = NULL; 293 GdkPixmap *xw_snapshot = NULL;
217 GdkGC *gdkgc = NULL; 294 GdkGC *gdkgc = NULL;
218 GdkNativeWindow p_xid; 295 GdkNativeWindow p_xid;
219 GdkNativeWindow xid; 296 GdkWindow* xid;
220 297
221 if (0 298 if (xw->type == 3 && xwidget_has_composition()){
222 //xw->type == 3 //this doesnt work atm
223 ) {
224 //its a gtk_socket, get_snapshot() doesnt work so try using composition methods 299 //its a gtk_socket, get_snapshot() doesnt work so try using composition methods
225 xid = gtk_socket_get_plug_window (GTK_SOCKET (xw->widget));
226 p_xid = XCompositeNameWindowPixmap( GDK_DISPLAY (), GDK_WINDOW_XID(xid)) ;
227 //xw_snapshot = gdk_pixmap_foreign_new_for_display(GDK_DISPLAY(), p_xid); 300 //xw_snapshot = gdk_pixmap_foreign_new_for_display(GDK_DISPLAY(), p_xid);
301 xid = gtk_socket_get_plug_window (GTK_SOCKET (xw->widget));
302 //should check the xid here, because it could be invalid
303 //p_xid = XCompositeNameWindowPixmap( GDK_DISPLAY (), GDK_WINDOW_XID(xid)) ;
304
228 printf("phantom socket 1: %d %d\n", xid, p_xid); 305 printf("phantom socket 1: %d %d\n", xid, p_xid);
229 xw_snapshot = gdk_pixmap_foreign_new(p_xid); //wraps the native window in a gdk windw, but it crashes! 306 xw_snapshot = gdk_pixmap_foreign_new(GDK_WINDOW_XID(xid)); //wraps the native window in a gdk windw, but it crashes!
230 printf("2\n"); 307 printf("2\n");
231 }else { 308 }else {
232 //if its not a socket, its got a snapshot method that works 309 //if its not a socket, its got a snapshot method that works
310 //or if we dont have composition well try for sockets, but probably get a grey rect
233 printf("phantom other\n"); 311 printf("phantom other\n");
234 xw_snapshot = gtk_widget_get_snapshot (xw->widget, NULL); 312 xw_snapshot = gtk_widget_get_snapshot (xw->widget, NULL);
235 } 313 }
@@ -282,7 +360,7 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
282 //and its phantom counterpart 360 //and its phantom counterpart
283 clipx = min (xw->width, WINDOW_RIGHT_EDGE_X (s->w) - x); 361 clipx = min (xw->width, WINDOW_RIGHT_EDGE_X (s->w) - x);
284 clipy = min (xw->height, 362 clipy = min (xw->height,
285 WINDOW_BOTTOM_EDGE_Y (s->w) - WINDOW_MODE_LINE_HEIGHT (s->w) - y); 363 WINDOW_BOTTOM_EDGE_Y (s->w) - WINDOW_MODE_LINE_HEIGHT (s->w) - y);
286 364
287 365
288 //TODO: 366 //TODO:
@@ -353,9 +431,8 @@ DEFUN ("xwidget-embed-steal-window", Fxwidget_embed_steal_window, Sxwidget_embed
353 431
354 432
355DEFUN ("xwidget-resize-internal", Fxwidget_resize_internal, Sxwidget_resize_internal, 3, 3, 0, doc: 433DEFUN ("xwidget-resize-internal", Fxwidget_resize_internal, Sxwidget_resize_internal, 3, 3, 0, doc:
356 /* tell existing embed xwidget to steal other window id. */
357 ) 434 )
358 (Lisp_Object xwidget_id, Lisp_Object new_width, Lisp_Object new_height) 435 (Lisp_Object xwidget_id, Lisp_Object new_width, Lisp_Object new_height)
359{ 436{
360 struct xwidget *xw; 437 struct xwidget *xw;
361 int xid = XFASTINT (xwidget_id); 438 int xid = XFASTINT (xwidget_id);
@@ -413,10 +490,10 @@ DEFUN ("xwidget-set-keyboard-grab", Fxwidget_set_keyboard_grab, Sxwidget_set_key
413 xwidget_owns_kbd = FALSE; 490 xwidget_owns_kbd = FALSE;
414 } 491 }
415 /* 492 /*
416 gdk_keyboard_grab(xw->widget,TRUE,GDK_CURRENT_TIME); 493 gdk_keyboard_grab(xw->widget,TRUE,GDK_CURRENT_TIME);
417 else 494 else
418 gdk_keyboard_ungrab(GDK_CURRENT_TIME); 495 gdk_keyboard_ungrab(GDK_CURRENT_TIME);
419 */ 496 */
420 return Qnil; 497 return Qnil;
421} 498}
422 499
@@ -620,8 +697,8 @@ xwidget_show (struct xwidget *xw)
620 697
621Lisp_Object 698Lisp_Object
622xwidget_spec_value ( 699xwidget_spec_value (
623 Lisp_Object spec, Lisp_Object key, 700 Lisp_Object spec, Lisp_Object key,
624 int *found) 701 int *found)
625{ 702{
626 Lisp_Object tail; 703 Lisp_Object tail;
627 704
@@ -716,14 +793,14 @@ xwidget_touch (struct xwidget *xw)
716 793
717/* redisplay has ended, now we should hide untouched xwidgets 794/* redisplay has ended, now we should hide untouched xwidgets
718 795
719atm this works as follows: only check if xwidgets are displayed in the 796 atm this works as follows: only check if xwidgets are displayed in the
720"selected window". if not, hide them or phantom them. 797 "selected window". if not, hide them or phantom them.
721 798
722this means valid cases like xwidgets being displayed only once in 799 this means valid cases like xwidgets being displayed only once in
723non-selected windows, does not work well. they should also be visible 800 non-selected windows, does not work well. they should also be visible
724in that case not phantomed. 801 in that case not phantomed.
725 802
726 */ 803*/
727void 804void
728xwidget_end_redisplay (struct glyph_matrix *matrix) 805xwidget_end_redisplay (struct glyph_matrix *matrix)
729{ 806{
@@ -783,17 +860,17 @@ xwidget_end_redisplay (struct glyph_matrix *matrix)
783 } 860 }
784 } 861 }
785 862
786 for (i = 0; i < MAX_XWIDGETS; i++) 863 for (i = 0; i < MAX_XWIDGETS; i++)
787 { 864 {
788 xw = &xwidgets[i]; 865 xw = &xwidgets[i];
789 if (xw->initialized) 866 if (xw->initialized)
790 { 867 {
791 if (xw->redisplayed) 868 if (xw->redisplayed)
792 xwidget_show (xw); 869 xwidget_show (xw);
793 else 870 else
794 xwidget_hide (xw); 871 xwidget_hide (xw);
795 } 872 }
796 } 873 }
797 874
798} 875}
799 876