Logo Search packages:      
Sourcecode: sanduhr version File versions  Download package

alarm.c

/* alarm.c - signal an alarm to the user
 *
 * Copyright (C) 1999, 2000  Jochen Voss.  */

static const  char  rcsid[] = "$Id: alarm.c,v 1.13 2002/01/02 12:39:48 voss Rel $";


#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdlib.h>
#include <string.h>
#include <time.h>

#include <gnome.h>

#include "interface.h"
#include "support.h"
#include "sandcommon.h"


/**********************************************************************
 * callback functions
 */

static void
delete_alarm_beep (struct alarm_beep *alarm)
{
  PortableServer_ObjectId *objid;
  CORBA_Environment  ev;

  g_assert (alarm->ref == 0 && ! alarm->delivering);
  
  CORBA_exception_init (&ev);
  objid = PortableServer_POA_servant_to_id (alarm->poa, alarm, &ev);
  PortableServer_POA_deactivate_object (alarm->poa, objid, &ev);
  CORBA_free (objid);

  POA_SandUhr_AlarmBeep__fini ((PortableServer_Servant) alarm, &ev);
  g_free (alarm);

  check_corba_error (&ev, NULL);
}

static void
delete_alarm_sound (struct alarm_sound *alarm)
{
  PortableServer_ObjectId *objid;
  CORBA_Environment  ev;
    
  CORBA_exception_init (&ev);
  objid = PortableServer_POA_servant_to_id (alarm->poa, alarm, &ev);
  PortableServer_POA_deactivate_object (alarm->poa, objid, &ev);
  CORBA_free (objid);

  POA_SandUhr_AlarmSound__fini ((PortableServer_Servant) alarm, &ev);
  g_free (alarm->file);
  g_free (alarm);

  check_corba_error (&ev, NULL);
}

static void
delete_alarm_command (struct alarm_command *alarm)
{
  PortableServer_ObjectId *objid;
  CORBA_Environment  ev;
    
  CORBA_exception_init (&ev);
  objid = PortableServer_POA_servant_to_id (alarm->poa, alarm, &ev);
  PortableServer_POA_deactivate_object (alarm->poa, objid, &ev);
  CORBA_free (objid);

  POA_SandUhr_AlarmCommand__fini ((PortableServer_Servant) alarm, &ev);
  g_free (alarm->command);
  g_free (alarm);

  check_corba_error (&ev, NULL);
}

static gint
beep_cb (gpointer data)
/* Helper function to iterate the console beep.  */
{
  struct alarm_beep *alarm = data;
  
  gdk_beep ();
  --alarm->count;
  
  if (alarm->count > 0) {
    return  TRUE;
  } else {
    alarm->delivering = FALSE;
    if (alarm->ref <= 0)  delete_alarm_beep (alarm);
    return  FALSE;
  }
}

/**********************************************************************
 * Implement the CORBA servant
 */

static CORBA_unsigned_short
impl_SandUhr_AlarmBeep__get_Count (struct alarm_beep *alarm,
                           CORBA_Environment *ev)
{
  return  alarm->count;
}

static void
impl_SandUhr_AlarmBeep__set_Count (struct alarm_beep *alarm,
                           CORBA_unsigned_short value,
                           CORBA_Environment *ev)
{
  alarm->count = value;
}

static CORBA_boolean
impl_SandUhr_AlarmBeep__get_NeedsPopup (struct alarm_beep *alarm,
                              CORBA_Environment *ev)
{
  return  CORBA_TRUE;
}

static void
impl_SandUhr_AlarmBeep_Attach (struct alarm_beep *alarm,
                         SandUhr_Timer T,
                         CORBA_Environment *ev)
{
  alarm->ref += 1;
}

static void
impl_SandUhr_AlarmBeep_Detach (struct alarm_beep *alarm,
                         SandUhr_Timer T,
                         CORBA_Environment *ev)
{
  alarm->ref -= 1;
  if (alarm->ref <= 0 && ! alarm->delivering)  delete_alarm_beep (alarm);
}

