]> code.delx.au - gnu-emacs/commitdiff
upstream
authorJoakim Verona <joakim@verona.se>
Tue, 22 May 2012 06:52:40 +0000 (08:52 +0200)
committerJoakim Verona <joakim@verona.se>
Tue, 22 May 2012 06:52:40 +0000 (08:52 +0200)
24 files changed:
.gitignore
README.xwidget [new file with mode: 0644]
autogen/configure
configure.in
lisp/emacs-lisp/cl-loaddefs.el
lisp/emacs-lisp/cl-macs.el
lisp/net/browse-url.el
lisp/xwidget-test.el [new file with mode: 0644]
lisp/xwidget.el [new file with mode: 0644]
src/Makefile.in
src/dispextern.h
src/dispnew.c
src/emacs.c
src/emacsgtkfixed.c
src/emacsgtkfixed.h
src/keyboard.c
src/lisp.h
src/print.c
src/termhooks.h
src/window.c
src/xdisp.c
src/xterm.c
src/xwidget.c [new file with mode: 0644]
src/xwidget.h [new file with mode: 0644]

index 21702f7cd07f8386b6ccf9c806d1b738243f517d..50470179e38594cc5edc67b0e9c3421acd5c35a3 100644 (file)
@@ -15,3 +15,7 @@ makefile
 
 /bin/
 /site-lisp/
