summaryrefslogtreecommitdiff
blob: abcba8a56097b67a663ca3fd6077ef032f4d3871 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
XEmbed support, patches by Timo Savola <timo.savola@iki.fi>
http://timo.stc.cx/tmp/emacs/

diff -Nur emacs-22.1-orig/lisp/startup.el emacs-22.1/lisp/startup.el
--- emacs-22.1-orig/lisp/startup.el	2007-05-14 16:56:29.000000000 +0200
+++ emacs-22.1/lisp/startup.el	2007-07-14 03:13:43.000000000 +0200
@@ -151,7 +151,8 @@
     ("--vertical-scroll-bars" 0 x-handle-switch vertical-scroll-bars t)
     ("--line-spacing" 1 x-handle-numeric-switch line-spacing)
     ("--border-color" 1 x-handle-switch border-color)
-    ("--smid" 1 x-handle-smid))
+    ("--smid" 1 x-handle-smid)
+    ("--parent-id" 1 x-handle-parent-id))
   "Alist of X Windows options.
 Each element has the form
   (NAME NUMARGS HANDLER FRAME-PARAM VALUE)
diff -Nur emacs-22.1-orig/lisp/term/x-win.el emacs-22.1/lisp/term/x-win.el
--- emacs-22.1-orig/lisp/term/x-win.el	2007-03-06 06:50:48.000000000 +0100
+++ emacs-22.1/lisp/term/x-win.el	2007-07-14 03:13:43.000000000 +0200
@@ -181,6 +181,15 @@
   (setq initial-frame-alist (cons (cons 'name x-resource-name)
 				  initial-frame-alist)))
 
