summaryrefslogtreecommitdiff
path: root/src/nautilus-file-changes-queue.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nautilus-file-changes-queue.c')
-rw-r--r--src/nautilus-file-changes-queue.c624
1 files changed, 331 insertions, 293 deletions
diff --git a/src/nautilus-file-changes-queue.c b/src/nautilus-file-changes-queue.c
index b637c61e2..44c2d55c3 100644
--- a/src/nautilus-file-changes-queue.c
+++ b/src/nautilus-file-changes-queue.c
@@ -1,393 +1,431 @@
/*
- Copyright (C) 1999, 2000, 2001 Eazel, Inc.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, see <http://www.gnu.org/licenses/>.
-
- Author: Pavel Cisler <pavel@eazel.com>
-*/
+ * Copyright (C) 1999, 2000, 2001 Eazel, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Pavel Cisler <pavel@eazel.com>
+ */
#include <config.h>
#include "nautilus-file-changes-queue.h"
#include "nautilus-directory-notify.h"
-typedef enum {
- CHANGE_FILE_INITIAL,
- CHANGE_FILE_ADDED,
- CHANGE_FILE_CHANGED,
- CHANGE_FILE_REMOVED,
- CHANGE_FILE_MOVED,
- CHANGE_POSITION_SET,
- CHANGE_POSITION_REMOVE
+typedef enum
+{
+ CHANGE_FILE_INITIAL,
+ CHANGE_FILE_ADDED,
+ CHANGE_FILE_CHANGED,
+ CHANGE_FILE_REMOVED,
+ CHANGE_FILE_MOVED,
+ CHANGE_POSITION_SET,
+ CHANGE_POSITION_REMOVE
} NautilusFileChangeKind;
-typedef struct {
- NautilusFileChangeKind kind;
- GFile *from;
- GFile *to;
- GdkPoint point;
- int screen;
+typedef struct
+{
+ NautilusFileChangeKind kind;
+ GFile *from;
+ GFile *to;
+ GdkPoint point;
+ int screen;
} NautilusFileChange;
-typedef struct {
- GList *head;
- GList *tail;
- GMutex mutex;
+typedef struct
+{
+ GList *head;
+ GList *tail;
+ GMutex mutex;
} NautilusFileChangesQueue;
static NautilusFileChangesQueue *
nautilus_file_changes_queue_new (void)
{
- NautilusFileChangesQueue *result;
+ NautilusFileChangesQueue *result;
- result = g_new0 (NautilusFileChangesQueue, 1);
- g_mutex_init (&result->mutex);
+ result = g_new0 (NautilusFileChangesQueue, 1);
+ g_mutex_init (&result->mutex);
- return result;
+ return result;
}
static NautilusFileChangesQueue *
nautilus_file_changes_queue_get (void)
{
- static NautilusFileChangesQueue *file_changes_queue;
+ static NautilusFileChangesQueue *file_changes_queue;
- if (file_changes_queue == NULL) {
- file_changes_queue = nautilus_file_changes_queue_new ();
- }
+ if (file_changes_queue == NULL)
+ {
+ file_changes_queue = nautilus_file_changes_queue_new ();
+ }
- return file_changes_queue;
+ return file_changes_queue;
}
static void
-nautilus_file_changes_queue_add_common (NautilusFileChangesQueue *queue,
- NautilusFileChange *new_item)
+nautilus_file_changes_queue_add_common (NautilusFileChangesQueue *queue,
+ NautilusFileChange *new_item)
{
- /* enqueue the new queue item while locking down the list */
- g_mutex_lock (&queue->mutex);
+ /* enqueue the new queue item while locking down the list */
+ g_mutex_lock (&queue->mutex);
- queue->head = g_list_prepend (queue->head, new_item);
- if (queue->tail == NULL)
- queue->tail = queue->head;
+ queue->head = g_list_prepend (queue->head, new_item);
+ if (queue->tail == NULL)
+ {
+ queue->tail = queue->head;
+ }
- g_mutex_unlock (&queue->mutex);
+ g_mutex_unlock (&queue->mutex);
}
void
nautilus_file_changes_queue_file_added (GFile *location)
{
- NautilusFileChange *new_item;
- NautilusFileChangesQueue *queue;
+ NautilusFileChange *new_item;
+ NautilusFileChangesQueue *queue;
- queue = nautilus_file_changes_queue_get();
+ queue = nautilus_file_changes_queue_get ();
- new_item = g_new0 (NautilusFileChange, 1);
- new_item->kind = CHANGE_FILE_ADDED;
- new_item->from = g_object_ref (location);
- nautilus_file_changes_queue_add_common (queue, new_item);
+ new_item = g_new0 (NautilusFileChange, 1);
+ new_item->kind = CHANGE_FILE_ADDED;
+ new_item->from = g_object_ref (location);
+ nautilus_file_changes_queue_add_common (queue, new_item);
}
void
nautilus_file_changes_queue_file_changed (GFile *location)
{
- NautilusFileChange *new_item;
- NautilusFileChangesQueue *queue;
+ NautilusFileChange *new_item;
+ NautilusFileChangesQueue *queue;
- queue = nautilus_file_changes_queue_get();
+ queue = nautilus_file_changes_queue_get ();
- new_item = g_new0 (NautilusFileChange, 1);
- new_item->kind = CHANGE_FILE_CHANGED;
- new_item->from = g_object_ref (location);
- nautilus_file_changes_queue_add_common (queue, new_item);
+ new_item = g_new0 (NautilusFileChange, 1);
+ new_item->kind = CHANGE_FILE_CHANGED;
+ new_item->from = g_object_ref (location);
+ nautilus_file_changes_queue_add_common (queue, new_item);
}
void
nautilus_file_changes_queue_file_removed (GFile *location)
{
- NautilusFileChange *new_item;
- NautilusFileChangesQueue *queue;
+ NautilusFileChange *new_item;
+ NautilusFileChangesQueue *queue;
- queue = nautilus_file_changes_queue_get();
+ queue = nautilus_file_changes_queue_get ();
- new_item = g_new0 (NautilusFileChange, 1);
- new_item->kind = CHANGE_FILE_REMOVED;
- new_item->from = g_object_ref (location);
- nautilus_file_changes_queue_add_common (queue, new_item);
+ new_item = g_new0 (NautilusFileChange, 1);
+ new_item->kind = CHANGE_FILE_REMOVED;
+ new_item->from = g_object_ref (location);
+ nautilus_file_changes_queue_add_common (queue, new_item);
}
void
nautilus_file_changes_queue_file_moved (GFile *from,
- GFile *to)
+ GFile *to)
{
- NautilusFileChange *new_item;
- NautilusFileChangesQueue *queue;
+ NautilusFileChange *new_item;
+ NautilusFileChangesQueue *queue;
- queue = nautilus_file_changes_queue_get ();
+ queue = nautilus_file_changes_queue_get ();
- new_item = g_new (NautilusFileChange, 1);
- new_item->kind = CHANGE_FILE_MOVED;
- new_item->from = g_object_ref (from);
- new_item->to = g_object_ref (to);
- nautilus_file_changes_queue_add_common (queue, new_item);
+ new_item = g_new (NautilusFileChange, 1);
+ new_item->kind = CHANGE_FILE_MOVED;
+ new_item->from = g_object_ref (from);
+ new_item->to = g_object_ref (to);
+ nautilus_file_changes_queue_add_common (queue, new_item);
}
void
-nautilus_file_changes_queue_schedule_position_set (GFile *location,
- GdkPoint point,
- int screen)
+nautilus_file_changes_queue_schedule_position_set (GFile *location,
+ GdkPoint point,
+ int screen)
{
- NautilusFileChange *new_item;
- NautilusFileChangesQueue *queue;
+ NautilusFileChange *new_item;
+ NautilusFileChangesQueue *queue;
- queue = nautilus_file_changes_queue_get ();
+ queue = nautilus_file_changes_queue_get ();
- new_item = g_new (NautilusFileChange, 1);
- new_item->kind = CHANGE_POSITION_SET;
- new_item->from = g_object_ref (location);
- new_item->point = point;
- new_item->screen = screen;
- nautilus_file_changes_queue_add_common (queue, new_item);
+ new_item = g_new (NautilusFileChange, 1);
+ new_item->kind = CHANGE_POSITION_SET;
+ new_item->from = g_object_ref (location);
+ new_item->point = point;
+ new_item->screen = screen;
+ nautilus_file_changes_queue_add_common (queue, new_item);
}
void
nautilus_file_changes_queue_schedule_position_remove (GFile *location)
{
- NautilusFileChange *new_item;
- NautilusFileChangesQueue *queue;
+ NautilusFileChange *new_item;
+ NautilusFileChangesQueue *queue;
- queue = nautilus_file_changes_queue_get ();
+ queue = nautilus_file_changes_queue_get ();
- new_item = g_new (NautilusFileChange, 1);
- new_item->kind = CHANGE_POSITION_REMOVE;
- new_item->from = g_object_ref (location);
- nautilus_file_changes_queue_add_common (queue, new_item);
+ new_item = g_new (NautilusFileChange, 1);
+ new_item->kind = CHANGE_POSITION_REMOVE;
+ new_item->from = g_object_ref (location);
+ nautilus_file_changes_queue_add_common (queue, new_item);
}
static NautilusFileChange *
nautilus_file_changes_queue_get_change (NautilusFileChangesQueue *queue)
{
- GList *new_tail;
- NautilusFileChange *result;
-
- g_assert (queue != NULL);
-
- /* dequeue the tail item while locking down the list */
- g_mutex_lock (&queue->mutex);
-
- if (queue->tail == NULL) {
- result = NULL;
- } else {
- new_tail = queue->tail->prev;
- result = queue->tail->data;
- queue->head = g_list_remove_link (queue->head,
- queue->tail);
- g_list_free_1 (queue->tail);
- queue->tail = new_tail;
- }
-
- g_mutex_unlock (&queue->mutex);
-
- return result;
+ GList *new_tail;
+ NautilusFileChange *result;
+
+ g_assert (queue != NULL);
+
+ /* dequeue the tail item while locking down the list */
+ g_mutex_lock (&queue->mutex);
+
+ if (queue->tail == NULL)
+ {
+ result = NULL;
+ }
+ else
+ {
+ new_tail = queue->tail->prev;
+ result = queue->tail->data;
+ queue->head = g_list_remove_link (queue->head,
+ queue->tail);
+ g_list_free_1 (queue->tail);
+ queue->tail = new_tail;
+ }
+
+ g_mutex_unlock (&queue->mutex);
+
+ return result;
}
-enum {
- CONSUME_CHANGES_MAX_CHUNK = 20
+enum
+{
+ CONSUME_CHANGES_MAX_CHUNK = 20
};
static void
pairs_list_free (GList *pairs)
{
- GList *p;
- GFilePair *pair;
+ GList *p;
+ GFilePair *pair;
- /* deep delete the list of pairs */
+ /* deep delete the list of pairs */
- for (p = pairs; p != NULL; p = p->next) {
- /* delete the strings in each pair */
- pair = p->data;
- g_object_unref (pair->from);
- g_object_unref (pair->to);
- }
+ for (p = pairs; p != NULL; p = p->next)
+ {
+ /* delete the strings in each pair */
+ pair = p->data;
+ g_object_unref (pair->from);
+ g_object_unref (pair->to);
+ }
- /* delete the list and the now empty pair structs */
- g_list_free_full (pairs, g_free);
+ /* delete the list and the now empty pair structs */
+ g_list_free_full (pairs, g_free);
}
static void
position_set_list_free (GList *list)
{
- GList *p;
- NautilusFileChangesQueuePosition *item;
-
- for (p = list; p != NULL; p = p->next) {
- item = p->data;
- g_object_unref (item->location);
- }
- /* delete the list and the now empty structs */
- g_list_free_full (list, g_free);
+ GList *p;
+ NautilusFileChangesQueuePosition *item;
+
+ for (p = list; p != NULL; p = p->next)
+ {
+ item = p->data;
+ g_object_unref (item->location);
+ }
+ /* delete the list and the now empty structs */
+ g_list_free_full (list, g_free);
}
/* go through changes in the change queue, send ones with the same kind
* in a list to the different nautilus_directory_notify calls
- */
+ */
void
nautilus_file_changes_consume_changes (gboolean consume_all)
{
- NautilusFileChange *change;
- GList *additions, *changes, *deletions, *moves;
- GList *position_set_requests;
- GFilePair *pair;
- NautilusFileChangesQueuePosition *position_set;
- guint chunk_count;
- NautilusFileChangesQueue *queue;
- gboolean flush_needed;
-
-
- additions = NULL;
- changes = NULL;
- deletions = NULL;
- moves = NULL;
- position_set_requests = NULL;
-
- queue = nautilus_file_changes_queue_get();
-
- /* Consume changes from the queue, stuffing them into one of three lists,
- * keep doing it while the changes are of the same kind, then send them off.
- * This is to ensure that the changes get sent off in the same order that they
- * arrived.
- */
- for (chunk_count = 0; ; chunk_count++) {
- change = nautilus_file_changes_queue_get_change (queue);
-
- /* figure out if we need to flush the pending changes that we collected sofar */
-
- if (change == NULL) {
- flush_needed = TRUE;
- /* no changes left, flush everything */
- } else {
- flush_needed = additions != NULL
- && change->kind != CHANGE_FILE_ADDED
- && change->kind != CHANGE_POSITION_SET
- && change->kind != CHANGE_POSITION_REMOVE;
-
- flush_needed |= changes != NULL
- && change->kind != CHANGE_FILE_CHANGED;
-
- flush_needed |= moves != NULL
- && change->kind != CHANGE_FILE_MOVED
- && change->kind != CHANGE_POSITION_SET
- && change->kind != CHANGE_POSITION_REMOVE;
-
- flush_needed |= deletions != NULL
- && change->kind != CHANGE_FILE_REMOVED;
-
- flush_needed |= position_set_requests != NULL
- && change->kind != CHANGE_POSITION_SET
- && change->kind != CHANGE_POSITION_REMOVE
- && change->kind != CHANGE_FILE_ADDED
- && change->kind != CHANGE_FILE_MOVED;
-
- flush_needed |= !consume_all && chunk_count >= CONSUME_CHANGES_MAX_CHUNK;
- /* we have reached the chunk maximum */
- }
-
- if (flush_needed) {
- /* Send changes we collected off.
- * At one time we may only have one of the lists
- * contain changes.
- */
-
- if (deletions != NULL) {
- deletions = g_list_reverse (deletions);
- nautilus_directory_notify_files_removed (deletions);
- g_list_free_full (deletions, g_object_unref);
- deletions = NULL;
- }
- if (moves != NULL) {
- moves = g_list_reverse (moves);
- nautilus_directory_notify_files_moved (moves);
- pairs_list_free (moves);
- moves = NULL;
- }
- if (additions != NULL) {
- additions = g_list_reverse (additions);
- nautilus_directory_notify_files_added (additions);
- g_list_free_full (additions, g_object_unref);
- additions = NULL;
- }
- if (changes != NULL) {
- changes = g_list_reverse (changes);
- nautilus_directory_notify_files_changed (changes);
- g_list_free_full (changes, g_object_unref);
- changes = NULL;
- }
- if (position_set_requests != NULL) {
- position_set_requests = g_list_reverse (position_set_requests);
- nautilus_directory_schedule_position_set (position_set_requests);
- position_set_list_free (position_set_requests);
- position_set_requests = NULL;
- }
- }
-
- if (change == NULL) {
- /* we are done */
- return;
- }
-
- /* add the new change to the list */
- switch (change->kind) {
- case CHANGE_FILE_ADDED:
- additions = g_list_prepend (additions, change->from);
- break;
-
- case CHANGE_FILE_CHANGED:
- changes = g_list_prepend (changes, change->from);
- break;
-
- case CHANGE_FILE_REMOVED:
- deletions = g_list_prepend (deletions, change->from);
- break;
-
- case CHANGE_FILE_MOVED:
- pair = g_new (GFilePair, 1);
- pair->from = change->from;
- pair->to = change->to;
- moves = g_list_prepend (moves, pair);
- break;
-
- case CHANGE_POSITION_SET:
- position_set = g_new (NautilusFileChangesQueuePosition, 1);
- position_set->location = change->from;
- position_set->set = TRUE;
- position_set->point = change->point;
- position_set->screen = change->screen;
- position_set_requests = g_list_prepend (position_set_requests,
- position_set);
- break;
-
- case CHANGE_POSITION_REMOVE:
- position_set = g_new (NautilusFileChangesQueuePosition, 1);
- position_set->location = change->from;
- position_set->set = FALSE;
- position_set_requests = g_list_prepend (position_set_requests,
- position_set);
- break;
-
- default:
- g_assert_not_reached ();
- break;
- }
-
- g_free (change);
- }
+ NautilusFileChange *change;
+ GList *additions, *changes, *deletions, *moves;
+ GList *position_set_requests;
+ GFilePair *pair;
+ NautilusFileChangesQueuePosition *position_set;
+ guint chunk_count;
+ NautilusFileChangesQueue *queue;
+ gboolean flush_needed;
+
+
+ additions = NULL;
+ changes = NULL;
+ deletions = NULL;
+ moves = NULL;
+ position_set_requests = NULL;
+
+ queue = nautilus_file_changes_queue_get ();
+
+ /* Consume changes from the queue, stuffing them into one of three lists,
+ * keep doing it while the changes are of the same kind, then send them off.
+ * This is to ensure that the changes get sent off in the same order that they
+ * arrived.
+ */
+ for (chunk_count = 0;; chunk_count++)
+ {
+ change = nautilus_file_changes_queue_get_change (queue);
+
+ /* figure out if we need to flush the pending changes that we collected sofar */
+
+ if (change == NULL)
+ {
+ flush_needed = TRUE;
+ /* no changes left, flush everything */
+ }
+ else
+ {
+ flush_needed = additions != NULL
+ && change->kind != CHANGE_FILE_ADDED
+ && change->kind != CHANGE_POSITION_SET
+ && change->kind != CHANGE_POSITION_REMOVE;
+
+ flush_needed |= changes != NULL
+ && change->kind != CHANGE_FILE_CHANGED;
+
+ flush_needed |= moves != NULL
+ && change->kind != CHANGE_FILE_MOVED
+ && change->kind != CHANGE_POSITION_SET
+ && change->kind != CHANGE_POSITION_REMOVE;
+
+ flush_needed |= deletions != NULL
+ && change->kind != CHANGE_FILE_REMOVED;
+
+ flush_needed |= position_set_requests != NULL
+ && change->kind != CHANGE_POSITION_SET
+ && change->kind != CHANGE_POSITION_REMOVE
+ && change->kind != CHANGE_FILE_ADDED
+ && change->kind != CHANGE_FILE_MOVED;
+
+ flush_needed |= !consume_all && chunk_count >= CONSUME_CHANGES_MAX_CHUNK;
+ /* we have reached the chunk maximum */
+ }
+
+ if (flush_needed)
+ {
+ /* Send changes we collected off.
+ * At one time we may only have one of the lists
+ * contain changes.
+ */
+
+ if (deletions != NULL)
+ {
+ deletions = g_list_reverse (deletions);
+ nautilus_directory_notify_files_removed (deletions);
+ g_list_free_full (deletions, g_object_unref);
+ deletions = NULL;
+ }
+ if (moves != NULL)
+ {
+ moves = g_list_reverse (moves);
+ nautilus_directory_notify_files_moved (moves);
+ pairs_list_free (moves);
+ moves = NULL;
+ }
+ if (additions != NULL)
+ {
+ additions = g_list_reverse (additions);
+ nautilus_directory_notify_files_added (additions);
+ g_list_free_full (additions, g_object_unref);
+ additions = NULL;
+ }
+ if (changes != NULL)
+ {
+ changes = g_list_reverse (changes);
+ nautilus_directory_notify_files_changed (changes);
+ g_list_free_full (changes, g_object_unref);
+ changes = NULL;
+ }
+ if (position_set_requests != NULL)
+ {
+ position_set_requests = g_list_reverse (position_set_requests);
+ nautilus_directory_schedule_position_set (position_set_requests);
+ position_set_list_free (position_set_requests);
+ position_set_requests = NULL;
+ }
+ }
+
+ if (change == NULL)
+ {
+ /* we are done */
+ return;
+ }
+
+ /* add the new change to the list */
+ switch (change->kind)
+ {
+ case CHANGE_FILE_ADDED:
+ {
+ additions = g_list_prepend (additions, change->from);
+ }
+ break;
+
+ case CHANGE_FILE_CHANGED:
+ {
+ changes = g_list_prepend (changes, change->from);
+ }
+ break;
+
+ case CHANGE_FILE_REMOVED:
+ {
+ deletions = g_list_prepend (deletions, change->from);
+ }
+ break;
+
+ case CHANGE_FILE_MOVED:
+ {
+ pair = g_new (GFilePair, 1);
+ pair->from = change->from;
+ pair->to = change->to;
+ moves = g_list_prepend (moves, pair);
+ }
+ break;
+
+ case CHANGE_POSITION_SET:
+ {
+ position_set = g_new (NautilusFileChangesQueuePosition, 1);
+ position_set->location = change->from;
+ position_set->set = TRUE;
+ position_set->point = change->point;
+ position_set->screen = change->screen;
+ position_set_requests = g_list_prepend (position_set_requests,
+ position_set);
+ }
+ break;
+
+ case CHANGE_POSITION_REMOVE:
+ {
+ position_set = g_new (NautilusFileChangesQueuePosition, 1);
+ position_set->location = change->from;
+ position_set->set = FALSE;
+ position_set_requests = g_list_prepend (position_set_requests,
+ position_set);
+ }
+ break;
+
+ default:
+ {
+ g_assert_not_reached ();
+ }
+ break;
+ }
+
+ g_free (change);
+ }
}