+*.o
+*.elc
+.bzr
+*#
\ No newline at end of file
diff --git a/README.xwidget b/README.xwidget
new file mode 100644 (file)
index 0000000..fa3f9da
--- /dev/null
@@ -0,0 +1,1565 @@
+-*-org-*-
+* Xwidgets
+
+This is an experimental branch to enable embedding of GTK widgets
+inside an Emacs window. The Emacs abstraction is called an Xwidget,
+for eXternal widget, and also in reference to the Xembed protocoll.
+
+There is a demo file called xwidget-test.el which shows some of the
+possibilities. There are some screnshots at the emacswiki.
+
+Currently its possible to insert buttons, sliders, xembed widgets, and
+webkit in the buffer. It works similar to the support for images in
+Emacs.  Adding more types of widgets should be fairly straightforward,
+but will require adapter code for each type.
+
+A difference from images is that xwidgets live their own life. You
+create them with an api, get a reference, and tie them to a particular
+buffer with a display spec. 
+
+Each xwidget can have several views. In MVC terms, an xwidget is the
+model, and an xwidget-view is a view of the xwidget in a particular
+Emacs window.
+
+The xwidget code attempts to keep the visual appearance of the views
+in sync with through an Observer pattern implementation. This is
+necessary to support the Emacs window paradigm.
+
+** building
+bzr co bzr+ssh://bzr.savannah.gnu.org/emacs/xwidget/
+#the below compiler flags shouldn't be strictly necessary
+export CFLAGS=" -g"
+./configure --with-xwidgets --enable-asserts --with-x-toolkit=gtk3
+make -j4
+gdb -ex run src/emacs
+
+** try it out
+If you have GTK3 and gtk-webkit installed, you should be able to
+start the embedded webkit browser now:
+
+M-X xwidget-webkit-browse-url
+
+If that didnt work out try the minimal demonstration instead:
+
+(load-library "xwidget-test")
+(xwidget-demo-a-button)
+
+It looks unimpressive, but it's a gtk button inside an Emacs buffer!
+*** webkit hints
+If you got webkit working, great! Please note, though, that the
+current support is far from a full fledged browser. My focus is on
+delivering a component that can be used to build a full emacs based
+browser on. Since I implement a browse-url function you can get quite
+far just by:
+
+(setq browse-url-browser-function 'xwidget-webkit-browse-url)
+
+then all Emacs browser interface systems work to a degree.
+heres stuff I use currenly
+
+- m-x anything-surfraw interfaces to search engines
+- C-o in org mode opens links inside org
+- m-x ffap opens links anywhere in a buffer
+- m-x gtk-lookup-symbol searches gtk docs
+- m-x bookmark-jump
+etc..
+
+I'll add more examples as I go along.
+
+However theres lots of support missing, see TODO list for
+information. Briefly:
+- download handling
+- keyboard field navigation
+- isearch
+- history
+- sites that use flash. I dont really care about this issue so its
+unlikely to be fixed. Just a heads up.
+
+** Stability
+Beginning with Summer 2011 I am now able to use Xwidget Emacs as my
+primary Emacs. That is good for the project and the stability of the
+code.
+
+At the time of writing I have 24 hour Emacs uptime with several
+embedded webkit browsers, Gnus, org-mode, tramp, etc. etc.
+
+That said, there are still many improvements that needs to be done,
+particularily in memory management. Expect xwidget emacs to leak
+heavily for now.
+
+** timeline for inclusion in trunk
+The Emacs 24 feature freeze is passed, so xwidgets won't probably be merged
+until Emacs 25. OTOH since I now use xwidget emacs as my primary
+emacs, I will merge from trunk much more often than in the past.
+
+** reporting bugs
+emacs xwidgets uses the same tracker as mainline emacs, but a
+different package.
+
+m-x report-emacs-bug
+
+Change the address to:
+submit@debbugs.gnu.org
+
+Include this line first in the body:
+Package: emacs-xwidgets
+
+browse bugs:
+http://debbugs.gnu.org/cgi/pkgreport.cgi?package=emacs-xwidgets
+** Thanks
+emacs-devel@gnu.org. There are very helpful people there. When I
+started the xwidget project I had no clue about the Emacs internals. 
+
+* Brief overview of how xwidgets work
+Xwidgets work in one way like images in Emacs. You bind a display spec very
+similar to an image display spec to buffer contents. The display engine will
+notice the display spec and try to display the xwidget there. The display engine
+prepares space at the right place for the xwidget and so on for free, as long as
+we provide proper sizes and so on back to the redisplay engine.
+
+** Issues
+The problem is that Emacs cant actually draw the widgets, as it can with
+images. Emacs must notify GTK about where the widgets should be, and how they
+should be clipped and so on, and this information must be given to GTK
+synchonous with Emacs display changes. Ok, so why is that difficult then?
+
+- How do we know when a widget is NOT to be drawn? The only way I found so far
+  is having a flag for each xwdiget, that is reset before a redisplay. When an
+  xwidget is encountered during display, the flag is set. After redisplay,
+  iterate all xwidgets and hide those which hasnt been displayed. 
+
+- The gtk socket type for embedding external applications is desirable
+  but presents a lot of difficulties of its own. One difficulty is
+  deciding which input events to forward, and when and how to do it.
+
+** placement and clipping
+the entire emacs frame is a gtk window. we use the fixed layout
+manager to place xwidgets on the frame. coordinates are supplied by
+the emacs display engine. widgets are placed inside an intermediate
+window, called the widgetwindow. the widgetwindows are placed on the
+emacs frame.
+
+this way was chosen to simplify clipping of the widgets against emacs
+window borders.
+
+
+** different strategies
+Integrating toolkit widgets(gtk in this case) and the emacs display
+engine is more difficult than your plain average gui application, and
+different strategies has been tested and will continue to be tested.
+
+There was a distinction between live xwidgets and
+phantom xwidgets, previous to the change to MVC.
+
+- the first aproach was to have the live xwidget on-screen, and move
+  them about. the phantoms were generated by snapshoting the live
+  xwidget. 
+
+the drawback of that aproach was that the gtk toolkit is admirably
+lazy and doesnt draw the widget if its not actualy shown, meaning that
+the snapshots for the phantoms will show garbage.
+
+- the second aproach was to use composition support. that tells gtk
+  that the widget should be drawn in an off-screen buffer and drawn on
+  screen by the application.
+
+this has the primary advantage that the snapshot is always
+available, and enables the possibility of more eye-candy like drawing
+live and phantom widgets in different colors.
+
+the drawback is that its our own responsibility to handle drawing,
+which puts more of the display optimization burden on us.
+
+this is aproach worked so-so.
+
+- another aproach is to have both live and phantom widgets drawn
+  on-screen by proxy gtk objects. the live xwidget will be entirely
+  handled in an off-screen window, and the proxy objects will redirect
+  events there.
+
+- combine on-screen and off-screen aproaches. maybe composition is the
+  way to go for most cases, but on-screen xembeding is the way to go
+  for particular special cases, like showing video in a
+  window. off-screen rendering and whatnot, is not efficient in that
+  particular case, and the user will simply have to accept that the
+  phantom of a video widget isnt particularily beautiful.
+
+- The current and seemingly sanest aproach implements a MVC pattern.
+
+** Testing
+;;test like:
+;; cd /path/to/xwidgets-emacs-dir
+;; make   all&&  src/emacs -q --eval "(progn (load \"`pwd`/lisp/xwidget-test.el\") (xwidget-demo-basic))"
+
+** MVC and Xembedd
+The MVC approach appears to be at least in principle robust for plain gtk
+widgets. For the interesting case of gtk sockets which implements an
+xembed host widget that allows for embedding other applications inside
+an Emacs window, the story gets more complex.
+
+The problem is that xembed is designed to plug an application window
+inside a a secket and thats it. You can't move a plug between
+sockets. I tried numerous hacks to get around this but there is
+nothing that works realy well.
+
+Therefore the Emacs part of the code will only expose well-defined
+interfaces. cooperating applications will be able to use the interface
+in a well defined manner. The problem is that there is no known xembeddable
+application that implement the needed type of functionality, which is
+allowing for creating new windows on the fly that plug into new
+sockets.
+
+Therefore I will attempt to provide an external application that wraps
+another application and through hacks attempts to provide the needed
+multi view xembed function. That way Emacs is sane and the insanity
+contained.
+
+This app will work by providing a socket that an app plugs into. The
+socket window is copied efficientlp by means of composition to a
+number of other windows, that then are plugged into the different
+Emacs sockets. 
+** old notes from x_draw_xwidget_glyph_string
+
+    BUG it seems this method for some reason is called with bad s->x and s->y sometimes.
+    When this happens the xwidget doesnt move on screen as it should.
+    This mightbe because of x_scroll_run. Emacs decides to scroll the screen by blitting sometimes.
+    then emacs doesnt try to actualy call the paint routines, which means this here code will never
+    run so the xwidget wont know it has been moved.
+
+    Solved temporarily by never optimizing in try_window_reusing_current_matrix().
+
+    BUG the phantoming code doesnt work very well when the live xwidget is off screen.
+    you will get weirdo display artefacts. Composition ought to solve this, since that means the live window is
+    always available in an off-screen buffer. My current attempt at composition doesnt work properly however.
+
+    //allocation debugging. the correct values cant be expected to show upp immediately, but eventually they should get to be ok
+    // this is because we dont know when the container gets around to doing layout
+    //GtkAllocation galloc;
+    //gtk_widget_get_allocation(GTK_WIDGET (xv->widgetwindow), &galloc);
+    //printf("allocation %d %d , %d %d\n", galloc.x,galloc.y,galloc.width,galloc.height);
+
+
+*** old notes about the old live/phantom scheme
+
+   //TODO:
+   // 1) always draw live xwidget in slected window
+   // (2) if there were no live instances of the xwidget in selected window, also draw it live)
+   // 3) if there was a live xwidget previously, now phantom it.
+
+   else
+     {
+       //ok, we are painting the xwidgets in non-selected window, so draw a phantom
+       //printf("draw phantom xwidget at:%d %d\n",x,y);
+       //xwidget_composite_draw_phantom (xw, x, y, clipx, clipy); //TODO MVC there will be very few cases of phantoming
+     }
+
+
+   atm this works as follows: only check if xwidgets are displayed in the
+   "selected window". if not, hide them or phantom them.
+
+   this means valid cases like xwidgets being displayed only once in
+   non-selected windows, does not work well. they should also be visible
+   in that case not phantomed.
+
+* ToDo:s
+** TODO optimize drawing off large offscreen widgets
+Currently I just allocate as large an area as the offscreen widget
+desires. This works well most of the time. But a HTML page might in
+principle be of infinite height so there will probably be cases where
+this doesn't work too well.
+** DONE again a trace
+   CLOSED: [2011-10-28 Fri 13:48]
+[2011-08-23 Tue]
+the hunch is that since I still hand-wave the view storage the array
+can get out of synchronous. so maybe switching to a lisp structure
+will help as it did for the model. Anyway, doesnt happen at all often.
+*** the trace
+(gdb) bt
+#0  0x0000000000685304 in xwidget_touch (xv=0x0) at xwidget.c:1225
+#1  0x00000000006853e7 in xwidget_end_redisplay (w=0x11b42ca0, matrix=
+    0xff9bf40) at xwidget.c:1272
+#2  0x000000000041cc31 in update_window (w=0x11b42ca0, force_p=0)
+    at dispnew.c:3705
+#3  0x000000000041c0e5 in update_window_tree (w=0x11b42ca0, force_p=0)
+    at dispnew.c:3331
+#4  0x000000000041be8b in update_frame (f=0x1682a50, force_p=0, 
+    inhibit_hairy_id_p=0) at dispnew.c:3258
+#5  0x000000000045066f in redisplay_internal () at xdisp.c:12931
+#6  0x000000000044e210 in redisplay () at xdisp.c:12110
+#7  0x0000000000567e65 in read_char (commandflag=1, nmaps=7, maps=
+    0x7fffffffc040, prev_event=12708226, used_mouse_menu=0x7fffffffc254, 
+    end_time=0x0) at keyboard.c:2447
+#8  0x000000000057613c in read_key_sequence (keybuf=0x7fffffffc4a0, bufsize=
+    30, prompt=12708226, dont_downcase_last=0, can_return_switch_frame=1, 
+    fix_current_buffer=1) at keyboard.c:9299
+#9  0x0000000000565d45 in command_loop_1 () at keyboard.c:1448
+#10 0x0000000000601008 in internal_condition_case (bfun=
+    0x565962 <command_loop_1>, handlers=12760466, hfun=0x565259 <cmd_error>)
+    at eval.c:1490
+#11 0x0000000000565659 in command_loop_2 (ignore=12708226) at keyboard.c:1159
+#12 0x0000000000600992 in internal_catch (tag=12873826, func=
+---Type <return> to continue, or q <return> to quit---
+    0x565633 <command_loop_2>, arg=12708226) at eval.c:1247
+#13 0x00000000005655bd in command_loop () at keyboard.c:1124
+#14 0x0000000000564da7 in recursive_edit_1 () at keyboard.c:759
+#15 0x0000000000564f43 in Frecursive_edit () at keyboard.c:823
+#16 0x000000000060444f in Ffuncall (nargs=1, args=0x7fffffffca20)
+    at eval.c:2986
+#17 0x00000000006507f8 in exec_byte_code (bytestr=145172929, vector=145179445, 
+    maxdepth=116, args_template=12708226, nargs=0, args=0x0) at bytecode.c:785
+#18 0x0000000000604eec in funcall_lambda (fun=140575909, nargs=2, arg_vector=
+    0x7fffffffcfe8) at eval.c:3220
+#19 0x000000000060467e in Ffuncall (nargs=3, args=0x7fffffffcfe0)
+    at eval.c:3038
+#20 0x00000000006035fc in Fapply (nargs=2, args=0x7fffffffd0b0) at eval.c:2494
+#21 0x0000000000603b43 in apply1 (fn=12874242, arg=301666310) at eval.c:2732
+#22 0x00000000005feb25 in call_debugger (arg=301666310) at eval.c:220
+#23 0x0000000000601ca9 in maybe_call_debugger (conditions=9431542, sig=
+    12761282, data=301666742) at eval.c:1893
+#24 0x0000000000601785 in Fsignal (error_symbol=12761282, data=301666742)
+    at eval.c:1714
+#25 0x0000000000601898 in xsignal (error_symbol=12761282, data=301666742)
+    at eval.c:1749
+#26 0x0000000000601926 in xsignal2 (error_symbol=12761282, arg1=102756373, 
+    arg2=0) at eval.c:1770
+---Type <return> to continue, or q <return> to quit---
+#27 0x0000000000604d6e in funcall_lambda (fun=102756373, nargs=0, arg_vector=
+    0x7fffffffd398) at eval.c:3189
+#28 0x000000000060467e in Ffuncall (nargs=1, args=0x7fffffffd390)
+    at eval.c:3038
+#29 0x00000000006507f8 in exec_byte_code (bytestr=54783137, vector=109656229, 
+    maxdepth=12, args_template=12708226, nargs=0, args=0x0) at bytecode.c:785
+#30 0x0000000000604eec in funcall_lambda (fun=109656517, nargs=0, arg_vector=
+    0x7fffffffd890) at eval.c:3220
+#31 0x000000000060467e in Ffuncall (nargs=1, args=0x7fffffffd888)
+    at eval.c:3038
+#32 0x0000000000603b08 in apply1 (fn=109656517, arg=12708226) at eval.c:2725
+#33 0x00000000005fc8c9 in Fcall_interactively (function=109656517, record_flag=
+    12708226, keys=12754549) at callint.c:379
+#34 0x00000000006044c2 in Ffuncall (nargs=4, args=0x7fffffffdc60)
+    at eval.c:2996
+#35 0x0000000000603c57 in call3 (fn=12893554, arg1=109656517, arg2=12708226, 
+    arg3=12708226) at eval.c:2789
+#36 0x00000000005784cd in Fcommand_execute (cmd=109656517, record_flag=
+    12708226, keys=12708226, special=12708226) at keyboard.c:10290
+#37 0x00000000005661fb in command_loop_1 () at keyboard.c:1575
+#38 0x0000000000601008 in internal_condition_case (bfun=
+    0x565962 <command_loop_1>, handlers=12760466, hfun=0x565259 <cmd_error>)
+    at eval.c:1490
+---Type <return> to continue, or q <return> to quit---
+#39 0x0000000000565659 in command_loop_2 (ignore=12708226) at keyboard.c:1159
+#40 0x0000000000600992 in internal_catch (tag=12756258, func=
+    0x565633 <command_loop_2>, arg=12708226) at eval.c:1247
+#41 0x000000000056560c in command_loop () at keyboard.c:1138
+#42 0x0000000000564da7 in recursive_edit_1 () at keyboard.c:759
+#43 0x0000000000564f43 in Frecursive_edit () at keyboard.c:823
+#44 0x0000000000563052 in main (argc=1, argv=0x7fffffffe678) at emacs.c:1711
+
+Lisp Backtrace:
+"recursive-edit" (0xffffca28)
+"debug" (0xffffcfe8)
+"image-bol" (0xffffd398)
+0x68939c0 PVEC_COMPILED
+"call-interactively" (0xffffdc68)
+(gdb) 
+
+
+** DONE new annoying trace
+   CLOSED: [2011-08-13 Sat 16:16]
+maybe related to scroll inhibiting or cursor inhibiting code.
+It appears actually to be related to GLYPH_DEBUG=1. this flag is no
+longer needed.
+*** the trace
+Breakpoint 1, abort () at emacs.c:383
+383       kill (getpid (), SIGABRT);
+Missing separate debuginfos, use: debuginfo-install hunspell-1.2.15-2.fc15.x86_64 nss-mdns-0.10-9.fc15.x86_64
+(gdb) 
+(gdb) 
+(gdb) bt
+#0  abort () at emacs.c:383
+#1  0x0000000000418f01 in matrix_row (matrix=0xac29400, row=-1)
+    at dispnew.c:1477
+#2  0x000000000046e113 in draw_glyphs (w=0x18235c0, x=198, row=0xa3af100, area=
+    TEXT_AREA, start=17, end=18, hl=DRAW_CURSOR, overlaps=0) at xdisp.c:22550
+#3  0x000000000047869f in draw_phys_cursor_glyph (w=0x18235c0, row=0xa3af100, 
+    hl=DRAW_CURSOR) at xdisp.c:24882
+#4  0x00000000005083bb in x_draw_window_cursor (w=0x18235c0, glyph_row=
+    0xa3af100, x=180, y=361, cursor_type=0, cursor_width=1, on_p=1, active_p=1)
+    at xterm.c:7440
+#5  0x00000000004790cd in display_and_set_cursor (w=0x18235c0, on=1, hpos=17, 
+    vpos=19, x=180, y=361) at xdisp.c:25098
+#6  0x00000000004fa31f in x_update_window_end (w=0x18235c0, cursor_on_p=1, 
+    mouse_face_overwritten_p=0) at xterm.c:644
+#7  0x000000000041ccb9 in update_window (w=0x18235c0, force_p=0)
+    at dispnew.c:3694
+#8  0x000000000041c165 in update_window_tree (w=0x18235c0, force_p=0)
+    at dispnew.c:3331
+#9  0x000000000041beee in update_frame (f=0x1658460, force_p=0, 
+    inhibit_hairy_id_p=0) at dispnew.c:3258
+#10 0x0000000000450a2e in redisplay_internal () at xdisp.c:12983
+#11 0x000000000044e2a6 in redisplay () at xdisp.c:12099
+#12 0x000000000056a60d in read_char (commandflag=1, nmaps=6, maps=
+
+** DONE allow xwidgets to report their size
+   CLOSED: [2011-07-19 Tue 14:26]
+now we just hard code sizes. but webkit widgets for instance can
+report sizes that suit the content. support that.
+** TODO BUG xwidget view ghosts
+- xwidget-webkit-browse-url somewhere
+- split window.
+now theres 2 webkit views
+- c-x 1
+now theres 2 views but one is a ghost!
+one should have been deleted when its window died but that didnt work
+for some reason here.
+
+- m-x xwidget-cleanup
+
+the ghost goes away because we killed explicitly but this is just a workaround.
+
+xwidget_view_delete_all_in_window(w); in delete-window-internal is not sufficient.
+delete-other-windows-internal
+delete_all_subwindows
+unshow_buffer
+
+Added cleanup those window configuration hook which works in practice
+but feels kludgy.
+
+*** code looks like this
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defun xwidget-cleanup ()
+  "Delete zombie xwidgets."
+  ;;its still pretty easy to trigger bugs with xwidgets.
+  ;;this function tries to implement a workaround
+  (interactive)
+  (xwidget-delete-zombies) ;;kill xviews who should have been deleted but stull linger
+  (redraw-display);;redraw display otherwise ghost of zombies  will remain to haunt the screen
+  )
+
+
+
+;;this is a workaround because I cant find the right place to put it in C
+;;seems to work well in practice though
+(add-hook 'window-configuration-change-hook 'xwidget-cleanup)
+
+*** but it ought rather to work like this
+xwidget-delete-zombies should be called from C after window
+configuration has changed but before redisplay. redisplay should not
+be called.
+
+
+** DONE BUG annoying backtrace
+   CLOSED: [2011-07-19 Tue 14:28]
+(this no longer seems to happen even under heavy usage. seems merging
+from trunk helped. lots were happening in redisplay at this time in trunk.)
+
+sadly happens a lot.
+- happens even with no initialized xwidgets
+-                   + row->glyphs[area][i].face_id
+or similar code, so row is invalid for some reason.
+xwidgets currently disable some redisplay opimizations so it might be
+an actual emacs bug manifesting without optimizations.
+
+*** bt 1
+      /* Compute the width of this line.  */
+      row->pixel_width = row->x;
+      for (i = 0; i < row->used[TEXT_AREA]; ++i)
+       row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
+
+(gdb) bt
+#0  0x000000000045c340 in compute_line_metrics (it=0x7fffffff8a20)
+    at xdisp.c:17549
+#1  0x00000000004603da in display_line (it=0x7fffffff8a20) at xdisp.c:18792
+#2  0x0000000000457646 in try_window (window=23403045, pos=..., flags=1)
+    at xdisp.c:15399
+#3  0x00000000004559c9 in redisplay_window (window=23403045, just_this_one_p=0)
+    at xdisp.c:14944
+#4  0x0000000000450247 in redisplay_window_0 (window=23403045) at xdisp.c:13152
+#5  0x00000000005fdcd9 in internal_condition_case_1 (bfun=
+    0x450208 <redisplay_window_0>, arg=23403045, handlers=12691046, hfun=
+    0x4501d9 <redisplay_window_error>) at eval.c:1538
+#6  0x00000000004501ba in redisplay_windows (window=23403045) at xdisp.c:13132
+#7  0x000000000044f19c in redisplay_internal () at xdisp.c:12706
+#8  0x000000000044f9f2 in redisplay_preserve_echo_area (from_where=7)
+    at xdisp.c:12964
+#9  0x0000000000568525 in swallow_events (do_display=1) at keyboard.c:4197
+#10 0x0000000000422554 in sit_for (timeout=40, reading=1, do_display=1)
+    at dispnew.c:5963
+#11 0x000000000056512c in read_char (commandflag=1, nmaps=8, maps=
+    0x7fffffffd3f0, prev_event=12720514, used_mouse_menu=0x7fffffffd604, 
+    end_time=0x0) at keyboard.c:2689
+#12 0x0000000000572c59 in read_key_sequence (keybuf=0x7fffffffd850, bufsize=
+    30, prompt=12720514, dont_downcase_last=0, can_return_switch_frame=1, 
+---Type <return> to continue, or q <return> to quit---
+    fix_current_buffer=1) at keyboard.c:9291
+#13 0x0000000000562897 in command_loop_1 () at keyboard.c:1446
+#14 0x00000000005fdb52 in internal_condition_case (bfun=
+    0x5624b4 <command_loop_1>, handlers=12772898, hfun=0x561dab <cmd_error>)
+    at eval.c:1493
+#15 0x00000000005621ab in command_loop_2 (ignore=12720514) at keyboard.c:1157
+#16 0x00000000005fd4ce in internal_catch (tag=12768770, func=
+    0x562185 <command_loop_2>, arg=12720514) at eval.c:1247
+#17 0x000000000056215e in command_loop () at keyboard.c:1136
+#18 0x00000000005618f9 in recursive_edit_1 () at keyboard.c:757
+#19 0x0000000000561a95 in Frecursive_edit () at keyboard.c:821
+#20 0x000000000055fba2 in main (argc=1, argv=0x7fffffffe188) at emacs.c:1704
+
+
+*** bt 2
+
+** DONE Examine using XComposite rather than GTK off-screen
+  rendering. This would make xembed widgets work much better. This
+  would probably be rathter difficult, but could open up other
+  interesting possibilities for Emacs. There is an early attempt in
+  xwidget.c, but the X call to redirect to offscreen rendering fails
+  for unknown reasons.
+
+  the attempt was further worked on, and the xlib calls replaced with
+  gdk calls, this works better.
+
+  In the end I abandoned this aproach. Xwidget-osr is the new aproach.
+
+** TODO  make the keyboard event code propagation code work. 
+There is an attempt to provide an api to send keyboard events to an
+xwidget, but it doesnt currently work very well.
+
+*** TODO try gtk event creation instead 
+since that works fine in the webkit osr code. 
+but, oh no, that didn't work for some reason.
+the widgets seems to receive the event but then the embedded widgets
+hangs.
+
+http://kegel.com/gtk/button.c
+
+*** TODO examine some library to synthesise events
+xdotool
+xte xautomation
+crikey
+libxdo
+
+*** TODO webkit raw keyboard event escape
+c-c tab could send a raw tab to the webkit instance.
+** DONE remove the special-case for when the minibuffer is
+  active.  I added some code to reduce the annoying problem display artefacts
+  when making the minibuffer the selected window. This made xwidgets in the
+  buffer go grey or black whenever one did m-x to activate the minibuffer. The
+  coded tried to handle the minibuffer as a special case. That simply wasnt a
+  good idea. Special-casing will never work properly. It is much better to spend
+  time finding solutions that work acceptably in the general case.
+
+** DONE disable emacs cursor drawing on top of an active xwidget. 
+  This ought to be rather simple and should improve the visuals a lot.
+
+** TODO  improve the xwidgets programming interface 
+so its less of hand-waving affair. This shouldnt be too hard, but I
+  have deliberatley not spent any time on it, since getting the
+  visuals right is much harder. Anyway, I sort of think the interface
+  should be somewhat like it is, except symbols is used instead of
+  integers.
+*** DONE use symbols for xwidget types rather than ints
+    CLOSED: [2011-06-27 Mon 12:52]
+
+
+*** TODO better lisp based structure for xwidgets
+the lisp interface woud be like this:
+- make-xwidget returns an xwidget object, similar to a process
+  object. this object is used when creating the display spec(instead of
+  the user defined id now used)
+
+the data structure would be something like this:
+- a "process" like aproach to create the xwidgets. xwidgets are
+  coupled to buffers, somewhat like processes, except a buffer can
+  hold several xwidgets
+- an xwidget has a plist to hold the model, like a process
+- an xwidget has an assoc list of xwidget views
+
+there are some things that arent clear:
+- an xwidget doesnt necessarily need to be coupled to a buffer but it
+  seems to be the clearest model. xwidgets would be buffer local
+- xwidget-views are by necessity coupled to a emacs window so it might
+  be better to store them window locally rather than in an assoc
+  coupled to the xwidget model
+- for some gtk widgets that resist an mvc approach, like the webkit
+  widgets, special operations are needed, similar to the old phantom
+  widgets aproach. so we need to differentiate live and phantom
+  instances for these troublesome widgets and let lisp manage all the trickery.
+
+stuff that needs to work:
+- do something for all views of a xwidget(resize, value change)
+- do something for all xw-views in an emacs window(deletion etc)
+- lookup xw-view for xwidget in emacs window(during redisplay)
+(- do something for all siblings of a xw-view. not atm)
+
+*** DONE xwidget creation interface
+    CLOSED: [2011-07-18 Mon 01:59]
+xwidgets are a little bit like emacs processes but also a little bit
+like emacs images. Therefore its not perfectly obvious how to handle
+creation. Currently I just use hardcoded identifiers. the real scheme
+needs to be something else.
+
+Heres a tentative approach:
+- xwidget-create returns a xwidget object, like process creation
+  functions. the xwidget will be largely uninitialized until
+  discovered by redisplay. an xw belongs to a buffer
+- xwidget-insert inserts the xwidget in a buffer. when discovered by
+  redisplay it will be initialized and a xwidget-view allocated
+- an event will be emitted when initialization is finished when
+  relevant like for sockets
+
+the problem with this aproach is that its not really legal to reuse
+xwidget objects by writing several display specs who reference the
+same xwidget. It could presumably be done but it would just become
+weird for no real benefit. the big preblem is that the display spec
+decides the on-screen size, and its not sane to have xwidget views
+with different sizes. therefore such display specs would need to be
+catched and dissallowed. Except it is hard because AFAIK the specs
+don't have an identity as such. A flag in the structure could be set
+by lookup so the first display attempt would win. but then you can't
+rewrite the spec to change the size. hmmm. A third approach would be
+to just allow the 1st spec refering an xw during a redisplay to take
+effect, the rest are signaled as errors. this wouldnt be too bad.
+
+the other aproach would be to work more like images:
+
+- write the display spec with all information needed to create the
+  xwidget.
+- retrieve the xwidget objet from the spec with an xwidget-at-point function. It
+  can be uninitalized which client code must handle. Unlike
+  assynchronous process creation we dont get back a handle, because
+  there is none yet.
+- emitted event on initialization, when needed. Many widgets don't
+  need this. for instance, a button sends an event when pressed. but
+  you can't press it unless its on screen, and then its initialized
+  properly. 
+
+This approach seemed good, but how do I know which instance
+generates an event if I cant set the id beforehand?
+
+so, therefore, the first two aproach is used. 
+
+
+*** DONE xwidget creation interface actually
+    CLOSED: [2011-07-18 Mon 01:59]
+conclusion of above ramblings:
+- should be similar to make-text-button
+- don't init from display spec, instead during make-xwidget call
+*** TODO callbacks would be nice 
+but they need to be handled initially with events for technical
+reasons. C code can't call Lisp easily. The event handler can call the
+callback though.
+
+** TODO  more documentation
+There should be user docs, and xwidget contributor docs. The current README
+is all contributor docs there is now, apart from the code.
+
+
+
+** CANCELLED look into more ways of displaying xwidgets, like binding them to a
+   CLOSED: [2011-07-05 Tue 11:34]
+window rather than a point in a buffer. This was suggested by Chidong.
+This would be a useful addition to Emacs in itself, and would avoid nearly all 
+display issues. I still think the general case is more interesting, but this
+special case should also be added. The xwidget would then be bound to
+replace the view of a particular window, and it would only show in
+that window.
+
+I got the webkit xwidget to work well enough so I dont see the need
+for this now, except for sockets and I think it can better be dealt
+with at the lisp level.
+
+** DONE MVC mode for xwidgets
+   CLOSED: [2011-06-27 Mon 12:53]
+It appears unfruitful to chase using the same display mode for all
+types of xwidgets. Composition is fun but not robust the way I
+tried to do it.
+
+Instead there should be a set of MVC xwidgets. Each on-screen instance
+of an MVC widget would be a real GTK widget. The instances would
+communciate state using signals. 
+
+There are drawbacks. There is no inbuilt support for MVC in GTK, so we
+have to roll our own, which is tedious if not much work for the few
+cases.
+
+MVC for xembedded application will need support from the applications
+themselves. Inkscape supports multiple views to the same document,
+other programs don't. In practice it might not be a big drawback.
+
+
+*** DONE figure out what to do with the multiple frames case. 
+    CLOSED: [2011-06-27 Mon 12:52]
+This should be easier to solve with MVC.
+Surprisingly, this just worked!
+*** DONE how to propagate changes in views to other views?
+    CLOSED: [2011-06-27 Mon 12:53]
+I used gtk signals, the implementation for sliders works well!
+
+** TODO canvas support
+heres an interesting comparision of gtk canvases
+http://live.gnome.org/ProjectRidley/CanvasOverview
+*** goocanvas
+goocanvas is a gtk canvas implemented using cairo. investigate.
+
+pros:
+- it has a MVC model aproach out of the box which is nice.
+
+http://developer.gnome.org/goocanvas/unstable/goocanvas-model-view-canvas.html
+
+export CFLAGS="`pkg-config --cflags goocanvas` -DHAVE_GOOCANVAS"
+export LDFLAGS=`pkg-config --libs goocanvas`
+./configure
+make
+
+I made a hello goo world xwidget so seems doable.
+I wanted to load a SVG which wasnt immediately straightforward, so I
+tried clutter. but it turns out the exact same strategy could be used
+with goocanvas.
+
+*** clutter
+maybe clutter can be used as a canvas? 
+pros:
+- seems to have a lot of traction atm. many examples
+- potentialy fast and cool vector graphics
+cons:
+- no out of the box MVC support, but seems doable. no worse than the
+  other home brew mvc support I have in xwidgets
+(media-explorer in an application that employes the MVC pattern)
+
+http://www.openismus.com/documents/clutter_tutorial/0.9/docs/tutorial/html/sec-stage-widget.html
+
+there is also cool stuff like this:
+http://gitorious.org/webkit-clutter/webkit-clutter which is an webkit actor for
+clutter! hmmmmm.
+
+I want to render svg. aparently:
+  librsvg rsvg_handle_render_cairo(h, cr);
+  ClutterCairoTexture
+  Clutter
+
+export CFLAGS="`pkg-config --cflags clutter-gtk-1.0` -DHAVE_CLUTTER"
+export LDFLAGS=`pkg-config --libs clutter-gtk-1.0`
+./configure
+make
+
+compiles but I get:
+Gtk-ERROR **: GTK+ 2.x symbols detected. Using GTK+ 2.x and GTK+ 3 in
+the same process is not supported
+
+export CFLAGS="`pkg-config --cflags clutter-gtk-0.10` -DHAVE_CLUTTER"
+export LDFLAGS=`pkg-config --libs clutter-gtk-0.10`
+./configure
+make
+
+
+*** webkit html 5
+expose the DOM to lisp or something. The webkit xwidget works pretty
+well now, so this might be the way ahead.
+** DONE mvc code crashes after a while
+   CLOSED: [2011-07-12 Tue 18:52]
+seemingly only when compiling with optimizations.
+I have no idea why.
+
+Doesn't seem to happen after some code cleanups.
+** DONE xwidget-resize-at
+   CLOSED: [2011-07-19 Tue 14:28]
+reimplement so display spec is not involved
+** DONE display spec validation
+   CLOSED: [2011-07-19 Tue 14:44]
+it is an error to reuse xwidgets in several buffers or in the same
+buffer. how do we catch these errors? 
+- showing the same xwidget twice in a buffer is no more wrong than
+  showing in several emacs windows, just conceptually wrong, so ignore
+  this case for now
+- xwidgets now store a reference to the buffer they were created in,
+  so use that to invalidate xwidget references in oher buffers. but
+  thats not really an error either
+- xwidgets should now be proper lisp objects so you dont delete them
+  you await their garbage collection. so therefore there can never be
+  invalid display specs
+
+so turned out this got solved by using proper lisp objects for
+xwidgets. yay!
+
+** DONE clipping of controllers
+   CLOSED: [2011-07-05 Tue 11:33]
+
+Emacs uses a big GTK window and does its own clipping against Emacs
+windows inside this area. So, in order to layout gtk widgets in emacs
+windows we must clip thim ourselves. 
+
+The following method worked well for a long time:
+- make a gtk widget, say a button, xw
+- make a clipping area, of type gtkfixed(many types have been tested)
+- put the clip area in the main emacs gtk window
+- figure out clip area changes during emacs redisplay
+
+the only weirdness was that one has to tell gtk the clip area has a
+window in order to get clipping. This is weird because all gtkwidgets
+are windows in a sense and a window is almost by definition also a
+clipping area.
+
+Anyway, in GTK3 the   gtk_widget_set_has_window(GTK_WIDGET (
+xv->widgetwindow), TRUE); call is ignored. 
+
+The gtkeventbox which is documented to have its own window doesnt work
+either.
+
+http://www.lanedo.com/~carlos/gtk3-doc/chap-drawing-model.html
+
+anyway clipping is rather complicated but seems to finally work okay.
+
+*** DONE subclass my own clipping widget
+    CLOSED: [2011-07-04 Mon 16:55]
+http://www.lanedo.com/~carlos/gtk3-doc/GtkWidget.html#gtk-widget-set-has-window
+mentions that it has_window can only be called inside a widget
+impementation.
+
+this wasnt really the issue. allocation was the problem
+*** DONE try scrolled window
+    CLOSED: [2011-07-01 Fri 10:56]
+clipping does in fact work with
+gtk_scrolled_window_add_with_viewport (xv->widgetwindow, xv->widget);
+!!
+
+I get unwanted scrollbars in the widget though.
+
+  gtk_scrolled_window_set_policy      (  xv->widgetwindow,
+  GTK_POLICY_NEVER, GTK_POLICY_NEVER); 
+
+stops clipping from working! 
+
+
+*** DONE try viewport
+    CLOSED: [2011-07-01 Fri 10:56]
+gtkviewport is used in scrolled window so in order to remove
+scrollbars it should be possible to use viewport directly. however, 
+viewport ignores size requests. or rather the container does.
+
+
+*** DONE debug allocation
+    CLOSED: [2011-07-04 Mon 16:56]
+the container determines how much size to allocate to child widgets.
+
+        GtkAllocation galloc;
+        gtk_widget_get_allocation(GTK_WIDGET (xv->widgetwindow), &galloc);
+        printf("allocation %d %d , %d %d\n", galloc.x,galloc.y,galloc.width,galloc.height);
+
+after my clipping attemp shows that my size request is ignored! this
+might be logical, since the container provided by emacs is a
+gtkfixed. gtkfixed might choose to heed the widgets size desires and
+allocate the entire widget size. but we want clipping!
+
+since i cant reasonably expect to change the emacs main container, i
+can maybe overide the setallocation method in gwfixed, and adjust
+allocation to clipping if its an xwidget asking for allocation.
+
+**** DONE subclass gtkfixed
+     CLOSED: [2011-07-04 Mon 16:56]
+possibly i need to subclass gtkfixed and override
+#+begin_src C
+  void                gtk_widget_size_allocate            (GtkWidget *widget,
+                                                           GtkAllocation *allocation);
+#+end_src
+http://developer.gnome.org/gobject/stable/howto-gobject.html
+
+turns out emacs already does this for gtk3 according to jan D:
+>>For GTK3, Emacs already subclasses GtkFixed, see emacsgtkfixed.[ch].
+
+- widgets may not be underallocated, aparently
+http://mail.gnome.org/archives/commits-list/2011-April/msg10950.html
+
+- how to call base class method/chain up
+http://developer.gnome.org/gobject/stable/howto-gobject-chainup.html
+
+- the allocation modification could happen in the container or the
+  child. it feels more apropiate in the container
+
+it is however unexpectedy inconvenient to modify allocation because
+the needed data is private to the base class. to overcome this:
+
+ - run base class method 1st. 
+ - then, iterate all children, and modify allocation  for xwidget
+   children only. x y will then be set.
+
+JanD pointed out the GTK3 port already has its own subclass, so I
+modified that one.
+
+*** DONE clip top
+    CLOSED: [2011-07-05 Tue 11:30]
+there are four controller edges that potentialy need clipping. I begun
+with right and bottom edges. clipping them is just a matter of setting
+the right size of the widgetwindow and also ensure it gets the right
+allocation from the container.
+
+clipping top (and left) is not equally straightforward. I'm using a
+viewport now and scroll it the amount that needs to be clipped.
+however, the viewport is sensitive to changes in allocation, which
+makes it harder to use the allocation workarounds.
+
+see:
+- gtk_widget_set_size_request
+- gtkscrolledwindow
+
+I returned to using a simple gtkfixed for the widgetwindow. with
+allocation hack and set_has_window it works. Idea prefer not to have
+the allocatien hack and it wasnt needed it gtk3 only gtk2. needs
+furthi investigation,
+
+** various code cleanups
+There are many cleanups necessary before any hope of inclusion in
+Emacs trunk. To begin with, the part of the patch that touches other
+parts of emacs must be very clean. 
+*** DONE use FRAME_GTK_WIDGET (f)
+    CLOSED: [2011-07-20 Wed 20:02]
+rather than gwfixed.
+
+*** DONE support configure
+    CLOSED: [2011-07-12 Tue 18:48]
+*** DONE ifdef all xwidget code
+    CLOSED: [2011-08-13 Sat 16:19]
+so you can reliably disable the code at compiletime
+** DONE translate clicks 
+   CLOSED: [2011-07-03 Sun 22:12]
+on onscreen webkit peer to offscreen
+
+maybe
+http://developer.gnome.org/gdk/stable/gdk-Windows.html#GdkWindow-from-embedder
+
+turned out to be not so hard, captured events, copied them and
+forwarded them offscreen!
+
+** TODO investigate gdk_window_redirect_to_drawable
+http://developer.gnome.org/gdk/stable/gdk-Windows.html#gdk-offscreen-window-set-embedder
+maybe could be used in place of my own copy hacks? to work it must
+support a chain of redirects, which seems unlikely. the benefit would
+be that I dont have to spend time optimizing redrawing.
+
+
+** DONE remove xwidget_views when emacs window is deleted
+   CLOSED: [2011-07-05 Tue 11:29]
+removing xwidget views when an Emacs window closes is not reliable.
+
+- switching buffers in a window seems to hide the corresponding
+  xwidget-views properly, but they might as well be deleted.
+
+-  patching delete-window-internal could be used to delete the xwidget-views
+this seems to work
+
+
+** browser xwidget
+although embedding a browser is not my primary concern many are
+interested in this. some suitable browser component needs to be found
+supporting gtk.
+
+*** DONE webkit
+    CLOSED: [2011-07-03 Sun 22:13]
+there is a webkit gtk port. there is no obvious mvc support.
+http://live.gnome.org/WebKitGtk
+http://webkitgtk.org/
+
+it might be possible to keep a set of webxits in artificial
+synchronisation by recursive deep copy of the DOM from one webkit to
+another. This will be error prone at best though. Another way might be
+to just use bitmap copy of the "live"instance to the "phantom"
+instances. the problem of transfering the live view remains though.
+
+export CFLAGS="`pkg-config --cflags webkit-1.0` -DHAVE_WEBKIT -g"
+export LDFLAGS=`pkg-config --libs webkit-1.0`
+./configure
+make
+
+**** off screen rendering
+export CFLAGS="`pkg-config --cflags webkit-1.0` -DHAVE_WEBKIT_OSR -g"
+export LDFLAGS=`pkg-config --libs webkit-1.0`
+./configure
+make
+
+works a little bit  but i get errors like:
+
+(emacs:8362): GLib-GObject-WARNING **: invalid cast from `GdkOffscreenWindow' to `GdkDrawableImplX11'
+
+set a breakpoint in g_log, backtrace seems to indicate
+webkitViewportAttributesRecompute is the offender. 
+
+maybe try gtk3 variants?
+#+begin_src sh
+  export CFLAGS="`pkg-config --cflags webkitgtk-3.0 ` -DHAVE_WEBKIT_OSR "
+  export LDFLAGS=`pkg-config --libs webkitgtk-3.0 `
+  ./configure   --with-x-toolkit=gtk3
+  make
+#+end_src
+crash in gtk_window_get_size instead. great.
+
+http://gtkplus-p3.0.sourcearchive.com/documentation/2.91.5-0ubuntu1/testoffscreenwindow_8c-source.html
+
+after many atempts, the basic issue remains. for some reason the
+offscreen widget isnt ok when I want to snapshot it, so i simply get
+emptiness. the surface is only ok someimes. 
+
+here is a useful debugging snippets:
+#+begin_src C
+  // debugging redraw:
+  //  - the bg colors always change, so theres no error in signal handling
+  //  - i get this error now and then:
+  //(emacs:7109): GLib-GObject-WARNING **: invalid cast from `GdkOffscreenWindow' to `GdkDrawableImplX11'
+  // seems to happen in webkit actually. see README
+  
+  if(0){ //redraw debug hack. helped a lot in fact. use the with alpha painter below also
+    cairo_set_source_rgb(cr, osr_dbg_color, 1.0, 0.2);
+    cairo_rectangle(cr, 0,0, xw->width, xw->height);
+    cairo_fill(cr);
+    osr_dbg_color+=0.1;
+    if(osr_dbg_color>1.0)
+      osr_dbg_color=0.0;
+    
+  }
+#+end_src
+you need to terminate drawing like this:
+#+begin_src C  
+  //cairo_set_source_surface (cr, src_pixmap, 0,0); 
+  //cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+  //cairo_paint_with_alpha (cr, 1.0);
+  //cairo_paint(cr);
+#+end_src
+
+the snippets change background color on oach redraw. 
+
+**** on-screen rendering to separate window
+an alternative might be to open a separate window and snapshot it. the
+idea is that whatever oddness webkit does so that offscreen rendering
+doesnt work, doesnt happen on-screen. the window could be opened
+somewhere not in the way.
+
+*** CANCELLED firefox
+    CLOSED: [2011-07-03 Sun 22:13]
+http://www-archive.mozilla.org/unix/gtk-embedding.html
+seems to be severly bitrotted
+
+heres a newer aproach
+http://hg.mozilla.org/incubator/embedding/file/29ac0fe51754/gtk/tests/test.cpp
+
+while webkit clearly has the best traction as an embeddee, the
+offscreen rendering issues makes it interesting to see what ff brings
+to the table. 
+
+turned out webkit has as good offscreen support as anyone, see I went
+with that in the end.
+
+
+*** DONE text field support
+    CLOSED: [2011-07-20 Wed 20:05]
+Emacs captures all keyboard events so text field support isn't super
+straightforward. 
+
+**** propagate keyboard events
+I have some old hacks for this and they are not good.
+**** use the DOM model
+expose document.activeElement to lisp. This is potentially more
+interesting than just forwarding keyboard events.
+
+webkit_web_view_get_dom_document ()
+
+this is hard it seems. an idea might be to hack elisp support for swig
+to machine generate the bindings. 
+**** DONE inject javascript
+     CLOSED: [2011-07-03 Sun 22:50]
+webkit_web_view_execute_script ()
+
+this works now:
+(xwidget-webkit-execute-script 5 "document.activeElement.value='test'")
+
+so it should be possible to do some interesting stuff.
+execute-script does however not return anything at the interface level
+so satisfaction is not total:
+
+http://markmail.org/message/4yowmdgras73z3x5
+
+maybe
+https://launchpad.net/gnome-seed
+
+or this funny hack:
+<jave> im trying to understanh how to interact via javascript to an embedded
+       webkit gtk instance  [23:38]
+<jave> i use webkit_web_view_execute_script() which is nice but doesnt return
+       a value, by design aparently  [23:39]
+<jave> any hints?
+<lucian> jave: afaik, webkit still doesn't have full gobject bindings  [23:48]
+<lucian> jave: you can hack it up by making the JS modify the title, and read
+         the title from gtk-side
+<jave> lucian: that was a pretty cool idea!
+
+
+*** webkit_web_view_load_string ()
+I would like preview of html in a buffer rather than from uri.
+
+
+
+*** DONE simple xwidget-webkit wrapper
+    CLOSED: [2011-07-22 Fri 11:01]
+so that it could be used for actual browsing :)
+I dont want to reinvent too many wheels so i'd like to use existing
+emacs facilities here possible. use bindings similar to w3m(or info)
+
+- m-x xwidget-webkit starts a session
+- 'g' goes to a url
+- use bookmark-jump i suppose. I mostly use org for bookmarks myself
+- browse-url support so webkit can be the default browser
+- some way of getting around the quirky keyboard interaction since
+  xwidgets dont receive keyboard events because I hawe no idea how to
+  do that in a sane way
+
+... and one can of course go on bikeshedding forever. lets keep it
+simple and extensible, and compatible with other Emacs packages.
+
+the really cool ideas would need Emacs DOM integration, which is not
+easy. 
+
+** webkit related
+*** TODO webkit support webkit signals
+
+**** DONE particularily document-load-finished
+     CLOSED: [2011-08-01 Mon 22:34]
+http://webkitgtk.org/reference/webkitgtk-webkitwebview.html#WebKitWebView-document-load-finished
+because one might need tell set a title and sizes and things when it loads.
+**** TODO event bug
+Debugger entered--Lisp error: (error "Two bases given in one event")
+
+hapens sometimes with xwidget events. appears to be when the
+originating xwidget is offscreen so that the event doesn't get caught
+by the correct emacs event map.
+
+maybe I need to set the originating window in the event structure.
+  event.frame_or_window = Qnil;        //frame; //how to get the frame here? //TODO i store it in the xwidget now
+
+since its an offscreen xwidget the buffer local keymap isnt the right
+place for the handler. some global map should be used.
+
+onscreen widgets don't have the same issue.
+
+anyway, seems it'll turn out like this:
+- xwidget-osr stores a callback and user data
+- the event is an implementation detail only and get caught in the
+  topmost event map
+- the event map calls the callback in the xw with the right args.
+
+we need the event handler at some level because we can't call lisp
+asynchronously. 
+
+**** TODO navigation signal
+**** TODO new window signal
+*** TODO console messages
+http://webkitgtk.org/reference/webkitgtk-webkitwebview.html#WebKitWebView-console-message
+http://getfirebug.com/wiki/index.php/Console_API#console.count.28.5Btitle.5D.29
+because maybe we can make a simple JS REPL that way.
+  (xwidget-webkit-execute-script ( xwidget-webkit-last-session)
+  "console.log('hello')")
+prints hello to stdout but theres no way to catch stdout from webkit I
+think other than receiving the signal.
+
+*** TODO webkit flashkiller by default
+while its possible to support plugins in the webkit xwidget, flash has
+issues on 64 bit, and slows down emacs to a halt with off screen
+rendering, and of course is not free software. its in the way for real
+world usage even if its interesting to watch flash animations inside
+emacs. which should be achieved with Gnash or other free software
+instead.
+
+http://stackoverflow.com/questions/4885513/prevent-flash-in-cocoa-webview
+
+simply use this api:
+http://webkitgtk.org/reference/WebKitWebPluginDatabase.html
+
+theres an implementation now but it's not robust enough webkit often
+crashes taking emacs with it.
+
+*** TODO webkit downloads
+when clicking a download link in Webkit Emacs should take over and handle it
+from there. Probably need signals. There are Emacs libraries to
+download things, with wget etc. an url.el facility should be made.
+"download-requested"
+*** TODO webkit alt-text not handled
+XKCD use image-title to display a cartoon comment. These mysteriously
+don't work ATM. Other mouseovers work though. Maybe webkit tries to
+open a new window or something, which wont work.
+
+*** TODO webkit isearch in webkit buffers
+have a look at how docview solves it
+webkit_web_view_search_text ()
+*** TODO webkit relative references doesn't work
+because we handle scrolling in a non-standard way. It does
+work sort of when theres a html frameset and webkit scrolls by itself.
+
+internal links (page.html#section) do not work
+see xwidget-webkit-show-named-element
+
+also did some  webkit signal work for this.
+
+now it actually works! except for I need to know the Y coordinate of
+the element to navigate to, and that can either be by "name" or "id"
+attribute, currently "id"  works.
+
+
+
+*** TODO webkit width adjustment handling issue
+since there are so many levels of clipping and whatnot in xwidgets
+sizing issues are difficult.
+
+- an xwidget is told how large it can be by emacs. thats the end of
+  it. if the xwidget thinks otherwise it will be clipped.
+- but emacs can ask the xwidget how large it wants to be. it can then
+  resize the reserved area and inform the xwidget thusly. 
+
+That should have been enough. but webkit never reports less than what
+it already has. So currently a webkit view will only growth and not
+adjust to smaller sizes. 
+
+This is not a big problem in practice but is still annoying.
+
+to see the problem surface to http://www.slashdot.org
+- xwidget-webkit-adjust-size
+- xwidget-webkit-adjust-size-to-content
+
+and then compare by resizing in Epiphany, which is also webkit based.
+
+**** TODO try putting webkit osr inside a scrolling window
+it seems webkit is supposed to behave differently while embedded in a
+scrolling window. This is a bit cumbersome because the container stack
+is already deep.
+*** TODO xwidget webkit allow loading from string from emacs
+*** DONE xwidget-webkit-last-session
+    CLOSED: [2011-08-01 Mon 22:38]
+was rather hurried. end result is that the lisp layer only really
+allows for one webkit session.
+*** TODO extract DOM to lisp
+then the SHR html renderer from Gnus could render the DOM as created
+by Webkit. 
+
+made a simple oxperimental DOM tree traverser. It can be expanded to
+return a lisp representation, LDOM.
+
+in order to bring lisp and DOM closer together the LDOM can include a
+mapping to the originating DOM node. so, find a node in LDOM, and the
+cell maps to the original DOM. but since the LDOM is a copy it can get
+out of sync. DOM events might help.
+*** DONE C-X b in other buffer from webkit
+    CLOSED: [2011-08-12 Fri 22:20]
+bafflingly resets the webkit view to the top. Maybe the window
+reconfiguration hook code? further mystification is added because it
+only seems to happen with ido mode enabled.
+
+in comparison with image-mode which does the right thing, I discovered
+that image-mode has special code to handle scrolling. the browser mode
+and image mode has some similarities.
+
+I made some delegation code frrom webkit mode to image mode.
+*** TODO url-browse improvement
+sindikat: site.com and http://site.com should be equivalent (simple site.com
+  throws error)
+
+Yes, but its unclear at what level in Emacs to do this
+properly. I added a url-tidy function as a start.
+
+this should be further improved:
+- change the call to url-tidy so its a hook
+- provide a couple of demonstration hooks:
+  - url-tidy, which just prepends http://
+  - youtube which appends &html5=1 to urls looking like http://www.youtube.com/watch?v=DZdUgjEx_dQ
+  - history which logs all visited urls like a traditional browser
+
+*** TODO sindicat notes
+Here are some comments from user "sindikat" and my replies
+
+- http://ya.ru renders inadequatly (compare with any other browser) -
+  the search text-input is way below
+
+The problem is the size communication between Emacs and Webkit. 
+
+- doing PageDown is endless; so if you do 100 PageDowns, you have to
+  do 100 PageUps to retun to the header of the page
+
+True, I hadn't noticed. Thanks.
+
+- http://linux.org.ru (just an example) renders incorrectly too - it
+  should stretch horizontally
+
+Size communication.
+
+- obviously, pointing of mouse over some link should change it to
+  pointing hand cursor
+
+Need to verify with some other webkit browser.
+
+- when you are somewhere on the middle of a long page, than go to some
+  other page, you are still in the middle, instead of being again on
+  the top
+
+This is because I inherit from Image view mode. I kind of like it so
+we can add an option for it.
+
+
+- changing dropdown menus cause flickering
+
+
+- string entering is incorrect - by default it enters the title of the
+  page, while it should be empty
+
+The cause is the lack of return value in the webkit evaluation
+API. Ive made some fixes.
+
+- internal links (page.html#section) do not work
+
+ ive added a rudimentary function "xwidget-webkit-show-named-element" for this
+
+- maybe it's a good idea to implement Conkeror or some other
+  keybindings, where you press 'f' then select the exact <input
+  type="text"> where you want to enter text, without using mouse,
+  etc.;
+
+Indeed, this would require better DOM integration.
+
+- pressing 'home' and 'end' puts nonsense into minibuffer
+
+Probably because the Image mode derivative is mostly a hack.
+fixed now I think.
+
+
+
+
+
+
+- implement search (emacs internal isearch obviously doesn't work)
+
+Either use the webkit search but that doesn't feel right. It would be
+better to expose the DOM and search that.
+
+- some sites intercept with keyboard; example -
+  http://www.artlebedev.ru/kovodstvo/business-lynch/2011/10/03/ uses
+  Ctrl+left/right/up/down to navigate between pages - this should be
+  implemented too
+
+Keyboard integration is the unloved step-child of xwidgets, unfortunately.
+
+
+
+** TODO xwidget image display  spec compatibility
+some history: the first version of the xwidget display spec was
+the same as an image spec. This turned out not to be fantastic because
+an xwidget is both like a process and like an image. it has a separate
+existence from display. So now the xwidget display spec is just a
+pointer to a xwidget. But then some useful functionality in Emacs
+can't be reused for xwidget, in particular image-mode.
+
+Maybe a new image type could be added that was a wraper on an
+xwidget. Then image mode could be reused for webkit mode. 
+
+I tried some adaptor code in xwidget.el so webkit mode now delegates
+to image mode buh its a kludge.
+
+** socket related
+*** TODO some flickering during redisplay of sockets
+with gtk3 an size allocation workaround is used.
+this seems maybe to result in flickering sizewize y-axis with the
+xwidget socket type. The webkit xwidget doesn't seem similarily
+afflicted.
+
+the size allocation workaround works by 1st running the ordinary
+allocation then modifying the results. its done this way to minimise
+the copy paste index from the base class. it might be that the
+original allocation has a brief time window to show itself.
+
+tried to modify the allocation hack so it doesn't call allocate
+twice. this doesn't seem to help flicker at all aparently so the
+hypothesis falls. Maybe then a socket simply doesn't lke being clipped
+by gtkfixed. 
+
+*** TODO xwidget view reaping too agressive
+hide an emacs window for a while and return to it. the xwidget might
+get reaped and a new socket thus created.
+*** DONE try out OSR for sockets
+    CLOSED: [2011-07-25 Mon 21:30]
+
+didn't work too well in the inkscape case. it might be that some other
+bitmap copy method works better though.
+
+basically sockets doesn't like to be offscreen because they want their
+own gdk window.
+
+** DONE synchronise emacs background with xwidget color
+   CLOSED: [2011-08-11 Thu 11:04]
+fine-tuning to reduce flicker.
+
+isn't needed if emacs bg erase disabled
+
+** DONE xwidgets doesn't work during bootstrap all of a sudden
+   CLOSED: [2011-08-01 Mon 22:33]
+might be some annoying local issues with my install because it is not
+reliably reproducible. (went away during merges)
+
+** TODO low impact xwidget based image viewer
+for instance to render SVG using webkit, or some other canvas.
+that way it would be possible to merge to trunk in stages.
+
+so, webkit could be used to display the SVG. the display spec for
+images would be used. multiple webkits would be used rather than
+offscreen rendering, so it would be GTK2 compatible. 
+** DONE xwidget movement doesn't work all of a sudden
+   CLOSED: [2011-08-11 Thu 11:03]
+this used to work great. now it doesn't.
+
+suspects:
+- XCopyArea
+  - x_shift_glyphs_for_insert
+  - x_scroll_run. this is run by the try_window* functions, and
+    inhibiting them dösnt help. but also callid in scrolling_window.
+  
+
+- try_window_reusing_current_matrix
+- I used to enable GLYPH_DEBUG which I currently don't. it disables
+  many optimisations. this was fixed.
+- lookup_xwidget then produce_xwidget_glyph gets called always but not 
+x_draw_xwidget_glyph_string probably because of scroll optimization. 
+movement detection could possibly be moved to produce_xwidget_glyph(not)
+
+no longer helps:
+(setq inhibit-try-window-id t)
+(setq inhibit-try-window-reusing t)
+
+workaround:
+(run-with-timer 1 1 'redraw-display)
+
+seems to work:
+inhibiting scrolling_window(). and this seem to be enaugh to restore
+old behaviour, GLYPH_DEBUG doesn't seem needed.
+
+
+** DONE GLYPH_DEBUG doesn't work
+   CLOSED: [2011-08-08 Mon 17:30]
+was stupid accidental line removal that was hard to spot
+** TODO osc xwidget example  
+a couple of xwidget sliders that control a csound/supercollider song with osc.
+so, for that to work we need slider callbacks to work. when a slider
+changes send an osc message. use ocssend:
+
+ oscsend localhost 7777 /sample/address iTfs 1 3.14 hello
+
+or better:
+http://delysid.org/emacs/osc.el
+
+sliders could be defined in csound comments or something to illustrate
+the point. or if real fanciness is desired parse the csound source
+with Semantic and provide a control buffer corresponding to the
+defined controls.
+
+
+
+Added: [2011-08-11 Thu 10:53]
+
+
+** DONE SEB
+   CLOSED: [2011-10-26 Wed 15:36]
+the SEB site does something funny so I can't insert text in
+fields. aparently document.activeElement.value doesn't work with framesets.
+
+seems to work using the ugly javascript in 
+xwidget-webkit-activeelement-js
+
+** support downstreams
+http://aur.archlinux.org/packages.php?ID=53902
+http://gpo.zugaina.org/app-editors/emacs-xwidget/ChangeLog
+** DONE the proof of concept canvas code should be disabled by default.
+   CLOSED: [2011-10-12 Wed 23:03]
+** TODO advi
+active dvi viewer. investigate if it could be xwidgetified.
+advi supports embedding inside presentations.
+** cairo configuration support
+gtk3 brings in cairo on Fedora, but apparently not on all plattforms.
+pkg-config --cflags cairo
+** TODO splint
+splint   -Demacs -DHAVE_CONFIG_H  -I. -I/home/joakim/build_myprojs/emacsnew/emacs.bzr/xwidget.mint/src -I../lib -I/home/joakim/build_myprojs/emacsnew/emacs.bzr/xwidget.mint/src/../lib   -DGSEAL_ENABLE  -I/usr/include/gtk-3.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12   -I/usr/include/freetype2    -I/usr/include/alsa    -I/usr/include/librsvg-2.0 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/cairo -I/usr/include/libpng12 -I/usr/include/pixman-1 -I/usr/include/freetype2    -I/usr/include/ImageMagick   -I/usr/include/libxml2   -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include   -DGSEAL_ENABLE  -I/usr/include/webkit-3.0 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/gtk-3.0 -I/usr/include/libsoup-2.4 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/libxml2  -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include   -DORBIT2=1  -I/usr/include/gconf/2 -I/usr/include/orbit-2.0 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include   -I/usr/include/freetype2   xwidget.c
+
+** TODO 32 bit bug
+user reports that xwidgets segfaults  on the 32 bit Mint distribution
+but not the 64 bit. Mint is an Ubuntu derivative. I got some
+VirtualBox images to test with.
+** DONE youtube 
+   CLOSED: [2011-11-01 Tue 11:19]
+http://www.youtube.com/watch?v=DZdUgjEx_dQ&html5=1
+html5 makes it work without stupid flash plugins!
+** TODO clicking on an webkit xwidgets
+doesn't make the window active. this leads to problems.
+** DONE "g" should default to current url
+   CLOSED: [2011-11-03 Thu 22:25]
+"g" runs xwidget-webkit-browse-url which gets its interactive argument
+from browse-url-interactive-arg. this might need a new optional argument.
+
+http://test
+** TODO anything support
+hook so anything can filter browser history.
+** TODO new relative url code sometimes fail
+http://www.dilbert.com
+** TODO input field enhancements
+*** password field. 
+was straightforward
+
+*** textarea 
+less straightforward. I would like it to work like emacs-w3m, where a
+new editing buffer is opened. on c-c, the buffer is closed and the
+browser field updated. however, it's not immediately obvious how to
+store the reference to the field reliably.
+
+furthermore the current code doesn't seem to propagate linefeed
+properly to text areas.
+
+** DONE bug in current navigation handler
+   CLOSED: [2011-11-09 Wed 10:04]
+on www.dn.se
+Debugger entered--Lisp error: (args-out-of-range "http://platform.twitter.com/widgets/hub.html" 54 357)
+  match-string(1 "http://platform.twitter.com/widgets/hub.html")
+  xwidget-webkit-callback(48890368 navigation-policy-decision-requested)
+  xwidget-event-handler()
+  call-interactively(xwidget-event-handler nil nil)
+** TODO how to set the name of a webkit buffer?
+not obvious because, the buffer isn't created immediately and there is
+a callback that sets the buffer name automatically
+** TODO how to find next field in tab order?
+** TODO unique buffer names
+the webkit xwidgets renames the buffer after load but not uniquely so
+it sometimes fails.
+** TODO kill the offscreen webkit xwidgets when last view killed
+The offscreen xwidgets is currently kept around even if the xwidgets
+views are all gone. this is a general problem and it requires actions
+on the behalf of the application to resolve.
+
+In the case of webkit it is currently possible to get errors like these:
+
+Debugger entered--Lisp error: (error "Selecting deleted buffer")
+  xwidget-webkit-callback(60925380 navigation-policy-decision-requested)
+  xwidget-event-handler()
+  call-interactively(xwidget-event-handler nil nil)
+
+
+because the last view is gone and the offscreen widgets is still
+generating events. 
+
+In the case of webkit it is okay to kill the offscreen widgets
+completely when the user kills the last view window because it would
+be unexpected by the user to see it pop up again. This is not true in
+the general case.
+
+** DONE xwidgets debugging log
+   CLOSED: [2012-01-23 Mon 14:32]
+currently theres a lot of debugging traces using "message" which is
+annoying. Instead put them in a separate trace buffer.
+(see xwidgetbuffer)
+** TODO make garbage collect work for xwidgets
+when an xwidget is removed from xwidget-alist, and there are no other
+references(mostly views) the xwidget should be garbage collected.
+
+special finalization would go into gc_sweep()
+<<<<<<< TREE
+** TODO embedding evince
+http://developer.gnome.org/libevview/3.2/libevview-ev-view.html
+would be useful for reading PDF:s and other document types.
+it would work the same way webkit embedding works.
index c6f7cde3711434006695d57b7c7a15318fca9860..edd092f7f815d8a3726c0c1d703f4972ddc277dd 100755 (executable)
@@ -607,6 +607,55 @@ SUBDIR_MAKEFILES_IN
 LIB_GCC
 LD_FIRSTFLAG
 LD_SWITCH_SYSTEM_TEMACS
+POST_ALLOC_OBJ
+PRE_ALLOC_OBJ
+CYGWIN_OBJ
+RALLOC_OBJ
+OLDXMENU_DEPS
+LIBX_OTHER
+LIBXMENU
+OLDXMENU
+OLDXMENU_TARGET
+LIBXT_OTHER
+TOOLKIT_LIBW
+WIDGET_OBJ
+XOBJ
+XMENU_OBJ
+FONT_OBJ
+OTHER_FILES
+GNU_OBJC_CFLAGS
+ns_appsrc
+ns_appresdir
+ns_appbindir
+ns_appdir
+S_FILE
+M_FILE
+X_TOOLKIT_TYPE
+C_SWITCH_X_SYSTEM
+C_SWITCH_X_SITE
+LD_SWITCH_X_SITE
+gameuser
+gamedir
+bitmapdir
+archlibdir
+etcdir
+x_default_search_path
+lisppath
+locallisppath
+lispdir
+srcdir
+canonical
+configuration
+version
+KRB4LIB
+DESLIB
+KRB5LIB
+CRYPTOLIB
+COM_ERRLIB
+LIBRESOLV
+LIBHESIOD
+TERMCAP_OBJ
+LIBS_TERMCAP
 LIBGNU_LTLIBDEPS
 LIBGNU_LIBDEPS
 gltests_WITNESS
@@ -614,14 +663,15 @@ gl_GNULIB_ENABLED_verify_FALSE
 gl_GNULIB_ENABLED_verify_TRUE
 gl_GNULIB_ENABLED_strtoull_FALSE
 gl_GNULIB_ENABLED_strtoull_TRUE
-gl_GNULIB_ENABLED_strtoll_FALSE
-gl_GNULIB_ENABLED_strtoll_TRUE
 gl_GNULIB_ENABLED_stat_FALSE
 gl_GNULIB_ENABLED_stat_TRUE
+<<<<<<< TREE
+=======
 gl_GNULIB_ENABLED_sigprocmask_FALSE
 gl_GNULIB_ENABLED_sigprocmask_TRUE
 gl_GNULIB_ENABLED_pathmax_FALSE
 gl_GNULIB_ENABLED_pathmax_TRUE
+>>>>>>> MERGE-SOURCE
 gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_FALSE
 gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_TRUE
 gl_GNULIB_ENABLED_dosname_FALSE
@@ -672,14 +722,11 @@ REPLACE_FPURGE
 REPLACE_FPRINTF
 REPLACE_FOPEN
 REPLACE_FFLUSH
-REPLACE_FDOPEN
 REPLACE_FCLOSE
 REPLACE_DPRINTF
 HAVE_VDPRINTF
 HAVE_VASPRINTF
 HAVE_RENAMEAT
-HAVE_POPEN
-HAVE_PCLOSE
 HAVE_FTELLO
 HAVE_FSEEKO
 HAVE_DPRINTF
@@ -717,7 +764,6 @@ GNULIB_PRINTF_POSIX
 GNULIB_PRINTF
 GNULIB_POPEN
 GNULIB_PERROR
-GNULIB_PCLOSE
 GNULIB_OBSTACK_PRINTF_POSIX
 GNULIB_OBSTACK_PRINTF
 GNULIB_GETS
@@ -742,7 +788,6 @@ GNULIB_FOPEN
 GNULIB_FGETS
 GNULIB_FGETC
 GNULIB_FFLUSH
-GNULIB_FDOPEN
 GNULIB_FCLOSE
 GNULIB_DPRINTF
 NEXT_AS_FIRST_DIRECTIVE_STDDEF_H
@@ -761,25 +806,6 @@ GL_GENERATE_STDARG_H_TRUE
 STDARG_H
 NEXT_AS_FIRST_DIRECTIVE_STDARG_H
 NEXT_STDARG_H
-NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H
-NEXT_SIGNAL_H
-REPLACE_RAISE
-REPLACE_PTHREAD_SIGMASK
-HAVE_SIGHANDLER_T
-HAVE_TYPE_VOLATILE_SIG_ATOMIC_T
-HAVE_STRUCT_SIGACTION_SA_SIGACTION
-HAVE_SIGACTION
-HAVE_SIGINFO_T
-HAVE_SIGSET_T
-HAVE_RAISE
-HAVE_PTHREAD_SIGMASK
-HAVE_POSIX_SIGNALBLOCKING
-GNULIB_SIGACTION
-GNULIB_SIGPROCMASK
-GNULIB_SIGNAL_H_SIGPIPE
-GNULIB_RAISE
-GNULIB_PTHREAD_SIGMASK
-LIB_PTHREAD_SIGMASK
 REPLACE_TIMEGM
 REPLACE_NANOSLEEP
 REPLACE_MKTIME
@@ -824,7 +850,6 @@ GNULIB_LSTAT
 GNULIB_LCHMOD
 GNULIB_FUTIMENS
 GNULIB_FSTATAT
-GNULIB_FSTAT
 GNULIB_FCHMODAT
 NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H
 NEXT_INTTYPES_H
@@ -978,7 +1003,6 @@ HAVE_DECL_GETUSERSHELL
 HAVE_DECL_GETPAGESIZE
 HAVE_DECL_GETLOGIN_R
 HAVE_DECL_GETDOMAINNAME
-HAVE_DECL_FDATASYNC
 HAVE_DECL_FCHDIR
 HAVE_DECL_ENVIRON
 HAVE_USLEEP
@@ -1003,7 +1027,6 @@ HAVE_GETGROUPS
 HAVE_GETDTABLESIZE
 HAVE_FTRUNCATE
 HAVE_FSYNC
-HAVE_FDATASYNC
 HAVE_FCHOWNAT
 HAVE_FCHDIR
 HAVE_FACCESSAT
@@ -1046,7 +1069,6 @@ GNULIB_GETDOMAINNAME
 GNULIB_GETCWD
 GNULIB_FTRUNCATE
 GNULIB_FSYNC
-GNULIB_FDATASYNC
 GNULIB_FCHOWNAT
 GNULIB_FCHDIR
 GNULIB_FACCESSAT
@@ -1054,16 +1076,16 @@ GNULIB_EUIDACCESS
 GNULIB_ENVIRON
 GNULIB_DUP3
 GNULIB_DUP2
-GNULIB_DUP
 GNULIB_CLOSE
 GNULIB_CHOWN
-GNULIB_CHDIR
 GL_GENERATE_ALLOCA_H_FALSE
 GL_GENERATE_ALLOCA_H_TRUE
 ALLOCA_H
 ALLOCA
 GL_COND_LIBTOOL_FALSE
 GL_COND_LIBTOOL_TRUE
+<<<<<<< TREE
+=======
 POST_ALLOC_OBJ
 PRE_ALLOC_OBJ
 CYGWIN_OBJ
@@ -1114,6 +1136,7 @@ LIBRESOLV
 LIBHESIOD
 TERMCAP_OBJ
 LIBS_TERMCAP
+>>>>>>> MERGE-SOURCE
 BLESSMAIL_TARGET
 LIBS_MAIL
 liblockfile
@@ -1141,12 +1164,8 @@ LIBXTR6
 LIBGNUTLS_LIBS
 LIBGNUTLS_CFLAGS
 LIBSELINUX_LIBS
-SETTINGS_LIBS
-SETTINGS_CFLAGS
 GCONF_LIBS
 GCONF_CFLAGS
-GSETTINGS_LIBS
-GSETTINGS_CFLAGS
 DBUS_OBJ
 DBUS_LIBS
 DBUS_CFLAGS
@@ -1176,9 +1195,9 @@ ALSA_LIBS
 ALSA_CFLAGS
 PKG_CONFIG
 LIBSOUND
-CRT_DIR
 START_FILES
 LIB_MATH
+CRT_DIR
 LIBS_SYSTEM
 C_SWITCH_SYSTEM
 UNEXEC_OBJ
@@ -1225,7 +1244,6 @@ build
 PROFILING_CFLAGS
 MAINT
 GZIP_INFO
-cache_file
 am__untar
 am__tar
 AMTAR
@@ -1321,7 +1339,6 @@ with_ns
 with_gpm
 with_dbus
 with_gconf
-with_gsettings
 with_selinux
 with_gnutls
 with_makeinfo
@@ -1979,8 +1996,8 @@ Optional Features:
   --disable-ns-self-contained
                           disable self contained build under NeXTstep
   --enable-asserts        compile code with asserts enabled
-  --disable-maintainer-mode
-                          disable make rules and dependencies not useful (and
+  --enable-maintainer-mode
+                          enable make rules and dependencies not useful (and
                           sometimes confusing) to the casual installer
   --enable-locallisppath=PATH
                           directories Emacs should search for lisp files
@@ -2040,7 +2057,6 @@ Optional Packages:
                           console
   --without-dbus          don't compile with D-Bus support
   --without-gconf         don't compile with GConf support
-  --without-gsettings     don't compile with GSettings support
   --without-selinux       don't compile with SELinux support
   --without-gnutls        don't use -lgnutls for SSL/TLS support
   --without-makeinfo      don't require makeinfo for building manuals
@@ -2495,6 +2511,63 @@ $as_echo "$ac_res" >&6; }
 
 } # ac_fn_c_check_header_preproc
 
+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
+# ----------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_c_check_member ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+$as_echo_n "checking for $2.$3... " >&6; }
+if { as_var=$4; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$4=yes"
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$4=yes"
+else
+  eval "$4=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$4
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_member
+
 # ac_fn_c_check_func LINENO FUNC VAR
 # ----------------------------------
 # Tests whether FUNC exists, setting the cache variable VAR accordingly
@@ -2562,6 +2635,8 @@ $as_echo "$ac_res" >&6; }
 
 } # ac_fn_c_check_func
 
+<<<<<<< TREE
+=======
 # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
 # ----------------------------------------------------
 # Tries to find if the field MEMBER exists in type AGGR, after including
@@ -2673,6 +2748,7 @@ $as_echo "$ac_res" >&6; }
 
 } # ac_fn_c_check_type
 
