wmail: strcasecmp and strncasecmp are properly declared in strings.h.
[dockapps.git] / wmcalendar / Src / wmCalendar.c
blob39496a9f447f74b86f742481f6ec8e70092952c7
1 /*------------------------------------------------------
3 * wmCalendar (c)2003 Matthias Laabs
5 * mattlaabs@users.sourceforge.net
7 * a calendar dockapp
8 -----------------------------------------------------*/
10 #include "wmCalendar.h"
12 /*------------------------------------------------------
13 * main
14 -----------------------------------------------------*/
15 int main(int argc, char *argv[])
17 int n = 0;
18 getSettings();
19 ParseCMDLine(argc, argv);
20 if(get_debug())printf("debugging mode:\nstarting wmCalendar version %s\n", getVersion());
21 if(get_debug())printf("using libical version %s\n", ICAL_VERSION);
22 dockapp_open_window("", "wmCalendar", 64, 64, argc, argv);
23 initValues();
24 gtk_init(&argc, &argv);
25 checkicalversion();
27 /* Loop until we die */
28 while(1) {
29 if(n == 0){ /* do updates only every COUNTERth time */
30 getTime();
31 calendar();
32 draw();
34 n = COUNTER;
36 /* check for events every time */
37 n--;
38 if(processXEvents())
39 n = 0;
46 /*------------------------------------------------------
47 * draw
48 -----------------------------------------------------*/
49 void draw()
52 blankScreen();
53 drawButtons();
54 drawDays();
55 drawMonthYear();
60 /*------------------------------------------------------
61 * initValues
62 -----------------------------------------------------*/
63 void initValues(){
64 XClassHint class_hints;
65 XpmColorSymbol colors[2];
66 int i, j;
67 monthOffset = 0;
68 class_hints.res_name="wmCalendar";
69 class_hints.res_class="wmCalendar";
70 /* Compute widths of months and digits */
71 for(i = 0; i < 12; ++i)
72 for( j = 0; j < 6; ++j)
73 xdMonth[j][i] = xeMonth[j][i] - xsMonth[j][i] + 1;
74 for(i = 0; i < 12; ++i)
75 for( j = 0; j < 2; ++j)
76 xdYear[j][i] = xeYear[j][i] - xsYear[j][i] + 1;
77 for(i = 0; i < MAXBUTTON; ++i)
78 xdButton[i] = xeButton[i] - xsButton[i] + 1;
80 dockapp_set_eventmask();
81 dockapp_xpm2pixmap( wmCalendar_master2_xpm, &bg[1], &mask, colors, 0);
82 dockapp_xpm2pixmap( wmCalendar_master_xpm, &bg[0], &mask, colors, 0);
83 pixmap = dockapp_XCreatePixmap(64, 64);
84 dockapp_setshape(mask, 0, 0);
85 if(mask)
86 XFreePixmap(display, mask);
87 dockapp_set_background(pixmap);
88 dockapp_show();
93 /*------------------------------------------------------
94 * read_stream
95 -----------------------------------------------------*/
96 char* read_stream(char *s, size_t size, void *d){
97 char *c = fgets(s, size, (FILE*)d);
98 return c;
102 /*------------------------------------------------------
103 * getClickedDay
104 -----------------------------------------------------*/
105 int getClickedDay(int bx, int by)
107 int dayofweek, week, day;
108 dayofweek = bx / 9 + 1;
109 week = (by - 20) / 7;
110 tgr = get_civil(t, calendartype);
111 day = dayofweek + 7 * week - ((day_of_week(tgr) - t.day + 37 + get_start_of_week()) % 7);
112 if(day <= days_in_month(t.month, t.year, calendartype) && day > 0){
113 tgr.day = day;
114 tgr.month = t.month;
115 tgr.year = t.year;
116 tgr = get_civil(tgr, calendartype);
117 return 1;
119 return 0;
124 /*------------------------------------------------------
125 * getClickedButton
126 -----------------------------------------------------*/
127 int getClickedButton(int bx, int by)
129 if(bx < 12 && by < 12) /* arrow left : month back*/
130 return BT_BACK;
131 else if(bx > 50 && by < 12) /* arrow right : month forward*/
132 return BT_FORWARD;
133 else if(bx > 52 && by > 56) /* show/hide buttons */
134 return BT_OPENCLOSE;
135 else if(showbuttons){
136 if(bx < 46 && bx > 37 && by > 55) /* toggle gregorian/persian/... */
137 return BT_MOON ;
138 else if(bx < 52 && bx > 46 && by > 55) /* open settings dialog */
139 return BT_SETTINGS;
140 else if(bx < 37 && bx > 28 && by > 55) /* toggle moonphase on/off */
141 return BT_CALTYPE;
142 else if(bx < 28 && bx > 19 && by > 55) /* start calendar application */
143 return BT_APP;
145 return 0;
150 /*------------------------------------------------------
151 * ButtonPressEvent
152 -----------------------------------------------------*/
153 void buttonPress(int btype, int bx, int by, long etime){
154 char* applaunch;
155 if(get_debug() > 1) printf("push button %d\n", btype);
157 switch(btype){
158 case 1: /* leftmouse - button or mark */
159 switch ( getClickedButton(bx, by)){
160 case BT_BACK: /* arrow left : month back*/
161 monthOffset--;
162 break;
164 case BT_FORWARD: /* arrow right : month forward*/
165 monthOffset++;
166 break;
168 case BT_OPENCLOSE: /* show/hide buttons */
169 showbuttons = 1 - showbuttons;
170 break;
172 case BT_CALTYPE: /* toggle gregorian/persian/... */
173 calendartype = (calendartype + 1) % CALTYPES;
174 break;
176 case BT_MOON:/* toggle moonphase on/off */
177 showmoon = 1 - showmoon ;
178 break;
180 case BT_SETTINGS: /* open settings dialog */
181 openSettings();
182 break;
184 case BT_APP: /* start calendar application */
185 if(appDoubleClick && (etime - appClickTime < DBLCLKTIME)){
186 applaunch = malloc(250);
187 strcpy(applaunch, (const char*)get_application());
188 strcat(applaunch, " &");
189 system(applaunch);
190 appDoubleClick = 0;
191 free(applaunch);
193 else{
194 appDoubleClick = 1;
195 appClickTime = etime;
197 break;
199 default: /* no button clicked check for marking days*/
200 if(getClickedDay(bx, by)){
201 if(!icaltime_is_null_time(mark))
202 mark = icaltime_null_time();
203 else
204 mark = tgr;
207 break;
209 case 4: /* mousewheel up : month back*/
210 monthOffset--;
211 break;
213 case 5: /* mousewheel down : month forward*/
214 monthOffset++;
215 break;
217 case 2: /* Middlemouse click : go to actual month*/
218 monthOffset = 0;
219 break;
221 case 3: /* rightmouse click : show day entries*/
222 if(getClickedDay(bx, by))
223 showDay(tgr);
224 break;
227 told.month = 0; /* invalid month -> forces clearScreen at next draw*/
232 /*------------------------------------------------------
233 * ParseCMDLine
234 -----------------------------------------------------*/
235 void ParseCMDLine(int argc, char *argv[]){
236 int i;
238 for (i = 1; i < argc; i++){
239 if (!strcmp(argv[i], "--version") || !strcmp(argv[i], "-v")){
240 printf("wmCalendar %s\n", getVersion());
241 exit(1);
243 else if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")){
244 print_usage();
245 exit(1);
247 else if (!strcmp(argv[i], "--farsi") || !strcmp(argv[i], "-f"))
248 set_lang(1);
249 else if (!strcmp(argv[i], "--persian") || !strcmp(argv[i], "-p"))
250 calendartype = 1;
251 else if (!strcmp(argv[i], "--debug") || !strcmp(argv[i], "-d"))
252 set_debug( 1);
253 else{
254 print_usage();
255 exit(1);
262 /*------------------------------------------------------
263 * print_usage
264 -----------------------------------------------------*/
265 void print_usage()
267 printf("wmCalendar %s (c) 2003 Matthias Laabs (mattlaabs@users.sourceforge.net)\n", getVersion());
268 printf("This is free software under GPL!\n");
269 printf("\nOptions:");
270 printf("\n -h --help\n Show summary of options.");
271 printf("\n -v --version\n Show version of program.");
272 printf("\n -d --debug\n Show debugging info.");
273 printf("\n -f --farsi\n Show months and numbers in farsi.");
274 printf("\n -p --persian\n Changes to persian calendar.");
275 printf("\n\nUsage: \nLeft and right arrow or mousewheel change month.\n");
276 printf("Middle mouseclick goes back to current month.\n");
277 printf("Right mouseclick opens dayview.\nClick on Moon to toggle moonphase-view on/off\n");
278 printf("Click on screwdriver to open settings menu\nClick on 'G' to toggle between Gregorian, Persian and Islamic calendar\n");
279 printf("Doubleclick evolution/mozilla icon to start application\nClick on blue arrow to show/hide buttons\n");
280 printf("Leftclick a day to highlight for converting between calendars\n");
285 /*------------------------------------------------------
286 * getTime
287 -----------------------------------------------------*/
288 void getTime(){
289 struct tm *Time;
290 long CurrentLocalTime;
292 /* get time */
293 CurrentLocalTime = time(CurrentTime);
294 Time = localtime(&CurrentLocalTime);
295 t.day = Time->tm_mday;
296 t.month = Time->tm_mon + 1;
297 t.year = Time->tm_year + 1900;
298 today = t;
300 /* change calendar*/
301 if(calendartype == 1)
302 t = civil_persian(t);
303 else if(calendartype == 2)
304 t = civil_islamic(t);
305 /* set t to currently shown month and year */
306 t.month += monthOffset;
307 while(t.month > 12){
308 t.month -= 12;
309 t.year += 1;
311 while(t.month < 1){
312 t.month += 12;
313 t.year -= 1;
319 /*------------------------------------------------------
320 * drawMonthYear
321 -----------------------------------------------------*/
322 void drawMonthYear(){
323 int xoff, yoff;
324 int Year1, Year2, Year3, Year4;
325 int monthset;
326 yoff = 1;
327 monthset = calendartype + get_lang() * CALTYPES;
328 /* calculate digits of the year */
329 Year4 = t.year % 10;
330 Year3 = ((t.year - Year4) / 10) % 10;
331 Year2 = ((t.year - Year4 - 10 * Year3) / 100) % 10;
332 Year1 = (t.year - Year4 - 10 * Year3 - 100 * Year2) / 1000;
334 xoff = 30 - (xdMonth[monthset][t.month-1] + xdYear[get_lang()][Year3] + xdYear[get_lang()][Year4]) / 2;
336 /* draw Month */
337 dockapp_copyarea(bg[1], pixmap, xsMonth[monthset][t.month - 1], yMonth[monthset],
338 xdMonth[monthset][t.month - 1], ydMonth, xoff, yoff);
339 xoff += xdMonth[monthset][t.month - 1] + 3;
341 /* draw Year 3rd and 4th digit */
342 dockapp_copyarea(bg[1], pixmap,xsYear[get_lang()][Year3], yYear, xdYear[get_lang()][Year3], ydYear, xoff, yoff);
343 xoff += xdYear[get_lang()][Year3];
344 dockapp_copyarea(bg[1], pixmap,xsYear[get_lang()][Year4], yYear, xdYear[get_lang()][Year4], ydYear, xoff, yoff);
345 dockapp_copy2window(pixmap);
350 /*------------------------------------------------------
351 * drawButtons
352 -----------------------------------------------------*/
353 void drawButtons(){
354 int xoff, yoff;
355 yoff = 56;
356 xoff = 56;
357 if(showbuttons){
358 xoff = drawButton(ARROW_CLOSE, xoff, yoff);
359 xoff = drawButton(SETTINGS, xoff, yoff);
360 xoff = drawButton(MOON + showmoon, xoff, yoff);
361 xoff = drawButton(CALENDAR + calendartype, xoff, yoff);
362 xoff = drawButton(APPLAUNCH + getAppicon(), xoff, yoff);
364 else
365 drawButton(ARROW_OPEN, xoff, yoff);
367 dockapp_copy2window(pixmap);
372 /*------------------------------------------------------
373 * drawButton
374 -----------------------------------------------------*/
375 int drawButton(int btype, int xoff, int yoff){
376 xoff-= xdButton[btype];
377 dockapp_copyarea(bg[0], pixmap, xsButton[btype], yButton[btype], xdButton[btype],
378 ydButton, xoff, yoff);
379 return --xoff;
384 /*------------------------------------------------------
385 * drawDays
386 -----------------------------------------------------*/
387 void drawDays()
389 int i, dayOfWeek;
390 int amount, startday;
391 int moonphase = 0;
392 int yoff = 20;
394 tgr = t;
395 tgr.day = 1;
397 tgr = get_civil(tgr, calendartype);
398 amount = days_in_month(t.month, t.year, calendartype);
399 startday = (day_of_week(tgr) + get_start_of_week()) % 7;
400 for(i = 1; i <= amount; i++){
401 dayOfWeek = (startday + i) % 7;
402 if((dayOfWeek == 0) && (i != 1))
403 yoff += 7; /* increase y-offset on Monday except it is day #1*/
405 tgr = t;
406 tgr.day = i;
407 tgr = get_civil(tgr, calendartype);
409 if(showmoon)
410 moonphase = moon(tgr);
412 if(daysEqual(tgr, mark))
413 drawNumber(i, yoff, dayOfWeek, 3, 0);
414 else if(moonphase == 0 || !showmoon) /* draw number */
415 drawNumber(i, yoff, dayOfWeek, getDayType(tgr), daysEqual(tgr, today));
416 else /* draw moonphase */
417 dockapp_copyarea(bg[0], pixmap, xsMoon[moonphase - 1], yMoon, xdMoon, ydMoon,
418 dayOfWeek * 9, yoff);
421 dockapp_copy2window(pixmap);
426 /*------------------------------------------------------
427 * drawNumber
428 -----------------------------------------------------*/
429 void drawNumber(int number,int yoff, int dayOfWeek, int type, int today){
430 int digit1, digit2;
431 int offset;
432 offset = yNumbers + 20 * type + 10 * today;
433 if(number < 10){ /* draw single digit numbers*/
434 dockapp_copyarea(bg[0], pixmap, xeNumbers[get_lang()][1] - 5, offset, 2, ydNumbers,
435 dayOfWeek * 9, yoff);
436 dockapp_copyarea(bg[0], pixmap, xeNumbers[get_lang()][1] - 5, offset, 2, ydNumbers,
437 dayOfWeek * 9 + 7, yoff);
438 dockapp_copyarea(bg[0], pixmap, xeNumbers[get_lang()][number], offset, xdNumbers, ydNumbers,
439 dayOfWeek * 9 + 2, yoff);
441 else{ /* draw double digit numbers*/
442 digit2 = number % 10;
443 digit1 = (number - digit2) / 10;
444 dockapp_copyarea(bg[0], pixmap, xeNumbers[get_lang()][digit1], offset, xdNumbers, ydNumbers,
445 dayOfWeek * 9, yoff);
446 dockapp_copyarea(bg[0], pixmap, xeNumbers[get_lang()][digit2], offset, xdNumbers, ydNumbers,
447 dayOfWeek * 9 + 4, yoff);
453 /*------------------------------------------------------
454 * processXEvents
455 -----------------------------------------------------*/
456 int processXEvents()
458 if(dockapp_nextevent_or_timeout(&event, 150)) {
459 /* Next Event */
460 switch (event.type) {
461 case ButtonPress:
462 buttonPress(event.xbutton.button,event.xbutton.x, event.xbutton.y, event.xbutton.time);
463 return 1;
464 default: break;
467 return 0;
472 /*------------------------------------------------------
473 * blankScreen
474 -----------------------------------------------------*/
475 void blankScreen()
477 if(daysEqual(t, told))
478 return;
479 /* only neccessary if day has changed*/
480 dockapp_copyarea(bg[0], pixmap, 0, 0, 64, 64, 0, 0);
481 dockapp_copyarea(bg[0], pixmap, 9 * (7 - get_start_of_week()),70 + get_lang() * 12, 63, 8, 0, 12);
482 dockapp_copy2window(pixmap);
483 calendar(); /* reread calendardata */
484 told = t;