+;; Handle the --parent-id option.
+(defun x-handle-parent-id (switch)
+  (or (consp x-invocation-args)
+      (error "%s: missing argument to `%s' option" (invocation-name) switch))
+  (setq parent-id (string-to-number (car x-invocation-args))
+	x-invocation-args (cdr x-invocation-args))
+  (setq initial-frame-alist (cons (cons 'parent-id parent-id)
+				  initial-frame-alist)))
+
 (defvar x-display-name nil
   "The name of the X display on which Emacs was started.
 
diff -Nur emacs-22.1-orig/src/emacs.c emacs-22.1/src/emacs.c
--- emacs-22.1-orig/src/emacs.c	2007-04-22 05:45:41.000000000 +0200
+++ emacs-22.1/src/emacs.c	2007-07-14 03:13:43.000000000 +0200
@@ -325,6 +325,7 @@
 --title, -T TITLE               title for initial Emacs frame\n\
 --vertical-scroll-bars, -vb     enable vertical scroll bars\n\
 --xrm XRESOURCES                set additional X resources\n\
+--parent-id XID                 set parent window\n\
 --help                          display this help and exit\n\
 --version                       output version information and exit\n\
 \n"
@@ -1835,6 +1836,7 @@
   { "-title", 0, 10, 1 },
   { "-name", "--name", 10, 1 },
   { "-xrm", "--xrm", 10, 1 },
+  { "-parent-id", "--parent-id", 10, 1 },
   { "-r", "--reverse-video", 5, 0 },
   { "-rv", 0, 5, 0 },
   { "-reverse", 0, 5, 0 },
diff -Nur emacs-22.1-orig/src/gtkutil.c emacs-22.1/src/gtkutil.c
--- emacs-22.1-orig/src/gtkutil.c	2007-05-14 16:56:31.000000000 +0200
+++ emacs-22.1/src/gtkutil.c	2007-07-14 03:13:57.000000000 +0200
@@ -769,7 +769,11 @@
 
   BLOCK_INPUT;
 
-  wtop = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  if (FRAME_X_EMBEDDED_P (f))
+    wtop = gtk_plug_new (f->output_data.x->parent_desc);
+  else
+    wtop = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
   xg_set_screen (wtop, f);
 
   wvbox = gtk_vbox_new (FALSE, 0);
diff -Nur emacs-22.1-orig/src/xfns.c emacs-22.1/src/xfns.c
--- emacs-22.1-orig/src/xfns.c	2007-07-14 03:11:59.000000000 +0200
+++ emacs-22.1/src/xfns.c	2007-07-14 03:14:20.000000000 +0200
@@ -2609,6 +2609,10 @@
   XtManageChild (pane_widget);
   XtRealizeWidget (shell_widget);
 
+  if (FRAME_X_EMBEDDED_P (f))
+    XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
+		     f->output_data.x->parent_desc, 0, 0);
+
   FRAME_X_WINDOW (f) = XtWindow (frame_widget);
 
   validate_x_resource_name ();
@@ -3267,8 +3271,10 @@
   xlwmenu_default_font = FRAME_FONT (f);
 #endif
 
-  x_default_parameter (f, parms, Qborder_width, make_number (2),
-		       "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
+  /* Frame contents get displaced if an embedded X window has a border.  */
+  if (! FRAME_X_EMBEDDED_P (f))
+    x_default_parameter (f, parms, Qborder_width, make_number (2),
+			 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
 
   /* This defaults to 1 in order to match xterm.  We recognize either
      internalBorderWidth or internalBorder (which is what xterm calls
@@ -3339,8 +3345,6 @@
   x_default_parameter (f, parms, Qfullscreen, Qnil,
                        "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
 
-  f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
-
   /* Compute the size of the X window.  */
   window_prompting = x_figure_window_size (f, parms, 1);
 
diff -Nur emacs-22.1-orig/src/xterm.c emacs-22.1/src/xterm.c
--- emacs-22.1-orig/src/xterm.c	2007-05-25 14:43:35.000000000 +0200
+++ emacs-22.1/src/xterm.c	2007-07-14 03:14:11.000000000 +0200
@@ -3306,6 +3306,15 @@
 			FOCUS_IMPLICIT : FOCUS_EXPLICIT),
 		       dpyinfo, frame, bufp);
       break;
+
+    case ClientMessage:
+      if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
+	{
+	  enum xembed_message msg = event->xclient.data.l[1];
+	  x_focus_changed ((msg == XEMBED_FOCUS_IN ? FocusIn : FocusOut),
+			   FOCUS_EXPLICIT, dpyinfo, frame, bufp);
+	}
+      break;
     }
 }
 
@@ -5876,6 +5885,18 @@
           }
 #endif /* USE_TOOLKIT_SCROLL_BARS */
 
+	/* XEmbed messages from the embedder (if any).  */
+        if (event.xclient.message_type
+	    == dpyinfo->Xatom_XEMBED)
+          {
+	    enum xembed_message msg = event.xclient.data.l[1];
+	    if (msg == XEMBED_FOCUS_IN || msg == XEMBED_FOCUS_OUT)
+	      x_detect_focus_change (dpyinfo, &event, &inev.ie);
+
+	    *finish = X_EVENT_GOTO_OUT;
+            goto done;
+          }
+
 	f = x_any_window_to_frame (dpyinfo, event.xclient.window);
 	if (!f)
 	  goto OTHER;
@@ -6796,6 +6817,10 @@
 		      else
 			construct_mouse_click (&inev.ie, &event.xbutton, f);
 		    }
+
+		  if (FRAME_X_EMBEDDED_P (f))
+		    xembed_send_message (f, event.xbutton.time,
+					 XEMBED_REQUEST_FOCUS, 0, 0, 0);
                 }
           }
         else
@@ -8889,6 +8914,51 @@
     x_lower_frame (f);
 }
 
