home *** CD-ROM | disk | FTP | other *** search
- #include "iconclock.h"
-
- // Define the version string here
- static char *version="$VER: iconclock.module 55.0 (15.08.96)";
-
- // Main entry point
- int __asm __saveds L_Module_Entry(
- register __a0 char *args,
- register __a1 struct Screen *screen,
- register __a2 IPCData *ipc,
- register __a3 IPCData *main_ipc,
- register __d0 ULONG mod_id,
- register __d1 EXT_FUNC(func_callback))
- {
- iconclock_data *data;
- IPCData *clock_ipc;
-
- // See if we're already running; return if we are
- if (FindSemaphore(NAME_ICONCLOCK)) return 1;
-
- // Allocate data
- if (data=AllocVec(sizeof(iconclock_data),MEMF_CLEAR))
- {
- // Store A4 and library bases
- data->a4=getreg(REG_A4);
- data->library=DOpusBase;
- data->module=(struct Library *)getreg(REG_A6);
- data->main_ipc=main_ipc;
-
- // Store initial screen
- data->screen=screen;
- data->pen=-1;
-
- // Launch process
- if (!(IPC_Launch(
- 0,
- &clock_ipc,
- NAME_ICONCLOCK,
- (ULONG)icon_clock,
- 4000,
- (ULONG)data,
- DOSBase))) FreeVec(data);
- }
-
- // No process?
- if (!clock_ipc) return 0;
-
- return 1;
- }
-
-
- // Icon clock process
- void __saveds icon_clock(void)
- {
- IPCData *ipc;
- IPCMessage *msg;
- DOpusNotify *nmsg;
- struct AppMessage *amsg;
- struct Library *DOpusBase;
- iconclock_data *data;
- BOOL quit=0,visible=1;
-
- // Get dopus library
- if (!(DOpusBase=(struct Library *)FindName(&((struct ExecBase *)*((ULONG *)4))->LibList,"dopus5.library")))
- return;
-
- // Do startup
- ipc=IPC_ProcStartup((ULONG *)&data,iconclock_startup);
-
- // Fix A4 so we can access global data in the module (eg library bases)
- putreg(REG_A4,data->a4);
-
- // Failed?
- if (!ipc)
- {
- iconclock_cleanup(data);
- return;
- }
-
- // Got a screen?
- if (data->screen)
- {
- struct Screen *scr=data->screen;
-
- // Initialise clock for this screen
- data->screen=0;
- iconclock_init(data,scr);
- }
-
- // Event loop
- FOREVER
- {
- // Timer returned?
- if (CheckTimer(data->timer))
- {
- // Update the time if visible
- if (visible)
- {
- // Show time
- iconclock_show(data);
- }
-
- // Restart timer
- StartTimer(data->timer,0,900000);
- }
-
- // IPC messages?
- while (msg=(IPCMessage *)GetMsg(ipc->command_port))
- {
- // We don't do anything with them at this stage
- IPC_Reply(msg);
- }
-
- // Notify messages from Opus?
- while (nmsg=(DOpusNotify *)GetMsg(data->notify_port))
- {
- // Opus has Quit?
- if (nmsg->dn_Type&DN_OPUS_QUIT) quit=1;
-
- // Opus has been hidden?
- else
- if (nmsg->dn_Type&DN_OPUS_HIDE)
- {
- // Made invisible
- iconclock_init(data,0);
- visible=0;
- }
-
- // Opus has been revealed
- else
- if (nmsg->dn_Type&DN_OPUS_SHOW)
- {
- // Screen changed?
- if (data->screen!=((struct Window *)nmsg->dn_Data)->WScreen)
- {
- // Just made visible
- iconclock_init(data,((struct Window *)nmsg->dn_Data)->WScreen);
- }
- visible=1;
- }
-
- // Reply to the message
- ReplyFreeMsg((struct Message *)nmsg);
- }
-
- // About Requester open?
- if (data->about)
- {
- // Handle requester
- if (SysReqHandler(data->about,0,0)>=0)
- {
- // Close requester
- FreeSysRequest(data->about);
- data->about=0;
- }
- }
-
- // Check quit flag
- if (quit) break;
-
- // AppMessages?
- while (amsg=(struct AppMessage *)GetMsg(data->app_port))
- {
- // SnapShot?
- if (amsg->am_Type==MTYPE_APPSNAPSHOT)
- {
- struct AppSnapshotMsg *asm;
-
- // Get SnapShot message pointer
- asm=(struct AppSnapshotMsg *)amsg;
-
- // Menu operation?
- if (asm->flags&APPSNAPF_MENU)
- {
- // Help?
- if (asm->flags&APPSNAPF_HELP)
- {
- // Send help request
- if (data->main_ipc)
- IPC_Command(data->main_ipc,IPC_HELP,(1<<31),"Icon Clock",0,REPLY_NO_PORT);
- }
-
- // Colour?
- else
- if (asm->id==0)
- {
- struct Screen *screen;
-
- // Toggle colour state
- data->colour=1-data->colour;
-
- // Set menu state
- SetAppIconMenuState(data->appicon,0,data->colour);
-
- // Save screen
- screen=data->screen;
-
- // Close and re-open
- iconclock_init(data,0);
- iconclock_init(data,screen);
- }
- }
-
- // Close?
- else
- if (asm->flags&APPSNAPF_CLOSE) quit=1;
-
- // Info?
- else
- if (asm->flags&APPSNAPF_INFO)
- {
- // Show info
- iconclock_info(data);
- }
-
- // Otherwise
- else
- {
- // Unsnapshot?
- if (asm->flags&APPSNAPF_UNSNAPSHOT)
- {
- // Reinitialise position
- data->icon_x=NO_ICON_POSITION;
- data->icon_y=NO_ICON_POSITION;
- }
-
- // Store position
- else
- {
- data->icon_x=asm->position_x;
- data->icon_y=asm->position_y;
- }
-
- // Build environment variable
- sprintf(
- data->buffer,
- "%d/%d/%d\n",
- data->icon_x,
- data->icon_y,
- data->colour);
-
- // Set environment variable
- SetEnv(ENV_ICONCLOCK,data->buffer,TRUE);
- }
- }
-
- // Double-click?
- else
- if (amsg->am_Type==MTYPE_APPICON &&
- amsg->am_NumArgs==0)
- {
- // Launch date prefs
- LaunchWB("sys:prefs/time",0,0);
- }
-
- // Reply to message
- ReplyMsg((struct Message *)amsg);
- }
-
- // Check quit flag
- if (quit) break;
-
- // Wait for event
- Wait( 1<<ipc->command_port->mp_SigBit|
- 1<<data->notify_port->mp_SigBit|
- 1<<data->timer->port->mp_SigBit|
- 1<<data->app_port->mp_SigBit|
- ((data->about)?(1<<data->about->UserPort->mp_SigBit):0));
- }
-
- // Decrement open count so we can be flushed again
- --data->module->lib_OpenCnt;
-
- // Cleanup
- iconclock_cleanup(data);
- }
-
-
- // Startup code, called by IPC_ProcStartup()
- ULONG __asm __saveds iconclock_startup(
- register __a0 IPCData *ipc,
- register __a1 iconclock_data *data)
- {
- struct Library *DOpusBase;
-
- // Fix A4
- putreg(REG_A4,data->a4);
-
- // Store IPC
- data->ipc=ipc;
-
- // Get library
- DOpusBase=data->library;
-
- // Initialise data
- data->icon_x=NO_ICON_POSITION;
- data->icon_y=NO_ICON_POSITION;
-
- // Initialise Semaphore
- data->sem.sem.ss_Link.ln_Name=NAME_ICONCLOCK;
- data->sem.ipc=ipc;
- AddSemaphore((struct SignalSemaphore *)&data->sem);
-
- // Create message ports
- if (!(data->notify_port=CreateMsgPort()) ||
- !(data->app_port=CreateMsgPort()))
- return 0;
-
- // Create timer
- if (!(data->timer=AllocTimer(UNIT_VBLANK,0)))
- return 0;
-
- // Add notify request
- if (!(data->notify_req=
- AddNotifyRequest(
- DN_OPUS_QUIT|DN_OPUS_HIDE|DN_OPUS_SHOW,
- 0,
- data->notify_port))) return 0;
-
- // Get environment variable
- if (GetVar(ENV_ICONCLOCK,data->buffer,sizeof(data->buffer),GVF_GLOBAL_ONLY)>0)
- {
- char *ptr;
-
- // Get buffer pointer
- ptr=data->buffer;
-
- // Get position
- read_parse_set(&ptr,&data->icon_x);
- read_parse_set(&ptr,&data->icon_y);
- read_parse_set(&ptr,&data->colour);
- }
-
- // Bump library open count so we don't get flushed
- ++data->module->lib_OpenCnt;
-
- // Start timer
- StartTimer(data->timer,0,900000);
-
- return 1;
- }
-
-
- // Cleanup
- void iconclock_cleanup(iconclock_data *data)
- {
- if (data)
- {
- struct Message *msg;
-
- // Free screen lock
- iconclock_init(data,0);
-
- // Remove notify request
- RemoveNotifyRequest(data->notify_req);
-
- // Close requester
- FreeSysRequest(data->about);
- data->about=0;
-
- // Flush message ports
- if (data->notify_port)
- {
- while (msg=GetMsg(data->notify_port))
- ReplyFreeMsg(msg);
- }
- if (data->app_port)
- {
- while (msg=GetMsg(data->app_port))
- ReplyFreeMsg(msg);
- }
-
- // Delete message ports
- DeleteMsgPort(data->notify_port);
- DeleteMsgPort(data->app_port);
-
- // Free timer
- FreeTimer(data->timer);
-
- // Remove Semaphore
- RemSemaphore((struct SignalSemaphore *)&data->sem);
-
- // Free data
- IPC_Free(data->ipc);
- FreeVec(data);
- }
- }
-
-
- // Show current time
- void iconclock_show(iconclock_data *data)
- {
- struct DateStamp date;
- unsigned long hour,minute,second;
- short time[4],colon,x,y=2,a;
- long flags=CAIF_RENDER|CAIF_SELECT;
-
- // Open?
- if (!data->screen) return;
-
- // Get current time
- DateStamp(&date);
-
- // Get hours and minutes and seconds
- hour=DivideU(date.ds_Minute,60,&minute,UtilityBase);
- second=UDivMod32(date.ds_Tick,TICKS_PER_SECOND);
-
- // Get colon we need (either upper or lower half flashing)
- if ((second%2)==0) colon=0;
- else
- if (second<30) colon=1;
- else
- colon=2;
-
- // Get numerals we need for hour
- if (hour>9)
- {
- if (hour>19)
- {
- time[0]=2;
- time[1]=hour-20;
- }
- else
- {
- time[0]=1;
- time[1]=hour-10;
- }
- }
- else
- {
- time[0]=-1;
- time[1]=hour;
- }
-
- // Get numerals we need for minute
- time[2]=0;
- while (minute>9)
- {
- ++time[2];
- minute-=10;
- }
- time[3]=minute;
-
- // Draw digits
- for (a=0,x=2;a<4;a++,x+=NUMERAL_WIDTH+2)
- {
- // Valid number?
- if (time[a]>-1)
- {
- // Draw number
- BltTemplate(
- (char *)numeral_data[time[a]],
- 0,2,
- &data->clock_rp,
- x,y,
- NUMERAL_WIDTH,NUMERAL_HEIGHT);
- }
-
- // Erase area
- else
- {
- // Save fg pen
- short fg=data->clock_rp.FgPen;
-
- // Set bg pen
- SetAPen(&data->clock_rp,data->clock_rp.BgPen);
-
- // Erase it
- RectFill(
- &data->clock_rp,
- x,y,
- x+NUMERAL_WIDTH-1,
- y+NUMERAL_HEIGHT-1);
-
- // Restore pen
- SetAPen(&data->clock_rp,fg);
- }
-
- // Time for the colon?
- if (a==1)
- {
- // Draw colon
- BltTemplate(
- (char *)colon_data[colon],
- 0,2,
- &data->clock_rp,
- x+NUMERAL_WIDTH+1,y,
- COLON_WIDTH,COLON_HEIGHT);
-
- // Bump x position
- x+=COLON_WIDTH;
- }
- }
-
- // Day different?
- if (date.ds_Days!=data->day)
- {
- struct DateTime dt;
-
- // Fill out dt
- dt.dat_Stamp=date;
- dt.dat_Format=FORMAT_DOS;
- dt.dat_Flags=0;
- dt.dat_StrDay=0;
- dt.dat_StrDate=data->date_buffer;
- dt.dat_StrTime=0;
-
- // Get date string
- DateToStr(&dt);
- flags|=CAIF_TITLE;
- }
-
- // Update image
- ChangeAppIcon(data->appicon,&data->clock_image,&data->clock_image,data->date_buffer,flags);
- }
-
-
- // Parse number out of string, leave pointer at one character after end of number
- void read_parse_set(char **ptr,long *val)
- {
- // Digit?
- if (isdigit(*(*ptr)))
- {
- *val=atoi(*ptr);
- while (*(*ptr) && isdigit(*(*ptr))) ++*ptr;
- ++*ptr;
- }
- }
-
-
- // Initialise screen stuff
- void iconclock_init(iconclock_data *data,struct Screen *screen)
- {
- // Got a screen locked?
- if (data->screen)
- {
- // Free pen
- if (data->pen>-1)
- {
- ReleasePen(data->screen->ViewPort.ColorMap,data->pen);
- data->pen=-1;
- }
-
- // Unlock it
- UnlockPubScreen(0,data->screen);
- data->screen=0;
-
- // Remove AppIcon
- if (data->appicon) RemoveAppIcon(data->appicon);
- data->appicon=0;
-
- // Free bitmap
- FreeVec(data->clock_image.ImageData);
- data->clock_image.ImageData=0;
- }
-
- // No new screen?
- if (!screen) return;
-
- // Try to lock screen
- if (FindPubScreen(screen,TRUE))
- {
- short depth=1;
-
- // Store pointer
- data->screen=screen;
-
- // Under 39 grab a pen
- if (GfxBase->lib_Version>=39 && data->colour)
- {
- // Allocate pen
- if ((data->pen=ObtainPen(
- screen->ViewPort.ColorMap,
- -1,
- 0,0xffffffff,0,
- PENF_EXCLUSIVE))>-1)
- {
- // Set colour
- SetRGB32(&screen->ViewPort,data->pen,0,0xffffffff,0);
-
- // Get depth we need
- for (depth=1;depth<=8;depth++)
- if (1<<depth>data->pen) break;
- }
- }
-
- // Initialise clock bitmap
- InitBitMap(&data->clock_bm,depth,CLOCK_WIDTH,CLOCK_HEIGHT);
-
- // Allocate clock bitmap
- if (data->clock_image.ImageData=
- (USHORT *)AllocVec(RASSIZE(CLOCK_WIDTH,CLOCK_HEIGHT)*depth,MEMF_CHIP|MEMF_CLEAR))
- {
- struct TagItem tags[7];
- USHORT *ptr;
- short a;
-
- // Get bitmap pointers
- ptr=data->clock_image.ImageData;
- for (a=0;a<depth;a++)
- {
- data->clock_bm.Planes[a]=(PLANEPTR)ptr;
- ptr+=((CLOCK_WIDTH+15)>>4)*CLOCK_HEIGHT;
- }
-
- // Initialise rastport
- InitRastPort(&data->clock_rp);
- data->clock_rp.BitMap=&data->clock_bm;
- SetDrMd(&data->clock_rp,JAM2);
-
- // Fill in image
- data->clock_image.Width=CLOCK_WIDTH;
- data->clock_image.Height=CLOCK_HEIGHT;
- data->clock_image.Depth=depth;
- data->clock_image.PlanePick=(1<<depth)-1;
-
- // Fill out fake DiskObject
- data->clock_icon.do_Gadget.Width=CLOCK_WIDTH;
- data->clock_icon.do_Gadget.Height=CLOCK_HEIGHT;
- data->clock_icon.do_Gadget.Flags=GFLG_GADGHIMAGE;
- data->clock_icon.do_Gadget.GadgetRender=&data->clock_image;
- data->clock_icon.do_Gadget.SelectRender=&data->clock_image;
- data->clock_icon.do_CurrentX=data->icon_x;
- data->clock_icon.do_CurrentY=data->icon_y;
-
- // AppIcon tags
- tags[0].ti_Tag=DAE_SnapShot;
- tags[0].ti_Data=1;
- tags[1].ti_Tag=DAE_Close;
- tags[1].ti_Data=2;
- tags[2].ti_Tag=DAE_Local;
- tags[2].ti_Data=1;
- tags[3].ti_Tag=DAE_Info;
- tags[3].ti_Data=1;
-
- // Under 39 we can use colour
- if (GfxBase->lib_Version>=39)
- {
- tags[4].ti_Tag=(data->pen>-1)?DAE_Background:TAG_IGNORE;
- tags[4].ti_Data=1;
- tags[5].ti_Tag=(data->colour)?DAE_ToggleMenuSel:DAE_ToggleMenu;
- tags[5].ti_Data=(ULONG)DOpusGetString(locale,MSG_ICONCLOCK_COLOUR);
- tags[6].ti_Tag=TAG_END;
- }
- else tags[4].ti_Tag=TAG_END;
-
- // Add AppIcon
- if (data->appicon=AddAppIconA(0,0,NAME_ICONCLOCK,data->app_port,0,&data->clock_icon,tags))
- {
- // If we have a pen, fill background
- if (data->pen>-1) SetRast(&data->clock_rp,1);
-
- // Set pen for clock
- SetAPen(&data->clock_rp,(data->pen>-1)?data->pen:1);
- SetBPen(&data->clock_rp,(data->pen>-1)?1:0);
-
- // Show clock
- iconclock_show(data);
- }
- }
-
- // Failed?
- if (!data->appicon)
- {
- // Free stuff (this is a bit recursive)
- iconclock_init(data,0);
- }
- }
- }
-
-
- // Show info window
- void iconclock_info(iconclock_data *data)
- {
- struct EasyStruct easy;
-
- // Window open?
- if (data->about)
- {
- WindowToFront(data->about);
- ActivateWindow(data->about);
- return;
- }
-
- // Fill out easy struct
- easy.es_StructSize=sizeof(easy);
- easy.es_Flags=0;
- easy.es_Title=DOpusGetString(locale,MSG_ICONCLOCK_TITLE);
- easy.es_TextFormat="Directory Opus 5 Icon Clock\nv55.0 (15.08.96)\n\n© 1996 Jonathan Potter";
- easy.es_GadgetFormat=DOpusGetString(locale,MSG_OK);
-
- // Open requester
- data->about=BuildEasyRequestArgs(data->screen->FirstWindow,&easy,0,0);
- }
-