+>>>>>>> MERGE-SOURCE
 # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
 # --------------------------------------------
 # Tries to find the compile-time value of EXPR in a program that includes
@@ -2850,6 +2926,60 @@ rm -f conftest.val
   as_fn_set_status $ac_retval
 
 } # ac_fn_c_compute_int
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+        return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+           return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_type
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
@@ -3144,7 +3274,6 @@ as_fn_append ac_header_list " stdint.h"
 as_fn_append ac_header_list " inttypes.h"
 as_fn_append ac_func_list " lstat"
 as_fn_append ac_func_list " alarm"
-as_fn_append ac_func_list " pthread_sigmask"
 as_fn_append ac_func_list " readlink"
 as_fn_append ac_header_list " sys/socket.h"
 as_fn_append ac_func_list " tzset"
@@ -4047,14 +4176,6 @@ else
 fi
 
 
-# Check whether --with-gsettings was given.
-if test "${with_gsettings+set}" = set; then :
-  withval=$with_gsettings;
-else
-     with_gsettings=yes
-fi
-
-
 # Check whether --with-selinux was given.
 if test "${with_selinux+set}" = set; then :
   withval=$with_selinux;
@@ -4082,9 +4203,6 @@ else
 fi
 
 
-## Makefile.in needs the cache file name.
-
-
 ## This is an option because I do not know if all info/man support
 ## compressed files, nor how to test if they do so.
 
@@ -4516,7 +4634,7 @@ case "${canonical}" in
   ## Silicon Graphics machines
   ## Iris 4D
   mips-sgi-irix6.5 )
-    opsys=irix6-5
+    machine=iris4d opsys=irix6-5
     # Without defining _LANGUAGE_C, things get masked out in the headers
     # so that, for instance, grepping for `free' in stdlib.h fails and
     # AC_HEADER_STD_C fails.   (MIPSPro 7.2.1.2m compilers, Irix 6.5.3m).
@@ -6962,16 +7080,22 @@ esac
   # Code from module manywarnings:
   # Code from module mktime:
   # Code from module multiarch:
+<<<<<<< TREE
+=======
   # Code from module nocrash:
   # Code from module pathmax:
   # Code from module pthread_sigmask:
+>>>>>>> MERGE-SOURCE
   # Code from module readlink:
-  # Code from module signal-h:
+<<<<<<< TREE
+=======
+  # Code from module signal:
   # Code from module sigprocmask:
   # Code from module snippet/_Noreturn:
   # Code from module snippet/arg-nonnull:
   # Code from module snippet/c++defs:
   # Code from module snippet/warn-on-use:
+>>>>>>> MERGE-SOURCE
   # Code from module socklen:
   # Code from module ssize_t:
   # Code from module stat:
@@ -6985,8 +7109,6 @@ esac
   # Code from module stdio:
   # Code from module stdlib:
   # Code from module strftime:
-  # Code from module strtoimax:
-  # Code from module strtoll:
   # Code from module strtoull:
   # Code from module strtoumax:
   # Code from module symlink:
@@ -8138,8 +8260,6 @@ fi
 
 # Suppress obsolescent Autoconf test for size_t; Emacs assumes C89 or better.
 
-# Likewise for obsolescent test for uid_t, gid_t; Emacs assumes them.
-
 
 # Check whether --enable-largefile was given.
 if test "${enable_largefile+set}" = set; then :
@@ -8343,6 +8463,76 @@ fi
 
 
 
+## If user specified a crt-dir, use that unconditionally.
+if test "X$CRT_DIR" = "X"; then
+
+  case "$canonical" in
+    x86_64-*-linux-gnu* | s390x-*-linux-gnu*)
+    ## On x86-64 and s390x GNU/Linux distributions, the standard library
+    ## can be in a variety of places.  We only try /usr/lib64 and /usr/lib.
+    ## For anything else (eg /usr/lib32), it is up the user to specify
+    ## the location (bug#5655).
+    ## Test for crtn.o, not just the directory, because sometimes the
+    ## directory exists but does not have the relevant files (bug#1287).
+    ## FIXME better to test for binary compatibility somehow.
+    test -e /usr/lib64/crtn.o && CRT_DIR=/usr/lib64
+    ;;
+
+    powerpc64-*-linux-gnu* | sparc64-*-linux-gnu*) CRT_DIR=/usr/lib64 ;;
+  esac
+
+  case "$opsys" in
+    hpux10-20) CRT_DIR=/lib ;;
+  esac
+
+  ## Default is /usr/lib.
+  test "X$CRT_DIR" = "X" && CRT_DIR=/usr/lib
+
+  ## If we're using gcc, try to determine it automatically by asking
+  ## gcc.  [If this doesn't work, CRT_DIR will remain at the
+  ## system-dependent default from above.]
+  if test "x${GCC}" = xyes; then
+     crt_file=`$CC --print-file-name=crt1.o 2>/dev/null`
+     case "$crt_file" in
+       */*)
+         CRT_DIR=`$as_dirname -- "$crt_file" ||
+$as_expr X"$crt_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$crt_file" : 'X\(//\)[^/]' \| \
+        X"$crt_file" : 'X\(//\)$' \| \
+        X"$crt_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$crt_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)[^/].*/{
+           s//\1/
+           q
+         }
+         /^X\(\/\/\)$/{
+           s//\1/
+           q
+         }
+         /^X\(\/\).*/{
+           s//\1/
+           q
+         }
+         s/.*/./; q'`
+         ;;
+     esac
+  fi
+
+else
+
+  ## Some platforms don't use any of these files, so it is not
+  ## appropriate to put this test outside the if block.
+  test -e $CRT_DIR/crtn.o || test -e $CRT_DIR/crt0.o || \
+    as_fn_error "crt*.o not found in specified location." "$LINENO" 5
+
+fi
+
+
+
 LIB_MATH=-lm
 LIB_STANDARD=
 START_FILES=
@@ -8378,6 +8568,8 @@ esac
 
 
 
+<<<<<<< TREE
+=======
 crt_files=
 
 for file in x $LIB_STANDARD $START_FILES; do
@@ -8484,6 +8676,7 @@ case $opsys in
 esac
 
 
+>>>>>>> MERGE-SOURCE
 
 
 
@@ -8644,9 +8837,9 @@ $as_echo "no" >&6; }
 
   if test $HAVE_ALSA = yes; then
     SAVE_CFLAGS="$CFLAGS"
-    SAVE_LIBS="$LIBS"
+    SAVE_LDFLAGS="$LDFLAGS"
     CFLAGS="$ALSA_CFLAGS $CFLAGS"
-    LIBS="$ALSA_LIBS $LIBS"
+    LDFLAGS="$ALSA_LIBS $LDFLAGS"
     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <asoundlib.h>
@@ -8689,7 +8882,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     fi
 
     CFLAGS="$SAVE_CFLAGS"
-    LIBS="$SAVE_LIBS"
+    LDFLAGS="$SAVE_LDFLAGS"
     LIBSOUND="$LIBSOUND $ALSA_LIBS"
     CFLAGS_SOUND="$CFLAGS_SOUND $ALSA_CFLAGS"
 
@@ -9023,6 +9216,8 @@ $as_echo "#define NO_MATHERR 1" >>confdefs.h
 
 fi
 
+<<<<<<< TREE
+=======
 for ac_header in sys/socket.h
 do :
   ac_fn_c_check_header_mongrel "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "$ac_includes_default"
@@ -9035,6 +9230,7 @@ fi
 
 done
 
+>>>>>>> MERGE-SOURCE
 for ac_header in net/if.h
 do :
   ac_fn_c_check_header_compile "$LINENO" "net/if.h" "ac_cv_header_net_if_h" "$ac_includes_default
@@ -9051,6 +9247,8 @@ fi
 
 done
 
+<<<<<<< TREE
+=======
 for ac_header in ifaddrs.h
 do :
   ac_fn_c_check_header_compile "$LINENO" "ifaddrs.h" "ac_cv_header_ifaddrs_h" "$ac_includes_default
@@ -9096,6 +9294,7 @@ _ACEOF
 fi
 done
 
+>>>>>>> MERGE-SOURCE
 
 ac_fn_c_check_member "$LINENO" "struct ifreq" "ifr_flags" "ac_cv_member_struct_ifreq_ifr_flags" "$ac_includes_default
 #if HAVE_SYS_SOCKET_H
@@ -9177,6 +9376,8 @@ _ACEOF
 
 
 fi
+<<<<<<< TREE
+=======
 ac_fn_c_check_member "$LINENO" "struct ifreq" "ifr_addr.sa_len" "ac_cv_member_struct_ifreq_ifr_addr_sa_len" "$ac_includes_default
 #if HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
@@ -9193,6 +9394,7 @@ _ACEOF
 
 
 fi
+>>>>>>> MERGE-SOURCE
 
 
 
@@ -10300,7 +10502,7 @@ $as_echo "#define DOUG_LEA_MALLOC 1" >>confdefs.h
   ## Use mmap directly for allocating larger buffers.
   ## FIXME this comes from src/s/{gnu,gnu-linux}.h:
   ## #ifdef DOUG_LEA_MALLOC; #undef REL_ALLOC; #endif
-  ## Does the AC_FUNC_MMAP test below make this check unnecessary?
+  ## Does the AC_FUNC_MMAP test below make this check unecessary?
   case "$opsys" in
     gnu*) REL_ALLOC=no ;;
   esac
 done
 
 if test "$ac_cv_header_pthread_h"; then
