3 * wmGrabImage-1.00 (C) 1999 Mike Henderson (mghenderson@lanl.gov)
5 * - Monitors an image on the WWW in a WindowMaker DockApp
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program (see the file COPYING); if not, write to the
22 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 * Boston, MA 02111-1307, USA
26 * Platforms tested on: Linux, Solaris 2.6, IRIX 6.5
29 * ToDo: Add inicator to show if image is uptodate or not
30 * Get rid of GrabImage and put all that stuff in wmGrabImage.c
31 * Center image in icon - this info should be in the returned Attributes struct.
34 * I am still not sure we are handling color resources properly... Seems to work OK on my 24-bit displays...
40 * Version 0.72 - May 27, 2001
41 * Fixed resource leak (XFreeColors)
43 * Version 0.71 - May 24, 2001
44 * Added support for "zooming" the icon display
47 * Version 0.70 - March 28, 1999.
48 * Added support for local images (e.g. file:///home/mgh/junk.gif.)
50 * Version 0.66 - February 23, 1999.
51 * Added help line for -delay option. And added a man page.
53 * Version 0.65 - February 11, 1999.
54 * Now starts netscape if not already running...
56 * Version 0.64 - February 9, 1999.
57 * Added command-line option for "Time between updates"
59 * Version 0.63 - February 9, 1999.
60 * Fixed (potential) memory leak in the ShapeMask Pixmap
61 * (gets returned only if color None is used in xpm file)
62 * Added XFreeColors call.
64 * Version 0.62 - February 4, 1999.
65 * buf fixes. Added -c option to center vertically.
68 * Version 0.61 - February 2, 1999.
69 * Added Attributes support for Xpm Creation.
70 * Also, added a kludge to GrabImage to stream edit
71 * any "Transparent" colors that may get generated. (Change them
74 * Version 0.6 - February 2, 1999.
75 * Some bug fixes. Added Double click support.
76 * Now, DoubleClick's do the following:
78 * Button1: display original size image via xv.
80 * Button2: send another URL (specified with the -http
81 * command line option) to netscape.
83 * Button3: Force Update.
86 * Version 0.5 - initial (very) beta release February 1, 1999.
105 #include <sys/types.h>
106 #include <sys/stat.h>
108 #include "../wmgeneral/wmgeneral.h"
109 #include "wmGrabImage_master.xpm"
110 #include "wmGrabImage_mask.xbm"
115 * Delay between refreshes (in microseconds)
118 #define WMGRABIMAGE_VERSION "0.72"
124 void ParseCMDLine(int argc
, char *argv
[]);
125 void pressEvent(XButtonEvent
*xev
);
129 char ImageURL
[1024], XpmFileName
[256], ImageFileName
[1024];
131 char *ConvertGeometry
= NULL
;
134 int ForceUpdate2
= 1;
135 int GotFirstClick1
, GotDoubleClick1
;
136 int GotFirstClick2
, GotDoubleClick2
;
137 int GotFirstClick3
, GotDoubleClick3
;
140 long int UpdateDELAY
= 600;
149 int main(int argc
, char *argv
[]) {
151 struct tm
*gTime
, *gmt
;
154 Pixmap NewPixmap
, NewShapeMask
;
155 XpmAttributes Attributes
;
157 int n
, s
, m
, dt1
, dt2
, dt3
, len
;
158 int Year
, Month
, Day
;
159 int Hours
, Mins
, Secs
;
160 int i
, j
, Width
, Height
, yoff
, fd
, Flag
;
161 long CurrentLocalTime
;
162 double UT
, hour24(), jd(), CurrentJD
, OldFileUT
, FileUT
;
163 char command
[1040], ImageName
[256];
176 * Parse any command line arguments.
178 ParseCMDLine(argc
, argv
);
182 * Figure out what the name of the image xpm file should be...
184 len
= strlen(ImageURL
);
185 for (j
= 0, i
=0; i
<len
; ++i
){ if (ImageURL
[i
] == '/') j
= i
; }
186 strcpy(ImageName
, ImageURL
+j
+1);
187 sprintf(XpmFileName
, "%s/.wmGrabImage/%s.xpm", getenv("HOME"), ImageName
);
188 sprintf(ImageFileName
, "%s/.wmGrabImage/%s", getenv("HOME"), ImageName
);
191 openXwindow(argc
, argv
, wmGrabImage_master
, wmGrabImage_mask_bits
, wmGrabImage_mask_width
, wmGrabImage_mask_height
);
193 cmap
= DefaultColormap(display
, DefaultScreen(display
));
211 Attributes
.nalloc_pixels
= 0;
218 * Keep track of # of seconds
242 * Double Click Delays
243 * Keep track of click events. If Delay too long, set GotFirstClick's to False.
245 if (DblClkDelay
> 15) {
248 GotFirstClick1
= 0; GotDoubleClick1
= 0;
249 GotFirstClick2
= 0; GotDoubleClick2
= 0;
250 GotFirstClick3
= 0; GotDoubleClick3
= 0;
272 * Process any pending X events.
274 while(XPending(display
)){
275 XNextEvent(display
, &event
);
281 pressEvent(&event
.xbutton
);
302 if (ForceUpdate
||Flag
){
307 * Compute Current Julian Date
309 CurrentLocalTime
= time(CurrentTime
);
310 gTime
= gmtime(&CurrentLocalTime
);
311 Year
= gTime
->tm_year
+1900;
312 Month
= gTime
->tm_mon
+1;
313 Day
= gTime
->tm_mday
;
314 Hours
= gTime
->tm_hour
;
315 Mins
= gTime
->tm_min
;
316 Secs
= gTime
->tm_sec
;
317 UT
= (double)Hours
+ (double)Mins
/60.0 + (double)Secs
/3600.0;
318 CurrentJD
= jd(Year
, Month
, Day
, UT
);
324 copyXPMArea(5, 69, 54, 54, 5, 5);
330 * free up the colors, if we alloc'd some before
332 if (Attributes
.nalloc_pixels
> 0)
333 XFreeColors(display
, cmap
, Attributes
.alloc_pixels
,
334 Attributes
.nalloc_pixels
, 0);
336 * Free last pixmap -- we dont need it anymore...
337 * A ShapeMask is returned if the Pixmap had the color None used.
338 * We could probably change Transparent to None to make use of this, but for now,
339 * lets just ignore it...
341 if ( NewShapeMask
!= 0 )
342 XFreePixmap(display
, NewShapeMask
);
343 XFreePixmap(display
, NewPixmap
);
345 XpmFreeAttributes(&Attributes
);
350 * Grab new pixmap. Accept a reasonable color match.
352 Attributes
.valuemask
= XpmExactColors
| XpmCloseness
| XpmReturnAllocPixels
;
353 Attributes
.exactColors
= 0;
354 Attributes
.closeness
= 40000;
355 if (XpmReadFileToPixmap(display
, Root
, XpmFileName
, &NewPixmap
, &NewShapeMask
, &Attributes
) >= 0){
359 Height
= Attributes
.height
;
360 Width
= Attributes
.width
;
361 yoff
= (CenterImage
) ? (54 - Height
)/2 : 0;
362 XCopyArea(display
, NewPixmap
, wmgen
.pixmap
, NormalGC
, 0, 0, Width
, Height
, 5, 5+yoff
);
376 * Make changes visible
389 * Check xpm file status
395 if ( (fd
= open(XpmFileName
, O_RDONLY
)) >= 0 ) {
399 gmt
= gmtime(&fi
.st_mtime
);
401 FileUT
= (double)gmt
->tm_hour
+ (double)gmt
->tm_min
/60.0 + (double)gmt
->tm_sec
/3600.0;
402 if (FileUT
!= OldFileUT
) ForceUpdate
= 1;
418 * Check every 5 min if the values are not up to date...
421 if (ForceUpdate2
||(dt3
> UpdateDELAY
)){
426 * Execute Perl script to grab the Latest METAR Report
428 if (ConvertGeometry
!= NULL
)
429 sprintf(command
, "GrabImage %s %s &", ImageURL
, ConvertGeometry
);
431 sprintf(command
, "GrabImage %s &", ImageURL
);
444 * Wait for next update
460 void ParseCMDLine(int argc
, char *argv
[]) {
465 for (i
= 1; i
< argc
; i
++) {
467 if (!strcmp(argv
[i
], "-display")){
471 } else if ((!strcmp(argv
[i
], "-url"))||(!strcmp(argv
[i
], "-u"))){
473 strcpy(ImageURL
, argv
[++i
]);
475 } else if (!strcmp(argv
[i
], "-delay")){
477 UpdateDELAY
= atol(argv
[++i
]);
478 if (UpdateDELAY
< 10){
479 printf("Try a longer delay\n");
483 } else if (!strcmp(argv
[i
], "-http")){
485 strcpy(HttpURL
, argv
[++i
]);
487 } else if (!strcmp(argv
[i
], "-geom")){
489 ConvertGeometry
= argv
[++i
];
491 } else if (!strcmp(argv
[i
], "-c")){
501 if (ImageURL
[0] == '\0'){
502 fprintf(stderr
, "You must specify an Image URL\n");
512 printf("\nwmGrabImage version: %s\n", WMGRABIMAGE_VERSION
);
513 printf("\nusage: wmGrabImage -u <ImageURL> -http <httpURL> -display <Display>] [-h]\n");
514 printf("\t\t[-geom <CroppingGeometry>\n\n");
515 printf("\t-display <Display>\tUse alternate X display.\n");
516 printf("\t-h\t\t\tDisplay help screen.\n");
517 printf("\t-url <ImageURL>\t\tThe URL of image to display.\n\n");
518 printf("\t-delay <Time>\t\tSet time (in seconds) between updates.\n\n");
519 printf("\t-http <httpURL>\t\tThe URL of the WWW page to send to\n\t\t\t\tnetscape with Button2 double click.\n\n");
520 printf("\t-c \tCenter the image vertically in the icon.\n\n");
521 printf("\t-geom <CropGeometry>\tThe geometry to pass to convert\n");
522 printf("\t\t\t\twhen scaling the image..\n\n");
529 * Compute the Julian Day number for the given date.
530 * Julian Date is the number of days since noon of Jan 1 4713 B.C.
532 double jd(ny
, nm
, nd
, UT
)
536 double A
, B
, C
, D
, JD
, day
;
541 if ((nm
== 1) || (nm
== 2)){
546 if (((double)ny
+nm
/12.0+day
/365.25)>=(1582.0+10.0/12.0+15.0/365.25)){
547 A
= ((int)(ny
/ 100.0));
548 B
= 2.0 - A
+ (int)(A
/4.0);
554 C
= (int)((365.25*(double)ny
) - 0.75);
557 C
= (int)(365.25*(double)ny
);
560 D
= (int)(30.6001*(double)(nm
+1));
563 JD
= B
+ C
+ D
+ day
+ 1720994.5;
571 * This routine handles button presses.
574 * Mouse Button 1: Display full size image with xv.
575 * Mouse Button 2: Send HttpURL to netscape.
576 * Mouse Button 3: Update image right away (i.e. grab a new one).
580 void pressEvent(XButtonEvent
*xev
){
589 if ((xev
->button
== Button1
) && (xev
->type
== ButtonPress
)){
590 if (GotFirstClick1
) GotDoubleClick1
= 1;
591 else GotFirstClick1
= 1;
592 } else if ((xev
->button
== Button2
) && (xev
->type
== ButtonPress
)){
593 if (GotFirstClick2
) GotDoubleClick2
= 1;
594 else GotFirstClick2
= 1;
595 } else if ((xev
->button
== Button3
) && (xev
->type
== ButtonPress
)){
596 if (GotFirstClick3
) GotDoubleClick3
= 1;
597 else GotFirstClick3
= 1;
602 * We got a double click on Mouse Button1 (i.e. the left one)
604 if (GotDoubleClick1
) {
607 sprintf(Command
, "xv %s &", ImageFileName
);
613 * We got a double click on Mouse Button2 (i.e. the left one)
615 if (GotDoubleClick2
) {
618 sprintf(Command
, "netscape -remote 'openURL(%s)' || netscape '%s' &", HttpURL
, HttpURL
);
624 * We got a double click on Mouse Button3 (i.e. the left one)
626 if (GotDoubleClick3
) {