aboutsummaryrefslogtreecommitdiffstats
path: root/src/xwidget.c
diff options
context:
space:
mode:
authorJoakim Verona2010-09-15 11:34:12 +0200
committerJoakim Verona2010-09-15 11:34:12 +0200
commitffce6496f1e23dbe524b8c3c0e3530cf610e1b08 (patch)
tree9dc9d35237fc616280b31bf469848527777fe122 /src/xwidget.c
parent263063570533390c3859ad1e64c7fdcc06c8617d (diff)
downloademacs-ffce6496f1e23dbe524b8c3c0e3530cf610e1b08.tar.gz
emacs-ffce6496f1e23dbe524b8c3c0e3530cf610e1b08.zip
this doesnt actually work at all, but it does do some interesting things with composition, and contains lots of random experimental code. so i commit now, remove junk, and continue
Diffstat (limited to 'src/xwidget.c')
-rw-r--r--src/xwidget.c232
1 files changed, 140 insertions, 92 deletions
diff --git a/src/xwidget.c b/src/xwidget.c
index 142dda0e76f..ea32ea841ab 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -189,7 +189,7 @@ xwidget_setup_socket_composition(struct xwidget* xw)
189 XCompositeRedirectSubwindows( dpy, xid, 189 XCompositeRedirectSubwindows( dpy, xid,
190 CompositeRedirectAutomatic ); 190 CompositeRedirectAutomatic );
191 191
192 192
193/* 193/*
194 XWindowAttributes attr; 194 XWindowAttributes attr;
195 XGetWindowAttributes( dpy, xid, &attr ); 195 XGetWindowAttributes( dpy, xid, &attr );
@@ -226,7 +226,40 @@ xwidget_show (struct xwidget *xw)
226 xw->hidden = 0; 226 xw->hidden = 0;
227 //gtk_widget_show(GTK_WIDGET(xw->widgetwindow)); 227 //gtk_widget_show(GTK_WIDGET(xw->widgetwindow));
228 gtk_fixed_move (GTK_FIXED (xw->emacswindow), GTK_WIDGET (xw->widgetwindow), 228 gtk_fixed_move (GTK_FIXED (xw->emacswindow), GTK_WIDGET (xw->widgetwindow),
229 xw->x, xw->y); 229 xw->x, xw->y);
230}
231
232
233xwidget_composite_draw(GtkWidget *widget,
234 GdkEventExpose *event,
235 gpointer data)
236//struct xwidget *xw)
237{
238 FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (widget), XG_FRAME_DATA);
239 ////////////////////////////////////////////////////////////////
240 //Example 7. Composited windows
241 GdkRegion *region;
242 GtkWidget *child;
243 cairo_t *cr;
244 /* get our child (in this case, the event box) */
245 child = widget; //gtk_bin_get_child (GTK_BIN (widget));
246 /* create a cairo context to draw to the window */
247 cr = gdk_cairo_create (gtk_widget_get_window(f->gwfixed));//xw->widgetwindow));//widget->window);
248 /* the source data is the (composited) event box */
249 gdk_cairo_set_source_pixmap (cr, child->window,
250 child->allocation.x,
251 child->allocation.y);
252 /* draw no more than our expose event intersects our child */
253 /* region = gdk_region_rectangle (&child->allocation);
254 gdk_region_intersect (region, event->region);
255 gdk_cairo_region (cr, region);
256 cairo_clip (cr); */
257 /* composite, with a 50% opacity */
258 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
259 cairo_paint_with_alpha (cr, 0.5);//transparency);
260 /* we're done */
261 cairo_destroy (cr);
262 // return FALSE;
230} 263}
231 264
232void 265void
@@ -242,7 +275,7 @@ xwidget_init (struct xwidget *xw, struct glyph_string *s, int x, int y)
242 case 1: 275 case 1:
243 xw->widget = gtk_button_new_with_label (xw->title); 276 xw->widget = gtk_button_new_with_label (xw->title);
244 g_signal_connect (G_OBJECT (xw->widget), "clicked", 277 g_signal_connect (G_OBJECT (xw->widget), "clicked",
245 G_CALLBACK (buttonclick_handler), xw); 278 G_CALLBACK (buttonclick_handler), xw);
246 break; 279 break;
247 case 2: 280 case 2:
248 xw->widget = gtk_toggle_button_new_with_label (xw->title); 281 xw->widget = gtk_toggle_button_new_with_label (xw->title);
@@ -252,8 +285,8 @@ xwidget_init (struct xwidget *xw, struct glyph_string *s, int x, int y)
252 break; 285 break;
253 case 4: 286 case 4:
254 xw->widget = 287 xw->widget =
255 gtk_hscale_new (GTK_ADJUSTMENT 288 gtk_hscale_new (GTK_ADJUSTMENT
256 (gtk_adjustment_new (0, 0, 100, 1, 1, 0))); 289 (gtk_adjustment_new (0, 0, 100, 1, 1, 0)));
257 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 290 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
258 } 291 }
259 //widget realization 292 //widget realization
@@ -265,24 +298,30 @@ xwidget_init (struct xwidget *xw, struct glyph_string *s, int x, int y)
265 gtk_layout_set_size (GTK_LAYOUT (xw->widgetwindow), xw->width, xw->height); 298 gtk_layout_set_size (GTK_LAYOUT (xw->widgetwindow), xw->width, xw->height);
266 gtk_container_add (xw->widgetwindow, xw->widget); 299 gtk_container_add (xw->widgetwindow, xw->widget);
267 gtk_widget_set_size_request (GTK_WIDGET (xw->widget), xw->width, 300 gtk_widget_set_size_request (GTK_WIDGET (xw->widget), xw->width,
268 xw->height); 301 xw->height);
269 gtk_fixed_put (GTK_FIXED (s->f->gwfixed), GTK_WIDGET (xw->widgetwindow), x, 302 gtk_fixed_put (GTK_FIXED (s->f->gwfixed), GTK_WIDGET (xw->widgetwindow), x,
270 y); 303 y);
271 gtk_widget_show_all (GTK_WIDGET (xw->widgetwindow)); 304 gtk_widget_show_all (GTK_WIDGET (xw->widgetwindow));
272 305
273 //a bit inconsistent, but the rest of emacs stores stuff in the widgets, 306 //a bit inconsistent, but the rest of emacs stores stuff in the widgets,
274 //like frame data. in my case it might as well reside in the xwidget struct i think 307 //like frame data. in my case it might as well reside in the xwidget struct i think
275 g_object_set_data (G_OBJECT (xw->widget), XG_FRAME_DATA, (gpointer) (s->f)); 308 g_object_set_data (G_OBJECT (xw->widget), XG_FRAME_DATA, (gpointer) (s->f));
276 309
310 //this seems to enable xcomposition. later we need to paint ourselves somehow,
311 //since the widget is no longer responsible for painting itself
312 gdk_window_set_composited (xw->widget->window, TRUE);
313
314 g_signal_connect(xw->widget, "expose-event", G_CALLBACK(xwidget_composite_draw), NULL);
315
277 //widgettype specific initialization only possible after realization 316 //widgettype specific initialization only possible after realization
278 switch (xw->type) 317 switch (xw->type)
279 { 318 {
280 case 3: 319 case 3:
281 printf ("socket id:%x %d\n", 320 printf ("socket id:%x %d\n",
282 gtk_socket_get_id (GTK_SOCKET (xw->widget)), 321 gtk_socket_get_id (GTK_SOCKET (xw->widget)),
283 gtk_socket_get_id (GTK_SOCKET (xw->widget))); 322 gtk_socket_get_id (GTK_SOCKET (xw->widget)));
284 send_xembed_ready_event (xw->id, 323 send_xembed_ready_event (xw->id,
285 gtk_socket_get_id (GTK_SOCKET (xw->widget))); 324 gtk_socket_get_id (GTK_SOCKET (xw->widget)));
286 break; 325 break;
287 } 326 }
288} 327}
@@ -293,7 +332,8 @@ void
293xwidget_draw_phantom (struct xwidget *xw, 332xwidget_draw_phantom (struct xwidget *xw,
294 int x, int y, 333 int x, int y,
295 int clipx, int clipy, 334 int clipx, int clipy,
296 struct glyph_string *s) 335 struct glyph_string *s,
336 float transparency)
297{ 337{
298 //we cant always get real widgets, so here we try to fetch a snapshot of 338 //we cant always get real widgets, so here we try to fetch a snapshot of
299 //the real xwidget and paint that as a phantom image. if that fails, we 339 //the real xwidget and paint that as a phantom image. if that fails, we
@@ -309,7 +349,7 @@ xwidget_draw_phantom (struct xwidget *xw,
309 GdkNativeWindow p_xid; 349 GdkNativeWindow p_xid;
310 GdkWindow* xid; 350 GdkWindow* xid;
311 351
312 if (xw->type == 3 && xwidget_has_composition()){ 352 /* if (xw->type == 3 && xwidget_has_composition()){
313 //its a gtk_socket, get_snapshot() doesnt work so try using composition methods 353 //its a gtk_socket, get_snapshot() doesnt work so try using composition methods
314 //xw_snapshot = gdk_pixmap_foreign_new_for_display(GDK_DISPLAY(), p_xid); 354 //xw_snapshot = gdk_pixmap_foreign_new_for_display(GDK_DISPLAY(), p_xid);
315 xid = gtk_socket_get_plug_window (GTK_SOCKET (xw->widget)); 355 xid = gtk_socket_get_plug_window (GTK_SOCKET (xw->widget));
@@ -326,25 +366,29 @@ xwidget_draw_phantom (struct xwidget *xw,
326 printf("phantom other\n"); 366 printf("phantom other\n");
327 xw_snapshot = gtk_widget_get_snapshot (xw->widget, NULL); 367 xw_snapshot = gtk_widget_get_snapshot (xw->widget, NULL);
328 } 368 }
329 369 */
330 if(xw_snapshot==NULL){ 370#if 0
331 printf(" xw_snapshot null for some reason ... \n"); 371 xw_snapshot=gdk_offscreen_window_get_pixmap(xw->widget->window);
332 return; 372 if(xw_snapshot==NULL){
333 } 373 printf(" xw_snapshot null for some reason ... \n");
334 374 /* //return; */
335 printf("3\n"); 375 }
336 gdkgc = gdk_gc_new (xw_snapshot); 376 gdkgc = gdk_gc_new (xw_snapshot);
337 377
338 //currently a phantom gets a line drawn across it to denote phantomness 378 //currently a phantom gets a line drawn across it to denote phantomness
339 //dimming or such would be more elegant 379 //dimming or such would be more elegant, but we cant be bothered atm
340 printf("4\n"); 380 gdk_draw_line (xw_snapshot, gdkgc, 0, 0, xw->width, xw->height);
341 gdk_draw_line (xw_snapshot, gdkgc, 0, 0, xw->width, xw->height); 381 gdk_draw_drawable (gtk_widget_get_window (s->f->gwfixed), //convert to GdkWindow from gtkWindow
342 printf("5\n"); 382 gdkgc, xw_snapshot, 0, 0, x, y, clipx, clipy);
343 gdk_draw_drawable (gtk_widget_get_window (s->f->gwfixed), //convert to GdkWindow from gtkWindow 383#else
344 gdkgc, xw_snapshot, 0, 0, x, y, clipx, clipy);
345}
346 384
385 xwidget_composite_draw(xw->widget, NULL, NULL);
386#endif
387 ////////////////////////////////////////////////////////////////
388
347 389
390 //clean up here...
391}
348/* gtk widget reparent snippet to be used: 392/* gtk widget reparent snippet to be used:
349 g_object_ref((gpointer)xw->widgetwindow); 393 g_object_ref((gpointer)xw->widgetwindow);
350 gtk_container_remove(GTK_CONTAINER(old_parent), xw->widgetwindow); 394 gtk_container_remove(GTK_CONTAINER(old_parent), xw->widgetwindow);
@@ -369,12 +413,12 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
369 run so the xwidget wont know it has been moved. 413 run so the xwidget wont know it has been moved.
370 414
371 Solved temporarily by never optimizing in try_window_reusing_current_matrix(). 415 Solved temporarily by never optimizing in try_window_reusing_current_matrix().
372 416
373 BUG the phantoming code doesnt work very well when the live xwidget is off screen. 417 BUG the phantoming code doesnt work very well when the live xwidget is off screen.
374 you will get weirdo display artefacts. Composition ought to solve this, since that means the live window is 418 you will get weirdo display artefacts. Composition ought to solve this, since that means the live window is
375 always available in an off-screen buffer. My current attempt at composition doesnt work properly however. 419 always available in an off-screen buffer. My current attempt at composition doesnt work properly however.
376 420
377 421
378 */ 422 */
379 int box_line_hwidth = eabs (s->face->box_line_width); 423 int box_line_hwidth = eabs (s->face->box_line_width);
380 int box_line_vwidth = max (s->face->box_line_width, 0); 424 int box_line_vwidth = max (s->face->box_line_width, 0);
@@ -384,7 +428,7 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
384 //TODO drawing_in_selected_window can be true for several windows if we have several frames. 428 //TODO drawing_in_selected_window can be true for several windows if we have several frames.
385 //we also need to check that the xwidget is to be drawn inside a window on a frame where it originaly lives. 429 //we also need to check that the xwidget is to be drawn inside a window on a frame where it originaly lives.
386 //otherwise draw a phantom, or maybe reparent the xwidget. 430 //otherwise draw a phantom, or maybe reparent the xwidget.
387 431
388 struct xwidget *xw = &xwidgets[s->xwidget_id]; 432 struct xwidget *xw = &xwidgets[s->xwidget_id];
389 int clipx; int clipy; 433 int clipx; int clipy;
390 434
@@ -412,27 +456,31 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
412 if (drawing_in_selected_window) 456 if (drawing_in_selected_window)
413 { 457 {
414 if ((xw->x != x) || (xw->y != y)) //has it moved? 458 if ((xw->x != x) || (xw->y != y)) //has it moved?
415 { 459 {
416 printf ("xwidget moved: id:%d (%d,%d)->(%d,%d)\n", xw->id, xw->x, xw->y, x, y); 460 printf ("xwidget moved: id:%d (%d,%d)->(%d,%d)\n", xw->id, xw->x, xw->y, x, y);
417 } 461 }
418 else 462 else
419 { 463 {
420 } 464 }
421 //TODO maybe theres a bug that the hidden flag sometimes dont get reset properly 465 //TODO maybe theres a bug that the hidden flag sometimes dont get reset properly
422 if (!xwidget_hidden(xw)) //hidden equals not being seen in the live window 466 if (!xwidget_hidden(xw)) //hidden equals not being seen in the live window
423 { 467 {
424 gtk_fixed_move (GTK_FIXED (s->f->gwfixed), 468 gtk_fixed_move (GTK_FIXED (s->f->gwfixed),
425 GTK_WIDGET (xw->widgetwindow), x, y); 469 GTK_WIDGET (xw->widgetwindow), x, y);
426 //clip the widget window if some parts happen to be outside drawable area 470 //clip the widget window if some parts happen to be outside drawable area
427 //an emacs window is not a gtk window, a gtk window covers the entire frame 471 //an emacs window is not a gtk window, a gtk window covers the entire frame
428 gtk_widget_set_size_request (GTK_WIDGET (xw->widgetwindow), clipx, 472 gtk_widget_set_size_request (GTK_WIDGET (xw->widgetwindow), clipx,
429 clipy); 473 clipy);
430 } 474
475 //if we are using compositing, we are always responsible for drawing the widget on the screen
476 //just reuse the phantom routine for now
477 xwidget_draw_phantom (xw, x, y, clipx, clipy, s, 1.0);
478 }
431 else 479 else
432 { 480 {
433 //xwidget is hidden, hide it offscreen somewhere, still realized, so we may snapshot it 481 //xwidget is hidden, hide it offscreen somewhere, still realized, so we may snapshot it
434 //gtk_fixed_move(GTK_FIXED(s->f->gwfixed),GTK_WIDGET(xw->widgetwindow) ,10000,10000); 482 //gtk_fixed_move(GTK_FIXED(s->f->gwfixed),GTK_WIDGET(xw->widgetwindow) ,10000,10000);
435 } 483 }
436 //xw refers to the *live* instance of the xwidget 484 //xw refers to the *live* instance of the xwidget
437 xw->x = x; 485 xw->x = x;
438 xw->y = y; 486 xw->y = y;
@@ -442,7 +490,7 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
442 else 490 else
443 { 491 {
444 //ok, we are painting the xwidgets in non-selected window, so draw a phantom 492 //ok, we are painting the xwidgets in non-selected window, so draw a phantom
445 xwidget_draw_phantom (xw, x, y, clipx, clipy, s); 493 xwidget_draw_phantom (xw, x, y, clipx, clipy, s, 0.1);
446 494
447 } 495 }
448 496
@@ -494,7 +542,7 @@ DEFUN ("xwidget-resize-internal", Fxwidget_resize_internal, Sxwidget_resize_inte
494 xw->height=h; 542 xw->height=h;
495 gtk_layout_set_size (GTK_LAYOUT (xw->widgetwindow), xw->width, xw->height); 543 gtk_layout_set_size (GTK_LAYOUT (xw->widgetwindow), xw->width, xw->height);
496 gtk_widget_set_size_request (GTK_WIDGET (xw->widget), xw->width, 544 gtk_widget_set_size_request (GTK_WIDGET (xw->widget), xw->width,
497 xw->height); 545 xw->height);
498 return Qnil; 546 return Qnil;
499} 547}
500 548
@@ -598,7 +646,7 @@ xwidget_key_send_message (struct frame *f,
598 event.state = modifiers; 646 event.state = modifiers;
599 647
600 XSendEvent (event.display, event.window, TRUE, KeyPressMask, 648 XSendEvent (event.display, event.window, TRUE, KeyPressMask,
601 (XEvent *) & event); 649 (XEvent *) & event);
602} 650}
603 651
604//using "accessible" interfaces seems expensive 652//using "accessible" interfaces seems expensive
@@ -662,7 +710,7 @@ syms_of_xwidget (void)
662 Qxwidget_info = intern ("xwidget-info"); 710 Qxwidget_info = intern ("xwidget-info");
663 staticpro (&Qxwidget_info); 711 staticpro (&Qxwidget_info);
664 defsubr (&Sxwidget_info); 712 defsubr (&Sxwidget_info);
665 713
666 Qxwidget_resize_internal = intern ("xwidget-resize-internal"); 714 Qxwidget_resize_internal = intern ("xwidget-resize-internal");
667 staticpro (&Qxwidget_resize_internal); 715 staticpro (&Qxwidget_resize_internal);
668 defsubr (&Sxwidget_resize_internal); 716 defsubr (&Sxwidget_resize_internal);
@@ -757,7 +805,7 @@ xwidget_hide (struct xwidget *xw)
757 xw->hidden = 1; 805 xw->hidden = 1;
758 //gtk_widget_hide(GTK_WIDGET(xw->widgetwindow)); 806 //gtk_widget_hide(GTK_WIDGET(xw->widgetwindow));
759 gtk_fixed_move (GTK_FIXED (xw->emacswindow), GTK_WIDGET (xw->widgetwindow), 807 gtk_fixed_move (GTK_FIXED (xw->emacswindow), GTK_WIDGET (xw->widgetwindow),
760 10000, 10000); 808 10000, 10000);
761} 809}
762 810
763 811
@@ -781,11 +829,11 @@ xwidget_spec_value (
781 CONSP (tail) && CONSP (XCDR (tail)); tail = XCDR (XCDR (tail))) 829 CONSP (tail) && CONSP (XCDR (tail)); tail = XCDR (XCDR (tail)))
782 { 830 {
783 if (EQ (XCAR (tail), key)) 831 if (EQ (XCAR (tail), key))
784 { 832 {
785 if (found) 833 if (found)
786 *found = 1; 834 *found = 1;
787 return XCAR (XCDR (tail)); 835 return XCAR (XCDR (tail));
788 } 836 }
789 } 837 }
790 838
791 if (found) 839 if (found)
@@ -835,7 +883,7 @@ lookup_xwidget (Lisp_Object spec)
835 883
836 884
837 printf ("xwidget_id:%d type:%d found:%d %d %d title:%s (%d,%d)\n", id, 885 printf ("xwidget_id:%d type:%d found:%d %d %d title:%s (%d,%d)\n", id,
838 xw->type, found, found1, found2, xw->title, xw->height, xw->width); 886 xw->type, found, found1, found2, xw->title, xw->height, xw->width);
839 887
840 888
841 assert_valid_xwidget_id (id, "lookup_xwidget"); 889 assert_valid_xwidget_id (id, "lookup_xwidget");
@@ -908,35 +956,35 @@ xwidget_end_redisplay (struct glyph_matrix *matrix)
908 struct glyph_row *row; 956 struct glyph_row *row;
909 row = MATRIX_ROW (matrix, i); 957 row = MATRIX_ROW (matrix, i);
910 if (row->enabled_p != 0) 958 if (row->enabled_p != 0)
911 { 959 {
912 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) 960 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
913 { 961 {
914 struct glyph *glyph = row->glyphs[area]; 962 struct glyph *glyph = row->glyphs[area];
915 struct glyph *glyph_end = glyph + row->used[area]; 963 struct glyph *glyph_end = glyph + row->used[area];
916 for (; glyph < glyph_end; ++glyph) 964 for (; glyph < glyph_end; ++glyph)
917 { 965 {
918 if (glyph->type == XWIDGET_GLYPH) 966 if (glyph->type == XWIDGET_GLYPH)
919 { 967 {
920 //printf("(%d)",glyph->u.xwidget_id); 968 //printf("(%d)",glyph->u.xwidget_id);
921 //here the id sometimes sucks, so maybe the desired glyph matrix isnt ready here? 969 //here the id sometimes sucks, so maybe the desired glyph matrix isnt ready here?
922 //also, it appears the desired matrix is not the entire window, but only the changed part. wtf? 970 //also, it appears the desired matrix is not the entire window, but only the changed part. wtf?
923 int id = glyph->u.xwidget_id; 971 int id = glyph->u.xwidget_id;
924 if (id < 0 || id > MAX_XWIDGETS) 972 if (id < 0 || id > MAX_XWIDGETS)
925 { 973 {
926 printf 974 printf
927 ("glyph matrix contains crap, abort xwidget handling and wait for better times\n "); 975 ("glyph matrix contains crap, abort xwidget handling and wait for better times\n ");
928 //dump_glyph_matrix(matrix, 2); 976 //dump_glyph_matrix(matrix, 2);
929 return; 977 return;
930 } 978 }
931 else 979 else
932 { 980 {
933 // printf("row %d not enabled\n", i); 981 // printf("row %d not enabled\n", i);
934 } 982 }
935 xwidget_touch (&xwidgets[glyph->u.xwidget_id]); 983 xwidget_touch (&xwidgets[glyph->u.xwidget_id]);
936 } 984 }
937 } 985 }
938 } 986 }
939 } 987 }
940 } 988 }
941 989
942 for (i = 0; i < MAX_XWIDGETS; i++) 990 for (i = 0; i < MAX_XWIDGETS; i++)
@@ -985,11 +1033,11 @@ xwidget_invalidate (void)
985 { 1033 {
986 xw = &xwidgets[i]; 1034 xw = &xwidgets[i];
987 if (xw->initialized) 1035 if (xw->initialized)
988 { 1036 {
989 printf ("%d,", i); 1037 printf ("%d,", i);
990 gtk_widget_queue_draw_area (xw->widget, 0, 0, xw->width, 1038 gtk_widget_queue_draw_area (xw->widget, 0, 0, xw->width,
991 xw->height); 1039 xw->height);
992 } 1040 }
993 } 1041 }
994 printf ("\n"); 1042 printf ("\n");
995} 1043}