+/* XEmbed implementation.  */
+
+void
+xembed_set_info (f, flags)
+     struct frame *f;
+     enum xembed_info flags;
+{
+  Atom atom;
+  unsigned long data[2];
+
+  atom = XInternAtom (FRAME_X_DISPLAY (f), "_XEMBED_INFO", False);
+
+  data[0] = XEMBED_VERSION;
+  data[1] = flags;
+
+  XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), atom, atom,
+		   32, PropModeReplace, (unsigned char *) data, 2);
+}
+
+void
+xembed_send_message (f, time, message, detail, data1, data2)
+     struct frame *f;
+     Time time;
+     enum xembed_message message;
+     long detail;
+     long data1;
+     long data2;
+{
+  XEvent event;
+
+  event.xclient.type = ClientMessage;
+  event.xclient.window = FRAME_X_OUTPUT (f)->parent_desc;
+  event.xclient.message_type = FRAME_X_DISPLAY_INFO (f)->Xatom_XEMBED;
+  event.xclient.format = 32;
+  event.xclient.data.l[0] = time;
+  event.xclient.data.l[1] = message;
+  event.xclient.data.l[2] = detail;
+  event.xclient.data.l[3] = data1;
+  event.xclient.data.l[4] = data2;
+
+  XSendEvent (FRAME_X_DISPLAY (f), FRAME_X_OUTPUT (f)->parent_desc,
+	      False, NoEventMask, &event);
+  XSync (FRAME_X_DISPLAY (f), False);
+}
+
 /* Change of visibility.  */
 
 /* This tries to wait until the frame is really visible.
@@ -8921,6 +8991,7 @@
 	 if we get to x_make_frame_visible a second time
 	 before the window gets really visible.  */
       if (! FRAME_ICONIFIED_P (f)
+	  && ! FRAME_X_EMBEDDED_P (f)
 	  && ! f->output_data.x->asked_for_visible)
 	x_set_offset (f, f->left_pos, f->top_pos, 0);
 
@@ -8929,14 +9000,22 @@
       if (! EQ (Vx_no_window_manager, Qt))
 	x_wm_set_window_state (f, NormalState);
 #ifdef USE_X_TOOLKIT
-      /* This was XtPopup, but that did nothing for an iconified frame.  */
-      XtMapWidget (f->output_data.x->widget);
+      if (FRAME_X_EMBEDDED_P (f))
+	xembed_set_info (f, XEMBED_MAPPED);
+      else
+	{
+	  /* This was XtPopup, but that did nothing for an iconified frame.  */
+	  XtMapWidget (f->output_data.x->widget);
+	}
 #else /* not USE_X_TOOLKIT */
 #ifdef USE_GTK
       gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
       gtk_window_deiconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
 #else
-      XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+      if (FRAME_X_EMBEDDED_P (f))
+	xembed_set_info (f, XEMBED_MAPPED);
+      else
+	XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 #endif /* not USE_GTK */
 #endif /* not USE_X_TOOLKIT */
 #if 0 /* This seems to bring back scroll bars in the wrong places
@@ -8977,7 +9056,9 @@
        because the window manager may choose the position
        and we don't want to override it.  */
 
