2168
+ − 1 /* Functions for the GTK toolkit.
462
+ − 2 Copyright (C) 1989, 1992-5, 1997 Free Software Foundation, Inc.
1346
+ − 3 Copyright (C) 1995, 1996, 2002, 2003 Ben Wing.
462
+ − 4
+ − 5 This file is part of XEmacs.
+ − 6
+ − 7 XEmacs is free software; you can redistribute it and/or modify it
+ − 8 under the terms of the GNU General Public License as published by the
+ − 9 Free Software Foundation; either version 2, or (at your option) any
+ − 10 later version.
+ − 11
+ − 12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ − 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ − 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ − 15 for more details.
+ − 16
+ − 17 You should have received a copy of the GNU General Public License
+ − 18 along with XEmacs; see the file COPYING. If not, write to
+ − 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ − 20 Boston, MA 02111-1307, USA. */
+ − 21
+ − 22 /* Synched up with: Not synched with FSF. */
+ − 23
+ − 24 /* Substantially rewritten for XEmacs. */
+ − 25 /* Revamped to use Gdk/Gtk by William Perry */
+ − 26
+ − 27 #include <config.h>
+ − 28 #include "lisp.h"
+ − 29
872
+ − 30 #include "buffer.h"
+ − 31 #include "device-impl.h"
+ − 32 #include "events.h"
+ − 33 #include "extents.h"
+ − 34 #include "faces.h"
+ − 35 #include "frame-impl.h"
+ − 36 #include "window.h"
+ − 37
+ − 38 #ifdef HAVE_DRAGNDROP
+ − 39 #include "dragdrop.h"
+ − 40 #endif
+ − 41
2168
+ − 42 #include "elhash.h"
872
+ − 43 #include "console-gtk-impl.h"
462
+ − 44 #include "glyphs-gtk.h"
872
+ − 45 #include "objects-gtk-impl.h"
462
+ − 46 #include "scrollbar-gtk.h"
872
+ − 47 #include "ui-gtk.h"
462
+ − 48
+ − 49 #include "gtk-xemacs.h"
+ − 50
+ − 51 #ifdef HAVE_GNOME
+ − 52 #include <libgnomeui/libgnomeui.h>
+ − 53 #endif
+ − 54
+ − 55 #define BORDER_WIDTH 0
+ − 56 #define INTERNAL_BORDER_WIDTH 0
+ − 57
+ − 58 #define TRANSIENT_DATA_IDENTIFIER "xemacs::transient_for"
+ − 59 #define UNMAPPED_DATA_IDENTIFIER "xemacs::initially_unmapped"
+ − 60
+ − 61 #define STUPID_X_SPECIFIC_GTK_STUFF
+ − 62
+ − 63 #ifdef STUPID_X_SPECIFIC_GTK_STUFF
+ − 64 #include <gdk/gdkx.h>
+ − 65 #endif
+ − 66
+ − 67 /* Default properties to use when creating frames. */
+ − 68 Lisp_Object Vdefault_gtk_frame_plist;
+ − 69
+ − 70 Lisp_Object Qdetachable_menubar;
+ − 71 Lisp_Object Qtext_widget;
+ − 72 Lisp_Object Qcontainer_widget;
+ − 73 Lisp_Object Qshell_widget;
+ − 74
+ − 75 #ifdef STUPID_X_SPECIFIC_GTK_STUFF
+ − 76 EXFUN (Fgtk_window_id, 1);
+ − 77 #endif
+ − 78
+ − 79 #ifdef HAVE_DRAGNDROP
+ − 80 enum {
+ − 81 TARGET_TYPE_STRING,
+ − 82 TARGET_TYPE_URI_LIST,
+ − 83 };
+ − 84
+ − 85 static GtkTargetEntry dnd_target_table[] = {
+ − 86 { "STRING", 0, TARGET_TYPE_STRING },
+ − 87 { "text/plain", 0, TARGET_TYPE_STRING },
+ − 88 { "text/uri-list", 0, TARGET_TYPE_URI_LIST },
+ − 89 { "_NETSCAPE_URL", 0, TARGET_TYPE_STRING }
+ − 90 };
+ − 91
+ − 92 static guint dnd_n_targets = sizeof(dnd_target_table) / sizeof(dnd_target_table[0]);
+ − 93
+ − 94 #endif
+ − 95
1204
+ − 96 static const struct memory_description gtk_frame_data_description_1 [] = {
+ − 97 { XD_LISP_OBJECT, offsetof (struct gtk_frame, icon_pixmap) },
+ − 98 { XD_LISP_OBJECT, offsetof (struct gtk_frame, icon_pixmap_mask) },
+ − 99 { XD_LISP_OBJECT_ARRAY, offsetof (struct gtk_frame, lisp_visible_widgets),
+ − 100 3 },
1346
+ − 101 { XD_LISP_OBJECT, offsetof (struct gtk_frame, menubar_data) },
1204
+ − 102 { XD_END }
+ − 103 };
+ − 104
3092
+ − 105 #ifdef NEW_GC
+ − 106 DEFINE_LRECORD_IMPLEMENTATION ("gtk-frame", gtk_frame,
+ − 107 1, /*dumpable-flag*/
+ − 108 0, 0, 0, 0, 0,
+ − 109 gtk_frame_data_description_1,
+ − 110 Lisp_Gtk_Frame);
+ − 111 #else /* not NEW_GC */
1204
+ − 112 extern const struct sized_memory_description gtk_frame_data_description;
+ − 113
+ − 114 const struct sized_memory_description gtk_frame_data_description = {
+ − 115 sizeof (struct gtk_frame), gtk_frame_data_description_1
+ − 116 };
3092
+ − 117 #endif /* not NEW_GC */
1204
+ − 118
462
+ − 119
+ − 120 /************************************************************************/
+ − 121 /* helper functions */
+ − 122 /************************************************************************/
+ − 123
2168
+ − 124 /* Return the Emacs frame-object which contains the given widget. */
+ − 125 struct frame *
+ − 126 gtk_widget_to_frame (GtkWidget *w)
+ − 127 {
+ − 128 struct frame *f = NULL;
+ − 129
+ − 130 for (; w; w = w->parent)
+ − 131 {
+ − 132 if ((f = (struct frame *) gtk_object_get_data (GTK_OBJECT (w),
+ − 133 GTK_DATA_FRAME_IDENTIFIER)))
+ − 134 return (f);
+ − 135 }
+ − 136
+ − 137 return (selected_frame());
+ − 138 }
+ − 139
+ − 140
462
+ − 141 /* Return the Emacs frame-object corresponding to an X window */
+ − 142 struct frame *
+ − 143 gtk_window_to_frame (struct device *d, GdkWindow *wdesc)
+ − 144 {
+ − 145 Lisp_Object tail, frame;
+ − 146 struct frame *f;
+ − 147
+ − 148 /* This function was previously written to accept only a window argument
+ − 149 (and to loop over all devices looking for a matching window), but
+ − 150 that is incorrect because window ID's are not unique across displays. */
+ − 151
+ − 152 for (tail = DEVICE_FRAME_LIST (d); CONSP (tail); tail = XCDR (tail))
+ − 153 {
+ − 154 frame = XCAR (tail);
+ − 155 if (!FRAMEP (frame))
+ − 156 continue;
+ − 157 f = XFRAME (frame);
+ − 158 if (FRAME_GTK_P (f) && GET_GTK_WIDGET_WINDOW (FRAME_GTK_TEXT_WIDGET (f)) == wdesc)
+ − 159 return f;
+ − 160 }
+ − 161 return 0;
+ − 162 }
+ − 163
+ − 164 /* Like gtk_window_to_frame but also compares the window with the widget's
+ − 165 windows */
+ − 166 struct frame *
+ − 167 gtk_any_window_to_frame (struct device *d, GdkWindow *w)
+ − 168 {
+ − 169 do
+ − 170 {
+ − 171 Lisp_Object frmcons;
+ − 172
+ − 173 DEVICE_FRAME_LOOP (frmcons, d)
+ − 174 {
+ − 175 struct frame *fr = XFRAME (XCAR (frmcons));
+ − 176 if ((w == GET_GTK_WIDGET_WINDOW (FRAME_GTK_SHELL_WIDGET (fr))) ||
+ − 177 (w == GET_GTK_WIDGET_WINDOW (FRAME_GTK_CONTAINER_WIDGET (fr))) ||
+ − 178 #ifdef HAVE_MENUBARS
+ − 179 (w == GET_GTK_WIDGET_WINDOW (FRAME_GTK_MENUBAR_WIDGET (fr))) ||
+ − 180 #endif
+ − 181 (w == GET_GTK_WIDGET_WINDOW (FRAME_GTK_TEXT_WIDGET (fr))))
+ − 182 {
+ − 183 return (fr);
+ − 184 }
+ − 185 }
+ − 186 w = gdk_window_get_parent (w);
+ − 187 } while (w);
+ − 188
+ − 189 return (0);
+ − 190 }
+ − 191
+ − 192 struct frame *
+ − 193 gtk_any_widget_or_parent_to_frame (struct device *d, GtkWidget *widget)
+ − 194 {
+ − 195 return (gtk_any_window_to_frame (d, GET_GTK_WIDGET_WINDOW (widget)));
+ − 196 }
+ − 197
+ − 198 struct device *
+ − 199 gtk_any_window_to_device (GdkWindow *w)
+ − 200 {
+ − 201 struct device *d = NULL;
+ − 202 Lisp_Object devcons, concons;
+ − 203
+ − 204 DEVICE_LOOP_NO_BREAK (devcons, concons)
+ − 205 {
+ − 206 d = XDEVICE (XCAR (devcons));
+ − 207 if (!DEVICE_GTK_P (d)) continue;
+ − 208 if (gtk_any_window_to_frame (d, w))
+ − 209 return (d);
+ − 210 }
+ − 211 return (NULL);
+ − 212 }
+ − 213
+ − 214 struct frame *
+ − 215 decode_gtk_frame (Lisp_Object frame)
+ − 216 {
+ − 217 if (NILP (frame))
793
+ − 218 frame = wrap_frame (selected_frame ());
462
+ − 219 CHECK_LIVE_FRAME (frame);
+ − 220 /* this will also catch dead frames, but putting in the above check
+ − 221 results in a more useful error */
+ − 222 CHECK_GTK_FRAME (frame);
+ − 223 return XFRAME (frame);
+ − 224 }
+ − 225
+ − 226
+ − 227 /************************************************************************/
+ − 228 /* window-manager interactions */
+ − 229 /************************************************************************/
+ − 230 static int
+ − 231 gtk_frame_iconified_p (struct frame *f)
+ − 232 {
+ − 233 return (f->iconified);
+ − 234 }
+ − 235
+ − 236
+ − 237 /************************************************************************/
+ − 238 /* frame properties */
+ − 239 /************************************************************************/
+ − 240
+ − 241 static Lisp_Object
+ − 242 gtk_frame_property (struct frame *f, Lisp_Object property)
+ − 243 {
+ − 244 GtkWidget *shell = FRAME_GTK_SHELL_WIDGET (f);
+ − 245
+ − 246 if (EQ (Qleft, property) || EQ (Qtop, property))
+ − 247 {
+ − 248 gint x, y;
+ − 249 if (!GET_GTK_WIDGET_WINDOW(shell))
+ − 250 return Qzero;
+ − 251 gdk_window_get_deskrelative_origin (GET_GTK_WIDGET_WINDOW (shell), &x, &y);
+ − 252 if (EQ (Qleft, property)) return make_int (x);
+ − 253 if (EQ (Qtop, property)) return make_int (y);
+ − 254 }
+ − 255 if (EQ (Qshell_widget, property))
+ − 256 {
+ − 257 return (FRAME_GTK_LISP_WIDGETS (f)[0]);
+ − 258 }
+ − 259 if (EQ (Qcontainer_widget, property))
+ − 260 {
+ − 261 return (FRAME_GTK_LISP_WIDGETS (f)[1]);
+ − 262 }
+ − 263 if (EQ (Qtext_widget, property))
+ − 264 {
+ − 265 return (FRAME_GTK_LISP_WIDGETS (f)[2]);
+ − 266 }
+ − 267 #ifdef STUPID_X_SPECIFIC_GTK_STUFF
+ − 268 if (EQ (Qwindow_id, property))
771
+ − 269 return Fgtk_window_id (wrap_frame (f));
462
+ − 270 #endif
+ − 271
+ − 272 return Qunbound;
+ − 273 }
+ − 274
+ − 275 static int
3087
+ − 276 gtk_internal_frame_property_p (struct frame *UNUSED(f), Lisp_Object property)
462
+ − 277 {
+ − 278 return EQ (property, Qleft)
+ − 279 || EQ (property, Qtop)
+ − 280 || EQ (Qshell_widget, property)
+ − 281 || EQ (Qcontainer_widget, property)
+ − 282 || EQ (Qtext_widget, property)
+ − 283 || EQ (property, Qwindow_id)
+ − 284 || STRINGP (property);
+ − 285 }
+ − 286
+ − 287 static Lisp_Object
+ − 288 gtk_frame_properties (struct frame *f)
+ − 289 {
+ − 290 Lisp_Object props = Qnil;
+ − 291 GtkWidget *shell = FRAME_GTK_SHELL_WIDGET (f);
+ − 292 gint x, y;
+ − 293
+ − 294 props = cons3 (Qshell_widget, FRAME_GTK_LISP_WIDGETS (f)[0], props);
+ − 295 props = cons3 (Qcontainer_widget, FRAME_GTK_LISP_WIDGETS (f)[1], props);
+ − 296 props = cons3 (Qtext_widget, FRAME_GTK_LISP_WIDGETS (f)[2], props);
+ − 297
+ − 298 #ifdef STUPID_X_SPECIFIC_GTK_STUFF
771
+ − 299 props = cons3 (Qwindow_id, Fgtk_window_id (wrap_frame (f)), props);
462
+ − 300 #endif
+ − 301
+ − 302 if (!GET_GTK_WIDGET_WINDOW (shell))
+ − 303 x = y = 0;
+ − 304 else
+ − 305 gdk_window_get_deskrelative_origin (GET_GTK_WIDGET_WINDOW (shell), &x, &y);
+ − 306
+ − 307 props = cons3 (Qtop, make_int (y), props);
+ − 308 props = cons3 (Qleft, make_int (x), props);
+ − 309
+ − 310 return props;
+ − 311 }
+ − 312
+ − 313
+ − 314 /* Functions called only from `gtk_set_frame_properties' to set
+ − 315 individual properties. */
+ − 316
+ − 317 static void
2286
+ − 318 gtk_set_frame_text_value (struct frame *UNUSED (f), Ibyte *value,
462
+ − 319 void (*func) (gpointer, gchar *),
+ − 320 gpointer arg)
+ − 321 {
+ − 322 gchar *the_text = (gchar *) value;
+ − 323
+ − 324 /* Programmer fuckup or window is not realized yet. */
+ − 325 if (!func || !arg) return;
+ − 326
+ − 327 #ifdef MULE
+ − 328 {
867
+ − 329 Ibyte *ptr;
462
+ − 330
+ − 331 /* Optimize for common ASCII case */
+ − 332 for (ptr = value; *ptr; ptr++)
826
+ − 333 if (!byte_ascii_p (*ptr))
462
+ − 334 {
+ − 335 char *tmp;
+ − 336 C_STRING_TO_EXTERNAL (value, tmp, Qctext);
+ − 337 the_text = tmp;
+ − 338 break;
+ − 339 }
+ − 340 }
+ − 341 #endif /* MULE */
+ − 342
+ − 343 (*func) (arg, (gchar *) the_text);
+ − 344 }
+ − 345
+ − 346 static void
867
+ − 347 gtk_set_title_from_ibyte (struct frame *f, Ibyte *name)
462
+ − 348 {
+ − 349 if (GTK_IS_WINDOW (FRAME_GTK_SHELL_WIDGET (f)))
+ − 350 gtk_set_frame_text_value (f, name,
+ − 351 (void (*)(gpointer, gchar *))
+ − 352 gtk_window_set_title, FRAME_GTK_SHELL_WIDGET (f));
+ − 353 }
+ − 354
+ − 355 static void
867
+ − 356 gtk_set_icon_name_from_ibyte (struct frame *f, Ibyte *name)
462
+ − 357 {
+ − 358 gtk_set_frame_text_value (f, name,
+ − 359 (void (*)(gpointer, gchar *))
+ − 360 gdk_window_set_icon_name, FRAME_GTK_SHELL_WIDGET (f)->window);
+ − 361 }
+ − 362
+ − 363 /* Set the initial frame size as specified. This function is used
+ − 364 when the frame's widgets have not yet been realized.
+ − 365 */
+ − 366 static void
+ − 367 gtk_set_initial_frame_size (struct frame *f, int x, int y,
+ − 368 unsigned int w, unsigned int h)
+ − 369 {
+ − 370 GtkWidget *shell = FRAME_GTK_SHELL_WIDGET (f);
+ − 371 GdkGeometry geometry;
+ − 372
+ − 373 if (GTK_IS_WINDOW (shell))
+ − 374 {
2054
+ − 375 GdkWindowHints geometry_mask = GDK_HINT_RESIZE_INC;
462
+ − 376 /* Deal with the cell size */
771
+ − 377 default_face_height_and_width (wrap_frame (f), &geometry.height_inc, &geometry.width_inc);
462
+ − 378
+ − 379 gtk_window_set_geometry_hints (GTK_WINDOW (shell),
+ − 380 FRAME_GTK_TEXT_WIDGET (f), &geometry, geometry_mask);
+ − 381 gdk_window_set_hints (GET_GTK_WIDGET_WINDOW (shell), x, y, 0, 0, 0, 0, GDK_HINT_POS);
+ − 382 gtk_window_set_policy (GTK_WINDOW (shell), TRUE, TRUE, FALSE);
+ − 383 }
+ − 384
+ − 385 FRAME_HEIGHT (f) = h;
+ − 386 FRAME_WIDTH (f) = w;
+ − 387
+ − 388 change_frame_size (f, h, w, 0);
+ − 389 {
+ − 390 GtkRequisition req;
+ − 391
+ − 392 gtk_widget_size_request (FRAME_GTK_SHELL_WIDGET (f), &req);
+ − 393 gtk_widget_set_usize (FRAME_GTK_SHELL_WIDGET (f), req.width, req.height);
+ − 394 }
+ − 395 }
+ − 396
+ − 397 /* Report that a frame property of frame S is being set or changed.
+ − 398 If the property is not specially recognized, do nothing.
+ − 399 */
+ − 400
+ − 401 static void
+ − 402 gtk_set_frame_properties (struct frame *f, Lisp_Object plist)
+ − 403 {
+ − 404 gint x, y;
+ − 405 gint width = 0, height = 0;
+ − 406 gboolean width_specified_p = FALSE;
+ − 407 gboolean height_specified_p = FALSE;
+ − 408 gboolean x_position_specified_p = FALSE;
+ − 409 gboolean y_position_specified_p = FALSE;
+ − 410 Lisp_Object tail;
+ − 411
+ − 412 for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail)))
+ − 413 {
+ − 414 Lisp_Object prop = Fcar (tail);
+ − 415 Lisp_Object val = Fcar (Fcdr (tail));
+ − 416
+ − 417 if (SYMBOLP (prop))
+ − 418 {
+ − 419 if (EQ (prop, Qfont))
+ − 420 {
+ − 421 /* If the value is not a string we silently ignore it. */
+ − 422 if (STRINGP (val))
+ − 423 {
+ − 424 Lisp_Object frm, font_spec;
+ − 425
793
+ − 426 frm = wrap_frame (f);
462
+ − 427 font_spec = Fget (Fget_face (Qdefault), Qfont, Qnil);
+ − 428
+ − 429 Fadd_spec_to_specifier (font_spec, val, frm, Qnil, Qnil);
+ − 430 update_frame_face_values (f);
+ − 431 }
+ − 432 continue;
+ − 433 }
+ − 434 else if (EQ (prop, Qwidth))
+ − 435 {
+ − 436 CHECK_INT (val);
+ − 437 width = XINT (val);
+ − 438 width_specified_p = TRUE;
+ − 439 continue;
+ − 440 }
+ − 441 else if (EQ (prop, Qheight))
+ − 442 {
+ − 443 CHECK_INT (val);
+ − 444 height = XINT (val);
+ − 445 height_specified_p = TRUE;
+ − 446 continue;
+ − 447 }
+ − 448 /* Further kludge the x/y. */
+ − 449 else if (EQ (prop, Qx))
+ − 450 {
+ − 451 CHECK_INT (val);
+ − 452 x = (gint) XINT (val);
+ − 453 x_position_specified_p = TRUE;
+ − 454 continue;
+ − 455 }
+ − 456 else if (EQ (prop, Qy))
+ − 457 {
+ − 458 CHECK_INT (val);
+ − 459 y = (gint) XINT (val);
+ − 460 y_position_specified_p = TRUE;
+ − 461 continue;
+ − 462 }
+ − 463 }
+ − 464 }
+ − 465
+ − 466 /* Kludge kludge kludge. We need to deal with the size and position
+ − 467 specially. */
+ − 468 {
+ − 469 int size_specified_p = width_specified_p || height_specified_p;
+ − 470 int position_specified_p = x_position_specified_p || y_position_specified_p;
+ − 471
+ − 472 if (!width_specified_p)
+ − 473 width = 80;
+ − 474 if (!height_specified_p)
+ − 475 height = 30;
+ − 476
+ − 477 /* Kludge kludge kludge kludge. */
+ − 478 if (position_specified_p &&
+ − 479 (!x_position_specified_p || !y_position_specified_p))
+ − 480 {
+ − 481 gint dummy;
+ − 482 GtkWidget *shell = FRAME_GTK_SHELL_WIDGET (f);
+ − 483 gdk_window_get_deskrelative_origin (GET_GTK_WIDGET_WINDOW (shell),
+ − 484 (x_position_specified_p ? &dummy : &x),
+ − 485 (y_position_specified_p ? &dummy : &y));
+ − 486 }
+ − 487
+ − 488 if (!f->init_finished)
+ − 489 {
+ − 490 if (size_specified_p || position_specified_p)
+ − 491 gtk_set_initial_frame_size (f, x, y, width, height);
+ − 492 }
+ − 493 else
+ − 494 {
+ − 495 if (size_specified_p)
+ − 496 {
793
+ − 497 Lisp_Object frame = wrap_frame (f);
+ − 498
462
+ − 499 Fset_frame_size (frame, make_int (width), make_int (height), Qnil);
+ − 500 }
+ − 501 if (position_specified_p)
+ − 502 {
793
+ − 503 Lisp_Object frame = wrap_frame (f);
+ − 504
462
+ − 505 Fset_frame_position (frame, make_int (x), make_int (y));
+ − 506 }
+ − 507 }
+ − 508 }
+ − 509 }
+ − 510
+ − 511
+ − 512 /************************************************************************/
+ − 513 /* widget creation */
+ − 514 /************************************************************************/
+ − 515 /* Figure out what size the shell widget should initially be,
+ − 516 and set it. Should be called after the default font has been
+ − 517 determined but before the widget has been realized. */
+ − 518
+ − 519 extern Lisp_Object Vgtk_initial_geometry;
+ − 520
+ − 521 #ifndef HAVE_GNOME
+ − 522 static int
+ − 523 get_number (const char **geometry)
+ − 524 {
+ − 525 int value = 0;
+ − 526 int mult = 1;
+ − 527
+ − 528 if (**geometry == '-'){
+ − 529 mult = -1;
+ − 530 (*geometry)++;
+ − 531 }
+ − 532 while (**geometry && isdigit (**geometry)){
+ − 533 value = value * 10 + (**geometry - '0');
+ − 534 (*geometry)++;
+ − 535 }
+ − 536 return value * mult;
+ − 537 }
+ − 538
+ − 539 /*
+ − 540 */
+ − 541
+ − 542 /**
+ − 543 * gnome_parse_geometry
+ − 544 * @geometry: geometry string to be parsed
+ − 545 * @xpos: X position geometry component
+ − 546 * @ypos: Y position geometry component
+ − 547 * @width: pixel width geometry component
+ − 548 * @height: pixel height geometry component
+ − 549 *
+ − 550 * Description:
+ − 551 * Parses the geometry string passed in @geometry, and fills
+ − 552 * @xpos, @ypos, @width, and @height with
+ − 553 * the corresponding values upon completion of the parse.
+ − 554 * If the parse fails, it should be assumed that @xpos, @ypos, @width,
+ − 555 * and @height contain undefined values.
+ − 556 *
+ − 557 * Returns:
+ − 558 * %TRUE if the geometry was successfully parsed, %FALSE otherwise.
+ − 559 **/
+ − 560
+ − 561 static gboolean
+ − 562 gnome_parse_geometry (const gchar *geometry, gint *xpos,
+ − 563 gint *ypos, gint *width, gint *height)
+ − 564 {
+ − 565 int subtract;
+ − 566
+ − 567 g_return_val_if_fail (xpos != NULL, FALSE);
+ − 568 g_return_val_if_fail (ypos != NULL, FALSE);
+ − 569 g_return_val_if_fail (width != NULL, FALSE);
+ − 570 g_return_val_if_fail (height != NULL, FALSE);
+ − 571
+ − 572 *xpos = *ypos = *width = *height = -1;
+ − 573
+ − 574 if (!geometry)
+ − 575 return FALSE;
+ − 576
+ − 577 if (*geometry == '=')
+ − 578 geometry++;
+ − 579 if (!*geometry)
+ − 580 return FALSE;
+ − 581 if (isdigit (*geometry))
+ − 582 *width = get_number (&geometry);
+ − 583 if (!*geometry)
+ − 584 return TRUE;
+ − 585 if (*geometry == 'x' || *geometry == 'X'){
+ − 586 geometry++;
+ − 587 *height = get_number (&geometry);
+ − 588 }
+ − 589 if (!*geometry)
+ − 590 return 1;
+ − 591 if (*geometry == '+'){
+ − 592 subtract = 0;
+ − 593 geometry++;
+ − 594 } else if (*geometry == '-'){
+ − 595 subtract = gdk_screen_width ();
+ − 596 geometry++;
+ − 597 } else
+ − 598 return FALSE;
+ − 599 *xpos = get_number (&geometry);
+ − 600 if (subtract)
+ − 601 *xpos = subtract - *xpos;
+ − 602 if (!*geometry)
+ − 603 return TRUE;
+ − 604 if (*geometry == '+'){
+ − 605 subtract = 0;
+ − 606 geometry++;
+ − 607 } else if (*geometry == '-'){
+ − 608 subtract = gdk_screen_height ();
+ − 609 geometry++;
+ − 610 } else
+ − 611 return FALSE;
+ − 612 *ypos = get_number (&geometry);
+ − 613 if (subtract)
+ − 614 *ypos = subtract - *ypos;
+ − 615 return TRUE;
+ − 616 }
+ − 617 #endif
+ − 618
+ − 619 static void
+ − 620 gtk_initialize_frame_size (struct frame *f)
+ − 621 {
+ − 622 gint x = 10, y = 10, w = 80, h = 30;
+ − 623
+ − 624 if (STRINGP (Vgtk_initial_geometry))
+ − 625 {
2054
+ − 626 if (!gnome_parse_geometry ((char*) XSTRING_DATA (Vgtk_initial_geometry), &x,&y,&w,&h))
462
+ − 627 {
+ − 628 x = y = 10;
+ − 629 w = 80;
+ − 630 h = 30;
+ − 631 }
+ − 632 }
+ − 633
+ − 634 /* set the position of the frame's root window now. When the
+ − 635 frame was created, the position was initialized to (0,0). */
+ − 636 {
+ − 637 struct window *win = XWINDOW (f->root_window);
+ − 638
+ − 639 WINDOW_LEFT (win) = FRAME_LEFT_BORDER_END (f);
+ − 640 WINDOW_TOP (win) = FRAME_TOP_BORDER_END (f);
+ − 641
+ − 642 if (!NILP (f->minibuffer_window))
+ − 643 {
+ − 644 win = XWINDOW (f->minibuffer_window);
+ − 645 WINDOW_LEFT (win) = FRAME_LEFT_BORDER_END (f);
+ − 646 }
+ − 647 }
+ − 648
+ − 649 gtk_set_initial_frame_size (f, x, y, w, h);
+ − 650 }
+ − 651
+ − 652 static gboolean
2286
+ − 653 resize_event_cb (GtkWidget *UNUSED (w), GtkAllocation *allocation,
+ − 654 gpointer user_data)
462
+ − 655 {
+ − 656 struct frame *f = (struct frame *) user_data;
+ − 657
+ − 658 f->pixwidth = allocation->width;
+ − 659 f->pixheight = allocation->height;
+ − 660
+ − 661 if (FRAME_GTK_TEXT_WIDGET (f)->window)
+ − 662 {
793
+ − 663 Lisp_Object frame = wrap_frame (f);
+ − 664
462
+ − 665 Fredraw_frame (frame, Qt);
+ − 666 }
+ − 667
+ − 668 return (FALSE);
+ − 669 }
+ − 670
+ − 671 static gboolean
2286
+ − 672 delete_event_cb (GtkWidget *UNUSED (w), GdkEvent *UNUSED (ev),
+ − 673 gpointer user_data)
462
+ − 674 {
+ − 675 struct frame *f = (struct frame *) user_data;
793
+ − 676 Lisp_Object frame = wrap_frame (f);
462
+ − 677
+ − 678 enqueue_misc_user_event (frame, Qeval, list3 (Qdelete_frame, frame, Qt));
+ − 679
+ − 680 /* See if tickling the event queue helps us with our delays when
+ − 681 clicking 'close' */
+ − 682 signal_fake_event ();
+ − 683
+ − 684 return (TRUE);
+ − 685 }
+ − 686
+ − 687 extern gboolean emacs_shell_event_handler (GtkWidget *wid, GdkEvent *event, gpointer closure);
+ − 688 extern Lisp_Object build_gtk_object (GtkObject *obj);
+ − 689
+ − 690 #ifndef GNOME_IS_APP
+ − 691 #define GNOME_IS_APP(x) 0
+ − 692 #define gnome_app_set_contents(x,y) 0
+ − 693 #endif
+ − 694
+ − 695 static void
+ − 696 cleanup_deleted_frame (gpointer data)
+ − 697 {
+ − 698 struct frame *f = (struct frame *) data;
793
+ − 699 Lisp_Object frame = wrap_frame (f);
462
+ − 700
+ − 701 Fdelete_frame (frame, Qt);
+ − 702 }
+ − 703
+ − 704 #ifdef HAVE_DRAGNDROP
+ − 705 extern void
+ − 706 dragndrop_data_received (GtkWidget *widget,
+ − 707 GdkDragContext *context,
+ − 708 gint x,
+ − 709 gint y,
+ − 710 GtkSelectionData *data,
+ − 711 guint info,
+ − 712 guint time);
+ − 713
+ − 714 extern gboolean
+ − 715 dragndrop_dropped (GtkWidget *widget,
+ − 716 GdkDragContext *drag_context,
+ − 717 gint x,
+ − 718 gint y,
+ − 719 guint time,
+ − 720 gpointer user_data);
+ − 721
+ − 722 Lisp_Object Vcurrent_drag_object;
+ − 723
+ − 724 #define DRAG_SELECTION_DATA_ERROR "Error converting drag data to external format"
+ − 725 static void
2286
+ − 726 dragndrop_get_drag (GtkWidget *UNUSED (widget),
+ − 727 GdkDragContext *UNUSED (drag_context),
462
+ − 728 GtkSelectionData *data,
+ − 729 guint info,
2286
+ − 730 guint UNUSED (time),
+ − 731 gpointer UNUSED (user_data))
462
+ − 732 {
+ − 733 gtk_selection_data_set (data, GDK_SELECTION_TYPE_STRING, 8,
+ − 734 DRAG_SELECTION_DATA_ERROR,
+ − 735 strlen (DRAG_SELECTION_DATA_ERROR));
+ − 736
+ − 737 switch (info)
+ − 738 {
+ − 739 case TARGET_TYPE_STRING:
+ − 740 {
+ − 741 Lisp_Object string = Vcurrent_drag_object;
+ − 742
+ − 743 if (!STRINGP (Vcurrent_drag_object))
+ − 744 {
+ − 745 string = Fprin1_to_string (string, Qnil);
+ − 746 /* Convert to a string */
+ − 747 }
+ − 748
+ − 749 gtk_selection_data_set (data, GDK_SELECTION_TYPE_STRING,
+ − 750 8, XSTRING_DATA (string), XSTRING_LENGTH (string));
+ − 751 }
+ − 752 break;
+ − 753 case TARGET_TYPE_URI_LIST:
+ − 754 break;
+ − 755 default:
+ − 756 break;
+ − 757 }
+ − 758 Vcurrent_drag_object = Qnil;
+ − 759 }
+ − 760
+ − 761 DEFUN ("gtk-start-drag-internal", Fgtk_start_drag_internal, 2, 3, 0, /*
+ − 762 Start a GTK drag from a buffer.
+ − 763 First arg is the event that started the drag,
+ − 764 second arg should be some string, and the third
+ − 765 is the type of the data (this should be a MIME type as a string (ie: text/plain)).
+ − 766 The type defaults to text/plain.
+ − 767 */
+ − 768 (event, data, dtyp))
+ − 769 {
+ − 770 if (EVENTP(event))
+ − 771 {
+ − 772 struct frame *f = decode_gtk_frame (Fselected_frame (Qnil));
+ − 773 GtkWidget *wid = FRAME_GTK_TEXT_WIDGET (f);
+ − 774 struct Lisp_Event *lisp_event = XEVENT(event);
+ − 775 GdkAtom dnd_typ;
+ − 776 GtkTargetList *tl = gtk_target_list_new (dnd_target_table, dnd_n_targets);
+ − 777
+ − 778 /* only drag if this is really a press */
+ − 779 if (EVENT_TYPE(lisp_event) != button_press_event)
+ − 780 return Qnil;
+ − 781
+ − 782 /* get the desired type */
+ − 783 if (!NILP (dtyp) && STRINGP (dtyp))
+ − 784 dnd_typ = gdk_atom_intern (XSTRING_DATA (dtyp), FALSE);
+ − 785
1204
+ − 786 gtk_drag_begin (wid, tl, GDK_ACTION_COPY,
+ − 787 EVENT_BUTTON_BUTTON (lisp_event), NULL);
462
+ − 788
+ − 789 Vcurrent_drag_object = data;
+ − 790
+ − 791 gtk_target_list_unref (tl);
+ − 792 }
+ − 793 return Qnil;
+ − 794 }
+ − 795 #endif
+ − 796
+ − 797 /* Creates the widgets for a frame.
+ − 798 lisp_window_id is a Lisp description of an X window or Xt
+ − 799 widget to parse.
+ − 800
+ − 801 This function does not map the windows. (That is
+ − 802 done by gtk_popup_frame().)
+ − 803 */
+ − 804 static void
+ − 805 gtk_create_widgets (struct frame *f, Lisp_Object lisp_window_id, Lisp_Object parent)
+ − 806 {
+ − 807 const char *name;
+ − 808 GtkWidget *text, *container, *shell;
+ − 809 gboolean embedded_p = !NILP (lisp_window_id);
+ − 810 #ifdef HAVE_MENUBARS
+ − 811 int menubar_visible;
+ − 812 #endif
+ − 813
+ − 814 if (STRINGP (f->name))
+ − 815 TO_EXTERNAL_FORMAT (LISP_STRING, f->name, C_STRING_ALLOCA, name, Qctext);
+ − 816 else
+ − 817 name = "emacs";
+ − 818
+ − 819 FRAME_GTK_TOP_LEVEL_FRAME_P (f) = 1;
+ − 820
+ − 821 if (embedded_p)
+ − 822 {
+ − 823 CHECK_GTK_OBJECT (lisp_window_id);
+ − 824
+ − 825 if (!GTK_IS_CONTAINER (XGTK_OBJECT (lisp_window_id)->object))
+ − 826 {
563
+ − 827 invalid_argument ("Window ID must be a GtkContainer subclass", lisp_window_id);
462
+ − 828 }
+ − 829
+ − 830 shell = gtk_vbox_new (FALSE, 0);
+ − 831
+ − 832 gtk_object_weakref (GTK_OBJECT (shell), cleanup_deleted_frame, f);
+ − 833 gtk_container_add (GTK_CONTAINER (XGTK_OBJECT (lisp_window_id)->object), shell);
+ − 834 }
+ − 835 else
+ − 836 {
+ − 837 #ifdef HAVE_GNOME
+ − 838 shell = GTK_WIDGET (gnome_app_new ("XEmacs", "XEmacs/GNOME"));
+ − 839 #else
+ − 840 shell = GTK_WIDGET (gtk_window_new (GTK_WINDOW_TOPLEVEL));
+ − 841 #endif
+ − 842 }
+ − 843
+ − 844 if (!NILP (parent))
+ − 845 {
+ − 846 /* If this is a transient window, keep the parent info around */
+ − 847 GtkWidget *parentwid = FRAME_GTK_SHELL_WIDGET (XFRAME (parent));
+ − 848 gtk_object_set_data (GTK_OBJECT (shell), TRANSIENT_DATA_IDENTIFIER, parentwid);
+ − 849 gtk_window_set_transient_for (GTK_WINDOW (shell), GTK_WINDOW (parentwid));
+ − 850 }
+ − 851
+ − 852 gtk_container_set_border_width (GTK_CONTAINER (shell), 0);
+ − 853
2168
+ − 854 /* Add a mapping from widget to frame to help widget callbacks quickly find
+ − 855 their corresponding frame. */
+ − 856 gtk_object_set_data (GTK_OBJECT (shell), GTK_DATA_FRAME_IDENTIFIER, f);
462
+ − 857
+ − 858 FRAME_GTK_SHELL_WIDGET (f) = shell;
+ − 859
+ − 860 text = GTK_WIDGET (gtk_xemacs_new (f));
+ − 861
+ − 862 if (!GNOME_IS_APP (shell))
+ − 863 container = GTK_WIDGET (gtk_vbox_new (FALSE, INTERNAL_BORDER_WIDTH));
+ − 864 else
+ − 865 container = shell;
+ − 866
+ − 867 FRAME_GTK_CONTAINER_WIDGET (f) = container;
+ − 868 FRAME_GTK_TEXT_WIDGET (f) = text;
+ − 869
+ − 870 #ifdef HAVE_DRAGNDROP
+ − 871 gtk_drag_dest_set (text, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT,
+ − 872 dnd_target_table, dnd_n_targets,
+ − 873 GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_ASK);
+ − 874 gtk_signal_connect (GTK_OBJECT (text), "drag_drop",
+ − 875 GTK_SIGNAL_FUNC (dragndrop_dropped), text);
+ − 876 gtk_signal_connect (GTK_OBJECT (text), "drag_data_received",
+ − 877 GTK_SIGNAL_FUNC (dragndrop_data_received), text);
+ − 878 gtk_signal_connect (GTK_OBJECT (text), "drag_data_get",
+ − 879 GTK_SIGNAL_FUNC (dragndrop_get_drag), NULL);
+ − 880 #endif
+ − 881
+ − 882 #ifdef HAVE_MENUBARS
+ − 883 /* Create the initial menubar widget. */
+ − 884 menubar_visible = gtk_initialize_frame_menubar (f);
+ − 885
+ − 886 if (menubar_visible)
+ − 887 {
+ − 888 gtk_widget_show_all (FRAME_GTK_MENUBAR_WIDGET (f));
+ − 889 }
+ − 890 #endif /* HAVE_MENUBARS */
+ − 891
+ − 892 if (GNOME_IS_APP (shell))
+ − 893 gnome_app_set_contents (GNOME_APP (shell), text);
+ − 894 else
+ − 895 /* Now comes the drawing area, which should fill the rest of the
+ − 896 ** frame completely.
+ − 897 */
+ − 898 gtk_box_pack_end (GTK_BOX (container), text, TRUE, TRUE, 0);
+ − 899
+ − 900 /* Connect main event handler */
+ − 901 gtk_signal_connect (GTK_OBJECT (shell), "delete-event", GTK_SIGNAL_FUNC (delete_event_cb), f);
+ − 902
+ − 903 {
+ − 904 static char *events_to_frob[] = { "focus-in-event",
+ − 905 "focus-out-event",
+ − 906 "enter-notify-event",
+ − 907 "leave-notify-event",
+ − 908 "map-event",
+ − 909 "unmap-event",
+ − 910 "property-notify-event",
+ − 911 "selection-clear-event",
+ − 912 "selection-request-event",
+ − 913 "selection-notify-event",
+ − 914 "client-event",
+ − 915 /* "configure-event", */
+ − 916 "visibility-notify-event",
+ − 917 NULL };
+ − 918 int i;
+ − 919
+ − 920 for (i = 0; events_to_frob[i]; i++)
+ − 921 {
+ − 922 gtk_signal_connect (GTK_OBJECT (shell), events_to_frob[i],
+ − 923 GTK_SIGNAL_FUNC (emacs_shell_event_handler), f);
+ − 924 }
+ − 925 }
+ − 926
+ − 927 gtk_signal_connect (GTK_OBJECT (shell), "size-allocate", GTK_SIGNAL_FUNC (resize_event_cb), f);
+ − 928
+ − 929 /* This might be safe to call now... */
+ − 930 /* gtk_signal_connect (GTK_OBJECT (shell), "event", GTK_SIGNAL_FUNC (emacs_shell_event_handler), f); */
+ − 931
+ − 932 /* Let's make sure we get all the events we can */
+ − 933 gtk_widget_set_events (text, GDK_ALL_EVENTS_MASK);
+ − 934
+ − 935 if (shell != container)
+ − 936 gtk_container_add (GTK_CONTAINER (shell), container);
+ − 937
+ − 938 gtk_widget_set_name (shell, "XEmacs::shell");
+ − 939 gtk_widget_set_name (container, "XEmacs::container");
+ − 940 gtk_widget_set_name (text, "XEmacs::text");
+ − 941
+ − 942 FRAME_GTK_LISP_WIDGETS(f)[0] = build_gtk_object (GTK_OBJECT (shell));
+ − 943 FRAME_GTK_LISP_WIDGETS(f)[1] = build_gtk_object (GTK_OBJECT (container));
+ − 944 FRAME_GTK_LISP_WIDGETS(f)[2] = build_gtk_object (GTK_OBJECT (text));
+ − 945
+ − 946 gtk_widget_realize (shell);
+ − 947 }
+ − 948
+ − 949 /* create the windows for the specified frame and display them.
+ − 950 Note that the widgets have already been created, and any
+ − 951 necessary geometry calculations have already been done. */
+ − 952 static void
+ − 953 gtk_popup_frame (struct frame *f)
+ − 954 {
+ − 955 /* */
+ − 956
+ − 957 if (gtk_object_get_data (GTK_OBJECT (FRAME_GTK_SHELL_WIDGET (f)), UNMAPPED_DATA_IDENTIFIER))
+ − 958 {
+ − 959 FRAME_GTK_TOTALLY_VISIBLE_P (f) = 0;
+ − 960 f->visible = 0;
+ − 961 gtk_widget_realize (FRAME_GTK_SHELL_WIDGET (f));
+ − 962 gtk_widget_realize (FRAME_GTK_TEXT_WIDGET (f));
+ − 963 gtk_widget_hide_all (FRAME_GTK_SHELL_WIDGET (f));
+ − 964 }
+ − 965 else
+ − 966 {
+ − 967 gtk_widget_show_all (FRAME_GTK_SHELL_WIDGET (f));
+ − 968 }
+ − 969 }
+ − 970
+ − 971 static void
+ − 972 allocate_gtk_frame_struct (struct frame *f)
+ − 973 {
1346
+ − 974 int i;
+ − 975
462
+ − 976 /* zero out all slots. */
3092
+ − 977 #ifdef NEW_GC
+ − 978 f->frame_data = alloc_lrecord_type (struct gtk_frame, &lrecord_gtk_frame);
+ − 979 #else /* not NEW_GC */
462
+ − 980 f->frame_data = xnew_and_zero (struct gtk_frame);
3092
+ − 981 #endif /* not NEW_GC */
462
+ − 982
+ − 983 /* yeah, except the lisp ones */
+ − 984 FRAME_GTK_ICON_PIXMAP (f) = Qnil;
+ − 985 FRAME_GTK_ICON_PIXMAP_MASK (f) = Qnil;
1346
+ − 986 FRAME_GTK_MENUBAR_DATA (f) = Qnil;
+ − 987 for (i = 0; i < 3; i++)
+ − 988 FRAME_GTK_LISP_WIDGETS (f)[i] = Qnil;
2168
+ − 989
+ − 990 /*
+ − 991 Hashtables of callback data for glyphs on the frame. Make them EQ because
+ − 992 we only use ints as keys. Otherwise we run into stickiness in redisplay
+ − 993 because internal_equal() can QUIT. See enter_redisplay_critical_section().
+ − 994 */
+ − 995 FRAME_GTK_WIDGET_INSTANCE_HASH_TABLE (f) =
+ − 996 make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQ);
+ − 997 FRAME_GTK_WIDGET_CALLBACK_HASH_TABLE (f) =
+ − 998 make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQ);
+ − 999 FRAME_GTK_WIDGET_CALLBACK_EX_HASH_TABLE (f) =
+ − 1000 make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQ);
462
+ − 1001 }
+ − 1002
+ − 1003
+ − 1004 /************************************************************************/
+ − 1005 /* Lisp functions */
+ − 1006 /************************************************************************/
+ − 1007
+ − 1008 static void
771
+ − 1009 gtk_init_frame_1 (struct frame *f, Lisp_Object props,
2286
+ − 1010 int UNUSED (frame_name_is_defaulted))
462
+ − 1011 {
+ − 1012 /* This function can GC */
+ − 1013 Lisp_Object initially_unmapped;
+ − 1014 Lisp_Object device = FRAME_DEVICE (f);
+ − 1015 Lisp_Object lisp_window_id = Fplist_get (props, Qwindow_id, Qnil);
+ − 1016 Lisp_Object popup = Fplist_get (props, Qpopup, Qnil);
+ − 1017
+ − 1018 if (!NILP (popup))
+ − 1019 {
+ − 1020 if (EQ (popup, Qt))
+ − 1021 popup = Fselected_frame (device);
+ − 1022 CHECK_LIVE_FRAME (popup);
+ − 1023 if (!EQ (device, FRAME_DEVICE (XFRAME (popup))))
563
+ − 1024 invalid_argument_2 ("Parent must be on same device as frame",
+ − 1025 device, popup);
462
+ − 1026 }
+ − 1027
+ − 1028 initially_unmapped = Fplist_get (props, Qinitially_unmapped, Qnil);
+ − 1029
+ − 1030 /*
+ − 1031 * Previously we set this only if NILP (DEVICE_SELECTED_FRAME (d))
+ − 1032 * to make sure that messages were displayed as soon as possible
+ − 1033 * if we're creating the first frame on a device. But it is
+ − 1034 * better to just set this all the time, so that when a new frame
+ − 1035 * is created that covers the selected frame, echo area status
+ − 1036 * messages can still be seen. f->visible is reset later if the
+ − 1037 * initially-unmapped property is found to be non-nil in the
+ − 1038 * frame properties.
+ − 1039 */
+ − 1040 f->visible = 1;
+ − 1041
+ − 1042 allocate_gtk_frame_struct (f);
+ − 1043 gtk_create_widgets (f, lisp_window_id, popup);
+ − 1044
+ − 1045 if (!NILP (initially_unmapped))
+ − 1046 {
+ − 1047 gtk_object_set_data (GTK_OBJECT (FRAME_GTK_SHELL_WIDGET (f)),
+ − 1048 UNMAPPED_DATA_IDENTIFIER, (gpointer) 1);
+ − 1049 }
+ − 1050 }
+ − 1051
+ − 1052 static void
2286
+ − 1053 gtk_init_frame_2 (struct frame *f, Lisp_Object UNUSED (props))
462
+ − 1054 {
+ − 1055 /* Set up the values of the widget/frame. A case could be made for putting
+ − 1056 this inside of the widget's initialize method. */
+ − 1057
+ − 1058 update_frame_face_values (f);
+ − 1059 gtk_initialize_frame_size (f);
+ − 1060 /* Kyle:
+ − 1061 * update_frame_title() can't be done here, because some of the
+ − 1062 * modeline specs depend on the frame's device having a selected
+ − 1063 * frame, and that may not have been set up yet. The redisplay
+ − 1064 * will update the frame title anyway, so nothing is lost.
+ − 1065 * JV:
+ − 1066 * It turns out it gives problems with FVWMs name based mapping.
+ − 1067 * We'll just need to be carefull in the modeline specs.
+ − 1068 */
+ − 1069 update_frame_title (f);
+ − 1070 }
+ − 1071
+ − 1072 static void
+ − 1073 gtk_init_frame_3 (struct frame *f)
+ − 1074 {
+ − 1075 /* Pop up the frame. */
+ − 1076 gtk_popup_frame (f);
+ − 1077 }
+ − 1078
+ − 1079 static void
+ − 1080 gtk_mark_frame (struct frame *f)
+ − 1081 {
+ − 1082 mark_object (FRAME_GTK_ICON_PIXMAP (f));
+ − 1083 mark_object (FRAME_GTK_ICON_PIXMAP_MASK (f));
1346
+ − 1084 mark_object (FRAME_GTK_MENUBAR_DATA (f));
462
+ − 1085 mark_object (FRAME_GTK_LISP_WIDGETS (f)[0]);
+ − 1086 mark_object (FRAME_GTK_LISP_WIDGETS (f)[1]);
+ − 1087 mark_object (FRAME_GTK_LISP_WIDGETS (f)[2]);
2168
+ − 1088 mark_object (FRAME_GTK_WIDGET_INSTANCE_HASH_TABLE (f));
+ − 1089 mark_object (FRAME_GTK_WIDGET_CALLBACK_HASH_TABLE (f));
+ − 1090 mark_object (FRAME_GTK_WIDGET_CALLBACK_EX_HASH_TABLE (f));
462
+ − 1091 }
+ − 1092
+ − 1093 static void
+ − 1094 gtk_set_frame_icon (struct frame *f)
+ − 1095 {
+ − 1096 GdkPixmap *gtk_pixmap = NULL, *gtk_mask = NULL;
+ − 1097
+ − 1098 if (IMAGE_INSTANCEP (f->icon)
+ − 1099 && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (f->icon)))
+ − 1100 {
+ − 1101 gtk_pixmap = XIMAGE_INSTANCE_GTK_PIXMAP (f->icon);
+ − 1102 gtk_mask = XIMAGE_INSTANCE_GTK_MASK (f->icon);
+ − 1103 }
+ − 1104 else
+ − 1105 {
+ − 1106 gtk_pixmap = 0;
+ − 1107 gtk_mask = 0;
+ − 1108 }
+ − 1109
+ − 1110 gdk_window_set_icon (GET_GTK_WIDGET_WINDOW (FRAME_GTK_SHELL_WIDGET (f)), NULL, gtk_pixmap, gtk_mask);
+ − 1111 }
+ − 1112
+ − 1113 static void
+ − 1114 gtk_set_frame_pointer (struct frame *f)
+ − 1115 {
+ − 1116 GtkWidget *w = FRAME_GTK_TEXT_WIDGET (f);
+ − 1117 GdkCursor *c = XIMAGE_INSTANCE_GTK_CURSOR (f->pointer);
+ − 1118
+ − 1119 if (POINTER_IMAGE_INSTANCEP (f->pointer))
+ − 1120 {
+ − 1121 gdk_window_set_cursor (GET_GTK_WIDGET_WINDOW (w), c);
+ − 1122 gdk_flush ();
+ − 1123 }
+ − 1124 else
+ − 1125 {
2500
+ − 1126 /* ABORT()? */
462
+ − 1127 stderr_out ("POINTER_IMAGE_INSTANCEP (f->pointer) failed!\n");
+ − 1128 }
+ − 1129 }
+ − 1130
+ − 1131 static Lisp_Object
+ − 1132 gtk_get_frame_parent (struct frame *f)
+ − 1133 {
2054
+ − 1134 GtkWidget *parentwid = (GtkWidget*) gtk_object_get_data (GTK_OBJECT (FRAME_GTK_SHELL_WIDGET (f)),
+ − 1135 TRANSIENT_DATA_IDENTIFIER);
462
+ − 1136
+ − 1137 /* find the frame whose wid is parentwid */
+ − 1138 if (parentwid)
+ − 1139 {
+ − 1140 Lisp_Object frmcons;
+ − 1141 DEVICE_FRAME_LOOP (frmcons, XDEVICE (FRAME_DEVICE (f)))
+ − 1142 {
+ − 1143 Lisp_Object frame = XCAR (frmcons);
+ − 1144 if (FRAME_GTK_SHELL_WIDGET (XFRAME (frame)) == parentwid)
+ − 1145 return frame;
+ − 1146 }
+ − 1147 }
+ − 1148 return Qnil;
+ − 1149 }
+ − 1150
+ − 1151 #ifdef STUPID_X_SPECIFIC_GTK_STUFF
+ − 1152 DEFUN ("gtk-window-id", Fgtk_window_id, 0, 1, 0, /*
+ − 1153 Get the ID of the Gtk window.
+ − 1154 This gives us a chance to manipulate the Emacs window from within a
+ − 1155 different program. Since the ID is an unsigned long, we return it as
+ − 1156 a string.
+ − 1157 */
+ − 1158 (frame))
+ − 1159 {
+ − 1160 char str[255];
+ − 1161 struct frame *f = decode_gtk_frame (frame);
+ − 1162
+ − 1163 /* Arrrrggghhh... this defeats the whole purpose of using Gdk... do we really need this? */
+ − 1164 sprintf (str, "%lu", GDK_WINDOW_XWINDOW( GET_GTK_WIDGET_WINDOW (FRAME_GTK_TEXT_WIDGET (f))));
+ − 1165 return build_string (str);
+ − 1166 }
+ − 1167 #endif
+ − 1168
+ − 1169
+ − 1170 /************************************************************************/
+ − 1171 /* manipulating the X window */
+ − 1172 /************************************************************************/
+ − 1173
+ − 1174 static void
+ − 1175 gtk_set_frame_position (struct frame *f, int xoff, int yoff)
+ − 1176 {
+ − 1177 gtk_widget_set_uposition (FRAME_GTK_SHELL_WIDGET (f), xoff, yoff);
+ − 1178 }
+ − 1179
+ − 1180 /* Call this to change the size of frame S's x-window. */
+ − 1181
+ − 1182 static void
+ − 1183 gtk_set_frame_size (struct frame *f, int cols, int rows)
+ − 1184 {
+ − 1185 GtkWidget *shell = FRAME_GTK_SHELL_WIDGET (f);
+ − 1186 GdkGeometry geometry;
+ − 1187
+ − 1188 if (GTK_IS_WINDOW (shell))
+ − 1189 {
2054
+ − 1190 GdkWindowHints geometry_mask = GDK_HINT_RESIZE_INC;
+ − 1191
462
+ − 1192 /* Update the cell size */
771
+ − 1193 default_face_height_and_width (wrap_frame (f), &geometry.height_inc, &geometry.width_inc);
462
+ − 1194
+ − 1195 gtk_window_set_geometry_hints (GTK_WINDOW (shell),
+ − 1196 FRAME_GTK_TEXT_WIDGET (f), &geometry, geometry_mask);
+ − 1197 }
+ − 1198
+ − 1199 change_frame_size (f, rows, cols, 0);
+ − 1200
+ − 1201 {
+ − 1202 GtkRequisition req;
+ − 1203
+ − 1204 gtk_widget_size_request (FRAME_GTK_SHELL_WIDGET (f), &req);
+ − 1205 gtk_widget_set_usize (FRAME_GTK_SHELL_WIDGET (f), req.width, req.height);
+ − 1206 }
+ − 1207 }
+ − 1208
+ − 1209 #ifdef STUPID_X_SPECIFIC_GTK_STUFF
+ − 1210 /* There is NO equivalent to XWarpPointer under Gtk */
+ − 1211 static void
+ − 1212 gtk_set_mouse_position (struct window *w, int x, int y)
+ − 1213 {
+ − 1214 struct frame *f = XFRAME (w->frame);
+ − 1215 Display *display = GDK_DISPLAY ();
+ − 1216 XWarpPointer (display, None,
+ − 1217 GDK_WINDOW_XWINDOW (GET_GTK_WIDGET_WINDOW (FRAME_GTK_TEXT_WIDGET (f))),
+ − 1218 0, 0, 0, 0, w->pixel_left + x, w->pixel_top + y);
+ − 1219 }
+ − 1220 #endif /* STUPID_X_SPECIFIC_GTK_STUFF */
+ − 1221
+ − 1222 static int
+ − 1223 gtk_get_mouse_position (struct device *d, Lisp_Object *frame, int *x, int *y)
+ − 1224 {
+ − 1225 /* Returns the pixel position within the editor text widget */
+ − 1226 gint win_x, win_y;
+ − 1227 GdkWindow *w = gdk_window_at_pointer (&win_x, &win_y);
+ − 1228 struct frame *f = NULL;
+ − 1229
+ − 1230 if (!w) return (0);
+ − 1231
+ − 1232 /* At this point, w is the innermost GdkWindow containing the
+ − 1233 ** pointer and win_x and win_y are the coordinates of that window.
+ − 1234 */
+ − 1235 f = gtk_any_window_to_frame (d, w);
+ − 1236
+ − 1237 if (!f) return (0);
+ − 1238
793
+ − 1239 *frame = wrap_frame (f);
462
+ − 1240
+ − 1241 gdk_window_get_pointer (GET_GTK_WIDGET_WINDOW (FRAME_GTK_TEXT_WIDGET (f)),
+ − 1242 &win_x, &win_y, NULL);
+ − 1243
+ − 1244 *x = win_x;
+ − 1245 *y = win_y;
+ − 1246
+ − 1247 return (1);
+ − 1248 }
+ − 1249
2268
+ − 1250 static DECLARE_DOESNT_RETURN (gtk_cant_notify_wm_error (void));
+ − 1251
+ − 1252 static DOESNT_RETURN
+ − 1253 gtk_cant_notify_wm_error ()
462
+ − 1254 {
563
+ − 1255 signal_error (Qgui_error, "Can't notify window manager of iconification", Qunbound);
462
+ − 1256 }
+ − 1257
+ − 1258 /* Raise frame F. */
+ − 1259 static void
+ − 1260 gtk_raise_frame_1 (struct frame *f, int force)
+ − 1261 {
+ − 1262 if (FRAME_VISIBLE_P (f) || force)
+ − 1263 {
+ − 1264 GdkWindow *emacs_window = GET_GTK_WIDGET_WINDOW (FRAME_GTK_SHELL_WIDGET (f));
+ − 1265
+ − 1266 gdk_window_raise (emacs_window);
+ − 1267 }
+ − 1268 }
+ − 1269
+ − 1270 static void
+ − 1271 gtk_raise_frame (struct frame *f)
+ − 1272 {
+ − 1273 gtk_raise_frame_1 (f, 1);
+ − 1274 }
+ − 1275
+ − 1276 /* Lower frame F. */
+ − 1277 static void
+ − 1278 gtk_lower_frame (struct frame *f)
+ − 1279 {
+ − 1280 if (FRAME_VISIBLE_P (f))
+ − 1281 {
+ − 1282 gdk_window_lower (GET_GTK_WIDGET_WINDOW (FRAME_GTK_SHELL_WIDGET (f)));
+ − 1283 }
+ − 1284 }
+ − 1285
+ − 1286 /* Change from withdrawn state to mapped state. */
+ − 1287 static void
+ − 1288 gtk_make_frame_visible (struct frame *f)
+ − 1289 {
2195
+ − 1290 gtk_widget_map (FRAME_GTK_SHELL_WIDGET (f));
462
+ − 1291 gtk_raise_frame_1 (f, 0);
+ − 1292 }
+ − 1293
+ − 1294 /* Change from mapped state to withdrawn state. */
+ − 1295 static void
+ − 1296 gtk_make_frame_invisible (struct frame *f)
+ − 1297 {
2195
+ − 1298 gtk_widget_unmap(FRAME_GTK_SHELL_WIDGET (f));
462
+ − 1299 }
+ − 1300
+ − 1301 static int
+ − 1302 gtk_frame_visible_p (struct frame *f)
+ − 1303 {
+ − 1304 GtkWidget *w = FRAME_GTK_SHELL_WIDGET (f);
+ − 1305
+ − 1306 f->visible = (GTK_OBJECT_FLAGS (w) & GTK_VISIBLE);
+ − 1307
+ − 1308 return f->visible;
+ − 1309 }
+ − 1310
+ − 1311 static int
+ − 1312 gtk_frame_totally_visible_p (struct frame *f)
+ − 1313 {
+ − 1314 return FRAME_GTK_TOTALLY_VISIBLE_P (f);
+ − 1315 }
+ − 1316
+ − 1317 /* Change window state from mapped to iconified. */
+ − 1318 static void
+ − 1319 gtk_iconify_frame (struct frame *f)
+ − 1320 {
+ − 1321 GdkWindow *w = GET_GTK_WIDGET_WINDOW (FRAME_GTK_SHELL_WIDGET (f));
+ − 1322
+ − 1323 /* There is no equivalent to XIconifyWindow in Gtk/Gdk. */
+ − 1324 if (!XIconifyWindow (GDK_WINDOW_XDISPLAY (w),
+ − 1325 GDK_WINDOW_XWINDOW (w),
+ − 1326 DefaultScreen (GDK_WINDOW_XDISPLAY (w))))
+ − 1327 gtk_cant_notify_wm_error ();
+ − 1328
+ − 1329 f->iconified = 1;
+ − 1330 }
+ − 1331
+ − 1332 /* Sets the X focus to frame f. */
+ − 1333 static void
+ − 1334 gtk_focus_on_frame (struct frame *f)
+ − 1335 {
+ − 1336 GtkWidget *shell_widget;
+ − 1337
+ − 1338 assert (FRAME_GTK_P (f));
+ − 1339
+ − 1340 shell_widget = FRAME_GTK_SHELL_WIDGET (f);
+ − 1341 if (!GET_GTK_WIDGET_WINDOW (shell_widget))
+ − 1342 return;
+ − 1343
+ − 1344 gtk_widget_grab_focus (shell_widget);
+ − 1345 }
+ − 1346
+ − 1347 /* Destroy the window of frame S. */
+ − 1348 static void
+ − 1349 gtk_delete_frame (struct frame *f)
+ − 1350 {
+ − 1351 GtkWidget *w = FRAME_GTK_SHELL_WIDGET (f);
+ − 1352
+ − 1353 gtk_widget_destroy (w);
+ − 1354
+ − 1355 if (FRAME_GTK_GEOM_FREE_ME_PLEASE (f))
1726
+ − 1356 xfree (FRAME_GTK_GEOM_FREE_ME_PLEASE (f), char *);
4117
+ − 1357 #ifndef NEW_GC
1726
+ − 1358 xfree (f->frame_data, void *);
3092
+ − 1359 #endif /* not NEW_GC */
462
+ − 1360 f->frame_data = 0;
+ − 1361 }
+ − 1362
+ − 1363 static void
+ − 1364 gtk_recompute_cell_sizes (struct frame *frm)
+ − 1365 {
+ − 1366 if (GTK_IS_WINDOW (FRAME_GTK_SHELL_WIDGET (frm)))
+ − 1367 {
+ − 1368 GtkWindow *w = GTK_WINDOW (FRAME_GTK_SHELL_WIDGET (frm));
+ − 1369 GdkGeometry geometry;
+ − 1370 GdkWindowHints geometry_mask;
+ − 1371 gint width_inc = 10;
+ − 1372 gint height_inc = 10;
+ − 1373
771
+ − 1374 default_face_height_and_width (wrap_frame (frm), &height_inc, &width_inc);
462
+ − 1375 geometry_mask = GDK_HINT_RESIZE_INC;
+ − 1376 geometry.width_inc = width_inc;
+ − 1377 geometry.height_inc = height_inc;
+ − 1378
+ − 1379 gtk_window_set_geometry_hints (w, FRAME_GTK_TEXT_WIDGET (frm), &geometry, geometry_mask);
+ − 1380 }
+ − 1381 }
+ − 1382
+ − 1383 static void
+ − 1384 gtk_update_frame_external_traits (struct frame* frm, Lisp_Object name)
+ − 1385 {
+ − 1386 Lisp_Object frame = Qnil;
+ − 1387
793
+ − 1388 frame = wrap_frame (frm);
462
+ − 1389
+ − 1390 if (EQ (name, Qforeground))
+ − 1391 {
+ − 1392 Lisp_Object color = FACE_FOREGROUND (Vdefault_face, frame);
+ − 1393 GdkColor *fgc;
+ − 1394
+ − 1395 if (!EQ (color, Vthe_null_color_instance))
+ − 1396 {
+ − 1397 fgc = COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (color));
+ − 1398 /* #### BILL!!! The X code set the XtNforeground property of
+ − 1399 the text widget here. Why did they bother? All that type
+ − 1400 of thing is done down in the guts of the redisplay code,
+ − 1401 not in the Emacs* widgets. */
+ − 1402 }
+ − 1403 }
+ − 1404 else if (EQ (name, Qbackground))
+ − 1405 {
+ − 1406 Lisp_Object color = FACE_BACKGROUND (Vdefault_face, frame);
+ − 1407 GdkColor *bgc;
+ − 1408
+ − 1409 if (!EQ (color, Vthe_null_color_instance))
+ − 1410 {
+ − 1411 bgc = COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (color));
+ − 1412 if (FRAME_GTK_SHELL_WIDGET (frm)->window)
+ − 1413 {
+ − 1414 gdk_window_set_background (FRAME_GTK_SHELL_WIDGET (frm)->window, bgc);
+ − 1415 }
+ − 1416 if (FRAME_GTK_TEXT_WIDGET (frm)->window)
+ − 1417 {
+ − 1418 gdk_window_set_background (FRAME_GTK_TEXT_WIDGET (frm)->window, bgc);
+ − 1419 }
+ − 1420 }
+ − 1421
+ − 1422 /* Really crappy way to force the modeline shadows to be
+ − 1423 redrawn. But effective. */
+ − 1424 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (frm);
+ − 1425 MARK_FRAME_CHANGED (frm);
+ − 1426 }
+ − 1427 else if (EQ (name, Qfont))
+ − 1428 {
+ − 1429 Lisp_Object font = FACE_FONT (Vdefault_face, frame, Vcharset_ascii);
+ − 1430
3676
+ − 1431 /* It may be that instantiating the font has deleted the frame (will
+ − 1432 happen if the user has specified a charset registry for ASCII that
+ − 1433 isn't available on the server, and our fallback of iso8859-1 isn't
+ − 1434 available; something vanishingly rare.) In that case, return from
+ − 1435 this function. */
+ − 1436
+ − 1437 if (!FRAME_LIVE_P(frm))
+ − 1438 {
+ − 1439 return;
+ − 1440 }
+ − 1441
462
+ − 1442 if (!EQ (font, Vthe_null_font_instance))
+ − 1443 {
+ − 1444 /* #### BILL!!! The X code set the XtNfont property of the
+ − 1445 text widget here. Why did they bother? All that type of
+ − 1446 thing is done down in the guts of the redisplay code, not
+ − 1447 in the Emacs* widgets. */
+ − 1448 }
+ − 1449 }
+ − 1450 else
2500
+ − 1451 ABORT ();
462
+ − 1452
+ − 1453 #ifdef HAVE_TOOLBARS
+ − 1454 /* Setting the background clears the entire frame area
+ − 1455 including the toolbar so we force an immediate redraw of
+ − 1456 it. */
+ − 1457 if (EQ (name, Qbackground))
+ − 1458 MAYBE_DEVMETH (XDEVICE (frm->device), redraw_frame_toolbars, (frm));
+ − 1459 #endif /* HAVE_TOOLBARS */
+ − 1460
+ − 1461 /* Set window manager resize increment hints according to
+ − 1462 the new character size */
+ − 1463 if (EQ (name, Qfont) && FRAME_GTK_TOP_LEVEL_FRAME_P (frm))
+ − 1464 gtk_recompute_cell_sizes (frm);
+ − 1465 }
+ − 1466
+ − 1467
+ − 1468 /************************************************************************/
+ − 1469 /* initialization */
+ − 1470 /************************************************************************/
+ − 1471
+ − 1472 void
+ − 1473 syms_of_frame_gtk (void)
+ − 1474 {
3092
+ − 1475 #ifdef NEW_GC
+ − 1476 INIT_LRECORD_IMPLEMENTATION (gtk_frame);
+ − 1477 #endif /* NEW_GC */
+ − 1478
563
+ − 1479 DEFSYMBOL (Qtext_widget);
+ − 1480 DEFSYMBOL (Qcontainer_widget);
+ − 1481 DEFSYMBOL (Qshell_widget);
+ − 1482 DEFSYMBOL (Qdetachable_menubar);
462
+ − 1483
+ − 1484 #ifdef HAVE_DRAGNDROP
+ − 1485 staticpro (&Vcurrent_drag_object);
+ − 1486 Vcurrent_drag_object = Qnil;
+ − 1487 DEFSUBR (Fgtk_start_drag_internal);
+ − 1488 #endif
+ − 1489 #ifdef STUPID_X_SPECIFIC_GTK_STUFF
+ − 1490 DEFSUBR (Fgtk_window_id);
+ − 1491 #endif
+ − 1492 }
+ − 1493
+ − 1494 void
+ − 1495 console_type_create_frame_gtk (void)
+ − 1496 {
+ − 1497 /* frame methods */
+ − 1498 CONSOLE_HAS_METHOD (gtk, init_frame_1);
+ − 1499 CONSOLE_HAS_METHOD (gtk, init_frame_2);
+ − 1500 CONSOLE_HAS_METHOD (gtk, init_frame_3);
+ − 1501 CONSOLE_HAS_METHOD (gtk, mark_frame);
+ − 1502 CONSOLE_HAS_METHOD (gtk, focus_on_frame);
+ − 1503 CONSOLE_HAS_METHOD (gtk, delete_frame);
+ − 1504 CONSOLE_HAS_METHOD (gtk, get_mouse_position);
+ − 1505 #ifdef STUPID_X_SPECIFIC_GTK_STUFF
+ − 1506 CONSOLE_HAS_METHOD (gtk, set_mouse_position);
+ − 1507 #endif
+ − 1508 CONSOLE_HAS_METHOD (gtk, raise_frame);
+ − 1509 CONSOLE_HAS_METHOD (gtk, lower_frame);
+ − 1510 CONSOLE_HAS_METHOD (gtk, make_frame_visible);
+ − 1511 CONSOLE_HAS_METHOD (gtk, make_frame_invisible);
+ − 1512 CONSOLE_HAS_METHOD (gtk, iconify_frame);
+ − 1513 CONSOLE_HAS_METHOD (gtk, set_frame_size);
+ − 1514 CONSOLE_HAS_METHOD (gtk, set_frame_position);
+ − 1515 CONSOLE_HAS_METHOD (gtk, frame_property);
+ − 1516 CONSOLE_HAS_METHOD (gtk, internal_frame_property_p);
+ − 1517 CONSOLE_HAS_METHOD (gtk, frame_properties);
+ − 1518 CONSOLE_HAS_METHOD (gtk, set_frame_properties);
867
+ − 1519 CONSOLE_HAS_METHOD (gtk, set_title_from_ibyte);
+ − 1520 CONSOLE_HAS_METHOD (gtk, set_icon_name_from_ibyte);
462
+ − 1521 CONSOLE_HAS_METHOD (gtk, frame_visible_p);
+ − 1522 CONSOLE_HAS_METHOD (gtk, frame_totally_visible_p);
+ − 1523 CONSOLE_HAS_METHOD (gtk, frame_iconified_p);
+ − 1524 CONSOLE_HAS_METHOD (gtk, set_frame_pointer);
+ − 1525 CONSOLE_HAS_METHOD (gtk, set_frame_icon);
+ − 1526 CONSOLE_HAS_METHOD (gtk, get_frame_parent);
+ − 1527 CONSOLE_HAS_METHOD (gtk, update_frame_external_traits);
+ − 1528 }
+ − 1529
+ − 1530 void
+ − 1531 vars_of_frame_gtk (void)
+ − 1532 {
+ − 1533 DEFVAR_LISP ("default-gtk-frame-plist", &Vdefault_gtk_frame_plist /*
+ − 1534 Plist of default frame-creation properties for Gtk frames.
+ − 1535 These override what is specified in the resource database and in
+ − 1536 `default-frame-plist', but are overridden by the arguments to the
+ − 1537 particular call to `make-frame'.
+ − 1538
+ − 1539 Note: In many cases, properties of a frame are available as specifiers
+ − 1540 instead of through the frame-properties mechanism.
+ − 1541
+ − 1542 Here is a list of recognized frame properties, other than those
+ − 1543 documented in `set-frame-properties' (they can be queried and
+ − 1544 set at any time, except as otherwise noted):
+ − 1545
+ − 1546 initially-unmapped If non-nil, the frame will not be visible
+ − 1547 when it is created. In this case, you
+ − 1548 need to call `make-frame-visible' to make
+ − 1549 the frame appear.
+ − 1550 popup If non-nil, it should be a frame, and this
+ − 1551 frame will be created as a "popup" frame
+ − 1552 whose parent is the given frame. This
+ − 1553 will make the window manager treat the
+ − 1554 frame as a dialog box, which may entail
+ − 1555 doing different things (e.g. not asking
+ − 1556 for positioning, and not iconifying
+ − 1557 separate from its parent).
+ − 1558 inter-line-space Not currently implemented.
+ − 1559 toolbar-shadow-thickness Thickness of toolbar shadows.
+ − 1560 background-toolbar-color Color of toolbar background.
+ − 1561 bottom-toolbar-shadow-color Color of bottom shadows on toolbars.
+ − 1562 (*Not* specific to the bottom-toolbar.)
+ − 1563 top-toolbar-shadow-color Color of top shadows on toolbars.
+ − 1564 (*Not* specific to the top-toolbar.)
+ − 1565 internal-border-width Width of internal border around text area.
+ − 1566 border-width Width of external border around text area.
+ − 1567 top Y position (in pixels) of the upper-left
+ − 1568 outermost corner of the frame (i.e. the
+ − 1569 upper-left of the window-manager
+ − 1570 decorations).
+ − 1571 left X position (in pixels) of the upper-left
+ − 1572 outermost corner of the frame (i.e. the
+ − 1573 upper-left of the window-manager
+ − 1574 decorations).
+ − 1575 border-color Color of external border around text area.
+ − 1576 cursor-color Color of text cursor.
+ − 1577
+ − 1578 See also `default-frame-plist', which specifies properties which apply
+ − 1579 to all frames, not just Gtk frames.
+ − 1580 */ );
+ − 1581 Vdefault_gtk_frame_plist = Qnil;
+ − 1582
+ − 1583 gtk_console_methods->device_specific_frame_props = &Vdefault_gtk_frame_plist;
+ − 1584 }