File: timer.c

package info (click to toggle)
gworldclock 1.4.4-10
  • links: PTS
  • area: main
  • in suites: stretch
  • size: 1,016 kB
  • ctags: 159
  • sloc: sh: 3,855; ansic: 2,241; makefile: 75; sed: 16
file content (198 lines) | stat: -rw-r--r-- 5,126 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <gtk/gtk.h>
#include <time.h>
#include <string.h>

#include "main.h"
#include "timer.h"
#include "misc.h"

/*  display format for time&date  */
GString *displayFormat;


/* functions related to running the timer, displaying the times in each zone */
void  start_clocks(gpointer clocklist)
{
  FILE *cf;
  extern gint changed;
  extern GString *configfile;
  extern gchar *defaultConfigFilename;
  GtkTreeModel *clocklistModel;

  /* format of list:
     name of time zone (TZ variable), description, time in zone
  */
  gchar *rowdata[2], *localstr="Local";
  /* is there a way of reading the information without hardwiring '200' here?
     eg can flag 'a' in sscanf work with %[ as well as %s ? */
  gchar description[200], *timezone, line[200];
  int row;
  GString *title, *msg;
  gchar *button[]={"OK"};
  GtkTreeIter   iter;

  /* ??? associate configfile with list as widget data ?? */

  rowdata[1]=NULL; /* necessary to set to NULL, or segfault related
		      to List Reordering results */
  

  clocklistModel = gtk_tree_view_get_model( GTK_TREE_VIEW(clocklist) );
  cf=fopen(configfile->str,"r");
  if (cf) 
  {
    while(fgets(line,200,cf)) 
    {

      /* configfile is assumed to have two entries per line,
	 the TZ value followed by a description enclosed in quotation marks.
	 If the description is missing, the TZ string is used as a description instead */
      /* the second entry looks complicated, but just copies the whole set of
	 characters between two quotation marks
	 [finds the first '"', accounting for any spaces or tabs, 
	 then grabs everything up to the second '"'] */

      if ( sscanf(line,"%ms %*[ \t\"]%[^\"]",&timezone,description) < 2 )
	strncpy(description,timezone,200);

      gtk_list_store_append ( GTK_LIST_STORE(clocklistModel), &iter);
      gtk_list_store_set ( GTK_LIST_STORE(clocklistModel), &iter,
			   TZ_NAME, timezone,
			   TZ_DESCRIPTION, description,
			   -1);     
    }
    fclose(cf);
  } 
  else 
  {
     /* ignore error if it simply means the zone file does not (yet) exist,
      otherwise, report it to the user */
     if ( errno != ENOENT ) 
     {
	  title = g_string_new("Read Zone File");
	  msg = g_string_new(NULL);
	  g_string_sprintf(msg," Error reading zone file \"%s\": \n %s \n",
		     configfile->str,  g_strerror(errno) );
	  showMessageDialog( msg->str, GTK_MESSAGE_ERROR );
	  g_string_free(msg,TRUE);
	  g_string_free(title,TRUE);
     }
     
     gtk_list_store_append ( GTK_LIST_STORE(clocklistModel), &iter);
     gtk_list_store_set ( GTK_LIST_STORE(clocklistModel), &iter,
			  TZ_NAME, localstr,
			  TZ_DESCRIPTION, localstr,
			  -1);     
    changed=1;
  }
  SetTime(clocklist);
}

gint SetTime(gpointer clocklist)
{
   time_t currenttime;

   time(&currenttime);

   gtk_widget_freeze_child_notify( GTK_WIDGET(clocklist) );

   gtk_tree_model_foreach( gtk_tree_view_get_model(GTK_TREE_VIEW(clocklist)),
			   (GtkTreeModelForeachFunc) SetToGivenTime,
			   (gpointer) currenttime );

   gtk_widget_thaw_child_notify( GTK_WIDGET(clocklist) );

   return 1;
}

gboolean SetToGivenTime  (GtkTreeModel *clocklistModel,
			  GtkTreePath *path,
			  GtkTreeIter *iter,
			  gpointer timeToSet)
{
  gchar *timezone, *TZdefault;
  gint N,i;
  char rawTimeDisplay[TIME_DISPLAY_SIZE];
  gchar *timeDisplay;

  TZdefault = (gchar *)getenv("TZ");
  gtk_tree_model_get( clocklistModel, iter,
		      TZ_NAME, &timezone,
		      -1);

  if(strcasecmp(timezone,"Local"))
    setenv("TZ",timezone,1);
  else 
    {
    /* local time is set by the ordinary value of TZ */
    if (TZdefault)
      setenv("TZ",TZdefault,1);
    else
      unsetenv("TZ");
  }

  strftime (rawTimeDisplay, TIME_DISPLAY_SIZE, 
	    displayFormat->str, 
	    localtime( (time_t *) &timeToSet ) 
     );
  timeDisplay = g_locale_to_utf8 ( rawTimeDisplay,
				   -1, NULL, NULL, NULL );

  gtk_list_store_set ( GTK_LIST_STORE(clocklistModel), iter,
		       TZ_TIMEDATE, timeDisplay,
		       -1);     

  g_free( timeDisplay );

  if (TZdefault)
    setenv("TZ",TZdefault,1);
  else
    unsetenv("TZ");

  g_free(timezone);

  return FALSE;
}

gint start_timer( gpointer clocklist )
{
    /* by default update every minute = 60,000 ms */
    int beatInterval = 60000;

    /* 
       Change to seconds beat when needed.
       All the date formats which show seconds are listed here. 
    */
    if ( strstr( displayFormat->str, "%c" ) ||
	 strstr( displayFormat->str, "%N" ) ||
	 strstr( displayFormat->str, "%r" ) ||
	 strstr( displayFormat->str, "%s" ) ||
	 strstr( displayFormat->str, "%S" ) ||
	 strstr( displayFormat->str, "%T" ) ||
	 strstr( displayFormat->str, "%X" )   )
    {
	beatInterval = 1000;
    }

    return g_timeout_add( beatInterval, SetTime, clocklist);
}

void stop_timer()
{
   extern gint timer;
   g_source_remove( timer );

   /* set timer to -1 to show that there is no timer, and therefore
      synchronisation is taking place */
   timer = -1;
}

void reset_timer( gpointer clocklist )
{
    extern gint timer;
    stop_timer();
    timer = start_timer( clocklist );
}