]> code.delx.au - gnu-emacs/blobdiff - src/xfns.c
(regexp-opt-group): Compute HALF2 properly.
[gnu-emacs] / src / xfns.c
index 5290220873549fe83c988b5361c1d7e74499d75e..1b9b629b36638046ec9600c5b645b15704899346 100644 (file)
@@ -65,6 +65,10 @@ Boston, MA 02111-1307, USA.  */
 #include "[.bitmaps]gray.xbm"
 #endif
 
+#ifdef USE_GTK
+#include "gtkutil.h"
+#endif
+
 #ifdef USE_X_TOOLKIT
 #include <X11/Shell.h>
 
@@ -340,6 +344,15 @@ x_window_to_frame (dpyinfo, wdesc)
           || f->output_data.x->icon_desc == wdesc)
         return f;
 #else /* not USE_X_TOOLKIT */
+#ifdef USE_GTK
+      if (f->output_data.x->edit_widget)
+      {
+        GtkWidget *gwdesc = xg_win_to_widget (wdesc);
+        struct x_output *x = f->output_data.x;
+        if (gwdesc != 0 && gwdesc == x->edit_widget)
+          return f;
+      }
+#endif /* USE_GTK */
       if (FRAME_X_WINDOW (f) == wdesc
           || f->output_data.x->icon_desc == wdesc)
         return f;
@@ -348,7 +361,7 @@ x_window_to_frame (dpyinfo, wdesc)
   return 0;
 }
 
-#ifdef USE_X_TOOLKIT
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 /* Like x_window_to_frame but also compares the window with the widget's
    windows.  */
 
@@ -377,6 +390,15 @@ x_any_window_to_frame (dpyinfo, wdesc)
            found = f;
          else if (x->widget)
            {
+#ifdef USE_GTK
+              GtkWidget *gwdesc = xg_win_to_widget (wdesc);
+              if (gwdesc != 0
+                  && (gwdesc == x->widget
+                      || gwdesc == x->edit_widget
+                      || gwdesc == x->vbox_widget
+                      || gwdesc == x->menubar_widget))
+                found = f;
+#else
              if (wdesc == XtWindow (x->widget) 
                  || wdesc == XtWindow (x->column_widget) 
                  || wdesc == XtWindow (x->edit_widget))
@@ -384,6 +406,7 @@ x_any_window_to_frame (dpyinfo, wdesc)
              /* Match if the window is this frame's menubar.  */
              else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
                found = f;
+#endif
            }
          else if (FRAME_X_WINDOW (f) == wdesc)
            /* A tooltip frame.  */
@@ -419,10 +442,19 @@ x_non_menubar_window_to_frame (dpyinfo, wdesc)
        return f;
       else if (x->widget)
        {
+#ifdef USE_GTK
+          GtkWidget *gwdesc = xg_win_to_widget (wdesc);
+          if (gwdesc != 0
+              && (gwdesc == x->widget
+                  || gwdesc == x->edit_widget
+                  || gwdesc == x->vbox_widget))
+            return f;
+#else
          if (wdesc == XtWindow (x->widget) 
              || wdesc == XtWindow (x->column_widget) 
              || wdesc == XtWindow (x->edit_widget))
            return f;
+#endif
        }
       else if (FRAME_X_WINDOW (f) == wdesc)
        /* A tooltip frame.  */
@@ -452,9 +484,25 @@ x_menubar_window_to_frame (dpyinfo, wdesc)
        continue;
       x = f->output_data.x;
       /* Match if the window is this frame's menubar.  */
+#ifdef USE_GTK
+      if (x->menubar_widget)
+        {
+          GtkWidget *gwdesc = xg_win_to_widget (wdesc);
+          int found = 0;
+          
+          BLOCK_INPUT;
+          if (gwdesc != 0
+              && (gwdesc == x->menubar_widget
+                  || gtk_widget_get_parent (gwdesc) == x->menubar_widget))
+            found = 1;
+          UNBLOCK_INPUT;
+          if (found) return f;
+        }
+#else
       if (x->menubar_widget
          && lw_window_is_in_menubar (wdesc, x->menubar_widget))
        return f;