static void
impl_SandUhr_AlarmBeep_Deliver (struct alarm_beep *alarm,
                        CORBA_char *TimeSpec,
                        CORBA_char *Message,
                        CORBA_Environment *ev)
{
  if (alarm->count > 0) {
    gdk_beep ();
    -- alarm->count;
  }
  if (alarm->count > 0) {
    gtk_timeout_add (450, beep_cb, alarm);
    alarm->delivering = TRUE;
  } else {
    alarm->delivering = FALSE;
  }
}

static CORBA_char *
impl_SandUhr_AlarmSound__get_SoundFile (struct alarm_sound *alarm,
                              CORBA_Environment *ev)
{
  CORBA_char *retval;

  retval = CORBA_string_dup (alarm->file);
  return retval;
}

static void
impl_SandUhr_AlarmSound__set_SoundFile (struct alarm_sound *alarm,
                              CORBA_char *value,
                              CORBA_Environment *ev)
{
  g_free (alarm->file);
  alarm->file = g_strdup (value);
}

static CORBA_boolean
impl_SandUhr_AlarmSound__get_NeedsPopup (struct alarm_sound *alarm,
                               CORBA_Environment *ev)
{
  return  CORBA_TRUE;
}

static void
impl_SandUhr_AlarmSound_Attach (struct alarm_sound *alarm,
                        SandUhr_Timer T,
                        CORBA_Environment *ev)
{
  return;
}

static void
impl_SandUhr_AlarmSound_Detach (struct alarm_sound *alarm,
                        SandUhr_Timer T,
                        CORBA_Environment *ev)
{
  delete_alarm_sound (alarm);
}

static void
impl_SandUhr_AlarmSound_Deliver (struct alarm_sound *alarm,
                         CORBA_char *TimeSpec,
                         CORBA_char *Message,
                         CORBA_Environment *ev)
{
  gnome_sound_play (alarm->file);
}

static CORBA_char *
impl_SandUhr_AlarmCommand__get_CommandString (struct alarm_command *alarm,
                                    CORBA_Environment *ev)
{
  CORBA_char *retval;

  retval = CORBA_string_dup (alarm->command);
  return retval;
}

static void
impl_SandUhr_AlarmCommand__set_CommandString (struct alarm_command *alarm,
                                    CORBA_char *value,
                                    CORBA_Environment *ev)
{
  g_free (alarm->command);
  alarm->command = g_strdup (value);
}

static CORBA_boolean
impl_SandUhr_AlarmCommand__get_NeedsPopup (struct alarm_command *alarm,
                                 CORBA_Environment *ev)
{
  return  CORBA_TRUE;
}

static void
impl_SandUhr_AlarmCommand_Attach (struct alarm_command *alarm,
                          SandUhr_Timer T,
                          CORBA_Environment *ev)
{
  return;
}

static void
impl_SandUhr_AlarmCommand_Detach (struct alarm_command *alarm,
                          SandUhr_Timer T,
                          CORBA_Environment *ev)
{
  delete_alarm_command (alarm);
}

static void
impl_SandUhr_AlarmCommand_Deliver (struct alarm_command *alarm,
                           CORBA_char *TimeSpec,
                           CORBA_char *Message,
                           CORBA_Environment *ev)
{
  int  res;

  res = gnome_execute_shell (NULL, alarm->command);
  if (res == -1) {
    SandUhr_AlarmAction_DeliveryFailed *exn;
    
    exn = SandUhr_AlarmAction_DeliveryFailed__alloc ();
    exn->Reason = CORBA_string_dup (_("Execution of external command failed"));
    CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
                   ex_SandUhr_AlarmAction_DeliveryFailed,
                   exn);
  }
}

/**********************************************************************
 * epv structures
 */

static PortableServer_ServantBase__epv impl_SandUhr_AlarmBeep_base_epv = {
  NULL,                       /* _private data */
  NULL,                       /* finalize routine */
  NULL,                       /* default_POA routine */
};

static POA_SandUhr_AlarmBeep__epv impl_SandUhr_AlarmBeep_epv = {
  NULL,                       /* _private */
  (gpointer) &impl_SandUhr_AlarmBeep__get_Count,
  (gpointer) &impl_SandUhr_AlarmBeep__set_Count,

};

