aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJoakim Verona2010-09-17 09:41:01 +0200
committerJoakim Verona2010-09-17 09:41:01 +0200
commite93717961b31f9c1548892182dc01e6afa1afef1 (patch)
treecb85f2820ed78ef3c7aa4dcc68a7cd808938c106 /src
parent07b89477b22b5c2343009c62a7cfaa3006e45d57 (diff)
downloademacs-e93717961b31f9c1548892182dc01e6afa1afef1.tar.gz
emacs-e93717961b31f9c1548892182dc01e6afa1afef1.zip
still doesnt work, but good enough to showcase a little bit what might be possible if we get off-screen rendering working properly. some improved docs also.
Diffstat (limited to 'src')
-rw-r--r--src/xdisp.c8
-rw-r--r--src/xwidget.c147
-rw-r--r--src/xwidget.h1
3 files changed, 47 insertions, 109 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index 6fed6287496..f466fae8574 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -4080,7 +4080,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4080 Lisp_Object location, value; 4080 Lisp_Object location, value;
4081 struct text_pos start_pos, save_pos; 4081 struct text_pos start_pos, save_pos;
4082 int valid_p; 4082 int valid_p;
4083 printf("handle_single_display_spec:\n"); 4083 //printf("handle_single_display_spec:\n");
4084 4084
4085 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM. 4085 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4086 If the result is non-nil, use VALUE instead of SPEC. */ 4086 If the result is non-nil, use VALUE instead of SPEC. */
@@ -4365,14 +4365,14 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4365 LOCATION specifies where to display: `left-margin', 4365 LOCATION specifies where to display: `left-margin',
4366 `right-margin' or nil. */ 4366 `right-margin' or nil. */
4367 4367
4368 4368 /*
4369 printf("handle_single_display_spec xwidgetp:%d imagep:%d spacep:%d display_replaced_before_p:%d stringp:%d\n", 4369 printf("handle_single_display_spec xwidgetp:%d imagep:%d spacep:%d display_replaced_before_p:%d stringp:%d\n",
4370 XWIDGETP(value), 4370 XWIDGETP(value),
4371 valid_image_p (value), 4371 valid_image_p (value),
4372 (CONSP (value) && EQ (XCAR (value), Qspace)), 4372 (CONSP (value) && EQ (XCAR (value), Qspace)),
4373 display_replaced_before_p, 4373 display_replaced_before_p,
4374 STRINGP (value)); 4374 STRINGP (value));
4375 4375 */
4376 valid_p = (STRINGP (value) 4376 valid_p = (STRINGP (value)
4377#ifdef HAVE_WINDOW_SYSTEM 4377#ifdef HAVE_WINDOW_SYSTEM
4378 || (FRAME_WINDOW_P (it->f) && valid_image_p (value)) 4378 || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
@@ -4422,7 +4422,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4422 } 4422 }
4423 else if (XWIDGETP(value)) 4423 else if (XWIDGETP(value))
4424 { 4424 {
4425 printf("handle_single_display_spec: im an xwidget!!\n"); 4425 //printf("handle_single_display_spec: im an xwidget!!\n");
4426 it->what = IT_XWIDGET; 4426 it->what = IT_XWIDGET;
4427 it->method = GET_FROM_XWIDGET; 4427 it->method = GET_FROM_XWIDGET;
4428 it->position = start_pos; 4428 it->position = start_pos;
diff --git a/src/xwidget.c b/src/xwidget.c
index 98b861ca401..3047a400cb9 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -96,6 +96,11 @@ extern Lisp_Object QCwidth, QCheight;
96 96
97#define XG_XWIDGET "emacs_xwidget" 97#define XG_XWIDGET "emacs_xwidget"
98 98
99int
100xwidget_hidden(struct xwidget *xw)
101{
102 return xw->hidden;
103}
99 104
100 105
101static void 106static void
@@ -184,14 +189,11 @@ xwidget_show (struct xwidget *xw)
184 189
185 190
186static gboolean 191static gboolean
187xwidget_composite_draw_2(GtkWidget *widget, 192xwidget_composite_draw_phantom(struct xwidget* xw,
188 GdkEventExpose *event, 193 int x, int y,
189 gpointer data, 194 int clipx, int clipy)
190 int x, int y,
191 int phantom)
192{ 195{
193 FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (widget), XG_FRAME_DATA); 196 FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (xw->widget), XG_FRAME_DATA);
194 struct xwidget* xw = (struct xwidget*) g_object_get_data (G_OBJECT (widget), XG_XWIDGET);
195 //////////////////////////////////////////////////////////////// 197 ////////////////////////////////////////////////////////////////
196 //Example 7. Composited windows 198 //Example 7. Composited windows
197 GdkRegion *region; 199 GdkRegion *region;
@@ -199,24 +201,23 @@ xwidget_composite_draw_2(GtkWidget *widget,
199 cairo_t *cr; 201 cairo_t *cr;
200 printf("xwidget_composite_draw_2 at:%d %d\n", x,y); 202 printf("xwidget_composite_draw_2 at:%d %d\n", x,y);
201 /* get our child (in this case, the event box) */ 203 /* get our child (in this case, the event box) */
202 child = widget; //gtk_bin_get_child (GTK_BIN (widget)); 204 child = xw->widget; //gtk_bin_get_child (GTK_BIN (widget));
203 /* create a cairo context to draw to the emacs window */ 205 /* create a cairo context to draw to the emacs window */
204 // cr = gdk_cairo_create (gtk_widget_get_window (f->gwfixed));//GTK_WIDGET(xw->emacswindow));//xw->widgetwindow));//widget->window); 206 // cr = gdk_cairo_create (gtk_widget_get_window (f->gwfixed));//GTK_WIDGET(xw->emacswindow));//xw->widgetwindow));//widget->window);
205 cr = gdk_cairo_create (gtk_widget_get_window (phantom ? f->gwfixed : xw->widgetwindow));//GTK_WIDGET(xw->emacswindow));//));//widget->window); 207 cr = gdk_cairo_create (gtk_widget_get_window (f->gwfixed));//GTK_WIDGET(xw->emacswindow));//));//widget->window);
206 /* the source data is the (composited) xwidget */ 208 /* the source data is the (composited) xwidget */
207 //cairo_move_to(cr, xw->x, xw->y); 209 //cairo_move_to(cr, xw->x, xw->y);
208 210
209 if(phantom){ 211 cairo_rectangle(cr, x,y, clipx, clipy);
210 cairo_rectangle(cr, x,y, xw->width, xw->height);
211 cairo_clip(cr); 212 cairo_clip(cr);
212 213
213 cairo_set_source_rgb(cr,1.0,0,0); 214 cairo_set_source_rgb(cr,1.0,0,0);
214 cairo_rectangle(cr,x,y,xw->width,xw->height); 215 cairo_rectangle(cr,x,y,xw->width,xw->height);
215 cairo_fill(cr); 216 cairo_fill(cr);
216 } 217
217 gdk_cairo_set_source_pixmap (cr, child->window, 218 gdk_cairo_set_source_pixmap (cr, child->window,
218 phantom ? x : 0,//child->allocation.x, 219 x,//child->allocation.x,
219 phantom ? y : 0//child->allocation.y 220 y//child->allocation.y
220 ); 221 );
221 /* draw no more than our expose event intersects our child */ 222 /* draw no more than our expose event intersects our child */
222 /* region = gdk_region_rectangle (&child->allocation); 223 /* region = gdk_region_rectangle (&child->allocation);
@@ -266,8 +267,10 @@ xwidget_composite_draw_widgetwindow(GtkWidget *widget,
266 cairo_t *cr; 267 cairo_t *cr;
267 GdkPixmap *pixmap; 268 GdkPixmap *pixmap;
268 pixmap=xw->widget->window; 269 pixmap=xw->widget->window;
269 270 printf("xwidget_composite_draw_widgetwindow xw.id:%d xw.type:%d window:%d\n", xw->id,xw->type, gtk_widget_get_window (widget));
270 cr = gdk_cairo_create (gtk_widget_get_window (widget)); 271 //if(xw->type!=3)//TODO this is just trial and terror to see if i can draw the live socket anywhere at all
272 cr = gdk_cairo_create (gtk_widget_get_window (widget));
273 //else cr = gdk_cairo_create (gtk_widget_get_window (xw->emacswindow));
271 cairo_rectangle(cr, 0,0, xw->width, xw->height); 274 cairo_rectangle(cr, 0,0, xw->width, xw->height);
272 cairo_clip(cr); 275 cairo_clip(cr);
273 276
@@ -307,7 +310,7 @@ xwidget_init (struct xwidget *xw, struct glyph_string *s, int x, int y)
307 xw->widget = gtk_socket_new (); 310 xw->widget = gtk_socket_new ();
308 //gtk_widget_set_app_paintable (xw->widget, TRUE); //workaround for composited sockets 311 //gtk_widget_set_app_paintable (xw->widget, TRUE); //workaround for composited sockets
309 GdkColor color; 312 GdkColor color;
310 gdk_color_parse("blue",&color); //the blue color never seems to show up. something else draw the bg 313 gdk_color_parse("blue",&color); //the blue color never seems to show up. something else draws a grey bg
311 gtk_widget_modify_bg(xw->widget, GTK_STATE_NORMAL, &color); 314 gtk_widget_modify_bg(xw->widget, GTK_STATE_NORMAL, &color);
312 g_signal_connect_after(xw->widget, "plug-added", G_CALLBACK(xwidget_plug_added), "plug added"); 315 g_signal_connect_after(xw->widget, "plug-added", G_CALLBACK(xwidget_plug_added), "plug added");
313 break; 316 break;
@@ -318,7 +321,7 @@ xwidget_init (struct xwidget *xw, struct glyph_string *s, int x, int y)
318 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 321 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
319 } 322 }
320 //widget realization 323 //widget realization
321 // mk container widget 1st, and put the widget inside 324 //make container widget 1st, and put the actual widget inside the container
322 //later, drawing should crop container window if necessary to handle case where xwidget 325 //later, drawing should crop container window if necessary to handle case where xwidget
323 //is partially obscured by other emacs windows 326 //is partially obscured by other emacs windows
324 xw->emacswindow = GTK_CONTAINER (s->f->gwfixed); 327 xw->emacswindow = GTK_CONTAINER (s->f->gwfixed);
@@ -340,6 +343,8 @@ xwidget_init (struct xwidget *xw, struct glyph_string *s, int x, int y)
340 //since the widget is no longer responsible for painting itself 343 //since the widget is no longer responsible for painting itself
341 if(xw->type!=3) //im having trouble with compositing and sockets. hmmm. 344 if(xw->type!=3) //im having trouble with compositing and sockets. hmmm.
342 gdk_window_set_composited (xw->widget->window, TRUE); 345 gdk_window_set_composited (xw->widget->window, TRUE);
346 gtk_widget_set_double_buffered (xw->widget,FALSE);
347 gtk_widget_set_double_buffered (xw->widgetwindow,FALSE);
343 //gdk_window_set_composited (xw->widgetwindow, TRUE); 348 //gdk_window_set_composited (xw->widgetwindow, TRUE);
344 //g_signal_connect_after(xw->widget, "expose-event", G_CALLBACK(xwidget_composite_draw), "widget exposed"); 349 //g_signal_connect_after(xw->widget, "expose-event", G_CALLBACK(xwidget_composite_draw), "widget exposed");
345 g_signal_connect_after(xw->widgetwindow, "expose-event", G_CALLBACK(xwidget_composite_draw_widgetwindow), "widgetwindow exposed"); 350 g_signal_connect_after(xw->widgetwindow, "expose-event", G_CALLBACK(xwidget_composite_draw_widgetwindow), "widgetwindow exposed");
@@ -354,82 +359,12 @@ xwidget_init (struct xwidget *xw, struct glyph_string *s, int x, int y)
354 gtk_socket_get_id (GTK_SOCKET (xw->widget))); 359 gtk_socket_get_id (GTK_SOCKET (xw->widget)));
355 send_xembed_ready_event (xw->id, 360 send_xembed_ready_event (xw->id,
356 gtk_socket_get_id (GTK_SOCKET (xw->widget))); 361 gtk_socket_get_id (GTK_SOCKET (xw->widget)));
362 //gtk_widget_realize(xw->widget);
357 break; 363 break;
358 } 364 }
359} 365}
360 366
361 367
362
363void
364xwidget_draw_phantom (struct xwidget *xw,
365 int x, int y,
366 int clipx, int clipy,
367 struct glyph_string *s,
368 int phantom)
369{
370 //we cant always get real widgets, so here we try to fetch a snapshot of
371 //the real xwidget and paint that as a phantom image. if that fails, we
372 //get an even simpler phantom(grey rectangle currently)
373
374 //this annoyingly doesnt work for gtk_sockets(but gtk_plug then? TODO research (probably doesnt work))
375 //another way is composition: http://ktown.kde.org/~fredrik/composite_howto.html
376 //but XCopyArea() might be sufficient for our needs here
377
378
379 GdkPixmap *xw_snapshot = NULL;
380 GdkGC *gdkgc = NULL;
381 GdkNativeWindow p_xid;
382 GdkWindow* xid;
383
384 /* if (xw->type == 3 && xwidget_has_composition()){
385 //its a gtk_socket, get_snapshot() doesnt work so try using composition methods
386 //xw_snapshot = gdk_pixmap_foreign_new_for_display(GDK_DISPLAY(), p_xid);
387 xid = gtk_socket_get_plug_window (GTK_SOCKET (xw->widget));
388 //should check the xid here, because it could be invalid
389 //p_xid = XCompositeNameWindowPixmap( GDK_DISPLAY (), GDK_WINDOW_XID(xid)) ;
390
391 printf("phantom socket 1: %d %d\n", xid, p_xid);
392 xw_snapshot = gdk_pixmap_foreign_new(GDK_WINDOW_XID(xid));
393 //wraps the native window in a gdk windw, this doesnt seem to benefit from compositing
394 printf("2\n");
395 }else {
396 //if its not a socket, its got a snapshot method that works
397 //or if we dont have composition well try for sockets, but probably get a grey rect
398 printf("phantom other\n");
399 xw_snapshot = gtk_widget_get_snapshot (xw->widget, NULL);
400 }
401 */
402#if 0
403 xw_snapshot=gdk_offscreen_window_get_pixmap(xw->widget->window);
404 if(xw_snapshot==NULL){
405 printf(" xw_snapshot null for some reason ... \n");
406 /* //return; */
407 }
408 gdkgc = gdk_gc_new (xw_snapshot);
409
410 //currently a phantom gets a line drawn across it to denote phantomness
411 //dimming or such would be more elegant, but we cant be bothered atm
412 gdk_draw_line (xw_snapshot, gdkgc, 0, 0, xw->width, xw->height);
413 gdk_draw_drawable (gtk_widget_get_window (s->f->gwfixed), //convert to GdkWindow from gtkWindow
414 gdkgc, xw_snapshot, 0, 0, x, y, clipx, clipy);
415#else
416
417 xwidget_composite_draw_2(xw->widget, NULL, NULL,x,y, phantom);
418#endif
419 ////////////////////////////////////////////////////////////////
420
421
422 //clean up here...
423}
424/* gtk widget reparent snippet to be used:
425 g_object_ref((gpointer)xw->widgetwindow);
426 gtk_container_remove(GTK_CONTAINER(old_parent), xw->widgetwindow);
427 gtk_container_add(GTK_CONTAINER(new_parent), xw->widgetwindow);
428 g_object_unrefref((gpointer)xw->widgetwindow);
429*/
430
431
432
433void 368void
434x_draw_xwidget_glyph_string (struct glyph_string *s) 369x_draw_xwidget_glyph_string (struct glyph_string *s)
435{ 370{
@@ -472,6 +407,7 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
472 int x = s->x; 407 int x = s->x;
473 int y = s->y + (s->height / 2) - (xw->height / 2); 408 int y = s->y + (s->height / 2) - (xw->height / 2);
474 int doingsocket = 0; 409 int doingsocket = 0;
410 int moved=0;
475 if (!xw->initialized) 411 if (!xw->initialized)
476 xwidget_init (xw, s, x, y); 412 xwidget_init (xw, s, x, y);
477 413
@@ -487,33 +423,39 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
487 // 3) if there was a live xwidget previously, now phantom it. 423 // 3) if there was a live xwidget previously, now phantom it.
488 if (drawing_in_selected_window) 424 if (drawing_in_selected_window)
489 { 425 {
490 if ((xw->x != x) || (xw->y != y)) //has it moved? 426 moved = (xw->x != x) || (xw->y != y);
427 if(moved)
428 printf ("live xwidget moved: id:%d (%d,%d)->(%d,%d)\n", xw->id, xw->x, xw->y, x, y);
429 //xw refers to the *live* instance of the xwidget, so only
430 //update coords when drawing in the selected window
431 xw->x = x;
432 xw->y = y;
433 if (moved) //has it moved?
491 { 434 {
492 printf ("live xwidget moved: id:%d (%d,%d)->(%d,%d)\n", xw->id, xw->x, xw->y, x, y);
493 if (!xwidget_hidden(xw)) //hidden equals not being seen in the live window 435 if (!xwidget_hidden(xw)) //hidden equals not being seen in the live window
494 { 436 {
495 gtk_fixed_move (GTK_FIXED (s->f->gwfixed), 437 gtk_fixed_move (GTK_FIXED (s->f->gwfixed),
496 GTK_WIDGET (xw->widgetwindow), x, y); 438 GTK_WIDGET (xw->widgetwindow), x, y);
497 //clip the widget window if some parts happen to be outside drawable area
498 //an emacs window is not a gtk window, a gtk window covers the entire frame
499 gtk_widget_set_size_request (GTK_WIDGET (xw->widgetwindow),
500 clipx, clipy);
501 } 439 }
502 } 440 }
441 //clip the widget window if some parts happen to be outside drawable area
442 //an emacs window is not a gtk window, a gtk window covers the entire frame
443 //cliping might have changed even if we havent actualy moved, we try figure out when we need to reclip for real
444 if((xw->clipx != clipx) || (xw->clipy != clipy))
445 gtk_widget_set_size_request (GTK_WIDGET (xw->widgetwindow),
446 clipx, clipy);
447 xw->clipx = clipx; xw->clipy = clipy;
503 //a live xwidget paints itself. when using composition, that 448 //a live xwidget paints itself. when using composition, that
504 //happens through the expose handler for the xwidget 449 //happens through the expose handler for the xwidget
450 //if emacs wants to repaint the area where the widget lives, queue a redraw
505 if (!xwidget_hidden(xw)) 451 if (!xwidget_hidden(xw))
506 gtk_widget_queue_draw (xw->widget); 452 gtk_widget_queue_draw (xw->widget);
507 //xw refers to the *live* instance of the xwidget, so only
508 //update coords when drawing in the selected window
509 xw->x = x;
510 xw->y = y;
511 } 453 }
512 else 454 else
513 { 455 {
514 //ok, we are painting the xwidgets in non-selected window, so draw a phantom 456 //ok, we are painting the xwidgets in non-selected window, so draw a phantom
515 //printf("draw phantom xwidget at:%d %d\n",x,y); 457 //printf("draw phantom xwidget at:%d %d\n",x,y);
516 xwidget_draw_phantom (xw, x, y, clipx, clipy, s, 1); 458 xwidget_composite_draw_phantom (xw, x, y, clipx, clipy);
517 } 459 }
518} 460}
519 461
@@ -832,11 +774,6 @@ xwidget_hide (struct xwidget *xw)
832 774
833 775
834 776
835int
836xwidget_hidden(struct xwidget *xw)
837{
838 return xw->hidden;
839}
840 777
841Lisp_Object 778Lisp_Object
842xwidget_spec_value ( 779xwidget_spec_value (
diff --git a/src/xwidget.h b/src/xwidget.h
index ac405fee12f..3852103d78d 100644
--- a/src/xwidget.h
+++ b/src/xwidget.h
@@ -27,6 +27,7 @@ struct xwidget{
27 Lisp_Object message_hook; 27 Lisp_Object message_hook;
28 int redisplayed; 28 int redisplayed;
29 GtkContainer* emacswindow; 29 GtkContainer* emacswindow;
30 int clipx; int clipy;
30}; 31};
31 32
32 33