+#endif
     }
   return 0;
 }
@@ -484,6 +532,11 @@ x_top_window_to_frame (dpyinfo, wdesc)
       if (x->widget)
        {
          /* This frame matches if the window is its topmost widget.  */
+#ifdef USE_GTK
+          GtkWidget *gwdesc = xg_win_to_widget (wdesc);
+          if (gwdesc == x->widget)
+            return f;
+#else
          if (wdesc == XtWindow (x->widget))
            return f;
 #if 0 /* I don't know why it did this,
@@ -493,6 +546,7 @@ x_top_window_to_frame (dpyinfo, wdesc)
          if (x->menubar_widget 
              && wdesc == XtWindow (x->menubar_widget))
            return f;
+#endif
 #endif
        }
       else if (FRAME_X_WINDOW (f) == wdesc)
@@ -501,7 +555,7 @@ x_top_window_to_frame (dpyinfo, wdesc)
     }
   return 0;
 }
-#endif /* USE_X_TOOLKIT */
+#endif /* USE_X_TOOLKIT || USE_GTK */
 
 \f
 
@@ -1553,6 +1607,10 @@ x_set_background_color (f, arg, oldval)
       XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
       XSetForeground (dpy, x->cursor_gc, bg);
 
+#ifdef USE_GTK
+      xg_set_background_color (f, bg);
+#endif
+
 #ifndef USE_TOOLKIT_SCROLL_BARS /* Turns out to be annoying with
                                   toolkit scroll bars.  */
       {
@@ -2119,7 +2177,7 @@ x_set_menu_bar_lines (f, value, oldval)
   /* Make sure we redisplay all windows in this frame.  */
   windows_or_buffers_changed++;
 
-#ifdef USE_X_TOOLKIT
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
   FRAME_MENU_BAR_LINES (f) = 0;
   if (nlines)
     {
@@ -2136,7 +2194,7 @@ x_set_menu_bar_lines (f, value, oldval)
       if (FRAME_X_P (f))
        f->output_data.x->menubar_widget = 0;
     }
-#else /* not USE_X_TOOLKIT */
+#else /* not USE_X_TOOLKIT && not USE_GTK */
   FRAME_MENU_BAR_LINES (f) = nlines;
   x_change_window_heights (f->root_window, nlines - olines);
 #endif /* not USE_X_TOOLKIT */
@@ -2168,7 +2226,27 @@ x_set_tool_bar_lines (f, value, oldval)
   else
     nlines = 0;
 
-  /* Make sure we redisplay all windows in this frame.  */
+#ifdef USE_GTK
+  FRAME_TOOL_BAR_LINES (f) = 0;
+  if (nlines)
+    {
+      FRAME_EXTERNAL_TOOL_BAR (f) = 1;
+      if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
+       /* Make sure next redisplay shows the tool bar.  */
+       XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
+      update_frame_tool_bar (f);
+    }
+  else
+    {
+      if (FRAME_EXTERNAL_TOOL_BAR (f))
+        free_frame_tool_bar (f);
+      FRAME_EXTERNAL_TOOL_BAR (f) = 0;
+    }
+
+  return;
+#endif
+  
+     /* Make sure we redisplay all windows in this frame.  */
   ++windows_or_buffers_changed;
 
   delta = nlines - FRAME_TOOL_BAR_LINES (f);
@@ -2439,9 +2517,7 @@ x_set_name (f, name, explicit)
        int bytes, stringp;
        Lisp_Object coding_system;
 
-       coding_system = Vlocale_coding_system;
-       if (NILP (coding_system))
-         coding_system = Qcompound_text;
+       coding_system = Qcompound_text;
        text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp);
        text.encoding = (stringp ? XA_STRING
                         : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
@@ -2467,8 +2543,15 @@ x_set_name (f, name, explicit)
        XSetWMIconName (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget),
                        &icon);
 #else /* not USE_X_TOOLKIT */
