Commit 3785528e authored by Tim Janik's avatar Tim Janik Committed by Tim Janik

GtkType and macro fixups set a pattern for the file selection widget to

Thu Oct 22 02:29:53 1998  Tim Janik  <timj@gtk.org>

        * gtk/gtkfilesel.h: GtkType and macro fixups
        * gtk/gtkfilesel.c (gtk_file_selection_complete): set a pattern
        for the file selection widget to try a completion on (set the
        initial filter).

Wed Oct 14 14:34:04 1998  Tim Janik  <timj@gtk.org>

        * gtk/gtkmain.c: implement idle functions via GHook. this gives a
        slight speed improvement and lessens code duplication.
parent acfab255
Thu Oct 22 02:29:53 1998 Tim Janik <timj@gtk.org>
* gtk/gtkfilesel.h: GtkType and macro fixups
* gtk/gtkfilesel.c (gtk_file_selection_complete): set a pattern
for the file selection widget to try a completion on (set the
initial filter).
Wed Oct 14 14:34:04 1998 Tim Janik <timj@gtk.org>
* gtk/gtkmain.c: implement idle functions via GHook. this gives a
slight speed improvement and lessens code duplication.
Tue Oct 20 14:53:28 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkdnd.c: Always send "drag_leave" to dests
......
Thu Oct 22 02:29:53 1998 Tim Janik <timj@gtk.org>
* gtk/gtkfilesel.h: GtkType and macro fixups
* gtk/gtkfilesel.c (gtk_file_selection_complete): set a pattern
for the file selection widget to try a completion on (set the
initial filter).
Wed Oct 14 14:34:04 1998 Tim Janik <timj@gtk.org>
* gtk/gtkmain.c: implement idle functions via GHook. this gives a
slight speed improvement and lessens code duplication.
Tue Oct 20 14:53:28 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkdnd.c: Always send "drag_leave" to dests
......
Thu Oct 22 02:29:53 1998 Tim Janik <timj@gtk.org>
* gtk/gtkfilesel.h: GtkType and macro fixups
* gtk/gtkfilesel.c (gtk_file_selection_complete): set a pattern
for the file selection widget to try a completion on (set the
initial filter).
Wed Oct 14 14:34:04 1998 Tim Janik <timj@gtk.org>
* gtk/gtkmain.c: implement idle functions via GHook. this gives a
slight speed improvement and lessens code duplication.
Tue Oct 20 14:53:28 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkdnd.c: Always send "drag_leave" to dests
......
Thu Oct 22 02:29:53 1998 Tim Janik <timj@gtk.org>
* gtk/gtkfilesel.h: GtkType and macro fixups
* gtk/gtkfilesel.c (gtk_file_selection_complete): set a pattern
for the file selection widget to try a completion on (set the
initial filter).
Wed Oct 14 14:34:04 1998 Tim Janik <timj@gtk.org>
* gtk/gtkmain.c: implement idle functions via GHook. this gives a
slight speed improvement and lessens code duplication.
Tue Oct 20 14:53:28 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkdnd.c: Always send "drag_leave" to dests
......
Thu Oct 22 02:29:53 1998 Tim Janik <timj@gtk.org>
* gtk/gtkfilesel.h: GtkType and macro fixups
* gtk/gtkfilesel.c (gtk_file_selection_complete): set a pattern
for the file selection widget to try a completion on (set the
initial filter).
Wed Oct 14 14:34:04 1998 Tim Janik <timj@gtk.org>
* gtk/gtkmain.c: implement idle functions via GHook. this gives a
slight speed improvement and lessens code duplication.
Tue Oct 20 14:53:28 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkdnd.c: Always send "drag_leave" to dests
......
Thu Oct 22 02:29:53 1998 Tim Janik <timj@gtk.org>
* gtk/gtkfilesel.h: GtkType and macro fixups
* gtk/gtkfilesel.c (gtk_file_selection_complete): set a pattern
for the file selection widget to try a completion on (set the
initial filter).
Wed Oct 14 14:34:04 1998 Tim Janik <timj@gtk.org>
* gtk/gtkmain.c: implement idle functions via GHook. this gives a
slight speed improvement and lessens code duplication.
Tue Oct 20 14:53:28 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkdnd.c: Always send "drag_leave" to dests
......
Thu Oct 22 02:29:53 1998 Tim Janik <timj@gtk.org>
* gtk/gtkfilesel.h: GtkType and macro fixups
* gtk/gtkfilesel.c (gtk_file_selection_complete): set a pattern
for the file selection widget to try a completion on (set the
initial filter).
Wed Oct 14 14:34:04 1998 Tim Janik <timj@gtk.org>
* gtk/gtkmain.c: implement idle functions via GHook. this gives a
slight speed improvement and lessens code duplication.
Tue Oct 20 14:53:28 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkdnd.c: Always send "drag_leave" to dests
......
......@@ -322,10 +322,10 @@ static GtkWindowClass *parent_class = NULL;
/* Saves errno when something cmpl does fails. */
static gint cmpl_errno;
guint
GtkType
gtk_file_selection_get_type (void)
{
static guint file_selection_type = 0;
static GtkType file_selection_type = 0;
if (!file_selection_type)
{
......@@ -341,7 +341,7 @@ gtk_file_selection_get_type (void)
(GtkClassInitFunc) NULL,
};
file_selection_type = gtk_type_unique (gtk_window_get_type (), &filesel_info);
file_selection_type = gtk_type_unique (GTK_TYPE_WINDOW, &filesel_info);
}
return file_selection_type;
......@@ -354,7 +354,7 @@ gtk_file_selection_class_init (GtkFileSelectionClass *class)
object_class = (GtkObjectClass*) class;
parent_class = gtk_type_class (gtk_window_get_type ());
parent_class = gtk_type_class (GTK_TYPE_WINDOW);
object_class->destroy = gtk_file_selection_destroy;
}
......@@ -497,7 +497,7 @@ gtk_file_selection_new (const gchar *title)
{
GtkFileSelection *filesel;
filesel = gtk_type_new (gtk_file_selection_get_type ());
filesel = gtk_type_new (GTK_TYPE_FILE_SELECTION);
gtk_window_set_title (GTK_WINDOW (filesel), title);
return GTK_WIDGET (filesel);
......@@ -627,6 +627,19 @@ gtk_file_selection_get_filename (GtkFileSelection *filesel)
return nothing;
}
void
gtk_file_selection_complete (GtkFileSelection *filesel,
const gchar *pattern)
{
g_return_if_fail (filesel != NULL);
g_return_if_fail (GTK_IS_FILE_SELECTION (filesel));
g_return_if_fail (pattern != NULL);
if (filesel->selection_entry)
gtk_entry_set_text (GTK_ENTRY (filesel->selection_entry), pattern);
gtk_file_selection_populate (filesel, (gchar*) pattern, TRUE);
}
static void
gtk_file_selection_destroy (GtkObject *object)
{
......@@ -1696,7 +1709,7 @@ cmpl_completion_matches (gchar* text_to_complete,
prune_memory_usage(cmpl_state);
g_assert(text_to_complete);
g_assert (text_to_complete != NULL);
cmpl_state->user_completion_index = -1;
cmpl_state->last_completion_text = text_to_complete;
......@@ -1706,14 +1719,14 @@ cmpl_completion_matches (gchar* text_to_complete,
cmpl_state->updated_text[0] = 0;
cmpl_state->re_complete = FALSE;
first_slash = strchr(text_to_complete, '/');
first_slash = strchr (text_to_complete, '/');
if(text_to_complete[0] == '~' && !first_slash)
if (text_to_complete[0] == '~' && !first_slash)
{
/* Text starts with ~ and there is no slash, show all the
* home directory completions.
*/
poss = attempt_homedir_completion(text_to_complete, cmpl_state);
poss = attempt_homedir_completion (text_to_complete, cmpl_state);
update_cmpl(poss, cmpl_state);
......@@ -1721,13 +1734,13 @@ cmpl_completion_matches (gchar* text_to_complete,
}
cmpl_state->reference_dir =
open_ref_dir(text_to_complete, remaining_text, cmpl_state);
open_ref_dir (text_to_complete, remaining_text, cmpl_state);
if(!cmpl_state->reference_dir)
return NULL;
cmpl_state->completion_dir =
find_completion_dir(*remaining_text, remaining_text, cmpl_state);
find_completion_dir (*remaining_text, remaining_text, cmpl_state);
cmpl_state->last_valid_char = *remaining_text - text_to_complete;
......
......@@ -29,9 +29,11 @@ extern "C" {
#endif /* __cplusplus */
#define GTK_FILE_SELECTION(obj) GTK_CHECK_CAST (obj, gtk_file_selection_get_type (), GtkFileSelection)
#define GTK_FILE_SELECTION_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_file_selection_get_type (), GtkFileSelectionClass)
#define GTK_IS_FILE_SELECTION(obj) GTK_CHECK_TYPE (obj, gtk_file_selection_get_type ())
#define GTK_TYPE_FILE_SELECTION (gtk_file_selection_get_type ())
#define GTK_FILE_SELECTION(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_FILE_SELECTION, GtkFileSelection))
#define GTK_FILE_SELECTION_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_FILE_SELECTION, GtkFileSelectionClass))
#define GTK_IS_FILE_SELECTION(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_FILE_SELECTION))
#define GTK_IS_FILE_SELECTION_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FILE_SELECTION))
typedef struct _GtkFileSelection GtkFileSelection;
......@@ -72,11 +74,13 @@ struct _GtkFileSelectionClass
};
guint gtk_file_selection_get_type (void);
GtkWidget* gtk_file_selection_new (const gchar *title);
void gtk_file_selection_set_filename (GtkFileSelection *filesel,
const gchar *filename);
gchar* gtk_file_selection_get_filename (GtkFileSelection *filesel);
GtkType gtk_file_selection_get_type (void);
GtkWidget* gtk_file_selection_new (const gchar *title);
void gtk_file_selection_set_filename (GtkFileSelection *filesel,
const gchar *filename);
gchar* gtk_file_selection_get_filename (GtkFileSelection *filesel);
void gtk_file_selection_complete (GtkFileSelection *filesel,
const gchar *pattern);
void gtk_file_selection_show_fileop_buttons (GtkFileSelection *filesel);
void gtk_file_selection_hide_fileop_buttons (GtkFileSelection *filesel);
......
......@@ -48,7 +48,7 @@
typedef struct _GtkInitFunction GtkInitFunction;
typedef struct _GtkQuitFunction GtkQuitFunction;
typedef struct _GtkTimeoutFunction GtkTimeoutFunction;
typedef struct _GtkIdleFunction GtkIdleFunction;
typedef struct _GtkIdleHook GtkIdleHook;
typedef struct _GtkInputFunction GtkInputFunction;
typedef struct _GtkKeySnooperData GtkKeySnooperData;
......@@ -80,15 +80,17 @@ struct _GtkTimeoutFunction
GtkDestroyNotify destroy;
};
struct _GtkIdleFunction
enum
{
guint tag;
gint priority;
GtkCallbackMarshal marshal;
GtkFunction function;
gpointer data;
GtkDestroyNotify destroy;
GTK_HOOK_MARSHAL = 1 << (G_HOOK_FLAG_USER_SHIFT)
};
struct _GtkIdleHook
{
GHook hook;
gint priority;
};
#define GTK_IDLE_HOOK(hook) ((GtkIdleHook*) hook)
struct _GtkInputFunction
{
......@@ -104,16 +106,18 @@ struct _GtkKeySnooperData
guint id;
};
static void gtk_exit_func (void);
static void gtk_exit_func (void);
static void gtk_invoke_hook (GHookList *hook_list,
GHook *hook);
static void gtk_handle_idles (void);
static gboolean gtk_finish_idles (void);
static gint gtk_quit_invoke_function (GtkQuitFunction *quitf);
static void gtk_quit_destroy (GtkQuitFunction *quitf);
static void gtk_timeout_insert (GtkTimeoutFunction *timeoutf);
static void gtk_handle_current_timeouts (guint32 the_time);
static void gtk_handle_current_idles (void);
static gint gtk_invoke_key_snoopers (GtkWidget *grab_widget,
GdkEvent *event);
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);
......@@ -124,17 +128,10 @@ static void gtk_message (gchar *str);
static void gtk_print (gchar *str);
#endif
static gint gtk_idle_remove_from_list (GList **list,
guint tag,
gpointer data,
gint remove_link);
static gint gtk_timeout_remove_from_list (GList **list,
guint tag,
gint remove_link);
static gint gtk_idle_compare (gconstpointer a,
gconstpointer b);
static gint gtk_timeout_compare (gconstpointer a,
gconstpointer b);
......@@ -191,23 +188,20 @@ static GList *timeout_functions = NULL; /* A list of timeout functions sorted
* function to expire is at the head of
* the list and the last to expire is at
* the tail of the list. */
static GList *idle_functions = NULL; /* A list of idle functions.
*/
/* Prioritized idle callbacks */
static GHookList idle_hooks = { 0 };
static GHook *last_idle = NULL;
/* The idle functions / timeouts that are currently being processed
* by gtk_handle_current_(timeouts/idles)
/* The timeouts that are currently being processed
* by gtk_handle_current_timeouts
*/
static GList *current_idles = NULL;
static GList *current_timeouts = NULL;
/* A stack of idle functions / timeouts that are currently being
* being executed
/* A stack of timeouts that is currently being executed
*/
static GList *running_idles = NULL;
static GList *running_timeouts = NULL;
static GMemChunk *timeout_mem_chunk = NULL;
static GMemChunk *idle_mem_chunk = NULL;
static GMemChunk *quit_mem_chunk = NULL;
static GSList *key_snoopers = NULL;
......@@ -590,14 +584,16 @@ gtk_events_pending (void)
result += next_event != NULL;
result += gdk_events_pending();
result += current_idles != NULL;
result += last_idle != NULL;
result += current_timeouts != NULL;
if (!result)
{
result += (idle_functions &&
(((GtkIdleFunction *)idle_functions->data)->priority <=
GTK_PRIORITY_INTERNAL));
GHook *hook;
hook = g_hook_first_valid (&idle_hooks, FALSE);
result += hook && GTK_IDLE_HOOK (hook)->priority <= GTK_PRIORITY_INTERNAL;
}
if (!result && timeout_functions)
......@@ -644,10 +640,8 @@ gtk_main_iteration_do (gboolean blocking)
return iteration_done;
}
if (current_idles)
if (last_idle && gtk_finish_idles ())
{
gtk_handle_current_idles ();
if (iteration_done)
gdk_flush ();
......@@ -674,7 +668,8 @@ gtk_main_iteration_do (gboolean blocking)
*/
gtk_handle_timer ();
if (blocking) event = gdk_event_get ();
if (blocking)
event = gdk_event_get ();
}
/* "gdk_event_get" can return FALSE if the timer goes off
......@@ -864,7 +859,7 @@ gtk_main_iteration_do (gboolean blocking)
else
{
if (gdk_events_pending() == 0)
gtk_handle_idle ();
gtk_handle_idles ();
}
event_handling_done:
......@@ -1110,17 +1105,6 @@ gtk_timeout_remove (guint tag)
return;
}
/* 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 (gconstpointer a, gconstpointer b)
{
return (((const GtkIdleFunction *)a)->priority <
((const GtkIdleFunction *)b)->priority)
? -1 : 1;
}
guint
gtk_quit_add_full (guint main_level,
GtkFunction function,
......@@ -1151,6 +1135,20 @@ gtk_quit_add_full (guint main_level,
return quitf->id;
}
gint
gtk_idle_compare (GHook *new_g_hook,
GHook *g_sibling)
{
GtkIdleHook *new_hook = GTK_IDLE_HOOK (new_g_hook);
GtkIdleHook *sibling = GTK_IDLE_HOOK (g_sibling);
/* We add an extra +1 to the comparision result to make sure
* that we get inserted at the end of the list of hooks with
* the same priority.
*/
return new_hook->priority - sibling->priority + 1;
}
guint
gtk_idle_add_full (gint priority,
GtkFunction function,
......@@ -1158,34 +1156,54 @@ gtk_idle_add_full (gint priority,
gpointer data,
GtkDestroyNotify destroy)
{
static guint idle_tag = 1;
GtkIdleFunction *idlef;
g_return_val_if_fail ((function != NULL) || (marshal != NULL), 0);
GHook *hook;
GtkIdleHook *ihook;
if (!idle_mem_chunk)
idle_mem_chunk = g_mem_chunk_new ("idle mem chunk", sizeof (GtkIdleFunction),
1024, G_ALLOC_AND_FREE);
idlef = g_chunk_new (GtkIdleFunction, idle_mem_chunk);
idlef->tag = idle_tag++;
idlef->priority = priority;
idlef->function = function;
idlef->marshal = marshal;
idlef->data = data;
idlef->destroy = destroy;
if (function)
g_return_val_if_fail (marshal == NULL, 0);
else
g_return_val_if_fail (marshal != NULL, 0);
if (!idle_hooks.seq_id)
g_hook_list_init (&idle_hooks, sizeof (GtkIdleHook));
hook = g_hook_alloc (&idle_hooks);
ihook = GTK_IDLE_HOOK (hook);
hook->data = data;
if (marshal)
{
hook->flags |= GTK_HOOK_MARSHAL;
hook->func = marshal;
}
else
hook->func = function;
hook->destroy = destroy;
ihook->priority = priority;
/* If we are adding the first idle function, possibly wake up
* the main thread out of its select().
*/
if (!idle_functions)
if (!g_hook_first_valid (&idle_hooks, TRUE))
gdk_threads_wake ();
idle_functions = g_list_insert_sorted (idle_functions, idlef, gtk_idle_compare);
g_hook_insert_sorted (&idle_hooks, hook, gtk_idle_compare);
return idlef->tag;
return hook->hook_id;
}
guint
gtk_idle_add (GtkFunction function,
gpointer data)
{
return gtk_idle_add_full (GTK_PRIORITY_DEFAULT, function, NULL, data, NULL);
}
guint
gtk_idle_add_priority (gint priority,
GtkFunction function,
gpointer data)
{
return gtk_idle_add_full (priority, function, NULL, data, NULL);
}
guint
......@@ -1196,12 +1214,209 @@ gtk_idle_add_interp (GtkCallbackMarshal marshal,
return gtk_idle_add_full (GTK_PRIORITY_DEFAULT, NULL, marshal, data, destroy);
}
void
gtk_idle_remove (guint tag)
{
g_return_if_fail (tag > 0);
if (!g_hook_destroy (&idle_hooks, tag))
g_warning ("gtk_idle_remove(%d): no such idle function", tag);
}
void
gtk_idle_remove_by_data (gpointer data)
{
GHook *hook;
hook = g_hook_find_data (&idle_hooks, TRUE, data);
if (hook)
g_hook_destroy_link (&idle_hooks, hook);
else
g_warning ("gtk_idle_remove_by_data(%p): no such idle function", data);
}
static gboolean
gtk_finish_idles (void)
{
gboolean idles_called;
idles_called = FALSE;
while (last_idle)
{
GHook *hook;
hook = g_hook_next_valid (last_idle, FALSE);
if (!hook || GTK_IDLE_HOOK (hook)->priority != GTK_IDLE_HOOK (last_idle)->priority)
{
g_hook_unref (&idle_hooks, last_idle);
last_idle = NULL;
}
else
{
g_hook_unref (&idle_hooks, last_idle);
last_idle = hook;
g_hook_ref (&idle_hooks, last_idle);
idles_called = TRUE;
gtk_invoke_hook (&idle_hooks, last_idle);
}
}
return idles_called;
}
static void
gtk_idle_destroy (GtkIdleFunction *idlef)
gtk_handle_idles (void)
{
if (idlef->destroy)
idlef->destroy (idlef->data);
g_mem_chunk_free (idle_mem_chunk, idlef);
GHook *hook;
/* Caller must already have called gtk_finish_idles() if necessary
*/
g_assert (last_idle == NULL);
hook = g_hook_first_valid (&idle_hooks, FALSE);
if (hook)
{
last_idle = hook;
g_hook_ref (&idle_hooks, last_idle);
gtk_invoke_hook (&idle_hooks, last_idle);
gtk_finish_idles ();
}
}
static void
gtk_invoke_hook (GHookList *hook_list,
GHook *hook)
{
gboolean keep_alive;
if (hook->flags & GTK_HOOK_MARSHAL)
{
GtkArg args[1];
register GtkCallbackMarshal marshal;
keep_alive = FALSE;
args[0].name = NULL;
args[0].type = GTK_TYPE_BOOL;
GTK_VALUE_POINTER (args[0]) = &keep_alive;
marshal = hook->func;
marshal (NULL, hook->data, 0, args);
}
else
{
register GtkFunction func;
func = hook->func;
keep_alive = func (hook->data);
}
if (!keep_alive)
g_hook_destroy_link (hook_list, hook);
}
static gint
gtk_invoke_timeout_function (GtkTimeoutFunction *timeoutf)
{
if (!timeoutf->marshal)
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;
timeoutf->marshal (NULL, timeoutf->data, 0, args);
return ret_val;
}
}
static void
gtk_handle_current_timeouts (guint32 the_time)
{
gint result;
GList *tmp_list;
GtkTimeoutFunction *timeoutf;
while (current_timeouts)
{
tmp_list = current_timeouts;
timeoutf = tmp_list->data;
current_timeouts = g_list_remove_link (current_timeouts, tmp_list);
if (running_timeouts)
{
running_timeouts->prev = tmp_list;
tmp_list->next = running_timeouts;
}
running_timeouts = tmp_list;
result = gtk_invoke_timeout_function (timeoutf);
running_timeouts = g_list_remove_link (running_timeouts, tmp_list);
timeoutf = tmp_list->data;
g_list_free_1 (tmp_list);
if (timeoutf)
{
if (!result)
{
gtk_timeout_destroy (timeoutf);
}
else
{
timeoutf->interval = timeoutf->originterval;
timeoutf->start = the_time;
gtk_timeout_insert (timeoutf);
}
}
}
}
static void
gtk_handle_timeouts (void)
{
guint32 the_time;
GList *tmp_list;
GList *tmp_list2;
GtkTimeoutFunction *timeoutf;
/* Caller must already have called gtk_handle_current_timeouts if
* necessary */
g_assert (current_timeouts == NULL);
if (timeout_functions)
{
the_time = gdk_time_get ();
tmp_list = timeout_functions;
while (tmp_list)
{
timeoutf = tmp_list->data;
if (timeoutf->interval <= (the_time - timeoutf->start))
{
tmp_list2 = tmp_list;
tmp_list = tmp_list->next;