-        if test "$GMALLOC_OBJ" = gmalloc.o; then
-    emacs_pthread_function=pthread_atfork
-  else
-    emacs_pthread_function=pthread_self
-  fi
-  as_ac_Lib=`$as_echo "ac_cv_lib_pthread_$emacs_pthread_function" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $emacs_pthread_function in -lpthread" >&5
-$as_echo_n "checking for $emacs_pthread_function in -lpthread... " >&6; }
-if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_self in -lpthread" >&5
+$as_echo_n "checking for pthread_self in -lpthread... " >&6; }
+if test "${ac_cv_lib_pthread_pthread_self+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -10643,29 +10839,27 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 #ifdef __cplusplus
 extern "C"
 #endif
-char $emacs_pthread_function ();
+char pthread_self ();
 int
 main ()
 {
-return $emacs_pthread_function ();
+return pthread_self ();
   ;
   return 0;
 }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  eval "$as_ac_Lib=yes"
+  ac_cv_lib_pthread_pthread_self=yes
 else
-  eval "$as_ac_Lib=no"
+  ac_cv_lib_pthread_pthread_self=no
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-eval ac_res=\$$as_ac_Lib
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-eval as_val=\$$as_ac_Lib
-   if test "x$as_val" = x""yes; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_self" >&5
+$as_echo "$ac_cv_lib_pthread_pthread_self" >&6; }
+if test "x$ac_cv_lib_pthread_pthread_self" = x""yes; then :
   HAVE_PTHREAD=yes
 fi
 
@@ -11641,6 +11835,8 @@ done
 fi
 
 
+<<<<<<< TREE
+=======
 HAVE_GSETTINGS=no
 if test "${HAVE_X11}" = "yes" && test "${with_gsettings}" = "yes"; then
 
@@ -11744,6 +11940,7 @@ $as_echo "#define HAVE_GSETTINGS 1" >>confdefs.h
    fi
 fi
 
+>>>>>>> MERGE-SOURCE
 HAVE_GCONF=no
 if test "${HAVE_X11}" = "yes" && test "${with_gconf}" = "yes"; then
 
@@ -11842,17 +12039,7 @@ $as_echo "no" >&6; }
 
 $as_echo "#define HAVE_GCONF 1" >>confdefs.h
 
-            SETTINGS_CFLAGS="$SETTINGS_CFLAGS $GCONF_CFLAGS"
-      SETTINGS_LIBS="$SETTINGS_LIBS $GCONF_LIBS"
-   fi
-fi
-
-if test "$HAVE_GSETTINGS" = "yes" || test "$HAVE_GCONF" = "yes"; then
-    SAVE_CFLAGS="$CFLAGS"
-    SAVE_LIBS="$LIBS"
-    CFLAGS="$SETTINGS_CFLAGS $CFLAGS"
-    LIBS="$SETTINGS_LIBS $LIBS"
-    for ac_func in g_type_init
+            for ac_func in g_type_init
 do :
   ac_fn_c_check_func "$LINENO" "g_type_init" "ac_cv_func_g_type_init"
 if test "x$ac_cv_func_g_type_init" = x""yes; then :
@@ -11863,13 +12050,9 @@ _ACEOF
 fi
 done
 
-    CFLAGS="$SAVE_CFLAGS"
-    LIBS="$SAVE_LIBS"
+   fi
 fi
 
-
-
-
 HAVE_LIBSELINUX=no
 LIBSELINUX_LIBS=
 if test "${with_selinux}" = "yes"; then
@@ -13857,7 +14040,6 @@ fi
 
 
 ### Use libxml (-lxml2) if available
-HAVE_LIBXML2=no
 if test "${with_xml2}" != "no"; then
   ### I'm not sure what the version number should be, so I just guessed.
 
@@ -14483,6 +14665,9 @@ $as_echo "#define GETPGRP_VOID 1" >>confdefs.h
 fi
 
 
+<<<<<<< TREE
+# Configure gnulib.
+=======
 # UNIX98 PTYs.
 for ac_func in grantpt
 do :
@@ -16195,6 +16380,7 @@ fi
 
 
 # Configure gnulib here, now that we know LIBS.
+>>>>>>> MERGE-SOURCE
 
 
 
@@ -16731,10 +16917,8 @@ $as_echo "#define HAVE_C99_STRTOLD 1" >>confdefs.h
   fi
 
 
-  GNULIB_CHDIR=0;
   GNULIB_CHOWN=0;
   GNULIB_CLOSE=0;
-  GNULIB_DUP=0;
   GNULIB_DUP2=0;
   GNULIB_DUP3=0;
   GNULIB_ENVIRON=0;
@@ -16742,7 +16926,6 @@ $as_echo "#define HAVE_C99_STRTOLD 1" >>confdefs.h
   GNULIB_FACCESSAT=0;
   GNULIB_FCHDIR=0;
   GNULIB_FCHOWNAT=0;
-  GNULIB_FDATASYNC=0;
   GNULIB_FSYNC=0;
   GNULIB_FTRUNCATE=0;
   GNULIB_GETCWD=0;
@@ -16785,7 +16968,6 @@ $as_echo "#define HAVE_C99_STRTOLD 1" >>confdefs.h
   HAVE_FACCESSAT=1;
   HAVE_FCHDIR=1;
   HAVE_FCHOWNAT=1;
-  HAVE_FDATASYNC=1;
   HAVE_FSYNC=1;
   HAVE_FTRUNCATE=1;
   HAVE_GETDTABLESIZE=1;
@@ -16810,7 +16992,6 @@ $as_echo "#define HAVE_C99_STRTOLD 1" >>confdefs.h
   HAVE_USLEEP=1;
   HAVE_DECL_ENVIRON=1;
   HAVE_DECL_FCHDIR=1;
-  HAVE_DECL_FDATASYNC=1;
   HAVE_DECL_GETDOMAINNAME=1;
   HAVE_DECL_GETLOGIN_R=1;
   HAVE_DECL_GETPAGESIZE=1;
@@ -17121,9 +17302,9 @@ _ACEOF
                    ;;
                esac
 
-               gl_absolute_header_sed='\|'"${gl_dirsep_regex}"'getopt.h|{
-                   s|.*"\(.*'"${gl_dirsep_regex}"'getopt.h\)".*|\1|
-                   s|^/[^/]|//&|
+               gl_absolute_header_sed='\#'"${gl_dirsep_regex}"'getopt.h#{
+                   s#.*"\(.*'"${gl_dirsep_regex}"'getopt.h\)".*#\1#
+                   s#^/[^/]#//&#
                    p
                    q
                  }'
@@ -17212,7 +17393,7 @@ int *p = &optreset; return optreset;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"; then :
   gl_optind_min=1
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -17233,8 +17414,7 @@ else
 fi
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
                 gl_save_CPPFLAGS=$CPPFLAGS
         CPPFLAGS="$CPPFLAGS -DOPTIND_MIN=$gl_optind_min"
@@ -17257,20 +17437,22 @@ int
 main ()
 {
   {
-    static char program[] = "program";
-    static char a[] = "-a";
-    static char foo[] = "foo";
-    static char bar[] = "bar";
-    char *argv[] = { program, a, foo, bar, NULL };
+    int argc = 0;
+    char *argv[10];
     int c;
 
+    argv[argc++] = "program";
+    argv[argc++] = "-a";
+    argv[argc++] = "foo";
+    argv[argc++] = "bar";
+    argv[argc] = NULL;
     optind = OPTIND_MIN;
     opterr = 0;
 
-    c = getopt (4, argv, "ab");
+    c = getopt (argc, argv, "ab");
     if (!(c == 'a'))
       return 1;
-    c = getopt (4, argv, "ab");
+    c = getopt (argc, argv, "ab");
     if (!(c == -1))
       return 2;
     if (!(optind == 2))
@@ -17278,20 +17460,22 @@ main ()
   }
   /* Some internal state exists at this point.  */
   {
-    static char program[] = "program";
-    static char donald[] = "donald";
-    static char p[] = "-p";
-    static char billy[] = "billy";
-    static char duck[] = "duck";
-    static char a[] = "-a";
-    static char bar[] = "bar";
-    char *argv[] = { program, donald, p, billy, duck, a, bar, NULL };
+    int argc = 0;
+    char *argv[10];
     int c;
 
+    argv[argc++] = "program";
+    argv[argc++] = "donald";
+    argv[argc++] = "-p";
+    argv[argc++] = "billy";
+    argv[argc++] = "duck";
+    argv[argc++] = "-a";
+    argv[argc++] = "bar";
+    argv[argc] = NULL;
     optind = OPTIND_MIN;
     opterr = 0;
 
-    c = getopt (7, argv, "+abp:q:");
+    c = getopt (argc, argv, "+abp:q:");
     if (!(c == -1))
       return 4;
     if (!(strcmp (argv[0], "program") == 0))
@@ -17313,9 +17497,7 @@ main ()
   }
   /* Detect MacOS 10.5, AIX 7.1 bug.  */
   {
-    static char program[] = "program";
-    static char ab[] = "-ab";
-    char *argv[3] = { program, ab, NULL };
+    char *argv[3] = { "program", "-ab", NULL };
     optind = OPTIND_MIN;
     opterr = 0;
     if (getopt (2, argv, "ab:") != 'a')
@@ -17510,22 +17692,19 @@ main ()
                 and fails on MacOS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5,
                 OSF/1 5.1, Solaris 10.  */
              {
-               static char conftest[] = "conftest";
-               static char plus[] = "-+";
-               char *argv[3] = { conftest, plus, NULL };
+               char *myargv[3];
+               myargv[0] = "conftest";
+               myargv[1] = "-+";
+               myargv[2] = 0;
                opterr = 0;
-               if (getopt (2, argv, "+a") != '?')
+               if (getopt (2, myargv, "+a") != '?')
                  result |= 1;
              }
              /* This code succeeds on glibc 2.8, mingw,
                 and fails on MacOS X 10.5, OpenBSD 4.0, AIX 5.2, HP-UX 11,
                 IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.5.x.  */
              {
-               static char program[] = "program";
-               static char p[] = "-p";
-               static char foo[] = "foo";
-               static char bar[] = "bar";
-               char *argv[] = { program, p, foo, bar, NULL };
+               char *argv[] = { "program", "-p", "foo", "bar", NULL };
 
                optind = 1;
                if (getopt (4, argv, "p::") != 'p')
@@ -17539,10 +17718,7 @@ main ()
              }
              /* This code succeeds on glibc 2.8 and fails on Cygwin 1.7.0.  */
              {
-               static char program[] = "program";
-               static char foo[] = "foo";
-               static char p[] = "-p";
-               char *argv[] = { program, foo, p, NULL };
+               char *argv[] = { "program", "foo", "-p", NULL };
                optind = 0;
                if (getopt (3, argv, "-p") != 1)
                  result |= 16;
@@ -17551,26 +17727,13 @@ main ()
              }
              /* This code fails on glibc 2.11.  */
              {
-               static char program[] = "program";
-               static char b[] = "-b";
-               static char a[] = "-a";
-               char *argv[] = { program, b, a, NULL };
+               char *argv[] = { "program", "-b", "-a", NULL };
                optind = opterr = 0;
                if (getopt (3, argv, "+:a:b") != 'b')
                  result |= 64;
                else if (getopt (3, argv, "+:a:b") != ':')
                  result |= 64;
              }
-             /* This code dumps core on glibc 2.14.  */
-             {
-               static char program[] = "program";
-               static char w[] = "-W";
-               static char dummy[] = "dummy";
-               char *argv[] = { program, w, dummy, NULL };
-               optind = opterr = 1;
-               if (getopt (3, argv, "W;") != 'W')
-                 result |= 128;
-             }
              return result;
 
   ;
@@ -17878,9 +18041,9 @@ _ACEOF
                    ;;
                esac
 
-               gl_absolute_header_sed='\|'"${gl_dirsep_regex}"'stdint.h|{
-                   s|.*"\(.*'"${gl_dirsep_regex}"'stdint.h\)".*|\1|
-                   s|^/[^/]|//&|
+               gl_absolute_header_sed='\#'"${gl_dirsep_regex}"'stdint.h#{
+                   s#.*"\(.*'"${gl_dirsep_regex}"'stdint.h\)".*#\1#
+                   s#^/[^/]#//&#
                    p
                    q
                  }'
@@ -18510,10 +18673,6 @@ _ACEOF
 
 
 
-          if test $BITSIZEOF_WINT_T -lt 32; then
-    BITSIZEOF_WINT_T=32
-  fi
-
     STDINT_H=stdint.h
   fi
 
@@ -18589,9 +18748,9 @@ _ACEOF
                    ;;
                esac
 
-               gl_absolute_header_sed='\|'"${gl_dirsep_regex}"'inttypes.h|{
-                   s|.*"\(.*'"${gl_dirsep_regex}"'inttypes.h\)".*|\1|
-                   s|^/[^/]|//&|
+               gl_absolute_header_sed='\#'"${gl_dirsep_regex}"'inttypes.h#{
+                   s#.*"\(.*'"${gl_dirsep_regex}"'inttypes.h\)".*#\1#
+                   s#^/[^/]#//&#
                    p
                    q
                  }'
@@ -18632,7 +18791,6 @@ $as_echo "#define GL_TRIGGER_STDC_LIMIT_MACROS 1" >>confdefs.h
 
 
      GNULIB_FCHMODAT=0;
-  GNULIB_FSTAT=0;
   GNULIB_FSTATAT=0;
   GNULIB_FUTIMENS=0;
   GNULIB_LCHMOD=0;
@@ -18745,14 +18903,14 @@ _ACEOF
 
 
 
+<<<<<<< TREE
+=======
   GNULIB_PTHREAD_SIGMASK=0;
-  GNULIB_RAISE=0;
   GNULIB_SIGNAL_H_SIGPIPE=0;
   GNULIB_SIGPROCMASK=0;
   GNULIB_SIGACTION=0;
     HAVE_POSIX_SIGNALBLOCKING=1;
   HAVE_PTHREAD_SIGMASK=1;
-  HAVE_RAISE=1;
   HAVE_SIGSET_T=1;
   HAVE_SIGINFO_T=1;
   HAVE_SIGACTION=1;
@@ -18762,7 +18920,6 @@ _ACEOF
 
   HAVE_SIGHANDLER_T=1;
   REPLACE_PTHREAD_SIGMASK=0;
-  REPLACE_RAISE=0;
 
 
 
@@ -18790,6 +18947,7 @@ fi
 
 
 
+>>>>>>> MERGE-SOURCE
 
 
    if test $ac_cv_header_sys_socket_h = no; then
@@ -18934,7 +19092,6 @@ $as_echo "#define HAVE_WCHAR_T 1" >>confdefs.h
 
   GNULIB_DPRINTF=0;
   GNULIB_FCLOSE=0;
-  GNULIB_FDOPEN=0;
   GNULIB_FFLUSH=0;
   GNULIB_FGETC=0;
   GNULIB_FGETS=0;
@@ -18959,7 +19116,6 @@ $as_echo "#define HAVE_WCHAR_T 1" >>confdefs.h
   GNULIB_GETS=0;
   GNULIB_OBSTACK_PRINTF=0;
   GNULIB_OBSTACK_PRINTF_POSIX=0;
-  GNULIB_PCLOSE=0;
   GNULIB_PERROR=0;
   GNULIB_POPEN=0;
   GNULIB_PRINTF=0;
@@ -18997,14 +19153,11 @@ $as_echo "#define HAVE_WCHAR_T 1" >>confdefs.h
   HAVE_DPRINTF=1;
   HAVE_FSEEKO=1;
   HAVE_FTELLO=1;
-  HAVE_PCLOSE=1;
-  HAVE_POPEN=1;
   HAVE_RENAMEAT=1;
   HAVE_VASPRINTF=1;
   HAVE_VDPRINTF=1;
   REPLACE_DPRINTF=0;
   REPLACE_FCLOSE=0;
-  REPLACE_FDOPEN=0;
   REPLACE_FFLUSH=0;
   REPLACE_FOPEN=0;
   REPLACE_FPRINTF=0;
@@ -19149,6 +19302,8 @@ fi
 
 
 
+<<<<<<< TREE
+=======
 
 
 ac_fn_c_check_decl "$LINENO" "strtoimax" "ac_cv_have_decl_strtoimax" "$ac_includes_default"
@@ -19164,6 +19319,7 @@ _ACEOF
 
 
 
+>>>>>>> MERGE-SOURCE
 ac_fn_c_check_decl "$LINENO" "strtoumax" "ac_cv_have_decl_strtoumax" "$ac_includes_default"
 if test "x$ac_cv_have_decl_strtoumax" = x""yes; then :
   ac_have_decl=1
 
 
 
-ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
-if test "x$ac_cv_type_mode_t" = x""yes; then :
-
-else
-
-cat >>confdefs.h <<_ACEOF
-#define mode_t int
-_ACEOF
-
-fi
-
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C/C++ restrict keyword" >&5
 $as_echo_n "checking for C/C++ restrict keyword... " >&6; }
 if test "${ac_cv_c_restrict+set}" = set; then :
@@ -19418,9 +19563,9 @@ _ACEOF
                    ;;
                esac
 
-               gl_absolute_header_sed='\|'"${gl_dirsep_regex}"'time.h|{
-                   s|.*"\(.*'"${gl_dirsep_regex}"'time.h\)".*|\1|
-                   s|^/[^/]|//&|
+               gl_absolute_header_sed='\#'"${gl_dirsep_regex}"'time.h#{
+                   s#.*"\(.*'"${gl_dirsep_regex}"'time.h\)".*#\1#
+                   s#^/[^/]#//&#
                    p
                    q
                  }'
@@ -19448,6 +19593,8 @@ $as_echo "$gl_cv_next_time_h" >&6; }
 
 
 
+
+
 ac_fn_c_check_decl "$LINENO" "localtime_r" "ac_cv_have_decl_localtime_r" "$ac_includes_default"
 if test "x$ac_cv_have_decl_localtime_r" = x""yes; then :
   ac_have_decl=1
@@ -19652,7 +19799,6 @@ if test $HAVE_DUP2 = 0 || test $REPLACE_DUP2 = 1; then
 
   gl_LIBOBJS="$gl_LIBOBJS dup2.$ac_objext"
 
-
 fi
 
 
@@ -20053,9 +20199,9 @@ else
   HAVE_SYS_LOADAVG_H=0
 fi
 ac_fn_c_check_decl "$LINENO" "getloadavg" "ac_cv_have_decl_getloadavg" "#if HAVE_SYS_LOADAVG_H
-    # include <sys/loadavg.h>
-    #endif
-    #include <stdlib.h>
+   # include <sys/loadavg.h>
+   #endif
+   #include <stdlib.h>
 "
 if test "x$ac_cv_have_decl_getloadavg" = x""yes; then :
 
@@ -20587,6 +20733,8 @@ fi
 
 
 
+<<<<<<< TREE
+=======
   LIB_PTHREAD_SIGMASK=
 
 
@@ -20821,6 +20969,7 @@ fi
 
 
 
+>>>>>>> MERGE-SOURCE
 
   if test $ac_cv_func_readlink = no; then
     HAVE_READLINK=0
@@ -20925,6 +21074,8 @@ fi
 
 
 
+<<<<<<< TREE
+=======
 
 
 
@@ -20964,9 +21115,9 @@ _ACEOF
                    ;;
                esac
 
-               gl_absolute_header_sed='\|'"${gl_dirsep_regex}"'signal.h|{
-                   s|.*"\(.*'"${gl_dirsep_regex}"'signal.h\)".*|\1|
-                   s|^/[^/]|//&|
+               gl_absolute_header_sed='\#'"${gl_dirsep_regex}"'signal.h#{
+                   s#.*"\(.*'"${gl_dirsep_regex}"'signal.h\)".*#\1#
+                   s#^/[^/]#//&#
                    p
                    q
                  }'
@@ -21024,6 +21175,7 @@ fi
 
 
 
+>>>>>>> MERGE-SOURCE
    ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "
 /* <sys/types.h> is not needed according to POSIX, but the
    <sys/socket.h> in i386-unknown-freebsd4.10 and
@@ -21208,9 +21360,9 @@ _ACEOF
                    ;;
                esac
 
-               gl_absolute_header_sed='\|'"${gl_dirsep_regex}"'stdarg.h|{
-                   s|.*"\(.*'"${gl_dirsep_regex}"'stdarg.h\)".*|\1|
-                   s|^/[^/]|//&|
+               gl_absolute_header_sed='\#'"${gl_dirsep_regex}"'stdarg.h#{
+                   s#.*"\(.*'"${gl_dirsep_regex}"'stdarg.h\)".*#\1#
+                   s#^/[^/]#//&#
                    p
                    q
                  }'
@@ -21408,9 +21560,9 @@ _ACEOF
                    ;;
                esac
 
-               gl_absolute_header_sed='\|'"${gl_dirsep_regex}"'stddef.h|{
-                   s|.*"\(.*'"${gl_dirsep_regex}"'stddef.h\)".*|\1|
-                   s|^/[^/]|//&|
+               gl_absolute_header_sed='\#'"${gl_dirsep_regex}"'stddef.h#{
+                   s#.*"\(.*'"${gl_dirsep_regex}"'stddef.h\)".*#\1#
+                   s#^/[^/]#//&#
                    p
                    q
                  }'
@@ -21478,9 +21630,9 @@ _ACEOF
                    ;;
                esac
 
-               gl_absolute_header_sed='\|'"${gl_dirsep_regex}"'stdio.h|{
-                   s|.*"\(.*'"${gl_dirsep_regex}"'stdio.h\)".*|\1|
-                   s|^/[^/]|//&|
+               gl_absolute_header_sed='\#'"${gl_dirsep_regex}"'stdio.h#{
+                   s#.*"\(.*'"${gl_dirsep_regex}"'stdio.h\)".*#\1#
+                   s#^/[^/]#//&#
                    p
                    q
                  }'
@@ -21570,9 +21722,9 @@ _ACEOF
                    ;;
                esac
 
-               gl_absolute_header_sed='\|'"${gl_dirsep_regex}"'stdlib.h|{
-                   s|.*"\(.*'"${gl_dirsep_regex}"'stdlib.h\)".*|\1|
-                   s|^/[^/]|//&|
+               gl_absolute_header_sed='\#'"${gl_dirsep_regex}"'stdlib.h#{
+                   s#.*"\(.*'"${gl_dirsep_regex}"'stdlib.h\)".*#\1#
+                   s#^/[^/]#//&#
                    p
                    q
                  }'
@@ -21619,6 +21771,8 @@ $as_echo "#define my_strftime nstrftime" >>confdefs.h
 
 
 
+<<<<<<< TREE
+=======
 
   if test "$ac_cv_have_decl_strtoimax" != yes; then
     HAVE_DECL_STRTOIMAX=0
@@ -21665,6 +21819,7 @@ fi
 
 
 
+>>>>>>> MERGE-SOURCE
   if test "$ac_cv_have_decl_strtoumax" != yes; then
     HAVE_DECL_STRTOUMAX=0
   fi
@@ -21827,9 +21982,9 @@ _ACEOF
                    ;;
                esac
 
-               gl_absolute_header_sed='\|'"${gl_dirsep_regex}"'sys/stat.h|{
-                   s|.*"\(.*'"${gl_dirsep_regex}"'sys/stat.h\)".*|\1|
-                   s|^/[^/]|//&|
+               gl_absolute_header_sed='\#'"${gl_dirsep_regex}"'sys/stat.h#{
+                   s#.*"\(.*'"${gl_dirsep_regex}"'sys/stat.h\)".*#\1#
+                   s#^/[^/]#//&#
                    p
                    q
                  }'
@@ -21859,8 +22014,6 @@ $as_echo "$gl_cv_next_sys_stat_h" >&6; }
 
 
 
-
-
       ac_fn_c_check_type "$LINENO" "nlink_t" "ac_cv_type_nlink_t" "#include <sys/types.h>
      #include <sys/stat.h>
 "
@@ -22007,9 +22160,9 @@ _ACEOF
                    ;;
                esac
 
-               gl_absolute_header_sed='\|'"${gl_dirsep_regex}"'unistd.h|{
-                   s|.*"\(.*'"${gl_dirsep_regex}"'unistd.h\)".*|\1|
-                   s|^/[^/]|//&|
+               gl_absolute_header_sed='\#'"${gl_dirsep_regex}"'unistd.h#{
+                   s#.*"\(.*'"${gl_dirsep_regex}"'unistd.h\)".*#\1#
+                   s#^/[^/]#//&#
                    p
                    q
                  }'
@@ -22052,10 +22205,12 @@ $as_echo "$gl_cv_next_unistd_h" >&6; }
 
   gl_gnulib_enabled_dosname=false
   gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=false
+<<<<<<< TREE
+=======
   gl_gnulib_enabled_pathmax=false
   gl_gnulib_enabled_sigprocmask=false
+>>>>>>> MERGE-SOURCE
   gl_gnulib_enabled_stat=false
-  gl_gnulib_enabled_strtoll=false
   gl_gnulib_enabled_strtoull=false
   gl_gnulib_enabled_verify=false
   func_gl_gnulib_m4code_dosname ()
@@ -22072,6 +22227,10 @@ $as_echo "$gl_cv_next_unistd_h" >&6; }
       gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=true
     fi
   }
+<<<<<<< TREE
+<<<<<<< TREE
+=======
+=======
   func_gl_gnulib_m4code_pathmax ()
   {
     if ! $gl_gnulib_enabled_pathmax; then
@@ -22081,6 +22240,7 @@ $as_echo "$gl_cv_next_unistd_h" >&6; }
       gl_gnulib_enabled_pathmax=true
     fi
   }
+>>>>>>> MERGE-SOURCE
   func_gl_gnulib_m4code_sigprocmask ()
   {
     if ! $gl_gnulib_enabled_sigprocmask; then
@@ -22109,9 +22269,7 @@ if test $HAVE_POSIX_SIGNALBLOCKING = 0; then
 
   gl_LIBOBJS="$gl_LIBOBJS sigprocmask.$ac_objext"
 
-
-
-
+  :
 fi
 
 
@@ -22127,6 +22285,7 @@ fi
       gl_gnulib_enabled_sigprocmask=true
     fi
   }
+>>>>>>> MERGE-SOURCE
   func_gl_gnulib_m4code_stat ()
   {
     if ! $gl_gnulib_enabled_stat; then
       if test $REPLACE_STAT = 1; then
         func_gl_gnulib_m4code_dosname
       fi
+<<<<<<< TREE
+      if $condition; then
+=======
       if test $REPLACE_STAT = 1; then
+<<<<<<< TREE
+>>>>>>> MERGE-SOURCE
+=======
         func_gl_gnulib_m4code_pathmax
       fi
       if test $REPLACE_STAT = 1; then
+>>>>>>> MERGE-SOURCE
         func_gl_gnulib_m4code_verify
       fi
     fi
   }
+<<<<<<< TREE
+=======
   func_gl_gnulib_m4code_strtoll ()
   {
     if ! $gl_gnulib_enabled_strtoll; then
@@ -22319,6 +22487,7 @@ fi
       gl_gnulib_enabled_strtoll=true
     fi
   }
+>>>>>>> MERGE-SOURCE
   func_gl_gnulib_m4code_strtoull ()
   {
     if ! $gl_gnulib_enabled_strtoull; then
   if test $REPLACE_LSTAT = 1; then
     func_gl_gnulib_m4code_stat
   fi
-  if test $HAVE_PTHREAD_SIGMASK = 0 || test $REPLACE_PTHREAD_SIGMASK = 1; then
-    func_gl_gnulib_m4code_sigprocmask
-  fi
   if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then
     func_gl_gnulib_m4code_stat
   fi
+<<<<<<< TREE
+  if test "$ac_cv_have_decl_strtoumax" != yes && test $ac_cv_func_strtoumax = no; then
+=======
   if test $ac_cv_func_strtoimax = no; then
     func_gl_gnulib_m4code_verify
   fi
@@ -22399,6 +22568,7 @@ fi
     func_gl_gnulib_m4code_strtoll
   fi
   if test $ac_cv_func_strtoumax = no; then
+>>>>>>> MERGE-SOURCE
     func_gl_gnulib_m4code_verify
   fi
   if test $ac_cv_func_strtoumax = no && test $ac_cv_type_unsigned_long_long_int = yes; then
@@ -22421,6 +22591,8 @@ else
   gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_FALSE=
 fi
 
+<<<<<<< TREE
+=======
    if $gl_gnulib_enabled_pathmax; then
   gl_GNULIB_ENABLED_pathmax_TRUE=
   gl_GNULIB_ENABLED_pathmax_FALSE='#'
@@ -22437,6 +22609,7 @@ else
   gl_GNULIB_ENABLED_sigprocmask_FALSE=
 fi
 
+>>>>>>> MERGE-SOURCE
    if $gl_gnulib_enabled_stat; then
   gl_GNULIB_ENABLED_stat_TRUE=
   gl_GNULIB_ENABLED_stat_FALSE='#'
@@ -22445,14 +22618,6 @@ else
   gl_GNULIB_ENABLED_stat_FALSE=
 fi
 
-   if $gl_gnulib_enabled_strtoll; then
-  gl_GNULIB_ENABLED_strtoll_TRUE=
-  gl_GNULIB_ENABLED_strtoll_FALSE='#'
-else
-  gl_GNULIB_ENABLED_strtoll_TRUE='#'
-  gl_GNULIB_ENABLED_strtoll_FALSE=
-fi
-
    if $gl_gnulib_enabled_strtoull; then
   gl_GNULIB_ENABLED_strtoull_TRUE=
   gl_GNULIB_ENABLED_strtoull_FALSE='#'
 
 
 
+# UNIX98 PTYs.
+for ac_func in grantpt
+do :
+  ac_fn_c_check_func "$LINENO" "grantpt" "ac_cv_func_grantpt"
+if test "x$ac_cv_func_grantpt" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_GRANTPT 1
+_ACEOF
+
+fi
+done
+
+
+# PTY-related GNU extensions.
+for ac_func in getpt
+do :
+  ac_fn_c_check_func "$LINENO" "getpt" "ac_cv_func_getpt"
+if test "x$ac_cv_func_getpt" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_GETPT 1
+_ACEOF
+
+fi
+done
+
+
+# Check this now, so that we will NOT find the above functions in ncurses.
+# That is because we have not set up to link ncurses in lib-src.
+# It's better to believe a function is not available
+# than to expect to find it in ncurses.
+# Also we need tputs and friends to be able to build at all.
+have_tputs_et_al=true
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing tputs" >&5
+$as_echo_n "checking for library containing tputs... " >&6; }
+if test "${ac_cv_search_tputs+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char tputs ();
+int
+main ()
+{
+return tputs ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' ncurses terminfo termcap; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_tputs=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if test "${ac_cv_search_tputs+set}" = set; then :
+  break
+fi
+done
+if test "${ac_cv_search_tputs+set}" = set; then :
+
+else
+  ac_cv_search_tputs=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_tputs" >&5
+$as_echo "$ac_cv_search_tputs" >&6; }
+ac_res=$ac_cv_search_tputs
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+  have_tputs_et_al=false
+fi
+
+if test "$have_tputs_et_al" != true; then
+  as_fn_error "I couldn't find termcap functions (tputs and friends).
+Maybe some development libraries/packages are missing?  Try installing
+libncurses-dev(el), libterminfo-dev(el) or similar." "$LINENO" 5
+fi
+# Must define this when any termcap library is found.
+
+$as_echo "#define HAVE_LIBNCURSES 1" >>confdefs.h
+
+## FIXME This was the cpp logic, but I am not sure it is right.
+## The above test has not necessarily found libncurses.
+HAVE_LIBNCURSES=yes
+
+## Use terminfo instead of termcap?
+## Note only system files NOT using terminfo are:
+## freebsd < 40000, ms-w32, msdos, netbsd < 599002500, and
+## darwin|gnu without ncurses.
+TERMINFO=no
+LIBS_TERMCAP=
+case "$opsys" in
+  ## cygwin: Fewer environment variables to go wrong, more terminal types.
+  ## hpux10-20: Use the system provided termcap(3) library.
+  ## openbsd: David Mazieres <dm@reeducation-labor.lcs.mit.edu> says this
+  ##  is necessary.  Otherwise Emacs dumps core when run -nw.
+  aix4-2|cygwin|hpux*|irix6-5|openbsd|sol2*|unixware) TERMINFO=yes ;;
+
+  ## darwin: Prevents crashes when running Emacs in Terminal.app under 10.2.
+  ##  The ncurses library has been moved out of the System framework in
+  ##  Mac OS X 10.2.  So if configure detects it, set the command-line
+  ##  option to use it.
+  darwin|gnu*)
+    ## (HAVE_LIBNCURSES was not always true, but is since 2010-03-18.)
+    if test "x$HAVE_LIBNCURSES" = "xyes"; then
+      TERMINFO=yes
+      LIBS_TERMCAP="-lncurses"
+    fi
+    ;;
+
+  freebsd)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether FreeBSD is new enough to use terminfo" >&5
+$as_echo_n "checking whether FreeBSD is new enough to use terminfo... " >&6; }
+    if test "${emacs_cv_freebsd_terminfo+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <osreldate.h>
+int
+main ()
+{
+#if __FreeBSD_version < 400000
+fail;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  emacs_cv_freebsd_terminfo=yes
+else
+  emacs_cv_freebsd_terminfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $emacs_cv_freebsd_terminfo" >&5
+$as_echo "$emacs_cv_freebsd_terminfo" >&6; }
+
+    if test $emacs_cv_freebsd_terminfo = yes; then
+      TERMINFO=yes
+      LIBS_TERMCAP="-lncurses"
+    else
+      LIBS_TERMCAP="-ltermcap"
+    fi
+    ;;
+
+  netbsd)
+    if test $ac_cv_search_tputs = -lterminfo; then
+      TERMINFO=yes
+      LIBS_TERMCAP="-lterminfo"
+    else
+      LIBS_TERMCAP="-ltermcap"
+    fi
+    ;;
+
+esac
+
+case "$opsys" in
+  ## hpux: Make sure we get select from libc rather than from libcurses
+  ##  because libcurses on HPUX 10.10 has a broken version of select.
+  ##  We used to use -lc -lcurses, but this may be cleaner.
+  hpux*) LIBS_TERMCAP="-ltermcap" ;;
+
+  openbsd) LIBS_TERMCAP="-lncurses" ;;
+
+  ## Must use system termcap, if we use any termcap.  It does special things.
+  sol2*) test "$TERMINFO" != yes && LIBS_TERMCAP="-ltermcap" ;;
+esac
+
+TERMCAP_OBJ=tparam.o
+if test $TERMINFO = yes; then
+
+$as_echo "#define TERMINFO 1" >>confdefs.h
+
+
+  ## Default used to be -ltermcap.  Add a case above if need something else.
+  test "x$LIBS_TERMCAP" = "x" && LIBS_TERMCAP="-lcurses"
+
+  TERMCAP_OBJ=terminfo.o
+fi
+
+
+
+
+# Do we have res_init, for detecting changes in /etc/resolv.conf?
+resolv=no
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+int
+main ()
+{
+return res_init();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  have_res_init=yes
+else
+  have_res_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+if test "$have_res_init" = no; then
+  OLIBS="$LIBS"
+  LIBS="$LIBS -lresolv"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for res_init with -lresolv" >&5
+$as_echo_n "checking for res_init with -lresolv... " >&6; }
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+int
+main ()
+{
+return res_init();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  have_res_init=yes
+else
+  have_res_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_res_init" >&5
+$as_echo "$have_res_init" >&6; }
+  if test "$have_res_init" = yes ; then
+    resolv=yes
+  fi
+  LIBS="$OLIBS"
+fi
+
+if test "$have_res_init" = yes; then
+
+$as_echo "#define HAVE_RES_INIT 1" >>confdefs.h
+
+fi
+
+# Do we need the Hesiod library to provide the support routines?
+LIBHESIOD=
+if test "$with_hesiod" != no ; then
+  # Don't set $LIBS here -- see comments above.  FIXME which comments?
+  ac_fn_c_check_func "$LINENO" "res_send" "ac_cv_func_res_send"
+if test "x$ac_cv_func_res_send" = x""yes; then :
+
+else
+  ac_fn_c_check_func "$LINENO" "__res_send" "ac_cv_func___res_send"
+if test "x$ac_cv_func___res_send" = x""yes; then :
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for res_send in -lresolv" >&5
+$as_echo_n "checking for res_send in -lresolv... " >&6; }
+if test "${ac_cv_lib_resolv_res_send+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lresolv  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char res_send ();
+int
+main ()
+{
+return res_send ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_resolv_res_send=yes
+else
+  ac_cv_lib_resolv_res_send=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_res_send" >&5
+$as_echo "$ac_cv_lib_resolv_res_send" >&6; }
+if test "x$ac_cv_lib_resolv_res_send" = x""yes; then :
+  resolv=yes
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __res_send in -lresolv" >&5
+$as_echo_n "checking for __res_send in -lresolv... " >&6; }
+if test "${ac_cv_lib_resolv___res_send+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lresolv  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char __res_send ();
+int
+main ()
+{
+return __res_send ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_resolv___res_send=yes
+else
+  ac_cv_lib_resolv___res_send=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv___res_send" >&5
+$as_echo "$ac_cv_lib_resolv___res_send" >&6; }
+if test "x$ac_cv_lib_resolv___res_send" = x""yes; then :
+  resolv=yes
+fi
+
+fi
+
+fi
+
+fi
+
+  if test "$resolv" = yes ; then
+    RESOLVLIB=-lresolv
+  else
+    RESOLVLIB=
+  fi
+  ac_fn_c_check_func "$LINENO" "hes_getmailhost" "ac_cv_func_hes_getmailhost"
+if test "x$ac_cv_func_hes_getmailhost" = x""yes; then :
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for hes_getmailhost in -lhesiod" >&5
+$as_echo_n "checking for hes_getmailhost in -lhesiod... " >&6; }
+if test "${ac_cv_lib_hesiod_hes_getmailhost+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lhesiod $RESOLVLIB $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char hes_getmailhost ();
+int
+main ()
+{
+return hes_getmailhost ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_hesiod_hes_getmailhost=yes
+else
+  ac_cv_lib_hesiod_hes_getmailhost=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_hesiod_hes_getmailhost" >&5
+$as_echo "$ac_cv_lib_hesiod_hes_getmailhost" >&6; }
+if test "x$ac_cv_lib_hesiod_hes_getmailhost" = x""yes; then :
+  hesiod=yes
+else
+  :
+fi
+
+fi
+
+
+  if test x"$hesiod" = xyes; then
+
+$as_echo "#define HAVE_LIBHESIOD 1" >>confdefs.h
+
+    LIBHESIOD=-lhesiod
+  fi
+fi
+
+
+# Do we need libresolv (due to res_init or Hesiod)?
+if test "$resolv" = yes ; then
+
+$as_echo "#define HAVE_LIBRESOLV 1" >>confdefs.h
+
+  LIBRESOLV=-lresolv
+else
+  LIBRESOLV=
+fi
+
+
+# These tell us which Kerberos-related libraries to use.
+COM_ERRLIB=
+CRYPTOLIB=
+KRB5LIB=
+DESLIB=
+KRB4LIB=
+
+if test "${with_kerberos}" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for com_err in -lcom_err" >&5
+$as_echo_n "checking for com_err in -lcom_err... " >&6; }
+if test "${ac_cv_lib_com_err_com_err+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcom_err  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char com_err ();
+int
+main ()
+{
+return com_err ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_com_err_com_err=yes
+else
+  ac_cv_lib_com_err_com_err=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_com_err_com_err" >&5
+$as_echo "$ac_cv_lib_com_err_com_err" >&6; }
+if test "x$ac_cv_lib_com_err_com_err" = x""yes; then :
+  have_com_err=yes
+else
+  have_com_err=no
+fi
+
+  if test $have_com_err = yes; then
+    COM_ERRLIB=-lcom_err
+    LIBS="$COM_ERRLIB $LIBS"
+
+$as_echo "#define HAVE_LIBCOM_ERR 1" >>confdefs.h
+
+  fi
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mit_des_cbc_encrypt in -lcrypto" >&5
+$as_echo_n "checking for mit_des_cbc_encrypt in -lcrypto... " >&6; }
+if test "${ac_cv_lib_crypto_mit_des_cbc_encrypt+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char mit_des_cbc_encrypt ();
+int
+main ()
+{
+return mit_des_cbc_encrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_crypto_mit_des_cbc_encrypt=yes
+else
+  ac_cv_lib_crypto_mit_des_cbc_encrypt=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_mit_des_cbc_encrypt" >&5
+$as_echo "$ac_cv_lib_crypto_mit_des_cbc_encrypt" >&6; }
+if test "x$ac_cv_lib_crypto_mit_des_cbc_encrypt" = x""yes; then :
+  have_crypto=yes
+else
+  have_crypto=no
+fi
+
+  if test $have_crypto = yes; then
+    CRYPTOLIB=-lcrypto
+    LIBS="$CRYPTOLIB $LIBS"
+
+$as_echo "#define HAVE_LIBCRYPTO 1" >>confdefs.h
+
+  fi
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mit_des_cbc_encrypt in -lk5crypto" >&5
+$as_echo_n "checking for mit_des_cbc_encrypt in -lk5crypto... " >&6; }
+if test "${ac_cv_lib_k5crypto_mit_des_cbc_encrypt+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lk5crypto  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char mit_des_cbc_encrypt ();
+int
+main ()
+{
+return mit_des_cbc_encrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_k5crypto_mit_des_cbc_encrypt=yes
+else
+  ac_cv_lib_k5crypto_mit_des_cbc_encrypt=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_k5crypto_mit_des_cbc_encrypt" >&5
+$as_echo "$ac_cv_lib_k5crypto_mit_des_cbc_encrypt" >&6; }
+if test "x$ac_cv_lib_k5crypto_mit_des_cbc_encrypt" = x""yes; then :
+  have_k5crypto=yes
+else
+  have_k5crypto=no
+fi
+
+  if test $have_k5crypto = yes; then
+    CRYPTOLIB=-lk5crypto
+    LIBS="$CRYPTOLIB $LIBS"
+
+$as_echo "#define HAVE_LIBK5CRYPTO 1" >>confdefs.h
+
+  fi
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_init_context in -lkrb5" >&5
+$as_echo_n "checking for krb5_init_context in -lkrb5... " >&6; }
+if test "${ac_cv_lib_krb5_krb5_init_context+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char krb5_init_context ();
+int
+main ()
+{
+return krb5_init_context ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_krb5_krb5_init_context=yes
+else
+  ac_cv_lib_krb5_krb5_init_context=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_krb5_krb5_init_context" >&5
+$as_echo "$ac_cv_lib_krb5_krb5_init_context" >&6; }
+if test "x$ac_cv_lib_krb5_krb5_init_context" = x""yes; then :
+  have_krb5=yes
+else
+  have_krb5=no
+fi
+
+  if test $have_krb5=yes; then
+    KRB5LIB=-lkrb5
+    LIBS="$KRB5LIB $LIBS"
+
+$as_echo "#define HAVE_LIBKRB5 1" >>confdefs.h
+
+  fi
+    if test "${with_kerberos5}" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for des_cbc_encrypt in -ldes425" >&5
+$as_echo_n "checking for des_cbc_encrypt in -ldes425... " >&6; }
+if test "${ac_cv_lib_des425_des_cbc_encrypt+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldes425  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char des_cbc_encrypt ();
+int
+main ()
+{
+return des_cbc_encrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_des425_des_cbc_encrypt=yes
+else
+  ac_cv_lib_des425_des_cbc_encrypt=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_des425_des_cbc_encrypt" >&5
+$as_echo "$ac_cv_lib_des425_des_cbc_encrypt" >&6; }
+if test "x$ac_cv_lib_des425_des_cbc_encrypt" = x""yes; then :
+  have_des425=yes
+else
+  have_des425=no
+fi
+
+    if test $have_des425 = yes; then
+      DESLIB=-ldes425
+      LIBS="$DESLIB $LIBS"
+
+$as_echo "#define HAVE_LIBDES425 1" >>confdefs.h
+
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for des_cbc_encrypt in -ldes" >&5
+$as_echo_n "checking for des_cbc_encrypt in -ldes... " >&6; }
+if test "${ac_cv_lib_des_des_cbc_encrypt+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldes  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char des_cbc_encrypt ();
+int
+main ()
+{
+return des_cbc_encrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_des_des_cbc_encrypt=yes
+else
+  ac_cv_lib_des_des_cbc_encrypt=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_des_des_cbc_encrypt" >&5
+$as_echo "$ac_cv_lib_des_des_cbc_encrypt" >&6; }
+if test "x$ac_cv_lib_des_des_cbc_encrypt" = x""yes; then :
+  have_des=yes
+else
+  have_des=no
+fi
+
+      if test $have_des = yes; then
+        DESLIB=-ldes
+        LIBS="$DESLIB $LIBS"
+
+$as_echo "#define HAVE_LIBDES 1" >>confdefs.h
+
+      fi
+    fi
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb_get_cred in -lkrb4" >&5
+$as_echo_n "checking for krb_get_cred in -lkrb4... " >&6; }
+if test "${ac_cv_lib_krb4_krb_get_cred+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb4  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char krb_get_cred ();
+int
+main ()
+{
+return krb_get_cred ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_krb4_krb_get_cred=yes
+else
+  ac_cv_lib_krb4_krb_get_cred=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_krb4_krb_get_cred" >&5
+$as_echo "$ac_cv_lib_krb4_krb_get_cred" >&6; }
+if test "x$ac_cv_lib_krb4_krb_get_cred" = x""yes; then :
+  have_krb4=yes
+else
+  have_krb4=no
+fi
+
+    if test $have_krb4 = yes; then
+      KRB4LIB=-lkrb4
+      LIBS="$KRB4LIB $LIBS"
+
+$as_echo "#define HAVE_LIBKRB4 1" >>confdefs.h
+
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb_get_cred in -lkrb" >&5
+$as_echo_n "checking for krb_get_cred in -lkrb... " >&6; }
+if test "${ac_cv_lib_krb_krb_get_cred+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char krb_get_cred ();
+int
+main ()
+{
+return krb_get_cred ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_krb_krb_get_cred=yes
+else
+  ac_cv_lib_krb_krb_get_cred=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_krb_krb_get_cred" >&5
+$as_echo "$ac_cv_lib_krb_krb_get_cred" >&6; }
+if test "x$ac_cv_lib_krb_krb_get_cred" = x""yes; then :
+  have_krb=yes
+else
+  have_krb=no
+fi
+
+      if test $have_krb = yes; then
+        KRB4LIB=-lkrb
+        LIBS="$KRB4LIB $LIBS"
+
+$as_echo "#define HAVE_LIBKRB 1" >>confdefs.h
+
+      fi
+    fi
+  fi
+
+  if test "${with_kerberos5}" != no; then
+    for ac_header in krb5.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "krb5.h" "ac_cv_header_krb5_h" "$ac_includes_default"
+if test "x$ac_cv_header_krb5_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_H 1
+_ACEOF
+ ac_fn_c_check_member "$LINENO" "krb5_error" "text" "ac_cv_member_krb5_error_text" "#include <krb5.h>
+"
+if test "x$ac_cv_member_krb5_error_text" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_ERROR_TEXT 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_member "$LINENO" "krb5_error" "e_text" "ac_cv_member_krb5_error_e_text" "#include <krb5.h>
+"
+if test "x$ac_cv_member_krb5_error_e_text" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_ERROR_E_TEXT 1
+_ACEOF
+
+
+fi
+
+fi
+
+done
+
+  else
+    for ac_header in des.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "des.h" "ac_cv_header_des_h" "$ac_includes_default"
+if test "x$ac_cv_header_des_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DES_H 1
+_ACEOF
+
+else
+  for ac_header in kerberosIV/des.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "kerberosIV/des.h" "ac_cv_header_kerberosIV_des_h" "$ac_includes_default"
+if test "x$ac_cv_header_kerberosIV_des_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_KERBEROSIV_DES_H 1
+_ACEOF
+
+else
+  for ac_header in kerberos/des.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "kerberos/des.h" "ac_cv_header_kerberos_des_h" "$ac_includes_default"
+if test "x$ac_cv_header_kerberos_des_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_KERBEROS_DES_H 1
+_ACEOF
+
+fi
+
+done
+
+fi
+
+done
+
+fi
+
+done
+
+    for ac_header in krb.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "krb.h" "ac_cv_header_krb_h" "$ac_includes_default"
+if test "x$ac_cv_header_krb_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB_H 1
+_ACEOF
+
+else
+  for ac_header in kerberosIV/krb.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "kerberosIV/krb.h" "ac_cv_header_kerberosIV_krb_h" "$ac_includes_default"
+if test "x$ac_cv_header_kerberosIV_krb_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_KERBEROSIV_KRB_H 1
+_ACEOF
+
+else
+  for ac_header in kerberos/krb.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "kerberos/krb.h" "ac_cv_header_kerberos_krb_h" "$ac_includes_default"
+if test "x$ac_cv_header_kerberos_krb_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_KERBEROS_KRB_H 1
+_ACEOF
+
+fi
+
+done
+
+fi
+
+done
+
+fi
+
+done
+
+  fi
+  for ac_header in com_err.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "com_err.h" "ac_cv_header_com_err_h" "$ac_includes_default"
+if test "x$ac_cv_header_com_err_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_COM_ERR_H 1
+_ACEOF
+
+fi
+
+done
+
+fi
+
+
+
+
+
+
+
+# Solaris requires -lintl if you want strerror (which calls dgettext)
+# to return localized messages.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dgettext in -lintl" >&5
+$as_echo_n "checking for dgettext in -lintl... " >&6; }
+if test "${ac_cv_lib_intl_dgettext+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dgettext ();
+int
+main ()
+{
+return dgettext ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_intl_dgettext=yes
+else
+  ac_cv_lib_intl_dgettext=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_dgettext" >&5
+$as_echo "$ac_cv_lib_intl_dgettext" >&6; }
+if test "x$ac_cv_lib_intl_dgettext" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBINTL 1
+_ACEOF
+
+  LIBS="-lintl $LIBS"
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether localtime caches TZ" >&5
+$as_echo_n "checking whether localtime caches TZ... " >&6; }
+if test "${emacs_cv_localtime_cache+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test x$ac_cv_func_tzset = xyes; then
+if test "$cross_compiling" = yes; then :
+  # If we have tzset, assume the worst when cross-compiling.
+emacs_cv_localtime_cache=yes
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <time.h>
+char TZ_GMT0[] = "TZ=GMT0";
+char TZ_PST8[] = "TZ=PST8";
+main()
+{
+  time_t now = time ((time_t *) 0);
+  int hour_GMT0, hour_unset;
+  if (putenv (TZ_GMT0) != 0)
+    exit (1);
+  hour_GMT0 = localtime (&now)->tm_hour;
+  unsetenv("TZ");
+  hour_unset = localtime (&now)->tm_hour;
+  if (putenv (TZ_PST8) != 0)
+    exit (1);
+  if (localtime (&now)->tm_hour == hour_GMT0)
+    exit (1);
+  unsetenv("TZ");
+  if (localtime (&now)->tm_hour != hour_unset)
+    exit (1);
+  exit (0);
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  emacs_cv_localtime_cache=no
+else
+  emacs_cv_localtime_cache=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+else
+       # If we lack tzset, report that localtime does not cache TZ,
+       # since we can't invalidate the cache if we don't have tzset.
+       emacs_cv_localtime_cache=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $emacs_cv_localtime_cache" >&5
+$as_echo "$emacs_cv_localtime_cache" >&6; }
+if test $emacs_cv_localtime_cache = yes; then
+
+$as_echo "#define LOCALTIME_CACHE 1" >>confdefs.h
+
+fi
+
+if test "x$HAVE_TIMEVAL" = xyes; then
+  for ac_func in gettimeofday
+do :
+  ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday"
+if test "x$ac_cv_func_gettimeofday" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_GETTIMEOFDAY 1
+_ACEOF
+
+fi
+done
+
+  if test $ac_cv_func_gettimeofday = yes; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gettimeofday can accept two arguments" >&5
+$as_echo_n "checking whether gettimeofday can accept two arguments... " >&6; }
+if test "${emacs_cv_gettimeofday_two_arguments+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+int
+main ()
+{
+struct timeval time;
+       gettimeofday (&time, 0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  emacs_cv_gettimeofday_two_arguments=yes
+else
+  emacs_cv_gettimeofday_two_arguments=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $emacs_cv_gettimeofday_two_arguments" >&5
+$as_echo "$emacs_cv_gettimeofday_two_arguments" >&6; }
+    if test $emacs_cv_gettimeofday_two_arguments = no; then
+
+$as_echo "#define GETTIMEOFDAY_ONE_ARGUMENT 1" >>confdefs.h
+
+    fi
+  fi
+fi
+
+ok_so_far=yes
+ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket"
+if test "x$ac_cv_func_socket" = x""yes; then :
+
+else
+  ok_so_far=no
+fi
+
+if test $ok_so_far = yes; then
+  ac_fn_c_check_header_mongrel "$LINENO" "netinet/in.h" "ac_cv_header_netinet_in_h" "$ac_includes_default"
+if test "x$ac_cv_header_netinet_in_h" = x""yes; then :
+
+else
+  ok_so_far=no
+fi
+
+
+fi
+if test $ok_so_far = yes; then
+  ac_fn_c_check_header_mongrel "$LINENO" "arpa/inet.h" "ac_cv_header_arpa_inet_h" "$ac_includes_default"
+if test "x$ac_cv_header_arpa_inet_h" = x""yes; then :
+
+else
+  ok_so_far=no
+fi
+
+
+fi
+if test $ok_so_far = yes; then
+
+$as_echo "#define HAVE_INET_SOCKETS 1" >>confdefs.h
+
+fi
+
+if test -f /usr/lpp/X11/bin/smt.exp; then
+
+$as_echo "#define HAVE_AIX_SMT_EXP 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether system supports dynamic ptys" >&5
+$as_echo_n "checking whether system supports dynamic ptys... " >&6; }
+if test -d /dev/pts && ls -d /dev/ptmx > /dev/null 2>&1 ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_DEV_PTMX 1" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
+if test "x$ac_cv_type_pid_t" = x""yes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+for ac_header in vfork.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default"
+if test "x$ac_cv_header_vfork_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_VFORK_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_func in fork vfork
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+if test "x$ac_cv_func_fork" = xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5
+$as_echo_n "checking for working fork... " >&6; }
+if test "${ac_cv_func_fork_works+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_fork_works=cross
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+
+         /* By Ruediger Kuhlmann. */
+         return fork () < 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_fork_works=yes
+else
+  ac_cv_func_fork_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5
+$as_echo "$ac_cv_func_fork_works" >&6; }
+
+else
+  ac_cv_func_fork_works=$ac_cv_func_fork
+fi
+if test "x$ac_cv_func_fork_works" = xcross; then
+  case $host in
+    *-*-amigaos* | *-*-msdosdjgpp*)
+      # Override, as these systems have only a dummy fork() stub
+      ac_cv_func_fork_works=no
+      ;;
+    *)
+      ac_cv_func_fork_works=yes
+      ;;
+  esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
+$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
+fi
+ac_cv_func_vfork_works=$ac_cv_func_vfork
+if test "x$ac_cv_func_vfork" = xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5
+$as_echo_n "checking for working vfork... " >&6; }
+if test "${ac_cv_func_vfork_works+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_vfork_works=cross
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Thanks to Paul Eggert for this test.  */
+$ac_includes_default
+#include <sys/wait.h>
+#ifdef HAVE_VFORK_H
+# include <vfork.h>
+#endif
+/* On some sparc systems, changes by the child to local and incoming
+   argument registers are propagated back to the parent.  The compiler
+   is told about this with #include <vfork.h>, but some compilers
+   (e.g. gcc -O) don't grok <vfork.h>.  Test for this by using a
+   static variable whose address is put into a register that is
+   clobbered by the vfork.  */
+static void
+#ifdef __cplusplus
+sparc_address_test (int arg)
+# else
+sparc_address_test (arg) int arg;
+#endif
+{
+  static pid_t child;
+  if (!child) {
+    child = vfork ();
+    if (child < 0) {
+      perror ("vfork");
+      _exit(2);
+    }
+    if (!child) {
+      arg = getpid();
+      write(-1, "", 0);
+      _exit (arg);
+    }
+  }
+}
+
+int
+main ()
+{
+  pid_t parent = getpid ();
+  pid_t child;
+
+  sparc_address_test (0);
+
+  child = vfork ();
+
+  if (child == 0) {
+    /* Here is another test for sparc vfork register problems.  This
+       test uses lots of local variables, at least as many local
+       variables as main has allocated so far including compiler
+       temporaries.  4 locals are enough for gcc 1.40.3 on a Solaris
+       4.1.3 sparc, but we use 8 to be safe.  A buggy compiler should
+       reuse the register of parent for one of the local variables,
+       since it will think that parent can't possibly be used any more
+       in this routine.  Assigning to the local variable will thus
+       munge parent in the parent process.  */
+    pid_t
+      p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
+      p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
+    /* Convince the compiler that p..p7 are live; otherwise, it might
+       use the same hardware register for all 8 local variables.  */
+    if (p != p1 || p != p2 || p != p3 || p != p4
+       || p != p5 || p != p6 || p != p7)
+      _exit(1);
+
+    /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
+       from child file descriptors.  If the child closes a descriptor
+       before it execs or exits, this munges the parent's descriptor
+       as well.  Test for this by closing stdout in the child.  */
+    _exit(close(fileno(stdout)) != 0);
+  } else {
+    int status;
+    struct stat st;
+
+    while (wait(&status) != child)
+      ;
+    return (
+        /* Was there some problem with vforking?  */
+        child < 0
+
+        /* Did the child fail?  (This shouldn't happen.)  */
+        || status
+
+        /* Did the vfork/compiler bug occur?  */
+        || parent != getpid()
+
+        /* Did the file descriptor bug occur?  */
+        || fstat(fileno(stdout), &st) != 0
+        );
+  }
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_vfork_works=yes
+else
+  ac_cv_func_vfork_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5
+$as_echo "$ac_cv_func_vfork_works" >&6; }
+
+fi;
+if test "x$ac_cv_func_fork_works" = xcross; then
+  ac_cv_func_vfork_works=$ac_cv_func_vfork
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
+$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
+fi
+
+if test "x$ac_cv_func_vfork_works" = xyes; then
+
+$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h
+
+else
+
+$as_echo "#define vfork fork" >>confdefs.h
+
+fi
+if test "x$ac_cv_func_fork_works" = xyes; then
+
+$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_langinfo and CODESET" >&5
+$as_echo_n "checking for nl_langinfo and CODESET... " >&6; }
+if test "${emacs_cv_langinfo_codeset+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <langinfo.h>
+int
+main ()
+{
+char* cs = nl_langinfo(CODESET);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  emacs_cv_langinfo_codeset=yes
+else
+  emacs_cv_langinfo_codeset=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $emacs_cv_langinfo_codeset" >&5
+$as_echo "$emacs_cv_langinfo_codeset" >&6; }
+if test $emacs_cv_langinfo_codeset = yes; then
+
+$as_echo "#define HAVE_LANGINFO_CODESET 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mbstate_t" >&5
+$as_echo_n "checking for mbstate_t... " >&6; }
+if test "${ac_cv_type_mbstate_t+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+#          include <wchar.h>
+int
+main ()
+{
+mbstate_t x; return sizeof x;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_type_mbstate_t=yes
+else
+  ac_cv_type_mbstate_t=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_mbstate_t" >&5
+$as_echo "$ac_cv_type_mbstate_t" >&6; }
+   if test $ac_cv_type_mbstate_t = yes; then
+
+$as_echo "#define HAVE_MBSTATE_T 1" >>confdefs.h
+
+   else
+
+$as_echo "#define mbstate_t int" >>confdefs.h
+
+   fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C restricted array declarations" >&5
+$as_echo_n "checking for C restricted array declarations... " >&6; }
+if test "${emacs_cv_c_restrict_arr+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+void fred (int x[__restrict]);
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  emacs_cv_c_restrict_arr=yes
+else
+  emacs_cv_c_restrict_arr=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $emacs_cv_c_restrict_arr" >&5
+$as_echo "$emacs_cv_c_restrict_arr" >&6; }
+if test "$emacs_cv_c_restrict_arr" = yes; then
+
+$as_echo "#define __restrict_arr __restrict" >>confdefs.h
+
+fi
+
+
+
+# Set up the CFLAGS for real compilation, so we can substitute it.
+CFLAGS="$REAL_CFLAGS"
+CPPFLAGS="$REAL_CPPFLAGS"
+
+## Hack to detect a buggy GCC version.
+if test "x$GCC" = xyes \
+   && test x"`$CC --version 2> /dev/null | grep 'gcc.* 4.5.0'`" != x \
+   && test x"`echo $CFLAGS | grep '\-O[23]'`" != x \
+   && test x"`echo $CFLAGS | grep '\-fno-optimize-sibling-calls'`" = x; then
+   as_fn_error "GCC 4.5.0 has problems compiling Emacs; see etc/PROBLEMS'." "$LINENO" 5
+fi
+
+version=$PACKAGE_VERSION
+
+### Specify what sort of things we'll be editing into Makefile and config.h.
+### Use configuration here uncanonicalized to avoid exceeding size limits.
+
+
+## Unused?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## FIXME? Nothing uses @LD_SWITCH_X_SITE@.
+## src/Makefile.in did add LD_SWITCH_X_SITE (as a cpp define) to the
+## end of LIBX_BASE, but nothing ever set it.
+
+
+
+
+## Used in lwlib/Makefile.in.
+
+if test -n "${machfile}"; then
+  M_FILE="\$(srcdir)/${machfile}"
+else
+  M_FILE=
+fi
+S_FILE="\$(srcdir)/${opsysfile}"
+
+
+
+
+
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define EMACS_CONFIGURATION "${canonical}"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define EMACS_CONFIG_OPTIONS "${ac_configure_args}"
+_ACEOF
+
+if test -n "$machfile"; then
+
+cat >>confdefs.h <<_ACEOF
+#define config_machfile "${machfile}"
+_ACEOF
+
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define config_opsysfile "${opsysfile}"
+_ACEOF
+
+
+XMENU_OBJ=
+XOBJ=
+FONT_OBJ=
+if test "${HAVE_X_WINDOWS}" = "yes" ; then
+
+$as_echo "#define HAVE_X_WINDOWS 1" >>confdefs.h
+
+  XMENU_OBJ=xmenu.o
+  XOBJ="xterm.o xfns.o xselect.o xrdb.o fontset.o xsmfns.o fringe.o image.o xsettings.o xgselect.o"
+  FONT_OBJ=xfont.o
+  if test "$HAVE_XFT" = "yes"; then
+    FONT_OBJ="$FONT_OBJ ftfont.o xftfont.o ftxfont.o"
+  elif test "$HAVE_FREETYPE" = "yes"; then
+    FONT_OBJ="$FONT_OBJ ftfont.o ftxfont.o"
+  fi
+
+fi
+
+
+
+
+WIDGET_OBJ=
+MOTIF_LIBW=
+if test "${USE_X_TOOLKIT}" != "none" ; then
+  WIDGET_OBJ=widget.o
+
+$as_echo "#define USE_X_TOOLKIT 1" >>confdefs.h
+
+  if test "${USE_X_TOOLKIT}" = "LUCID"; then
+
+$as_echo "#define USE_LUCID 1" >>confdefs.h
+
+  elif test "${USE_X_TOOLKIT}" = "MOTIF"; then
+
+$as_echo "#define USE_MOTIF 1" >>confdefs.h
+
+    MOTIF_LIBW=-lXm
+    case "$opsys" in
+      gnu-linux)
+        ## Paul Abrahams <abrahams at equinox.shaysnet.com> says this is needed.
+        MOTIF_LIBW="$MOTIF_LIBW -lXpm"
+        ;;
+
+      unixware)
+        ## Richard Anthony Ryan <ryanr at ellingtn.ftc.nrcs.usda.gov>
+        ## says -lXimp is needed in UNIX_SV ... 4.2 1.1.2.
+        MOTIF_LIBW="MOTIF_LIBW -lXimp"
+        ;;
+
+      aix4-2)
+        ## olson@mcs.anl.gov says -li18n is needed by -lXm.
+        MOTIF_LIBW="$MOTIF_LIBW -li18n"
+        ;;
+    esac
+    MOTIF_LIBW="$MOTIF_LIBW $LIBXP"
+  fi
+fi
+
+
+TOOLKIT_LIBW=
+case "$USE_X_TOOLKIT" in
+  MOTIF) TOOLKIT_LIBW="$MOTIF_LIBW" ;;
+  LUCID) TOOLKIT_LIBW="$LUCID_LIBW" ;;
+  none) test "x$HAVE_GTK" = "xyes" && TOOLKIT_LIBW="$GTK_LIBS -lXcomposite" ;;
+esac
+
+
+if test "$USE_X_TOOLKIT" = "none"; then
+  LIBXT_OTHER="\$(LIBXSM)"
+  OLDXMENU_TARGET="really-oldXMenu"
+else
+  LIBXT_OTHER="\$(LIBXMU) -lXt \$(LIBXTR6) -lXext"
+  OLDXMENU_TARGET="really-lwlib"
+fi
+
+
+## The X Menu stuff is present in the X10 distribution, but missing
+## from X11.  If we have X10, just use the installed library;
+## otherwise, use our own copy.
+if test "${HAVE_X11}" = "yes" ; then
+
+$as_echo "#define HAVE_X11 1" >>confdefs.h
+
+
+  if test "$USE_X_TOOLKIT" = "none"; then
+    OLDXMENU="\${oldXMenudir}/libXMenu11.a"
+  else
+    OLDXMENU="\${lwlibdir}/liblw.a"
+  fi
+  LIBXMENU="\$(OLDXMENU)"
+  LIBX_OTHER="\$(LIBXT) \$(LIBX_EXTRA)"
+  OLDXMENU_DEPS="\${OLDXMENU} ../src/\${OLDXMENU}"
+else
+  ## For a syntactically valid Makefile; not actually used for anything.
+  ## See comments in src/Makefile.in.
+  OLDXMENU=nothing
+  ## FIXME This case (!HAVE_X11 && HAVE_X_WINDOWS) is no longer possible(?).
+  if test "${HAVE_X_WINDOWS}" = "yes"; then
+    LIBXMENU="-lXMenu"
+  else
+    LIBXMENU=
+  fi
+  LIBX_OTHER=
+  OLDXMENU_DEPS=
+fi
+
+if test "$HAVE_GTK" = "yes" || test "$HAVE_MENUS" != "yes"; then
+  OLDXMENU_TARGET=
+  OLDXMENU=nothing
+  LIBXMENU=
+  OLDXMENU_DEPS=
+fi
+
+
+
+
+
+
+
+if test "${HAVE_MENUS}" = "yes" ; then
+
+$as_echo "#define HAVE_MENUS 1" >>confdefs.h
+
+fi
+
+if test "${GNU_MALLOC}" = "yes" ; then
+
+$as_echo "#define GNU_MALLOC 1" >>confdefs.h
+
+fi
+
+RALLOC_OBJ=
+if test "${REL_ALLOC}" = "yes" ; then
+
+$as_echo "#define REL_ALLOC 1" >>confdefs.h
+
+
+  test "$system_malloc" != "yes" && RALLOC_OBJ=ralloc.o
+fi
+
+
+if test "$opsys" = "cygwin"; then
+  CYGWIN_OBJ="sheap.o"
+  ## Cygwin differs because of its unexec().
+  PRE_ALLOC_OBJ=
+  POST_ALLOC_OBJ=lastfile.o
+else
+  CYGWIN_OBJ=
+  PRE_ALLOC_OBJ=lastfile.o
+  POST_ALLOC_OBJ=
+fi
+
+
+
+
+
 case "$opsys" in
   aix4-2) LD_SWITCH_SYSTEM_TEMACS="-Wl,-bnodelcsect" ;;
 
@@ -22525,7 +24450,7 @@ case "$opsys" in
      libs_nsgui=
      headerpad_extra=690
    fi
-   LD_SWITCH_SYSTEM_TEMACS="-fno-pie -prebind $libs_nsgui -Xlinker -headerpad -Xlinker $headerpad_extra"
+   LD_SWITCH_SYSTEM_TEMACS="-prebind $libs_nsgui -Xlinker -headerpad -Xlinker $headerpad_extra"
 
    ## This is here because src/Makefile.in did some extra fiddling around
    ## with LD_SWITCH_SYSTEM.  The cpp logic was:
@@ -22706,7 +24631,6 @@ echo "  Does Emacs use imagemagick?                             ${HAVE_IMAGEMAGI
 echo "  Does Emacs use -lgpm?                                   ${HAVE_GPM}"
 echo "  Does Emacs use -ldbus?                                  ${HAVE_DBUS}"
 echo "  Does Emacs use -lgconf?                                 ${HAVE_GCONF}"
-echo "  Does Emacs use GSettings?                               ${HAVE_GSETTINGS}"
 echo "  Does Emacs use -lselinux?                               ${HAVE_LIBSELINUX}"
 echo "  Does Emacs use -lgnutls?                                ${HAVE_GNUTLS}"
 echo "  Does Emacs use -lxml2?                                  ${HAVE_LIBXML2}"
@@ -22946,22 +24870,31 @@ if test -z "${gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_TRUE}" && test
   as_fn_error "conditional \"gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+<<<<<<< TREE
+<<<<<<< TREE
+=======
+=======
 if test -z "${gl_GNULIB_ENABLED_pathmax_TRUE}" && test -z "${gl_GNULIB_ENABLED_pathmax_FALSE}"; then
   as_fn_error "conditional \"gl_GNULIB_ENABLED_pathmax\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+>>>>>>> MERGE-SOURCE
 if test -z "${gl_GNULIB_ENABLED_sigprocmask_TRUE}" && test -z "${gl_GNULIB_ENABLED_sigprocmask_FALSE}"; then
   as_fn_error "conditional \"gl_GNULIB_ENABLED_sigprocmask\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+>>>>>>> MERGE-SOURCE
 if test -z "${gl_GNULIB_ENABLED_stat_TRUE}" && test -z "${gl_GNULIB_ENABLED_stat_FALSE}"; then
   as_fn_error "conditional \"gl_GNULIB_ENABLED_stat\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+<<<<<<< TREE
+=======
 if test -z "${gl_GNULIB_ENABLED_strtoll_TRUE}" && test -z "${gl_GNULIB_ENABLED_strtoll_FALSE}"; then
   as_fn_error "conditional \"gl_GNULIB_ENABLED_strtoll\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+>>>>>>> MERGE-SOURCE
 if test -z "${gl_GNULIB_ENABLED_strtoull_TRUE}" && test -z "${gl_GNULIB_ENABLED_strtoull_FALSE}"; then
   as_fn_error "conditional \"gl_GNULIB_ENABLED_strtoull\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
index eb5e8482e9b6642deb048921fa38aa1a13bdf566..e4962b0a40567013b280d608e3d747b0a30c4c7e 100644 (file)
@@ -178,6 +178,8 @@ OPTION_DEFAULT_ON([gsettings],[don't compile with GSettings support])
 OPTION_DEFAULT_ON([selinux],[don't compile with SELinux support])
 OPTION_DEFAULT_ON([gnutls],[don't use -lgnutls for SSL/TLS support])
 
+OPTION_DEFAULT_OFF([xwidgets],[enable use of some gtk widgets it Emacs buffers])
+
 ## For the times when you want to build Emacs but don't have
 ## a suitable makeinfo, and can live without the manuals.
 dnl http://lists.gnu.org/archive/html/emacs-devel/2008-04/msg01844.html
@@ -2015,6 +2017,54 @@ if test "${HAVE_GTK}" = "yes"; then
                 gtk_window_set_has_resize_grip)
 fi
 
+
+HAVE_XWIDGETS=no
+HAVE_WEBKIT=no
+HAVE_GOOCANVAS=no
+HAVE_CLUTTER=no
+if test "${with_xwidgets}" != "no"; then
+   echo "xwidgets enabled, checking webkit, and others"
+   HAVE_XWIDGETS=yes
+   AC_DEFINE(HAVE_XWIDGETS, 1, [Define to 1 if you have xwidgets support.])        
+#xwidgets
+#TODO
+# - enable only if gtk/gtk3 enabled
+# - webkit, goocanvas, clutter
+# - only webkit_osr is good so remove plain webkit laterish
+
+#webkit version for gtk3. 
+  WEBKIT_REQUIRED=1.4.0
+  WEBKIT_MODULES="webkitgtk-3.0 >= $WEBKIT_REQUIRED"
+
+  if test "${with_gtk3}" = "yes"; then
+    PKG_CHECK_MODULES(WEBKIT, $WEBKIT_MODULES, HAVE_WEBKIT=yes, HAVE_WEBKIT=no)
+    if test $HAVE_WEBKIT = yes; then
+        AC_DEFINE(HAVE_WEBKIT_OSR, 1, [Define to 1 if you have webkit_osr support.])     
+    fi
+  fi
+
+  if test "${with_xwdemo}"  = "yes"; then
+#clutter and goocanvas are just proof of concept so disable for now  
+  CLUTTER_REQUIRED=1.0.0   
+  CLUTTER_MODULES="clutter-gtk-1.0 >= $CLUTTER_REQUIRED"
+
+  PKG_CHECK_MODULES(CLUTTER, $CLUTTER_MODULES, HAVE_CLUTTER=yes, HAVE_CLUTTER=no)
+  if test $HAVE_CLUTTER = yes;  then
+     AC_DEFINE(HAVE_CLUTTER, 1, [Define to 1 if you have clutter support.])
+  fi
+
+
+  GOOCANVAS_REQUIRED=1.4.0
+  GOOCANVAS_MODULES="goocanvasgtk-3.0 >= $GOOCANVAS_REQUIRED"
+
+  PKG_CHECK_MODULES(GOOCANVAS, $GOOCANVAS_MODULES, HAVE_GOOCANVAS=yes, HAVE_GOOCANVAS=no)
+  if test $HAVE_GOOCANVAS = yes; then
+     AC_DEFINE(HAVE_GOOCANVAS, 1, [Define to 1 if you have goocanvas support.])
+  fi
+  fi
+fi
+
+
 dnl D-Bus has been tested under GNU/Linux only.  Must be adapted for
 dnl other platforms.
 HAVE_DBUS=no
@@ -3301,7 +3351,7 @@ TOOLKIT_LIBW=
 case "$USE_X_TOOLKIT" in
   MOTIF) TOOLKIT_LIBW="$MOTIF_LIBW" ;;
   LUCID) TOOLKIT_LIBW="$LUCID_LIBW" ;;
-  none) test "x$HAVE_GTK" = "xyes" && TOOLKIT_LIBW="$GTK_LIBS" ;;
+  none) test "x$HAVE_GTK" = "xyes" && TOOLKIT_LIBW="$GTK_LIBS -lXcomposite" ;;
 esac
 AC_SUBST(TOOLKIT_LIBW)
 
@@ -3761,6 +3811,11 @@ echo "  Does Emacs use -lotf?                                   ${HAVE_LIBOTF}"
 echo "  Does Emacs use -lxft?                                   ${HAVE_XFT}"
 
 echo "  Does Emacs use toolkit scroll bars?                     ${USE_TOOLKIT_SCROLL_BARS}"
+
+echo "  Does Emacs support Xwidgets?                            ${HAVE_XWIDGETS}"
+echo "       Does xwidgets support webkit(requires gtk3)?       ${HAVE_WEBKIT}"
+echo "       Does xwidgets support clutter(demo code)?          ${HAVE_CLUTTER}"
+echo "       Does xwidgets support goocanvas(demo code)?        ${HAVE_GOOCANVAS}"
 echo
 
 if test -n "${EMACSDATA}"; then
index a9380619e6a3a9b5c8682d4104d7d6ddfe9e696e..aa577577a20664e99528ec671b25b836d6f8c805 100644 (file)
@@ -286,7 +286,7 @@ This also does some trivial optimizations to make the form prettier.
 ;;;;;;  flet progv psetq do-all-symbols do-symbols dotimes dolist
 ;;;;;;  do* do loop return-from return block etypecase typecase ecase
 ;;;;;;  case load-time-value eval-when destructuring-bind function*
-;;;;;;  defmacro* defun* gentemp gensym) "cl-macs" "cl-macs.el" "c383ef0fa5f6d28796cd8e9cf65e1c5d")
+;;;;;;  defmacro* defun* gentemp gensym) "cl-macs" "cl-macs.el" "d19555cbac873fe90a312b8977a8ebff")
 ;;; Generated autoloads from cl-macs.el
 
 (autoload 'gensym "cl-macs" "\
index c547a4f646033c19aec7ca39667fc816be5d3e06..f1469766437d7743e09f258f4b9428448763f5d5 100644 (file)
@@ -3200,3 +3200,4 @@ surrounded by (block NAME ...).
 ;; End:
 
 ;;; cl-macs.el ends here
+
index f4e7e942931ff3c316776dbcb204d3fd3c4ec324..a57b7cc0c7c42339d8dfdfdd68a2573dcc4318a7 100644 (file)
@@ -669,7 +669,7 @@ regarding its parameter treatment."
 ;; functions allows them to be stand-alone commands, making it easier
 ;; to switch between browsers.
 
-(defun browse-url-interactive-arg (prompt)
+(defun browse-url-interactive-arg (prompt &optional default-url)
   "Read a URL from the minibuffer, prompting with PROMPT.
 If `transient-mark-mode' is non-nil and the mark is active,
 it defaults to the current region, else to the URL at or before