static POA_SandUhr_AlarmAction__epv impl_SandUhr_AlarmBeep_SandUhr_AlarmAction_epv = {
  NULL,                       /* _private */
  (gpointer) &impl_SandUhr_AlarmBeep__get_NeedsPopup,
  (gpointer) &impl_SandUhr_AlarmBeep_Attach,
  (gpointer) &impl_SandUhr_AlarmBeep_Detach,
  (gpointer) &impl_SandUhr_AlarmBeep_Deliver,
};

static PortableServer_ServantBase__epv impl_SandUhr_AlarmSound_base_epv = {
  NULL,                       /* _private data */
  NULL,                       /* finalize routine */
  NULL,                       /* default_POA routine */
};

static POA_SandUhr_AlarmSound__epv impl_SandUhr_AlarmSound_epv = {
  NULL,                       /* _private */
  (gpointer) &impl_SandUhr_AlarmSound__get_SoundFile,
  (gpointer) &impl_SandUhr_AlarmSound__set_SoundFile,

};

static POA_SandUhr_AlarmAction__epv impl_SandUhr_AlarmSound_SandUhr_AlarmAction_epv = {
  NULL,                       /* _private */
  (gpointer) &impl_SandUhr_AlarmSound__get_NeedsPopup,
  (gpointer) &impl_SandUhr_AlarmSound_Attach,
  (gpointer) &impl_SandUhr_AlarmSound_Detach,
  (gpointer) &impl_SandUhr_AlarmSound_Deliver,
};

static PortableServer_ServantBase__epv impl_SandUhr_AlarmCommand_base_epv = {
  NULL,                       /* _private data */
  NULL,                       /* finalize routine */
  NULL,                       /* default_POA routine */
};

static POA_SandUhr_AlarmCommand__epv impl_SandUhr_AlarmCommand_epv = {
  NULL,                       /* _private */
  (gpointer) &impl_SandUhr_AlarmCommand__get_CommandString,
  (gpointer) &impl_SandUhr_AlarmCommand__set_CommandString,

};

static POA_SandUhr_AlarmAction__epv
  impl_SandUhr_AlarmCommand_SandUhr_AlarmAction_epv = {
  NULL,                       /* _private */
  (gpointer) &impl_SandUhr_AlarmCommand__get_NeedsPopup,
  (gpointer) &impl_SandUhr_AlarmCommand_Attach,
  (gpointer) &impl_SandUhr_AlarmCommand_Detach,
  (gpointer) &impl_SandUhr_AlarmCommand_Deliver,
};

static POA_SandUhr_AlarmBeep__vepv impl_SandUhr_AlarmBeep_vepv = {
  &impl_SandUhr_AlarmBeep_base_epv,
  &impl_SandUhr_AlarmBeep_SandUhr_AlarmAction_epv,
  &impl_SandUhr_AlarmBeep_epv,
};

static POA_SandUhr_AlarmSound__vepv impl_SandUhr_AlarmSound_vepv = {
  &impl_SandUhr_AlarmSound_base_epv,
  &impl_SandUhr_AlarmSound_SandUhr_AlarmAction_epv,
  &impl_SandUhr_AlarmSound_epv,
};

static POA_SandUhr_AlarmCommand__vepv impl_SandUhr_AlarmCommand_vepv = {
  &impl_SandUhr_AlarmCommand_base_epv,
  &impl_SandUhr_AlarmCommand_SandUhr_AlarmAction_epv,
  &impl_SandUhr_AlarmCommand_epv,
};

/**********************************************************************
 * external functions for AlarmAction objects
 */

struct alarm_beep *
create_alarm_beep (PortableServer_POA poa, unsigned count,
               CORBA_Environment *ev)
{
  struct alarm_beep *alarm;
  PortableServer_ObjectId *objid;

  alarm = g_new0 (struct alarm_beep, 1);
  alarm->servant.vepv = &impl_SandUhr_AlarmBeep_vepv;
  alarm->poa = poa;
  POA_SandUhr_AlarmBeep__init ((PortableServer_Servant) alarm, ev);

  alarm->delivering = FALSE;
  alarm->ref = 0;
  alarm->count = count;

  objid = PortableServer_POA_activate_object (poa, alarm, ev);
  CORBA_free (objid);
  
  return  alarm;
}

