1997-11-24 22:37:52 +00:00
|
|
|
/* GTK - The GIMP Toolkit
|
|
|
|
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
1997-11-28 01:22:38 +00:00
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
1997-11-24 22:37:52 +00:00
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this library; if not, write to the Free
|
|
|
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "gtkbutton.h"
|
|
|
|
#include "gtkhscrollbar.h"
|
|
|
|
#include "gtkhseparator.h"
|
|
|
|
#include "gtkmain.h"
|
|
|
|
#include "gtkpreview.h"
|
|
|
|
#include "gtkrc.h"
|
|
|
|
#include "gtkselection.h"
|
|
|
|
#include "gtksignal.h"
|
|
|
|
#include "gtktable.h"
|
|
|
|
#include "gtktext.h"
|
|
|
|
#include "gtkvbox.h"
|
|
|
|
#include "gtkvscrollbar.h"
|
|
|
|
#include "gtkwidget.h"
|
|
|
|
#include "gtkwindow.h"
|
GTK_RESIZE_NEEDED is a private flag now.
Mon Feb 2 04:15:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtkcontainer.h:
* gtk/gtkcontainer.c: GTK_RESIZE_NEEDED is a private flag now.
(gtk_container_register_toplevel): new function.
(gtk_container_unregister_toplevel): new function.
* gtk/gtkmain.c: GTK_LEAVE_PENDING is a private flag now.
* gtk/gtkmenu.c: call gtk_container_register_toplevel in
gtk_menu_class_init instead of this dirty gtk_widget_set_parent(,NULL)
hack. new default handler gtk_menu_destroy for calling
gtk_container_unregister_toplevel. removed GTK_ANCHORED, GTK_UNMAPPED.
* gtk/gtkobject.h: macro cleanups, added GTK_DESTROYED flag.
* gtk/gtkobject.c: only emit DESTROY signal if !GTK_OBJECT_DESTROYED
(object).
* gtk/gtkprivate.h: new file that will not be automatically included.
it holds the private flags for GtkWidget along with it's SET/UNSET
and examination macros.
* gtk/gtkwidget.c: private flags: GTK_RESIZE_NEEDED, GTK_REDRAW_PENDING,
GTK_RESIZE_PENDING, GTK_IN_REPARENT, GTK_USER_STYLE. GTK_ANCHORED is
replaced by GTK_TOPLEVEL. added missing UNSET for GTK_IN_REPARENT.
removed the gtk_widget_set_parent(, NULL) hack for toplevels.
upon destroy free memory for widgets with GTK_WIDGET_HAS_SHAPE_MASK.
* gtk/gtkwidget.h: split up the widget flags into a public and a private
portion. added an extra field private_flags to GtkWidget without making
it bigger by using an alignment gap of 16 bit. macro cleanups.
* gtk/gtkwindow.c: removed GTK_ANCHORED. new function gtk_window_destroy
for calling gtk_container_unregister_toplevel. removed the
gtk_widget_set_parent(,NULL), call gtk_container_register_toplevel
instead. remove GTK_UNMAPPED. GTK_RESIZE_NEEDED is private now.
* gtk/gtksignal.c (gtk_signal_disconnect): removed a bug on
removal that cut off the handler list -> living_objects == 0
with testgtk. made some warnings more descriptive.
new function gtk_signal_connect_object_while_alive, which
will automatically destroy the connection once one of the objects
is destroyed. didn't include this before removal of the above
mentioned bug.
* reflected refcounting revolution in ChangeLog
1998-02-02 04:54:25 +00:00
|
|
|
#include "gtkprivate.h"
|
1997-11-24 22:37:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* Private type definitions
|
|
|
|
*/
|
1998-01-18 18:17:23 +00:00
|
|
|
typedef struct _GtkInitFunction GtkInitFunction;
|
|
|
|
typedef struct _GtkTimeoutFunction GtkTimeoutFunction;
|
|
|
|
typedef struct _GtkIdleFunction GtkIdleFunction;
|
|
|
|
typedef struct _GtkInputFunction GtkInputFunction;
|
|
|
|
typedef struct _GtkKeySnooperData GtkKeySnooperData;
|
1997-11-24 22:37:52 +00:00
|
|
|
|
|
|
|
struct _GtkInitFunction
|
|
|
|
{
|
|
|
|
GtkFunction function;
|
|
|
|
gpointer data;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _GtkTimeoutFunction
|
|
|
|
{
|
|
|
|
gint tag;
|
|
|
|
guint32 start;
|
|
|
|
guint32 interval;
|
|
|
|
guint32 originterval;
|
|
|
|
GtkFunction function;
|
1998-02-13 05:19:06 +00:00
|
|
|
GtkCallbackMarshal marshal;
|
1997-11-24 22:37:52 +00:00
|
|
|
gpointer data;
|
|
|
|
GtkDestroyNotify destroy;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _GtkIdleFunction
|
|
|
|
{
|
|
|
|
gint tag;
|
1998-02-13 05:19:06 +00:00
|
|
|
gint priority;
|
|
|
|
GtkCallbackMarshal marshal;
|
1997-11-24 22:37:52 +00:00
|
|
|
GtkFunction function;
|
|
|
|
gpointer data;
|
|
|
|
GtkDestroyNotify destroy;
|
|
|
|
};
|
|
|
|
|
1997-12-18 02:17:14 +00:00
|
|
|
struct _GtkInputFunction
|
|
|
|
{
|
|
|
|
GtkCallbackMarshal callback;
|
|
|
|
gpointer data;
|
|
|
|
GtkDestroyNotify destroy;
|
|
|
|
};
|
1997-11-24 22:37:52 +00:00
|
|
|
|
1998-01-18 18:17:23 +00:00
|
|
|
struct _GtkKeySnooperData
|
|
|
|
{
|
|
|
|
GtkKeySnoopFunc func;
|
|
|
|
gpointer func_data;
|
|
|
|
gint id;
|
|
|
|
};
|
|
|
|
|
1997-11-28 01:22:38 +00:00
|
|
|
static void gtk_exit_func (void);
|
|
|
|
static void gtk_timeout_insert (GtkTimeoutFunction *timeoutf);
|
|
|
|
static void gtk_handle_current_timeouts (guint32 the_time);
|
|
|
|
static void gtk_handle_current_idles (void);
|
1998-01-18 18:17:23 +00:00
|
|
|
static gint gtk_invoke_key_snoopers (GtkWidget *grab_widget,
|
|
|
|
GdkEvent *event);
|
1997-11-28 01:22:38 +00:00
|
|
|
static void gtk_handle_timeouts (void);
|
|
|
|
static void gtk_handle_idle (void);
|
|
|
|
static void gtk_handle_timer (void);
|
|
|
|
static void gtk_propagate_event (GtkWidget *widget,
|
|
|
|
GdkEvent *event);
|
|
|
|
static void gtk_error (gchar *str);
|
|
|
|
static void gtk_warning (gchar *str);
|
|
|
|
static void gtk_message (gchar *str);
|
|
|
|
static void gtk_print (gchar *str);
|
|
|
|
|
1998-02-17 04:39:47 +00:00
|
|
|
static gint gtk_idle_compare (gpointer a,
|
|
|
|
gpointer b);
|
|
|
|
|
|
|
|
static gint gtk_timeout_compare (gpointer a,
|
|
|
|
gpointer b);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
ok, there have been several severe bugs in the signal handler referencing
Tue Feb 10 07:12:07 1998 Tim Janik <timj@gimp.org>
* gtk/gtksignal.h:
* gtk/gtksignal.c:
ok, there have been several severe bugs in the signal handler
referencing and ->next connection stuff. these bugs caused
invokations of handlers that are disconnected and - worse -
destroyed already. invokation of *destroyd* handlers mean:
anything can be executed , because the handler structure can just
as well be realocated.
at the cost of an extra ->prev field per handler we should have a
reasonable stable system now, because of the various places that
can cause a handler to be disconnected (*any* handler invokation can
cause *any* or *all* handlers to be disconnected, there is no way
around a doubly linked list, actually handler disconnection has never
worked correctly because of this.
handlers are connected together via a *doubly* linked list now, and it
is *not* valid to remove a handler out of this list untill all its
references have been droped, i.e. handler->ref_count==0.
to prevent emissions of disconnected but still referenced handlers,
disconnected handlers are simply marked as blocked and get an id of 0
which is an invalid signal handler id.
the handler->id has been changed to have 28 significant bits (using
alignment gaps), since 65536 (old range: guint16) signal connections
(as a total) can easily be reached by complex applications.
this whole handler thingy is at least as tedious as writing doubly
linked list implementations ;)
1998-02-10 06:53:08 +00:00
|
|
|
static gboolean iteration_done = FALSE;
|
1997-11-28 01:22:38 +00:00
|
|
|
static guint main_level = 0;
|
|
|
|
static gint initialized = FALSE;
|
1997-12-18 02:17:14 +00:00
|
|
|
static GdkEvent *next_event = NULL;
|
|
|
|
static GList *current_events = NULL;
|
1997-11-24 22:37:52 +00:00
|
|
|
|
1998-01-19 08:23:24 +00:00
|
|
|
static GSList *grabs = NULL; /* A stack of unique grabs. The grabbing
|
|
|
|
* widget is the first one on the list.
|
1997-11-24 22:37:52 +00:00
|
|
|
*/
|
1997-11-28 01:22:38 +00:00
|
|
|
static GList *init_functions = NULL; /* A list of init functions.
|
1997-11-24 22:37:52 +00:00
|
|
|
*/
|
1997-11-28 01:22:38 +00:00
|
|
|
static GList *timeout_functions = NULL; /* A list of timeout functions sorted by
|
1997-11-24 22:37:52 +00:00
|
|
|
* when the length of the time interval
|
|
|
|
* remaining. Therefore, the first timeout
|
|
|
|
* function to expire is at the head of
|
|
|
|
* the list and the last to expire is at
|
|
|
|
* the tail of the list.
|
|
|
|
*/
|
1997-11-28 01:22:38 +00:00
|
|
|
static GList *idle_functions = NULL; /* A list of idle functions.
|
1997-11-24 22:37:52 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
static GList *current_idles = NULL;
|
|
|
|
static GList *current_timeouts = NULL;
|
|
|
|
static GMemChunk *timeout_mem_chunk = NULL;
|
|
|
|
static GMemChunk *idle_mem_chunk = NULL;
|
|
|
|
|
1998-01-18 18:17:23 +00:00
|
|
|
static GSList *key_snoopers = NULL;
|
|
|
|
|
1997-11-28 01:22:38 +00:00
|
|
|
static GdkVisual *gtk_visual; /* The visual to be used in creating new
|
1997-11-24 22:37:52 +00:00
|
|
|
* widgets.
|
|
|
|
*/
|
1997-11-28 01:22:38 +00:00
|
|
|
static GdkColormap *gtk_colormap; /* The colormap to be used in creating new
|
1997-11-24 22:37:52 +00:00
|
|
|
* widgets.
|
|
|
|
*/
|
|
|
|
|
1998-02-19 18:02:03 +00:00
|
|
|
guint gtk_debug_flags = 0; /* Global GTK debug flag */
|
1998-02-19 06:21:27 +00:00
|
|
|
|
|
|
|
#ifdef G_ENABLE_DEBUG
|
|
|
|
static GDebugKey gtk_debug_keys[] = {
|
|
|
|
{"objects", GTK_DEBUG_OBJECTS}
|
|
|
|
};
|
1998-02-19 18:02:03 +00:00
|
|
|
|
|
|
|
static const int gtk_ndebug_keys = sizeof(gtk_debug_keys)/sizeof(GDebugKey);
|
|
|
|
|
1998-02-19 06:21:27 +00:00
|
|
|
#endif /* G_ENABLE_DEBUG */
|
1997-11-24 22:37:52 +00:00
|
|
|
|
1998-02-19 18:02:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
void
|
1997-11-28 01:22:38 +00:00
|
|
|
gtk_init (int *argc,
|
1997-11-24 22:37:52 +00:00
|
|
|
char ***argv)
|
|
|
|
{
|
|
|
|
if (0)
|
|
|
|
{
|
|
|
|
g_set_error_handler (gtk_error);
|
|
|
|
g_set_warning_handler (gtk_warning);
|
|
|
|
g_set_message_handler (gtk_message);
|
|
|
|
g_set_print_handler (gtk_print);
|
|
|
|
}
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1998-02-19 06:21:27 +00:00
|
|
|
/* Initialize "gdk". We pass along the 'argc' and 'argv'
|
|
|
|
* parameters as they contain information that GDK uses
|
1997-11-24 22:37:52 +00:00
|
|
|
*/
|
|
|
|
gdk_init (argc, argv);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1998-02-19 06:21:27 +00:00
|
|
|
#ifdef G_ENABLE_DEBUG
|
1998-02-19 18:02:03 +00:00
|
|
|
{
|
|
|
|
gchar *debug_string = getenv("GTK_DEBUG");
|
|
|
|
if (debug_string != NULL)
|
|
|
|
gtk_debug_flags = g_parse_debug_string (debug_string,
|
|
|
|
gtk_debug_keys,
|
|
|
|
gtk_ndebug_keys);
|
|
|
|
}
|
|
|
|
|
1998-02-19 06:21:27 +00:00
|
|
|
if (argc && argv)
|
|
|
|
{
|
|
|
|
gint i;
|
|
|
|
|
|
|
|
for (i = 1; i < *argc;)
|
|
|
|
{
|
1998-02-19 18:02:03 +00:00
|
|
|
if ((*argv)[i] == NULL)
|
|
|
|
{
|
|
|
|
i += 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp ("--gtk-debug", (*argv)[i]) == 0)
|
1998-02-19 06:21:27 +00:00
|
|
|
{
|
|
|
|
(*argv)[i] = NULL;
|
|
|
|
|
|
|
|
if ((i + 1) < *argc && (*argv)[i + 1])
|
|
|
|
{
|
1998-02-19 18:02:03 +00:00
|
|
|
gtk_debug_flags |= g_parse_debug_string ((*argv)[i+1],
|
|
|
|
gtk_debug_keys,
|
|
|
|
gtk_ndebug_keys);
|
|
|
|
(*argv)[i + 1] = NULL;
|
|
|
|
i += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (strcmp ("--gtk-no-debug", (*argv)[i]) == 0)
|
|
|
|
{
|
|
|
|
(*argv)[i] = NULL;
|
|
|
|
|
|
|
|
if ((i + 1) < *argc && (*argv)[i + 1])
|
|
|
|
{
|
|
|
|
gtk_debug_flags &= ~g_parse_debug_string ((*argv)[i+1],
|
|
|
|
gtk_debug_keys,
|
|
|
|
gtk_ndebug_keys);
|
1998-02-19 06:21:27 +00:00
|
|
|
(*argv)[i + 1] = NULL;
|
|
|
|
i += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
i += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* G_ENABLE_DEBUG */
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
/* Initialize the default visual and colormap to be
|
|
|
|
* used in creating widgets. (We want to use the system
|
|
|
|
* defaults so as to be nice to the colormap).
|
|
|
|
*/
|
|
|
|
gtk_visual = gdk_visual_get_system ();
|
|
|
|
gtk_colormap = gdk_colormap_get_system ();
|
|
|
|
gtk_rc_init ();
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
gtk_type_init ();
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
/* Register an exit function to make sure we are able to cleanup.
|
|
|
|
*/
|
|
|
|
if (ATEXIT (gtk_exit_func))
|
|
|
|
g_warning ("unable to register exit function");
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
/* Set the 'initialized' flag.
|
|
|
|
*/
|
|
|
|
initialized = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gtk_exit (int errorcode)
|
|
|
|
{
|
|
|
|
/* Only if "gtk" has been initialized should we de-initialize.
|
|
|
|
*/
|
1997-11-28 01:22:38 +00:00
|
|
|
/* de-initialisation is done by the gtk_exit_funct(),
|
|
|
|
* no need to do this here (Alex J.)
|
|
|
|
*/
|
1997-11-24 22:37:52 +00:00
|
|
|
gdk_exit(errorcode);
|
|
|
|
}
|
|
|
|
|
|
|
|
gchar*
|
|
|
|
gtk_set_locale ()
|
|
|
|
{
|
|
|
|
return gdk_set_locale ();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gtk_main ()
|
|
|
|
{
|
|
|
|
GList *tmp_list;
|
|
|
|
GList *functions;
|
|
|
|
GtkInitFunction *init;
|
|
|
|
int old_done;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
|
|
|
main_level++;
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
tmp_list = functions = init_functions;
|
|
|
|
init_functions = NULL;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
while (tmp_list)
|
|
|
|
{
|
|
|
|
init = tmp_list->data;
|
|
|
|
tmp_list = tmp_list->next;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
(* init->function) (init->data);
|
|
|
|
g_free (init);
|
|
|
|
}
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
g_list_free (functions);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
ok, there have been several severe bugs in the signal handler referencing
Tue Feb 10 07:12:07 1998 Tim Janik <timj@gimp.org>
* gtk/gtksignal.h:
* gtk/gtksignal.c:
ok, there have been several severe bugs in the signal handler
referencing and ->next connection stuff. these bugs caused
invokations of handlers that are disconnected and - worse -
destroyed already. invokation of *destroyd* handlers mean:
anything can be executed , because the handler structure can just
as well be realocated.
at the cost of an extra ->prev field per handler we should have a
reasonable stable system now, because of the various places that
can cause a handler to be disconnected (*any* handler invokation can
cause *any* or *all* handlers to be disconnected, there is no way
around a doubly linked list, actually handler disconnection has never
worked correctly because of this.
handlers are connected together via a *doubly* linked list now, and it
is *not* valid to remove a handler out of this list untill all its
references have been droped, i.e. handler->ref_count==0.
to prevent emissions of disconnected but still referenced handlers,
disconnected handlers are simply marked as blocked and get an id of 0
which is an invalid signal handler id.
the handler->id has been changed to have 28 significant bits (using
alignment gaps), since 65536 (old range: guint16) signal connections
(as a total) can easily be reached by complex applications.
this whole handler thingy is at least as tedious as writing doubly
linked list implementations ;)
1998-02-10 06:53:08 +00:00
|
|
|
old_done = iteration_done;
|
1997-11-24 22:37:52 +00:00
|
|
|
while (!gtk_main_iteration ())
|
|
|
|
;
|
ok, there have been several severe bugs in the signal handler referencing
Tue Feb 10 07:12:07 1998 Tim Janik <timj@gimp.org>
* gtk/gtksignal.h:
* gtk/gtksignal.c:
ok, there have been several severe bugs in the signal handler
referencing and ->next connection stuff. these bugs caused
invokations of handlers that are disconnected and - worse -
destroyed already. invokation of *destroyd* handlers mean:
anything can be executed , because the handler structure can just
as well be realocated.
at the cost of an extra ->prev field per handler we should have a
reasonable stable system now, because of the various places that
can cause a handler to be disconnected (*any* handler invokation can
cause *any* or *all* handlers to be disconnected, there is no way
around a doubly linked list, actually handler disconnection has never
worked correctly because of this.
handlers are connected together via a *doubly* linked list now, and it
is *not* valid to remove a handler out of this list untill all its
references have been droped, i.e. handler->ref_count==0.
to prevent emissions of disconnected but still referenced handlers,
disconnected handlers are simply marked as blocked and get an id of 0
which is an invalid signal handler id.
the handler->id has been changed to have 28 significant bits (using
alignment gaps), since 65536 (old range: guint16) signal connections
(as a total) can easily be reached by complex applications.
this whole handler thingy is at least as tedious as writing doubly
linked list implementations ;)
1998-02-10 06:53:08 +00:00
|
|
|
iteration_done = old_done;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
|
|
|
main_level--;
|
|
|
|
}
|
|
|
|
|
|
|
|
guint
|
|
|
|
gtk_main_level (void)
|
|
|
|
{
|
|
|
|
return main_level;
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gtk_main_quit ()
|
|
|
|
{
|
ok, there have been several severe bugs in the signal handler referencing
Tue Feb 10 07:12:07 1998 Tim Janik <timj@gimp.org>
* gtk/gtksignal.h:
* gtk/gtksignal.c:
ok, there have been several severe bugs in the signal handler
referencing and ->next connection stuff. these bugs caused
invokations of handlers that are disconnected and - worse -
destroyed already. invokation of *destroyd* handlers mean:
anything can be executed , because the handler structure can just
as well be realocated.
at the cost of an extra ->prev field per handler we should have a
reasonable stable system now, because of the various places that
can cause a handler to be disconnected (*any* handler invokation can
cause *any* or *all* handlers to be disconnected, there is no way
around a doubly linked list, actually handler disconnection has never
worked correctly because of this.
handlers are connected together via a *doubly* linked list now, and it
is *not* valid to remove a handler out of this list untill all its
references have been droped, i.e. handler->ref_count==0.
to prevent emissions of disconnected but still referenced handlers,
disconnected handlers are simply marked as blocked and get an id of 0
which is an invalid signal handler id.
the handler->id has been changed to have 28 significant bits (using
alignment gaps), since 65536 (old range: guint16) signal connections
(as a total) can easily be reached by complex applications.
this whole handler thingy is at least as tedious as writing doubly
linked list implementations ;)
1998-02-10 06:53:08 +00:00
|
|
|
iteration_done = TRUE;
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
|
1998-01-17 23:24:09 +00:00
|
|
|
gint
|
|
|
|
gtk_events_pending (void)
|
|
|
|
{
|
|
|
|
return gdk_events_pending() + (next_event != NULL) ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
gtk_main_iteration ()
|
1998-01-08 04:13:13 +00:00
|
|
|
{
|
1998-01-17 23:24:09 +00:00
|
|
|
return gtk_main_iteration_do (TRUE);
|
1998-01-08 04:13:13 +00:00
|
|
|
}
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
gint
|
1998-01-08 04:13:13 +00:00
|
|
|
gtk_main_iteration_do (gboolean blocking)
|
1997-11-24 22:37:52 +00:00
|
|
|
{
|
|
|
|
GtkWidget *event_widget;
|
|
|
|
GtkWidget *grab_widget;
|
1997-12-18 02:17:14 +00:00
|
|
|
GdkEvent *event = NULL;
|
|
|
|
GList *tmp_list;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
ok, there have been several severe bugs in the signal handler referencing
Tue Feb 10 07:12:07 1998 Tim Janik <timj@gimp.org>
* gtk/gtksignal.h:
* gtk/gtksignal.c:
ok, there have been several severe bugs in the signal handler
referencing and ->next connection stuff. these bugs caused
invokations of handlers that are disconnected and - worse -
destroyed already. invokation of *destroyd* handlers mean:
anything can be executed , because the handler structure can just
as well be realocated.
at the cost of an extra ->prev field per handler we should have a
reasonable stable system now, because of the various places that
can cause a handler to be disconnected (*any* handler invokation can
cause *any* or *all* handlers to be disconnected, there is no way
around a doubly linked list, actually handler disconnection has never
worked correctly because of this.
handlers are connected together via a *doubly* linked list now, and it
is *not* valid to remove a handler out of this list untill all its
references have been droped, i.e. handler->ref_count==0.
to prevent emissions of disconnected but still referenced handlers,
disconnected handlers are simply marked as blocked and get an id of 0
which is an invalid signal handler id.
the handler->id has been changed to have 28 significant bits (using
alignment gaps), since 65536 (old range: guint16) signal connections
(as a total) can easily be reached by complex applications.
this whole handler thingy is at least as tedious as writing doubly
linked list implementations ;)
1998-02-10 06:53:08 +00:00
|
|
|
iteration_done = FALSE;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
/* If this is a recursive call, and there are pending timeouts or
|
1997-11-28 01:22:38 +00:00
|
|
|
* idles, finish them, then return immediately to avoid blocking
|
|
|
|
* in gdk_event_get()
|
|
|
|
*/
|
1997-11-24 22:37:52 +00:00
|
|
|
if (current_timeouts)
|
|
|
|
{
|
|
|
|
gtk_handle_current_timeouts( gdk_time_get());
|
ok, there have been several severe bugs in the signal handler referencing
Tue Feb 10 07:12:07 1998 Tim Janik <timj@gimp.org>
* gtk/gtksignal.h:
* gtk/gtksignal.c:
ok, there have been several severe bugs in the signal handler
referencing and ->next connection stuff. these bugs caused
invokations of handlers that are disconnected and - worse -
destroyed already. invokation of *destroyd* handlers mean:
anything can be executed , because the handler structure can just
as well be realocated.
at the cost of an extra ->prev field per handler we should have a
reasonable stable system now, because of the various places that
can cause a handler to be disconnected (*any* handler invokation can
cause *any* or *all* handlers to be disconnected, there is no way
around a doubly linked list, actually handler disconnection has never
worked correctly because of this.
handlers are connected together via a *doubly* linked list now, and it
is *not* valid to remove a handler out of this list untill all its
references have been droped, i.e. handler->ref_count==0.
to prevent emissions of disconnected but still referenced handlers,
disconnected handlers are simply marked as blocked and get an id of 0
which is an invalid signal handler id.
the handler->id has been changed to have 28 significant bits (using
alignment gaps), since 65536 (old range: guint16) signal connections
(as a total) can easily be reached by complex applications.
this whole handler thingy is at least as tedious as writing doubly
linked list implementations ;)
1998-02-10 06:53:08 +00:00
|
|
|
return iteration_done;
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
if (current_idles)
|
|
|
|
{
|
|
|
|
gtk_handle_current_idles();
|
ok, there have been several severe bugs in the signal handler referencing
Tue Feb 10 07:12:07 1998 Tim Janik <timj@gimp.org>
* gtk/gtksignal.h:
* gtk/gtksignal.c:
ok, there have been several severe bugs in the signal handler
referencing and ->next connection stuff. these bugs caused
invokations of handlers that are disconnected and - worse -
destroyed already. invokation of *destroyd* handlers mean:
anything can be executed , because the handler structure can just
as well be realocated.
at the cost of an extra ->prev field per handler we should have a
reasonable stable system now, because of the various places that
can cause a handler to be disconnected (*any* handler invokation can
cause *any* or *all* handlers to be disconnected, there is no way
around a doubly linked list, actually handler disconnection has never
worked correctly because of this.
handlers are connected together via a *doubly* linked list now, and it
is *not* valid to remove a handler out of this list untill all its
references have been droped, i.e. handler->ref_count==0.
to prevent emissions of disconnected but still referenced handlers,
disconnected handlers are simply marked as blocked and get an id of 0
which is an invalid signal handler id.
the handler->id has been changed to have 28 significant bits (using
alignment gaps), since 65536 (old range: guint16) signal connections
(as a total) can easily be reached by complex applications.
this whole handler thingy is at least as tedious as writing doubly
linked list implementations ;)
1998-02-10 06:53:08 +00:00
|
|
|
return iteration_done;
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-12-18 02:17:14 +00:00
|
|
|
/* If there is a valid event in 'next_event' then move it to 'event'
|
1997-11-24 22:37:52 +00:00
|
|
|
*/
|
1997-12-18 02:17:14 +00:00
|
|
|
if (next_event)
|
1997-11-24 22:37:52 +00:00
|
|
|
{
|
1997-12-18 02:17:14 +00:00
|
|
|
event = next_event;
|
|
|
|
next_event = NULL;
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
/* If we don't have an event then get one.
|
|
|
|
*/
|
1997-12-18 02:17:14 +00:00
|
|
|
if (!event)
|
1997-11-24 22:37:52 +00:00
|
|
|
{
|
|
|
|
/* Handle setting of the "gdk" timer. If there are no
|
|
|
|
* timeout functions, then the timer is turned off.
|
|
|
|
* If there are timeout functions, then the timer is
|
|
|
|
* set to the shortest timeout interval (which is
|
|
|
|
* the first timeout function).
|
|
|
|
*/
|
|
|
|
gtk_handle_timer ();
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1998-01-17 23:24:09 +00:00
|
|
|
if (blocking) event = gdk_event_get ();
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
/* "gdk_event_get" can return FALSE if the timer goes off
|
|
|
|
* and no events are pending. Therefore, we should make
|
|
|
|
* sure that we got an event before continuing.
|
|
|
|
*/
|
1997-12-18 02:17:14 +00:00
|
|
|
if (event)
|
1997-11-24 22:37:52 +00:00
|
|
|
{
|
|
|
|
/* If there are any events pending then get the next one.
|
|
|
|
*/
|
|
|
|
if (gdk_events_pending () > 0)
|
1997-12-18 02:17:14 +00:00
|
|
|
next_event = gdk_event_get ();
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
/* Try to compress enter/leave notify events. These event
|
|
|
|
* pairs occur when the mouse is dragged quickly across
|
|
|
|
* a window with many buttons (or through a menu). Instead
|
|
|
|
* of highlighting and de-highlighting each widget that
|
|
|
|
* is crossed it is better to simply de-highlight the widget
|
|
|
|
* which contained the mouse initially and highlight the
|
|
|
|
* widget which ends up containing the mouse.
|
|
|
|
*/
|
1997-12-18 02:17:14 +00:00
|
|
|
if (next_event)
|
|
|
|
if (((event->type == GDK_ENTER_NOTIFY) ||
|
|
|
|
(event->type == GDK_LEAVE_NOTIFY)) &&
|
|
|
|
((next_event->type == GDK_ENTER_NOTIFY) ||
|
|
|
|
(next_event->type == GDK_LEAVE_NOTIFY)) &&
|
|
|
|
(next_event->type != event->type) &&
|
|
|
|
(next_event->any.window == event->any.window))
|
|
|
|
{
|
|
|
|
gdk_event_free (event);
|
1998-01-25 18:45:56 +00:00
|
|
|
gdk_event_free (next_event);
|
|
|
|
next_event = NULL;
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
|
|
|
goto event_handling_done;
|
1997-12-18 02:17:14 +00:00
|
|
|
}
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
/* Find the widget which got the event. We store the widget
|
|
|
|
* in the user_data field of GdkWindow's.
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
* Ignore the event if we don't have a widget for it, except
|
|
|
|
* for GDK_PROPERTY_NOTIFY events which are handled specialy.
|
|
|
|
* Though this happens rarely, bogus events can occour
|
|
|
|
* for e.g. destroyed GdkWindows.
|
1997-11-24 22:37:52 +00:00
|
|
|
*/
|
1997-12-18 02:17:14 +00:00
|
|
|
event_widget = gtk_get_event_widget (event);
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
if (!event_widget)
|
|
|
|
{
|
|
|
|
/* To handle selection INCR transactions, we select
|
|
|
|
* PropertyNotify events on the requestor window and create
|
|
|
|
* a corresponding (fake) GdkWindow so that events get
|
|
|
|
* here. There won't be a widget though, so we have to handle
|
|
|
|
* them specially
|
|
|
|
*/
|
|
|
|
if (event->type == GDK_PROPERTY_NOTIFY)
|
|
|
|
gtk_selection_incr_event (event->any.window,
|
|
|
|
&event->property);
|
|
|
|
|
|
|
|
gdk_event_free (event);
|
|
|
|
|
|
|
|
goto event_handling_done;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Push the event onto a stack of current events for
|
|
|
|
* gtk_current_event_get().
|
|
|
|
*/
|
|
|
|
current_events = g_list_prepend (current_events, event);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
/* If there is a grab in effect...
|
|
|
|
*/
|
|
|
|
if (grabs)
|
|
|
|
{
|
|
|
|
grab_widget = grabs->data;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
/* If the grab widget is an ancestor of the event widget
|
|
|
|
* then we send the event to the original event widget.
|
|
|
|
* This is the key to implementing modality.
|
|
|
|
*/
|
|
|
|
if (gtk_widget_is_ancestor (event_widget, grab_widget))
|
|
|
|
grab_widget = event_widget;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
grab_widget = event_widget;
|
|
|
|
}
|
1998-02-16 22:04:52 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
/* Not all events get sent to the grabbing widget.
|
|
|
|
* The delete, destroy, expose, focus change and resize
|
|
|
|
* events still get sent to the event widget because
|
|
|
|
* 1) these events have no meaning for the grabbing widget
|
|
|
|
* and 2) redirecting these events to the grabbing widget
|
|
|
|
* could cause the display to be messed up.
|
|
|
|
*/
|
1997-12-18 02:17:14 +00:00
|
|
|
switch (event->type)
|
1997-11-24 22:37:52 +00:00
|
|
|
{
|
|
|
|
case GDK_NOTHING:
|
|
|
|
break;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
case GDK_DELETE:
|
1998-01-30 23:47:09 +00:00
|
|
|
gtk_widget_ref (event_widget);
|
1997-12-18 02:17:14 +00:00
|
|
|
if (gtk_widget_event (event_widget, event))
|
1998-01-30 23:47:09 +00:00
|
|
|
gtk_widget_destroy (event_widget);
|
|
|
|
gtk_widget_unref (event_widget);
|
1997-11-24 22:37:52 +00:00
|
|
|
break;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
case GDK_DESTROY:
|
1998-01-30 23:47:09 +00:00
|
|
|
gtk_widget_ref (event_widget);
|
1997-12-18 02:17:14 +00:00
|
|
|
gtk_widget_event (event_widget, event);
|
1998-01-25 18:45:56 +00:00
|
|
|
gtk_widget_destroy (event_widget);
|
1998-01-30 23:47:09 +00:00
|
|
|
gtk_widget_unref (event_widget);
|
1997-11-24 22:37:52 +00:00
|
|
|
break;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
case GDK_PROPERTY_NOTIFY:
|
|
|
|
case GDK_EXPOSE:
|
1998-01-02 21:38:39 +00:00
|
|
|
case GDK_NO_EXPOSE:
|
1997-11-24 22:37:52 +00:00
|
|
|
case GDK_FOCUS_CHANGE:
|
|
|
|
case GDK_CONFIGURE:
|
|
|
|
case GDK_MAP:
|
|
|
|
case GDK_UNMAP:
|
|
|
|
case GDK_SELECTION_CLEAR:
|
|
|
|
case GDK_SELECTION_REQUEST:
|
|
|
|
case GDK_SELECTION_NOTIFY:
|
|
|
|
case GDK_CLIENT_EVENT:
|
1997-12-06 22:12:10 +00:00
|
|
|
case GDK_DRAG_BEGIN:
|
|
|
|
case GDK_DRAG_REQUEST:
|
|
|
|
case GDK_DROP_ENTER:
|
|
|
|
case GDK_DROP_LEAVE:
|
|
|
|
case GDK_DROP_DATA_AVAIL:
|
1998-01-02 21:38:39 +00:00
|
|
|
case GDK_VISIBILITY_NOTIFY:
|
1997-12-18 02:17:14 +00:00
|
|
|
gtk_widget_event (event_widget, event);
|
1997-11-24 22:37:52 +00:00
|
|
|
break;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1998-01-18 18:17:23 +00:00
|
|
|
case GDK_KEY_PRESS:
|
|
|
|
case GDK_KEY_RELEASE:
|
|
|
|
if (key_snoopers)
|
|
|
|
{
|
|
|
|
if (gtk_invoke_key_snoopers (grab_widget, event))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* else fall through */
|
1997-11-24 22:37:52 +00:00
|
|
|
case GDK_MOTION_NOTIFY:
|
|
|
|
case GDK_BUTTON_PRESS:
|
|
|
|
case GDK_2BUTTON_PRESS:
|
|
|
|
case GDK_3BUTTON_PRESS:
|
|
|
|
case GDK_BUTTON_RELEASE:
|
|
|
|
case GDK_PROXIMITY_IN:
|
|
|
|
case GDK_PROXIMITY_OUT:
|
|
|
|
case GDK_OTHER_EVENT:
|
1997-12-18 02:17:14 +00:00
|
|
|
gtk_propagate_event (grab_widget, event);
|
1997-11-24 22:37:52 +00:00
|
|
|
break;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
case GDK_ENTER_NOTIFY:
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
if (GTK_WIDGET_IS_SENSITIVE (grab_widget))
|
1998-01-25 18:45:56 +00:00
|
|
|
{
|
|
|
|
gtk_widget_event (grab_widget, event);
|
|
|
|
if (event_widget == grab_widget)
|
1998-02-02 21:41:24 +00:00
|
|
|
GTK_PRIVATE_SET_FLAG (event_widget, GTK_LEAVE_PENDING);
|
1998-01-25 18:45:56 +00:00
|
|
|
}
|
|
|
|
break;
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
1998-01-25 18:45:56 +00:00
|
|
|
case GDK_LEAVE_NOTIFY:
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
if (GTK_WIDGET_LEAVE_PENDING (event_widget))
|
1998-01-25 18:45:56 +00:00
|
|
|
{
|
1998-02-02 21:41:24 +00:00
|
|
|
GTK_PRIVATE_UNSET_FLAG (event_widget, GTK_LEAVE_PENDING);
|
1998-01-25 18:45:56 +00:00
|
|
|
gtk_widget_event (event_widget, event);
|
|
|
|
}
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
else if (GTK_WIDGET_IS_SENSITIVE (grab_widget))
|
1997-12-18 02:17:14 +00:00
|
|
|
gtk_widget_event (grab_widget, event);
|
1997-11-24 22:37:52 +00:00
|
|
|
break;
|
|
|
|
}
|
1997-12-18 02:17:14 +00:00
|
|
|
|
|
|
|
tmp_list = current_events;
|
|
|
|
current_events = g_list_remove_link (current_events, tmp_list);
|
|
|
|
g_list_free_1 (tmp_list);
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
1997-12-18 02:17:14 +00:00
|
|
|
gdk_event_free (event);
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1997-11-28 01:22:38 +00:00
|
|
|
if (gdk_events_pending() == 0)
|
|
|
|
gtk_handle_idle ();
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
1997-11-28 01:22:38 +00:00
|
|
|
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
event_handling_done:
|
|
|
|
|
|
|
|
/* Handle timeout functions that may have expired.
|
1997-11-24 22:37:52 +00:00
|
|
|
*/
|
|
|
|
gtk_handle_timeouts ();
|
1997-11-28 01:22:38 +00:00
|
|
|
|
ok, there have been several severe bugs in the signal handler referencing
Tue Feb 10 07:12:07 1998 Tim Janik <timj@gimp.org>
* gtk/gtksignal.h:
* gtk/gtksignal.c:
ok, there have been several severe bugs in the signal handler
referencing and ->next connection stuff. these bugs caused
invokations of handlers that are disconnected and - worse -
destroyed already. invokation of *destroyd* handlers mean:
anything can be executed , because the handler structure can just
as well be realocated.
at the cost of an extra ->prev field per handler we should have a
reasonable stable system now, because of the various places that
can cause a handler to be disconnected (*any* handler invokation can
cause *any* or *all* handlers to be disconnected, there is no way
around a doubly linked list, actually handler disconnection has never
worked correctly because of this.
handlers are connected together via a *doubly* linked list now, and it
is *not* valid to remove a handler out of this list untill all its
references have been droped, i.e. handler->ref_count==0.
to prevent emissions of disconnected but still referenced handlers,
disconnected handlers are simply marked as blocked and get an id of 0
which is an invalid signal handler id.
the handler->id has been changed to have 28 significant bits (using
alignment gaps), since 65536 (old range: guint16) signal connections
(as a total) can easily be reached by complex applications.
this whole handler thingy is at least as tedious as writing doubly
linked list implementations ;)
1998-02-10 06:53:08 +00:00
|
|
|
return iteration_done;
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
gtk_true (void)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
gtk_false (void)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gtk_grab_add (GtkWidget *widget)
|
|
|
|
{
|
1998-01-19 08:23:24 +00:00
|
|
|
g_return_if_fail (widget != NULL);
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
1998-01-30 23:47:09 +00:00
|
|
|
if (!GTK_WIDGET_HAS_GRAB (widget))
|
1998-01-19 08:23:24 +00:00
|
|
|
{
|
|
|
|
GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_GRAB);
|
1998-01-30 23:47:09 +00:00
|
|
|
|
1998-01-19 08:23:24 +00:00
|
|
|
grabs = g_slist_prepend (grabs, widget);
|
1998-01-30 23:47:09 +00:00
|
|
|
gtk_widget_ref (widget);
|
1998-01-19 08:23:24 +00:00
|
|
|
}
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
|
1998-02-17 06:03:40 +00:00
|
|
|
GtkWidget*
|
|
|
|
gtk_grab_get_current (void)
|
|
|
|
{
|
|
|
|
if (grabs)
|
|
|
|
return GTK_WIDGET (grabs->data);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
void
|
|
|
|
gtk_grab_remove (GtkWidget *widget)
|
|
|
|
{
|
1998-01-19 08:23:24 +00:00
|
|
|
g_return_if_fail (widget != NULL);
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
1998-01-19 08:23:24 +00:00
|
|
|
if (GTK_WIDGET_HAS_GRAB (widget))
|
|
|
|
{
|
|
|
|
GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_GRAB);
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
1998-01-19 08:23:24 +00:00
|
|
|
grabs = g_slist_remove (grabs, widget);
|
1998-01-30 23:47:09 +00:00
|
|
|
gtk_widget_unref (widget);
|
1998-01-19 08:23:24 +00:00
|
|
|
}
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gtk_init_add (GtkFunction function,
|
1997-11-28 01:22:38 +00:00
|
|
|
gpointer data)
|
1997-11-24 22:37:52 +00:00
|
|
|
{
|
|
|
|
GtkInitFunction *init;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
init = g_new (GtkInitFunction, 1);
|
|
|
|
init->function = function;
|
|
|
|
init->data = data;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
init_functions = g_list_prepend (init_functions, init);
|
|
|
|
}
|
|
|
|
|
1998-01-18 18:17:23 +00:00
|
|
|
gint
|
|
|
|
gtk_key_snooper_install (GtkKeySnoopFunc snooper,
|
|
|
|
gpointer func_data)
|
|
|
|
{
|
|
|
|
GtkKeySnooperData *data;
|
|
|
|
static guint snooper_id = 1;
|
|
|
|
|
|
|
|
g_return_val_if_fail (snooper != NULL, 0);
|
|
|
|
|
|
|
|
data = g_new (GtkKeySnooperData, 1);
|
|
|
|
data->func = snooper;
|
|
|
|
data->func_data = func_data;
|
|
|
|
data->id = snooper_id++;
|
|
|
|
key_snoopers = g_slist_prepend (key_snoopers, data);
|
|
|
|
|
|
|
|
return data->id;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gtk_key_snooper_remove (gint snooper_id)
|
|
|
|
{
|
|
|
|
GtkKeySnooperData *data = NULL;
|
|
|
|
GSList *slist;
|
|
|
|
|
|
|
|
slist = key_snoopers;
|
|
|
|
while (slist)
|
|
|
|
{
|
|
|
|
data = slist->data;
|
|
|
|
if (data->id == snooper_id)
|
|
|
|
break;
|
|
|
|
|
|
|
|
slist = slist->next;
|
|
|
|
data = NULL;
|
|
|
|
}
|
|
|
|
if (data)
|
|
|
|
key_snoopers = g_slist_remove (key_snoopers, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
gtk_invoke_key_snoopers (GtkWidget *grab_widget,
|
|
|
|
GdkEvent *event)
|
|
|
|
{
|
|
|
|
GSList *slist;
|
|
|
|
gint return_val = FALSE;
|
|
|
|
|
|
|
|
slist = key_snoopers;
|
|
|
|
while (slist && !return_val)
|
|
|
|
{
|
|
|
|
GtkKeySnooperData *data;
|
|
|
|
|
|
|
|
data = slist->data;
|
|
|
|
slist = slist->next;
|
|
|
|
return_val = (*data->func) (grab_widget, (GdkEventKey*) event, data->func_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
return return_val;
|
|
|
|
}
|
|
|
|
|
1998-02-13 05:19:06 +00:00
|
|
|
gint
|
|
|
|
gtk_timeout_add_full (guint32 interval,
|
|
|
|
GtkFunction function,
|
|
|
|
GtkCallbackMarshal marshal,
|
|
|
|
gpointer data,
|
|
|
|
GtkDestroyNotify destroy)
|
1997-11-24 22:37:52 +00:00
|
|
|
{
|
|
|
|
static gint timeout_tag = 1;
|
|
|
|
GtkTimeoutFunction *timeoutf;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1998-02-13 05:19:06 +00:00
|
|
|
g_return_val_if_fail ((function != NULL) || (marshal != NULL), 0);
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
/* Create a new timeout function structure.
|
|
|
|
* The start time is the current time.
|
|
|
|
*/
|
|
|
|
if (!timeout_mem_chunk)
|
|
|
|
timeout_mem_chunk = g_mem_chunk_new ("timeout mem chunk", sizeof (GtkTimeoutFunction),
|
|
|
|
1024, G_ALLOC_AND_FREE);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
timeoutf = g_chunk_new (GtkTimeoutFunction, timeout_mem_chunk);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
timeoutf->tag = timeout_tag++;
|
|
|
|
timeoutf->start = gdk_time_get ();
|
|
|
|
timeoutf->interval = interval;
|
|
|
|
timeoutf->originterval = interval;
|
|
|
|
timeoutf->function = function;
|
1998-02-13 05:19:06 +00:00
|
|
|
timeoutf->marshal = marshal;
|
1997-11-24 22:37:52 +00:00
|
|
|
timeoutf->data = data;
|
|
|
|
timeoutf->destroy = destroy;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
gtk_timeout_insert (timeoutf);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
return timeoutf->tag;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_timeout_destroy (GtkTimeoutFunction *timeoutf)
|
|
|
|
{
|
|
|
|
if (timeoutf->destroy)
|
|
|
|
(timeoutf->destroy) (timeoutf->data);
|
|
|
|
g_mem_chunk_free (timeout_mem_chunk, timeoutf);
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
gtk_timeout_add (guint32 interval,
|
|
|
|
GtkFunction function,
|
|
|
|
gpointer data)
|
|
|
|
{
|
1998-02-13 05:19:06 +00:00
|
|
|
return gtk_timeout_add_full (interval, function, FALSE, data, NULL);
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
1997-11-28 01:22:38 +00:00
|
|
|
gtk_timeout_add_interp (guint32 interval,
|
1997-11-24 22:37:52 +00:00
|
|
|
GtkCallbackMarshal function,
|
1997-11-28 01:22:38 +00:00
|
|
|
gpointer data,
|
1997-11-24 22:37:52 +00:00
|
|
|
GtkDestroyNotify destroy)
|
|
|
|
{
|
1998-02-13 05:19:06 +00:00
|
|
|
return gtk_timeout_add_full (interval, NULL, function, data, destroy);
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gtk_timeout_remove (gint tag)
|
|
|
|
{
|
|
|
|
GtkTimeoutFunction *timeoutf;
|
|
|
|
GList *tmp_list;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
/* Remove a timeout function.
|
|
|
|
* (Which, basically, involves searching the
|
|
|
|
* list for the tag).
|
|
|
|
*/
|
|
|
|
tmp_list = timeout_functions;
|
|
|
|
while (tmp_list)
|
|
|
|
{
|
|
|
|
timeoutf = tmp_list->data;
|
|
|
|
|
|
|
|
if (timeoutf->tag == tag)
|
|
|
|
{
|
|
|
|
timeout_functions = g_list_remove_link (timeout_functions, tmp_list);
|
|
|
|
g_list_free (tmp_list);
|
|
|
|
gtk_timeout_destroy (timeoutf);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp_list = tmp_list->next;
|
|
|
|
}
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
tmp_list = current_timeouts;
|
|
|
|
while (tmp_list)
|
|
|
|
{
|
|
|
|
timeoutf = tmp_list->data;
|
|
|
|
|
|
|
|
if (timeoutf->tag == tag)
|
|
|
|
{
|
|
|
|
current_timeouts = g_list_remove_link (current_timeouts, tmp_list);
|
|
|
|
g_list_free (tmp_list);
|
|
|
|
gtk_timeout_destroy (timeoutf);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp_list = tmp_list->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-02-17 04:39:47 +00:00
|
|
|
/* We rely on some knowledge of how g_list_insert_sorted works to make
|
|
|
|
* sure that we insert at the _end_ of the idles of this priority
|
|
|
|
*/
|
|
|
|
static gint
|
|
|
|
gtk_idle_compare (gpointer a, gpointer b)
|
|
|
|
{
|
|
|
|
return (((GtkIdleFunction *)a)->priority < ((GtkIdleFunction *)b)->priority)
|
|
|
|
? -1 : 1;
|
|
|
|
}
|
|
|
|
|
1998-02-13 05:19:06 +00:00
|
|
|
gint
|
|
|
|
gtk_idle_add_full (gint priority,
|
|
|
|
GtkFunction function,
|
|
|
|
GtkCallbackMarshal marshal,
|
|
|
|
gpointer data,
|
|
|
|
GtkDestroyNotify destroy)
|
1997-11-24 22:37:52 +00:00
|
|
|
{
|
|
|
|
static gint idle_tag = 1;
|
1998-02-17 04:39:47 +00:00
|
|
|
GtkIdleFunction *idlef;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1998-02-13 05:19:06 +00:00
|
|
|
g_return_val_if_fail ((function != NULL) || (marshal != NULL), 0);
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
if (!idle_mem_chunk)
|
|
|
|
idle_mem_chunk = g_mem_chunk_new ("idle mem chunk", sizeof (GtkIdleFunction),
|
|
|
|
1024, G_ALLOC_AND_FREE);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
idlef = g_chunk_new (GtkIdleFunction, idle_mem_chunk);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
idlef->tag = idle_tag++;
|
1998-02-13 05:19:06 +00:00
|
|
|
idlef->priority = priority;
|
1997-11-24 22:37:52 +00:00
|
|
|
idlef->function = function;
|
1998-02-13 05:19:06 +00:00
|
|
|
idlef->marshal = marshal;
|
1997-11-24 22:37:52 +00:00
|
|
|
idlef->data = data;
|
|
|
|
idlef->destroy = destroy;
|
1998-02-13 05:19:06 +00:00
|
|
|
|
1998-02-17 04:39:47 +00:00
|
|
|
idle_functions = g_list_insert_sorted (idle_functions, idlef, gtk_idle_compare);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
return idlef->tag;
|
|
|
|
}
|
|
|
|
|
1998-02-13 05:19:06 +00:00
|
|
|
gint
|
|
|
|
gtk_idle_add_interp (GtkCallbackMarshal marshal,
|
|
|
|
gpointer data,
|
|
|
|
GtkDestroyNotify destroy)
|
|
|
|
{
|
|
|
|
return gtk_idle_add_full (GTK_PRIORITY_DEFAULT, NULL, marshal, data, destroy);
|
|
|
|
}
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
static void
|
|
|
|
gtk_idle_destroy (GtkIdleFunction *idlef)
|
|
|
|
{
|
|
|
|
if (idlef->destroy)
|
|
|
|
idlef->destroy (idlef->data);
|
|
|
|
g_mem_chunk_free (idle_mem_chunk, idlef);
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
gtk_idle_add (GtkFunction function,
|
1997-11-28 01:22:38 +00:00
|
|
|
gpointer data)
|
1997-11-24 22:37:52 +00:00
|
|
|
{
|
1998-02-13 05:19:06 +00:00
|
|
|
return gtk_idle_add_full (GTK_PRIORITY_DEFAULT, function, NULL, data, NULL);
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
|
1998-02-13 05:19:06 +00:00
|
|
|
gint
|
|
|
|
gtk_idle_add_priority (gint priority,
|
|
|
|
GtkFunction function,
|
|
|
|
gpointer data)
|
1997-11-24 22:37:52 +00:00
|
|
|
{
|
1998-02-13 05:19:06 +00:00
|
|
|
return gtk_idle_add_full (priority, function, NULL, data, NULL);
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gtk_idle_remove (gint tag)
|
|
|
|
{
|
|
|
|
GtkIdleFunction *idlef;
|
|
|
|
GList *tmp_list;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
tmp_list = idle_functions;
|
|
|
|
while (tmp_list)
|
|
|
|
{
|
|
|
|
idlef = tmp_list->data;
|
|
|
|
|
|
|
|
if (idlef->tag == tag)
|
|
|
|
{
|
|
|
|
idle_functions = g_list_remove_link (idle_functions, tmp_list);
|
|
|
|
g_list_free (tmp_list);
|
|
|
|
gtk_idle_destroy (idlef);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp_list = tmp_list->next;
|
|
|
|
}
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
tmp_list = current_idles;
|
|
|
|
while (tmp_list)
|
|
|
|
{
|
|
|
|
idlef = tmp_list->data;
|
|
|
|
|
|
|
|
if (idlef->tag == tag)
|
|
|
|
{
|
|
|
|
current_idles = g_list_remove_link (current_idles, tmp_list);
|
|
|
|
g_list_free (tmp_list);
|
|
|
|
gtk_idle_destroy (idlef);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp_list = tmp_list->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gtk_idle_remove_by_data (gpointer data)
|
|
|
|
{
|
|
|
|
GtkIdleFunction *idlef;
|
|
|
|
GList *tmp_list;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
tmp_list = idle_functions;
|
|
|
|
while (tmp_list)
|
|
|
|
{
|
|
|
|
idlef = tmp_list->data;
|
|
|
|
|
|
|
|
if (idlef->data == data)
|
|
|
|
{
|
|
|
|
idle_functions = g_list_remove_link (idle_functions, tmp_list);
|
|
|
|
g_list_free (tmp_list);
|
|
|
|
g_mem_chunk_free (idle_mem_chunk, idlef);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp_list = tmp_list->next;
|
|
|
|
}
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
tmp_list = current_idles;
|
|
|
|
while (tmp_list)
|
|
|
|
{
|
|
|
|
idlef = tmp_list->data;
|
|
|
|
|
|
|
|
if (idlef->data == data)
|
|
|
|
{
|
|
|
|
current_idles = g_list_remove_link (current_idles, tmp_list);
|
|
|
|
g_list_free (tmp_list);
|
|
|
|
g_mem_chunk_free (idle_mem_chunk, idlef);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp_list = tmp_list->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1997-12-18 02:17:14 +00:00
|
|
|
static void
|
|
|
|
gtk_invoke_input_function (GtkInputFunction *input,
|
|
|
|
gint source,
|
|
|
|
GdkInputCondition condition)
|
|
|
|
{
|
|
|
|
GtkArg args[3];
|
|
|
|
args[0].type = GTK_TYPE_INT;
|
|
|
|
args[0].name = NULL;
|
|
|
|
GTK_VALUE_INT(args[0]) = source;
|
|
|
|
args[1].type = GTK_TYPE_GDK_INPUT_CONDITION;
|
|
|
|
args[1].name = NULL;
|
|
|
|
GTK_VALUE_FLAGS(args[1]) = condition;
|
|
|
|
args[2].type = GTK_TYPE_NONE;
|
|
|
|
args[2].name = NULL;
|
|
|
|
|
|
|
|
input->callback (NULL, input->data, 2, args);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_destroy_input_function (GtkInputFunction *input)
|
|
|
|
{
|
|
|
|
if (input->destroy)
|
|
|
|
(input->destroy) (input->data);
|
|
|
|
g_free (input);
|
|
|
|
}
|
|
|
|
|
1998-02-13 05:19:06 +00:00
|
|
|
gint
|
|
|
|
gtk_input_add_full (gint source,
|
|
|
|
GdkInputCondition condition,
|
|
|
|
GdkInputFunction function,
|
|
|
|
GtkCallbackMarshal marshal,
|
|
|
|
gpointer data,
|
|
|
|
GtkDestroyNotify destroy)
|
|
|
|
{
|
|
|
|
if (marshal)
|
|
|
|
{
|
|
|
|
GtkInputFunction *input = g_new (GtkInputFunction, 1);
|
|
|
|
input->callback = marshal;
|
|
|
|
input->data = data;
|
|
|
|
input->destroy = destroy;
|
|
|
|
|
1998-02-17 04:39:47 +00:00
|
|
|
return gdk_input_add_full (source,
|
|
|
|
condition,
|
|
|
|
(GdkInputFunction) gtk_invoke_input_function,
|
|
|
|
input,
|
|
|
|
(GdkDestroyNotify) gtk_destroy_input_function);
|
1998-02-13 05:19:06 +00:00
|
|
|
}
|
|
|
|
else
|
1998-02-17 04:39:47 +00:00
|
|
|
return gdk_input_add_full (source, condition, function, data, destroy);
|
1998-02-13 05:19:06 +00:00
|
|
|
}
|
|
|
|
|
1997-12-18 02:17:14 +00:00
|
|
|
gint
|
|
|
|
gtk_input_add_interp (gint source,
|
|
|
|
GdkInputCondition condition,
|
|
|
|
GtkCallbackMarshal callback,
|
|
|
|
gpointer data,
|
|
|
|
GtkDestroyNotify destroy)
|
|
|
|
{
|
1998-02-14 05:37:53 +00:00
|
|
|
return gdk_input_add_full (source, condition, NULL, callback, data);
|
1997-12-18 02:17:14 +00:00
|
|
|
}
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
void
|
1997-12-18 02:17:14 +00:00
|
|
|
gtk_input_remove (gint tag)
|
1997-11-24 22:37:52 +00:00
|
|
|
{
|
1997-12-18 02:17:14 +00:00
|
|
|
gdk_input_remove (tag);
|
|
|
|
}
|
|
|
|
|
|
|
|
GdkEvent *
|
|
|
|
gtk_get_current_event ()
|
|
|
|
{
|
|
|
|
if (current_events)
|
1998-01-30 01:34:19 +00:00
|
|
|
return gdk_event_copy ((GdkEvent *) current_events->data);
|
1997-12-18 02:17:14 +00:00
|
|
|
else
|
|
|
|
return NULL;
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GtkWidget*
|
|
|
|
gtk_get_event_widget (GdkEvent *event)
|
|
|
|
{
|
|
|
|
GtkWidget *widget;
|
1998-01-30 23:47:09 +00:00
|
|
|
|
|
|
|
widget = NULL;
|
|
|
|
if (event->any.window)
|
|
|
|
gdk_window_get_user_data (event->any.window, (void**) &widget);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
return widget;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_exit_func ()
|
|
|
|
{
|
|
|
|
if (initialized)
|
|
|
|
{
|
|
|
|
initialized = FALSE;
|
|
|
|
gtk_preview_uninit ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-02-17 04:39:47 +00:00
|
|
|
|
|
|
|
/* We rely on some knowledge of how g_list_insert_sorted works to make
|
|
|
|
* sure that we insert after timeouts of equal interval
|
|
|
|
*/
|
|
|
|
static gint
|
|
|
|
gtk_timeout_compare (gpointer a, gpointer b)
|
|
|
|
{
|
|
|
|
return (((GtkTimeoutFunction *)a)->interval <
|
|
|
|
((GtkTimeoutFunction *)b)->interval)
|
|
|
|
? -1 : 1;
|
|
|
|
}
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
static void
|
|
|
|
gtk_timeout_insert (GtkTimeoutFunction *timeoutf)
|
|
|
|
{
|
|
|
|
g_assert (timeoutf != NULL);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
/* Insert the timeout function appropriately.
|
|
|
|
* Appropriately meaning sort it into the list
|
|
|
|
* of timeout functions.
|
|
|
|
*/
|
1998-02-17 04:39:47 +00:00
|
|
|
timeout_functions = g_list_insert_sorted (timeout_functions, timeoutf,
|
|
|
|
gtk_timeout_compare);
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
gtk_invoke_timeout_function (GtkTimeoutFunction *timeoutf)
|
|
|
|
{
|
1998-02-13 05:19:06 +00:00
|
|
|
if (!timeoutf->marshal)
|
1997-11-24 22:37:52 +00:00
|
|
|
return timeoutf->function (timeoutf->data);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GtkArg args[1];
|
|
|
|
gint ret_val = FALSE;
|
|
|
|
args[0].name = NULL;
|
|
|
|
args[0].type = GTK_TYPE_BOOL;
|
|
|
|
args[0].d.pointer_data = &ret_val;
|
|
|
|
((GtkCallbackMarshal)timeoutf->function) (NULL,
|
|
|
|
timeoutf->data,
|
|
|
|
0, args);
|
|
|
|
return ret_val;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_handle_current_timeouts (guint32 the_time)
|
|
|
|
{
|
|
|
|
GList *tmp_list;
|
|
|
|
GtkTimeoutFunction *timeoutf;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
while (current_timeouts)
|
|
|
|
{
|
|
|
|
tmp_list = current_timeouts;
|
|
|
|
timeoutf = tmp_list->data;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
current_timeouts = g_list_remove_link (current_timeouts, tmp_list);
|
|
|
|
g_list_free (tmp_list);
|
|
|
|
|
|
|
|
if (gtk_invoke_timeout_function (timeoutf) == FALSE)
|
|
|
|
{
|
|
|
|
gtk_timeout_destroy (timeoutf);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
timeoutf->interval = timeoutf->originterval;
|
|
|
|
timeoutf->start = the_time;
|
|
|
|
gtk_timeout_insert (timeoutf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_handle_timeouts ()
|
|
|
|
{
|
|
|
|
guint32 the_time;
|
|
|
|
GList *tmp_list;
|
|
|
|
GList *tmp_list2;
|
|
|
|
GtkTimeoutFunction *timeoutf;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
/* Caller must already have called gtk_handle_current_timeouts if
|
|
|
|
* necessary */
|
|
|
|
g_assert (current_timeouts == NULL);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
if (timeout_functions)
|
|
|
|
{
|
|
|
|
the_time = gdk_time_get ();
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
tmp_list = timeout_functions;
|
|
|
|
while (tmp_list)
|
|
|
|
{
|
|
|
|
timeoutf = tmp_list->data;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
if (timeoutf->interval <= (the_time - timeoutf->start))
|
|
|
|
{
|
|
|
|
tmp_list2 = tmp_list;
|
|
|
|
tmp_list = tmp_list->next;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
timeout_functions = g_list_remove_link (timeout_functions, tmp_list2);
|
1997-11-26 01:52:50 +00:00
|
|
|
current_timeouts = g_list_concat (current_timeouts, tmp_list2);
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
timeoutf->interval -= (the_time - timeoutf->start);
|
|
|
|
timeoutf->start = the_time;
|
|
|
|
tmp_list = tmp_list->next;
|
|
|
|
}
|
|
|
|
}
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
if (current_timeouts)
|
|
|
|
gtk_handle_current_timeouts(the_time);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
gtk_idle_invoke_function (GtkIdleFunction *idlef)
|
|
|
|
{
|
1998-02-13 05:19:06 +00:00
|
|
|
if (!idlef->marshal)
|
1997-11-24 22:37:52 +00:00
|
|
|
return idlef->function (idlef->data);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GtkArg args[1];
|
|
|
|
gint ret_val = FALSE;
|
|
|
|
args[0].name = NULL;
|
|
|
|
args[0].type = GTK_TYPE_BOOL;
|
|
|
|
args[0].d.pointer_data = &ret_val;
|
1998-02-13 05:19:06 +00:00
|
|
|
((GtkCallbackMarshal)idlef->marshal) (NULL,
|
|
|
|
idlef->data,
|
|
|
|
0, args);
|
1997-11-24 22:37:52 +00:00
|
|
|
return ret_val;
|
|
|
|
}
|
|
|
|
}
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
static void
|
|
|
|
gtk_handle_current_idles ()
|
|
|
|
{
|
|
|
|
GList *tmp_list;
|
1998-02-13 05:19:06 +00:00
|
|
|
GList *tmp_list2;
|
1997-11-24 22:37:52 +00:00
|
|
|
GtkIdleFunction *idlef;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
while (current_idles)
|
|
|
|
{
|
|
|
|
tmp_list = current_idles;
|
|
|
|
idlef = tmp_list->data;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
current_idles = g_list_remove_link (current_idles, tmp_list);
|
|
|
|
|
|
|
|
if (gtk_idle_invoke_function (idlef) == FALSE)
|
|
|
|
{
|
|
|
|
g_list_free (tmp_list);
|
|
|
|
gtk_idle_destroy (idlef);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1998-02-13 05:19:06 +00:00
|
|
|
/* Insert the idle function back into the list of idle
|
|
|
|
* functions at the end of the idles of this priority
|
|
|
|
*/
|
|
|
|
tmp_list2 = idle_functions;
|
|
|
|
while (tmp_list2 &&
|
|
|
|
(((GtkIdleFunction *)tmp_list2->data)->priority <= idlef->priority))
|
|
|
|
tmp_list2 = tmp_list2->next;
|
|
|
|
|
|
|
|
if (!tmp_list2)
|
|
|
|
idle_functions = g_list_concat (idle_functions, tmp_list);
|
|
|
|
else if (tmp_list2 == idle_functions)
|
|
|
|
{
|
|
|
|
tmp_list->next = idle_functions;
|
|
|
|
if (idle_functions)
|
|
|
|
idle_functions->prev = tmp_list;
|
|
|
|
idle_functions = tmp_list;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tmp_list->prev = tmp_list2->prev;
|
|
|
|
tmp_list->next = tmp_list2;
|
|
|
|
tmp_list2->prev->next = tmp_list;
|
|
|
|
tmp_list2->prev = tmp_list;
|
|
|
|
}
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_handle_idle ()
|
|
|
|
{
|
|
|
|
/* Caller must already have called gtk_handle_current_idles if
|
1997-12-10 22:43:24 +00:00
|
|
|
* necessary
|
|
|
|
*/
|
1997-11-24 22:37:52 +00:00
|
|
|
g_assert (current_idles == NULL);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1998-02-13 05:19:06 +00:00
|
|
|
/* Handle only the idle functions that have the highest priority */
|
1997-11-24 22:37:52 +00:00
|
|
|
if (idle_functions)
|
|
|
|
{
|
1998-02-13 05:19:06 +00:00
|
|
|
GList *tmp_list;
|
|
|
|
gint top_priority;
|
|
|
|
|
|
|
|
tmp_list = idle_functions;
|
|
|
|
top_priority = ((GtkIdleFunction *)tmp_list->data)->priority;
|
|
|
|
|
|
|
|
while (tmp_list &&
|
|
|
|
(((GtkIdleFunction *)tmp_list->data)->priority == top_priority))
|
|
|
|
tmp_list = tmp_list->next;
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
current_idles = idle_functions;
|
1998-02-13 05:19:06 +00:00
|
|
|
idle_functions = tmp_list;
|
|
|
|
|
|
|
|
if (tmp_list)
|
|
|
|
{
|
|
|
|
tmp_list->prev->next = NULL;
|
|
|
|
tmp_list->prev = NULL;
|
|
|
|
}
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
gtk_handle_current_idles();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_handle_timer ()
|
|
|
|
{
|
|
|
|
GtkTimeoutFunction *timeoutf;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
if (idle_functions)
|
|
|
|
{
|
|
|
|
gdk_timer_set (0);
|
|
|
|
gdk_timer_enable ();
|
|
|
|
}
|
|
|
|
else if (timeout_functions)
|
|
|
|
{
|
|
|
|
timeoutf = timeout_functions->data;
|
|
|
|
gdk_timer_set (timeoutf->interval);
|
|
|
|
gdk_timer_enable ();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gdk_timer_set (0);
|
|
|
|
gdk_timer_disable ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_propagate_event (GtkWidget *widget,
|
|
|
|
GdkEvent *event)
|
|
|
|
{
|
|
|
|
GtkWidget *parent;
|
1998-02-02 18:44:28 +00:00
|
|
|
GtkWidget *tmp;
|
1997-11-24 22:37:52 +00:00
|
|
|
gint handled_event;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
g_return_if_fail (widget != NULL);
|
|
|
|
g_return_if_fail (event != NULL);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
handled_event = FALSE;
|
1998-02-02 18:44:28 +00:00
|
|
|
gtk_widget_ref (widget);
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
if ((event->type == GDK_KEY_PRESS) ||
|
|
|
|
(event->type == GDK_KEY_RELEASE))
|
|
|
|
{
|
1998-02-02 18:44:28 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
/* Only send key events to window widgets.
|
|
|
|
* The window widget will in turn pass the
|
|
|
|
* key event on to the currently focused widget
|
|
|
|
* for that window.
|
|
|
|
*/
|
|
|
|
parent = gtk_widget_get_ancestor (widget, gtk_window_get_type ());
|
1998-02-02 18:44:28 +00:00
|
|
|
handled_event = (parent &&
|
|
|
|
GTK_WIDGET_IS_SENSITIVE (parent) &&
|
|
|
|
gtk_widget_event (parent, event));
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1998-01-30 23:47:09 +00:00
|
|
|
/* Other events get propagated up the widget tree
|
|
|
|
* so that parents can see the button and motion
|
|
|
|
* events of the children.
|
|
|
|
*/
|
1998-02-02 18:44:28 +00:00
|
|
|
tmp = widget;
|
|
|
|
while (!handled_event && tmp)
|
1997-11-24 22:37:52 +00:00
|
|
|
{
|
1998-02-02 18:44:28 +00:00
|
|
|
gtk_widget_ref (tmp);
|
1998-02-03 14:13:05 +00:00
|
|
|
handled_event = !GTK_WIDGET_IS_SENSITIVE (tmp) || gtk_widget_event (tmp, event);
|
1998-02-02 18:44:28 +00:00
|
|
|
parent = tmp->parent;
|
|
|
|
gtk_widget_unref (tmp);
|
|
|
|
tmp = parent;
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
1998-02-02 18:44:28 +00:00
|
|
|
|
|
|
|
gtk_widget_unref (widget);
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
1997-11-28 01:22:38 +00:00
|
|
|
gtk_error (gchar *str)
|
1997-11-24 22:37:52 +00:00
|
|
|
{
|
|
|
|
gtk_print (str);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1997-11-28 01:22:38 +00:00
|
|
|
gtk_warning (gchar *str)
|
1997-11-24 22:37:52 +00:00
|
|
|
{
|
|
|
|
gtk_print (str);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1997-11-28 01:22:38 +00:00
|
|
|
gtk_message (gchar *str)
|
1997-11-24 22:37:52 +00:00
|
|
|
{
|
|
|
|
gtk_print (str);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1997-11-28 01:22:38 +00:00
|
|
|
gtk_print (gchar *str)
|
1997-11-24 22:37:52 +00:00
|
|
|
{
|
|
|
|
static GtkWidget *window = NULL;
|
|
|
|
static GtkWidget *text;
|
|
|
|
static int level = 0;
|
|
|
|
GtkWidget *box1;
|
|
|
|
GtkWidget *box2;
|
|
|
|
GtkWidget *table;
|
|
|
|
GtkWidget *hscrollbar;
|
|
|
|
GtkWidget *vscrollbar;
|
|
|
|
GtkWidget *separator;
|
|
|
|
GtkWidget *button;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
if (level > 0)
|
|
|
|
{
|
|
|
|
fputs (str, stdout);
|
|
|
|
fflush (stdout);
|
|
|
|
return;
|
|
|
|
}
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
if (!window)
|
|
|
|
{
|
|
|
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
GTK_RESIZE_NEEDED is a private flag now.
Mon Feb 2 04:15:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtkcontainer.h:
* gtk/gtkcontainer.c: GTK_RESIZE_NEEDED is a private flag now.
(gtk_container_register_toplevel): new function.
(gtk_container_unregister_toplevel): new function.
* gtk/gtkmain.c: GTK_LEAVE_PENDING is a private flag now.
* gtk/gtkmenu.c: call gtk_container_register_toplevel in
gtk_menu_class_init instead of this dirty gtk_widget_set_parent(,NULL)
hack. new default handler gtk_menu_destroy for calling
gtk_container_unregister_toplevel. removed GTK_ANCHORED, GTK_UNMAPPED.
* gtk/gtkobject.h: macro cleanups, added GTK_DESTROYED flag.
* gtk/gtkobject.c: only emit DESTROY signal if !GTK_OBJECT_DESTROYED
(object).
* gtk/gtkprivate.h: new file that will not be automatically included.
it holds the private flags for GtkWidget along with it's SET/UNSET
and examination macros.
* gtk/gtkwidget.c: private flags: GTK_RESIZE_NEEDED, GTK_REDRAW_PENDING,
GTK_RESIZE_PENDING, GTK_IN_REPARENT, GTK_USER_STYLE. GTK_ANCHORED is
replaced by GTK_TOPLEVEL. added missing UNSET for GTK_IN_REPARENT.
removed the gtk_widget_set_parent(, NULL) hack for toplevels.
upon destroy free memory for widgets with GTK_WIDGET_HAS_SHAPE_MASK.
* gtk/gtkwidget.h: split up the widget flags into a public and a private
portion. added an extra field private_flags to GtkWidget without making
it bigger by using an alignment gap of 16 bit. macro cleanups.
* gtk/gtkwindow.c: removed GTK_ANCHORED. new function gtk_window_destroy
for calling gtk_container_unregister_toplevel. removed the
gtk_widget_set_parent(,NULL), call gtk_container_register_toplevel
instead. remove GTK_UNMAPPED. GTK_RESIZE_NEEDED is private now.
* gtk/gtksignal.c (gtk_signal_disconnect): removed a bug on
removal that cut off the handler list -> living_objects == 0
with testgtk. made some warnings more descriptive.
new function gtk_signal_connect_object_while_alive, which
will automatically destroy the connection once one of the objects
is destroyed. didn't include this before removal of the above
mentioned bug.
* reflected refcounting revolution in ChangeLog
1998-02-02 04:54:25 +00:00
|
|
|
|
|
|
|
gtk_signal_connect (GTK_OBJECT (window), "destroy",
|
|
|
|
(GtkSignalFunc) gtk_widget_destroyed,
|
|
|
|
&window);
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
gtk_window_set_title (GTK_WINDOW (window), "Messages");
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
box1 = gtk_vbox_new (FALSE, 0);
|
|
|
|
gtk_container_add (GTK_CONTAINER (window), box1);
|
|
|
|
gtk_widget_show (box1);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
box2 = gtk_vbox_new (FALSE, 10);
|
|
|
|
gtk_container_border_width (GTK_CONTAINER (box2), 10);
|
|
|
|
gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show (box2);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
table = gtk_table_new (2, 2, FALSE);
|
|
|
|
gtk_table_set_row_spacing (GTK_TABLE (table), 0, 2);
|
|
|
|
gtk_table_set_col_spacing (GTK_TABLE (table), 0, 2);
|
|
|
|
gtk_box_pack_start (GTK_BOX (box2), table, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show (table);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
text = gtk_text_new (NULL, NULL);
|
|
|
|
gtk_text_set_editable (GTK_TEXT (text), FALSE);
|
|
|
|
gtk_table_attach_defaults (GTK_TABLE (table), text, 0, 1, 0, 1);
|
|
|
|
gtk_widget_show (text);
|
|
|
|
gtk_widget_realize (text);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
hscrollbar = gtk_hscrollbar_new (GTK_TEXT (text)->hadj);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), hscrollbar, 0, 1, 1, 2,
|
1997-11-28 01:22:38 +00:00
|
|
|
GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
1997-11-24 22:37:52 +00:00
|
|
|
gtk_widget_show (hscrollbar);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
vscrollbar = gtk_vscrollbar_new (GTK_TEXT (text)->vadj);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), vscrollbar, 1, 2, 0, 1,
|
1997-11-28 01:22:38 +00:00
|
|
|
GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
|
1997-11-24 22:37:52 +00:00
|
|
|
gtk_widget_show (vscrollbar);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
separator = gtk_hseparator_new ();
|
|
|
|
gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
|
|
|
|
gtk_widget_show (separator);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
box2 = gtk_vbox_new (FALSE, 10);
|
|
|
|
gtk_container_border_width (GTK_CONTAINER (box2), 10);
|
|
|
|
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
|
|
|
|
gtk_widget_show (box2);
|
1997-11-28 01:22:38 +00:00
|
|
|
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
button = gtk_button_new_with_label ("close");
|
|
|
|
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
|
1997-11-28 01:22:38 +00:00
|
|
|
(GtkSignalFunc) gtk_widget_hide,
|
|
|
|
GTK_OBJECT (window));
|
1997-11-24 22:37:52 +00:00
|
|
|
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
|
|
|
|
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
|
|
|
|
gtk_widget_grab_default (button);
|
|
|
|
gtk_widget_show (button);
|
|
|
|
}
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
level += 1;
|
|
|
|
gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, str, -1);
|
|
|
|
level -= 1;
|
1997-11-28 01:22:38 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
if (!GTK_WIDGET_VISIBLE (window))
|
|
|
|
gtk_widget_show (window);
|
|
|
|
}
|