@@ -686,7 +686,8 @@ for use in `interactive'."
                                      "[\t\r\f\n ]+" ""
                                      (buffer-substring-no-properties
                                       (region-beginning) (region-end))))
-                               (browse-url-url-at-point)))
+                               (browse-url-url-at-point)
+                                default-url))
        (not (eq (null browse-url-new-window-flag)
                 (null current-prefix-arg)))))
 
@@ -793,6 +794,13 @@ narrowed."
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Browser-independent commands
 
+(defun url-tidy (url)
+  "Tidy up URL as much as possible."
+  (if (equal 0 (string-match ".*://" url))
+      url
+    (concat "http://" url) ;;TODO guess more url forms, like mailto
+    ))
+
 ;; A generic command to call the current browse-url-browser-function
 
 ;;;###autoload
@@ -805,6 +813,7 @@ first, if that exists."
   (interactive (browse-url-interactive-arg "URL: "))
   (unless (called-interactively-p 'interactive)
     (setq args (or args (list browse-url-new-window-flag))))
+  (setq url (url-tidy url))
   (let ((process-environment (copy-sequence process-environment))
        (function (or (and (string-match "\\`mailto:" url)
                           browse-url-mailto-function)
diff --git a/lisp/xwidget-test.el b/lisp/xwidget-test.el
new file mode 100644 (file)
index 0000000..fd7ecfa
--- /dev/null
@@ -0,0 +1,147 @@
+;;test like:
+;; cd /path/to/xwidgets-emacs-dir
+;; make   all&&  src/emacs -q --eval "(progn (load \"`pwd`/lisp/xwidget-test.el\") (xwidget-demo-basic))"
+
+
+;; you should see:
+;; - a gtk button
+;; - a gtk toggle button
+;; - a gtk slider button
+;; - an xembed window(using gtk_socket) showing another emacs instance
+;; - an xembed window(using gtk_socket) showing an uzbl web browser if its installed
+
+;;the widgets will move when you type in the buffer. good!
+
+;;there will be redrawing issues when widgets change rows, etc. bad!
+
+;;its currently difficult to give kbd focus to the xembedded emacs,
+;;but try evaling the following:
+
+;; (xwidget-set-keyboard-grab 3 1)
+
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; demo/test functions
+(require 'xwidget)
+
+(defmacro xwidget-demo (name &rest body)
+  `(defun ,(intern (concat "xwidget-demo-" name)) ()
+     (interactive)
+     (switch-to-buffer ,(format "*xwidget-demo-%s*" name))
+     (text-mode);;otherwise no local keymap
+     (insert "Some random text for xwidgets to be inserted in for demo purposes.\n")
+     ,@body))
+
+(xwidget-demo "a-button" 
+              (xwidget-insert (point-min) 'button  "button" 60  50)
+              (define-key (current-local-map) [xwidget-event] 'xwidget-handler-demo-basic))
+
+(xwidget-demo "a-toggle-button" 
+              (xwidget-insert (point-min) 'toggle  "teggle" 60  50)
+              (define-key (current-local-map) [xwidget-event] 'xwidget-handler-demo-basic))
+
+(xwidget-demo "a-big-button" 
+              (xwidget-insert (point-min)  'button "button" 400  500)
+              (define-key (current-local-map) [xwidget-event] 'xwidget-handler-demo-basic))
+
+(xwidget-demo "a-socket" 
+              (xwidget-insert (point-min)  'socket "socket" 500  500)
+              (define-key (current-local-map) [xwidget-event] 'xwidget-handler-demo-basic))
+
+(xwidget-demo "a-socket-osr-broken" 
+              (xwidget-insert (point-min)  'socket-osr "socket-osr" 500  500)
+              (define-key (current-local-map) [xwidget-event] 'xwidget-handler-demo-basic))
+
+
+(xwidget-demo "a-slider" 
+              (xwidget-insert (point-min)  'slider "slider" 500  100)
+              (define-key (current-local-map) [xwidget-event] 'xwidget-handler-demo-basic))
+
+(xwidget-demo "a-canvas" 
+              (xwidget-insert (point-min)  'cairo "canvas" 1000  1000)
+              (define-key (current-local-map) [xwidget-event] 'xwidget-handler-demo-basic))
+
+(xwidget-demo "a-webkit-broken" 
+              (xwidget-insert (point-min)  'webkit "webkit" 1000  1000)
+              (define-key (current-local-map) [xwidget-event] 'xwidget-handler-demo-basic))
+
+(xwidget-demo "a-webkit-osr" 
+              (xwidget-insert (point-min)  'webkit-osr "webkit-osr" 1000  1000)
+              (define-key (current-local-map) [xwidget-event] 'xwidget-handler-demo-basic))
+
+
+
+(xwidget-demo "basic"
+  (xwidget-insert (point-min)  'button "button" 40  50 )
+  (xwidget-insert          15  'toggle "toggle" 60  30  )
+  (xwidget-insert          30  'socket "emacs"  400 200 )
+  (xwidget-insert          20  'slider "slider" 100 50  )
+  (xwidget-insert          40  'socket "uzbl-core"   400 400 )
+  (define-key (current-local-map) [xwidget-event] 'xwidget-handler-demo-basic)
+)
+
+
+;it doesnt seem gtk_socket_steal works very well. its deprecated.
+; xwininfo -int
+; then (xwidget-embed-steal 3 <winid>)
+(defun xwidget-demo-grab ()
+  (interactive)
+  (insert "0 <<< grabbed appp will appear here\n")
+  (xwidget-insert          1 1 3 "1" 1000 )
+  (define-key (current-local-map) [xwidget-event] 'xwidget-handler-demo-grab)  
+  )
+
+;ive basically found these xembeddable things:
+;openvrml
+;emacs
+;mplayer
+;surf
+;uzbl
+
+;try the openvrml:
+;/usr/libexec/openvrml-xembed 0 ~/Desktop/HelloWorld.wrl
+
+
+(defun xwidget-handler-demo-basic ()
+  (interactive)
+  (message "stuff happened to xwidget %S" last-input-event)
+  (let*
+      ((xwidget-event-type (nth 2 last-input-event))
+       (xwidget (nth 1 last-input-event)))
+    (cond ( (eq xwidget-event-type 'xembed-ready)
+            (let*
+                ((xembed-id (nth 3 last-input-event)))
+              (message "xembed ready  event: %S xw-id:%s" xembed-id xwidget)
+              ;;will start emacs/uzbl in a xembed socket when its ready
+              (cond
+               (t;;(eq 3 xwidget)
+                (start-process "xembed" "*xembed*" (format "%s/src/emacs" default-directory) "-q" "--parent-id" (number-to-string xembed-id) ) )
+;;               ((eq 5 xwidget-id)
+;;                (start-process "xembed2" "*xembed2*" "uzbl-core"  "-s" (number-to-string xembed-id)  "http://www.fsf.org" )
+               )
+               
+               )
+            ))))
+
+
+
+(defun xwidget-handler-demo-grab ()
+  (interactive)
+  (message "stuff happened to xwidget %S" last-input-event)
+  (let*
+      ((xwidget-event-type (nth 2 last-input-event)))
+    (cond ( (eq xwidget-event-type 'xembed-ready)
+            (let*
+                ((xembed-id (nth 3 last-input-event)))
+              (message "xembed ready  %S" xembed-id)
+              )
+            ))))
+(defun xwidget-dummy-hook ()
+  (message "xwidget dummy hook called"))
+
+;  (xwidget-resize-hack 1 200 200)
+
+;(xwidget-demo-basic)
diff --git a/lisp/xwidget.el b/lisp/xwidget.el
new file mode 100644 (file)
index 0000000..d90dca3
--- /dev/null
@@ -0,0 +1,467 @@
+;;; xwidget.el --- api functions for xwidgets
+;;  see xwidget.c for more api functions
+
+
+;;; Commentary:
+;; 
+
+(require 'xwidget-internal)
+
+;;TODO model after make-text-button instead!
+;;; Code:
+
+(defun xwidget-insert (pos type title width height)
+  "Insert an xwidget at POS, given ID, TYPE, TITLE WIDTH and HEIGHT.
+Return ID
+
+see xwidget.c for types suitable for TYPE."
+  (goto-char pos)
+  (let ((id (make-xwidget (point) (point)  type  title  width  height nil)))
+    (put-text-property (point)
+                       (+ 1 (point)) 'display (list 'xwidget ':xwidget id))
+    
+    id))
+
+
+(defun xwidget-at (pos)
+  "Return xwidget at POS."
+  ;;TODO this function is a bit tedious because the C layer isnt well protected yet and
+  ;;xwidgetp aparently doesnt work yet
+  (let* ((disp (get-text-property pos 'display))
+         (xw (car (cdr (cdr  disp)))))
+    ;;(if ( xwidgetp  xw) xw nil)
+    (if (equal 'xwidget (car disp)) xw)
+    ))
+
+
+
+
+;; (defun xwidget-socket-handler ()
+;;   "Create plug for socket.  TODO."
+;;   (interactive)
+;;   (message "socket handler xwidget %S" last-input-event)
+;;   (let*
+;;       ((xwidget-event-type (nth 2 last-input-event))
+;;        (xwidget-id (nth 1 last-input-event)))
+;;     (cond ( (eq xwidget-event-type 'xembed-ready)
+;;             (let*
+;;                 ((xembed-id (nth 3 last-input-event)))
+;;               (message "xembed ready  event: %S xw-id:%s" xembed-id xwidget-id)
+;;               ;;TODO fetch process data from the xwidget. create it, store process info
+;;               ;;will start emacs/uzbl in a xembed socket when its ready
+;;               ;; (cond
+;;               ;;  ((eq 3 xwidget-id)
+;;               ;;   (start-process "xembed" "*xembed*" (format "%ssrc/emacs" default-directory) "-q" "--parent-id" (number-to-string xembed-id) ) )
+;;               ;;  ((eq 5 xwidget-id)
+;;               ;;   (start-process "xembed2" "*xembed2*" "uzbl-core"  "-s" (number-to-string xembed-id)  "http://www.fsf.org" )  )
+;;               )))))
+
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; webkit support
+(require 'browse-url)
+(require 'image-mode);;for some image-mode alike functinoality
+(require 'cl);;for flet
+
+;;;###autoload
+(defun xwidget-webkit-browse-url (url &optional new-session)
+  "Ask xwidget-webkit to browse URL.
+NEW-SESSION specifies whether to create a new xwidget-webkit session.  URL
+defaults to the string looking like a url around the cursor position."
+  (interactive (progn
+                (require 'browse-url)
+                (browse-url-interactive-arg "xwidget-webkit URL: "
+                                             ;;( xwidget-webkit-current-url)
+                                             )))
+  (when (stringp url)
+    (setq url (url-tidy url))
+    (if new-session
+       (xwidget-webkit-new-session url)
+      (xwidget-webkit-goto-url url))))
+
+
+;;shims for adapting image mode code to the webkit browser window
+(defun xwidget-image-display-size  (spec &optional pixels frame)
+  "Image code adaptor.  SPEC PIXELS FRAME like the corresponding `image-mode' fn."
+  (let ((xwi (xwidget-info  (xwidget-at 1))))
+    (cons (aref xwi 2)
+          (aref xwi 3))))
+
+(defmacro xwidget-image-mode-navigation-adaptor (fn)
+  "Image code adaptor.  `image-mode' FN is called."
+  `(lambda () (interactive)
+     (flet ((image-display-size (spec) (xwidget-image-display-size spec)))
+       (funcall ,fn ))))
+
+(defmacro xwidget-image-mode-navigation-adaptor-p (fn)
+    "Image code adaptor.  `image-mode' FN is called with interactive arg."
+  `(lambda (n) (interactive "p")
+     (flet ((image-display-size (spec) (xwidget-image-display-size spec)))
+       (funcall ,fn n))))
+
+
+;;todo.
+;; - check that the webkit support is compiled in
+(defvar xwidget-webkit-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "g" 'xwidget-webkit-browse-url)
+    (define-key map "a" 'xwidget-webkit-adjust-size-to-content)
+    (define-key map "b" 'xwidget-webkit-back )
+    (define-key map "r" 'xwidget-webkit-reload )
+    (define-key map "t" (lambda () (interactive) (message "o")) )
+    (define-key map "\C-m" 'xwidget-webkit-insert-string)
+    (define-key map "w" 'xwidget-webkit-current-url)
+
+    ;;similar to image mode bindings
+    (define-key map (kbd "SPC")       (xwidget-image-mode-navigation-adaptor   'image-scroll-up))
+    (define-key map (kbd "DEL")       (xwidget-image-mode-navigation-adaptor   'image-scroll-down))
+
+    (define-key map [remap scroll-up]          (xwidget-image-mode-navigation-adaptor 'image-scroll-up))
+    (define-key map [remap scroll-up-command]  (xwidget-image-mode-navigation-adaptor 'image-scroll-up))
+    
+    (define-key map [remap scroll-down]       (xwidget-image-mode-navigation-adaptor  'image-scroll-down))
+    (define-key map [remap scroll-down-command]       (xwidget-image-mode-navigation-adaptor  'image-scroll-down))
+    
+    (define-key map [remap forward-char]       (xwidget-image-mode-navigation-adaptor-p  'image-forward-hscroll))
+    (define-key map [remap backward-char]       (xwidget-image-mode-navigation-adaptor-p  'image-backward-hscroll))
+    (define-key map [remap right-char]       (xwidget-image-mode-navigation-adaptor-p  'image-forward-hscroll))
+    (define-key map [remap left-char]       (xwidget-image-mode-navigation-adaptor-p  'image-backward-hscroll))
+    (define-key map [remap previous-line]       (xwidget-image-mode-navigation-adaptor-p  'image-previous-line))
+    (define-key map [remap next-line]       (xwidget-image-mode-navigation-adaptor-p  'image-next-line))
+
+    (define-key map [remap move-beginning-of-line]       (xwidget-image-mode-navigation-adaptor-p  'image-bol))
+    (define-key map [remap move-end-of-line]       (xwidget-image-mode-navigation-adaptor-p  'image-eol))
+    (define-key map [remap beginning-of-buffer]       (xwidget-image-mode-navigation-adaptor  'image-bob))
+    (define-key map [remap end-of-buffer]       (xwidget-image-mode-navigation-adaptor  'image-eob))
+    map)
+  "Keymap for `xwidget-webkit-mode'.")
+
+;;the xwidget event needs to go into a higher level handler
+;;since the xwidget can generate an event even if its offscreen
+;;TODO this needs to use callbacks and consider different xw ev types
+(define-key (current-global-map) [xwidget-event] 'xwidget-event-handler)
+(defun xwidget-log ( &rest msg)
+  (let ( (buf  (get-buffer-create "*xwidget-log*")))
+    (save-excursion
+      (buffer-disable-undo buf)
+      (set-buffer buf)
+      (insert (apply  'format msg))
+      (insert "\n"))))
+
+(defun xwidget-event-handler ()
+  "Receive xwidget event."
+  (interactive)
+  (xwidget-log "stuff happened to xwidget %S" last-input-event)
+  (let*
+      ((xwidget-event-type (nth 1 last-input-event))
+       (xwidget (nth 2 last-input-event))
+                                        ;(xwidget-callback (xwidget-get xwidget 'callback));;TODO stopped working for some reason
+       )
+                                        ;(funcall  xwidget-callback xwidget xwidget-event-type)
+    (message "xw callback %s" xwidget)
+    (funcall  'xwidget-webkit-callback xwidget xwidget-event-type)
+    ))
+
+(defun xwidget-webkit-callback (xwidget xwidget-event-type)
+  (save-excursion
+    (cond ( (buffer-live-p (xwidget-buffer xwidget))
+            (set-buffer (xwidget-buffer xwidget))
+            (let* ( (strarg  (nth 3 last-input-event)))
+              (cond ((eq xwidget-event-type 'document-load-finished)
+                     (xwidget-log "webkit finished loading: '%s'" (xwidget-webkit-get-title xwidget))
+                     (xwidget-adjust-size-to-content xwidget)
+                     (rename-buffer (format "*xwidget webkit: %s *" (xwidget-webkit-get-title xwidget)))
+                     (pop-to-buffer (current-buffer))
+                     )
+                    
+                    ((eq xwidget-event-type 'navigation-policy-decision-requested)
+                     (if (string-match ".*#\\(.*\\)" strarg)
+                         (xwidget-webkit-show-id-or-named-element xwidget (match-string 1 strarg))))
+                    (t (xwidget-log "unhandled event:%s" xwidget-event-type)))))
+          (t (xwidget-log "error: callback called for xwidget with dead buffer")))))
+
+(define-derived-mode xwidget-webkit-mode
+  special-mode "xwidget-webkit" "xwidget webkit view mode"
+  (setq buffer-read-only t)
+  ;; Keep track of [vh]scroll when switching buffers
+  (image-mode-setup-winprops)
+
+  )
+
+(defvar xwidget-webkit-last-session-buffer nil)
+
+(defun  xwidget-webkit-last-session ()
+  "Last active webkit, or nil."
+  (if (buffer-live-p xwidget-webkit-last-session-buffer)
+      (save-excursion
+        (set-buffer xwidget-webkit-last-session-buffer)
+        (xwidget-at 1))
+    nil))
+
+(defun xwidget-webkit-current-session ()
+  "Either the webkit in the current buffer, or the last one used, which might be nil."
+  (if (xwidget-at 1)
+      (xwidget-at 1)
+    (xwidget-webkit-last-session)))
+
+(defun xwidget-adjust-size-to-content (xw)
+  "Resize XW to content."
+  ;;xwidgets doesnt support widgets that have their own opinions about size well yet
+  ;;this reads the desired size and resizes the emacs allocated area accordingly
+  (let ((size (xwidget-size-request xw)))
+    (xwidget-resize xw (car size) (cadr size))))
+
+
+(defvar xwidget-webkit-activeelement-js"
+function findactiveelement(doc){
+//alert(doc.activeElement.value);
+   if(doc.activeElement.value != undefined){
+      return doc.activeElement;
+   }else{
+        // recurse over the child documents:
+        var frames = doc.getElementsByTagName('frame');
+        for (var i = 0; i < frames.length; i++)
+        {
+                var d = frames[i].contentDocument;
+                 var rv = findactiveelement(d);
+                 if(rv != undefined){
+                    return rv;
+                 }
+        }
+    }
+    return undefined;
+};
+
+
+"
+
+"javascript that finds the active element."
+;;yes its ugly. because:
+;; - there is aparently no way to find the active frame other than recursion
+;; - the js "for each" construct missbehaved on the "frames" collection
+;; - a window with no frameset still has frames.length == 1, but frames[0].document.activeElement != document.activeElement
+;;TODO the activeelement type needs to be examined, for iframe, etc. sucks.
+)
+
+(defun xwidget-webkit-insert-string (xw str)
+  "Insert string in the active field in the webkit.
+Argument XW webkit.
+Argument STR string."
+  ;;read out the string in the field first and provide for edit
+  (interactive
+   (let* ((xww (xwidget-webkit-current-session))
+
+          (field-value
+           (progn
+             (xwidget-webkit-execute-script xww xwidget-webkit-activeelement-js)
+             (xwidget-webkit-execute-script-rv xww "findactiveelement(document).value;" )))
+          (field-type              (xwidget-webkit-execute-script-rv xww "findactiveelement(document).type;" )))
+     (list xww
+           (cond ( (equal "text" field-type) (read-string "text:" field-value))
+                 ( (equal "password" field-type) (read-passwd "password:" nil field-value))
+                 ( (equal "textarea" field-type) (xwidget-webkit-begin-edit-textarea xww field-value))
+                 ))))
+  (xwidget-webkit-execute-script xw (format "findactiveelement(document).value='%s'" str)))
+
+
+(defun xwidget-webkit-begin-edit-textarea (xw text)
+  (switch-to-buffer 
+   (generate-new-buffer "textarea"))
+  
+  (set (make-local-variable 'xwbl) xw)
+  (insert text)
+  )
+
+(defun xwidget-webkit-end-edit-textarea ()
+  (interactive)
+  (goto-char (point-min))
+  (replace-string "\n" "\\n")
+  (xwidget-webkit-execute-script xwbl (format "findactiveelement(document).value='%s'"
+                                              (buffer-substring (point-min) (point-max))))
+  ;;TODO convert linefeed to \n
+  )
+
+(defun xwidget-webkit-show-named-element (xw element-name)
+  "make named-element show. for instance an anchor."
+  (interactive (list (xwidget-webkit-current-session) (read-string "element name:")))
+  ;;TODO
+  ;; since an xwidget is an Emacs object, it is not trivial to do some things that are taken for granted in a normal browser.
+  ;; scrolling an anchor/named-element into view is one such thing.
+  ;; this function implements a proof-of-concept for this.
+  ;; problems remaining:
+  ;; - the selected window is scrolled but this is not always correct
+  ;; - this needs to be interfaced into browse-url somehow. the tricky part is that we need to do this in two steps:
+  ;;   A: load the base url, wait for load signal to arrive B: navigate to the anchor when the base url is finished rendering
+  
+  ;;this part figures out the Y coordinate of the element
+  (let ((y 
+         (string-to-number (xwidget-webkit-execute-script-rv xw (format "document.getElementsByName('%s')[0].getBoundingClientRect().top" element-name) 0))))
+    ;;now we need to tell emacs to scroll the element into view. 
+    (xwidget-log "scroll: %d" y)
+    (set-window-vscroll (selected-window) y t))
+  )
+
+(defun xwidget-webkit-show-id-element (xw element-id)
+  "make id-element show. for instance an anchor."
+  (interactive (list (xwidget-webkit-current-session) (read-string "element id:")))
+  (let ((y 
+         (string-to-number (xwidget-webkit-execute-script-rv xw (format "document.getElementById('%s').getBoundingClientRect().top" element-id) 0))))
+    ;;now we need to tell emacs to scroll the element into view. 
+    (xwidget-log "scroll: %d" y)
+    (set-window-vscroll (selected-window) y t))
+  )
+
+(defun xwidget-webkit-show-id-or-named-element (xw element-id)
+  "make id-element show. for instance an anchor."
+  (interactive (list (xwidget-webkit-current-session) (read-string "element id:")))
+  (let* ((y1 
+         (string-to-number (xwidget-webkit-execute-script-rv xw (format "document.getElementsByName('%s')[0].getBoundingClientRect().top" element-id) "0")))
+        (y2 
+         (string-to-number (xwidget-webkit-execute-script-rv xw (format "document.getElementById('%s').getBoundingClientRect().top" element-id) "0")))
+        (y3 (max y1 y2)))
+    ;;now we need to tell emacs to scroll the element into view. 
+    (xwidget-log "scroll: %d" y3)
+    (set-window-vscroll (selected-window) y3 t))
+  )
+
+(defun xwidget-webkit-adjust-size-to-content ()
+  "Adjust webkit to content size."
+  (interactive)
+  ( xwidget-adjust-size-to-content ( xwidget-webkit-current-session)))
+
+(defun xwidget-webkit-adjust-size (w h)
+  "Manualy set webkit size.
+Argument W width.
+Argument H height."
+  ;;TODO shouldnt be tied to the webkit xwidget
+  (interactive "nWidth:\nnHeight:\n")
+  ( xwidget-resize ( xwidget-webkit-current-session) w h))
+
+(defun xwidget-webkit-fit-width ()
+  (interactive)
+  (xwidget-webkit-adjust-size
+   (- (caddr (window-inside-pixel-edges)) (car (window-inside-pixel-edges)))
+   1000))
+
+(defun xwidget-webkit-new-session (url)
+"Create a new webkit session buffer with URL."
+  (let*
+      ((bufname (generate-new-buffer-name "*xwidget-webkit*"))
+       xw)
+    (setq xwidget-webkit-last-session-buffer (switch-to-buffer (get-buffer-create bufname)))
+    (insert " ")
+    (setq xw (xwidget-insert 1 'webkit-osr  bufname 1000 1000))
+    (xwidget-put xw 'callback 'xwidget-webkit-callback)
+    (xwidget-webkit-mode)
+    (xwidget-webkit-goto-uri ( xwidget-webkit-last-session) url )))
+
+
+(defun xwidget-webkit-goto-url (url)
+  "Goto URL."
+  (if ( xwidget-webkit-current-session)
+      (progn
+        (xwidget-webkit-goto-uri ( xwidget-webkit-current-session) url))
+    ( xwidget-webkit-new-session url)))
+
+(defun xwidget-webkit-back ()
+  "Back in history."
+  (interactive)
+  (xwidget-webkit-execute-script ( xwidget-webkit-current-session)  "history.go(-1);"))
+
+(defun xwidget-webkit-reload ()
+  "Reload current url."
+  (interactive)
+  (xwidget-webkit-execute-script ( xwidget-webkit-current-session)  "history.go(0);"))
+
+(defun xwidget-webkit-current-url ()
+  "Get the webkit url. place it on kill ring."
+  (interactive)
+  (let* ((rv (xwidget-webkit-execute-script-rv (xwidget-webkit-current-session) "document.URL"))
+         (url (kill-new   (if rv rv ""))))
+    (message "url: %s" url )
+    url))
+
+(defun xwidget-webkit-execute-script-rv (xw script &optional default)
+  "same as xwidget-webkit-execute-script but also wraps an ugly hack to return a value"
+  ;;notice the fugly "title" hack. it is needed because the webkit api doesnt support returning values.
+  ;;this is a wrapper for the title hack so its easy to remove should webkit someday support JS return values
+  ;;or we find some other way to access the DOM
+
+  ;;reset webkit title. fugly.
+  (let* (          (emptytag "titlecantbewhitespaceohthehorror")
+                   title)
+    (xwidget-webkit-execute-script xw (format "document.title=\"%s\";" (if default default emptytag)))
+    (xwidget-webkit-execute-script xw (format "document.title=%s;" script))
+    (setq title (xwidget-webkit-get-title xw))
+    (if (equal emptytag title) (setq title ""))
+    (unless title (setq title default))
+    title))
+
+
+;; use declare here?
+;; (declare-function xwidget-resize-internal "xwidget.c" )
+;; check-declare-function?
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defun xwidget-webkit-get-selection ()
+  (xwidget-webkit-execute-script-rv (xwidget-webkit-current-session)
+                                    "window.getSelection().toString();"))
+
+(defun xwidget-webkit-copy-selection-as-kill ()
+  (interactive)
+  (kill-new (xwidget-webkit-get-selection)))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; xwidget plist management(similar to the process plist functions)
+
+(defun xwidget-get (xwidget propname)
+  "Return the value of XWIDGET' PROPNAME property.
+This is the last value stored with `(xwidget-put XWIDGET PROPNAME VALUE)'."
+  (plist-get (xwidget-plist xwidget) propname))
+
+(defun xwidget-put (xwidget propname value)
+  "Change XWIDGET' PROPNAME property to VALUE.
+It can be retrieved with `(xwidget-get XWIDGET PROPNAME)'."
+  (set-xwidget-plist xwidget
+                    (plist-put (xwidget-plist xwidget) propname value)))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defun xwidget-cleanup ()
+  "Delete zombie xwidgets."
+  ;;its still pretty easy to trigger bugs with xwidgets.
+  ;;this function tries to implement a workaround
+  (interactive)
+  (xwidget-delete-zombies) ;;kill xviews who should have been deleted but stull linger
+  (redraw-display);;redraw display otherwise ghost of zombies  will remain to haunt the screen
+  )
+
+
+
+;;this is a workaround because I cant find the right place to put it in C
+;;seems to work well in practice though
+;;(add-hook 'window-configuration-change-hook 'xwidget-cleanup)
+(add-hook 'window-configuration-change-hook 'xwidget-delete-zombies)
+
+;;killflash is sadly not reliable yet.
+(defvar xwidget-webkit-kill-flash-oneshot t)
+(defun xwidget-webkit-kill-flash ()
+  "Disable the flash plugin in webkit.
+This is needed because Flash is non-free and doesnt work reliably
+on 64 bit systems and offscreen rendering.  Sadly not reliable
+yet, so deinstall Flash instead for now."
+  ;;you can only call this once or webkit crashes and takes emacs with it. odd.
+  (unless xwidget-webkit-kill-flash-oneshot
+    (xwidget-disable-plugin-for-mime "application/x-shockwave-flash")
+    (setq xwidget-webkit-kill-flash-oneshot t)))
+
+(xwidget-webkit-kill-flash)
+
+(provide 'xwidget)
+
+(provide 'xwidget)
+
+;;; xwidget.el ends here
index dd667ea60a351cf3240612f735a762af1d318c70..8d4c530678205c6ca61e713dc8b158f7e580a65c 100644 (file)
@@ -227,6 +227,12 @@ CFLAGS_SOUND= @CFLAGS_SOUND@
 RSVG_LIBS= @RSVG_LIBS@
 RSVG_CFLAGS= @RSVG_CFLAGS@
 
+CLUTTER_LIBS= @CLUTTER_LIBS@
+CLUTTER_CFLAGS= @CLUTTER_CFLAGS@
+
+WEBKIT_LIBS= @WEBKIT_LIBS@
+WEBKIT_CFLAGS= @WEBKIT_CFLAGS@
+
 IMAGEMAGICK_LIBS= @IMAGEMAGICK_LIBS@
 IMAGEMAGICK_CFLAGS= @IMAGEMAGICK_CFLAGS@
 
@@ -305,6 +311,7 @@ ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I$(srcdir) \
   $(C_SWITCH_MACHINE) $(C_SWITCH_SYSTEM) $(C_SWITCH_X_SITE) \
   $(GNUSTEP_CFLAGS) $(CFLAGS_SOUND) $(RSVG_CFLAGS) $(IMAGEMAGICK_CFLAGS) \
   $(LIBXML2_CFLAGS) $(DBUS_CFLAGS) \
+  $(WEBKIT_CFLAGS) $(CLUTTER_CFLAGS) \
   $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \
   $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) $(PROFILING_CFLAGS) \
   $(LIBGNUTLS_CFLAGS) \
@@ -335,9 +342,11 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
        process.o gnutls.o callproc.o \
        region-cache.o sound.o atimer.o \
        doprnt.o intervals.o textprop.o composite.o xml.o \
+       xwidget.o \
        $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ)
 obj = $(base_obj) $(NS_OBJC_OBJ)
 
+xwidget.o: xwidget.c xwidget.h
 ## Object files used on some machine or other.
 ## These go in the DOC file on all machines in case they are needed.
 ## Some of them have no DOC entries, but it does no harm to have them
@@ -380,6 +389,7 @@ otherobj= $(TERMCAP_OBJ) $(PRE_ALLOC_OBJ) $(GMALLOC_OBJ) $(RALLOC_OBJ) \
 ## with GCC, we might need LIB_GCC again after them.
 LIBES = $(LIBS) $(LIBX_BASE) $(LIBX_OTHER) $(LIBSOUND) \
    $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(DBUS_LIBS) \
+   $(WEBKIT_LIBS) $(CLUTTER_LIBS) \
    $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \
    $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
    $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
index c7652504de2ae00771439b8b544029d54719c5d8..b4aa0153846fa3c5dadd0b561372f287d9f4df02 100644 (file)
@@ -290,7 +290,11 @@ enum glyph_type
   IMAGE_GLYPH,
 
   /* Glyph is a space of fractional width and/or height.  */
-  STRETCH_GLYPH
+  STRETCH_GLYPH,
+#ifdef HAVE_XWIDGETS
+  /* Glyph is an external widget drawn by the GUI toolkit.   */
+  XWIDGET_GLYPH
+#endif  
 };
 
 
@@ -433,6 +437,9 @@ struct glyph
     /* Image ID for image glyphs (type == IMAGE_GLYPH).  */
     int img_id;
 
+#ifdef HAVE_XWIDGETS
+    struct xwidget* xwidget;
+#endif    
     /* Sub-structure for type == STRETCH_GLYPH.  */
     struct
     {
@@ -1299,6 +1306,9 @@ struct glyph_string
   /* Image, if any.  */
   struct image *img;
 
+#ifdef HAVE_XWIDGETS  
+  struct xwidget* xwidget;
+#endif
   /* Slice */
   struct glyph_slice slice;
 
@@ -1984,7 +1994,11 @@ enum display_element_type
   IT_TRUNCATION,
 
   /* Continuation glyphs.  See the comment for IT_TRUNCATION.  */
-  IT_CONTINUATION
+  IT_CONTINUATION,
+
+#ifdef HAVE_XWIDGETS  
+  IT_XWIDGET
+#endif
 };
 
 
@@ -2048,6 +2062,9 @@ enum it_method {
   GET_FROM_C_STRING,
   GET_FROM_IMAGE,
   GET_FROM_STRETCH,
+#ifdef HAVE_XWIDGETS
+  GET_FROM_XWIDGET,
+#endif  
   NUM_IT_METHODS
 };
 
@@ -2265,6 +2282,13 @@ struct it
       struct {
        Lisp_Object object;
       } stretch;
+#ifdef HAVE_XWIDGETS
+      /* method == GET_FROM_XWIDGET */
+      struct {
+       Lisp_Object object;
+        struct xwidget* xwidget;
+      } xwidget;
+#endif
     } u;
 
     /* current text and display positions.  */
@@ -2388,6 +2412,10 @@ struct it
   /* If what == IT_IMAGE, the id of the image to display.  */
   ptrdiff_t image_id;
 
+#ifdef HAVE_XWIDGETS  
+  /* If what == IT_XWIDGET*/
+  struct xwidget* xwidget;
+#endif
   /* Values from `slice' property.  */
   struct it_slice slice;
 
index a50877a6a9001499513745c98ca2b591f243bfe2..73c58ceded8b419a3cc9594cce3f374084e5cfb4 100644 (file)
@@ -16,7 +16,6 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
-
 #include <config.h>
 #include <signal.h>
 #include <stdio.h>
@@ -49,6 +48,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "xterm.h"
 #endif /* HAVE_X_WINDOWS */
 
+
+
 #ifdef HAVE_NTGUI
 #include "w32term.h"
 #endif /* HAVE_NTGUI */
@@ -57,6 +58,10 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "nsterm.h"
 #endif
 
+#ifdef HAVE_XWIDGETS
+#include "xwidget.h"
+#endif
+
 /* Include systime.h after xterm.h to avoid double inclusion of time.h.  */
 
 #include "systime.h"
@@ -290,8 +295,7 @@ add_window_display_history (struct window *w, const char *msg, int paused_p)
    PAUSED_P non-zero means that the update has been interrupted for
    pending input.  */
 
-static void
-add_frame_display_history (struct frame *f, int paused_p)
+static void add_frame_display_history (struct frame *f, int paused_p)
 {
   char *buf;
 
@@ -3731,6 +3735,9 @@ update_window (struct window *w, int force_p)
   add_window_display_history (w, w->current_matrix->method, paused_p);
 #endif
 
+#ifdef HAVE_XWIDGETS
+  xwidget_end_redisplay(w, w->current_matrix);
+#endif
   clear_glyph_matrix (desired_matrix);
 
   return paused_p;
@@ -4324,6 +4331,12 @@ scrolling_window (struct window *w, int header_line_p)
        break;
     }
 
+#ifdef HAVE_XWIDGETS
+ //currently this is needed to detect xwidget movement reliably. or probably not.
+  //printf("scrolling_window\n");
+    return 0;
+#endif
+  
   /* Give up if some rows in the desired matrix are not enabled.  */
   if (!MATRIX_ROW (desired_matrix, i)->enabled_p)
     return -1;
index c36c7df7e453ffe1de91577d106740a91f4a6b6e..73be96f73bc10d5f5e704c1571e2243dff59a96c 100644 (file)
@@ -48,6 +48,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "buffer.h"
 #include "window.h"
 
+#ifdef HAVE_XWIDGETS
+#include "xwidget.h"
+#endif
 #include "systty.h"
 #include "blockinput.h"
 #include "syssignal.h"
@@ -1533,6 +1536,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
       syms_of_xfns ();
       syms_of_xmenu ();
       syms_of_fontset ();
+#ifdef HAVE_XWIDGETS
+      syms_of_xwidget();
+#endif
       syms_of_xsettings ();
 #ifdef HAVE_X_SM
       syms_of_xsmfns ();
index 1a62b59b7afb7c8d69fea7ee117c5b9d5f284d04..e45cc716a31d49faf84d7fcc0a60f6bfbf7ef43d 100644 (file)
@@ -27,28 +27,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "lisp.h"
 #include "frame.h"
 #include "xterm.h"
-
-#define EMACS_TYPE_FIXED emacs_fixed_get_type ()
-#define EMACS_FIXED(obj) \
-  G_TYPE_CHECK_INSTANCE_CAST (obj, EMACS_TYPE_FIXED, EmacsFixed)
-
-typedef struct _EmacsFixed EmacsFixed;
-typedef struct _EmacsFixedPrivate EmacsFixedPrivate;
-typedef struct _EmacsFixedClass EmacsFixedClass;
-
-struct _EmacsFixed
-{
-  GtkFixed container;
-
-  /*< private >*/
-  EmacsFixedPrivate *priv;
-};
-
-struct _EmacsFixedClass
-{
-  GtkFixedClass parent_class;
-};
-
+#ifdef HAVE_XWIDGETS
+#include "xwidget.h"
+#endif
 struct _EmacsFixedPrivate
 {
   struct frame *f;
@@ -61,21 +42,147 @@ static void emacs_fixed_get_preferred_width  (GtkWidget *widget,
 static void emacs_fixed_get_preferred_height (GtkWidget *widget,
                                               gint      *minimum,
                                               gint      *natural);
-static GType emacs_fixed_get_type (void);
 G_DEFINE_TYPE (EmacsFixed, emacs_fixed, GTK_TYPE_FIXED)
 
+#ifdef HAVE_XWIDGETS
+/* void aloc_callback(GtkWidget* child, GtkWidget* fixed){ */
+/*   GtkAllocation child_allocation; */
+/*   GtkRequisition child_requisition; */
+
+/*   //TODO */
+/*   // if child is an xwidget, find its clipping area and modify allocation */
+
+/*   struct xwidget_view* xv = (struct xwidget_view*) g_object_get_data (G_OBJECT (child), XG_XWIDGET_VIEW); */
+/*   printf("aloc callback %d %s\n", xv, gtk_widget_get_name(child)); */
+/*   if(xv){ */
+/*     printf(" allocation modification for xw\n"); */
+/*     gtk_widget_get_allocation(child, &child_allocation); */
+/*     child_allocation.width = xv->clip_right; */
+/*     child_allocation.height = xv->clip_bottom - xv->clip_top; */
+/*     gtk_widget_size_allocate (child, &child_allocation); */
+/*     //TODO find a way to remove this feeble workaround */
+/*   } */
+
+/* } */
+
+struct GtkFixedPrivateL
+{
+  GList *children;
+};
+
+static void emacs_fixed_gtk_widget_size_allocate (GtkWidget *widget,
+                                           GtkAllocation *allocation){
+  //for xwidgets
+
+
+  //TODO 1st call base class method
+  EmacsFixedClass *klass;
+  GtkWidgetClass *parent_class;
+  struct GtkFixedPrivateL* priv;
+  GtkFixedChild *child;
+  GtkAllocation child_allocation;
+  GtkRequisition child_requisition;
+  GList *children;
+  struct xwidget_view* xv;
+  
+  //  printf(" emacs_fixed_gtk_widget_size_allocate\n");
+  klass = EMACS_FIXED_GET_CLASS (widget);
+  parent_class = g_type_class_peek_parent (klass);
+  parent_class->size_allocate (widget, allocation);
+
+  priv = G_TYPE_INSTANCE_GET_PRIVATE (widget,
+                               GTK_TYPE_FIXED,
+                               struct GtkFixedPrivateL);
+  //fixed->priv = G_TYPE_INSTANCE_GET_PRIVATE (fixed, GTK_TYPE_FIXED, GtkFixedPrivate);
+  //then modify allocations
+  /* gtk_container_foreach  (widget, */
+  /*                         aloc_callback, */
+  /*                         widget); */
+
+  //begin copy paste extravaganza!!!
+
+  //GtkFixed *fixed = GTK_FIXED (widget);
+  //GtkFixedPrivate *priv = fixed->priv;
+
+  
+  gtk_widget_set_allocation (widget, allocation);
+
+  if (gtk_widget_get_has_window (widget))
+    {
+      if (gtk_widget_get_realized (widget))
+        gdk_window_move_resize (gtk_widget_get_window (widget),
+                                allocation->x,
+                                allocation->y,
+                                allocation->width,
+                                allocation->height);
+    }
+
+  for (children = priv->children;
+       children;
+       children = children->next)
+    {
+      child = children->data;
+
+      if (!gtk_widget_get_visible (child->widget))
+        continue;
+
+      gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
+      child_allocation.x = child->x;
+      child_allocation.y = child->y;
+
+      if (!gtk_widget_get_has_window (widget))
+        {
+          child_allocation.x += allocation->x;
+          child_allocation.y += allocation->y;
+        }
+
+      child_allocation.width = child_requisition.width;
+      child_allocation.height = child_requisition.height;
+
+
+
+      xv = (struct xwidget_view*) g_object_get_data (G_OBJECT (child->widget), XG_XWIDGET_VIEW);
+      //printf("aloc callback %d %s\n", xv, gtk_widget_get_name(child));
+      if(xv){
+        //gtk_widget_get_allocation(child, &child_allocation);
+        child_allocation.width = xv->clip_right;
+        child_allocation.height = xv->clip_bottom - xv->clip_top;
+        //gtk_widget_size_allocate (child, &child_allocation);
+        //TODO find a way to remove this feeble workaround
+        //        printf(" allocation internal modification for xw %d  %d,%d\n",xv,        child_allocation.width,        child_allocation.height);
+
+      }
+      gtk_widget_size_allocate (child->widget, &child_allocation);
+
+    }
+
+}
+
+#endif
+
 static void
 emacs_fixed_class_init (EmacsFixedClass *klass)
 {
   GtkWidgetClass *widget_class;
+  GtkFixedClass *fixed_class;
 
   widget_class = (GtkWidgetClass*) klass;
+  fixed_class = (GtkFixedClass*) klass;
 
   widget_class->get_preferred_width = emacs_fixed_get_preferred_width;
   widget_class->get_preferred_height = emacs_fixed_get_preferred_height;
+#ifdef HAVE_XWIDGETS
+  widget_class->size_allocate =  emacs_fixed_gtk_widget_size_allocate;
+#endif
   g_type_class_add_private (klass, sizeof (EmacsFixedPrivate));
 }
 
+static GType
+emacs_fixed_child_type (GtkFixed *container)
+{
+  return GTK_TYPE_WIDGET;
+}
+
 static void
 emacs_fixed_init (EmacsFixed *fixed)
 {
index 3fa294aa41eab95af5603605681986ac873f93fe..90fb37e521bc04ae3334ab976cfb579a24e37061 100644 (file)
@@ -27,7 +27,33 @@ G_BEGIN_DECLS
 
 struct frame;
 
+#define EMACS_TYPE_FIXED                  (emacs_fixed_get_type ())
+#define EMACS_FIXED(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), EMACS_TYPE_FIXED, EmacsFixed))
+#define EMACS_FIXED_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), EMACS_TYPE_FIXED, EmacsFixedClass))
+#define EMACS_IS_FIXED(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EMACS_TYPE_FIXED))
+#define EMACS_IS_FIXED_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), EMACS_TYPE_FIXED))
+#define EMACS_FIXED_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), EMACS_TYPE_FIXED, EmacsFixedClass))
+
+typedef struct _EmacsFixed              EmacsFixed;
+typedef struct _EmacsFixedPrivate       EmacsFixedPrivate;
+typedef struct _EmacsFixedClass         EmacsFixedClass;
+
+struct _EmacsFixed
+{
+  GtkFixed container;
+
+  /*< private >*/
+  EmacsFixedPrivate *priv;
+};
+
+
+struct _EmacsFixedClass
+{
+  GtkFixedClass parent_class;
+};
+
 extern GtkWidget *emacs_fixed_new (struct frame *f);
+extern GType emacs_fixed_get_type (void);
 
 G_END_DECLS
 
index 56858acd6aa058c1c68f40529daf204b4608162a..82609bb4cb2302cd3e59b69a4ac5e469ca1997dd 100644 (file)
@@ -331,6 +331,9 @@ static Lisp_Object Qsave_session;
 #ifdef HAVE_DBUS
 static Lisp_Object Qdbus_event;
 #endif
+#ifdef HAVE_XWIDGETS
+Lisp_Object Qxwidget_event;
+#endif
 static Lisp_Object Qconfig_changed_event;
 
 /* Lisp_Object Qmouse_movement; - also an event header */
@@ -4043,6 +4046,13 @@ kbd_buffer_get_event (KBOARD **kbp,
          obj = make_lispy_event (event);
          kbd_fetch_ptr = event + 1;
        }
+#endif
+#ifdef HAVE_XWIDGETS      
+      else if (event->kind == XWIDGET_EVENT)
+       {
+         obj = make_lispy_event (event);
+         kbd_fetch_ptr = event + 1;
+       }
 #endif
       else if (event->kind == CONFIG_CHANGED_EVENT)
        {
@@ -5972,7 +5982,13 @@ make_lispy_event (struct input_event *event)
        return Fcons (Qdbus_event, event->arg);
       }
 #endif /* HAVE_DBUS */
-
+#ifdef HAVE_XWIDGETS
+    case XWIDGET_EVENT:
+      {
+        printf("cool, an xwidget event arrived in make_lispy_event!\n");
+        return  Fcons (Qxwidget_event,event->arg);
+      }
+#endif
     case CONFIG_CHANGED_EVENT:
        return Fcons (Qconfig_changed_event,
                       Fcons (event->arg,
@@ -11496,6 +11512,10 @@ syms_of_keyboard (void)
   DEFSYM (Qdbus_event, "dbus-event");
 #endif
 
+#ifdef HAVE_XWIDGETS
+  Qxwidget_event = intern ("xwidget-event");
+  staticpro (&Qxwidget_event);
+#endif
   DEFSYM (QCenable, ":enable");
   DEFSYM (QCvisible, ":visible");
   DEFSYM (QChelp, ":help");
index fd5219adf4c10bbc89a5ca3a4b0359425951519a..823e0ec52055502e20fc2b3cd2246cabecf190c6 100644 (file)
@@ -428,7 +428,11 @@ enum pvec_type
   PVEC_SUB_CHAR_TABLE = 0x100000,
   PVEC_FONT = 0x200000,
   PVEC_OTHER = 0x400000,
-  PVEC_TYPE_MASK = 0x7ffe00
+#ifdef HAVE_XWIDGETS
+  PVEC_XWIDGET = 0x800000,
+  PVEC_XWIDGET_VIEW = 0x1000000,
+#endif
+  PVEC_TYPE_MASK = 0x3fffe00
 
 #if 0 /* This is used to make the value of PSEUDOVECTOR_FLAG available to
         GDB.  It doesn't work on OS Alpha.  Moved to a variable in
index c2edde590fea410e9c91c212a740035f8885d91e..5b1ea74879938efe670758e8d03bb945d9cf8a25 100644 (file)
@@ -36,7 +36,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "blockinput.h"
 #include "termhooks.h"         /* For struct terminal.  */
 #include "font.h"
-
+#ifdef HAVE_XWIDGETS
+#include "xwidget.h"
+#endif
 Lisp_Object Qstandard_output;
 
 static Lisp_Object Qtemp_buffer_setup_hook;
@@ -1767,6 +1769,13 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
          strout (XSUBR (obj)->symbol_name, -1, -1, printcharfun);
          PRINTCHAR ('>');
        }
+#ifdef HAVE_XWIDGETS
+      else if (XXWIDGETP (obj))
+       {
+         strout ("#<xwidget ", -1, -1, printcharfun);
+         PRINTCHAR ('>');
+       }
+#endif      
       else if (WINDOWP (obj))
        {
          strout ("#<window ", -1, -1, printcharfun);
index bc61a986cce52caaaef5ad4cde02062daaedc943..3e74046f13767f131b2c1c204f95bd3515360bd1 100644 (file)
@@ -205,7 +205,10 @@ enum event_kind
   /* Non-key system events (e.g. application menu events) */
   , NS_NONKEY_EVENT
 #endif
-
+#ifdef HAVE_XWIDGETS
+  /* events generated by xwidgets*/
+   , XWIDGET_EVENT
+#endif
 };
 
 /* If a struct input_event has a kind which is SELECTION_REQUEST_EVENT
index 048779d683087a112fc595419108c3388b54f7e6..827d3646e49608dda0a407de04c12002327b7b56 100644 (file)
@@ -49,7 +49,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #ifdef HAVE_NS
 #include "nsterm.h"
 #endif
-
+#ifdef HAVE_XWIDGETS
+#include "xwidget.h"
+#endif
 Lisp_Object Qwindowp, Qwindow_live_p;
 static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer;
 static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
@@ -3905,6 +3907,9 @@ Signal an error when WINDOW is the only window on its frame.  */)
 
       /* Block input.  */
       BLOCK_INPUT;
+#ifdef HAVE_XWIDGETS
+      xwidget_view_delete_all_in_window(w);
+#endif
       window_resize_apply (p, horflag);
 
       /* If this window is referred to by the dpyinfo's mouse
index e7ecd2c1d915f8ac76903a998276454faa56db81..90cd3cd9e2cfec05cc586fc3af012819e983a9f0 100644 (file)
@@ -313,7 +313,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #endif
 
 #include "font.h"
-
+#ifdef HAVE_XWIDGETS
+#include "xwidget.h"
+#endif
 #ifndef FRAME_X_OUTPUT
 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
 #endif
@@ -894,6 +896,9 @@ static int next_element_from_c_string (struct it *);
 static int next_element_from_buffer (struct it *);
 static int next_element_from_composition (struct it *);
 static int next_element_from_image (struct it *);
+#ifdef HAVE_XWIDGETS
+static int next_element_from_xwidget(struct it *);
+#endif
 static int next_element_from_stretch (struct it *);
 static void load_overlay_strings (struct it *, EMACS_INT);
 static int init_from_display_pos (struct it *, struct window *,
@@ -4407,6 +4412,9 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
   if (CONSP (spec)
       /* Simple specifications.  */
       && !EQ (XCAR (spec), Qimage)
+#ifdef HAVE_XWIDGETS
+      && !EQ (XCAR (spec), Qxwidget)
+#endif
       && !EQ (XCAR (spec), Qspace)
       && !EQ (XCAR (spec), Qwhen)
       && !EQ (XCAR (spec), Qslice)
@@ -4845,7 +4853,11 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
              || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
                 && valid_image_p (value))
 #endif /* not HAVE_WINDOW_SYSTEM */
-             || (CONSP (value) && EQ (XCAR (value), Qspace)));
+             || (CONSP (value) && EQ (XCAR (value), Qspace))
+#ifdef HAVE_XWIDGETS
+             || XWIDGETP(value)
+#endif
+             );
 
   if (valid_p && !display_replaced_p)
     {
@@ -4919,6 +4931,19 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
          *position = it->position = start_pos;
          retval = 1 + (it->area == TEXT_AREA);
        }
+#ifdef HAVE_XWIDGETS
+      else if (XWIDGETP(value))
+       {
+          //printf("handle_single_display_spec: im an xwidget!!\n");
+          it->what = IT_XWIDGET;
+          it->method = GET_FROM_XWIDGET;
+          it->position = start_pos;
+         it->object = NILP (object) ? it->w->buffer : object;
+         *position = start_pos;
+
+          it->xwidget = lookup_xwidget(value);
+       }
+#endif      
 #ifdef HAVE_WINDOW_SYSTEM
       else
        {
@@ -5647,6 +5672,11 @@ push_it (struct it *it, struct text_pos *position)
     case GET_FROM_STRETCH:
       p->u.stretch.object = it->object;
       break;
+#ifdef HAVE_XWIDGETS
+    case GET_FROM_XWIDGET:
+      p->u.xwidget.object = it->object;
+      break;
+#endif      
     }
   p->position = position ? *position : it->position;
   p->current = it->current;
@@ -5740,6 +5770,11 @@ pop_it (struct it *it)
       it->object = p->u.image.object;
       it->slice = p->u.image.slice;
       break;
+#ifdef HAVE_XWIDGETS
+    case GET_FROM_XWIDGET:
+      it->object = p->u.xwidget.object;
+      break;
+#endif
     case GET_FROM_STRETCH:
       it->object = p->u.stretch.object;
       break;
@@ -6387,6 +6422,9 @@ static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
   next_element_from_c_string,
   next_element_from_image,
   next_element_from_stretch
+#ifdef HAVE_XWIDGETS
+  ,next_element_from_xwidget
+#endif  
 };
 
 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
@@ -7218,6 +7256,9 @@ set_iterator_to_next (struct it *it, int reseat_p)
 
     case GET_FROM_IMAGE:
     case GET_FROM_STRETCH:
+#ifdef HAVE_XWIDGETS
+    case GET_FROM_XWIDGET:
+
       /* The position etc with which we have to proceed are on
         the stack.  The position may be at the end of a string,
          if the `display' property takes up the whole string.  */
@@ -7226,7 +7267,7 @@ set_iterator_to_next (struct it *it, int reseat_p)
       if (it->method == GET_FROM_STRING)
        goto consider_string_end;
       break;
-
+#endif
     default:
       /* There are no other methods defined, so this should be a bug.  */
       abort ();
@@ -7643,6 +7684,19 @@ next_element_from_image (struct it *it)
   return 1;
 }
 
+#ifdef HAVE_XWIDGETS
+/* im not sure about this FIXME JAVE*/
+static int
+next_element_from_xwidget (struct it *it)
+{
+  it->what = IT_XWIDGET;
+  //assert_valid_xwidget_id(it->xwidget_id,"next_element_from_xwidget");
+  //this is shaky because why do we set "what" if we dont set the other parts??
+  //printf("xwidget_id %d: in next_element_from_xwidget: FIXME \n", it->xwidget_id);
+  return 1;
+}
+#endif
+
 
 /* Fill iterator IT with next display element from a stretch glyph
    property.  IT->object is the value of the text property.  Value is
@@ -13192,6 +13246,13 @@ redisplay_internal (void)
              *w->desired_matrix->method = 0;
              debug_method_add (w, "optimization 1");
 #endif
+#if HAVE_XWIDGETS
+              //debug optimization movement issue
+              //w->desired_matrix->no_scrolling_p = 1;
+              //*w->desired_matrix->method = 0;
+              //debug_method_add (w, "optimization 1");
+#endif
+
 #ifdef HAVE_WINDOW_SYSTEM
              update_window_fringes (w, 0);
 #endif
@@ -16147,6 +16208,8 @@ try_window (Lisp_Object window, struct text_pos pos, int flags)
   /* Initialize iterator and info to start at POS.  */
   start_display (&it, w, pos);
 
+
+  
   /* Display all lines of W.  */
   while (it.current_y < it.last_visible_y)
     {
@@ -16155,6 +16218,11 @@ try_window (Lisp_Object window, struct text_pos pos, int flags)
       if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
        return 0;
     }
+#ifdef HAVE_XWIDGETS_xxx
+ //currently this is needed to detect xwidget movement reliably. or probably not.
+  printf("try_window\n");
+    return 0;
+#endif
 
   /* Don't let the cursor end in the scroll margins.  */
   if ((flags & TRY_WINDOW_CHECK_MARGINS)
@@ -16248,6 +16316,13 @@ try_window_reusing_current_matrix (struct window *w)
     return 0;
 #endif
 
+#ifdef HAVE_XWIDGETS_xxx
+ //currently this is needed to detect xwidget movement reliably. or probably not.
+  printf("try_window_reusing_current_matrix\n");
+    return 0;
+#endif
+
+
   if (/* This function doesn't handle terminal frames.  */
       !FRAME_WINDOW_P (f)
       /* Don't try to reuse the display if windows have been split
@@ -17028,6 +17103,13 @@ try_window_id (struct window *w)
     return 0;
 #endif
 
+#ifdef HAVE_XWIDGETS_xxx
+  //maybe needed for proper xwidget movement
+    printf("try_window_id\n");
+    return -1;
+#endif
+
+  
   /* This is handy for debugging.  */
 #if 0
 #define GIVE_UP(X)                                             \
@@ -17851,6 +17933,29 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
               glyph->left_box_line_p,
               glyph->right_box_line_p);
     }
+#ifdef HAVE_XWIDGETS  
+  else if (glyph->type == XWIDGET_GLYPH)
+    {
+      fprintf (stderr,
+              "  %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
+              glyph - row->glyphs[TEXT_AREA],
+              'X',
+              glyph->charpos,
+              (BUFFERP (glyph->object)
+               ? 'B'
+               : (STRINGP (glyph->object)
+                  ? 'S'
+                  : '-')),
+              glyph->pixel_width,
+              glyph->u.xwidget,
+              '.',
+              glyph->face_id,
+              glyph->left_box_line_p,
+              glyph->right_box_line_p);
+
+      //      printf("dump xwidget glyph\n");
+    }
+#endif  
 }
 
 
@@ -22103,6 +22208,13 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
 
              return OK_PIXELS (width_p ? img->width : img->height);
            }
+#ifdef HAVE_XWIDGETS
+         if (FRAME_WINDOW_P (it->f) && valid_xwidget_p (prop))
+           {
+              printf("calc_pixel_width_or_height: return dummy size FIXME\n");
+              return OK_PIXELS (width_p ? 100 : 100);
+            }
+#endif          
 #endif
          if (EQ (car, Qplus) || EQ (car, Qminus))
            {
@@ -22605,7 +22717,20 @@ fill_image_glyph_string (struct glyph_string *s)
   s->ybase += s->first_glyph->voffset;
 }
 
-
+#ifdef HAVE_XWIDGETS
+static void
+fill_xwidget_glyph_string (struct glyph_string *s)
+{
+  xassert (s->first_glyph->type == XWIDGET_GLYPH);
+  printf("fill_xwidget_glyph_string: width:%d \n",s->first_glyph->pixel_width);
+  s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
+  s->font = s->face->font;
+  s->width = s->first_glyph->pixel_width;
+  s->ybase += s->first_glyph->voffset;
+  s->xwidget = s->first_glyph->u.xwidget;
+  //assert_valid_xwidget_id ( s->xwidget, "fill_xwidget_glyph_string");
+}
+#endif
 /* Fill glyph string S from a sequence of stretch glyphs.
 
    START is the index of the first glyph to consider,
@@ -22937,6 +23062,21 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
        }                                                               \
      while (0)
 
+#ifdef HAVE_XWIDGETS
+#define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
+     do                                                                        \
+       { \
+         printf("BUILD_XWIDGET_GLYPH_STRING\n");                                                      \
+        s = (struct glyph_string *) alloca (sizeof *s);                \
+        INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL);          \
+        fill_xwidget_glyph_string (s);                                 \
+        append_glyph_string (&HEAD, &TAIL, s);                         \
+        ++START;                                                       \
+         s->x = (X);                                                   \
+       }                                                               \
+     while (0)
+#endif
+
 
 /* Add a glyph string for a sequence of character glyphs to the list
    of strings between HEAD and TAIL.  START is the index of the first
@@ -23091,6 +23231,11 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
              BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL,         \
                                        HL, X, LAST_X);                 \
              break;                                                    \
+            case XWIDGET_GLYPH:                                         \
+              BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL,       \
+                                          HL, X, LAST_X);               \
+              break;                                                    \
+                                                                        \
                                                                        \
            case GLYPHLESS_GLYPH:                                       \
              BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL,     \
@@ -23702,6 +23847,89 @@ produce_image_glyph (struct it *it)
     }
 }
 
+#ifdef HAVE_XWIDGETS
+static void
+produce_xwidget_glyph (struct it *it)
+{
+  struct xwidget* xw;
+  struct face *face;
+  int glyph_ascent, crop;
+  printf("produce_xwidget_glyph:\n");
+  xassert (it->what == IT_XWIDGET);
+
+  face = FACE_FROM_ID (it->f, it->face_id);
+  xassert (face);
+  /* Make sure X resources of the face is loaded.  */
+  PREPARE_FACE_FOR_DISPLAY (it->f, face);
+
+  xw = it->xwidget;
+  it->ascent = it->phys_ascent = glyph_ascent = xw->height/2;
+  it->descent = xw->height/2;
+  it->phys_descent = it->descent;
+  it->pixel_width = xw->width;
+  /* It's quite possible for images to have an ascent greater than
+     their height, so don't get confused in that case.  */
+  if (it->descent < 0)
+    it->descent = 0;
+
+  it->nglyphs = 1;
+
+  if (face->box != FACE_NO_BOX)
+    {
+      if (face->box_line_width > 0)
+       {
+           it->ascent += face->box_line_width;
+           it->descent += face->box_line_width;
+       }
+
+      if (it->start_of_box_run_p)
+       it->pixel_width += eabs (face->box_line_width);
+      it->pixel_width += eabs (face->box_line_width);
+    }
+
+  take_vertical_position_into_account (it);
+
+  /* Automatically crop wide image glyphs at right edge so we can
+     draw the cursor on same display row.  */
+  if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
+      && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
+    {
+      it->pixel_width -= crop;
+    }
+
+  if (it->glyph_row)
+    {
+      struct glyph *glyph;
+      enum glyph_row_area area = it->area;
+
+      glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
+      if (glyph < it->glyph_row->glyphs[area + 1])
+       {
+         glyph->charpos = CHARPOS (it->position);
+         glyph->object = it->object;
+         glyph->pixel_width = it->pixel_width;
+         glyph->ascent = glyph_ascent;
+         glyph->descent = it->descent;
+         glyph->voffset = it->voffset;
+         glyph->type = XWIDGET_GLYPH;
+
+         glyph->multibyte_p = it->multibyte_p;
+         glyph->left_box_line_p = it->start_of_box_run_p;
+         glyph->right_box_line_p = it->end_of_box_run_p;
+         glyph->overlaps_vertically_p = 0;
+          glyph->padding_p = 0;
+         glyph->glyph_not_available_p = 0;
+         glyph->face_id = it->face_id;
+          glyph->u.xwidget = it->xwidget;
+          //assert_valid_xwidget_id(glyph->u.xwidget_id,"produce_xwidget_glyph");
+         glyph->font_type = FONT_TYPE_UNKNOWN;
+         ++it->glyph_row->used[area];
+       }
+      else
+       IT_EXPAND_MATRIX_WIDTH (it, area);
+    }
+}
+#endif
 
 /* Append a stretch glyph to IT->glyph_row.  OBJECT is the source
    of the glyph, WIDTH and HEIGHT are the width and height of the
@@ -24926,7 +25154,10 @@ x_produce_glyphs (struct it *it)
     produce_image_glyph (it);
   else if (it->what == IT_STRETCH)
     produce_stretch_glyph (it);
-
+#ifdef HAVE_XWIDGETS
+  else if (it->what == IT_XWIDGET)
+    produce_xwidget_glyph (it);
+#endif
  done:
   /* Accumulate dimensions.  Note: can't assume that it->descent > 0
      because this isn't true for images with `:ascent 100'.  */
@@ -25295,6 +25526,13 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
   /* Use normal cursor if not blinked off.  */
   if (!w->cursor_off_p)
     {
+
+#ifdef HAVE_XWIDGETS      
+      if (glyph != NULL && glyph->type == XWIDGET_GLYPH){
+        //printf("attempt xwidget cursor avoidance in get_window_cursor_type\n");
+        return NO_CURSOR;
+      }
+#endif      
       if (glyph != NULL && glyph->type == IMAGE_GLYPH)
        {
          if (cursor_type == FILLED_BOX_CURSOR)
index d030df55748608c5d9ed117d8ef000d94f29659f..cc8987a4055c992f2256bf4b63c15eec70c7bd28 100644 (file)
@@ -62,6 +62,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "coding.h"
 #include "frame.h"
 #include "dispextern.h"
+#ifdef HAVE_XWIDGETS
+#include "xwidget.h"
+#endif
 #include "fontset.h"
 #include "termhooks.h"
 #include "termopts.h"
@@ -2725,7 +2728,13 @@ x_draw_glyph_string (struct glyph_string *s)
     case IMAGE_GLYPH:
       x_draw_image_glyph_string (s);
       break;
-
+#ifdef HAVE_XWIDGETS
+    case XWIDGET_GLYPH:
+      //erase xwidget background
+      //x_draw_glyph_string_background (s, 0);
+      x_draw_xwidget_glyph_string (s);
+      break;
+#endif
     case STRETCH_GLYPH:
       x_draw_stretch_glyph_string (s);
       break;
@@ -7322,7 +7331,12 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text
   cursor_glyph = get_phys_cursor_glyph (w);
   if (cursor_glyph == NULL)
     return;
-
+#ifdef HAVE_XWIDGETS  
+  if (cursor_glyph->type == XWIDGET_GLYPH){
+    printf("tried avoiding xwidget cursor\n");
+    return; //experimental avoidance of cursor on xwidget
+  }
+#endif  
   /* If on an image, draw like a normal cursor.  That's usually better
      visible than drawing a bar, esp. if the image is large so that
      the bar might not be in the window.  */
@@ -9986,12 +10000,16 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
            https://bugzilla.gnome.org/show_bug.cgi?id=563627.  */
         id = g_log_set_handler ("GLib", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL
                                   | G_LOG_FLAG_RECURSION, my_log_handler, NULL);
+#ifdef HAVE_CLUTTER
+        gtk_clutter_init (&argc, &argv2);
+#else
 
         /* NULL window -> events for all windows go to our function.
            Call before gtk_init so Gtk+ event filters comes after our.  */
         gdk_window_add_filter (NULL, event_handler_gdk, NULL);
 
         gtk_init (&argc, &argv2);
+#endif
         g_log_remove_handler ("GLib", id);
 
         /* gtk_init does set_locale.  We must fix locale after calling it.  */
diff --git a/src/xwidget.c b/src/xwidget.c
new file mode 100644 (file)
index 0000000..b43cc14
--- /dev/null
@@ -0,0 +1,1453 @@
+#include <config.h>
+
+#include <signal.h>
+
+#include <stdio.h>
+#include <setjmp.h>
+#ifdef HAVE_X_WINDOWS
+
+#include "lisp.h"
+#include "blockinput.h"
+#include "syssignal.h"
+
+#include "xterm.h"
+#include <X11/cursorfont.h>
+
+#ifndef makedev
+#include <sys/types.h>
+#endif /* makedev */
+
+#ifdef BSD_SYSTEM
+#include <sys/ioctl.h>
+#endif /* ! defined (BSD_SYSTEM) */
+
+#include "systime.h"
+
+#ifndef INCLUDED_FCNTL
+#include <fcntl.h>
+#endif
+#include <ctype.h>
+#include <errno.h>
+#include <setjmp.h>
+#include <sys/stat.h>
+
+#include "charset.h"
+#include "character.h"
+#include "coding.h"
+#include "ccl.h"
+#include "frame.h"
+#include "dispextern.h"
+#include "fontset.h"
+#include "termhooks.h"
+#include "termopts.h"
+#include "termchar.h"
+#include "emacs-icon.h"
+#include "disptab.h"
+#include "buffer.h"
+#include "window.h"
+#include "keyboard.h"
+#include "intervals.h"
+#include "process.h"
+#include "atimer.h"
+#include "keymap.h"
+
+
+#ifdef USE_X_TOOLKIT
+#include <X11/Shell.h>
+#endif
+#include <X11/extensions/Xcomposite.h>
+#include <X11/extensions/Xrender.h>
+#include <cairo.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "gtkutil.h"
+#include "font.h"
+#endif
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#ifdef HAVE_GTK3
+//for gtk3; sockets and plugs
+#include <gtk/gtkx.h>
+#include "emacsgtkfixed.h"
+#endif
+
+
+
+#ifdef HAVE_GOOCANVAS
+#include <goocanvas.h>
+#endif
+
+#ifdef HAVE_CLUTTER
+#include <librsvg/rsvg.h>
+#include <clutter/clutter.h>
+#include <clutter-gtk/clutter-gtk.h>
+#endif
+
+#include <wchar.h>
+
+#ifdef HAVE_WEBKIT_OSR
+#include <webkit/webkitwebview.h>
+#include <webkit/webkitwebplugindatabase.h>
+#include <webkit/webkitwebplugin.h>
+#include <webkit/webkitglobals.h>
+#include <webkit/webkitwebnavigationaction.h>
+#include <webkit/webkitdownload.h>
+#endif
+
+#include "xwidget.h"
+
+//TODO should of course not be a hardcoded array but I can't be bothered atm
+//just a fixed array of xwidgets for now
+//would need to be hashtables or something
+
+#define MAX_XWIDGETS 100
+struct xwidget_view xwidget_views[MAX_XWIDGETS];
+
+//TODO embryo of lisp allocators for xwidgets
+//TODO xwidget* should be Lisp_xwidget*
+struct xwidget*
+allocate_xwidget (void)
+{
+  return ALLOCATE_PSEUDOVECTOR (struct xwidget, height, PVEC_XWIDGET);
+}
+
+//TODO xwidget_view* should be Lisp_xwidget_view*
+struct xwidget_view*
+allocate_xwidget_view (void)
+{
+  return ALLOCATE_PSEUDOVECTOR (struct xwidget_view, redisplayed, PVEC_XWIDGET_VIEW);
+}
+#define XSETXWIDGET(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_XWIDGET))
+#define XSETXWIDGET_VIEW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_XWIDGET_VIEW))
+
+Lisp_Object Qxwidget;
+Lisp_Object Qcxwidget;
+Lisp_Object Qtitle;
+Lisp_Object Qxwidget_set_keyboard_grab;
+Lisp_Object Qxwidget_embed_steal_window;
+Lisp_Object Qxwidget_info;
+Lisp_Object Qxwidget_resize;
+Lisp_Object Qxwidget_send_keyboard_event;
+
+Lisp_Object Qbutton, Qtoggle, Qslider, Qsocket, Qsocket_osr, Qcairo,
+  Qwebkit_osr, QCplist;
+
+
+extern Lisp_Object  QCtype;
+extern Lisp_Object QCwidth, QCheight;
+
+struct xwidget_view* xwidget_view_lookup(struct xwidget* xw,     struct window *w);
+Lisp_Object xwidget_spec_value ( Lisp_Object spec, Lisp_Object  key,  int *found);
+gboolean webkit_osr_damage_event_callback (GtkWidget *widget, GdkEventExpose *event, gpointer data) ;
+gboolean webkit_osr_key_event_callback (GtkWidget *widget, GdkEventKey *event, gpointer data) ;
+void     webkit_osr_document_load_finished_callback (WebKitWebView  *webkitwebview,
+                                                     WebKitWebFrame *arg1,
+                                                     gpointer        user_data);
+gboolean     webkit_osr_download_callback (WebKitWebView  *webkitwebview,
+                                       WebKitDownload *arg1,
+                                       gpointer        data);
+
+gboolean  webkit_osr_mime_type_policy_typedecision_requested_callback(WebKitWebView           *webView,
+                                                                      WebKitWebFrame          *frame,
+                                                                      WebKitNetworkRequest    *request,
+                                                                      gchar                   *mimetype,
+                                                                      WebKitWebPolicyDecision *policy_decision,
+                                                                      gpointer                 user_data);
+
+gboolean webkit_osr_new_window_policy_decision_requested_callback(WebKitWebView             *webView,
+                                                                  WebKitWebFrame            *frame,
+                                                                  WebKitNetworkRequest      *request,
+                                                                  WebKitWebNavigationAction *navigation_action,
+                                                                  WebKitWebPolicyDecision   *policy_decision,
+                                                                  gpointer                   user_data);
+
+
+gboolean webkit_osr_navigation_policy_decision_requested_callback(WebKitWebView             *webView,
+                                                        WebKitWebFrame            *frame,
+                                                        WebKitNetworkRequest      *request,
+                                                        WebKitWebNavigationAction *navigation_action,
+                                                        WebKitWebPolicyDecision   *policy_decision,
+                                                                  gpointer                   user_data);
+
+  
+DEFUN ("make-xwidget", Fmake_xwidget, Smake_xwidget, 7, 7, 0,
+         doc: /* xw */
+         )
+  (Lisp_Object beg, Lisp_Object end,
+     Lisp_Object type,
+     Lisp_Object title,
+     Lisp_Object width, Lisp_Object height,
+     Lisp_Object data)
+{
+  //should work a bit like "make-button"(make-button BEG END &rest PROPERTIES)
+  // arg "type" and fwd should be keyword args eventually
+  //(make-xwidget 3 3 'button "oei" 31 31 nil)
+  //(xwidget-info (car xwidget-alist))
+  struct xwidget* xw = allocate_xwidget();
+  Lisp_Object val;
+  struct gcpro gcpro1;
+  GCPRO1(xw);
+  XSETSYMBOL(xw->type, type);
+  XSETSTRING(xw->title, title);
+  //TODO buffer should be an optional argument not just assumed to be the current buffer
+  XSETBUFFER(xw->buffer,  Fcurrent_buffer()); // conservatively gcpro xw since we call lisp
+  xw->height = XFASTINT(height);
+  xw->width = XFASTINT(width);
+  XSETPSEUDOVECTOR (val, xw, PVEC_XWIDGET); //?? dunno why i need this
+  Vxwidget_alist = Fcons ( val, Vxwidget_alist);
+  xw->widgetwindow_osr = NULL;
+  xw->widget_osr = NULL;
+  xw->plist = Qnil;
+
+
+#ifdef HAVE_WEBKIT_OSR
+  /* DIY mvc. widget is rendered offscreen,
+     later bitmap copied to the views.
+   */
+  if (EQ(xw->type, Qwebkit_osr)){
+    printf("init webkit osr\n");
+    BLOCK_INPUT;
+    xw->widgetwindow_osr = GTK_CONTAINER (gtk_offscreen_window_new ());
+    gtk_window_resize(    GTK_WINDOW(xw->widgetwindow_osr), xw->width, xw->height);
+    xw->widget_osr = webkit_web_view_new();
+
+    gtk_widget_set_size_request (GTK_WIDGET (xw->widget_osr), xw->width, xw->height);
+    gtk_container_add (xw->widgetwindow_osr, xw->widget_osr);
+
+    gtk_widget_show_all (GTK_WIDGET (xw->widgetwindow_osr));
+
+    /* store some xwidget data in the gtk widgets for convenient retrieval in the event handlers. */
+    g_object_set_data (G_OBJECT (xw->widget_osr), XG_XWIDGET, (gpointer) (xw));
+    g_object_set_data (G_OBJECT (xw->widgetwindow_osr), XG_XWIDGET, (gpointer) (xw));
+    /* signals */
+    g_signal_connect (G_OBJECT ( xw->widgetwindow_osr), "damage-event",    G_CALLBACK (webkit_osr_damage_event_callback), NULL);
+
+    //TODO these were just a test hack
+    /* g_signal_connect (G_OBJECT ( xw->widget_osr), "key-press-event",    G_CALLBACK (webkit_osr_key_event_callback), NULL); */
+    /* g_signal_connect (G_OBJECT ( xw->widget_osr), "key-release-event",    G_CALLBACK (webkit_osr_key_event_callback), NULL);     */
+
+    g_signal_connect (G_OBJECT ( xw->widget_osr),
+                      "document-load-finished",
+                      G_CALLBACK (webkit_osr_document_load_finished_callback),
+                      xw);    
+
+    g_signal_connect (G_OBJECT ( xw->widget_osr),
+                      "download-requested",
+                      G_CALLBACK (webkit_osr_download_callback),
+                      xw);    
+
+    g_signal_connect (G_OBJECT ( xw->widget_osr),
+                      "mime-type-policy-decision-requested",
+                      G_CALLBACK (webkit_osr_mime_type_policy_typedecision_requested_callback),
+                      xw);    
+
+    g_signal_connect (G_OBJECT ( xw->widget_osr),
+                      "new-window-policy-decision-requested",
+                      G_CALLBACK (webkit_osr_new_window_policy_decision_requested_callback),
+                      xw);    
+
+    g_signal_connect (G_OBJECT ( xw->widget_osr),
+                      "navigation-policy-decision-requested",
+                      G_CALLBACK (webkit_osr_navigation_policy_decision_requested_callback),
+                      xw);    
+
+
+    webkit_web_view_load_uri(WEBKIT_WEB_VIEW(xw->widget_osr), "http://www.fsf.org");
+    UNBLOCK_INPUT;
+
+  }
+#endif
+
+  if (EQ(xw->type, Qsocket_osr)){
+    printf("init socket osr\n");
+    BLOCK_INPUT;
+    xw->widgetwindow_osr = GTK_CONTAINER (gtk_offscreen_window_new ());
+    gtk_window_resize(    GTK_WINDOW(xw->widgetwindow_osr), xw->width, xw->height);
+
+    ////////////////////
+    //xw->widget_osr = webkit_web_view_new();
+    xw->widget_osr = gtk_socket_new();
+    //g_signal_connect_after(xv->widget, "plug-added", G_CALLBACK(xwidget_plug_added), "plug added");
+    //g_signal_connect_after(xv->widget, "plug-removed", G_CALLBACK(xwidget_plug_removed), "plug removed");
+    ///////////////////
+    
+    gtk_widget_set_size_request (GTK_WIDGET (xw->widget_osr), xw->width, xw->height);
+    gtk_container_add (xw->widgetwindow_osr, xw->widget_osr);
+
+    gtk_widget_show_all (GTK_WIDGET (xw->widgetwindow_osr));
+
+    /* store some xwidget data in the gtk widgets for convenient retrieval in the event handlers. */
+    g_object_set_data (G_OBJECT (xw->widget_osr), XG_XWIDGET, (gpointer) (xw));
+    g_object_set_data (G_OBJECT (xw->widgetwindow_osr), XG_XWIDGET, (gpointer) (xw));
+    g_signal_connect (G_OBJECT (    xw->widgetwindow_osr), "damage-event",    G_CALLBACK (webkit_osr_damage_event_callback), NULL);
+
+    //webkit_web_view_load_uri(WEBKIT_WEB_VIEW(xw->widget_osr), "http://www.fsf.org");
+    UNBLOCK_INPUT;
+
+  }
+
+  UNGCPRO;
+  return val;
+}
+
+int
+xwidget_hidden(struct xwidget_view *xv)
+{
+  return  xv->hidden;
+}
+
+
+static void
+buttonclick_handler (GtkWidget * widget, gpointer data)
+{
+  struct xwidget *xw = (struct xwidget *) data;
+  struct input_event event;
+  Lisp_Object frame;
+  FRAME_PTR f = NULL;//(FRAME_PTR) g_object_get_data (G_OBJECT (xw->widget), XG_FRAME_DATA); //TODO
+  printf ("button clicked xw:%d '%s'\n", xw, xw->title);
+
+  EVENT_INIT (event);
+  event.kind = XWIDGET_EVENT;
+
+  XSETFRAME (frame, f);
+
+  event.frame_or_window = Qnil;        //frame; //how to get the frame here?
+
+
+  event.arg = Qnil;
+  event.arg = Fcons ((Lisp_Object)xw, event.arg); //TODO send the actual xwidget object now instead
+  event.arg = Fcons (intern ("buttonclick"), event.arg);
+
+  kbd_buffer_store_event (&event);
+
+
+}
+
+
+static void
+send_xembed_ready_event (struct xwidget* xw, int xembedid)
+{
+  struct input_event event;
+  EVENT_INIT (event);
+  event.kind = XWIDGET_EVENT;
+  event.frame_or_window = Qnil;        //frame; //how to get the frame here? //TODO i store it in the xwidget now
+
+  event.arg = Qnil;
+  event.arg = Fcons (make_number (xembedid), event.arg);
+  event.arg = Fcons ((Lisp_Object)xw, event.arg); //TODO
+  event.arg = Fcons (intern ("xembed-ready"), event.arg);
+
+
+  kbd_buffer_store_event (&event);
+
+}
+
+void
+xwidget_show_view (struct xwidget_view *xv)
+{
+  xv->hidden = 0;
+  gtk_widget_show(GTK_WIDGET(xv->widgetwindow));
+  gtk_fixed_move (GTK_FIXED (xv->emacswindow), GTK_WIDGET (xv->widgetwindow),  xv->x  + xv->clip_left, xv->y + xv->clip_top); //TODO refactor
+}
+
+
+/* hide an xvidget view */
+void
+xwidget_hide_view (struct xwidget_view *xv)
+{
+  xv->hidden = 1;
+  //gtk_widget_hide(GTK_WIDGET(xw->widgetwindow));
+  gtk_fixed_move (GTK_FIXED (xv->emacswindow), GTK_WIDGET (xv->widgetwindow),
+                  10000, 10000);
+}
+
+
+void xwidget_plug_added(GtkSocket *socket,
+                        gpointer   user_data)
+{
+  //hmm this doesnt seem to get called for foreign windows
+  printf("xwidget_plug_added\n");
+}
+
+gboolean xwidget_plug_removed(GtkSocket *socket,
+                              gpointer   user_data)
+{
+  printf("xwidget_plug_removed\n");
+  return TRUE; /* dont run the default handler because that kills the socket and we want to reuse it*/
+}
+
+
+void xwidget_slider_changed (GtkRange *range,
+                             gpointer  user_data)
+{
+  //slider value changed. change value of siblings
+  //correspondingly. but remember that changing value will again
+  //trigger signal
+
+  //TODO MVC view storage wont be an array futureish so the loop needs to change eventually
+  //TODO MVC it would be nice if this code could be reusable but, alas, C is not a functional language
+  //issues are:
+  // - the type of the controllers value (double, boolean etc)
+  // - the getter and setter (but they can be func pointers)
+  // a behemoth macro is always an option.
+  double v=gtk_range_get_value(range);
+  struct xwidget_view* xvp = g_object_get_data (G_OBJECT (range), XG_XWIDGET_VIEW);
+  struct xwidget_view* xv;
+
+  printf("slider changed val:%f\n", v);
+
+
+  //block sibling views signal handlers
+  for (int i = 0; i < MAX_XWIDGETS; i++)
+    {
+      xv = &xwidget_views[i];
+      if(xv->initialized && xvp->model == xv->model){
+        g_signal_handler_block( xv->widget,xv->handler_id);
+      }
+    }
+  //set values of sibling views and unblock
+  for (int i = 0; i < MAX_XWIDGETS; i++)
+    {
+      xv = &xwidget_views[i];
+      if(xv->initialized && xvp->model == xv->model){
+        gtk_range_set_value(GTK_RANGE(xv->widget), v);
+        g_signal_handler_unblock( xv->widget,xv->handler_id);
+      }
+    }
+
+}
+
+
+/* when the off-screen webkit master view changes this signal is called.
+   it copies the bitmap from the off-screen webkit instance */
+gboolean webkit_osr_damage_event_callback (GtkWidget *widget, GdkEventExpose *event, gpointer data)
+{
+  //TODO this is wrong! should just oueu a redraw of onscreen widget
+  struct xwidget* xw = (struct xwidget*) g_object_get_data (G_OBJECT (widget), XG_XWIDGET);
+  struct xwidget_view* xv;
+  //webkit_osr_redraw_child(xw, widget);
+  printf ("damage\n");
+  for (int i = 0; i < MAX_XWIDGETS; i++)//todo mvc refactor
+    {
+      xv = &xwidget_views[i];
+      if(xv->initialized && xv->model == xw){
+        gtk_widget_queue_draw (xv->widget); //redraw all views, the master has changed
+      }
+    }
+
+  return FALSE;
+}
+
+
+
+gboolean webkit_osr_key_event_callback (GtkWidget *widget, GdkEventKey *event, gpointer data)
+{
+  printf("terminating a webkit osr keypress\n");
+  //TRUE terminate the event here. no paren handlers will be called. but webkit then doesng get the event and it still crashes
+  //FALSE paren handlers will be called. webkit then gets the event and it still crashes
+  return TRUE; 
+}
+
+
+void store_xwidget_event_string(struct xwidget* xw, char* eventname,char* eventstr){
+  //refactor attempt
+  struct input_event event;
+  Lisp_Object xwl;
+  XSETXWIDGET(xwl,xw);
+  EVENT_INIT (event);
+  event.kind = XWIDGET_EVENT;
+  event.frame_or_window = Qnil;        //frame; //how to get the frame here? //TODO i store it in the xwidget now
+
+  event.arg = Qnil;
+  event.arg = Fcons (build_string(eventstr), event.arg);  //string so dont intern
+  event.arg = Fcons (xwl, event.arg); //TODO
+  event.arg = Fcons (intern (eventname), event.arg);//interning should be ok
+  kbd_buffer_store_event (&event);
+
+}
+
+//TODO deprecated, use load-status
+void     webkit_osr_document_load_finished_callback (WebKitWebView  *webkitwebview,
+                                                     WebKitWebFrame *arg1,
+                                                     gpointer        data)
+{
+  //TODO this event sending code should be refactored
+  //  struct xwidget *xw = (struct xwidget *) data;
+  struct xwidget* xw = (struct xwidget*) g_object_get_data (G_OBJECT (webkitwebview), XG_XWIDGET);  
+  printf("webkit finished loading\n");
+
+  store_xwidget_event_string(xw, 
+                             "document-load-finished", "");
+}
+
+gboolean     webkit_osr_download_callback (WebKitWebView  *webkitwebview,
+                                       WebKitDownload *arg1,
+                                       gpointer        data)
+{
+  //TODO this event sending code should be refactored
+  struct input_event event;
+  //  struct xwidget *xw = (struct xwidget *) data;
+  struct xwidget* xw = (struct xwidget*) g_object_get_data (G_OBJECT (webkitwebview), XG_XWIDGET);  
+  printf("download requested %s\n", webkit_download_get_uri (arg1));
+
+
+  printf("webkit finished loading\n");
+
+  store_xwidget_event_string(xw, "download-requested", webkit_download_get_uri (arg1));
+
+  return FALSE;
+}
+
+gboolean  webkit_osr_mime_type_policy_typedecision_requested_callback(WebKitWebView           *webView,
+                                                                      WebKitWebFrame          *frame,
+                                                                      WebKitNetworkRequest    *request,
+                                                                      gchar                   *mimetype,
+                                                                      WebKitWebPolicyDecision *policy_decision,
+                                                                      gpointer                 user_data)
+{
+  printf("mime policy requested\n");
+  // this function makes webkit send a download signal for all unknown mime types
+  // TODO defer the decision to lisp, so that its possible to make Emacs handle text mime for instance
+  if(!webkit_web_view_can_show_mime_type(webView, mimetype)){
+    webkit_web_policy_decision_download (policy_decision);
+    return TRUE;
+  }else{
+    return FALSE;
+  }
+}
+
+
+gboolean webkit_osr_new_window_policy_decision_requested_callback(WebKitWebView             *webView,
+                                                                  WebKitWebFrame            *frame,
+                                                                  WebKitNetworkRequest      *request,
+                                                                  WebKitWebNavigationAction *navigation_action,
+                                                                  WebKitWebPolicyDecision   *policy_decision,
+                                                                  gpointer                   user_data)
+{
+  struct xwidget* xw = (struct xwidget*) g_object_get_data (G_OBJECT (webView), XG_XWIDGET);  
+  printf("webkit_osr_new_window_policy_decision_requested_callback %s\n",
+         webkit_web_navigation_action_get_original_uri (navigation_action));
+  
+  store_xwidget_event_string(xw,  "new-window-policy-decision-requested", webkit_web_navigation_action_get_original_uri (navigation_action)
+                            );
+  return FALSE;
+}
+
+gboolean webkit_osr_navigation_policy_decision_requested_callback(WebKitWebView             *webView,
+                                                        WebKitWebFrame            *frame,
+                                                        WebKitNetworkRequest      *request,
+                                                        WebKitWebNavigationAction *navigation_action,
+                                                        WebKitWebPolicyDecision   *policy_decision,
+                                                        gpointer                   user_data)
+{
+  struct xwidget* xw = (struct xwidget*) g_object_get_data (G_OBJECT (webView), XG_XWIDGET);  
+  printf("webkit_osr_navigation_policy_decision_requested_callback %s\n",
+         webkit_web_navigation_action_get_original_uri (navigation_action));
+  store_xwidget_event_string(xw,  "navigation-policy-decision-requested", webkit_web_navigation_action_get_original_uri (navigation_action)
+                            );
+  return FALSE;
+}
+
+//for gtk3 webkit_osr
+gboolean
+xwidget_osr_draw_callback (GtkWidget *widget, cairo_t *cr, gpointer data)
+{
+  struct xwidget* xw = (struct xwidget*) g_object_get_data (G_OBJECT (widget), XG_XWIDGET);
+  struct xwidget_view* xv = (struct xwidget_view*) g_object_get_data (G_OBJECT (widget), XG_XWIDGET_VIEW);
+
+  //  printf("xwidget_osr_draw_callback gtk3 xw.id:%d xw.type:%d window:%d vis:%d\n",
+  //         xw,xw->type, gtk_widget_get_window (widget),  gtk_widget_get_visible (xw->widget_osr));
+
+  cairo_rectangle(cr, 0,0, xv->clip_right, xv->clip_bottom);//xw->width, xw->height);
+  cairo_clip(cr);
+
+  gtk_widget_draw (xw->widget_osr,  cr);
+
+
+  return FALSE;
+}
+
+
+gboolean
+xwidget_osr_button_callback ( GtkWidget *widget,
+                              GdkEvent  *event,
+                              gpointer   user_data)
+{
+  struct xwidget* xw = (struct xwidget*) g_object_get_data (G_OBJECT (widget), XG_XWIDGET);
+  GdkEvent* eventcopy =  gdk_event_copy(event);
+
+  ((GdkEventButton*)eventcopy)->window = gtk_widget_get_window(xw->widget_osr);
+  gtk_main_do_event(eventcopy); //TODO this will leak events. they should be deallocated later
+  return TRUE; //dont propagate this event furter
+}
+
+int xwidget_view_index=0;
+
+/* initializes and does initial placement of an xwidget view on screen */
+struct xwidget_view*
+xwidget_init_view (
+                   struct xwidget *xww,
+                   struct glyph_string *s,
+                   int x, int y)
+{
+  //TODO temp code replace with lisp list
+  struct xwidget_view *xv;
+  GdkColor color;
+
+  do{
+    if(xwidget_view_index < MAX_XWIDGETS)
+      xwidget_view_index++;
+    else
+      xwidget_view_index=0;
+
+    xv = &xwidget_views[xwidget_view_index];
+  }while(  xv->initialized == 1); //TODO yeah this can infloop if there are MAX_WIDGETS on-screen
+
+  xv->initialized = 1;
+  xv->w = s->w;
+  xv->model = xww;
+
+  //widget creation
+  if(EQ(xww->type, Qbutton))
+    {
+      xv->widget = gtk_button_new_with_label (XSTRING(xww->title)->data);
+      g_signal_connect (G_OBJECT (xv->widget), "clicked",
+                        G_CALLBACK (buttonclick_handler), xww); //the model rather than the view
+    } else if (EQ(xww->type, Qtoggle)) {
+    xv->widget = gtk_toggle_button_new_with_label (XSTRING(xww->title)->data);
+    //xv->widget = gtk_entry_new ();//temp hack to experiment with key propagation TODO entry widget is useful for testing
+  } else if (EQ(xww->type, Qsocket)) {
+    xv->widget = gtk_socket_new ();
+    g_signal_connect_after(xv->widget, "plug-added", G_CALLBACK(xwidget_plug_added), "plug added");
+    g_signal_connect_after(xv->widget, "plug-removed", G_CALLBACK(xwidget_plug_removed), "plug removed");
+    //TODO these doesnt help
+    gtk_widget_add_events(xv->widget, GDK_KEY_PRESS);
+    gtk_widget_add_events(xv->widget, GDK_KEY_RELEASE);
+  } else if (EQ(xww->type, Qslider)) {
+    xv->widget =
+      //gtk_hscale_new (GTK_ADJUSTMENT(gtk_adjustment_new (0.0, 0.0, 100.0, 1.0, 10.0, 10.0)));
+      gtk_hscale_new_with_range ( 0.0, 100.0, 10.0);
+    gtk_scale_set_draw_value (GTK_SCALE (xv->widget), FALSE);  //i think its emacs role to show text and stuff, so disable the widgets own text
+    xv->handler_id = g_signal_connect_after(xv->widget, "value-changed", G_CALLBACK(xwidget_slider_changed), "slider changed");
+  } else if (EQ(xww->type, Qcairo)) {
+    //Cairo view
+    //uhm cairo is differentish in gtk 3.
+    //gdk_cairo_create (gtk_widget_get_window (FRAME_GTK_WIDGET (s->f)));
+#ifdef HAVE_GOOCANVAS
+    xv->widget = goo_canvas_new();
+    GooCanvasItem *root, *rect_item, *text_item;
+    goo_canvas_set_bounds (GOO_CANVAS (xv->widget), 0, 0, 1000, 1000);
+    root = goo_canvas_get_root_item (GOO_CANVAS (xv->widget));
+    rect_item = goo_canvas_rect_new (root, 100, 100, 400, 400,
+                                     "line-width", 10.0,
+                                     "radius-x", 20.0,
+                                     "radius-y", 10.0,
+                                     "stroke-color", "yellow",
+                                     "fill-color", "red",
+                                     NULL);
+
+    text_item = goo_canvas_text_new (root, "Hello World", 300, 300, -1,
+                                     GTK_ANCHOR_CENTER,
+                                     "font", "Sans 24",
+                                     NULL);
+    goo_canvas_item_rotate (text_item, 45, 300, 300);
+
+#endif
+#ifdef HAVE_CLUTTER
+    xv->widget = gtk_clutter_embed_new ();;
+    ClutterActor *stage = NULL;
+    stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (        xv->widget));
+    ClutterColor stage_color = { 0xaa, 0xaa, 0xaa, 0xff }; /* Black */
+    clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
+
+    ClutterActor *  texture =  clutter_cairo_texture_new (1000, 1000);
+    clutter_container_add_actor(stage, texture);
+    clutter_actor_set_position(texture, 0,0);
+    clutter_actor_show(texture);
+
+    cairo_t *cr;
+    cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (texture));
+
+    /* draw on the context */
+    RsvgHandle *h =  rsvg_handle_new_from_file  ("/tmp/tst.svg",
+                                                 NULL);
+
+    rsvg_handle_render_cairo(h, cr);
+    cairo_destroy (cr);
+
+    /* Show the stage: */
+    clutter_actor_show (stage);
+#endif
+  } else if (EQ(xww->type, Qwebkit_osr)||EQ(xww->type, Qsocket_osr)) {
+#ifdef HAVE_WEBKIT_OSR
+    xv->widget = gtk_drawing_area_new();
+    gtk_widget_set_app_paintable ( xv->widget, TRUE); //because expose event handling
+    gtk_widget_add_events(xv->widget,
+                          GDK_BUTTON_PRESS_MASK
+                          | GDK_BUTTON_RELEASE_MASK
+                          | GDK_POINTER_MOTION_MASK);
+    g_signal_connect (G_OBJECT (    xv->widget), "draw",
+                      G_CALLBACK (xwidget_osr_draw_callback), NULL);
+    g_signal_connect (G_OBJECT (    xv->widget), "button-press-event",
+                      G_CALLBACK (xwidget_osr_button_callback), NULL);
+    g_signal_connect (G_OBJECT (    xv->widget), "button-release-event",
+                      G_CALLBACK (xwidget_osr_button_callback), NULL);
+    g_signal_connect (G_OBJECT (    xv->widget), "motion-notify-event",
+                      G_CALLBACK (xwidget_osr_button_callback), NULL);
+    /* g_signal_connect (G_OBJECT (    xv->widget), "key-press-event", */
+    /*                   G_CALLBACK (xwidget_osr_button_callback), NULL); */
+    /* g_signal_connect (G_OBJECT (    xv->widget), "key-release-event", */
+    /*                   G_CALLBACK (xwidget_osr_button_callback), NULL); */
+    
+#endif
+
+
+  } else return NULL;
+
+  //widget realization
+  //make container widget 1st, and put the actual widget inside the container
+  //later, drawing should crop container window if necessary to handle case where xwidget
+  //is partially obscured by other emacs windows
+  //other containers than gtk_fixed where explored, but gtk_fixed had the most predictable behaviour so far.
+  xv->emacswindow = GTK_CONTAINER (FRAME_GTK_WIDGET (s->f));
+  xv->widgetwindow = GTK_CONTAINER (gtk_fixed_new ()); 
+  gtk_widget_set_has_window(GTK_WIDGET (  xv->widgetwindow), TRUE);
+  gtk_container_add (xv->widgetwindow, xv->widget);
+
+  //store some xwidget data in the gtk widgets
+  g_object_set_data (G_OBJECT (xv->widget), XG_FRAME_DATA, (gpointer) (s->f)); //the emacs frame
+  g_object_set_data (G_OBJECT (xv->widget), XG_XWIDGET, (gpointer) (xww)); //the xwidget
+  g_object_set_data (G_OBJECT (xv->widget), XG_XWIDGET_VIEW, (gpointer) (xv)); //the xwidget
+  g_object_set_data (G_OBJECT (xv->widgetwindow), XG_XWIDGET, (gpointer) (xww)); //the xwidget window
+  g_object_set_data (G_OBJECT (xv->widgetwindow), XG_XWIDGET_VIEW, (gpointer) (xv)); //the xwidget window
+
+
+  gtk_widget_set_size_request (GTK_WIDGET (xv->widget), xww->width, xww->height);
+  gtk_widget_set_size_request (GTK_WIDGET (xv->widgetwindow), xww->width, xww->height);
+  gtk_fixed_put (GTK_FIXED (FRAME_GTK_WIDGET (s->f)), GTK_WIDGET (xv->widgetwindow), x, y);
+  xv->x = x;  xv->y = y;
+  gtk_widget_show_all (GTK_WIDGET (xv->widgetwindow));
+
+  //widgettype specific initialization only possible after realization
+  if (EQ(xww->type, Qsocket)) {
+    printf ("xwid:%d socket id:%x %d\n",
+            xww,
+            gtk_socket_get_id (GTK_SOCKET (xv->widget)),
+            gtk_socket_get_id (GTK_SOCKET (xv->widget)));
+    send_xembed_ready_event (xww,
+                             gtk_socket_get_id (GTK_SOCKET (xv->widget)));
+    //gtk_widget_realize(xw->widget);
+  }
+  return xv;
+}
+
+
+void
+x_draw_xwidget_glyph_string (struct glyph_string *s)
+{
+  /*
+    this method is called by the redisplay engine and places the xwidget on screen.
+    moving and clipping is done here. also view init.
+
+  */
+  int box_line_hwidth = eabs (s->face->box_line_width);
+  int box_line_vwidth = max (s->face->box_line_width, 0);
+  int height = s->height;
+  struct xwidget *xww = s->xwidget;
+  struct xwidget_view *xv = xwidget_view_lookup(xww, (s->w));
+  int clip_right; int clip_bottom; int clip_top; int clip_left;
+
+  int x = s->x;
+  int y = s->y + (s->height / 2) - (xww->height / 2);
+  int moved=0;
+
+  if (xv == NULL || xv->initialized == 0){
+    /* Views must be initialized once(only once).
+       We do it here in the display loop because there is no other time to know things like
+       window placement etc.
+    */
+    printf ("xv init for xw %d\n", xww);
+    xv = xwidget_init_view (xww, s, x, y);
+  }
+
+  //calculate clipping, which is used for all manner of onscreen xwidget views
+  //each widget border can get clipped by other emacs objects so there are four clipping variables
+  clip_right = min (xww->width, WINDOW_RIGHT_EDGE_X (s->w) - x - WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH(s->w) - WINDOW_RIGHT_FRINGE_WIDTH(s->w));
+  clip_left = max (0, WINDOW_LEFT_EDGE_X (s->w) - x + WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH(s->w) + WINDOW_LEFT_FRINGE_WIDTH(s->w));
+
+  clip_bottom = min (xww->height, WINDOW_BOTTOM_EDGE_Y (s->w) - WINDOW_MODE_LINE_HEIGHT (s->w) - y);
+  clip_top = max(0, WINDOW_TOP_EDGE_Y(s->w) -y );
+
+  //we are conserned with movement of the onscreen area. the area might sit still when the widget actually moves
+  //this happens when an emacs window border moves across a widget window
+  //so, if any corner of the outer widget clippng window moves, that counts as movement here, even
+  //if it looks like no movement happens because the widget sits still inside the clipping area.
+  //the widget can also move inside the clipping area, which happens later
+  moved = (xv->x  + xv->clip_left != x+clip_left)
+    || ((xv->y + xv->clip_top)!= (y+clip_top));
+  if(moved)    printf ("lxwidget moved: id:%d (%d,%d)->(%d,%d) y+clip_top:%d\n", xww, xv->x, xv->y, x, y, y + clip_top);
+  else
+    printf ("lxwidget DIDNT move: id:%d (%d,%d)->(%d,%d) y+clip_top:%d\n", xww, xv->x, xv->y, x, y, y + clip_top);
+  xv->x = x;
+  xv->y = y;
+  if (moved)   //has it moved?
+    {
+      if (1)//!xwidget_hidden(xv))     //hidden equals not being seen during redisplay
+        {
+          //TODO should be possible to use xwidget_show_view here
+          gtk_fixed_move (GTK_FIXED (FRAME_GTK_WIDGET (s->f)),
+                          GTK_WIDGET (xv->widgetwindow),
+                          x + clip_left, y + clip_top);
+        }
+    }
+  //clip the widget window if some parts happen to be outside drawable area
+  //an emacs window is not a gtk window, a gtk window covers the entire frame
+  //cliping might have changed even if we havent actualy moved, we try figure out when we need to reclip for real
+  if((xv->clip_right != clip_right)
+     || (xv->clip_bottom != clip_bottom)
+     || (xv->clip_top != clip_top)
+     || (xv->clip_left != clip_left)){
+    gtk_widget_set_size_request (GTK_WIDGET (xv->widgetwindow),  clip_right + clip_left, clip_bottom + clip_top);
+    gtk_fixed_move(GTK_FIXED(xv->widgetwindow), xv->widget, -clip_left, -clip_top);
+    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);
+
+
+    xv->clip_right = clip_right; xv->clip_bottom = clip_bottom; xv->clip_top = clip_top;xv->clip_left = clip_left;
+  }
+  //if emacs wants to repaint the area where the widget lives, queue a redraw
+  //TODO it seems its possible to get out of sync with emacs redraws so emacs bg sometimes shows up instead of xwidget
+  //its just a visual glitch though
+  if (!xwidget_hidden(xv)){
+    gtk_widget_queue_draw (GTK_WIDGET(xv->widgetwindow));
+    gtk_widget_queue_draw (xv->widget);
+  }
+}
+
+
+#ifdef HAVE_WEBKIT_OSR
+
+//FUGLY macro that checks WEBKIT_IS_WEB_VIEW(xw->widget_osr) first 
+#define WEBKIT_FN_INIT()                        \
+  struct xwidget* xw; \
+if(!XXWIDGETP(xwidget)) {printf("ERROR not an xwidget\n"); return Qnil;}; \
+if(Qnil == xwidget) {printf("ERROR xwidget nil\n");   return Qnil;};    \
+  xw = XXWIDGET(xwidget);                                                    \
+  if(NULL == xw) printf("ERROR xw is 0\n");                               \
+  if((NULL == xw->widget_osr) || !WEBKIT_IS_WEB_VIEW(xw->widget_osr)){  \
+    printf("ERROR xw->widget_osr does not hold a webkit instance\n");\
+    return Qnil;\
+  };
+
+
+DEFUN ("xwidget-webkit-goto-uri", Fxwidget_webkit_goto_uri,  Sxwidget_webkit_goto_uri, 2, 2, 0,
+       doc:    /* webkit goto uri.*/
+       )
+  (Lisp_Object xwidget, Lisp_Object uri)
+{
+  WEBKIT_FN_INIT();
+  webkit_web_view_load_uri ( WEBKIT_WEB_VIEW(xw->widget_osr), SDATA(uri));
+  return Qnil;
+}
+
+
+DEFUN ("xwidget-webkit-execute-script", Fxwidget_webkit_execute_script,  Sxwidget_webkit_execute_script, 2, 2, 0,
+       doc:    /* webkit exec js.*/
+       )
+  (Lisp_Object xwidget, Lisp_Object script)
+{
+  WEBKIT_FN_INIT();
+  webkit_web_view_execute_script( WEBKIT_WEB_VIEW(xw->widget_osr), SDATA(script));
+  return Qnil;
+}
+
+DEFUN ("xwidget-webkit-get-title", Fxwidget_webkit_get_title,  Sxwidget_webkit_get_title, 1, 1, 0,
+       doc:    /* webkit get title. can be used to work around exec method lacks return val*/
+       )
+  (Lisp_Object xwidget)
+{
+  //TODO support multibyte strings
+  WEBKIT_FN_INIT();
+  const gchar* str=webkit_web_view_get_title( WEBKIT_WEB_VIEW(xw->widget_osr));
+  //return make_string_from_bytes(str, wcslen((const wchar_t *)str), strlen(str));
+  if(str == 0){
+    //TODO maybe return Qnil instead. I suppose webkit returns nullpointer when doc is not properly loaded or something
+    printf("xwidget-webkit-get-title null webkit title\n");
+    return build_string("");
+  }
+  return build_string(str);
+}
+
+//TODO missnamed
+DEFUN("xwidget-disable-plugin-for-mime", Fxwidget_disable_plugin_for_mime , Sxwidget_disable_plugin_for_mime, 1,1,0, doc: /* */)
+  (Lisp_Object mime)
+{
+  WebKitWebPlugin *wp = webkit_web_plugin_database_get_plugin_for_mimetype
+    (webkit_get_web_plugin_database(),  SDATA(mime));
+  if(wp == NULL) return Qnil;
+  if(webkit_web_plugin_get_enabled (wp)){
+    webkit_web_plugin_set_enabled  (wp, FALSE);
+    return Qt;
+  }
+  return Qnil;
+}
+
+
+//attempting a workaround for a webkit offscreen bug
+//TODO verify its still needed
+void                gtk_window_get_position             (GtkWindow *window,
+                                                         gint *root_x,
+                                                         gint *root_y){
+  printf("my getsize\n");
+  *root_x = 0;
+  *root_y = 0;
+}
+
+void
+xwidget_webkit_dom_dump(WebKitDOMNode* parent){
+  WebKitDOMNodeList* list;
+  int i;
+  int length;
+  WebKitDOMNode* attribute;
+  WebKitDOMNamedNodeMap* attrs;
+  WebKitDOMNode* child;
+  printf("node:%d type:%d name:%s content:%s\n",
+         parent,
+         webkit_dom_node_get_node_type(parent),//1 element 3 text 8 comment 2 attribute
+         webkit_dom_node_get_local_name(parent),
+         webkit_dom_node_get_text_content(parent));
+
+  if(webkit_dom_node_has_attributes(parent)){
+    attrs = webkit_dom_node_get_attributes(parent);
+
+    length = webkit_dom_named_node_map_get_length(attrs);
+    for (int i = 0; i < length; i++) {
+      attribute = webkit_dom_named_node_map_item(attrs,i);
+      printf(" attr node:%d type:%d name:%s content:%s\n",
+             attribute,
+             webkit_dom_node_get_node_type(attribute),//1 element 3 text 8 comment
+             webkit_dom_node_get_local_name(attribute),
+             webkit_dom_node_get_text_content(attribute));
+    }
+  }
+  list = webkit_dom_node_get_child_nodes(parent);
+  length = webkit_dom_node_list_get_length(list);
+  
+  for (int i = 0; i < length; i++) {
+    child = webkit_dom_node_list_item(list, i);
+    //if(webkit_dom_node_has_child_nodes(child))
+    xwidget_webkit_dom_dump(child);
+  }
+}
+
+
+DEFUN ("xwidget-webkit-dom-dump", Fxwidget_webkit_dom_dump,  Sxwidget_webkit_dom_dump, 1, 1, 0,
+       doc:    /* webkit dom dump*/
+       )
+  (Lisp_Object xwidget)
+{
+  WEBKIT_FN_INIT();
+  xwidget_webkit_dom_dump(WEBKIT_DOM_NODE(webkit_web_view_get_dom_document( WEBKIT_WEB_VIEW(xw->widget_osr))));
+  return Qnil;
+}
+
+
+
+#endif
+
+
+
+
+
+DEFUN ("xwidget-resize", Fxwidget_resize, Sxwidget_resize, 3, 3, 0, doc:
+       /* resize xwidgets*/)
+  (Lisp_Object xwidget, Lisp_Object new_width, Lisp_Object new_height)
+{
+  struct xwidget* xw = XXWIDGET(xwidget);
+  struct xwidget_view *xv;
+  int  w, h;
+
+  CHECK_NUMBER (new_width);
+  CHECK_NUMBER (new_height);
+  w = XFASTINT (new_width);
+  h = XFASTINT (new_height);
+
+
+  printf("resize xwidget %d (%d,%d)->(%d,%d)\n",xw, xw->width,xw->height,w,h);
+  xw->width=w;
+  xw->height=h;
+  //if theres a osr resize it 1st
+  if(xw->widget_osr){
+    printf("resize xwidget_osr\n");
+    //gtk_container_set_resize_mode ( GTK_WINDOW(xw->widgetwindow_osr), GTK_RESIZE_QUEUE);
+    //gtk_container_set_resize_mode ( GTK_WINDOW(xw->widget_osr), GTK_RESIZE_QUEUE);
+
+
+    //gtk_layout_set_size (GTK_LAYOUT (xw->widgetwindow_osr), xw->width, xw->height);
+    gtk_widget_set_size_request (GTK_WIDGET (xw->widget_osr), xw->width, xw->height); //minimum size
+    //gtk_window_resize(    GTK_WINDOW(xw->widget_osr), xw->width, xw->height);
+    gtk_window_resize(    GTK_WINDOW(xw->widgetwindow_osr), xw->width, xw->height);
+    gtk_container_resize_children ( GTK_WINDOW(xw->widgetwindow_osr));
+    
+  }
+
+  for (int i = 0; i < MAX_XWIDGETS; i++) //TODO MVC refactor lazy linear search
+    {
+      xv = &xwidget_views[i];
+      if(xv->initialized && xv->model == xw){
+        gtk_layout_set_size (GTK_LAYOUT (xv->widgetwindow), xw->width, xw->height);
+        gtk_widget_set_size_request (GTK_WIDGET (xv->widget), xw->width, xw->height);
+      }
+    }
+
+  return Qnil;
+}
+
+DEFUN ("xwidget-size-request", Fxwidget_size_request, Sxwidget_size_request, 1, 1, 0, doc:
+       /* desired size (TODO crashes if arg not osr widget)*/)
+  (Lisp_Object xwidget)
+{
+  GtkRequisition requisition;
+  Lisp_Object rv;
+  gtk_widget_size_request(XXWIDGET(xwidget)->widget_osr, &requisition);
+  rv = Qnil;
+  rv = Fcons (make_number(requisition.height), rv);
+  rv = Fcons (make_number(requisition.width), rv);
+  return rv;
+
+}
+
+DEFUN ("xwidgetp", Fxwidgetp, Sxwidgetp, 1, 1, 0,
+       doc: /* Return t if OBJECT is a xwidget.  */)
+  (Lisp_Object object)
+{
+  return XWIDGETP (object) ? Qt : Qnil;
+}
+
+DEFUN("xwidget-info", Fxwidget_info , Sxwidget_info, 1,1,0, doc: /* get xwidget props */)
+  (Lisp_Object xwidget)
+{
+  Lisp_Object info;
+  struct xwidget* xw = XXWIDGET(xwidget);
+
+  info = Fmake_vector (make_number (4), Qnil);
+  XSETSYMBOL (XVECTOR (info)->contents[0], xw->type);
+  XSETSTRING (XVECTOR (info)->contents[1], xw->title);
+  XSETINT    (XVECTOR (info)->contents[2], xw->width);
+  XSETINT    (XVECTOR (info)->contents[3], xw->height);
+
+
+  return info;
+}
+
+
+DEFUN("xwidget-view-info", Fxwidget_view_info , Sxwidget_view_info, 2,2,0, doc: /* get xwidget view props */)
+  (Lisp_Object xwidget, Lisp_Object window)
+{
+  struct xwidget* xw = XXWIDGET(xwidget);
+  struct xwidget_view* xv = xwidget_view_lookup(xw, XWINDOW(window));
+
+  Lisp_Object info;
+
+  info = Fmake_vector (make_number (6), Qnil);
+  XVECTOR (info)->contents[0] = make_number(xv->x);
+  XVECTOR (info)->contents[1] = make_number(xv->y);
+  XVECTOR (info)->contents[2] = make_number(xv->clip_right);
+  XVECTOR (info)->contents[3] = make_number(xv->clip_bottom);
+  XVECTOR (info)->contents[4] = make_number(xv->clip_top);
+  XVECTOR (info)->contents[5] = make_number(xv->clip_left);
+
+  return info;
+}
+
+DEFUN ("xwidget-send-keyboard-event", Fxwidget_send_keyboard_event, Sxwidget_send_keyboard_event, 2, 2, 0, doc:/* synthesize a kbd event for a xwidget. */
+       )
+  (Lisp_Object  xwidget, Lisp_Object keydescriptor)
+{
+  //TODO this code crashes for offscreen widgets and ive tried many different strategies
+  //int keyval = 0x058; //X
+  int keyval = XFASTINT(keydescriptor); //X
+  char *keystring = "";
+  GdkKeymapKey* keys;
+  gint n_keys;
+  GdkDeviceManager* manager;
+  struct xwidget *xw;
+  GtkWidget* widget;
+  GdkEventKey* ev;
+  Lisp_Object window;
+  //popup_activated_flag = 1; //TODO just a hack
+  gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), keyval, &keys, &n_keys);
+  
+  xw = XXWIDGET(xwidget);
+
+  ev = (GdkEventKey*)gdk_event_new(GDK_KEY_PRESS);
+
+
+  //todo what about windowless widgets?
+
+  window = FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
+
+
+  //TODO maybe we also need to special case sockets by picking up the plug rather than the socket
+  if(xw->widget_osr)
+    widget = xw->widget_osr;
+  else
+    widget = xwidget_view_lookup(xw, XWINDOW(window))->widget;
+  
+  ev->window = gtk_widget_get_window(widget);
+  gtk_widget_grab_focus(widget); 
+  ev->send_event = FALSE;
+
+  ev->hardware_keycode = keys[0].keycode;
+  ev->group = keys[0].group;
+  
+  ev->keyval = keyval;
+  ev->time = GDK_CURRENT_TIME;
+
+  //ev->device = gdk_device_get_core_pointer();
+  manager = gdk_display_get_device_manager(gdk_window_get_display(ev->window));
+  gdk_event_set_device ((GdkEvent*)ev,   gdk_device_manager_get_client_pointer(manager));
+  gdk_event_put((GdkEvent*)ev);
+  //g_signal_emit_by_name(ev->window,"key-press-event", ev);
+  
+  ev->type = GDK_KEY_RELEASE;
+  gdk_event_put((GdkEvent*)ev);
+  //g_signal_emit_by_name(ev->window,"key-release-event", ev);
+  //gtk_main_do_event(ev);
+
+  //TODO
+  //if I delete the event the receiving component eventually crashes.
+  //it ough TDTRT since event_put is supposed to copy the event
+  //so probably this leaks events now
+  //gdk_event_free((GdkEvent*)ev);
+
+  return Qnil;
+}
+
+
+
+DEFUN("xwidget-delete-zombies", Fxwidget_delete_zombies , Sxwidget_delete_zombies, 0,0,0, doc: /* */)
+  (void)
+{
+  /*
+    - remove all views with window gone
+
+    TODO
+    - remove all xwidgets with buffer gone
+    - remove all views with xw gone
+
+   */
+  struct xwidget_view* xv = NULL;
+  Lisp_Object w;
+  for (int i = 0; i < MAX_XWIDGETS; i++){
+      xv =  &xwidget_views[i];
+      XSETWINDOW(w,  xv->w);
+      if(xv->initialized && (! (WINDOW_LIVE_P(w)))){
+
+        gtk_widget_destroy(GTK_WIDGET(xv->widgetwindow));
+        xv->initialized = 0;
+      }
+  }
+}
+
+
+DEFUN ("xwidget-plist", Fxwidget_plist, Sxwidget_plist,
+       1, 1, 0,
+       doc: /* Return the plist of XWIDGET.  */)
+  (register Lisp_Object xwidget)
+{
+  //CHECK_XWIDGET (xwidget); //todo
+  return XXWIDGET (xwidget)->plist;
+}
+
+DEFUN ("xwidget-buffer", Fxwidget_buffer, Sxwidget_buffer,
+       1, 1, 0,
+       doc: /* Return the buffer of XWIDGET.  */)
+  (register Lisp_Object xwidget)
+{
+  //CHECK_XWIDGET (xwidget); //todo
+  return XXWIDGET (xwidget)->buffer;
+}
+
+DEFUN ("set-xwidget-plist", Fset_xwidget_plist, Sset_xwidget_plist,
+       2, 2, 0,
+       doc: /* Replace the plist of XWIDGET with PLIST.  Returns PLIST.  */)
+  (register Lisp_Object xwidget, Lisp_Object plist)
+{
+  //CHECK_XWIDGET (xwidget); //todo
+  CHECK_LIST (plist);
+
+  XXWIDGET (xwidget)->plist = plist;
+  return plist;
+}
+
+
+
+void
+syms_of_xwidget (void)
+{
+  int i;
+
+  defsubr (&Smake_xwidget);
+  defsubr (&Sxwidgetp);
+  defsubr (&Sxwidget_info);
+  defsubr (&Sxwidget_view_info);
+  defsubr (&Sxwidget_resize);
+
+#ifdef HAVE_WEBKIT_OSR
+  defsubr (&Sxwidget_webkit_goto_uri);
+  defsubr (&Sxwidget_webkit_execute_script);
+  defsubr (&Sxwidget_webkit_get_title);
+  DEFSYM (Qwebkit_osr ,"webkit-osr");
+#endif
+  
+  defsubr (&Sxwidget_size_request  );
+  defsubr (&Sxwidget_delete_zombies);
+  defsubr (&Sxwidget_disable_plugin_for_mime);
+
+  defsubr (&Sxwidget_send_keyboard_event);
+  defsubr (&Sxwidget_webkit_dom_dump);
+  defsubr (&Sxwidget_plist);
+  defsubr (&Sxwidget_buffer);
+  defsubr (&Sset_xwidget_plist);
+  
+  DEFSYM (Qxwidget ,"xwidget");
+
+  DEFSYM (Qcxwidget ,":xwidget");
+  DEFSYM (Qtitle ,":title");
+
+  DEFSYM (Qbutton, "button");
+  DEFSYM (Qtoggle, "toggle");
+  DEFSYM (Qslider, "slider");
+  DEFSYM (Qsocket, "socket");
+  DEFSYM (Qsocket_osr, "socket-osr");
+  DEFSYM (Qcairo, "cairo");
+
+  DEFSYM (QCplist, ":plist");
+
+   DEFVAR_LISP ("xwidget-alist", Vxwidget_alist, doc: /*xwidgets list*/);
+   Vxwidget_alist = Qnil;
+   DEFVAR_LISP ("xwidget-view-alist", Vxwidget_view_alist, doc: /*xwidget views list*/);
+   Vxwidget_alist = Qnil;
+
+  Fprovide (intern ("xwidget-internal"), Qnil);
+
+  //  for (i = 0; i < MAX_XWIDGETS; i++)
+  //xwidgets[i].initialized = 0;
+}
+
+
+/* Value is non-zero if OBJECT is a valid Lisp xwidget specification.  A
+   valid xwidget specification is a list whose car is the symbol
+   `xwidget', and whose rest is a property list.  The property list must
+   contain a value for key `:type'.  That value must be the name of a
+   supported xwidget type.  The rest of the property list depends on the
+   xwidget type.  */
+
+int
+valid_xwidget_p (Lisp_Object object)
+{
+  int valid_p = 0;
+
+  if (XWIDGETP (object))
+    {
+      /* Lisp_Object tem; */
+
+      /* for (tem = XCDR (object); CONSP (tem); tem = XCDR (tem)) */
+      /*   if (EQ (XCAR (tem), QCtype)) */
+      /*     { */
+      /*       tem = XCDR (tem); */
+      /*       if (CONSP (tem) && SYMBOLP (XCAR (tem))) */
+      /*         { */
+      /*        struct xwidget_type *type; */
+      /*        type = lookup_xwidget_type (XCAR (tem)); */
+      /*        if (type) */
+      /*          valid_p = type->valid_p (object); */
+      /*         } */
+
+      /*       break; */
+      /*     } */
+      //never mind type support for now
+      valid_p = 1;
+    }
+
+  return valid_p;
+}
+
+
+
+/* find a value associated with key in spec */
+Lisp_Object
+xwidget_spec_value ( Lisp_Object spec, Lisp_Object  key,
+                     int *found)
+{
+  Lisp_Object tail;
+
+  xassert (valid_xwidget_p (spec));
+
+  for (tail = XCDR (spec);
+       CONSP (tail) && CONSP (XCDR (tail)); tail = XCDR (XCDR (tail)))
+    {
+      if (EQ (XCAR (tail), key))
+        {
+          if (found)
+            *found = 1;
+          return XCAR (XCDR (tail));
+        }
+    }
+
+  if (found)
+    *found = 0;
+  return Qnil;
+}
+
+
+void      xwidget_view_delete_all_in_window(  struct window *w )
+{
+  struct xwidget_view* xv = NULL;
+  for (int i = 0; i < MAX_XWIDGETS; i++){
+      xv =  &xwidget_views[i];
+      if(xv->initialized && xv->w == w){
+        gtk_widget_destroy(GTK_WIDGET(xv->widgetwindow));
+        xv->initialized = 0;
+      }
+  }
+}
+
+
+
+struct xwidget_view* xwidget_view_lookup(struct xwidget* xw,     struct window *w){
+  struct xwidget_view* xv = NULL;
+  for (int i = 0; i < MAX_XWIDGETS; i++){
+    xv = &xwidget_views[i];
+    if (xv->initialized && (xv->model == xw) && (xv->w == w))
+      return xv;
+  }
+}
+
+struct xwidget*
+lookup_xwidget (Lisp_Object  spec)
+{
+  /* When a xwidget lisp spec is found initialize the C struct that is used in the C code.
+     This is done by redisplay so values change if the spec changes.
+     So, take special care of one-shot events
+
+     TODO remove xwidget init from display spec. simply store an xwidget reference only and set
+     size etc when creating the xwidget, which should happen before insertion into buffer
+  */
+  int found = 0, found1 = 0, found2 = 0;
+  Lisp_Object value;
+  struct xwidget *xw;
+
+  value = xwidget_spec_value (spec, Qcxwidget, &found1);
+  xw = XXWIDGET(value);
+
+  /* value = xwidget_spec_value (spec, QCtype, &found); */
+  /* xw->type = SYMBOLP (value) ? value : Qbutton;     //default to button */
+  /* value = xwidget_spec_value (spec, Qtitle, &found2); */
+  /* xw->title = STRINGP (value) ? (char *) SDATA (value) : "?";       //funky cast FIXME TODO */
+
+  /* value = xwidget_spec_value (spec, QCheight, NULL); */
+  /* xw->height = INTEGERP (value) ? XFASTINT (value) : 50;  */
+  /* value = xwidget_spec_value (spec, QCwidth, NULL); */
+  /* xw->width = INTEGERP (value) ? XFASTINT (value) : 50; */
+
+  /* value = xwidget_spec_value (spec, QCplist, NULL); */
+  /* xw->plist = value; */
+  /* coordinates are not known here */
+  printf ("lookup_xwidget xwidget_id:%d type:%d found:%d %d %d title:'%s' (%d,%d)\n", xw,
+          xw->type, found, found1, found2, xw->title, xw->height, xw->width);
+
+  //assert_valid_xwidget_id (id, "lookup_xwidget");
+  return xw;
+}
+
+/*set up detection of touched xwidget*/
+void
+xwidget_start_redisplay (void)
+{
+  int i;
+  for (i = 0; i < MAX_XWIDGETS; i++)
+    xwidget_views[i].redisplayed = 0;
+
+}
+
+/* the xwidget was touched during redisplay, so it isnt a candidate for hiding*/
+void
+xwidget_touch (struct xwidget_view *xv)
+{
+  xv->redisplayed = 1;
+}
+
+int
+xwidget_touched (struct xwidget_view *xv)
+{
+  return  xv->redisplayed;
+}
+
+/* redisplay has ended, now we should hide untouched xwidgets
+*/
+void
+xwidget_end_redisplay (struct window *w, struct glyph_matrix *matrix)
+{
+
+  int i;
+  struct xwidget *xw;
+  int area;
+
+
+  xwidget_start_redisplay ();
+  //iterate desired glyph matrix of window here, hide gtk widgets
+  //not in the desired matrix.
+
+  //this only takes care of xwidgets in active windows.
+  //if a window goes away from screen xwidget views wust be deleted
+  
+  //  dump_glyph_matrix(matrix, 2);
+  for (i = 0; i < matrix->nrows; ++i)
+    {
+      //    dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
+      struct glyph_row *row;
+      row = MATRIX_ROW (matrix, i);
+      if (row->enabled_p != 0)
+        {
+          for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
+            {
+              struct glyph *glyph = row->glyphs[area];
+              struct glyph *glyph_end = glyph + row->used[area];
+              for (; glyph < glyph_end; ++glyph)
+                {
+                  if (glyph->type == XWIDGET_GLYPH)
+                    {
+                      /*
+                        the only call to xwidget_end_redisplay is in dispnew
+                        xwidget_end_redisplay(w->current_matrix);
+                      */
+                      xwidget_touch (xwidget_view_lookup(glyph->u.xwidget,
+                                                         w));
+                    }
+                }
+            }
+        }
+    }
+
+  for (i = 0; i < MAX_XWIDGETS; i++)
+    {
+      struct xwidget_view* xv = &xwidget_views[i];
+
+      //"touched" is only meaningful for the current window, so disregard other views
+      if (xv->initialized && ( xv->w ==    w))
+        {
+          if (xwidget_touched(xv))
+            xwidget_show_view (xv);
+          else
+            xwidget_hide_view (xv);
+        }
+    }
+}
diff --git a/src/xwidget.h b/src/xwidget.h
new file mode 100644 (file)
index 0000000..e5cfe6d
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef XWIDGET_H_INCLUDED
+#define XWIDGET_H_INCLUDED
+
+void x_draw_xwidget_glyph_string (struct glyph_string *s);
+void syms_of_xwidget ();
+
+extern Lisp_Object Qxwidget;
+
+
+int valid_xwidget_p (Lisp_Object object) ;
+
+#include <gtk/gtk.h>
+
+
+/*
+each xwidget instance/model is described by this struct.
+
+lisp pseudovector.
+
+
+ */
+struct xwidget{
+  struct vectorlike_header header;  
+  Lisp_Object plist;//auxilliary data
+  Lisp_Object type;//the widget type
+  Lisp_Object buffer; //buffer where xwidget lives
+  Lisp_Object title;//a title that is used for button labels for instance
+  
+  //here ends the lisp part.
+  //"height" is the marker field
+  int height;
+  int width;
+
+  //for offscreen widgets, unused if not osr
+  GtkWidget* widget_osr;
+  GtkContainer* widgetwindow_osr;
+
+  //TODO these are WIP
+
+
+  
+};
+
+
+//struct for each xwidget view
+struct xwidget_view{
+  struct vectorlike_header header;
+  struct xwidget* model; //TODO should be lisp
+
+  
+  //here ends the lisp part.
+  //"redisplayed" is the marker field
+  int redisplayed; //if touched by redisplay  
+
+
+  struct window *w; //TODO should be lisp
+  
+  int hidden;//if the "live" instance isnt drawn
+
+  int initialized;  
+
+  GtkWidget* widget;
+  GtkContainer* widgetwindow;
+  GtkContainer* emacswindow;
+  int x; int y;
+  int clip_right; int clip_bottom; int clip_top; int clip_left;
+
+
+  long handler_id;
+};
+
+
+/* Test for xwidget (xwidget . spec)  (car must be the symbol xwidget)*/
+#define XWIDGETP(x) (CONSP (x) && EQ (XCAR (x), Qxwidget))
+/* Test for xwidget pseudovector*/
+#define XXWIDGETP(x) PSEUDOVECTORP (x, PVEC_XWIDGET)
+#define XXWIDGET(a) (eassert (XWIDGETP(a)),(struct xwidget *) XPNTR(a))
+
+
+struct xwidget_type
+{
+  /* A symbol uniquely identifying the xwidget type, */
+  Lisp_Object *type;
+
+  /* Check that SPEC is a valid image specification for the given
+     image type.  Value is non-zero if SPEC is valid.  */
+  int (* valid_p) (Lisp_Object spec);
+
+  /* Next in list of all supported image types.  */
+  struct xwidget_type *next;
+};
+                             
+static struct xwidget_type *lookup_xwidget_type (Lisp_Object symbol);
+
+struct xwidget* xwidget_from_id(int id);
+
+//extern int xwidget_owns_kbd;
+
+void xwidget_start_redisplay();
+void xwidget_end_redisplay (struct window *w, struct glyph_matrix *matrix);
+
+void xwidget_touch (struct xwidget_view *xw);
+
+//void assert_valid_xwidget_id(int id,char *str);
+
+struct xwidget* lookup_xwidget (Lisp_Object  spec); 
+#define XG_XWIDGET "emacs_xwidget"
+#define XG_XWIDGET_VIEW "emacs_xwidget_view"
+void      xwidget_view_delete_all_in_window(  struct window *w );
+#endif