Commit ec56ef9d authored by Sven Neumann's avatar Sven Neumann Committed by Sven Neumann

Address bug #307971:

2005-09-05  Sven Neumann  <sven@gimp.org>

	Address bug #307971:

	* app/core/gimp-gui.[ch]
	* app/display/gimpdisplay.[ch]
	* app/gui/gui-vtable.c
	* tools/pdbgen/pdb/display.pdb: added PDB function to obtain a
	window handle on an image display.

	* app/pdb/display_cmds.c
	* app/pdb/internal_procs.c
	* libgimp/gimpdisplay_pdb.[ch]: regenerated.

	* libgimp/gimpui.[ch]: added functions to set a GtkWindow transient
	to an image display.

	* plug-ins/common/gauss.c: use the new function exemplarily.

	* libgimp/gimp.def
	* libgimp/gimpui.def: updated.
parent 0ae992b9
2005-09-05 Sven Neumann <sven@gimp.org>
Address bug #307971:
* app/core/gimp-gui.[ch]
* app/display/gimpdisplay.[ch]
* app/gui/gui-vtable.c
* tools/pdbgen/pdb/display.pdb: added PDB function to obtain a
window handle on an image display.
* app/pdb/display_cmds.c
* app/pdb/internal_procs.c
* libgimp/gimpdisplay_pdb.[ch]: regenerated.
* libgimp/gimpui.[ch]: added functions to set a GtkWindow transient
to an image display.
* plug-ins/common/gauss.c: use the new function exemplarily.
* libgimp/gimp.def
* libgimp/gimpui.def: updated.
2005-09-05 Sven Neumann <sven@gimp.org>
* app/actions/edit-actions.c
......
......@@ -50,6 +50,7 @@ gimp_gui_init (Gimp *gimp)
gimp->gui.get_theme_dir = NULL;
gimp->gui.display_get_by_id = NULL;
gimp->gui.display_get_id = NULL;
gimp->gui.display_get_window = NULL;
gimp->gui.display_create = NULL;
gimp->gui.display_delete = NULL;
gimp->gui.displays_reconnect = NULL;
......@@ -235,6 +236,19 @@ gimp_get_display_ID (Gimp *gimp,
return -1;
}
guint32
gimp_get_display_window (Gimp *gimp,
GimpObject *display)
{
g_return_val_if_fail (GIMP_IS_GIMP (gimp), -1);
g_return_val_if_fail (GIMP_IS_OBJECT (display), -1);
if (gimp->gui.display_get_window)
return gimp->gui.display_get_window (display);
return -1;
}
GimpObject *
gimp_create_display (Gimp *gimp,
GimpImage *gimage,
......
......@@ -46,6 +46,7 @@ struct _GimpGui
GimpObject * (* display_get_by_id) (Gimp *gimp,
gint ID);
gint (* display_get_id) (GimpObject *display);
guint32 (* display_get_window) (GimpObject *display);
GimpObject * (* display_create) (GimpImage *gimage,
GimpUnit unit,
gdouble scale);
......@@ -100,6 +101,8 @@ GimpObject * gimp_get_display_by_ID (Gimp *gimp,
gint ID);
gint gimp_get_display_ID (Gimp *gimp,
GimpObject *display);
guint32 gimp_get_display_window (Gimp *gimp,
GimpObject *display);
GimpObject * gimp_create_display (Gimp *gimp,
GimpImage *gimage,
GimpUnit unit,
......
......@@ -20,6 +20,14 @@
#include <gtk/gtk.h>
#ifdef GDK_WINDOWING_WIN32
#include <gdk/gdkwin32.h>
#endif
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#endif
#include "display-types.h"
#include "tools/tools-types.h"
......@@ -438,6 +446,46 @@ gimp_display_get_ID (GimpDisplay *gdisp)
return gdisp->ID;
}
/**
* gimp_display_get_window:
* @display: a #GimpDisplayShell
*
* This function is used to pass a window handle to plug-ins so that
* they can set their dialog windows transient to the image display.
*
* Return value: a native window handle of the display's shell or 0
* if the shell isn't realized yet
*/
GdkNativeWindow
gimp_display_get_window (GimpDisplay *display)
{
GtkWidget *shell;
#ifdef GDK_NATIVE_WINDOW_POINTER
g_return_val_if_fail (GIMP_IS_DISPLAY (display), NULL);
#else
g_return_val_if_fail (GIMP_IS_DISPLAY (display), 0);
#endif
shell = display->shell;
#ifdef GDK_WINDOWING_WIN32
if (shell && GTK_WIDGET_REALIZED (shell))
return GDK_WINDOW_HWND (shell->window);
#endif
#ifdef GDK_WINDOWING_X11
if (shell && GTK_WIDGET_REALIZED (shell))
return GDK_WINDOW_XID (shell->window);
#endif
#ifdef GDK_NATIVE_WINDOW_POINTER
return NULL;
#else
return 0;
#endif
}
GimpDisplay *
gimp_display_get_by_ID (Gimp *gimp,
gint ID)
......
......@@ -54,31 +54,32 @@ struct _GimpDisplayClass
};
GType gimp_display_get_type (void) G_GNUC_CONST;
GimpDisplay * gimp_display_new (GimpImage *gimage,
GimpUnit unit,
gdouble scale,
GimpMenuFactory *menu_factory,
GimpUIManager *popup_manager);
void gimp_display_delete (GimpDisplay *gdisp);
gint gimp_display_get_ID (GimpDisplay *gdisp);
GimpDisplay * gimp_display_get_by_ID (Gimp *gimp,
gint ID);
void gimp_display_reconnect (GimpDisplay *gdisp,
GimpImage *gimage);
void gimp_display_update_area (GimpDisplay *gdisp,
gboolean now,
gint x,
gint y,
gint w,
gint h);
void gimp_display_flush (GimpDisplay *gdisp);
void gimp_display_flush_now (GimpDisplay *gdisp);
GType gimp_display_get_type (void) G_GNUC_CONST;
GimpDisplay * gimp_display_new (GimpImage *gimage,
GimpUnit unit,
gdouble scale,
GimpMenuFactory *menu_factory,
GimpUIManager *popup_manager);
void gimp_display_delete (GimpDisplay *gdisp);
gint gimp_display_get_ID (GimpDisplay *gdisp);
GdkNativeWindow gimp_display_get_window (GimpDisplay *gdisp);
GimpDisplay * gimp_display_get_by_ID (Gimp *gimp,
gint ID);
void gimp_display_reconnect (GimpDisplay *gdisp,
GimpImage *gimage);
void gimp_display_update_area (GimpDisplay *gdisp,
gboolean now,
gint x,
gint y,
gint w,
gint h);
void gimp_display_flush (GimpDisplay *gdisp);
void gimp_display_flush_now (GimpDisplay *gdisp);
#endif /* __GIMP_DISPLAY_H__ */
......@@ -93,6 +93,7 @@ static const gchar * gui_get_theme_dir (Gimp *gimp);
static GimpObject * gui_display_get_by_ID (Gimp *gimp,
gint ID);
static gint gui_display_get_ID (GimpObject *display);
static guint32 gui_display_get_window (GimpObject *display);
static GimpObject * gui_display_create (GimpImage *gimage,
GimpUnit unit,
gdouble scale);
......@@ -152,6 +153,7 @@ gui_vtable_init (Gimp *gimp)
gimp->gui.get_theme_dir = gui_get_theme_dir;
gimp->gui.display_get_by_id = gui_display_get_by_ID;
gimp->gui.display_get_id = gui_display_get_ID;
gimp->gui.display_get_window = gui_display_get_window;
gimp->gui.display_create = gui_display_create;
gimp->gui.display_delete = gui_display_delete;
gimp->gui.displays_reconnect = gui_displays_reconnect;
......@@ -328,6 +330,19 @@ gui_display_get_ID (GimpObject *display)
return gimp_display_get_ID (GIMP_DISPLAY (display));
}
static guint32
gui_display_get_window (GimpObject *display)
{
#ifdef GDK_NATIVE_WINDOW_POINTER
#ifdef __GNUC__
#warning gui_display_get_window() unimplementable for the target windowing system
#endif
return 0;
#else
return (guint32) gimp_display_get_window (GIMP_DISPLAY (display));
#endif
}
static GimpObject *
gui_display_create (GimpImage *gimage,
GimpUnit unit,
......
......@@ -32,6 +32,7 @@
static ProcRecord display_new_proc;
static ProcRecord display_delete_proc;
static ProcRecord display_get_window_handle_proc;
static ProcRecord displays_flush_proc;
static ProcRecord displays_reconnect_proc;
......@@ -40,6 +41,7 @@ register_display_procs (Gimp *gimp)
{
procedural_db_register (gimp, &display_new_proc);
procedural_db_register (gimp, &display_delete_proc);
procedural_db_register (gimp, &display_get_window_handle_proc);
procedural_db_register (gimp, &displays_flush_proc);
procedural_db_register (gimp, &displays_reconnect_proc);
}
......@@ -160,6 +162,68 @@ static ProcRecord display_delete_proc =
{ { display_delete_invoker } }
};
static Argument *
display_get_window_handle_invoker (Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
Argument *args)
{
gboolean success = TRUE;
Argument *return_args;
GimpObject *display;
gint32 window = 0;
display = gimp_get_display_by_ID (gimp, args[0].value.pdb_int);
if (! GIMP_IS_OBJECT (display))
success = FALSE;
if (success)
window = (gint32) gimp_get_display_window (gimp, display);
return_args = procedural_db_return_args (&display_get_window_handle_proc, success);
if (success)
return_args[1].value.pdb_int = window;
return return_args;
}
static ProcArg display_get_window_handle_inargs[] =
{
{
GIMP_PDB_DISPLAY,
"display",
"The display to get the window handle from"
}
};
static ProcArg display_get_window_handle_outargs[] =
{
{
GIMP_PDB_INT32,
"window",
"The native window handle or 0"
}
};
static ProcRecord display_get_window_handle_proc =
{
"gimp-display-get-window-handle",
"gimp-display-get-window-handle",
"Get a handle to the native window for an image display.",
"This procedure returns a handle to the native window for a given image display. For example in the X backend of GDK, a native window handle is an Xlib XID. A value of 0 is returned for an invalid display or if this function is unimplemented for the windowing system that is being used.",
"Sven Neumann",
"Sven Neumann",
"2005",
NULL,
GIMP_INTERNAL,
1,
display_get_window_handle_inargs,
1,
display_get_window_handle_outargs,
{ { display_get_window_handle_invoker } }
};
static Argument *
displays_flush_invoker (Gimp *gimp,
GimpContext *context,
......
......@@ -75,7 +75,7 @@ void register_undo_procs (Gimp *gimp);
void register_unit_procs (Gimp *gimp);
void register_vectors_procs (Gimp *gimp);
/* 473 procedures registered total */
/* 474 procedures registered total */
void
internal_procs_init (Gimp *gimp,
......@@ -87,19 +87,19 @@ internal_procs_init (Gimp *gimp,
(* status_callback) (_("Internal Procedures"), _("Brush"), 0.0);
register_brush_procs (gimp);
(* status_callback) (NULL, _("Brush UI"), 0.047);
(* status_callback) (NULL, _("Brush UI"), 0.046);
register_brush_select_procs (gimp);
(* status_callback) (NULL, _("Brushes"), 0.053);
register_brushes_procs (gimp);
(* status_callback) (NULL, _("Channel"), 0.066);
(* status_callback) (NULL, _("Channel"), 0.065);
register_channel_procs (gimp);
(* status_callback) (NULL, _("Color"), 0.087);
(* status_callback) (NULL, _("Color"), 0.086);
register_color_procs (gimp);
(* status_callback) (NULL, _("Context"), 0.121);
(* status_callback) (NULL, _("Context"), 0.12);
register_context_procs (gimp);
(* status_callback) (NULL, _("Convert"), 0.167);
......@@ -108,64 +108,64 @@ internal_procs_init (Gimp *gimp,
(* status_callback) (NULL, _("Display procedures"), 0.173);
register_display_procs (gimp);
(* status_callback) (NULL, _("Drawable procedures"), 0.182);
(* status_callback) (NULL, _("Drawable procedures"), 0.184);
register_drawable_procs (gimp);
(* status_callback) (NULL, _("Transformation procedures"), 0.256);
(* status_callback) (NULL, _("Transformation procedures"), 0.257);
register_drawable_transform_procs (gimp);
(* status_callback) (NULL, _("Edit procedures"), 0.29);
(* status_callback) (NULL, _("Edit procedures"), 0.291);
register_edit_procs (gimp);
(* status_callback) (NULL, _("File Operations"), 0.326);
(* status_callback) (NULL, _("File Operations"), 0.327);
register_fileops_procs (gimp);
(* status_callback) (NULL, _("Floating selections"), 0.347);
(* status_callback) (NULL, _("Floating selections"), 0.348);
register_floating_sel_procs (gimp);
(* status_callback) (NULL, _("Font UI"), 0.359);
(* status_callback) (NULL, _("Font UI"), 0.361);
register_font_select_procs (gimp);
(* status_callback) (NULL, _("Fonts"), 0.366);
(* status_callback) (NULL, _("Fonts"), 0.367);
register_fonts_procs (gimp);
(* status_callback) (NULL, _("Gimprc procedures"), 0.37);
(* status_callback) (NULL, _("Gimprc procedures"), 0.371);
register_gimprc_procs (gimp);
(* status_callback) (NULL, _("Gradient"), 0.385);
(* status_callback) (NULL, _("Gradient"), 0.386);
register_gradient_procs (gimp);
(* status_callback) (NULL, _("Gradient UI"), 0.448);
(* status_callback) (NULL, _("Gradient UI"), 0.449);
register_gradient_select_procs (gimp);
(* status_callback) (NULL, _("Gradients"), 0.455);
(* status_callback) (NULL, _("Gradients"), 0.456);
register_gradients_procs (gimp);
(* status_callback) (NULL, _("Guide procedures"), 0.465);
(* status_callback) (NULL, _("Guide procedures"), 0.466);
register_guides_procs (gimp);
(* status_callback) (NULL, _("Help procedures"), 0.478);
(* status_callback) (NULL, _("Help procedures"), 0.479);
register_help_procs (gimp);
(* status_callback) (NULL, _("Image"), 0.48);
(* status_callback) (NULL, _("Image"), 0.481);
register_image_procs (gimp);
(* status_callback) (NULL, _("Layer"), 0.613);
(* status_callback) (NULL, _("Layer"), 0.614);
register_layer_procs (gimp);
(* status_callback) (NULL, _("Message procedures"), 0.67);
(* status_callback) (NULL, _("Message procedures"), 0.671);
register_message_procs (gimp);
(* status_callback) (NULL, _("Miscellaneous"), 0.677);
register_misc_procs (gimp);
(* status_callback) (NULL, _("Paint Tool procedures"), 0.683);
(* status_callback) (NULL, _("Paint Tool procedures"), 0.684);
register_paint_tools_procs (gimp);
(* status_callback) (NULL, _("Palette"), 0.715);
register_palette_procs (gimp);
(* status_callback) (NULL, _("Palette UI"), 0.744);
(* status_callback) (NULL, _("Palette UI"), 0.745);
register_palette_select_procs (gimp);
(* status_callback) (NULL, _("Palettes"), 0.751);
......@@ -174,19 +174,19 @@ internal_procs_init (Gimp *gimp,
(* status_callback) (NULL, _("Parasite procedures"), 0.759);
register_parasite_procs (gimp);
(* status_callback) (NULL, _("Paths"), 0.784);
(* status_callback) (NULL, _("Paths"), 0.785);
register_paths_procs (gimp);
(* status_callback) (NULL, _("Pattern"), 0.818);
(* status_callback) (NULL, _("Pattern"), 0.819);
register_pattern_procs (gimp);
(* status_callback) (NULL, _("Pattern UI"), 0.822);
(* status_callback) (NULL, _("Pattern UI"), 0.823);
register_pattern_select_procs (gimp);
(* status_callback) (NULL, _("Patterns"), 0.829);
register_patterns_procs (gimp);
(* status_callback) (NULL, _("Plug-in"), 0.837);
(* status_callback) (NULL, _("Plug-in"), 0.838);
register_plug_in_procs (gimp);
(* status_callback) (NULL, _("Procedural database"), 0.85);
......
......@@ -95,6 +95,7 @@ EXPORTS
gimp_destroy_paramdefs
gimp_destroy_params
gimp_display_delete
gimp_display_get_window_handle
gimp_display_name
gimp_display_new
gimp_displays_flush
......
......@@ -90,6 +90,42 @@ gimp_display_delete (gint32 display_ID)
return success;
}
/**
* gimp_display_get_window_handle:
* @display_ID: The display to get the window handle from.
*
* Get a handle to the native window for an image display.
*
* This procedure returns a handle to the native window for a given
* image display. For example in the X backend of GDK, a native window
* handle is an Xlib XID. A value of 0 is returned for an invalid
* display or if this function is unimplemented for the windowing
* system that is being used.
*
* Returns: The native window handle or 0.
*
* Since: GIMP 2.4
*/
gint
gimp_display_get_window_handle (gint32 display_ID)
{
GimpParam *return_vals;
gint nreturn_vals;
gint window = 0;
return_vals = gimp_run_procedure ("gimp-display-get-window-handle",
&nreturn_vals,
GIMP_PDB_DISPLAY, display_ID,
GIMP_PDB_END);
if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
window = return_vals[1].data.d_int32;
gimp_destroy_params (return_vals, nreturn_vals);
return window;
}
/**
* gimp_displays_flush:
*
......
......@@ -29,11 +29,12 @@ G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
gint32 gimp_display_new (gint32 image_ID);
gboolean gimp_display_delete (gint32 display_ID);
gboolean gimp_displays_flush (void);
gboolean gimp_displays_reconnect (gint32 old_image_ID,
gint32 new_image_ID);
gint32 gimp_display_new (gint32 image_ID);
gboolean gimp_display_delete (gint32 display_ID);
gint gimp_display_get_window_handle (gint32 display_ID);
gboolean gimp_displays_flush (void);
gboolean gimp_displays_reconnect (gint32 old_image_ID,
gint32 new_image_ID);
G_END_DECLS
......
......@@ -34,9 +34,14 @@
/* local function prototypes */
static void gimp_ui_help_func (const gchar *help_id,
gpointer help_data);
static void gimp_ensure_modules (void);
static void gimp_ui_help_func (const gchar *help_id,
gpointer help_data);
static void gimp_ensure_modules (void);
static void gimp_window_transient_realized (GtkWidget *window,
GdkWindow *parent);
static gboolean gimp_ui_initialized = FALSE;
/* public functions */
......@@ -60,8 +65,6 @@ void
gimp_ui_init (const gchar *prog_name,
gboolean preview)
{
static gboolean initialized = FALSE;
const gchar *display_name;
gint argc;
gchar **argv;
......@@ -70,7 +73,7 @@ gimp_ui_init (const gchar *prog_name,
g_return_if_fail (prog_name != NULL);
if (initialized)
if (gimp_ui_initialized)
return;
display_name = gimp_display_name ();
......@@ -116,7 +119,102 @@ gimp_ui_init (const gchar *prog_name,
gimp_dialogs_show_help_button (gimp_show_help_button ());
initialized = TRUE;
gimp_ui_initialized = TRUE;
}
/**
* gimp_ui_get_display_window:
*
* Returns the #GdkWindow of a display window. The purpose is to allow
* to make plug-in dialogs transient to the image display as explained
* with gdk_window_set_transient_for().
*
* You shouldn't have to call this function directly. Use
* gimp_window_set_transient_for_display() instead.
*
* Return value: A reference to a #GdkWindow or %NULL. You should
* unref the window using g_object_unref() as soon as
* you don't need it any longer.
*
* Since: GIMP 2.4
*/
GdkWindow *
gimp_ui_get_display_window (guint32 gdisp_ID)
{
GdkNativeWindow window;
g_return_val_if_fail (gimp_ui_initialized, NULL);
#ifndef GDK_NATIVE_WINDOW_POINTER
window = gimp_display_get_window_handle (gdisp_ID);
if (window)
return gdk_window_foreign_new_for_display (gdk_display_get_default (),
window);
#endif
return NULL;
}
/**
* gimp_window_set_transient_for_display:
* @window: the #GtkWindow that should become transient
* @gdisp_ID: display ID of the image window that should become the parent
*
* Indicates to the window manager that @window is a transient dialog
* associated with the GIMP image window that is identified by it's
* display ID. See gdk_window_set_transient_for () for more information.
*
* Most of the time you will want to use the convenience function
* gimp_window_set_transient_for_default_display().
*
* Since: GIMP 2.4
*/
void
gimp_window_set_transient_for_display (GtkWindow *window,
guint32 gdisp_ID)
{
GdkWindow *display;
g_return_if_fail (gimp_ui_initialized);
g_return_if_fail (GTK_IS_WINDOW (window));