+#ifdef USE_GTK
+        gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+                              SDATA (name));
+       XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
+                        &icon);
+#else /* not USE_GTK */
        XSetWMName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &text);
        XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &icon);
+#endif /* not USE_GTK */
 #endif /* not USE_X_TOOLKIT */
        if (!NILP (f->icon_name)
            && icon.value != (unsigned char *) SDATA (f->icon_name))
@@ -2546,9 +2629,7 @@ x_set_title (f, name, old_name)
        int bytes, stringp;
        Lisp_Object coding_system;
 
-       coding_system = Vlocale_coding_system;
-       if (NILP (coding_system))
-         coding_system = Qcompound_text;
+       coding_system = Qcompound_text;
        text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp);
        text.encoding = (stringp ? XA_STRING
                         : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
@@ -2574,8 +2655,15 @@ x_set_title (f, name, old_name)
        XSetWMIconName (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget),
                        &icon);
 #else /* not USE_X_TOOLKIT */
+#ifdef USE_GTK
+        gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+                              SDATA (name));
+       XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
+                        &icon);
+#else /* not USE_GTK */
        XSetWMName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &text);
        XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &icon);
+#endif /* not USE_GTK */
 #endif /* not USE_X_TOOLKIT */
        if (!NILP (f->icon_name)
            && icon.value != (unsigned char *) SDATA (f->icon_name))
@@ -3668,7 +3756,9 @@ xic_set_statusarea (f)
   area.height = needed->height;
   area.x = PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
   area.y = (PIXEL_HEIGHT (f) - area.height
-           - FRAME_MENUBAR_HEIGHT (f) - FRAME_INTERNAL_BORDER_WIDTH (f));
+           - FRAME_MENUBAR_HEIGHT (f)
+           - FRAME_TOOLBAR_HEIGHT (f)
+            - FRAME_INTERNAL_BORDER_WIDTH (f));
   XFree (needed);
 
   attr = XVaCreateNestedList (0, XNArea, &area, NULL);
@@ -3942,7 +4032,16 @@ x_window (f, window_prompting, minibuffer_only)
 }
 
 #else /* not USE_X_TOOLKIT */
+#ifdef USE_GTK
+void
+x_window (f)
+     FRAME_PTR f;
+{
+  if (! xg_create_frame_widgets (f))
+    error ("Unable to create window");
+}
 
+#else /*! USE_GTK */
 /* Create and set up the X window for frame F.  */
 
 void
@@ -4045,6 +4144,7 @@ x_window (f)
     error ("Unable to create window");
 }
 
+#endif /* not USE_GTK */
 #endif /* not USE_X_TOOLKIT */
 
 /* Handle the icon stuff for this window.  Perhaps later we might
@@ -4622,7 +4722,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
      new frames.  */
   call1 (Qface_set_after_frame_default, frame);
 
