"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "libsn/sn-monitor.c" between
xfe-1.42.tar.gz and xfe-1.43.tar.gz

About: Xfe (X File Explorer) is a file manager and browser (using the FOX toolkit).

sn-monitor.c  (xfe-1.42):sn-monitor.c  (xfe-1.43)
skipping to change at line 31 skipping to change at line 31
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
#include "sn-monitor.h" #include "sn-monitor.h"
#include "sn-internals.h" #include "sn-internals.h"
#include "sn-xmessages.h" #include "sn-xmessages.h"
#include <sys/time.h> #include <sys/time.h>
struct SnMonitorContext struct SnMonitorContext
{ {
int refcount; int refcount;
SnDisplay *display; SnDisplay *display;
int screen; int screen;
SnMonitorEventFunc event_func; SnMonitorEventFunc event_func;
void *event_func_data; void *event_func_data;
SnFreeFunc free_data_func; SnFreeFunc free_data_func;
/* a context doesn't get events for sequences /* a context doesn't get events for sequences
* started prior to context creation * started prior to context creation
*/ */
int creation_serial; int creation_serial;
}; };
struct SnMonitorEvent struct SnMonitorEvent
{ {
int refcount; int refcount;
SnMonitorEventType type; SnMonitorEventType type;
SnMonitorContext *context; SnMonitorContext *context;
SnStartupSequence *sequence; SnStartupSequence *sequence;
}; };
struct SnStartupSequence struct SnStartupSequence
{ {
int refcount; int refcount;
SnDisplay *display; SnDisplay *display;
int screen; int screen;
char *id; char *id;
char *name; char *name;
char *description; char *description;
char *wmclass; char *wmclass;
int workspace; int workspace;
Time timestamp; Time timestamp;
char *binary_name; char *binary_name;
char *icon_name; char *icon_name;
char *application_id;
unsigned int completed : 1; unsigned int completed : 1;
unsigned int canceled : 1; unsigned int canceled : 1;
unsigned int timestamp_set : 1; unsigned int timestamp_set : 1;
int creation_serial; int creation_serial;
struct timeval initiation_time; struct timeval initiation_time;
}; };
static SnList *context_list = NULL; static SnList *context_list = NULL;
static SnList *sequence_list = NULL; static SnList *sequence_list = NULL;
static int next_sequence_serial = 0; static int next_sequence_serial = 0;
static void xmessage_func (SnDisplay *display, static void xmessage_func (SnDisplay *display,
const char *message_type, const char *message_type,
const char *message, const char *message,
void *user_data); void *user_data);
skipping to change at line 117 skipping to change at line 118
* *
* Return value: a new #SnMonitorContext * Return value: a new #SnMonitorContext
**/ **/
SnMonitorContext* SnMonitorContext*
sn_monitor_context_new (SnDisplay *display, sn_monitor_context_new (SnDisplay *display,
int screen, int screen,
SnMonitorEventFunc event_func, SnMonitorEventFunc event_func,
void *event_func_data, void *event_func_data,
SnFreeFunc free_data_func) SnFreeFunc free_data_func)
{ {
SnMonitorContext *context; SnMonitorContext *context;
context = sn_new0 (SnMonitorContext, 1); context = sn_new0 (SnMonitorContext, 1);
context->refcount = 1; context->refcount = 1;
context->event_func = event_func; context->event_func = event_func;
context->event_func_data = event_func_data; context->event_func_data = event_func_data;
context->free_data_func = free_data_func; context->free_data_func = free_data_func;
context->display = display; context->display = display;
sn_display_ref (context->display); sn_display_ref (context->display);
context->screen = screen; context->screen = screen;
if (context_list == NULL) if (context_list == NULL)
context_list = sn_list_new (); context_list = sn_list_new ();
if (sn_list_empty (context_list)) if (sn_list_empty (context_list))
sn_internal_add_xmessage_func (display, sn_internal_add_xmessage_func (display,
screen, screen,
"_NET_STARTUP_INFO", "_NET_STARTUP_INFO",
"_NET_STARTUP_INFO_BEGIN", "_NET_STARTUP_INFO_BEGIN",
xmessage_func, xmessage_func,
NULL, NULL); NULL, NULL);
sn_list_prepend (context_list, context); sn_list_prepend (context_list, context);
/* We get events for serials >= creation_serial */ /* We get events for serials >= creation_serial */
context->creation_serial = next_sequence_serial; context->creation_serial = next_sequence_serial;
return context; return context;
} }
/** /**
* sn_monitor_context_ref: * sn_monitor_context_ref:
* @context: an #SnMonitorContext * @context: an #SnMonitorContext
* *
* Increments the reference count on @context. * Increments the reference count on @context.
* *
**/ **/
void void
sn_monitor_context_ref (SnMonitorContext *context) sn_monitor_context_ref (SnMonitorContext *context)
{ {
context->refcount += 1; context->refcount += 1;
} }
/** /**
* sn_monitor_context_unref: * sn_monitor_context_unref:
* @context: an #SnMonitorContext * @context: an #SnMonitorContext
* *
* Decrements the reference count on @context and frees the * Decrements the reference count on @context and frees the
* context if the count reaches 0. * context if the count reaches 0.
**/ **/
void void
sn_monitor_context_unref (SnMonitorContext *context) sn_monitor_context_unref (SnMonitorContext *context)
{ {
context->refcount -= 1; context->refcount -= 1;
if (context->refcount == 0) if (context->refcount == 0)
{ {
sn_list_remove (context_list, context); sn_list_remove (context_list, context);
if (sn_list_empty (context_list)) if (sn_list_empty (context_list))
sn_internal_remove_xmessage_func (context->display, sn_internal_remove_xmessage_func (context->display,
context->screen, context->screen,
"_NET_STARTUP_INFO", "_NET_STARTUP_INFO",
xmessage_func, xmessage_func,
NULL); NULL);
if (context->free_data_func) if (context->free_data_func)
(* context->free_data_func) (context->event_func_data); (* context->free_data_func) (context->event_func_data);
sn_display_unref (context->display); sn_display_unref (context->display);
sn_free (context); sn_free (context);
} }
} }
void void
sn_monitor_event_ref (SnMonitorEvent *event) sn_monitor_event_ref (SnMonitorEvent *event)
{ {
event->refcount += 1; event->refcount += 1;
} }
void void
sn_monitor_event_unref (SnMonitorEvent *event) sn_monitor_event_unref (SnMonitorEvent *event)
{ {
event->refcount -= 1; event->refcount -= 1;
if (event->refcount == 0) if (event->refcount == 0)
{ {
if (event->context) if (event->context)
sn_monitor_context_unref (event->context); sn_monitor_context_unref (event->context);
if (event->sequence) if (event->sequence)
sn_startup_sequence_unref (event->sequence); sn_startup_sequence_unref (event->sequence);
sn_free (event); sn_free (event);
} }
} }
SnMonitorEvent* SnMonitorEvent*
sn_monitor_event_copy (SnMonitorEvent *event) sn_monitor_event_copy (SnMonitorEvent *event)
{ {
SnMonitorEvent *copy; SnMonitorEvent *copy;
copy = sn_new0 (SnMonitorEvent, 1); copy = sn_new0 (SnMonitorEvent, 1);
copy->refcount = 1; copy->refcount = 1;
copy->type = event->type; copy->type = event->type;
copy->context = event->context; copy->context = event->context;
if (copy->context) if (copy->context)
sn_monitor_context_ref (copy->context); sn_monitor_context_ref (copy->context);
copy->sequence = event->sequence; copy->sequence = event->sequence;
if (copy->sequence) if (copy->sequence)
sn_startup_sequence_ref (copy->sequence); sn_startup_sequence_ref (copy->sequence);
return copy; return copy;
} }
SnMonitorEventType SnMonitorEventType
sn_monitor_event_get_type (SnMonitorEvent *event) sn_monitor_event_get_type (SnMonitorEvent *event)
{ {
return event->type; return event->type;
} }
SnStartupSequence* SnStartupSequence*
sn_monitor_event_get_startup_sequence (SnMonitorEvent *event) sn_monitor_event_get_startup_sequence (SnMonitorEvent *event)
{ {
return event->sequence; return event->sequence;
} }
SnMonitorContext* SnMonitorContext*
sn_monitor_event_get_context (SnMonitorEvent *event) sn_monitor_event_get_context (SnMonitorEvent *event)
{ {
return event->context; return event->context;
} }
void void
sn_startup_sequence_ref (SnStartupSequence *sequence) sn_startup_sequence_ref (SnStartupSequence *sequence)
{ {
sequence->refcount += 1; sequence->refcount += 1;
} }
void void
sn_startup_sequence_unref (SnStartupSequence *sequence) sn_startup_sequence_unref (SnStartupSequence *sequence)
{ {
sequence->refcount -= 1; sequence->refcount -= 1;
if (sequence->refcount == 0) if (sequence->refcount == 0)
{ {
sn_free (sequence->id); sn_free (sequence->id);
sn_free (sequence->name); sn_free (sequence->name);
sn_free (sequence->description); sn_free (sequence->description);
sn_free (sequence->wmclass); sn_free (sequence->wmclass);
sn_free (sequence->binary_name); sn_free (sequence->binary_name);
sn_free (sequence->icon_name); sn_free (sequence->icon_name);
sn_free (sequence->application_id);
sn_display_unref (sequence->display); sn_display_unref (sequence->display);
sn_free (sequence); sn_free (sequence);
} }
} }
const char* const char*
sn_startup_sequence_get_id (SnStartupSequence *sequence) sn_startup_sequence_get_id (SnStartupSequence *sequence)
{ {
return sequence->id; return sequence->id;
} }
sn_bool_t sn_bool_t
sn_startup_sequence_get_completed (SnStartupSequence *sequence) sn_startup_sequence_get_completed (SnStartupSequence *sequence)
{ {
return sequence->completed; return sequence->completed;
} }
const char* const char*
sn_startup_sequence_get_name (SnStartupSequence *sequence) sn_startup_sequence_get_name (SnStartupSequence *sequence)
{ {
return sequence->name; return sequence->name;
} }
const char* const char*
sn_startup_sequence_get_description (SnStartupSequence *sequence) sn_startup_sequence_get_description (SnStartupSequence *sequence)
{ {
return sequence->description; return sequence->description;
} }
int int
sn_startup_sequence_get_workspace (SnStartupSequence *sequence) sn_startup_sequence_get_workspace (SnStartupSequence *sequence)
{ {
return sequence->workspace; return sequence->workspace;
} }
Time Time
sn_startup_sequence_get_timestamp (SnStartupSequence *sequence) sn_startup_sequence_get_timestamp (SnStartupSequence *sequence)
{ {
if (!sequence->timestamp_set) if (!sequence->timestamp_set)
{ {
fprintf (stderr, fprintf (stderr,
"libsn: Buggy startup-notification launcher! No timestamp!\n") "libsn: Buggy startup-notification launcher! No timestamp!\n");
; /* Unfortunately, all values are valid; let's just return -1 */
/* Unfortunately, all values are valid; let's just return -1 */ return -1;
return -1;
} }
else else
return sequence->timestamp; return sequence->timestamp;
} }
const char* const char*
sn_startup_sequence_get_wmclass (SnStartupSequence *sequence) sn_startup_sequence_get_wmclass (SnStartupSequence *sequence)
{ {
return sequence->wmclass; return sequence->wmclass;
} }
const char* const char*
sn_startup_sequence_get_binary_name (SnStartupSequence *sequence) sn_startup_sequence_get_binary_name (SnStartupSequence *sequence)
{ {
return sequence->binary_name; return sequence->binary_name;
} }
const char* const char*
sn_startup_sequence_get_icon_name (SnStartupSequence *sequence) sn_startup_sequence_get_icon_name (SnStartupSequence *sequence)
{ {
return sequence->icon_name; return sequence->icon_name;
}
const char*
sn_startup_sequence_get_application_id (SnStartupSequence *sequence)
{
return sequence->application_id;
} }
int int
sn_startup_sequence_get_screen (SnStartupSequence *sequence) sn_startup_sequence_get_screen (SnStartupSequence *sequence)
{ {
return sequence->screen; return sequence->screen;
} }
/** /**
* sn_startup_sequence_get_initiated_time: * sn_startup_sequence_get_initiated_time:
* @sequence: an #SnStartupSequence * @sequence: an #SnStartupSequence
* @tv_sec: seconds as in struct timeval * @tv_sec: seconds as in struct timeval
* @tv_usec: microseconds as struct timeval * @tv_usec: microseconds as struct timeval
* *
* When a startup sequence is first monitored, libstartup-notification * When a startup sequence is first monitored, libstartup-notification
* calls gettimeofday() and records the time, this function * calls gettimeofday() and records the time, this function
* returns that recorded time. * returns that recorded time.
* *
**/ **/
void void
sn_startup_sequence_get_initiated_time (SnStartupSequence *sequence, sn_startup_sequence_get_initiated_time (SnStartupSequence *sequence,
long *tv_sec, long *tv_sec,
long *tv_usec) long *tv_usec)
{ {
if (tv_sec) if (tv_sec)
*tv_sec = sequence->initiation_time.tv_sec; *tv_sec = sequence->initiation_time.tv_sec;
if (tv_usec) if (tv_usec)
*tv_usec = sequence->initiation_time.tv_usec; *tv_usec = sequence->initiation_time.tv_usec;
} }
/** /**
* sn_startup_sequence_get_last_active_time: * sn_startup_sequence_get_last_active_time:
* @sequence: an #SnStartupSequence * @sequence: an #SnStartupSequence
* @tv_sec: seconds as in struct timeval * @tv_sec: seconds as in struct timeval
* @tv_usec: microseconds as in struct timeval * @tv_usec: microseconds as in struct timeval
* *
* Returns the last time we had evidence the startup was active. * Returns the last time we had evidence the startup was active.
* This function should be used to decide whether a sequence * This function should be used to decide whether a sequence
* has timed out. * has timed out.
* *
**/ **/
void void
sn_startup_sequence_get_last_active_time (SnStartupSequence *sequence, sn_startup_sequence_get_last_active_time (SnStartupSequence *sequence,
long *tv_sec, long *tv_sec,
long *tv_usec) long *tv_usec)
{ {
/* for now the same as get_initiated_time */ /* for now the same as get_initiated_time */
if (tv_sec) if (tv_sec)
*tv_sec = sequence->initiation_time.tv_sec; *tv_sec = sequence->initiation_time.tv_sec;
if (tv_usec) if (tv_usec)
*tv_usec = sequence->initiation_time.tv_usec; *tv_usec = sequence->initiation_time.tv_usec;
} }
void void
sn_startup_sequence_complete (SnStartupSequence *sequence) sn_startup_sequence_complete (SnStartupSequence *sequence)
{ {
char *keys[2]; char *keys[2];
char *vals[2]; char *vals[2];
char *message; char *message;
if (sequence->id == NULL) if (sequence->id == NULL)
return; return;
if (sequence->screen < 0) if (sequence->screen < 0)
return; return;
keys[0] = "ID"; keys[0] = "ID";
keys[1] = NULL; keys[1] = NULL;
vals[0] = sequence->id; vals[0] = sequence->id;
vals[1] = NULL; vals[1] = NULL;
message = sn_internal_serialize_message ("remove", message = sn_internal_serialize_message ("remove",
(const char**) keys, (const char**) keys,
(const char **) vals); (const char **) vals);
sn_internal_broadcast_xmessage (sequence->display, sn_internal_broadcast_xmessage (sequence->display,
sequence->screen, sequence->screen,
"_NET_STARTUP_INFO", sn_internal_get_net_startup_info_atom(sequence
"_NET_STARTUP_INFO_BEGIN", ->display),
message); sn_internal_get_net_startup_info_begin_atom(se
quence->display),
message);
sn_free (message); sn_free (message);
} }
static SnStartupSequence* static SnStartupSequence*
sn_startup_sequence_new (SnDisplay *display) sn_startup_sequence_new (SnDisplay *display)
{ {
SnStartupSequence *sequence; SnStartupSequence *sequence;
sequence = sn_new0 (SnStartupSequence, 1); sequence = sn_new0 (SnStartupSequence, 1);
sequence->refcount = 1; sequence->refcount = 1;
sequence->creation_serial = next_sequence_serial; sequence->creation_serial = next_sequence_serial;
++next_sequence_serial; ++next_sequence_serial;
sequence->id = NULL; sequence->id = NULL;
sequence->display = display; sequence->display = display;
sn_display_ref (display); sn_display_ref (display);
sequence->screen = -1; /* not set */ sequence->screen = -1; /* not set */
sequence->workspace = -1; /* not set */ sequence->workspace = -1; /* not set */
sequence->timestamp = 0; sequence->timestamp = 0;
sequence->timestamp_set = FALSE; sequence->timestamp_set = FALSE;
sequence->initiation_time.tv_sec = 0; sequence->initiation_time.tv_sec = 0;
sequence->initiation_time.tv_usec = 0; sequence->initiation_time.tv_usec = 0;
gettimeofday (&sequence->initiation_time, NULL); gettimeofday (&sequence->initiation_time, NULL);
return sequence; return sequence;
} }
typedef struct typedef struct
{ {
SnMonitorEvent *base_event; SnMonitorEvent *base_event;
SnList *events; SnList *events;
} CreateContextEventsData; } CreateContextEventsData;
static sn_bool_t static sn_bool_t
create_context_events_foreach (void *value, create_context_events_foreach (void *value,
void *data) void *data)
{ {
/* Make a list of events holding a ref to the context they'll go to, /* Make a list of events holding a ref to the context they'll go to,
* for reentrancy robustness * for reentrancy robustness
*/ */
SnMonitorContext *context = value; SnMonitorContext *context = value;
CreateContextEventsData *ced = data; CreateContextEventsData *ced = data;
/* Don't send events for startup sequences initiated before the /* Don't send events for startup sequences initiated before the
* context was created * context was created
*/ */
if (ced->base_event->sequence->creation_serial >= if (ced->base_event->sequence->creation_serial >=
context->creation_serial) context->creation_serial)
{ {
SnMonitorEvent *copy; SnMonitorEvent *copy;
copy = sn_monitor_event_copy (ced->base_event); copy = sn_monitor_event_copy (ced->base_event);
copy->context = context; copy->context = context;
sn_monitor_context_ref (copy->context); sn_monitor_context_ref (copy->context);
sn_list_prepend (ced->events, copy); sn_list_prepend (ced->events, copy);
} }
return TRUE; return TRUE;
} }
static sn_bool_t static sn_bool_t
dispatch_event_foreach (void *value, dispatch_event_foreach (void *value,
void *data) void *data)
{ {
SnMonitorEvent *event = value; SnMonitorEvent *event = value;
/* Dispatch and free events */ /* Dispatch and free events */
if (event->context->event_func) if (event->context->event_func)
(* event->context->event_func) (event, (* event->context->event_func) (event,
event->context->event_func_data); event->context->event_func_data);
sn_monitor_event_unref (event); sn_monitor_event_unref (event);
return TRUE; return TRUE;
} }
static sn_bool_t static sn_bool_t
filter_event (SnMonitorEvent *event) filter_event (SnMonitorEvent *event)
{ {
sn_bool_t retval; sn_bool_t retval;
retval = FALSE; retval = FALSE;
/* Filter out duplicate events and update flags */ /* Filter out duplicate events and update flags */
switch (event->type) switch (event->type)
{ {
case SN_MONITOR_EVENT_CANCELED: case SN_MONITOR_EVENT_CANCELED:
if (event->sequence->canceled) if (event->sequence->canceled)
{ {
retval = TRUE; retval = TRUE;
} }
else else
{ {
event->sequence->canceled = TRUE; event->sequence->canceled = TRUE;
} }
break; break;
case SN_MONITOR_EVENT_COMPLETED: case SN_MONITOR_EVENT_COMPLETED:
if (event->sequence->completed) if (event->sequence->completed)
{ {
retval = TRUE; retval = TRUE;
} }
else else
{ {
event->sequence->completed = TRUE; event->sequence->completed = TRUE;
} }
break; break;
default: default:
break; break;
} }
return retval; return retval;
} }
static SnStartupSequence* static SnStartupSequence*
add_sequence (SnDisplay *display) add_sequence (SnDisplay *display)
{ {
SnStartupSequence *sequence; SnStartupSequence *sequence;
sequence = sequence =
sn_startup_sequence_new (display); sn_startup_sequence_new (display);
if (sequence) if (sequence)
{ {
sn_startup_sequence_ref (sequence); /* ref held by sequence list */ sn_startup_sequence_ref (sequence); /* ref held by sequence list */
if (sequence_list == NULL) if (sequence_list == NULL)
sequence_list = sn_list_new (); sequence_list = sn_list_new ();
sn_list_prepend (sequence_list, sequence); sn_list_prepend (sequence_list, sequence);
} }
return sequence; return sequence;
} }
static void static void
remove_sequence (SnStartupSequence *sequence) remove_sequence (SnStartupSequence *sequence)
{ {
sn_list_remove (sequence_list, sequence); sn_list_remove (sequence_list, sequence);
sn_startup_sequence_unref (sequence); sn_startup_sequence_unref (sequence);
} }
static void static void
dispatch_monitor_event (SnDisplay *display, dispatch_monitor_event (SnDisplay *display,
SnMonitorEvent *event) SnMonitorEvent *event)
{ {
if (event->type == SN_MONITOR_EVENT_INITIATED) if (event->type == SN_MONITOR_EVENT_INITIATED)
{ {
if (event->sequence == NULL) if (event->sequence == NULL)
event->sequence = add_sequence (display); event->sequence = add_sequence (display);
} }
if (event->sequence != NULL && if (event->sequence != NULL &&
!filter_event (event)) !filter_event (event))
{ {
CreateContextEventsData cced; CreateContextEventsData cced;
cced.base_event = event; cced.base_event = event;
cced.events = sn_list_new (); cced.events = sn_list_new ();
sn_list_foreach (context_list, create_context_events_foreach, sn_list_foreach (context_list, create_context_events_foreach,
&cced); &cced);
sn_list_foreach (cced.events, dispatch_event_foreach, NULL); sn_list_foreach (cced.events, dispatch_event_foreach, NULL);
/* values in the events list freed on dispatch */ /* values in the events list freed on dispatch */
sn_list_free (cced.events); sn_list_free (cced.events);
/* remove from sequence list */ /* remove from sequence list */
if (event->type == SN_MONITOR_EVENT_COMPLETED) if (event->type == SN_MONITOR_EVENT_COMPLETED)
remove_sequence (event->sequence); remove_sequence (event->sequence);
} }
} }
sn_bool_t sn_bool_t
sn_internal_monitor_process_event (SnDisplay *display) sn_internal_monitor_process_event (SnDisplay *display)
{ {
sn_bool_t retval; sn_bool_t retval;
if (context_list == NULL || if (context_list == NULL ||
sn_list_empty (context_list)) sn_list_empty (context_list))
return FALSE; /* no one cares */ return FALSE; /* no one cares */
retval = FALSE; retval = FALSE;
return retval; return retval;
} }
typedef struct typedef struct
{ {
SnDisplay *display; SnDisplay *display;
const char *id; const char *id;
SnStartupSequence *found; SnStartupSequence *found;
} FindSequenceByIdData; } FindSequenceByIdData;
static sn_bool_t static sn_bool_t
find_sequence_by_id_foreach (void *value, find_sequence_by_id_foreach (void *value,
void *data) void *data)
{ {
SnStartupSequence *sequence = value; SnStartupSequence *sequence = value;
FindSequenceByIdData *fsd = data; FindSequenceByIdData *fsd = data;
if (strcmp (sequence->id, fsd->id) == 0 && if (strcmp (sequence->id, fsd->id) == 0 &&
sn_internal_display_get_id (sequence->display) == sn_internal_display_get_id (sequence->display) ==
sn_internal_display_get_id (fsd->display)) sn_internal_display_get_id (fsd->display))
{ {
fsd->found = sequence; fsd->found = sequence;
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
static SnStartupSequence* static SnStartupSequence*
find_sequence_for_id (SnDisplay *display, find_sequence_for_id (SnDisplay *display,
const char *id) const char *id)
{ {
FindSequenceByIdData fsd; FindSequenceByIdData fsd;
if (sequence_list == NULL) if (sequence_list == NULL)
return NULL; return NULL;
fsd.display = display; fsd.display = display;
fsd.id = id; fsd.id = id;
fsd.found = NULL; fsd.found = NULL;
sn_list_foreach (sequence_list, find_sequence_by_id_foreach, &fsd); sn_list_foreach (sequence_list, find_sequence_by_id_foreach, &fsd);
return fsd.found; return fsd.found;
} }
static sn_bool_t static sn_bool_t
do_xmessage_event_foreach (void *value, do_xmessage_event_foreach (void *value,
void *data) void *data)
{ {
SnMonitorEvent *event = value; SnMonitorEvent *event = value;
SnDisplay *display = data; SnDisplay *display = data;
dispatch_monitor_event (display, event); dispatch_monitor_event (display, event);
return TRUE; return TRUE;
} }
static sn_bool_t static sn_bool_t
unref_event_foreach (void *value, unref_event_foreach (void *value,
void *data) void *data)
{ {
sn_monitor_event_unref (value); sn_monitor_event_unref (value);
return TRUE; return TRUE;
} }
static void static void
xmessage_func (SnDisplay *display, xmessage_func (SnDisplay *display,
const char *message_type, const char *message_type,
const char *message, const char *message,
void *user_data) void *user_data)
{ {
/* assert (strcmp (message_type, KDE_STARTUP_INFO_ATOM) == 0); */ /* assert (strcmp (message_type, KDE_STARTUP_INFO_ATOM) == 0); */
char *prefix; char *prefix;
char **names; char **names;
char **values; char **values;
int i; int i;
const char *launch_id; const char *launch_id;
SnStartupSequence *sequence; SnStartupSequence *sequence;
SnList *events; SnList *events;
prefix = NULL; prefix = NULL;
names = NULL; names = NULL;
values = NULL; values = NULL;
if (!sn_internal_unserialize_message (message, &prefix, &names, &values)) if (!sn_internal_unserialize_message (message, &prefix, &names, &values))
return; return;
launch_id = NULL; launch_id = NULL;
i = 0; i = 0;
while (names[i]) while (names[i])
{ {
if (strcmp (names[i], "ID") == 0) if (strcmp (names[i], "ID") == 0)
{ {
launch_id = values[i]; launch_id = values[i];
break; break;
} }
++i; ++i;
} }
events = sn_list_new (); events = sn_list_new ();
if (launch_id == NULL) if (launch_id == NULL)
goto out; goto out;
sequence = find_sequence_for_id (display, launch_id); sequence = find_sequence_for_id (display, launch_id);
if (strcmp (prefix, "new") == 0) if (strcmp (prefix, "new") == 0)
{ {
if (sequence == NULL) if (sequence == NULL)
{ {
SnMonitorEvent *event; SnMonitorEvent *event;
char *time_str; char *time_str;
sequence = add_sequence (display);
if (sequence == NULL)
goto out;
sequence->id = sn_internal_strdup (launch_id);
/* Current spec says timestamp is part of the startup id; so we need sequence = add_sequence (display);
* to get the timestamp here if the launcher is using the current sp if (sequence == NULL)
ec goto out;
*/
time_str = sn_internal_find_last_occurrence (sequence->id, "_TIME"); sequence->id = sn_internal_strdup (launch_id);
if (time_str != NULL)
/* Current spec says timestamp is part of the startup id; so we need
* to get the timestamp here if the launcher is using the current spec
*/
time_str = sn_internal_find_last_occurrence (sequence->id, "_TIME");
if (time_str != NULL)
{ {
/* Skip past the "_TIME" part */ /* Skip past the "_TIME" part */
time_str += 5; time_str += 5;
sequence->timestamp = sn_internal_string_to_ulong (time_str); sequence->timestamp = sn_internal_string_to_ulong (time_str);
sequence->timestamp_set = TRUE; sequence->timestamp_set = TRUE;
} }
event = sn_new (SnMonitorEvent, 1); event = sn_new (SnMonitorEvent, 1);
event->refcount = 1; event->refcount = 1;
event->type = SN_MONITOR_EVENT_INITIATED; event->type = SN_MONITOR_EVENT_INITIATED;
event->context = NULL; event->context = NULL;
event->sequence = sequence; /* ref from add_sequence goes here */ event->sequence = sequence; /* ref from add_sequence goes here */
sn_list_append (events, event); sn_list_append (events, event);
} }
} }
if (sequence == NULL) if (sequence == NULL)
goto out; goto out;
if (strcmp (prefix, "change") == 0 || if (strcmp (prefix, "change") == 0 ||
strcmp (prefix, "new") == 0) strcmp (prefix, "new") == 0)
{ {
sn_bool_t changed = FALSE; sn_bool_t changed = FALSE;
i = 0; i = 0;
while (names[i]) while (names[i])
{ {
if (strcmp (names[i], "BIN") == 0) if (strcmp (names[i], "BIN") == 0)
{ {
if (sequence->binary_name == NULL) if (sequence->binary_name == NULL)
{ {
sequence->binary_name = sn_internal_strdup (values[i]); sequence->binary_name = sn_internal_strdup (values[i]);
changed = TRUE; changed = TRUE;
} }
} }
else if (strcmp (names[i], "NAME") == 0) else if (strcmp (names[i], "NAME") == 0)
{ {
if (sequence->name == NULL) if (sequence->name == NULL)
{ {
sequence->name = sn_internal_strdup (values[i]); sequence->name = sn_internal_strdup (values[i]);
changed = TRUE; changed = TRUE;
} }
} }
else if (strcmp (names[i], "SCREEN") == 0) else if (strcmp (names[i], "SCREEN") == 0)
{ {
if (sequence->screen < 0) if (sequence->screen < 0)
{ {
int n; int n;
n = atoi (values[i]); n = atoi (values[i]);
if (n >= 0 && n < sn_internal_display_get_screen_number (seq if (n >= 0 && n < sn_internal_display_get_screen_number (seque
uence->display)) nce->display))
{ {
sequence->screen = n; sequence->screen = n;
changed = TRUE; changed = TRUE;
} }
} }
} }
else if (strcmp (names[i], "DESCRIPTION") == 0) else if (strcmp (names[i], "DESCRIPTION") == 0)
{ {
if (sequence->description == NULL) if (sequence->description == NULL)
{ {
sequence->description = sn_internal_strdup (values[i]); sequence->description = sn_internal_strdup (values[i]);
changed = TRUE; changed = TRUE;
} }
} }
else if (strcmp (names[i], "ICON") == 0) else if (strcmp (names[i], "ICON") == 0)
{ {
if (sequence->icon_name == NULL) if (sequence->icon_name == NULL)
{ {
sequence->icon_name = sn_internal_strdup (values[i]); sequence->icon_name = sn_internal_strdup (values[i]);
changed = TRUE; changed = TRUE;
} }
} }
else if (strcmp (names[i], "DESKTOP") == 0) else if (strcmp (names[i], "APPLICATION_ID") == 0)
{ {
int workspace; if (sequence->application_id == NULL)
{
workspace = sn_internal_string_to_ulong (values[i]); sequence->application_id = sn_internal_strdup (values[i]);
changed = TRUE;
sequence->workspace = workspace; }
changed = TRUE;
} }
else if (strcmp (names[i], "TIMESTAMP") == 0 && else if (strcmp (names[i], "DESKTOP") == 0)
!sequence->timestamp_set)
{ {
/* Old version of the spec says that the timestamp was int workspace;
* sent as part of a TIMESTAMP message. We try to
* handle that to enable backwards compatibility with
* older launchers.
*/
Time timestamp;
timestamp = sn_internal_string_to_ulong (values[i]); workspace = sn_internal_string_to_ulong (values[i]);
sequence->timestamp = timestamp; sequence->workspace = workspace;
sequence->timestamp_set = TRUE; changed = TRUE;
changed = TRUE; }
else if (strcmp (names[i], "TIMESTAMP") == 0 &&
!sequence->timestamp_set)
{
/* Old version of the spec says that the timestamp was
* sent as part of a TIMESTAMP message. We try to
* handle that to enable backwards compatibility with
* older launchers.
*/
Time timestamp;
timestamp = sn_internal_string_to_ulong (values[i]);
sequence->timestamp = timestamp;
sequence->timestamp_set = TRUE;
changed = TRUE;
} }
else if (strcmp (names[i], "WMCLASS") == 0) else if (strcmp (names[i], "WMCLASS") == 0)
{ {
if (sequence->wmclass == NULL) if (sequence->wmclass == NULL)
{ {
sequence->wmclass = sn_internal_strdup (values[i]); sequence->wmclass = sn_internal_strdup (values[i]);
changed = TRUE; changed = TRUE;
} }
} }
++i; ++i;
} }
if (strcmp (prefix, "new") == 0) if (strcmp (prefix, "new") == 0)
{ {
if (sequence->screen < 0) if (sequence->screen < 0)
{ {
SnMonitorEvent *event; SnMonitorEvent *event;
event = sn_new (SnMonitorEvent, 1); event = sn_new (SnMonitorEvent, 1);
event->refcount = 1; event->refcount = 1;
event->type = SN_MONITOR_EVENT_COMPLETED; event->type = SN_MONITOR_EVENT_COMPLETED;
event->context = NULL; event->context = NULL;
event->sequence = sequence; event->sequence = sequence;
sn_startup_sequence_ref (sequence); sn_startup_sequence_ref (sequence);
sn_list_append (events, event); sn_list_append (events, event);
fprintf (stderr, fprintf (stderr,
"Ending startup notification for %s (%s) because SCREEN "Ending startup notification for %s (%s) because SCREEN "
" "field was not provided; this is a bug in the launcher "
"field was not provided; this is a bug in the launcher "application\n",
" sequence->name ? sequence->name : "???",
"application\n", sequence->binary_name ? sequence->binary_name : "???");
sequence->name ? sequence->name : "???",
sequence->binary_name ? sequence->binary_name : "???");
} }
} }
else if (changed) else if (changed)
{ {
SnMonitorEvent *event; SnMonitorEvent *event;
event = sn_new (SnMonitorEvent, 1); event = sn_new (SnMonitorEvent, 1);
event->refcount = 1; event->refcount = 1;
event->type = SN_MONITOR_EVENT_CHANGED; event->type = SN_MONITOR_EVENT_CHANGED;
event->context = NULL; event->context = NULL;
event->sequence = sequence; event->sequence = sequence;
sn_startup_sequence_ref (sequence); sn_startup_sequence_ref (sequence);
sn_list_append (events, event); sn_list_append (events, event);
} }
} }
else if (strcmp (prefix, "remove") == 0) else if (strcmp (prefix, "remove") == 0)
{ {
SnMonitorEvent *event; SnMonitorEvent *event;
event = sn_new (SnMonitorEvent, 1); event = sn_new (SnMonitorEvent, 1);
event->refcount = 1; event->refcount = 1;
event->type = SN_MONITOR_EVENT_COMPLETED; event->type = SN_MONITOR_EVENT_COMPLETED;
event->context = NULL; event->context = NULL;
event->sequence = sequence; event->sequence = sequence;
sn_startup_sequence_ref (sequence); sn_startup_sequence_ref (sequence);
sn_list_append (events, event); sn_list_append (events, event);
} }
sn_list_foreach (events, sn_list_foreach (events,
do_xmessage_event_foreach, do_xmessage_event_foreach,
display); display);
out: out:
if (events != NULL) if (events != NULL)
{ {
sn_list_foreach (events, unref_event_foreach, NULL); sn_list_foreach (events, unref_event_foreach, NULL);
sn_list_free (events); sn_list_free (events);
} }
sn_free (prefix); sn_free (prefix);
sn_internal_strfreev (names); sn_internal_strfreev (names);
sn_internal_strfreev (values); sn_internal_strfreev (values);
} }
 End of changes. 196 change blocks. 
422 lines changed or deleted 436 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)