-    if (! FRAME_VISIBLE_P (f) && ! FRAME_ICONIFIED_P (f)
+    if (! FRAME_VISIBLE_P (f)
+	&& ! FRAME_ICONIFIED_P (f)
+	&& ! FRAME_X_EMBEDDED_P (f)
 	&& f->win_gravity == NorthWestGravity
 	&& previously_visible)
       {
@@ -9088,6 +9169,10 @@
   if (FRAME_GTK_OUTER_WIDGET (f))
     gtk_widget_hide (FRAME_GTK_OUTER_WIDGET (f));
   else
+#else
+  if (FRAME_X_EMBEDDED_P (f))
+    xembed_set_info (f, 0);
+  else
 #endif
   {
 #ifdef HAVE_X11R4
@@ -9218,7 +9303,9 @@
 
   /* Make sure the X server knows where the window should be positioned,
      in case the user deiconifies with the window manager.  */
-  if (! FRAME_VISIBLE_P (f) && !FRAME_ICONIFIED_P (f))
+  if (! FRAME_VISIBLE_P (f)
+      && ! FRAME_ICONIFIED_P (f)
+      && ! FRAME_X_EMBEDDED_P (f))
     x_set_offset (f, f->left_pos, f->top_pos, 0);
 
   /* Since we don't know which revision of X we're running, we'll use both
@@ -10851,6 +10938,9 @@
   dpyinfo->Xatom_Scrollbar = XInternAtom (dpyinfo->display, "SCROLLBAR",
 					  False);
 
+  dpyinfo->Xatom_XEMBED = XInternAtom (dpyinfo->display, "_XEMBED",
+				       False);
+
   dpyinfo->cut_buffers_initialized = 0;
 
   dpyinfo->x_dnd_atoms_size = 8;
diff -Nur emacs-22.1-orig/src/xterm.h emacs-22.1/src/xterm.h
--- emacs-22.1-orig/src/xterm.h	2007-01-21 05:18:14.000000000 +0100
+++ emacs-22.1/src/xterm.h	2007-07-14 03:13:57.000000000 +0200
@@ -327,6 +327,9 @@
   /* Atom used in toolkit scroll bar client messages.  */
   Atom Xatom_Scrollbar;
 
+  /* Atom used in XEmbed client messages.  */
+  Atom Xatom_XEMBED;
+
 #ifdef MULTI_KBOARD
   struct kboard *kboard;
 #endif
@@ -1101,6 +1104,66 @@
 extern int x_session_have_connection P_ ((void));
 #endif
 
+/* XEmbed implementation.  */
+
+#define XEMBED_VERSION 0
+
+enum xembed_info
+  {
+    XEMBED_MAPPED = 1 << 0
+  };
+
+enum xembed_message
+  {
+    XEMBED_EMBEDDED_NOTIFY        = 0,
+    XEMBED_WINDOW_ACTIVATE        = 1,
+    XEMBED_WINDOW_DEACTIVATE      = 2,
+    XEMBED_REQUEST_FOCUS          = 3,
+    XEMBED_FOCUS_IN               = 4,
+    XEMBED_FOCUS_OUT              = 5,
+    XEMBED_FOCUS_NEXT             = 6,
+    XEMBED_FOCUS_PREV             = 7,
+
+    XEMBED_MODALITY_ON            = 10,
+    XEMBED_MODALITY_OFF           = 11,
+    XEMBED_REGISTER_ACCELERATOR   = 12,
+    XEMBED_UNREGISTER_ACCELERATOR = 13,
+    XEMBED_ACTIVATE_ACCELERATOR   = 14
+  };
+
+enum xembed_focus
+  {
+    XEMBED_FOCUS_CURRENT = 0,
+    XEMBED_FOCUS_FIRST   = 1,
+    XEMBED_FOCUS_LAST    = 2
+  };
+
+enum xembed_modifier
+  {
+    XEMBED_MODIFIER_SHIFT   = 1 << 0,
+    XEMBED_MODIFIER_CONTROL = 1 << 1,
+    XEMBED_MODIFIER_ALT     = 1 << 2,
+    XEMBED_MODIFIER_SUPER   = 1 << 3,
+    XEMBED_MODIFIER_HYPER   = 1 << 4
+  };
+
+enum xembed_accelerator
+  {
+    XEMBED_ACCELERATOR_OVERLOADED = 1 << 0
+  };
+
+/* Defined in xterm.c */
+
+extern void xembed_set_info P_ ((struct frame *f, enum xembed_info flags));
+extern void xembed_send_message P_ ((struct frame *f, Time time,
+				     enum xembed_message message,
+				     long detail, long data1, long data2));
+
+/* Is the frame embedded into another application? */
+
+#define FRAME_X_EMBEDDED_P(f) (FRAME_X_OUTPUT(f)->explicit_parent != 0)
+
+
 #define FONT_TYPE_FOR_UNIBYTE(font, ch) 0
 #define FONT_TYPE_FOR_MULTIBYTE(font, ch) 0