-#ifdef USE_X_TOOLKIT
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
   /* Create the menu bar.  */
   if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
     {
@@ -4630,13 +4730,15 @@ This function is an internal primitive--use `make-frame' instead.  */)
         frame and we didn't make it visible.  */
       initialize_frame_menubar (f);
 
+#ifndef USE_GTK
       /* This is a no-op, except under Motif where it arranges the
         main window for the widgets on it.  */
       lw_set_main_areas (f->output_data.x->column_widget,
                         f->output_data.x->menubar_widget,
                         f->output_data.x->edit_widget);
+#endif /* not USE_GTK */
     }
-#endif /* USE_X_TOOLKIT */
+#endif /* USE_X_TOOLKIT || USE_GTK */
 
   /* Tell the server what size and position, etc, we want, and how
      badly we want them.  This should be done after we have the menu
@@ -6591,6 +6693,7 @@ x_put_x_image (f, ximg, pixmap, width, height)
      struct frame *f;
      XImage *ximg;
      Pixmap pixmap;
+     int width, height;
 {
   GC gc;
   
@@ -9006,8 +9109,8 @@ png_load (f, img)
 
   screen_gamma = (f->gamma ? 1 / f->gamma / 0.45455 : 2.2);
 
+#if 0 /* Avoid double gamma correction for PNG images. */
   /* Tell the PNG lib to handle gamma correction for us.  */
-
 #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
   if (png_get_sRGB (png_ptr, info_ptr, &intent))
     /* The libpng documentation says this is right in this case.  */
@@ -9020,6 +9123,7 @@ png_load (f, img)
   else
     /* Use the standard default for the image gamma.  */
     png_set_gamma (png_ptr, screen_gamma, 0.45455);
+#endif /* if 0 */
 
   /* Handle alpha channel by combining the image with a background
      color.  Do this only if a real alpha channel is supplied.  For
@@ -11651,18 +11755,14 @@ selection dialog's entry field, if MUSTMATCH is non-nil.  */)
       XmListSetPos (list, item_pos);
     }
 
-  /* Process events until the user presses Cancel or OK.  Block
-     and unblock input here so that we get a chance of processing
-     expose events.  */
-  UNBLOCK_INPUT;
+  /* Process events until the user presses Cancel or OK.  */
   result = 0;
   while (result == 0)
     {
-      BLOCK_INPUT;
-      XtAppProcessEvent (Xt_app_con, XtIMAll);
-      UNBLOCK_INPUT;
+      XEvent event;
+      XtAppNextEvent (Xt_app_con, &event);
+      x_dispatch_event (&event, FRAME_X_DISPLAY (f) );
     }
-  BLOCK_INPUT;
 
   /* Get the result.  */
   if (result == XmCR_OK)
@@ -11694,6 +11794,58 @@ selection dialog's entry field, if MUSTMATCH is non-nil.  */)
 
 #endif /* USE_MOTIF */
 
+#ifdef USE_GTK
+
+DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0,
+  "Read file name, prompting with PROMPT in directory DIR.\n\
+Use a file selection dialog.\n\
+Select DEFAULT-FILENAME in the dialog's file selection box, if\n\
+specified.  Don't let the user enter a file name in the file\n\
+selection dialog's entry field, if MUSTMATCH is non-nil.")
+  (prompt, dir, default_filename, mustmatch)
+     Lisp_Object prompt, dir, default_filename, mustmatch;
+{
+  FRAME_PTR f = SELECTED_FRAME ();
+  char *fn;
+  Lisp_Object file = Qnil;
+  int count = specpdl_ptr - specpdl;
+  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
+  char *cdef_file;
+  char *cprompt;
+  
+  GCPRO5 (prompt, dir, default_filename, mustmatch, file);
+  CHECK_STRING (prompt);
+  CHECK_STRING (dir);
+
+  /* Prevent redisplay.  */
+  specbind (Qinhibit_redisplay, Qt);
+
+  BLOCK_INPUT;
+
+  if (STRINGP (default_filename))
+    cdef_file = SDATA (default_filename);
+  else
+    cdef_file = SDATA (dir);
+
+  fn = xg_get_file_name (f, SDATA (prompt), cdef_file, ! NILP (mustmatch));
+  
+  if (fn)
+    {
+      file = build_string (fn);
+      xfree (fn);
+    }
+
+  UNBLOCK_INPUT;
+  UNGCPRO;
+
+  /* Make "Cancel" equivalent to C-g.  */
+  if (NILP (file))
+    Fsignal (Qquit, Qnil);
+  
+  return unbind_to (count, file);
+}
+
+#endif /* USE_GTK */
 
 \f
 /***********************************************************************
@@ -11915,7 +12067,7 @@ A cross is always drawn on black & white displays.  */);
   cross_disabled_images = 0;
 
   DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
-    doc: /* List of directories to search for bitmap files for X.  */);
+    doc: /* List of directories to search for window system bitmap files.  */);
   Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS);
 
   DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,