struct alarm_sound *
create_alarm_sound (PortableServer_POA poa, const char *file,
                CORBA_Environment *ev)
{
  struct alarm_sound *alarm;
  PortableServer_ObjectId *objid;

  alarm = g_new0 (struct alarm_sound, 1);
  alarm->servant.vepv = &impl_SandUhr_AlarmSound_vepv;
  alarm->poa = poa;
  POA_SandUhr_AlarmSound__init ((PortableServer_Servant) alarm, ev);

  alarm->file = g_strdup (file);
  
  objid = PortableServer_POA_activate_object (poa, alarm, ev);
  CORBA_free (objid);

  return  alarm;
}

struct alarm_command *
create_alarm_command (PortableServer_POA poa, const char *command,
                  CORBA_Environment *ev)
{
  struct alarm_command *alarm;
  PortableServer_ObjectId *objid;

  alarm = g_new0 (struct alarm_command, 1);
  alarm->servant.vepv = &impl_SandUhr_AlarmCommand_vepv;
  alarm->poa = poa;
  POA_SandUhr_AlarmCommand__init ((PortableServer_Servant) alarm, ev);

  alarm->command = g_strdup (command);
  
  objid = PortableServer_POA_activate_object (poa, alarm, ev);
  CORBA_free (objid);

  return  alarm;
}

static void
message_destroy_cb (GtkObject *obj, gpointer data)
/* This may be used as a "destroy" signal handler.  */
{
  struct timer *timer = data;
  CORBA_Environment  ev;
 
  CORBA_exception_init (&ev);
  delete_timer (timer);
  check_corba_error (&ev, NULL);
}

static void
display_popup_window (struct timer *timer)
{
  GtkWidget *messagebox;
  gchar *msg;
  
  msg = timer_get_message (timer);
  messagebox = gnome_ok_dialog_parented (msg, GTK_WINDOW (timer->window));
  g_free (msg);
  gtk_signal_connect (GTK_OBJECT (messagebox),
                  "destroy",
                  GTK_SIGNAL_FUNC (message_destroy_cb),
                  timer);
  if (gnome_win_hints_wm_exists ()) {
    gnome_win_hints_set_layer (GTK_WIDGET(messagebox), WIN_LAYER_ONTOP);
  }
  gtk_widget_show (messagebox);
}

void
deliver_alarm (struct timer *timer)
/* This must be called when the alarm time is reached.  */
{
  CORBA_Environment  ev;
  CORBA_char *exid;
  CORBA_boolean  popup;
  char  buffer [64];
  
  CORBA_exception_init (&ev);

  timer->state = SandUhr_Timer_TSDone;
  if (timer->prop_windows) {
    GSList *pwlist = timer->prop_windows;
    do {
      properties_timer_stopped (GTK_WIDGET (pwlist->data));
      pwlist = pwlist->next;
    } while (pwlist);
  }

  popup = SandUhr_AlarmAction__get_NeedsPopup (timer->alarm, &ev);
  if (ev._major != CORBA_NO_EXCEPTION)  popup = FALSE;
  if (popup)  display_popup_window (timer);
  
  strftime (buffer, 64, "%c", localtime (&timer->target_time_abs));
  SandUhr_AlarmAction_Deliver (timer->alarm, buffer, timer->message, &ev);
  exid = CORBA_exception_id (&ev);
  if (exid && strcmp (exid, ex_SandUhr_AlarmAction_DeliveryFailed) == 0) {
    SandUhr_AlarmAction_DeliveryFailed *exn;
    gchar *message;

    exn = CORBA_exception_value (&ev);
    message = g_strdup_printf (_("alarm delivery failed for message\n"
                         "\"%s\"\n"
                         "(%s)."), timer->message, exn->Reason);
    display_error_message (message, GTK_WINDOW (timer->window));
    g_free (message);
    CORBA_exception_free (&ev);
  }
  
  check_corba_error (&ev, GTK_WINDOW (timer->window));

  if (! popup)  delete_timer (timer);
}

Generated by  Doxygen 1.6.0   Back to index