diff options
| author | Joakim Verona | 2011-07-10 23:47:48 +0200 |
|---|---|---|
| committer | Joakim Verona | 2011-07-10 23:47:48 +0200 |
| commit | e098c552ccd4be2c05898bb69df97ce35efa90b7 (patch) | |
| tree | 11758196be04a6ec414100fd73419ffb582bde60 | |
| parent | d812bba65d7f22a624c8cc19e9ec21ffe3720228 (diff) | |
| download | emacs-e098c552ccd4be2c05898bb69df97ce35efa90b7.tar.gz emacs-e098c552ccd4be2c05898bb69df97ce35efa90b7.zip | |
minor cleanups and doc
| -rw-r--r-- | README.xwidget | 115 | ||||
| -rw-r--r-- | lisp/xwidget-screencast.el | 32 | ||||
| -rw-r--r-- | src/xwidget-attic.c | 229 | ||||
| -rw-r--r-- | src/xwidget.c | 57 |
4 files changed, 400 insertions, 33 deletions
diff --git a/README.xwidget b/README.xwidget index 8c4998cc960..068ffa01bed 100644 --- a/README.xwidget +++ b/README.xwidget | |||
| @@ -198,13 +198,62 @@ stuff that needs to work: | |||
| 198 | - lookup xw-view for xwidget in emacs window(during redisplay) | 198 | - lookup xw-view for xwidget in emacs window(during redisplay) |
| 199 | (- do something for all siblings of a xw-view. not atm) | 199 | (- do something for all siblings of a xw-view. not atm) |
| 200 | 200 | ||
| 201 | *** TODO xwidget creation interface | ||
| 202 | xwidgets are a little bit like emacs processes but also a little bit | ||
| 203 | like emacs images. Therefore its not perfectly obvious how to handle | ||
| 204 | creation. Currently I just use hardcoded identifiers. the real scheme | ||
| 205 | needs to be something else. | ||
| 206 | |||
| 207 | Heres a tentative approach: | ||
| 208 | - xwidget-create returns a xwidget object, like process creation | ||
| 209 | functions. the xwidget will be largely uninitialized until | ||
| 210 | discovered by redisplay. an xw belongs to a buffer | ||
| 211 | - xwidget-insert inserts the xwidget in a buffer. when discovered by | ||
| 212 | redisplay it will be initialized and a xwidget-view allocated | ||
| 213 | - an event will be emitted when initialization is finished when | ||
| 214 | relevant like for sockets | ||
| 215 | |||
| 216 | the problem with this aproach is that its not really legal to reuse | ||
| 217 | xwidget objects by writing several display specs who reference the | ||
| 218 | same xwidget. It could presumably be done but it would just become | ||
| 219 | weird for no real benefit. the big preblem is that the display spec | ||
| 220 | decides the on-screen size, and its not sane to have xwidget views | ||
| 221 | with different sizes. therefore such display specs would need to be | ||
| 222 | catched and dissallowed. Except it is hard because AFAIK the specs | ||
| 223 | don't have an identity as such. A flag in the structure could be set | ||
| 224 | by lookup so the first display attempt would win. but then you can't | ||
| 225 | rewrite the spec to change the size. hmmm. A third approach would be | ||
| 226 | to just allow the 1st spec refering an xw during a redisplay to take | ||
| 227 | effect, the rest are signaled as errors. this wouldnt be too bad. | ||
| 228 | |||
| 229 | the other aproach would be to work more like images: | ||
| 230 | |||
| 231 | - write the display spec with all information needed to create the | ||
| 232 | xwidget. | ||
| 233 | - retrieve the xwidget objet from the spec with an xwidget-at-point function. It | ||
| 234 | can be uninitalized which client code must handle. Unlike | ||
| 235 | assynchronous process creation we dont get back a handle, because | ||
| 236 | there is none yet. | ||
| 237 | - emitted event on initialization, when needed. Many widgets don't | ||
| 238 | need this. for instance, a button sends an event when pressed. but | ||
| 239 | you can't press it unless its on screen, and then its initialized | ||
| 240 | properly. | ||
| 241 | |||
| 242 | This approach seemed good, but how do I know which instance | ||
| 243 | generates an event if I cant set the id beforehand? | ||
| 244 | |||
| 245 | so, therefore, the first two aproach is used. | ||
| 246 | |||
| 247 | |||
| 248 | |||
| 201 | ** TODO more documentation | 249 | ** TODO more documentation |
| 202 | There should be user docs, and xwidget contributor docs. The current README | 250 | There should be user docs, and xwidget contributor docs. The current README |
| 203 | is all contributor docs there is now, apart from the code. | 251 | is all contributor docs there is now, apart from the code. |
| 204 | 252 | ||
| 205 | 253 | ||
| 206 | 254 | ||
| 207 | ** TODO look into more ways of displaying xwidgets, like binding them to a | 255 | ** CANCELLED look into more ways of displaying xwidgets, like binding them to a |
| 256 | CLOSED: [2011-07-05 Tue 11:34] | ||
| 208 | window rather than a point in a buffer. This was suggested by Chidong. | 257 | window rather than a point in a buffer. This was suggested by Chidong. |
| 209 | This would be a useful addition to Emacs in itself, and would avoid nearly all | 258 | This would be a useful addition to Emacs in itself, and would avoid nearly all |
| 210 | display issues. I still think the general case is more interesting, but this | 259 | display issues. I still think the general case is more interesting, but this |
| @@ -212,6 +261,9 @@ special case should also be added. The xwidget would then be bound to | |||
| 212 | replace the view of a particular window, and it would only show in | 261 | replace the view of a particular window, and it would only show in |
| 213 | that window. | 262 | that window. |
| 214 | 263 | ||
| 264 | I got the webkit xwidget to work well enough so I dont see the need | ||
| 265 | for this now, except for sockets and I think it can better be dealt | ||
| 266 | with at the lisp level. | ||
| 215 | 267 | ||
| 216 | ** DONE MVC mode for xwidgets | 268 | ** DONE MVC mode for xwidgets |
| 217 | CLOSED: [2011-06-27 Mon 12:53] | 269 | CLOSED: [2011-06-27 Mon 12:53] |
| @@ -298,10 +350,9 @@ make | |||
| 298 | 350 | ||
| 299 | 351 | ||
| 300 | ** TODO mvc code crashes after a while | 352 | ** TODO mvc code crashes after a while |
| 301 | seemingly only when compiling with optimizations | 353 | seemingly only when compiling with optimizations. |
| 354 | I have no idea why. | ||
| 302 | 355 | ||
| 303 | ** TODO delete xwidgets belonging to an emacs window | ||
| 304 | when it closes | ||
| 305 | ** TODO xwidget-resize-at | 356 | ** TODO xwidget-resize-at |
| 306 | currently it rewrites the display spec. then it resizes the xwidget | 357 | currently it rewrites the display spec. then it resizes the xwidget |
| 307 | views. maybe rewriting the spec should be sufficient, and changes to | 358 | views. maybe rewriting the spec should be sufficient, and changes to |
| @@ -349,7 +400,7 @@ webkitViewportAttributesRecompute is the offender. | |||
| 349 | 400 | ||
| 350 | maybe try gtk3 variants? | 401 | maybe try gtk3 variants? |
| 351 | 402 | ||
| 352 | export CFLAGS="`pkg-config --cflags webkitgtk-3.0 ` -DHAVE_WEBKIT_OSR -g" | 403 | export CFLAGS="`pkg-config --cflags webkitgtk-3.0 ` -DHAVE_WEBKIT_OSR " |
| 353 | export LDFLAGS=`pkg-config --libs webkitgtk-3.0 ` | 404 | export LDFLAGS=`pkg-config --libs webkitgtk-3.0 ` |
| 354 | ./configure --with-x-toolkit=gtk3 | 405 | ./configure --with-x-toolkit=gtk3 |
| 355 | make | 406 | make |
| @@ -420,6 +471,8 @@ interesting than just forwarding keyboard events. | |||
| 420 | 471 | ||
| 421 | webkit_web_view_get_dom_document () | 472 | webkit_web_view_get_dom_document () |
| 422 | 473 | ||
| 474 | this is hard it seems. an idea might be to hack elisp support for swig | ||
| 475 | to machine generate the bindings. | ||
| 423 | **** DONE inject javascript | 476 | **** DONE inject javascript |
| 424 | CLOSED: [2011-07-03 Sun 22:50] | 477 | CLOSED: [2011-07-03 Sun 22:50] |
| 425 | webkit_web_view_execute_script () | 478 | webkit_web_view_execute_script () |
| @@ -448,12 +501,32 @@ or this funny hack: | |||
| 448 | <jave> lucian: that was a pretty cool idea! | 501 | <jave> lucian: that was a pretty cool idea! |
| 449 | 502 | ||
| 450 | 503 | ||
| 451 | **** webkit_web_view_load_string () | 504 | *** webkit_web_view_load_string () |
| 452 | I would like preview of html in a buffer rather than from uri. | 505 | I would like preview of html in a buffer rather than from uri. |
| 453 | 506 | ||
| 454 | 507 | ||
| 455 | 508 | ||
| 456 | ** TODO clipping of controllers | 509 | *** TODO simple xwidget-webkit wrapper |
| 510 | so that it could be used for actual browsing :) | ||
| 511 | I dont want to reinvent too many wheels so i'd like to use existing | ||
| 512 | emacs facilities here possible. use bindings similar to w3m(or info) | ||
| 513 | |||
| 514 | - m-x xwidget-webkit starts a session | ||
| 515 | - 'g' goes to a url | ||
| 516 | - use bookmark-jump i suppose. I mostly use org for bookmarks myself | ||
| 517 | - browse-url support so webkit can be the default browser | ||
| 518 | - some way of getting around the quirky keyboard interaction since | ||
| 519 | xwidgets dont receive keyboard events because I hawe no idea how to | ||
| 520 | do that in a sane way | ||
| 521 | |||
| 522 | ... and one can of course go on bikeshedding forever. lets keep it | ||
| 523 | simple and extensible, and compatible with other Emacs packages. | ||
| 524 | |||
| 525 | the really cool ideas would need Emacs DOM integration, which is not | ||
| 526 | easy. | ||
| 527 | |||
| 528 | ** DONE clipping of controllers | ||
| 529 | CLOSED: [2011-07-05 Tue 11:33] | ||
| 457 | 530 | ||
| 458 | Emacs uses a big GTK window and does its own clipping against Emacs | 531 | Emacs uses a big GTK window and does its own clipping against Emacs |
| 459 | windows inside this area. So, in order to layout gtk widgets in emacs | 532 | windows inside this area. So, in order to layout gtk widgets in emacs |
| @@ -478,6 +551,7 @@ either. | |||
| 478 | 551 | ||
| 479 | http://www.lanedo.com/~carlos/gtk3-doc/chap-drawing-model.html | 552 | http://www.lanedo.com/~carlos/gtk3-doc/chap-drawing-model.html |
| 480 | 553 | ||
| 554 | anyway clipping is rather complicated but seems to finally work okay. | ||
| 481 | 555 | ||
| 482 | *** DONE subclass my own clipping widget | 556 | *** DONE subclass my own clipping widget |
| 483 | CLOSED: [2011-07-04 Mon 16:55] | 557 | CLOSED: [2011-07-04 Mon 16:55] |
| @@ -555,7 +629,8 @@ the needed data is private to the base class. to overcome this: | |||
| 555 | JanD pointed out the GTK3 port already has its own subclass, so I | 629 | JanD pointed out the GTK3 port already has its own subclass, so I |
| 556 | modified that one. | 630 | modified that one. |
| 557 | 631 | ||
| 558 | *** TODO clip top | 632 | *** DONE clip top |
| 633 | CLOSED: [2011-07-05 Tue 11:30] | ||
| 559 | there are four controller edges that potentialy need clipping. I begun | 634 | there are four controller edges that potentialy need clipping. I begun |
| 560 | with right and bottom edges. clipping them is just a matter of setting | 635 | with right and bottom edges. clipping them is just a matter of setting |
| 561 | the right size of the widgetwindow and also ensure it gets the right | 636 | the right size of the widgetwindow and also ensure it gets the right |
| @@ -569,9 +644,20 @@ makes it harder to use the allocation workarounds. | |||
| 569 | see: | 644 | see: |
| 570 | - gtk_widget_set_size_request | 645 | - gtk_widget_set_size_request |
| 571 | - gtkscrolledwindow | 646 | - gtkscrolledwindow |
| 572 | ** TODO use FRAME_GTK_WIDGET (f) | ||
| 573 | rather than gwfixed | ||
| 574 | 647 | ||
| 648 | I returned to using a simple gtkfixed for the widgetwindow. with | ||
| 649 | allocation hack and set_has_window it works. Idea prefer not to have | ||
| 650 | the allocatien hack and it wasnt needed it gtk3 only gtk2. needs | ||
| 651 | furthi investigation, | ||
| 652 | |||
| 653 | ** TODO various code cleanups | ||
| 654 | There are many cleanups necessary before any hope of inclusion in | ||
| 655 | Emacs trunk. To begin with, the part of the patch that touches other | ||
| 656 | parts of emacs must be very clean. | ||
| 657 | *** TODO use FRAME_GTK_WIDGET (f) | ||
| 658 | rather than gwfixed. | ||
| 659 | |||
| 660 | *** TODO support configure | ||
| 575 | ** DONE translate clicks | 661 | ** DONE translate clicks |
| 576 | CLOSED: [2011-07-03 Sun 22:12] | 662 | CLOSED: [2011-07-03 Sun 22:12] |
| 577 | on onscreen webkit peer to offscreen | 663 | on onscreen webkit peer to offscreen |
| @@ -584,18 +670,21 @@ forwarded them offscreen! | |||
| 584 | 670 | ||
| 585 | ** TODO investigate gdk_window_redirect_to_drawable | 671 | ** TODO investigate gdk_window_redirect_to_drawable |
| 586 | http://developer.gnome.org/gdk/stable/gdk-Windows.html#gdk-offscreen-window-set-embedder | 672 | http://developer.gnome.org/gdk/stable/gdk-Windows.html#gdk-offscreen-window-set-embedder |
| 587 | maybe control be used in place of my own copy hacks? | 673 | maybe control be used in place of my own copy hacks? to work it must |
| 674 | support a chain of redirects, which seems unlikely. the benefit would | ||
| 675 | be that I dont have to spend time optimizing redrawing. | ||
| 588 | 676 | ||
| 589 | 677 | ||
| 590 | 678 | ||
| 591 | ** TODO remove xwidget_views when emacs window is deleted | 679 | ** DONE remove xwidget_views when emacs window is deleted |
| 680 | CLOSED: [2011-07-05 Tue 11:29] | ||
| 592 | removing xwidget views when an Emacs window closes is not reliable. | 681 | removing xwidget views when an Emacs window closes is not reliable. |
| 593 | 682 | ||
| 594 | - switching buffers in a window seems to hide the corresponding | 683 | - switching buffers in a window seems to hide the corresponding |
| 595 | xwidget-views properly, but they might as well be deleted. | 684 | xwidget-views properly, but they might as well be deleted. |
| 596 | 685 | ||
| 597 | - patching delete-window-internal could be used to delete the xwidget-views | 686 | - patching delete-window-internal could be used to delete the xwidget-views |
| 598 | 687 | this seems to work | |
| 599 | 688 | ||
| 600 | 689 | ||
| 601 | ** notes from x_draw_xwidget_glyph_string | 690 | ** notes from x_draw_xwidget_glyph_string |
diff --git a/lisp/xwidget-screencast.el b/lisp/xwidget-screencast.el new file mode 100644 index 00000000000..f85dbe8f247 --- /dev/null +++ b/lisp/xwidget-screencast.el | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | ;;(require 'screencast) | ||
| 2 | (require 'xwidget) | ||
| 3 | (defconst xwidget-screencast-webkit '("Hello, and welcome to a | ||
| 4 | short demo of the Emacs xwidget branch, and the Webkit | ||
| 5 | integration it provides." n | ||
| 6 | "Xwidgets are toolkit widgets that behave like images in an | ||
| 7 | Emacs buffer. Except they are actual widgets, so you can | ||
| 8 | interact with them." n | ||
| 9 | "There are several, but people seem to fancy the webkit the most so lets have a look!" | ||
| 10 | (insert "some text") | ||
| 11 | (xwidget-insert (point-min) 'webkit-osr "webkit-osr" 500 1000 5) | ||
| 12 | n | ||
| 13 | "Okay so thats an actual webkit instance in an Emacs buffer! " n | ||
| 14 | "Mouse-overs work" n | ||
| 15 | "Mouse-clicks work" n | ||
| 16 | (split-window-vertically) | ||
| 17 | "You can split the buffer and scroll the windows separately, as | ||
| 18 | usual in Emacs. This is however not so usual in the browser | ||
| 19 | world for some reason." n | ||
| 20 | "So, can you use the xwidget branch as your main Emacs instance?"n | ||
| 21 | "Not yet, its still not mature. There are many tricky issues | ||
| 22 | left. That being said, there are many simple tasks to help out | ||
| 23 | with also if you like!" )) | ||
| 24 | |||
| 25 | |||
| 26 | (defun xwidget-screencast(&optional arg) | ||
| 27 | "Displays the screencast for xwidgets." | ||
| 28 | (interactive "P") | ||
| 29 | (apply (if arg | ||
| 30 | 'screencast-record | ||
| 31 | 'screencast) | ||
| 32 | xwidget-screencast-webkit "xvidgets" 1 ())) | ||
diff --git a/src/xwidget-attic.c b/src/xwidget-attic.c new file mode 100644 index 00000000000..84844587051 --- /dev/null +++ b/src/xwidget-attic.c | |||
| @@ -0,0 +1,229 @@ | |||
| 1 | static int once = 0; | ||
| 2 | |||
| 3 | int | ||
| 4 | xwidget_has_composition(void){ //unused | ||
| 5 | int event_base, error_base; | ||
| 6 | Display* dpy = GDK_DISPLAY (); | ||
| 7 | int i; | ||
| 8 | if(xwidget_query_composition_called) | ||
| 9 | return hasNamePixmap; | ||
| 10 | xwidget_query_composition_called = 1; | ||
| 11 | |||
| 12 | //do this once in an emacs session | ||
| 13 | |||
| 14 | if(gdk_display_supports_composite(gdk_display_get_default ())){ | ||
| 15 | hasNamePixmap = 1; | ||
| 16 | }else{ | ||
| 17 | return 0; | ||
| 18 | } | ||
| 19 | return 1; | ||
| 20 | } | ||
| 21 | |||
| 22 | |||
| 23 | |||
| 24 | |||
| 25 | |||
| 26 | void | ||
| 27 | xwidget_end_composition(struct xwidget* w){ //unused | ||
| 28 | //XCompositeUnredirectWindow(); stop redirecting, should be called when the socket is destroyed | ||
| 29 | } | ||
| 30 | |||
| 31 | |||
| 32 | static gboolean | ||
| 33 | xwidget_composite_draw_phantom(struct xwidget* xw, | ||
| 34 | int x, int y, | ||
| 35 | int clipx, int clipy) | ||
| 36 | { | ||
| 37 | FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (xw->widget), XG_FRAME_DATA); | ||
| 38 | //////////////////////////////////////////////////////////////// | ||
| 39 | //Example 7. Composited windows | ||
| 40 | GdkRegion *region; | ||
| 41 | GtkWidget *child; | ||
| 42 | cairo_t *cr; | ||
| 43 | printf("xwidget_composite_draw_2 at:%d %d\n", x,y); | ||
| 44 | /* get our child (in this case, the event box) */ | ||
| 45 | child = xw->widget; //gtk_bin_get_child (GTK_BIN (widget)); | ||
| 46 | /* create a cairo context to draw to the emacs window */ | ||
| 47 | // cr = gdk_cairo_create (gtk_widget_get_window (f->gwfixed));//GTK_WIDGET(xw->emacswindow));//xw->widgetwindow));//widget->window); | ||
| 48 | cr = gdk_cairo_create (gtk_widget_get_window (f->gwfixed));//GTK_WIDGET(xw->emacswindow));//));//widget->window); | ||
| 49 | /* the source data is the (composited) xwidget */ | ||
| 50 | //cairo_move_to(cr, xw->x, xw->y); | ||
| 51 | |||
| 52 | cairo_rectangle(cr, x,y, clipx, clipy); | ||
| 53 | cairo_clip(cr); | ||
| 54 | |||
| 55 | cairo_set_source_rgb(cr,1.0,0,0); | ||
| 56 | cairo_rectangle(cr,x,y,xw->width,xw->height); | ||
| 57 | cairo_fill(cr); | ||
| 58 | |||
| 59 | gdk_cairo_set_source_pixmap (cr, child->window, | ||
| 60 | x,//child->allocation.x, | ||
| 61 | y//child->allocation.y | ||
| 62 | ); | ||
| 63 | /* draw no more than our expose event intersects our child */ | ||
| 64 | /* region = gdk_region_rectangle (&child->allocation); | ||
| 65 | gdk_region_intersect (region, event->region); | ||
| 66 | gdk_cairo_region (cr, region); | ||
| 67 | cairo_clip (cr); */ | ||
| 68 | /* composite, with a 50% opacity */ | ||
| 69 | cairo_set_operator (cr, CAIRO_OPERATOR_OVER); | ||
| 70 | //cairo_paint_with_alpha (cr, phantom ? 0.5 : 0); | ||
| 71 | cairo_paint_with_alpha (cr, 0.9); | ||
| 72 | //cairo_paint(cr);//transparency); | ||
| 73 | /* we're done */ | ||
| 74 | cairo_destroy (cr); | ||
| 75 | return FALSE; | ||
| 76 | } | ||
| 77 | |||
| 78 | |||
| 79 | |||
| 80 | /* | ||
| 81 | static gboolean | ||
| 82 | xwidget_composite_draw(GtkWidget *widget, | ||
| 83 | GdkEventExpose *event, | ||
| 84 | gpointer data) | ||
| 85 | { | ||
| 86 | struct xwidget* xw = (struct xwidget*) g_object_get_data (G_OBJECT (widget), XG_XWIDGET); | ||
| 87 | printf("xwidget_composite_draw %s\n", data); | ||
| 88 | xwidget_composite_draw_2(widget, | ||
| 89 | event, | ||
| 90 | data, | ||
| 91 | xw->x, xw->y, 0); | ||
| 92 | return FALSE; | ||
| 93 | } | ||
| 94 | */ | ||
| 95 | |||
| 96 | |||
| 97 | static gboolean | ||
| 98 | xwidget_composite_draw_widgetwindow(GtkWidget *widget, | ||
| 99 | GdkEventExpose *event, | ||
| 100 | gpointer data) | ||
| 101 | { | ||
| 102 | struct xwidget* xw = (struct xwidget*) g_object_get_data (G_OBJECT (widget), XG_XWIDGET); | ||
| 103 | cairo_t *cr; | ||
| 104 | GdkPixmap *pixmap; | ||
| 105 | pixmap=xw->widget->window; | ||
| 106 | printf("xwidget_composite_draw_widgetwindow xw.id:%d xw.type:%d window:%d\n", xw->id,xw->type, gtk_widget_get_window (widget)); | ||
| 107 | //if(xw->type!=3)//TODO this is just trial and terror to see if i can draw the live socket anywhere at all | ||
| 108 | cr = gdk_cairo_create (gtk_widget_get_window (widget));//GTK_LAYOUT (xw->widgetwindow)->bin_window);// | ||
| 109 | //else cr = gdk_cairo_create (gtk_widget_get_window (xw->emacswindow)); | ||
| 110 | cairo_rectangle(cr, 0,0, xw->width, xw->height); | ||
| 111 | cairo_clip(cr); | ||
| 112 | |||
| 113 | cairo_set_source_rgb(cr,0,1.0,0); | ||
| 114 | cairo_rectangle(cr, 0,0, xw->width, xw->height); | ||
| 115 | cairo_fill(cr); | ||
| 116 | gdk_cairo_set_source_pixmap (cr, pixmap, | ||
| 117 | 0,0); | ||
| 118 | |||
| 119 | cairo_set_operator (cr, CAIRO_OPERATOR_OVER); | ||
| 120 | cairo_paint_with_alpha (cr, 0.9); | ||
| 121 | //cairo_paint(cr); | ||
| 122 | cairo_destroy (cr); | ||
| 123 | |||
| 124 | return FALSE; | ||
| 125 | } | ||
| 126 | |||
| 127 | |||
| 128 | //type support nevermind for now | ||
| 129 | |||
| 130 | /* /\* List of supported image types. Use define_image_type to add new */ | ||
| 131 | /* types. Use lookup_image_type to find a type for a given symbol. *\/ */ | ||
| 132 | |||
| 133 | /* static struct wxidget_type *wxidget_types; */ | ||
| 134 | |||
| 135 | /* /\* Look up xwidget type SYMBOL, and return a pointer to its xwidget_type */ | ||
| 136 | /* structure. Value is null if SYMBOL is not a known image type. *\/ */ | ||
| 137 | |||
| 138 | /* static INLINE struct xwidget_type *lookup_xwidget_type (Lisp_Object symbol) */ | ||
| 139 | /* { */ | ||
| 140 | /* struct xwidget_type *type; */ | ||
| 141 | |||
| 142 | /* for (type = xwidget_types; type; type = type->next) */ | ||
| 143 | /* if (EQ (symbol, *type->type)) */ | ||
| 144 | /* break; */ | ||
| 145 | |||
| 146 | /* return type; */ | ||
| 147 | /* } */ | ||
| 148 | |||
| 149 | |||
| 150 | //////////////////////////////////////////////////////////////// | ||
| 151 | |||
| 152 | /* delete the xwidget and its native widget peer(unused) */ | ||
| 153 | void xwidget_delete(struct xwidget* xw); | ||
| 154 | |||
| 155 | |||
| 156 | void | ||
| 157 | xwidget_delete (struct xwidget *xw) | ||
| 158 | { | ||
| 159 | printf ("xwidget %d deleted\n", xw->id); | ||
| 160 | xw->initialized = 0; | ||
| 161 | gtk_widget_destroy (xw->widget); | ||
| 162 | |||
| 163 | } | ||
| 164 | |||
| 165 | |||
| 166 | /* redraw all xwidgets(unused) */ | ||
| 167 | void | ||
| 168 | xwidget_invalidate (void) | ||
| 169 | { | ||
| 170 | int i; | ||
| 171 | struct xwidget *xw; | ||
| 172 | printf ("invalidate "); | ||
| 173 | for (i = 0; i < MAX_XWIDGETS; i++) | ||
| 174 | { | ||
| 175 | xw = &xwidgets[i]; | ||
| 176 | if (xw->initialized) | ||
| 177 | { | ||
| 178 | printf ("%d,", i); | ||
| 179 | gtk_widget_queue_draw_area (xw->widget, 0, 0, xw->width, | ||
| 180 | xw->height); | ||
| 181 | } | ||
| 182 | } | ||
| 183 | printf ("\n"); | ||
| 184 | } | ||
| 185 | |||
| 186 | |||
| 187 | /* initializes the xwidget model */ | ||
| 188 | void | ||
| 189 | xwidget_init_model (struct xwidget *xw, | ||
| 190 | struct glyph_string *s, | ||
| 191 | int x, int y) | ||
| 192 | { | ||
| 193 | xw->id = s->xwidget_id; | ||
| 194 | xw->initialized = 1; | ||
| 195 | } | ||
| 196 | |||
| 197 | |||
| 198 | |||
| 199 | DEFUN ("xwidget-replug", Fxwidget_replug, Sxwidget_replug, 2, 2, 0, | ||
| 200 | doc: /* unplug from socket1 plug into socket2.*/ | ||
| 201 | ) | ||
| 202 | (Lisp_Object old_parent, Lisp_Object new_parent) | ||
| 203 | { | ||
| 204 | |||
| 205 | struct xwidget *xw1; | ||
| 206 | struct xwidget *xw2; | ||
| 207 | |||
| 208 | |||
| 209 | GtkWidget* widget; | ||
| 210 | CHECK_NUMBER (old_parent); | ||
| 211 | CHECK_NUMBER (new_parent); | ||
| 212 | |||
| 213 | xw1 = &xwidgets[XFASTINT (old_parent)]; | ||
| 214 | xw2 = &xwidgets[XFASTINT (new_parent)]; | ||
| 215 | |||
| 216 | |||
| 217 | ///this wasnt thought through. we need the views rather than the model. | ||
| 218 | //so we need to map xw+w to xv | ||
| 219 | |||
| 220 | widget = xw1->widget->gtk_socket_get_plug_window (); | ||
| 221 | |||
| 222 | //the plug... | ||
| 223 | gtk_widget_ref(widget);//...gets an xtra ref to prevent garb, then it ... | ||
| 224 | gtk_container_remove(GTK_CONTAINER(xw1->widget), widget);//...is uplugged from old socket and... | ||
| 225 | gtk_container_add(GTK_CONTAINER(xw2->widget), widget);//...replugged in new socket... | ||
| 226 | gtk_widget_unref(widget);//...and lastly remove the ref | ||
| 227 | |||
| 228 | return Qnil; | ||
| 229 | } | ||
diff --git a/src/xwidget.c b/src/xwidget.c index 57243832ce3..6c712d1d707 100644 --- a/src/xwidget.c +++ b/src/xwidget.c | |||
| @@ -90,8 +90,11 @@ | |||
| 90 | #endif | 90 | #endif |
| 91 | 91 | ||
| 92 | 92 | ||
| 93 | #include <wchar.h> | ||
| 94 | |||
| 93 | #ifdef HAVE_WEBKIT | 95 | #ifdef HAVE_WEBKIT |
| 94 | #include <webkitgtk.h> | 96 | #include <webkitgtk.h> |
| 97 | |||
| 95 | #endif | 98 | #endif |
| 96 | 99 | ||
| 97 | 100 | ||
| @@ -412,15 +415,10 @@ xwidget_osr_button_callback ( GtkWidget *widget, | |||
| 412 | GdkEvent *event, | 415 | GdkEvent *event, |
| 413 | gpointer user_data) | 416 | gpointer user_data) |
| 414 | { | 417 | { |
| 415 | gdouble x, y; | ||
| 416 | struct xwidget* xw = (struct xwidget*) g_object_get_data (G_OBJECT (widget), XG_XWIDGET); | 418 | struct xwidget* xw = (struct xwidget*) g_object_get_data (G_OBJECT (widget), XG_XWIDGET); |
| 417 | GdkEventButton* eventcopy = gdk_event_copy(event); | 419 | GdkEvent* eventcopy = gdk_event_copy(event); |
| 418 | x = ((GdkEventButton*)event)->x; | ||
| 419 | y = ((GdkEventButton*)event)->y; | ||
| 420 | |||
| 421 | printf ("button callback %d %d\n",x,y); | ||
| 422 | 420 | ||
| 423 | eventcopy->window = gtk_widget_get_window(xw->widget_osr); | 421 | ((GdkEventButton*)eventcopy)->window = gtk_widget_get_window(xw->widget_osr); |
| 424 | gtk_main_do_event(eventcopy); //TODO this will leak events. they should be deallocated later | 422 | gtk_main_do_event(eventcopy); //TODO this will leak events. they should be deallocated later |
| 425 | } | 423 | } |
| 426 | 424 | ||
| @@ -620,7 +618,7 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) | |||
| 620 | { | 618 | { |
| 621 | /* | 619 | /* |
| 622 | this method is called by the redisplay engine and places the xwidget on screen. | 620 | this method is called by the redisplay engine and places the xwidget on screen. |
| 623 | moving and clpping | 621 | moving and clipping is done here. also view init. |
| 624 | 622 | ||
| 625 | */ | 623 | */ |
| 626 | int box_line_hwidth = eabs (s->face->box_line_width); | 624 | int box_line_hwidth = eabs (s->face->box_line_width); |
| @@ -676,7 +674,7 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) | |||
| 676 | || (xv->clip_top != clip_top) | 674 | || (xv->clip_top != clip_top) |
| 677 | || (xv->clip_left != clip_left)){ | 675 | || (xv->clip_left != clip_left)){ |
| 678 | gtk_widget_set_size_request (GTK_WIDGET (xv->widgetwindow), clip_right + clip_left, clip_bottom + clip_top); | 676 | gtk_widget_set_size_request (GTK_WIDGET (xv->widgetwindow), clip_right + clip_left, clip_bottom + clip_top); |
| 679 | gtk_fixed_put(GTK_FIXED(xv->widgetwindow), xv->widget, -clip_left, -clip_top); | 677 | gtk_fixed_move(GTK_FIXED(xv->widgetwindow), xv->widget, -clip_left, -clip_top); |
| 680 | printf("reclip %d %d -> %d %d clip_top:%d clip_left:%d\n",xv->clip_right, xv->clip_bottom, clip_right, clip_bottom, clip_top , clip_left); | 678 | printf("reclip %d %d -> %d %d clip_top:%d clip_left:%d\n",xv->clip_right, xv->clip_bottom, clip_right, clip_bottom, clip_top , clip_left); |
| 681 | 679 | ||
| 682 | 680 | ||
| @@ -684,7 +682,7 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) | |||
| 684 | } | 682 | } |
| 685 | //if emacs wants to repaint the area where the widget lives, queue a redraw | 683 | //if emacs wants to repaint the area where the widget lives, queue a redraw |
| 686 | if (!xwidget_hidden(xv)){ | 684 | if (!xwidget_hidden(xv)){ |
| 687 | gtk_widget_queue_draw (xv->widgetwindow); | 685 | gtk_widget_queue_draw (GTK_WIDGET(xv->widgetwindow)); |
| 688 | gtk_widget_queue_draw (xv->widget); | 686 | gtk_widget_queue_draw (xv->widget); |
| 689 | } | 687 | } |
| 690 | } | 688 | } |
| @@ -730,7 +728,7 @@ DEFUN ("xwidget-webkit-get-title", Fxwidget_webkit_get_title, Sxwidget_webkit_g | |||
| 730 | { | 728 | { |
| 731 | //TODO support multibyte strings | 729 | //TODO support multibyte strings |
| 732 | const gchar* str=webkit_web_view_get_title( WEBKIT_WEB_VIEW(xid2xw(xwidget_id)->widget_osr)); | 730 | const gchar* str=webkit_web_view_get_title( WEBKIT_WEB_VIEW(xid2xw(xwidget_id)->widget_osr)); |
| 733 | return make_string_from_bytes(str, wcslen(str), strlen(str)); | 731 | return make_string_from_bytes(str, wcslen((const wchar_t *)str), strlen(str)); |
| 734 | } | 732 | } |
| 735 | 733 | ||
| 736 | 734 | ||
| @@ -798,18 +796,37 @@ DEFUN("xwidget-info", Fxwidget_info , Sxwidget_info, 1,1,0, doc: /* get xwidget | |||
| 798 | struct xwidget *xw = xid2xw(xwidget_id); | 796 | struct xwidget *xw = xid2xw(xwidget_id); |
| 799 | Lisp_Object info; | 797 | Lisp_Object info; |
| 800 | 798 | ||
| 801 | info = Fmake_vector (make_number (7), Qnil); | 799 | info = Fmake_vector (make_number (4), Qnil); |
| 802 | XVECTOR (info)->contents[0] = make_number(xw->id); | 800 | XVECTOR (info)->contents[0] = make_number(xw->id); |
| 803 | XVECTOR (info)->contents[1] = make_number(xw->type); | 801 | XVECTOR (info)->contents[1] = xw->type; |
| 804 | XVECTOR (info)->contents[2] = Qnil; //make_number(xw->x); | 802 | XVECTOR (info)->contents[2] = make_number(xw->width); |
| 805 | XVECTOR (info)->contents[3] = Qnil;//make_number(xw->y); | 803 | XVECTOR (info)->contents[3] = make_number(xw->height); |
| 806 | XVECTOR (info)->contents[4] = make_number(xw->width); | 804 | |
| 807 | XVECTOR (info)->contents[5] = make_number(xw->height); | 805 | |
| 808 | XVECTOR (info)->contents[6] = Qnil;//make_number(xw->hidden); | 806 | return info; |
| 807 | } | ||
| 808 | |||
| 809 | DEFUN("xwidget-view-info", Fxwidget_view_info , Sxwidget_view_info, 2,2,0, doc: /* get xwidget view props */) | ||
| 810 | (Lisp_Object xwidget_id, Lisp_Object window) | ||
| 811 | { | ||
| 812 | struct xwidget *xw = xid2xw(xwidget_id); | ||
| 813 | struct xwidget_view* xv = xwidget_view_lookup(xw, XWINDOW(window)); | ||
| 814 | |||
| 815 | Lisp_Object info; | ||
| 816 | |||
| 817 | info = Fmake_vector (make_number (6), Qnil); | ||
| 818 | XVECTOR (info)->contents[0] = make_number(xv->x); | ||
| 819 | XVECTOR (info)->contents[1] = make_number(xv->y); | ||
| 820 | XVECTOR (info)->contents[2] = make_number(xv->clip_right); | ||
| 821 | XVECTOR (info)->contents[3] = make_number(xv->clip_bottom); | ||
| 822 | XVECTOR (info)->contents[4] = make_number(xv->clip_top); | ||
| 823 | XVECTOR (info)->contents[5] = make_number(xv->clip_left); | ||
| 809 | 824 | ||
| 810 | return info; | 825 | return info; |
| 811 | } | 826 | } |
| 812 | 827 | ||
| 828 | |||
| 829 | |||
| 813 | //xterm.c listens to xwidget_owns_kbd and tries to not eat events when its set | 830 | //xterm.c listens to xwidget_owns_kbd and tries to not eat events when its set |
| 814 | int xwidget_owns_kbd = 0; | 831 | int xwidget_owns_kbd = 0; |
| 815 | DEFUN ("xwidget-set-keyboard-grab", Fxwidget_set_keyboard_grab, Sxwidget_set_keyboard_grab, 2, 2, 0, doc: /* set unset kbd grab for xwidget. */ | 832 | DEFUN ("xwidget-set-keyboard-grab", Fxwidget_set_keyboard_grab, Sxwidget_set_keyboard_grab, 2, 2, 0, doc: /* set unset kbd grab for xwidget. */ |
| @@ -938,6 +955,7 @@ syms_of_xwidget (void) | |||
| 938 | defsubr (&Sxwidget_send_keyboard_event); | 955 | defsubr (&Sxwidget_send_keyboard_event); |
| 939 | defsubr (&Sxwidget_embed_steal_window); | 956 | defsubr (&Sxwidget_embed_steal_window); |
| 940 | defsubr (&Sxwidget_info); | 957 | defsubr (&Sxwidget_info); |
| 958 | defsubr (&Sxwidget_view_info); | ||
| 941 | defsubr (&Sxwidget_resize_internal); | 959 | defsubr (&Sxwidget_resize_internal); |
| 942 | defsubr (&Sxwidget_embed_steal_window); | 960 | defsubr (&Sxwidget_embed_steal_window); |
| 943 | 961 | ||
| @@ -1050,12 +1068,11 @@ xwidget_from_id (int id) | |||
| 1050 | 1068 | ||
| 1051 | void xwidget_view_delete_all_in_window( struct window *w ) | 1069 | void xwidget_view_delete_all_in_window( struct window *w ) |
| 1052 | { | 1070 | { |
| 1053 | //xxx | ||
| 1054 | struct xwidget_view* xv = NULL; | 1071 | struct xwidget_view* xv = NULL; |
| 1055 | for (int i = 0; i < MAX_XWIDGETS; i++){ | 1072 | for (int i = 0; i < MAX_XWIDGETS; i++){ |
| 1056 | xv = &xwidget_views[i]; | 1073 | xv = &xwidget_views[i]; |
| 1057 | if(xv->w == w){ | 1074 | if(xv->w == w){ |
| 1058 | gtk_widget_destroy(xv->widgetwindow); | 1075 | gtk_widget_destroy(GTK_WIDGET(xv->widgetwindow)); |
| 1059 | } | 1076 | } |
| 1060 | } | 1077 | } |
| 1061 | } | 1078 | } |