diff --git a/Makefile b/Makefile index 9b1e57d..d8848e3 100755 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ # in the file LICENSE that is included with this distribution. #************************************************************************* # -# Makefile,v 1.18 2008/12/03 17:20:17 jba Exp +# Makefile,v 1.22 2013/04/22 16:07:23 jba Exp # TOP=../.. include $(TOP)/configure/CONFIG @@ -157,11 +157,11 @@ alh_DB_SRCS = alh_DB.c alh_printer_SRCS = printer.c -PROD_HOST_DEFAULT = alh alh_printer +PROD_HOST_DEFAULT = alh alh_printer alh_DB PROD_HOST_WIN32 = alh WIN32_RUNTIME=MD -USR_CFLAGS_WIN32 += /DWIN32 /D_WINDOWS +USR_CFLAGS_WIN32 += -DWIN32 -D_WINDOWS ifndef BORLAND USR_LDFLAGS_WIN32 += /SUBSYSTEM:WINDOWS endif diff --git a/alConfig.c b/alConfig.c index c8ca3bb..50d0526 100644 --- a/alConfig.c +++ b/alConfig.c @@ -119,7 +119,10 @@ int caConnect) fp = fopen(filename,"r"); if(fp==NULL) { - perror("Could not open Alarm Configuration File"); + sprintf(buf, + "Could not open Alarm Configuration File: %.*s", + (int)MAX_STRING_LENGTH-42,filename); + perror(buf); exit(-1); } @@ -182,7 +185,7 @@ struct mainGroup *pmainGroup) parent_link = *pglink; - rtn = sscanf(buf,"%20s%32s%32s",command,parent,name); + rtn = sscanf(buf,"%20s%64s%64s",command,parent,name); if(rtn!=3) { print_error(buf,"Invalid GROUP command"); @@ -227,7 +230,7 @@ struct mainGroup *pmainGroup) parent_link = parent_link->parent; if(parent_link==NULL) { - print_error(buf,"Can not find parent"); + print_error(buf,"Cannot find parent"); return; } @@ -254,7 +257,7 @@ struct mainGroup *pmainGroup) if (pglink) parent_link = *pglink; - rtn = sscanf(buf,"%20s%32s%s",command,parent,name); + rtn = sscanf(buf,"%20s%64s%s",command,parent,name); if(rtn!=3) { print_error(buf,"Invalid INCLUDE command"); @@ -361,7 +364,7 @@ int caConnect,struct mainGroup *pmainGroup) parent_link = parent_link->parent; if(parent_link==NULL) { - print_error(buf,"Can not find parent"); + print_error(buf,"Cannot find parent"); return; } @@ -444,7 +447,7 @@ int context,int caConnect,struct mainGroup *pmainGroup) if (strncmp(&buf[1],"HEARTBEATPV",11)==0) { /*HEARTBEATPV*/ if (pmainGroup->heartbeatPV.name) return; - rtn = sscanf(buf,"%20s%32s%f%d",command,name,&rateIn,&valueIn); + rtn = sscanf(buf,"%20s%64s%f%d",command,name,&rateIn,&valueIn); if(rtn>=2) { if(rtn>=3) rate = rateIn; if(rtn>=4) value = valueIn; @@ -491,7 +494,7 @@ int context,int caConnect,struct mainGroup *pmainGroup) if (gcdata->pforcePV && gcdata->pforcePV->name) return; if (!gcdata->pforcePV) gcdata->pforcePV=(FORCEPV*)calloc(1,sizeof(FORCEPV)); dbl=0.0; - rtn = sscanf(buf,"%20s%32s%6s%lf%9s",command,name,mask,&dbl,string); + rtn = sscanf(buf,"%20s%64s%6s%lf%9s",command,name,mask,&dbl,string); if(rtn>=3) alSetMask(mask,&(gcdata->pforcePV->forceMask)); if (rtn >= 4) gcdata->pforcePV->forceValue = dbl; else gcdata->pforcePV->forceValue=1; @@ -598,7 +601,7 @@ int context,int caConnect,struct mainGroup *pmainGroup) if (strncmp(&buf[1],"SEVRPV",6)==0) { /*SEVRPV*/ if(strcmp(gcdata->sevrPVName,"-") != 0) return; - rtn = sscanf(buf,"%20s%32s",command,name); + rtn = sscanf(buf,"%20s%64s",command,name); if(rtn>=2) { gcdata->sevrPVName = (char *)calloc(1,strlen(name)+1); strcpy(gcdata->sevrPVName,name); diff --git a/alLib.c b/alLib.c index 8537117..304371f 100644 --- a/alLib.c +++ b/alLib.c @@ -48,6 +48,7 @@ static void alNewAlarmProcess(int stat,int sev, int acks,int ackt, void alSetAckTChan(CLINK *clink,int ackt); short alHighestBeepSeverity(int sevr[ALH_ALARM_NSEV], int beepSevr); static void alSetBeepSevCount(GLINK* glink,int beepSevr,int oldBeepSevr); +static void alAlarmFilterReset(CLINK *clink); char *Strncat( char *dest, @@ -57,7 +58,8 @@ char *Strncat( /* max must be >= 0 and no more than stringsize - 1 */ /* for char string[10]; max must be <= 9 */ -size_t l, newMax; +int newMax; +size_t l; char *s; l = strlen( dest ); @@ -578,23 +580,14 @@ static void alarmCountFilter_callback(XtPointer cd, XtIntervalId *id) { COUNTFILTER *countFilter=(COUNTFILTER *)cd; time_t alarmTime; - int j; #if DEBUG_CALLBACKS - { - static int n=0; - - printf("alarmCountFilter_callback: n=%d\n",n++); - } + { static int n=0; printf("alarmCountFilter_callback: n=%d\n",n++); } #endif alarmTime = countFilter->alarmTime; countFilter->alarmTime=0; countFilter->timeoutId=0; - /* reset alarm count filter when new alarm is processed */ - if (countFilter->inputCount){ - for (j=0;j<=2*(countFilter->inputCount)-1;j++){countFilter->alarmTimeHistory[j]=0;} - } - countFilter->countIndex=0; + alAlarmFilterReset(countFilter->clink); alNewAlarmProcess(countFilter->stat,countFilter->sev, countFilter->acks,countFilter->ackt, countFilter->value,countFilter->clink,alarmTime); @@ -668,7 +661,7 @@ void alNewEvent(int stat,int sevr,int acks,int acktCA,char *value,CLINK *clink) void alNewAlarmFilter(int stat,int sev,int acks,int ackt,char *value,CLINK *clink) { struct chanData *cdata; - int sevr_prev, i, j; + int sevr_prev, i; time_t alarmTime; COUNTFILTER *countFilter; @@ -693,8 +686,8 @@ void alNewAlarmFilter(int stat,int sev,int acks,int ackt,char *value,CLINK *clin return; } - /* Process if inputCount or inputSeconds is zero */ - if (countFilter->inputSeconds==0 || countFilter->inputCount==0) { + /* Process if inputSeconds is zero */ + if (countFilter->inputSeconds==0 ) { alNewAlarmProcess(stat,sev,acks,ackt,value,clink,alarmTime); return; } @@ -726,8 +719,10 @@ void alNewAlarmFilter(int stat,int sev,int acks,int ackt,char *value,CLINK *clin } - /* process changes in acks and ackt and if no timeout then add timeout */ if ( cdata->curSevr!=0 && sev==0 ){ + if ( countFilter->inputCount != -1 ) { + + /* if inputCount not -1 process changes in acks and ackt and add timeout */ alNewAlarmProcess(cdata->curStat,cdata->curSevr,acks,ackt,value,clink,alarmTime); if (countFilter->timeoutId==0) { countFilter->timeoutId = XtAppAddTimeOut(appContext, @@ -735,23 +730,23 @@ void alNewAlarmFilter(int stat,int sev,int acks,int ackt,char *value,CLINK *clin alarmCountFilter_callback,(XtPointer)countFilter); countFilter->alarmTime=alarmTime; } + } else { + + /* if inputCount is -1 dont start a timeout, reset filter and process new alarm state*/ + alAlarmFilterReset(clink); + alNewAlarmProcess(stat,sev,acks,ackt,value,clink,alarmTime); + } } /* check in/out alarm count within time interval*/ + if ( countFilter->inputCount > 0 ) { if ( (sevr_prev==0 && sev!=0) || (sevr_prev!=0 && sev==0)){ i = countFilter->countIndex; if ( !countFilter->alarmTimeHistory || (countFilter->alarmTimeHistory[i] && (((int)difftime(alarmTime,countFilter->alarmTimeHistory[i]))<=countFilter->inputSeconds))){ - /* reset alarm count filter when new alarm is processed */ - if (countFilter->inputCount){ - for (j=0;j<=2*(countFilter->inputCount)-1;j++){countFilter->alarmTimeHistory[j]=0;} - } - if (countFilter->timeoutId){ - XtRemoveTimeOut(countFilter->timeoutId); - countFilter->timeoutId=0; - } - countFilter->countIndex=0; + + alAlarmFilterReset(clink); alNewAlarmProcess(stat,sev,acks,ackt,value,clink,alarmTime); } else { countFilter->alarmTimeHistory[i] = alarmTime; @@ -761,8 +756,37 @@ void alNewAlarmFilter(int stat,int sev,int acks,int ackt,char *value,CLINK *clin } } } + } } + +/*********************************************************** + alNewAlarmFilterReset +************************************************************/ +void alAlarmFilterReset(CLINK *clink) +{ + COUNTFILTER *countFilter; + struct chanData *cdata; + int j; + + if (clink == NULL ) return; + cdata = clink->pchanData; + if (cdata == NULL ) return; + countFilter = cdata->countFilter; + if (countFilter == NULL ) return; + + /* reset alarm count filter when new alarm is processed */ + countFilter->countIndex=0; + if (countFilter->inputCount){ + for (j=0;j<=2*(countFilter->inputCount)-1;j++){countFilter->alarmTimeHistory[j]=0;} + } + if (countFilter->timeoutId){ + XtRemoveTimeOut(countFilter->timeoutId); + countFilter->timeoutId=0; + } +} + + /*********************************************************** alNewAlarmProcess ************************************************************/ diff --git a/alLog.c b/alLog.c index b09e92a..4c8c7bc 100644 --- a/alLog.c +++ b/alLog.c @@ -91,12 +91,16 @@ struct setup psetup = { /* initial files & beeping setup */ "", /* alarm log file name */ "", /* opMod log file name */ "", /* save config file name */ + "", /* sound wav file name */ + "", /* lock files basename */ 0, /* silenceForever */ 0, /* silenceOneHour */ 0, /* silenceCurrent */ 1, /* 1,2,3,4,5 */ 0, /* system highest sevr */ 0, /* system highest unack sevr */ + 0, /* system highest unack sevr >= beep sevr */ + 0, /* new unack sevr after beep sevr tests */ 0, /* config files directory */ 0}; /* log files directory */ @@ -137,10 +141,10 @@ char *displayName; #endif -int filePrintf(FILE *fPointer,char *buf,time_t *ptime,int typeOfRecord); +static int filePrintf(int fileType,char *buf,time_t *ptime,int typeOfRecord); #ifdef HAVE_SYSV_IPC -int write2MQ(int, char *); -int write2msgQ(int, char *); +static int write2MQ(int, char *); +static int write2msgQ(int, char *); #endif #ifdef CMLOG @@ -197,6 +201,7 @@ void alLogAlarmMessage(time_t *ptimeofdayAlarm,int messageCode,CLINK* clink,cons (alhArea ? alhArea->blinkString : "N/A"), cdata->value); #endif + if (_xml_flag) /* Use XML-ish entries which are easier to parse. SNS */ { if (!_description_field_flag) @@ -239,7 +244,7 @@ void alLogAlarmMessage(time_t *ptimeofdayAlarm,int messageCode,CLINK* clink,cons if (!_description_field_flag) { if (_global_flag) - sprintf(buff, "%-28s %-12s %-16s %-12s %-5s %-40.40s\n", + sprintf(buff, "%-28s %-12s %-16s %-12s %-5s %-40.40s", cdata->name, alhAlarmStatusString[cdata->curStat], alhAlarmSeverityString[cdata->curSevr], @@ -247,7 +252,7 @@ void alLogAlarmMessage(time_t *ptimeofdayAlarm,int messageCode,CLINK* clink,cons ackTransientsString[cdata->curMask.AckT], cdata->value); else - sprintf(buff, "%-28s %-12s %-16s %-40.40s\n", + sprintf(buff, "%-28s %-12s %-16s %-40.40s", cdata->name, alhAlarmStatusString[cdata->curStat], alhAlarmSeverityString[cdata->curSevr], @@ -256,20 +261,20 @@ void alLogAlarmMessage(time_t *ptimeofdayAlarm,int messageCode,CLINK* clink,cons else { /* _description_field_flag is ON */ if (_global_flag) - sprintf(buff, "%-28s %-28s %-40.40s %-12s %-16s %-12s %-5s\n", + sprintf(buff, "%-28s %-28s %-40.40s %-12s %-16s %-12s %-5s", cdata->name,cdata->description,cdata->value, alhAlarmStatusString[cdata->curStat], alhAlarmSeverityString[cdata->curSevr], alhAlarmSeverityString[cdata->unackSevr], ackTransientsString[cdata->curMask.AckT]); else - sprintf(buff, "%-28s %-28s %-40.40s %-12s %-16s\n", + sprintf(buff, "%-28s %-28s %-40.40s %-12s %-16s", cdata->name,cdata->description,cdata->value, alhAlarmStatusString[cdata->curStat], alhAlarmSeverityString[cdata->curSevr]); } } - filePrintf(fl,buff,ptimeofdayAlarm,messageCode); + filePrintf(ALARM_FILE,buff,ptimeofdayAlarm,messageCode); } @@ -281,6 +286,7 @@ void alLogOpModMessage(int messageCode,GCLINK* gclink,const char* fmt,...) va_list vargs; static char text[1024]; /* DANGER: Fixed buffer size */ struct gcData *gcdata=NULL; + size_t len; if (gclink) gcdata = gclink->pgcData; @@ -306,6 +312,8 @@ void alLogOpModMessage(int messageCode,GCLINK* gclink,const char* fmt,...) (alhArea ? alhArea->blinkString : "N/A")); } #endif + len = strlen(text); + if (text[len-1] == '\n' ) text[len-1]=' '; if (!alhArea || !alhArea->blinkString){ sprintf(buff,"%s",text); @@ -317,7 +325,7 @@ void alLogOpModMessage(int messageCode,GCLINK* gclink,const char* fmt,...) } } - filePrintf(fo,buff,NULL,messageCode); + filePrintf(OPMOD_FILE,buff,NULL,messageCode); } @@ -355,9 +363,8 @@ void alLogOpModAckMessage(int messageCode,GCLINK* gclink,const char* fmt,...) (alhArea ? alhArea->blinkString : "N/A")); } #endif - if (!alhArea || !alhArea->blinkString){ - sprintf(buff," : : %s \n",text); + sprintf(buff," : : %s",text); } else { if (!gcdata){ sprintf(buff,"%s: : %s %-16s",alhArea->blinkString,text, @@ -368,7 +375,7 @@ void alLogOpModAckMessage(int messageCode,GCLINK* gclink,const char* fmt,...) } } - filePrintf(fo,buff,NULL,messageCode); + filePrintf(OPMOD_FILE,buff,NULL,messageCode); } @@ -378,7 +385,7 @@ void alLogOpModAckMessage(int messageCode,GCLINK* gclink,const char* fmt,...) void alLogNotSaveStart(int not_save_time) { sprintf(buff,"Stop log start during %d min",not_save_time); - filePrintf(fl,buff,NULL,STOP_LOGGING_ALARM); + filePrintf(ALARM_FILE,buff,NULL,STOP_LOGGING_ALARM); } /*********************************************************************** @@ -387,7 +394,7 @@ void alLogNotSaveStart(int not_save_time) void alLogNotSaveFinish() { sprintf(buff,"Stop log finish"); - filePrintf(fl,buff,NULL,STOP_LOGGING_ALARM); + filePrintf(ALARM_FILE,buff,NULL,STOP_LOGGING_ALARM); } /*********************************************************************** @@ -399,7 +406,7 @@ save all recordName if someone acknowledges group) void alLog2DBAckChan (char *name) { sprintf(buff,"Ack Channel--- %-28s",name); - filePrintf(fo,buff,NULL,ACK_GROUP); /* update the file */ + filePrintf(OPMOD_FILE,buff,NULL,ACK_GROUP); /* update the file */ } /*********************************************************************** @@ -409,7 +416,7 @@ save all recordName if someone acknowledges group) void alLog2DBMask (char *name) { sprintf(buff,"Group Mask ID --- %-28s",name); - filePrintf(fo,buff,NULL,CHANGE_MASK_GROUP); /* update the file */ + filePrintf(OPMOD_FILE,buff,NULL,CHANGE_MASK_GROUP); /* update the file */ } @@ -434,7 +441,7 @@ Parameters: 1) filePointer ***********************************************************************/ -int filePrintf(FILE *fPointer,char *buf,time_t *ptime,int typeOfRecord) +static int filePrintf(int fileType,char *buf,time_t *ptime,int typeOfRecord) { int ret=0; int status; @@ -444,10 +451,10 @@ int filePrintf(FILE *fPointer,char *buf,time_t *ptime,int typeOfRecord) char buf_tmp[1024]; time_t timeofday; - if(!fPointer) return (-1); + if(!fileType) return (-1); - if((!masterFlag) && (fPointer==fl)) return (0); - if(_message_broadcast_flag && notsave && (fPointer==fl) ) return (0); + if ((_lock_flag && !masterFlag) && (fileType==ALARM_FILE)) return (0); + if(_message_broadcast_flag && notsave && (fileType==ALARM_FILE) ) return (0); if (ptime == NULL) /* Current time */ { @@ -468,9 +475,10 @@ int filePrintf(FILE *fPointer,char *buf,time_t *ptime,int typeOfRecord) psetup.logFile[strlen(psetup.logFile) - 11] = 0; strncat(psetup.logFile, buf_tmp, strlen(buf_tmp)); - fclose(fl); + if (fl) fclose(fl); fl = fopen(psetup.logFile,"a"); - fclose(fl); + if (fl) fclose(fl); + fl=0; if(_read_only_flag) fl = fopen(psetup.logFile,"r"); else if (_lock_flag) fl = fopen(psetup.logFile,"a"); else fl = fopen(psetup.logFile,"r+"); @@ -478,9 +486,9 @@ int filePrintf(FILE *fPointer,char *buf,time_t *ptime,int typeOfRecord) /* The same with psetup.opModFile: */ psetup.opModFile[strlen(psetup.opModFile) - 11] = 0; strncat(psetup.opModFile, buf_tmp, strlen(buf_tmp)); - fclose(fo); + if (fo) fclose(fo); fo = fopen(psetup.opModFile,"a"); - fclose(fo); + if (fo) fclose(fo); if(_read_only_flag) fo = fopen(psetup.opModFile,"r"); else if (_lock_flag) fo = fopen(psetup.opModFile,"a"); else fo = fopen(psetup.opModFile,"r+"); @@ -507,8 +515,12 @@ int filePrintf(FILE *fPointer,char *buf,time_t *ptime,int typeOfRecord) buf_tmp[20]=0; sprintf(bufSave,"%-20s : %s\n",buf_tmp,buf); } - if (alarmLogFileMaxRecords&&(fPointer==fl)) - { + + /* Write into Alarm log file*/ + + + if (fileType==ALARM_FILE) { + if (alarmLogFileMaxRecords && fl) { if (alarmLogFileOffsetBytes != ftell(fl)) fseek(fl,alarmLogFileOffsetBytes,SEEK_SET); if (alarmLogFileOffsetBytes >= alarmLogFileStringLength*alarmLogFileMaxRecords) { @@ -516,30 +528,36 @@ int filePrintf(FILE *fPointer,char *buf,time_t *ptime,int typeOfRecord) status=truncateFile(psetup.logFile,alarmLogFileOffsetBytes); alarmLogFileOffsetBytes = 0; } - } - - - ret=fprintf(fPointer,"%s",bufSave); - - if (ret<0 && !_read_only_flag) { - fprintf(stderr,"Can't write '%s' to file=%s!!!\n", - bufSave,(fPointer==fl)?"LOGfile":"OpModFile" ); - } - - if (alarmLogFileMaxRecords&&(fPointer==fl)){ - if (!alarmLogFileOffsetBytes) alarmLogFileStringLength=ftell(fl); - alarmLogFileOffsetBytes = ftell(fl); - } + } + if (!fl) ret=0; + else ret=fprintf(fl,"%s",bufSave); + if (ret<0 && !_read_only_flag) { + fprintf(stderr,"Can't write '%s' to file=%s!!!\n", bufSave,"LOGfile"); + errMsg("Error writing '%s' to file=%s!!!\n", bufSave,"LOGfile"); + } + if (alarmLogFileMaxRecords && fl){ + if (!alarmLogFileOffsetBytes) alarmLogFileStringLength=ftell(fl); + alarmLogFileOffsetBytes = ftell(fl); + } + if (fl) fflush(fl); + updateAlarmLog(ALARM_FILE,bufSave); + } - fflush(fPointer); + /* Write into Op Mod log file*/ + else if (fileType==OPMOD_FILE) { + if (!fo) ret=0; + else ret=fprintf(fo,"%s",bufSave); + if (ret<0 && !_read_only_flag) { + errMsg("Error writing '%s' to file=%s!!!\n", bufSave,"OpModFile"); + } + if (fo) fflush(fo); + updateLog(OPMOD_FILE,bufSave); + } + else fprintf(stderr,"\nBad file type for writing\n"); - if(fPointer==fl) updateAlarmLog(ALARM_FILE,bufSave); - else if (fPointer==fo) updateLog (OPMOD_FILE,bufSave); - else fprintf(stderr,"\nBad fPointer for writing\n"); - - if( (_printer_flag) && (fPointer==fl) &&printerMsgQId ) - { + + if( (_printer_flag) && (fileType==ALARM_FILE) &&printerMsgQId ) { sprintf(DBbuff,"%d %d %s %s",ALARM_LOG_DB, typeOfRecord+1,buf_tmp,buff); #ifdef HAVE_SYSV_IPC write2MQ(printerMsgQId, DBbuff); @@ -548,13 +566,13 @@ int filePrintf(FILE *fPointer,char *buf,time_t *ptime,int typeOfRecord) if(_DB_call_flag && DBMsgQId ) { - if (fPointer==fo) /* write into AlarmOp Database */ + if (fileType==OPMOD_FILE) /* write into AlarmOp Database */ { if(typeOfRecord ==0) return(ret); sprintf(DBbuff,"%d %d %s %s %s %s %s %s %s",OP_MOD_DB,typeOfRecord,applicationName, deviceName,userID.loginid,userID.myhostname,userID.displayName,buf_tmp,buff); } - else if (fPointer==fl) /* write into AlarmLOG Database */ + else if (fileType==ALARM_FILE) /* write into AlarmLOG Database */ { if(typeOfRecord ==0) return(ret); sprintf(DBbuff,"%d %d %s %s %s %s %s %s %s", ALARM_LOG_DB, typeOfRecord,applicationName, @@ -562,7 +580,7 @@ int filePrintf(FILE *fPointer,char *buf,time_t *ptime,int typeOfRecord) } else { - fprintf(stderr,"\nBad fPointer for writing\n"); + fprintf(stderr,"\nBad file type for writing\n"); return (ret); } #ifdef HAVE_SYSV_IPC @@ -579,7 +597,7 @@ return (ret); ***********************************************************************/ #ifdef HAVE_SYSV_IPC -int write2MQ(int mq,char *message) +static int write2MQ(int mq,char *message) { char buf[256]; static int lostFlag=0; @@ -645,7 +663,7 @@ int write2MQ(int mq,char *message) } -int write2msgQ(int mq, char *mes) +static int write2msgQ(int mq, char *mes) { if (msgsnd(mq,mes,strlen(mes),IPC_NOWAIT /* 0*/) == -1 ) { diff --git a/alh.c b/alh.c index 375fde1..3863675 100644 --- a/alh.c +++ b/alh.c @@ -23,6 +23,7 @@ #include #include +#include #include "alh.h" #include "epicsVersion.h" @@ -56,13 +57,16 @@ int main(int argc,char *argv[]) int interval=0; /* OS specific initialization */ +#ifdef HCLXMINIT #ifdef WIN32 HCLXmInit(); #endif +#endif #ifdef HP_UX _main(); #endif - + + /* Xt initialize the application */ topLevelShell = XtAppInitialize(&appContext, "Alarm", NULL, 0, &argc, argv, fallbackResources, NULL, 0); diff --git a/alh.h b/alh.h index c0047d6..37feac8 100644 --- a/alh.h +++ b/alh.h @@ -29,7 +29,7 @@ #include "alarm.h" #include "cadef.h" -#if (!defined(WIN32) && !defined(__APPLE__)) +#if !defined(WIN32) #define HAVE_SYSV_IPC #endif @@ -181,9 +181,11 @@ struct setup { char logFile[NAMEDEFAULT_SIZE]; /* alarm log file name */ char opModFile[NAMEDEFAULT_SIZE]; /* opMod log file name */ char saveFile[NAMEDEFAULT_SIZE]; /* save config file name */ - Boolean silenceForever; /* 1 - beepoff forever is true */ - short silenceOneHour; /* 1 - beepoff one hour is true */ - short silenceCurrent; /* 1 - current beep on 0 - off */ + char soundFile[NAMEDEFAULT_SIZE]; /* sound wav file name */ + char lockFileBase[NAMEDEFAULT_SIZE]; /* lock files basename */ + short silenceForever; /* 1 - beepoff forever is true */ + short silenceSelectedMinutes; /* 1 - beepoff selected minutes is true */ + short silenceCurrent; /* 1 - current beep on 0 - off */ short beepSevr; /* 1,2,3,4,5 */ short highestSevr; /* system highest sevr */ short highestUnackSevr; /* system highest unack sevr */ diff --git a/alh.notes b/alh.notes index 369292b..39325eb 100644 --- a/alh.notes +++ b/alh.notes @@ -181,7 +181,7 @@ Thu Mar 11 10:12:06 CST 1999 create/modify alarmLog and alarmOpMod files. -S Passive Mode --- means that operator can't acknowledge alarms and can't save alarmLog and alarmOpMod files. - -T AlarmLogDated --- 1) alarmLog and OpMod files will have "date" extensions + -T AlarmLogDated --- 1) alarmLog and OpMod files will have "date" extension like YYYY-MM-DD, and automatical switching this files in midnight. @@ -200,16 +200,17 @@ Thu Mar 11 10:12:06 CST 1999 and modificate Makefile.Unix. -L locking --- allow multiple work with the same config files, - only one process is real master and write to alhLog - other is slave and they wait until master will not killed + only one process is real master and write to alhLog + other is slave and they wait until master will not + killed - -0 Database(Oracle) --- simultaneously runtime add Alarm to Database. - it works asynchronous, so we add additional task "alh_DB" + -0 Database(Oracle) --- simultaneously runtime add Alarm to Database. It + works asynchronous, so we add additional task "alh_DB" - -B - message broadcasting -- allow send messages between operators work with the - same config file. Most important case: "REBOOT MESSAGE": - allow don't save alarm during reboot time. - (NOT IMPLEMENTED YET ;) ) + -B - message broadcasting -- allow send messages between operators work with + same config file. Most important case: "REBOOT + MESSAGE": allow don't save alarm during reboot + time. (NOT IMPLEMENTED YET ;) ) Mon Mar 15 08:57:01 CST 1999 ANSI c changes to eliminate warning messages on Linux build. @@ -413,7 +414,7 @@ Fri Feb 28 16:38:19 CST 2003 ALH_1_2_11Beta4 Mon Mar 3 09:24:38 CST 2003 ALH_1_2_11Beta5 Moved channel beepSevr modified indicators to preceed possible return. - Added code for display of highest existing beepSevr in sub groups and channels. + Added code for display of highest existing beepSevr in sub groups and channels Modified alarm log file output. Now calculate alarmLogFileStringLength. Changed fopen of alarm log file from r+ to w+(truncate or create). Modified forcePV opMod log messages text. @@ -464,9 +465,9 @@ Tue Apr 5 10:06:27 CDT 2005 Tue Jun 21 13:23:04 CDT 2005 ALH_1_2_20 Silence One Hour: - Set color of newly created row widgets to color of parent widget. - Change color of ALL widget children except ack button, sevr indicator, - and name push button. + Set color of newly created row widgets to color of parent widget. + Change color of ALL widget children except ack button, sevr indicator, + and name push button. Write errMsg text to opMod log file when errors occur. Remove extra carriage returns in opMod log file. Remove group and channel data from opMod log message if they do not exist. @@ -584,7 +585,87 @@ Fri Jul 9 15:14:24 CDT 2010 ALH_1_2_26 Portablility changes. Bug fix: set current value to -999 to recalculate and test the force pv expression after user changes are Applied from the ForcePV dialog box. - Core dump bug fix: Test for existance before trying to modify runtime + Core dump bug fix: Test for existance before trying to modify runtime window string. Alh may be started with main window only (-mainwindow). Removed references to Alarm Configuration Tool in ALH Users Manual. +Fri Feb 25 14:23:01 CST 2011 ALH_1_2_27 + Use alBeep instead of calling XBell directly. Changed call to XBell + to call to XkbBell. Portability changes. alLog.c: Added static qualifier + to local routines. Remove extra carrige return in alarm log output. + Check for _lock_flag also when checking masterFlag. + +Tue Jul 26 13:56:13 CDT 2011 + Changed code to allow up to 99 chars in group, channel, and pv names. + Modified Current Alarm Histroy Window to use 7x14 fixed font and to + truncate long channel names to 31 characters. Fixed formating bug in + error messagelogs. Modified main windows and popup Action dialogs to + allow long group/channel names and pv names. + +Tue May 22 16:29:19 CDT 2012 ALH_1_2_28 + Added following changes and command line options by Andreas Luedeke + Changed silenced bg color from lightpink to blue + Add file name to config file open error message. + -p file use wave file for sound instead of alarm beep (OS dependent) + -maskcolor Print mask colored when channel/group contains silencing flag + makes it easier to find all canceled/disabled/noAck channels. + -Lfile dir lockfile directory name for lock files [configdir] + +Thu Jun 21 15:26:50 CDT 2012 ALH_1_2_29 + Changed silenced and noack bg color from blue to lightpink. + Modified popup dialogs for WIN32 to allow use with Xming X server. + +Wed Aug 29 16:32:14 CDT 2012 ALH_1_2_30 + Increased size of group and channel config file input fields. Portability + changes. Bug fix in initialization of psetup. Change darwin default to + HAVE_SYSV_IPC. + +Thu Nov 29 15:13:46 CST 2012 ALH_1_2_31 + Added code to browser.c (from ) and Makefile to use + xdg-open on Linux systems to open an url from alh if the compiler macro + USE_XDGOPEN was defined during the build. + Fixed bugs in AlarmLogDated (-T option) code. + +Mon Apr 22 11:05:07 CDT 2012 + Modified text in 2 error messages. Changed alarm bell function from Xbell + to XkbBell. Used more modern tools to open default browser. Changed + silenced background color back to blue. + +Tue Apr 23 10:57:01 CDT 2013 + SilenceOneHour feature changed: Added setup/select_silence_interval menu + item with interval selections 5, 10, 15, 30, 60 minutes. SilenceOneHour + button text now shows selected interval (default is 1 hour). Pressing + silence button on message window will silence beeps for selected time + interval. Changing interval selection will terminate an existing silence + interval. + +Wed Apr 24 16:11:47 CDT 2013 + Added two more 'ALARMCOUNTFILTER counts seconds' filters. If counts is + zero, counts is not used in determining alarm/no-alarm state. Seconds only + are used for a channel going in and out of alarm. If counts is -1, seconds + only are used for channel going from no-alarm to alarm state. Change in + channel from alarm to no-alarm state is not filtered. + +Thu Apr 25 10:22:57 CDT 2013 + Changed log file handling on alh startup. Now when error opening alarmLog or + opModLog file, an error message popup will be displayed and alh will continue + without the file. The file can be opened/created after startup via setup menu. + +Tue May 14 11:19:07 CDT 2013 ALH_1_2_32 + Minor text changes. Updated User's Guide text and images. + +Mon May 20 13:49:51 CDT 2013 ALH_1_2_33 + Fixed code for the -maskcolor command line option. Accidental commit on May 14 + broke the -maskcolor code. + +Thu Jul 17 14:10:37 CDT 2014 ALH_1_2_34 + Changed way beeping option -p works. Used fork() and execlp() to get play + process to run in the background. Ignore SIGCHLD signals so alh doesn't have to + wait for child processes to finish. + +Mon Aug 25 14:09:19 CDT 2014 ALH_1_2_35 + Changed beeping option with -p again. Used system() with '&' at command + end. Created a "test beep" setup menu item to test the beeping sound. + An error message is displayed if the command line sound file cannot be + opened for read access. Changed default silence interval to .5 hour. + diff --git a/alh_DB.c b/alh_DB.c index 057084c..e72aa65 100644 --- a/alh_DB.c +++ b/alh_DB.c @@ -81,7 +81,6 @@ int DBMsgQId; int DBMsgQKey; int port; int bytes=250; -int socket; if (argc != 4) { fprintf(stderr,"usage:%s TCPName TCPport Key\n",argv[0]); @@ -99,10 +98,10 @@ int socket; fprintf(stderr,"msgQ with key=%d is OK\n",DBMsgQKey); if (msgctl(DBMsgQId,IPC_STAT,&infoBuf) != 1) { - fprintf(stderr,"owner = %d.%d, perms = %04o, max bytes = %d\n", + fprintf(stderr,"owner = %d.%d, perms = %04o, max bytes = %ld\n", infoBuf.msg_perm.uid,infoBuf.msg_perm.gid, infoBuf.msg_perm.mode,infoBuf.msg_qbytes); - fprintf(stderr,"%d msgs = %d bytes on queue\n", + fprintf(stderr,"%ld msgs = %ld bytes on queue\n", infoBuf.msg_qnum, infoBuf.msg_cbytes); } else {perror("msgctl()"); exit(1);} @@ -178,8 +177,6 @@ xdr_DBSend(xdrs, objp) DBSend *objp; { - register long *buf; - if (!xdr_string(xdrs, &objp->msg, ~0)) return (FALSE); return (TRUE); diff --git a/awAlh.c b/awAlh.c index 4ac8f1d..a06654a 100644 --- a/awAlh.c +++ b/awAlh.c @@ -118,22 +118,27 @@ void awUpdateRowWidgets(line) Update line widgets #define MENU_SETUP_FILTER_NONE 10503 #define MENU_SETUP_FILTER_ACTIVE 10504 #define MENU_SETUP_FILTER_UNACK 10505 -#define MENU_SETUP_SILENCE_FOREVER 10506 -#define MENU_SETUP_ALARMLOG 10507 -#define MENU_SETUP_OPMOD 10508 - -#define MENU_ACTION_BEEP_MINOR 10500 -#define MENU_ACTION_BEEP_MAJOR 10501 -#define MENU_ACTION_BEEP_INVALID 10502 +#define MENU_SETUP_SILENCE_INTERVAL_5 10506 +#define MENU_SETUP_SILENCE_INTERVAL_10 10507 +#define MENU_SETUP_SILENCE_INTERVAL_15 10509 +#define MENU_SETUP_SILENCE_INTERVAL_30 10510 +#define MENU_SETUP_SILENCE_INTERVAL_60 10511 +#define MENU_SETUP_SILENCE_FOREVER 10512 +#define MENU_SETUP_ALARMLOG 10513 +#define MENU_SETUP_OPMOD 10514 +#define MENU_SETUP_TESTBEEPSOUND 10515 #define MENU_HELP_HELP 10900 #define MENU_HELP_ABOUT 10906 /* external variables */ +extern Display *display; +extern Pixel silenced_bg_pixel; extern char alhVersionString[100]; extern char *bg_char[]; extern Pixel bg_pixel[]; extern Pixel channel_bg_pixel; +extern Pixel noack_bg_pixel; extern struct setup psetup; extern Widget versionPopup; extern int _message_broadcast_flag; /* messages sending flag. Albert1*/ @@ -146,6 +151,7 @@ extern int max_not_save_time; extern int amIsender; extern int DEBUG; extern int _main_window_flag; +extern int _mask_color_flag; char FS_filename[128]; /* Filename for FSBox. Albert*/ struct UserInfo { @@ -395,21 +401,21 @@ static Widget mkDragIcon ( unsigned long gcValueMask; char tmpStr[131+1], *str; - Display *display = XtDisplay(w); - int screenNum = DefaultScreen(display); + Display *disp = XtDisplay(w); + int screenNum = DefaultScreen(disp); Pixmap sourcePixmap = (Pixmap)NULL; if ( !g_ddFixedFont_created ) { g_ddFixedFont_created = 1; - g_ddFixedFont = XLoadQueryFont( display, "fixed" ); + g_ddFixedFont = XLoadQueryFont( disp, "fixed" ); } #define X_SHIFT 8 #define MARGIN 2 - bg = BlackPixel(display,screenNum); - fg = WhitePixel(display,screenNum); + bg = BlackPixel(disp,screenNum); + fg = WhitePixel(disp,screenNum); fontHeight = g_ddFixedFont->ascent + g_ddFixedFont->descent; @@ -425,14 +431,14 @@ static Widget mkDragIcon ( maxWidth = X_SHIFT + ( textWidth + MARGIN ); maxHeight = fontHeight + 2 * MARGIN; - sourcePixmap = XCreatePixmap(display, - RootWindow(display, screenNum), + sourcePixmap = XCreatePixmap(disp, + RootWindow(disp, screenNum), maxWidth,maxHeight, - DefaultDepth(display,screenNum) ); + DefaultDepth(disp,screenNum) ); if ( !g_ddgc_created ) { g_ddgc_created = 1; - g_ddgc = XCreateGC( display, sourcePixmap, 0, NULL ); + g_ddgc = XCreateGC( disp, sourcePixmap, 0, NULL ); } gcValueMask = GCForeground|GCBackground|GCFunction|GCFont; @@ -442,14 +448,14 @@ static Widget mkDragIcon ( gcValues.function = GXcopy; gcValues.font = g_ddFixedFont->fid; - XChangeGC( display, g_ddgc, gcValueMask, &gcValues ); + XChangeGC( disp, g_ddgc, gcValueMask, &gcValues ); - XFillRectangle( display, sourcePixmap, g_ddgc, 0, 0, maxWidth, + XFillRectangle( disp, sourcePixmap, g_ddgc, 0, 0, maxWidth, maxHeight); - XSetForeground( display, g_ddgc, fg ); + XSetForeground( disp, g_ddgc, fg ); - XDrawString( display, sourcePixmap, g_ddgc, + XDrawString( disp, sourcePixmap, g_ddgc, X_SHIFT, g_ddFixedFont->ascent + MARGIN, tmpStr, strlen(tmpStr) ); @@ -457,7 +463,7 @@ static Widget mkDragIcon ( XtSetArg(args[n],XmNpixmap,sourcePixmap); n++; XtSetArg(args[n],XmNwidth,maxWidth); n++; XtSetArg(args[n],XmNheight,maxHeight); n++; - XtSetArg(args[n],XmNdepth,DefaultDepth(display,screenNum)); n++; + XtSetArg(args[n],XmNdepth,DefaultDepth(disp,screenNum)); n++; sourceIcon = XmCreateDragIcon(XtParent(w),"sourceIcon",args,n); return sourceIcon; @@ -658,6 +664,20 @@ static MenuItem action_menuNew[] = { {NULL}, }; + static MenuItem setup_silence_interval_menu[] = { + { "5 minutes", PushButtonGadgetClass, 0, NULL, NULL, + alhSetupCallback, (XtPointer)MENU_SETUP_SILENCE_INTERVAL_5, (MenuItem *)NULL, 0 }, + { "10 minutes", PushButtonGadgetClass, 0, NULL, NULL, + alhSetupCallback, (XtPointer)MENU_SETUP_SILENCE_INTERVAL_10, (MenuItem *)NULL, 0 }, + { "15 minutes", PushButtonGadgetClass, 0, NULL, NULL, + alhSetupCallback, (XtPointer)MENU_SETUP_SILENCE_INTERVAL_15, (MenuItem *)NULL, 0 }, + { "30 minutes", PushButtonGadgetClass, 0, NULL, NULL, + alhSetupCallback, (XtPointer)MENU_SETUP_SILENCE_INTERVAL_30, (MenuItem *)NULL, 0 }, + { "1 hour", PushButtonGadgetClass, 0, NULL, NULL, + alhSetupCallback, (XtPointer)MENU_SETUP_SILENCE_INTERVAL_60, (MenuItem *)NULL, 0 }, + {NULL}, + }; + static MenuItem setup_filter_menu[] = { { "No filter", PushButtonGadgetClass, 'N', NULL, NULL, alhSetupCallback, (XtPointer)MENU_SETUP_FILTER_NONE, (MenuItem *)NULL, 0 }, @@ -677,12 +697,16 @@ static MenuItem action_menuNew[] = { { "Audio Setup...", ToggleButtonGadgetClass, 'D', NULL, NULL, alhAudioSetupCallback, NULL, (MenuItem *)NULL, 0 }, #endif + { "Select silence interval...",PushButtonGadgetClass, 'S', NULL, NULL, + 0, 0, (MenuItem *)setup_silence_interval_menu, 0 }, { "Silence Forever", ToggleButtonGadgetClass, 'S', NULL, NULL, alhSetupCallback, (XtPointer)MENU_SETUP_SILENCE_FOREVER,(MenuItem *)NULL, 0 }, { "New Alarm Log File Name...", PushButtonGadgetClass, 'L', NULL, NULL, alhSetupCallback, (XtPointer)MENU_SETUP_ALARMLOG, (MenuItem *)NULL, 0 }, { "New Oper. Log File Name...", PushButtonGadgetClass, 'O', NULL, NULL, alhSetupCallback, (XtPointer)MENU_SETUP_OPMOD, (MenuItem *)NULL, 0 }, + { "Test Beep Sound", PushButtonGadgetClass, 'B', NULL, NULL, + alhSetupCallback, (XtPointer)MENU_SETUP_TESTBEEPSOUND,(MenuItem *)NULL, 0 }, {NULL}, }; @@ -1129,16 +1153,14 @@ static void messBroadcast(Widget widget,XtPointer item,XtPointer cbs) /* Albert if(amIsender) { createDialog(area->form_main,XmDIALOG_INFORMATION, - "You send some message before. \n" "\n" - "Please wait a few seconds \n",""); + "You send some message before. \n\n Please wait a few seconds \n",""); return; } if ( lockf(messBroadcastDeskriptor, F_TLOCK, 0L) < 0 ) { if ((errno == EAGAIN || errno == EACCES )) { if(DEBUG) fprintf(stderr,"file is busy;Deskriptor=%d\n",messBroadcastDeskriptor); createDialog(area->form_main,XmDIALOG_INFORMATION, - "Some other operator type a message. \n" "\n" - "Please wait a few seconds \n",""); + "Some other operator type a message. \n\nPlease wait a few seconds\n",""); return; } else { @@ -1149,7 +1171,7 @@ static void messBroadcast(Widget widget,XtPointer item,XtPointer cbs) /* Albert { if(DEBUG) fprintf(stderr,"file is free;Deskriptor=%d\n",messBroadcastDeskriptor); - dialog = XmCreatePromptDialog(area->form_main, "dialog", NULL, 0); + dialog = XmCreatePromptDialog(area->form_main, "ALH MessageEntryDialog", NULL, 0); XtVaSetValues(dialog,XtVaTypedArg, XmNselectionLabelString, XmRString, "Type message (See help for detail):", 40,NULL); @@ -1208,7 +1230,6 @@ int type; return; } - timeID=time(0L); time_tmp=timeID; @@ -1257,10 +1278,9 @@ int type; } fprintf(fp,"%ld\n%s",timeID,buff); - createDialog(ar->form_main,XmDIALOG_MESSAGE,"Broadcast Message: \n""\n""\n",buff); + createDialog(ar->form_main,XmDIALOG_MESSAGE,"Broadcast Message: \n\n\n",buff); fclose(fp); - XtFree(string); amIsender=1; XtAppAddTimeOut(appContext,messBroadcastLockDelay,messBroadcastFileUnlock,NULL); @@ -1328,7 +1348,7 @@ static void alhSetupCallback( Widget widget, XtPointer calldata, XtPointer cbs) { int item=(long)calldata; ALINK *area; - + XmString silence_string; XtVaGetValues(widget, XmNuserData, &area, NULL); @@ -1367,6 +1387,66 @@ static void alhSetupCallback( Widget widget, XtPointer calldata, XtPointer cbs) changeBeepSeverityText(area); break; + case MENU_SETUP_SILENCE_INTERVAL_5: + + if (area->silenceMinutes != 5) { + area->silenceMinutes=5; + silenceSelectedMinutesReset(area); + } + silence_string = XmStringCreateLocalized ("Silence 5 minutes"); + XtVaSetValues(area->silenceSelectedMinutes, XmNlabelString, silence_string, NULL); + XmStringFree (silence_string); + alLogOpModMessage(0,0,"Silence interval set to 5 minutes"); + break; + + case MENU_SETUP_SILENCE_INTERVAL_10: + + if (area->silenceMinutes != 10) { + area->silenceMinutes=10; + silenceSelectedMinutesReset(area); + } + silence_string = XmStringCreateLocalized ("Silence 10 minutes"); + XtVaSetValues(area->silenceSelectedMinutes, XmNlabelString, silence_string, NULL); + XmStringFree (silence_string); + alLogOpModMessage(0,0,"Silence interval set to 10 minutes"); + break; + + case MENU_SETUP_SILENCE_INTERVAL_15: + + if (area->silenceMinutes != 15) { + area->silenceMinutes=15; + silenceSelectedMinutesReset(area); + } + silence_string = XmStringCreateLocalized ("Silence 15 minutes"); + XtVaSetValues(area->silenceSelectedMinutes, XmNlabelString, silence_string, NULL); + XmStringFree (silence_string); + alLogOpModMessage(0,0,"Silence interval set to 15 minutes"); + break; + + case MENU_SETUP_SILENCE_INTERVAL_30: + + if (area->silenceMinutes != 30) { + area->silenceMinutes=30; + silenceSelectedMinutesReset(area); + } + silence_string = XmStringCreateLocalized ("Silence 30 minutes"); + XtVaSetValues(area->silenceSelectedMinutes, XmNlabelString, silence_string, NULL); + XmStringFree (silence_string); + alLogOpModMessage(0,0,"Silence interval set to 30 minutes"); + break; + + case MENU_SETUP_SILENCE_INTERVAL_60: + + if (area->silenceMinutes != 60) { + area->silenceMinutes=60; + silenceSelectedMinutesReset(area); + } + silence_string = XmStringCreateLocalized ("Silence 1 hour"); + XtVaSetValues(area->silenceSelectedMinutes, XmNlabelString, silence_string, NULL); + XmStringFree (silence_string); + alLogOpModMessage(0,0,"Silence interval set to 1 hour"); + break; + case MENU_SETUP_SILENCE_FOREVER: silenceForeverChangeState(area); @@ -1392,6 +1472,11 @@ static void alhSetupCallback( Widget widget, XtPointer calldata, XtPointer cbs) "Operator Modification File", OPMOD_PATTERN,psetup.logDir); break; + case MENU_SETUP_TESTBEEPSOUND: + + /* Test beep sound */ + alBeep(display); + break; } } @@ -1445,8 +1530,9 @@ void awRowWidgets(struct anyLine *line,void *area) Position nextX; Dimension width; Widget parent; - Pixel backgroundColor; - + Pixel backgroundColor=1; + Pixel bgMask; + subWindow=line->pwindow; parent = ((struct subWindow *)subWindow)->drawing_area; wline=(WLINE *)line->wline; @@ -1474,7 +1560,8 @@ void awRowWidgets(struct anyLine *line,void *area) if ( glink->pgroupData->treeSym) { str = XmStringCreateSimple(glink->pgroupData->treeSym); wline->treeSym = XtVaCreateManagedWidget("treeSym", - xmLabelGadgetClass, wline->row_widget, + xmLabelWidgetClass, wline->row_widget, + XmNbackground, backgroundColor, XmNlabelString, str, XmNmarginHeight, 0, NULL); @@ -1552,7 +1639,7 @@ void awRowWidgets(struct anyLine *line,void *area) XmNuserData, (XtPointer)area, XmNx, nextX, XmNy, 2, - XmNbackground, backgroundColor, + /* XmNbackground, backgroundColor,*/ (XtPointer)NULL); if (line->linkType == GROUP && sllFirst(&(glink->subGroupList))){ XtManageChild(wline->arrow); @@ -1599,6 +1686,8 @@ void awRowWidgets(struct anyLine *line,void *area) nextX = nextX + width + 3; } + /* A.Luedeke : Added color when mask is silencing: 'C', 'D', 'A' or 'H' */ + if (_mask_color_flag&&(line->mask[1]!='-'||line->mask[2]!='-'||line->mask[3]!='-')) {bgMask=noack_bg_pixel;} else {bgMask=bg_pixel[0];} /* A.L.: added color */ str = XmStringCreateSimple(line->mask); wline->mask = XtVaCreateManagedWidget("mask", xmLabelWidgetClass, wline->row_widget, @@ -1610,6 +1699,11 @@ void awRowWidgets(struct anyLine *line,void *area) XmStringFree(str); XtVaGetValues(wline->mask,XmNwidth,&width,NULL); nextX = nextX + width + 3; +#if XmVersion && XmVersion >= 1002 + XmChangeColor(wline->mask,bgMask); /* A.L.: added color */ +#else + XtVaSetValues(wline->mask,XmNbackground,bgMask,NULL); /* A.L.: added color */ +#endif str = XmStringCreateSimple(line->highestBeepSevrString); wline->highestbeepsevr = XtVaCreateManagedWidget("highestbeepsevr", @@ -1790,6 +1884,8 @@ void awUpdateRowWidgets(struct anyLine *line) XmString str; WLINE *wline; Pixel bg; + Pixel bgMask; + Pixel backgroundColor; XmString strOld; Boolean sensitiveOld; @@ -1852,13 +1948,23 @@ void awUpdateRowWidgets(struct anyLine *line) XtVaGetValues(wline->mask, XmNlabelString, &strOld, + XmNbackground, &backgroundColor, NULL); str = XmStringCreateSimple(line->mask); - if (!XmStringCompare(str,strOld)) + /* A.Luedeke : Added color when mask is silencing: 'C', 'D', 'A' or 'H' */ + + if (_mask_color_flag&&(line->mask[1]!='-'||line->mask[2]!='-'||line->mask[3]!='-')) {bgMask=noack_bg_pixel;} else {bgMask=bg_pixel[0];} /* A.L.: added color */ + if (!XmStringCompare(str,strOld)) { XtVaSetValues(wline->mask, XmNlabelString, str, NULL); +#if XmVersion && XmVersion >= 1002 + XmChangeColor(wline->mask,bgMask); /* A.L.: added color */ +#else + XtVaSetValues(wline->mask,XmNbackground,bgMask,NULL); /* A.L.: added color */ +#endif + } XmStringFree(str); XmStringFree(strOld); diff --git a/ax.h b/ax.h index e56e85a..7341a98 100644 --- a/ax.h +++ b/ax.h @@ -70,7 +70,9 @@ void createRuntimeWindow( ALINK *area); void silenceCurrentReset(void *area); void silenceCurrent_callback( Widget w, ALINK* area, XmAnyCallbackStruct *call_data); void silenceForeverChangeState( ALINK *area); -void silenceOneHour_callback( Widget w, ALINK* area, XmAnyCallbackStruct *call_data); +void silenceSelectedMinutes_callback( Widget w, ALINK* area, XmAnyCallbackStruct *call_data); +void changeTreeColor(Widget widget,Pixel color); +void silenceSelectedMinutesReset(void *area); /******************************************************************** diff --git a/axArea.c b/axArea.c index 249ff18..42b9555 100644 --- a/axArea.c +++ b/axArea.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -47,9 +48,9 @@ #include "ax.h" Pixmap ALH_pixmap; -char *silenceString[] = {"Off","On"}; -const char *executionStateString[] = {"Active","Passive"}; -char *disabledForcePVCountString[] = {" ","Disabled forcePVs:"}; +static char *silenceString[] = {"Off","On"}; +static const char *executionStateString[] = {"Active","Passive"}; +static char *disabledForcePVCountString[] = {" ","Disabled forcePVs:"}; /* global variables */ extern int _global_flag; @@ -596,9 +597,9 @@ void createMainWindowWidgets(ALINK *area) NULL); XmStringFree(str); - - /* Create a Silence One Hour Toggle Button in the messageArea */ - area->silenceOneHour = XtVaCreateManagedWidget("SilenceOneHour", + /* Create a Silence Selected Minutes Toggle Button in the messageArea */ + area->silenceMinutes = 30; + area->silenceSelectedMinutes = XtVaCreateManagedWidget("Silence 30 minutes", xmToggleButtonGadgetClass, area->messageArea, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, area->scale, @@ -607,10 +608,10 @@ void createMainWindowWidgets(ALINK *area) NULL); /* Create a Silence Current Toggle Button in the messageArea */ - area->silenceCurrent = XtVaCreateManagedWidget("SilenceCurrent", + area->silenceCurrent = XtVaCreateManagedWidget("Silence current", xmToggleButtonGadgetClass, area->messageArea, XmNtopAttachment, XmATTACH_WIDGET, - XmNtopWidget, area->silenceOneHour, + XmNtopWidget, area->silenceSelectedMinutes, XmNrightAttachment, XmATTACH_FORM, XmNuserData, (XtPointer)area, NULL); @@ -667,8 +668,8 @@ void createMainWindowWidgets(ALINK *area) NULL); XmStringFree(str); - XtAddCallback(area->silenceOneHour, XmNvalueChangedCallback, - (XtCallbackProc)silenceOneHour_callback,area); + XtAddCallback(area->silenceSelectedMinutes, XmNvalueChangedCallback, + (XtCallbackProc)silenceSelectedMinutes_callback,area); XtAddCallback(area->silenceCurrent, XmNvalueChangedCallback, (XtCallbackProc)silenceCurrent_callback,area); diff --git a/axArea.h b/axArea.h index f3cab6d..b35b2a4 100644 --- a/axArea.h +++ b/axArea.h @@ -53,7 +53,7 @@ typedef struct areaLink{ Widget label_groupAlarm; Widget label_channelAlarm; Widget label_mask; - Widget silenceOneHour; + Widget silenceSelectedMinutes; Widget silenceCurrent; Widget silenceForever; Widget silenceForeverLabel; @@ -93,9 +93,11 @@ typedef struct areaLink{ int currentAlarmIndex; Widget currentAlarmForm; Widget currentAlarm[10]; - char currentAlarmString[10][128]; + char currentAlarmString[10][228]; int w; int h; + /* ----- Silence minutes info ----- */ + int silenceMinutes; } ALINK; typedef struct _menu_item { diff --git a/axRunW.c b/axRunW.c index f45c9af..a2b60e5 100644 --- a/axRunW.c +++ b/axRunW.c @@ -15,6 +15,7 @@ /* axRunW.c */ #include +#include #include #include @@ -40,7 +41,8 @@ static XtIntervalId blinkTimeoutId = (XtIntervalId)0; static char *bg_color[] = {"lightblue","yellow","red","white","white","grey"}; static char *channel_bg_color = "lightblue"; -static char *silenced_bg_color = "lightpink"; +static char *silenced_bg_color = "blue"; +static char *noack_bg_color = "blue"; /* global variabless */ @@ -49,9 +51,11 @@ extern Display *display; extern struct setup psetup; extern char *programName; extern Pixmap ALH_pixmap; +extern int _mask_color_flag; Pixel bg_pixel[ALH_ALARM_NSEV]; Pixel channel_bg_pixel; Pixel silenced_bg_pixel; +Pixel noack_bg_pixel; const char *bg_char[] = {" ", "Y", "R", "V", "E"," " }; /* forward declarations */ @@ -60,8 +64,7 @@ static void axExitArea_callback(Widget w,ALINK *area,XmAnyCallbackStruct *call_d static void blinking(XtPointer pointer, XtIntervalId *id); static void createMainWindow_callback(Widget w,ALINK *area,XmAnyCallbackStruct *call_data); static void icon_update(Widget blinkButton); -static void silenceOneHourReset(void *area); -static void changeTreeColor(Widget widget,Pixel color); + char *Strncat( char *dest, const char *src, @@ -174,11 +177,11 @@ void createRuntimeWindow(ALINK *area) XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, - XmNactivateCallback, (XtPointer)NULL, + XmNactivateCallback, (XtPointer)NULL, XmNuserData, (XtPointer)area, XmNlabelString, str, XmNfontList, fontList, - (XtPointer)NULL); + NULL); XmStringFree(str); XtAddCallback(area->blinkButton,XmNactivateCallback, @@ -206,7 +209,7 @@ void createRuntimeWindow(ALINK *area) /* reinitialize silence beep */ silenceCurrentReset(area); - silenceOneHourReset(area); + silenceSelectedMinutesReset(area); icon_update(area->blinkButton); @@ -348,7 +351,7 @@ static void blinking(XtPointer pointer, XtIntervalId *id) XmChangeColor(blinkButton,blinkPixel); } if (!psetup.silenceForever && - !psetup.silenceOneHour && + !psetup.silenceSelectedMinutes && !psetup.silenceCurrent && (psetup.highestUnackBeepSevr >= psetup.beepSevr)) { @@ -386,13 +389,13 @@ void silenceCurrentReset(void *area) } /*********************************************** - reset silenceOneHourReset + reset silenceSelectedMinutesReset ************************************************/ -static void silenceOneHourReset(void *area) +void silenceSelectedMinutesReset(void *area) { - if (psetup.silenceOneHour) { - XmToggleButtonGadgetSetState(((ALINK*)area)->silenceOneHour,FALSE,FALSE); - silenceOneHour_callback(((ALINK*)area)->silenceOneHour,area,NULL); + if (psetup.silenceSelectedMinutes) { + XmToggleButtonGadgetSetState(((ALINK*)area)->silenceSelectedMinutes,FALSE,FALSE); + silenceSelectedMinutes_callback(((ALINK*)area)->silenceSelectedMinutes,area,NULL); } } @@ -410,42 +413,46 @@ XmAnyCallbackStruct *call_data) } /*************************************************** - silenceOneHour button toggle callback + silenceSelectedMinutes button toggle callback ****************************************************/ -void silenceOneHour_callback(Widget w,ALINK* area, +void silenceSelectedMinutes_callback(Widget w,ALINK* area, XmAnyCallbackStruct *call_data) { static XtIntervalId intervalId = 0; - int seconds = 3600; + int seconds = 60*area->silenceMinutes; - psetup.silenceOneHour = psetup.silenceOneHour?FALSE:TRUE; - if (psetup.silenceOneHour) { + psetup.silenceSelectedMinutes = psetup.silenceSelectedMinutes?FALSE:TRUE; + if (psetup.silenceSelectedMinutes) { intervalId = XtAppAddTimeOut(appContext, (unsigned long)(1000*seconds), - (XtTimerCallbackProc)silenceOneHourReset, + (XtTimerCallbackProc)silenceSelectedMinutesReset, (XtPointer)area); XmChangeColor(area->messageArea,silenced_bg_pixel); - changeTreeColor(area->treeWindowForm,silenced_bg_pixel); - changeTreeColor(area->groupWindowForm,silenced_bg_pixel); + if (!_mask_color_flag) { + changeTreeColor(area->treeWindowForm,silenced_bg_pixel); + changeTreeColor(area->groupWindowForm,silenced_bg_pixel); + } changeTreeColor(area->scale,silenced_bg_pixel); - alLogOpModMessage(0,0,"Silence One Hour set to TRUE"); + alLogOpModMessage(0,0,"Silence Selected Minutes set to TRUE"); } else { if (intervalId) { XtRemoveTimeOut(intervalId); intervalId = 0; } XmChangeColor(area->messageArea,bg_pixel[0]); - changeTreeColor(area->treeWindowForm,bg_pixel[0]); - changeTreeColor(area->groupWindowForm,bg_pixel[0]); + if (!_mask_color_flag) { + changeTreeColor(area->treeWindowForm,bg_pixel[0]); + changeTreeColor(area->groupWindowForm,bg_pixel[0]); + } changeTreeColor(area->scale,bg_pixel[0]); - alLogOpModMessage(0,0,"Silence One Hour set to FALSE"); + alLogOpModMessage(0,0,"Silence Selected Minutes set to FALSE"); } } /*************************************************** changeTreeColor ****************************************************/ -static void changeTreeColor(Widget widget,Pixel color) +void changeTreeColor(Widget widget,Pixel color) { int i; Widget *children; @@ -527,6 +534,7 @@ void pixelData(Widget iconBoard) channel_bg_pixel = COLOR(dsply,channel_bg_color); silenced_bg_pixel = COLOR(dsply,silenced_bg_color); + noack_bg_pixel = COLOR(dsply,noack_bg_color); /* retrieve the background color of the iconBoard */ XtVaGetValues(iconBoard, XmNbackground, &bg_pixel[0], NULL); diff --git a/browser.c b/browser.c index 0e7f815..a69fc59 100644 --- a/browser.c +++ b/browser.c @@ -15,7 +15,7 @@ /* browser.c */ /************************DESCRIPTION*********************************** - Invokes Netscape browser + Invokes default browser Original Author : Kenneth Evans, Jr. **********************************************************************/ @@ -33,28 +33,18 @@ #include #include #include -#include -#include #include #include #include #include -#include - -#ifndef NETSCAPEPATH -#define NETSCAPEPATH "netscape" -#endif /* Function prototypes */ extern int kill(pid_t, int); /* May not be defined for strict ANSI */ int callBrowser(char *url); -static Window checkNetscapeWindow(Window w); static int execute(char *s); -static Window findNetscapeWindow(void); -static int ignoreXError(Display *display, XErrorEvent *xev); /* Global variables */ extern Display *display; @@ -65,12 +55,9 @@ int callBrowser(char *url) /* url is the URL that the browser is to display */ /* or "quit" to terminate the browser */ { - int (*oldhandler)(Display *, XErrorEvent *); - static Window netscapew=(Window)0; static pid_t pid=0; int status; char command[BUFSIZ]; - char *envstring; /* Handle quit */ if(!strcmp(url,"quit")) { @@ -80,48 +67,19 @@ int callBrowser(char *url) } return 3; } - /* Set handler to ignore possible BadWindow error */ - /* (Would prefer a routine that tells if the window is defined) */ - oldhandler=XSetErrorHandler(ignoreXError); - /* Check if the stored window value is valid */ - netscapew=checkNetscapeWindow(netscapew); - /* Reset error handler */ - XSetErrorHandler(oldhandler); - /* If stored window is not valid, look for a valid one */ - if(!netscapew) { - netscapew=findNetscapeWindow(); - /* If no window found, exec Netscape */ - if(!netscapew) { - envstring=getenv("BROWSER"); - if(!envstring) envstring=getenv("NETSCAPEPATH"); - if(!envstring) { - sprintf(command,"%s -install '%s' &",NETSCAPEPATH,url); - } - else { - sprintf(command,"%s -install '%s' &",envstring,url); - } -#if DEBUG - printf("execute(before): cmd=%s\n",command); -#endif - status=execute(command); -#if DEBUG - printf("execute(after): cmd=%s status=%d\n",command,status); -#endif - return 1; - } - } - /* Netscape window is valid, send url via -remote */ - /* (Use -id for speed) */ - envstring=getenv("BROWSER"); - if(!envstring) envstring=getenv("NETSCAPEPATH"); - if(!envstring) { - sprintf(command,"%s -id 0x%x -remote 'openURL(%s)' &", - NETSCAPEPATH,(unsigned int)netscapew,url); - } - else { - sprintf(command,"%s -id 0x%x -remote 'openURL(%s)' &", - envstring,(unsigned int)netscapew,url); - } +#if defined __linux__ /* defined by gnu compiler preprocessor */ + sprintf(command,"xdg-open \"%s\" &",url); +#elif defined SOLARIS /* defined in EPICS base configure files */ + sprintf(command,"sdtwebclient \"%s\" &",url); +#elif defined darwin /* defined in EPICS base configure files */ + sprintf(command,"open \"%s\" &",url); +#elif defined __CYGWIN32__ /* defined by gnu compiler preprocessor */ + sprintf(command,"cygstart \"%s\" &",url); +#elif defined USE_HTMLVIEW + sprintf(command,"htmlview \"%s\" &",url); +#else + return 1; +#endif #if DEBUG printf("execute(before): cmd=%s\n",command); #endif @@ -131,35 +89,7 @@ int callBrowser(char *url) #endif return 2; } -/**************************** checkNetscapeWindow ************************/ -static Window checkNetscapeWindow(Window w) -/* Checks if this window is the Netscape window and returns the window - * if it is or 0 otherwise */ -{ - Window wfound=(Window)0; - static Atom typeatom,versionatom=(Atom)0; - unsigned long nitems,bytesafter; - int format,status; - unsigned char *version=NULL; - /* If window is NULL, return it */ - if(!w) return w; - /* Get the atom for the version property (once) */ - if(!versionatom) versionatom=XInternAtom(display,"_MOZILLA_VERSION",False); - /* Get the version property for this window if it exists */ - status=XGetWindowProperty(display,w,versionatom,0, - (65536/sizeof(long)),False,AnyPropertyType, - &typeatom,&format,&nitems,&bytesafter,&version); - /* If the version property exists, it is the Netscape window */ - if(version && status == Success) wfound=w; -#if DEBUG - printf("XGetWindowProperty: status=%d version=%d w=%x wfound=%x\n", - status,version,w,wfound); -#endif - /* Free space and return */ - if(version) XFree((void *)version); - return wfound; -} /**************************** execute ************************************/ static int execute(char *s) /* From O'Reilly, Vol. 1, p. 438 */ @@ -182,47 +112,13 @@ static int execute(char *s) signal(SIGQUIT,qstat); return(status); } -/**************************** findNetscapeWindow *************************/ -static Window findNetscapeWindow(void) -{ - int screen=DefaultScreen(display); - Window rootwindow=RootWindow(display,screen); - Window *children,dummy,w,wfound=(Window)0; - unsigned int nchildren; - int i; - - /* Get the root window tree */ - if(!XQueryTree(display,rootwindow,&dummy,&dummy,&children,&nchildren)) - return (Window)0; - /* Look at the children from the top of the stacking order */ - for(i=nchildren-1; i >= 0; i--) { - w=XmuClientWindow(display,children[i]); - /* Check if this is the Netscape window */ -#if DEBUG - printf("Child %d ",i); -#endif - wfound=checkNetscapeWindow(w); - if(wfound) break; - } - if(children) XFree((void *)children); - return wfound; -} -/**************************** ignoreXError *******************************/ -static int ignoreXError(Display *display, XErrorEvent *xev) -{ -#if DEBUG - printf("In ignoreXError\n"); -#endif - return 0; -} -#else /*ifndef WIN32 */ +#else /*************************************************************************/ /*************************************************************************/ /* WIN32 Version */ /*************************************************************************/ /*************************************************************************/ - #include #include #include @@ -256,47 +152,13 @@ int callBrowser(char *url) ComSpec = getenv("ComSpec"); } if (!ComSpec) return(0); /* Abort with no message like the UNIX version*/ - /* Spawn the process that handles a url */ -#if 0 - /* Works, command window that goes away */ - sprintf(command,"start \"%s\"",url); - status = _spawnl(_P_WAIT, ComSpec, ComSpec, "/C", command, NULL); - - /* Works, command window that goes away */ - sprintf(command,"start \"%s\"",url); - status = _spawnl(_P_DETACH, ComSpec, ComSpec, "/C", command, NULL); - - /* Works, command window that goes away */ - sprintf(command,"\"%s\"",url); - status = _spawnl(_P_NOWAIT, "c:\\windows\\command\\start.exe", - "c:\\windows\\command\\start.exe", command, NULL); - - /* Works, command window that goes away */ - sprintf(command,"\"%s\"",url); - status = _spawnl(_P_WAIT, ComSpec, "start", command, NULL); - - /* Works, command window that goes away */ - sprintf(command,"start \"%s\"",url); - status = _spawnl(_P_NOWAIT, ComSpec, ComSpec, "/C", command, NULL); - - /* Doesn't work on 95 (No such file or directory), works on NT */ - sprintf(command,"start \"%s\"",url); - status = _spawnl(_P_NOWAIT, ComSpec, "/C", command, NULL); - - /* Works on 95, not NT, no command window - * No start.exe for NT */ - sprintf(command,"\"%s\"",url); - status = _spawnlp(_P_DETACH, "start", "start", command, NULL); - /* Doesn't work on 95 */ - sprintf(command,"\"start %s\"",url); - status = _spawnl(_P_DETACH, ComSpec, ComSpec, "/C", command, NULL); -#else + /* Spawn the process that handles a url */ /* This seems to work on 95 and NT, with a command box on 95 * It may have trouble if the URL has spaces */ sprintf(command,"start %s",url); status = _spawnl(_P_DETACH, ComSpec, ComSpec, "/C", command, NULL); -#endif + if(status == -1) { char *errstring=strerror(errno); @@ -308,67 +170,7 @@ int callBrowser(char *url) } return(1); } -#endif /* #ifndef WIN32 */ - -#if 0 -/*************************************************************************/ -/*************************************************************************/ -/* Mosaic Version */ -/*************************************************************************/ -/*************************************************************************/ - -#ifndef MOSAICPATH -/* #define MOSAICPATH "/usr/bin/X11/mosaic" */ -/* #define MOSAICPATH "/opt/local/bin/mosaic" */ -#define MOSAICPATH "mosaic" #endif -/**************************** callBrowser ********************************/ -int callBrowser(char *url) -/* Returns non-zero on success, 0 on failure */ -/* url is the URL that Mosaic is to display */ -/* or "quit" to terminate Mosaic */ -{ - static pid_t pid=0; - char filename[32]; - FILE *file; - char path[BUFSIZ]; - char *envstring; - signal(SIGCHLD,SIG_IGN); - /* Handle quit */ - if(!strcmp(url,"quit")) { - if (pid) { - sprintf(filename,"/tmp/Mosaic.%d",pid); - unlink(filename); - kill(pid,SIGTERM); - pid=0; - } - return 3; - } - /* If Mosaic is not up, exec it */ - if ((!pid) || kill(pid,0)) { - if (!(pid=fork())) { - envstring=getenv("MOSAICPATH"); - if(!envstring) { - sprintf(path,"%s",MOSAICPATH); - } - else { - sprintf(path,"%s",envstring); - } - execlp(path,path,url,(char *)0); - perror(path); - _exit(127); - } - return 1; - } - /* Mosaic is up, send message through file */ - sprintf(filename,"/tmp/Mosaic.%d",pid); - if (!(file=fopen(filename,"w"))) return 0; - fprintf(file,"goto\n%s\n",url); - fclose(file); - kill(pid,SIGUSR1); - return 2; -} -#endif diff --git a/current.c b/current.c index c58fec3..06a2bbd 100644 --- a/current.c +++ b/current.c @@ -55,6 +55,7 @@ void currentAlarmHistoryWindow(ALINK *area,Widget menuButton) Atom WM_DELETE_WINDOW; int i; char *app_name; + XmString xstr; if (!area->currentAlarmForm) { app_name = (char*) calloc(1,strlen(programName)+6); @@ -103,21 +104,24 @@ void currentAlarmHistoryWindow(ALINK *area,Widget menuButton) previous = button; /* add title line */ - title = XtVaCreateManagedWidget( - " TIME_STAMP PROCESS_VARIABLE_NAME " - "STATUS SEVERITY VALUE ", + xstr = XmStringCreateSimple( + " TIME_STAMP PROCESS_VARIABLE_NAME " + "STATUS SEVERITY VALUE "); + title = XtVaCreateManagedWidget("CurrentTitle", xmLabelGadgetClass, area->currentAlarmForm, + XmNlabelString, xstr, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, button, XmNrightAttachment, XmATTACH_FORM, NULL); + XmStringFree(xstr); /* create 10 label widgets */ for ( i=0;i<10;i++){ - area->currentAlarm[i] = XtVaCreateManagedWidget( "-----", + area->currentAlarm[i] = XtVaCreateManagedWidget( "CurrentAlarm", xmLabelGadgetClass, area->currentAlarmForm, XmNmarginHeight, 1, XmNalignment, XmALIGNMENT_BEGINNING, @@ -186,7 +190,7 @@ char value[],int stat,int sevr) if ( !area ) return; n = area->currentAlarmIndex; sprintf(area->currentAlarmString[n], - " %-24s : %-28s %-10s %-10s %s", + " %-24s %-31.31s %-10.10s %-10.10s %s", ctime(ptimeofday), name, alhAlarmStatusString[stat], @@ -194,6 +198,7 @@ char value[],int stat,int sevr) value); n = (n+1)%10; area->currentAlarmIndex = n; + } /****************************************************************** diff --git a/debian/alh-doc.install b/debian/alh-doc.install new file mode 100644 index 0000000..90374d6 --- /dev/null +++ b/debian/alh-doc.install @@ -0,0 +1 @@ +usr/share/doc/alh diff --git a/debian/alh.install b/debian/alh.install new file mode 100644 index 0000000..c053cdd --- /dev/null +++ b/debian/alh.install @@ -0,0 +1,2 @@ +usr/bin/alh +usr/bin/alh_printer diff --git a/debian/alh.lintian-overrides b/debian/alh.lintian-overrides new file mode 100644 index 0000000..49e36c0 --- /dev/null +++ b/debian/alh.lintian-overrides @@ -0,0 +1,2 @@ +alh: binary-without-manpage +# No manpage is provided diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..f6282a4 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,70 @@ +alh (1.2.35-1) unstable; urgency=medium + + * remove libxp-dev dependency + * set compat level to 9 + * epics-debhelper>=8.12 uses LINKER_USE_RPATH instead of USE_RPATH + * update dependencies + * fix i386 build + * DEB_DH_STRIP_ARGS is deprecated + * New upstream version 1.2.35 + * use source format 3.0 quilt + + -- Christoph Schröder Thu, 12 Mar 2020 15:33:33 +0100 + +alh (1.2.26-3) unstable; urgency=medium + + * Build against Base 3.15.3 + * Missing -lpthread + * Depend on epics-extensions-dev w/ RULES_PYTHON fix + + -- Michael Davidsaver Fri, 11 Mar 2016 09:29:02 -0500 + +alh (1.2.26-2.1) unstable; urgency=low + + * Rebuild for epics 3.14.12 + + -- Michael Davidsaver Wed, 05 Dec 2012 17:56:34 -0500 + +alh (1.2.26-2) squeeze-2012A; urgency=low + + * Add BEEPCMD option to run as shell command instead of XBell() + + -- Michael Davidsaver Tue, 09 Oct 2012 18:58:25 -0400 + +alh (1.2.26-1) unstable; urgency=low + + * New upstream version + + -- Michael Davidsaver Thu, 08 Mar 2012 11:47:08 -0500 + +alh (1.2.25-3) unstable; urgency=low + + * Base in /usr/lib/epics + + -- Michael Davidsaver Mon, 16 Aug 2010 17:27:51 -0400 + +alh (1.2.25-2) unstable; urgency=low + + * Update dependencies + + -- Michael Davidsaver Sun, 27 Dec 2009 18:19:29 -0500 + +alh (1.2.25-1) unstable; urgency=low + + * New Upstream Version + * Move html manual to alh-doc package + + -- Michael Davidsaver Fri, 04 Dec 2009 10:17:13 -0500 + +alh (1.2.24-2) unstable; urgency=low + + * Fix dependencies + + -- Michael Davidsaver Fri, 04 Dec 2009 10:04:35 -0500 + +alh (1.2.24-1) unstable; urgency=low + + * Initial release + + -- Michael Davidsaver Fri, 28 Aug 2009 13:24:29 -0400 + diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..74cf4d2 --- /dev/null +++ b/debian/control @@ -0,0 +1,27 @@ +Source: alh +Section: contrib/admin +Priority: extra +Maintainer: Michael Davidsaver +Build-Depends: debhelper (>= 9), cdbs, + epics-dev (>= 3.15.5-1~), epics-debhelper (>= 8.17~), + epics-extensions-dev (>= 20130514.5~), + htmldoc, + libmotif-dev, libx11-dev, libxmu-dev, libxtst-dev +Standards-Version: 3.8.0 +Homepage: http://www.aps.anl.gov/epics/extensions/alh/index.php + +Package: alh +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, +Suggests: alh-doc (= ${binary:Version}) +Description: EPICS Alarm Handler + A specialized EPICS client which listens for alarms on a preset list + of channels. + +Package: alh-doc +Section: contrib/doc +Architecture: all +Conflicts: alh (<< 1.2.25-1) +Description: EPICS Alarm Handler + A specialized EPICS client which listens for alarms on a preset list + of channels. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..ec789b8 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,91 @@ +This package was debianized by Michael Davidsaver on +Fri, 28 Aug 2009 13:24:29 -0400. + +It was downloaded from http://www.aps.anl.gov/epics/extensions/alh/index.php + +Upstream Authors: + + Ben-Chin Cha + Janet Anderson + Mark Anderson + Marty Kraimer + Albert Kagarmanov + +Copyright: + + Copyright (c) 2007 UChicago Argonne, LLC + as Operator of Argonne National Laboratory. + Copyright (c) 2002 Deutches Elektronen-Synchrotron + in der Helmholtz-Gemelnschaft (DESY). + Copyright (c) 2002 Berliner Speicherring-Gesellschaft + fuer Synchrotron-Strahlung mbH (BESSY). + +License: + + Copyright (c) 2002 University of Chicago. All rights reserved. + + ALH is distributed subject to the following license conditions: + + SOFTWARE LICENSE AGREEMENT + Software: Alarm Handler (ALH) + + 1. The "Software", below, refers to ALH (in either source code, or + binary form and accompanying documentation). Each licensee is + addressed as "you" or "Licensee." + + 2. The copyright holders shown above and their third-party licensors + hereby grant Licensee a royalty-free nonexclusive license, subject to + the limitations stated herein and U.S. Government license rights. + + 3. You may modify and make a copy or copies of the Software for use + within your organization, if you meet the following conditions: + a. Copies in source code must include the copyright notice and this + Software License Agreement. + b. Copies in binary form must include the copyright notice and this + Software License Agreement in the documentation and/or other + materials provided with the copy. + + 4. You may modify a copy or copies of the Software or any portion of it, + thus forming a work based on the Software, and distribute copies of + such work outside your organization, if you meet all of the following + conditions: + a. Copies in source code must include the copyright notice and this + Software License Agreement; + b. Copies in binary form must include the copyright notice and this + Software License Agreement in the documentation and/or other + materials provided with the copy; + c. Modified copies and works based on the Software must carry + prominent notices stating that you changed specified portions of + the Software. + + 5. Portions of the Software resulted from work developed under a U.S. + Government contract and are subject to the following license: the + Government is granted for itself and others acting on its behalf a + paid-up, nonexclusive, irrevocable worldwide license in this computer + software to reproduce, prepare derivative works, and perform publicly + and display publicly. + + 6. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT WARRANTY + OF ANY KIND. THE COPYRIGHT HOLDERS, THEIR THIRD PARTY LICENSORS, THE + UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND THEIR + EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME + ANY LEGAL LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, + OR USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE + SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT + THAT THE SOFTWARE WILL FUNCTION UNINTERRUPTED, THAT IT IS ERROR-FREE + OR THAT ANY ERRORS WILL BE CORRECTED. + + 7. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDERS, THEIR + THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT + OF ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, INCIDENTAL, + CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, + INCLUDING BUT NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY + REASON WHATSOEVER, WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF + CONTRACT, TORT (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR + OTHERWISE, EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE + POSSIBILITY OF SUCH LOSS OR DAMAGES. + +The Debian packaging is (C) 2009, Michael Davidsaver and +is licensed under the GPL, see `/usr/share/common-licenses/GPL'. diff --git a/debian/patches/0001-workaround-crash-on-startup-with-test.alhConfig.patch b/debian/patches/0001-workaround-crash-on-startup-with-test.alhConfig.patch new file mode 100644 index 0000000..dbb06b6 --- /dev/null +++ b/debian/patches/0001-workaround-crash-on-startup-with-test.alhConfig.patch @@ -0,0 +1,21 @@ +From: Michael Davidsaver +Date: Tue, 9 Oct 2012 18:58:15 -0400 +Subject: workaround crash on startup with test.alhConfig + +--- + axRunW.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/axRunW.c b/axRunW.c +index a2b60e5..f3dd0b5 100644 +--- a/axRunW.c ++++ b/axRunW.c +@@ -381,7 +381,7 @@ void silenceCurrentReset(void *area) + { + if (psetup.silenceCurrent) { + psetup.silenceCurrent = FALSE; +- if (((ALINK*)area)->silenceCurrent) { ++ if (area && ((ALINK*)area)->silenceCurrent) { + XmToggleButtonGadgetSetState(((ALINK*)area)->silenceCurrent, + FALSE,FALSE); + } diff --git a/debian/patches/0002-missing-lpthread.patch b/debian/patches/0002-missing-lpthread.patch new file mode 100644 index 0000000..00257dd --- /dev/null +++ b/debian/patches/0002-missing-lpthread.patch @@ -0,0 +1,21 @@ +From: Michael Davidsaver +Date: Thu, 10 Mar 2016 19:54:31 -0500 +Subject: missing -lpthread + +--- + Makefile | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/Makefile b/Makefile +index d8848e3..70a2781 100755 +--- a/Makefile ++++ b/Makefile +@@ -185,6 +185,8 @@ X11_DIR = $(X11_LIB) + + RCS_WIN32 += alh.rc + ++PROD_SYS_LIBS += pthread ++ + include $(TOP)/configure/RULES + + alh.res:../alh.ico diff --git a/debian/patches/0003-change-TOP.patch b/debian/patches/0003-change-TOP.patch new file mode 100644 index 0000000..0a7612d --- /dev/null +++ b/debian/patches/0003-change-TOP.patch @@ -0,0 +1,22 @@ +From: =?utf-8?q?Christoph_Schr=C3=B6der?= + +Date: Wed, 11 Mar 2020 14:10:53 +0100 +Subject: change TOP + +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 70a2781..6547e49 100755 +--- a/Makefile ++++ b/Makefile +@@ -15,7 +15,7 @@ + # + # Makefile,v 1.22 2013/04/22 16:07:23 jba Exp + # +-TOP=../.. ++TOP=. + include $(TOP)/configure/CONFIG + + #=========================== diff --git a/debian/patches/0004-BEEPCMD.patch b/debian/patches/0004-BEEPCMD.patch new file mode 100644 index 0000000..fc395e4 --- /dev/null +++ b/debian/patches/0004-BEEPCMD.patch @@ -0,0 +1,212 @@ +From: Michael Davidsaver +Date: Tue, 9 Oct 2012 18:57:57 -0400 +Subject: BEEPCMD + +Add option to run arbitrary shell command instead of X bell + +Command does not run from gui thread. Command will not +be run concurrently. +--- + alConfig.c | 33 +++++++++++++++++ + alh.h | 1 + + os/default/alAudio.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++-- + test.alhConfig | 1 + + 4 files changed, 132 insertions(+), 3 deletions(-) + +diff --git a/alConfig.c b/alConfig.c +index 50d0526..0d248be 100644 +--- a/alConfig.c ++++ b/alConfig.c +@@ -444,6 +444,37 @@ int context,int caConnect,struct mainGroup *pmainGroup) + return; + } + ++ if (strncmp(&buf[1],"BEEPCMD",7)==0) { ++ unsigned int start=8, end = strlen(buf) - 1; ++ ++ /* skip leading whitespace to find start of command */ ++ for(; start<=end && (buf[start]=='\t' || buf[start]==' '); start++) {} ++ ++ if(start>end) { ++ print_error(buf, "expected argument after BEEPCMD"); ++ return; ++ } ++ ++ /* back track to trim trailing whitespace */ ++ for(; end>=start && (buf[end]=='\0' || isspace(buf[end])); end--) {} ++ ++ if(end>start) { ++ if(psetup.beepCmd) ++ free(psetup.beepCmd); ++ psetup.beepCmd = malloc(end-start+2); ++ if(!psetup.beepCmd) { ++ print_error(buf, "Not enough memory for BEEPCMD"); ++ } else { ++ memcpy(psetup.beepCmd, &buf[start], end-start+1); ++ psetup.beepCmd[end-start+1] = '\0'; ++ } ++ } else { ++ print_error(buf, "Missing argument for BEEPCMD"); ++ } ++ ++ return; ++ } ++ + if (strncmp(&buf[1],"HEARTBEATPV",11)==0) { /*HEARTBEATPV*/ + + if (pmainGroup->heartbeatPV.name) return; +@@ -777,6 +808,8 @@ void alWriteConfig(char *filename,struct mainGroup *pmainGroup) + if (!fw) return; + if (psetup.beepSevr > 1) + fprintf(fw,"$BEEPSEVERITY %s\n",alhAlarmSeverityString[psetup.beepSevr]); ++ if (psetup.beepCmd) ++ fprintf(fw,"$BEEPCMD %s\n", psetup.beepCmd); + /*alWriteGroupConfig(fw,(SLIST *)&(pmainGroup->p1stgroup));*/ + alWriteGroupConfig(fw,(SLIST *)pmainGroup); + fclose(fw); +diff --git a/alh.h b/alh.h +index 37feac8..f6f8928 100644 +--- a/alh.h ++++ b/alh.h +@@ -181,6 +181,7 @@ struct setup { + char logFile[NAMEDEFAULT_SIZE]; /* alarm log file name */ + char opModFile[NAMEDEFAULT_SIZE]; /* opMod log file name */ + char saveFile[NAMEDEFAULT_SIZE]; /* save config file name */ ++ char *beepCmd; /* Optional command in place of X bell*/ + char soundFile[NAMEDEFAULT_SIZE]; /* sound wav file name */ + char lockFileBase[NAMEDEFAULT_SIZE]; /* lock files basename */ + short silenceForever; /* 1 - beepoff forever is true */ +diff --git a/os/default/alAudio.c b/os/default/alAudio.c +index c6e36ab..85ad91e 100644 +--- a/os/default/alAudio.c ++++ b/os/default/alAudio.c +@@ -18,13 +18,88 @@ + * + */ + ++#include + #include ++#include ++#include ++#include + + #include + #include + + #include "alh.h" + ++static pthread_mutex_t beep_lock = PTHREAD_MUTEX_INITIALIZER; ++static pthread_cond_t beep_wake = PTHREAD_COND_INITIALIZER; ++static pthread_once_t beep_setup = PTHREAD_ONCE_INIT; ++/* states: -2 done, -1 shutdown, 0 idle, 1 playing, 2 request play */ ++static int beeping = 0; ++static pthread_t beeper; ++ ++#define LOCK() assert(pthread_mutex_lock(&beep_lock)==0) ++#define UNLOCK() assert(pthread_mutex_unlock(&beep_lock)==0) ++ ++static void beeper_shutdown(void) ++{ ++ /* request shutdown and spin until beeper thread stops */ ++ LOCK(); ++ beeping = -1; ++ while(beeping!=-2) { ++ UNLOCK(); ++ pthread_cond_broadcast(&beep_wake); ++ usleep(10000); /* 10ms */ ++ LOCK(); ++ } ++ /* thread is stopped now */ ++ free(psetup.beepCmd); ++ psetup.beepCmd = NULL; ++ ++ UNLOCK(); ++} ++ ++static void* beeper_thread(void* junk) ++{ ++ LOCK(); ++ ++ atexit(&beeper_shutdown); ++ ++ while(beeping>=0) { ++ ++ assert(pthread_cond_wait(&beep_wake, &beep_lock)==0); ++ ++ if(beeping==2) { ++ beeping=1; ++ UNLOCK(); ++ ++ system(psetup.beepCmd); ++ ++ LOCK(); ++ /* be careful not to overwrite the shutdown command */ ++ if(beeping==1) ++ beeping=0; ++ } ++ } ++ UNLOCK(); ++ beeping=-2; ++ return NULL; ++} ++ ++static void setup(void) ++{ ++ if(!psetup.beepCmd) ++ return; ++ ++ if(pthread_create(&beeper, NULL, &beeper_thread, NULL)) { ++ printf("Error creating beeper thread!\n"); ++ /* clear beepCmd so that future calls to alBeep() will ++ * call XBell(). ++ */ ++ free(psetup.beepCmd); ++ psetup.beepCmd = NULL; ++ return; ++ } ++} ++ + /* Audio device not implemented */ + + /****************************************************** +@@ -32,9 +107,28 @@ + ******************************************************/ + void alBeep(Display *displayBB) + { +- /* system("play /path/to/beep.wav"); */ +- XkbBell(displayBB,None,0,None); +- return; ++ pthread_once(&beep_setup, &setup); ++ ++ if(!psetup.beepCmd) { ++ /* system("play /path/to/beep.wav"); */ ++ XkbBell(displayBB,None,0,None); ++ return; ++ } else { ++ LOCK(); ++ ++ /* wakeup for new command. ++ * also if still waiting for wakeup ++ * if beeper didn't start fast enough ++ * on the previous call. ++ */ ++ if(beeping==0 || beeping==2) { ++ beeping=2; ++ pthread_cond_broadcast(&beep_wake); ++ } ++ ++ UNLOCK(); ++ return; ++ } + } + + +diff --git a/test.alhConfig b/test.alhConfig +index 2475da1..84c96c8 100644 +--- a/test.alhConfig ++++ b/test.alhConfig +@@ -1,3 +1,4 @@ ++$BEEPCMD sleep 5;date -R >> alhtest + $BEEPSEVERITY MAJOR + GROUP NULL JBA_TEST_MAIN_GROUP + $COMMAND xload diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..daf61bb --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,4 @@ +0001-workaround-crash-on-startup-with-test.alhConfig.patch +0002-missing-lpthread.patch +0003-change-TOP.patch +0004-BEEPCMD.patch diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..6ddd7b6 --- /dev/null +++ b/debian/rules @@ -0,0 +1,53 @@ +#!/usr/bin/make -f +# -*- makefile -*- + +#export DH_VERBOSE=1 + +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/class/makefile.mk +include /usr/share/cdbs/1/rules/utils.mk + +EPICS_HOST_ARCH:=$(shell /usr/lib/epics/startup/EpicsHostArch) +# chop out the source version from Changelog (ie 3.14.10) +SOV=$(shell echo "$(DEB_NOEPOCH_VERSION)"| cut -f 1 -d '-') + +ifeq "$(DEB_BUILD_ARCH)" "i386" +EPICS_HOST_ARCH:=linux-x86 +else ifeq "$(DEB_BUILD_ARCH)" "amd64" +EPICS_HOST_ARCH:=linux-x86_64 +else +EPICS_HOST_ARCH:=$(shell /usr/lib/epics/startup/EpicsHostArch) +endif + +DEB_MAKE_MAKEVARS = EPICS_HOST_ARCH=$(EPICS_HOST_ARCH) LINKER_USE_RPATH=NO USE_SDDS=NO +DEB_MAKE_MAKEVARS+= SHRLIB_VERSION=$(SOV) + +DEB_MAKE_INVOKE = $(DEB_MAKE_ENVVARS) $(MAKE) -C $(DEB_BUILDDIR) $(DEB_MAKE_MAKEVARS) + +DEB_MAKE_CLEAN_TARGET = +DEB_MAKE_BUILD_TARGET = all +DEB_MAKE_INSTALL_TARGET = all INSTALL_LOCATION=$(CURDIR)/debian/tmp/usr +DEB_MAKE_CHECK_TARGET = + +post-patches:: configure + +configure: + ln -s /usr/lib/epics/extensions/configure . + +install/alh:: + mv $(CURDIR)/debian/tmp/usr/bin/$(EPICS_HOST_ARCH)/alh* $(CURDIR)/debian/tmp/usr/bin + rmdir $(CURDIR)/debian/tmp/usr/bin/$(EPICS_HOST_ARCH) + +install/alh-doc:: + install -d $(CURDIR)/debian/tmp/usr/share/doc/alh + cp -r documentation/* $(CURDIR)/debian/tmp/usr/share/doc/alh/ + +clean:: + rm -rf bin O.$(EPICS_HOST_ARCH) + rm -f configure + +# prevent debug targets from being stripped +override_dh_strip: + dh_strip -Xdebug + +.PHONY: override_dh_strip diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/source/local-options b/debian/source/local-options new file mode 100644 index 0000000..9cdfca9 --- /dev/null +++ b/debian/source/local-options @@ -0,0 +1,2 @@ +unapply-patches +abort-on-upstream-changes diff --git a/debian/source/options b/debian/source/options new file mode 100644 index 0000000..62d9178 --- /dev/null +++ b/debian/source/options @@ -0,0 +1 @@ +compression-level = 9 diff --git a/dialog.c b/dialog.c index b0d622b..98051dd 100644 --- a/dialog.c +++ b/dialog.c @@ -181,7 +181,10 @@ void createDialog(Widget parent,int dialogType,char *message1,char *message2) string2 = XmStringConcat(str3,str); XtVaSetValues(dialog, +#ifndef WIN32 + /* 6/2012 Xming hangs when dialogType is set */ XmNdialogType, dialogType, +#endif XmNdialogTitle, string2, XmNmessageString, string, (XtPointer)NULL); @@ -201,7 +204,7 @@ void createActionDialog(Widget parent,int dialogType,char *message1, XtCallbackProc okCallback,XtPointer okParm,XtPointer userParm) { static Widget dialog = 0; /* make it static for reuse */ - XmString str,str1,str2,str3; + XmString str,str2; static XtCallbackProc oldOkCallback = 0; static XtPointer oldOkParm = 0; @@ -226,36 +229,36 @@ XtCallbackProc okCallback,XtPointer okParm,XtPointer userParm) switch(dialogType) { case XmDIALOG_WARNING: - str = XmStringCreateSimple("WarningDialog"); + str = XmStringCreateSimple("ALH WarningDialog"); break; case XmDIALOG_ERROR: - str = XmStringCreateSimple("ErrorDialog"); + str = XmStringCreateSimple("ALH ErrorDialog"); break; case XmDIALOG_INFORMATION: - str = XmStringCreateSimple("InformationDialog"); + str = XmStringCreateSimple("ALH InformationDialog"); break; case XmDIALOG_MESSAGE: - str = XmStringCreateSimple("MessageDialog"); + str = XmStringCreateSimple("ALH MessageDialog"); break; case XmDIALOG_QUESTION: - str = XmStringCreateSimple("QuestionDialog"); + str = XmStringCreateSimple("ALH QuestionDialog"); break; case XmDIALOG_WORKING: - str = XmStringCreateSimple("WorkingDialog"); + str = XmStringCreateSimple("ALH WorkingDialog"); break; default: - str = XmStringCreateSimple("InformationDialog"); + str = XmStringCreateSimple("ALH InformationDialog"); break; } - str1 = XmStringCreateLtoR("ALH ",XmFONTLIST_DEFAULT_TAG); - str3 = XmStringConcat(str1,str); - str2=XmStringCreateLtoR(message1,XmSTRING_DEFAULT_CHARSET); XtVaSetValues(dialog, XmNuserData, userParm, +#ifndef WIN32 + /* 6/2012 Xming hangs when dialogType is set */ XmNdialogType, dialogType, - XmNdialogTitle, str3, +#endif + XmNdialogTitle, str, XmNmessageString, str2, (XtPointer)NULL); XmStringFree(str); @@ -326,16 +329,20 @@ void errMsg(const char *fmt, ...) warningboxMessages += 1; XtManageChild(warningbox); } else { - XBell(display,50); - XBell(display,50); - XBell(display,50); + alBeep(display); + alBeep(display); + alBeep(display); cstring=XmStringCreateLtoR(lstring,XmSTRING_DEFAULT_CHARSET); nargs=0; XtSetArg(args[nargs],XmNtitle,"ALH Warning"); nargs++; XtSetArg(args[nargs],XmNmessageString,cstring); nargs++; +#ifndef WIN32 warningbox=XmCreateWarningDialog(topLevelShell,"warningMessage", +#else + warningbox=XmCreateMessageDialog(topLevelShell,"warningMessage", +#endif args,nargs); XmStringFree(cstring); XtDestroyWidget(XmMessageBoxGetChild(warningbox,XmDIALOG_CANCEL_BUTTON)); diff --git a/documentation/ALH.html b/documentation/ALH.html index e5cd718..7fbfb54 100644 --- a/documentation/ALH.html +++ b/documentation/ALH.html @@ -115,7 +115,7 @@

Availability

The alarm handler is a Motif and X11 Window based application written in C language, and it runs on -Unix, Linux, and Windows 98/XP hosts. The Alarm Handler source code is +Unix, Linux, and Windows 98/XP/.../8 hosts. The Alarm Handler source code is available via WWW as an EPICS extension.

Purpose of the Alarm Handler

@@ -137,7 +137,7 @@

Purpose of the Alarm Handler

System Requirements

The Alarm Handler currently requires either -an IBM personal computer with Windows 95/NT and Hummingbird's +an IBM personal computer with Windows 98/XP/.../8 and Hummingbird's Exceed software or a workstation running a Unix type operating system with X Windows and Motif Version 1.2 or above. The Alarm Handler also requires the global alarm acknowledgment in EPICS base Version 3.11 or above.

@@ -306,6 +306,10 @@

Alarm Configuration File

desired alarm configuration file using a file selection window at Alarm Handler start-up, or on the command line.

+

The user can change to a new alarm configuration +file while the Alarm Handler is running by using the File/Open item on the +main window menu bar.

+

Alarm Log File

The Alarm Log output file contains a log of alarm @@ -345,7 +349,7 @@

ALARMHANDLER

variable ALARMHANDLER can be used to point the Alarm Handler to a desired working directory. If ALARMHANDLER is not set, the current working directory is assumed. If the alarm configuration file -resides on a different directory +resides in a different directory (e.g. /home/cs/appl/ah/dev) from the current working directory, under UNIX ALARMHANDLER can be set to point to the desired path by issuing the UNIX c shell command:

@@ -397,7 +401,7 @@

Command Line Syntax

-aCM - Alarm log using CMLOG + Alarm log using CMLOG (if built using CMLOG) -B @@ -445,6 +449,10 @@

Command Line Syntax

-L Use Locking System + + -Lfile lockfile + Basename for .LOCK lock file + -l logdir Directory for log files [.] @@ -457,6 +465,12 @@

Command Line Syntax

-mainwindow Start with Main Window + + -maskcolor + Print mask colored when channel/group contains silencing flag +
(makes it easier to find all canceled/disabled/noAck channels) + + -noerrorpopup Do not display error popup window (errors are logged) @@ -478,6 +492,10 @@

Command Line Syntax

-P key Print to TCP printer + + -p file + Use wave file for sound instead of alarm beep (OS dependent) + -S Passive state (no ca_puts to ACKS and ACKT fields and severity PV) @@ -619,6 +637,13 @@

Locking System

(i.e. actively logging) process dies, another Alarm Handler will seamlessly take over logging. Default is not to use this locking mechanism.

+

Locking File

+ +

The '-L lockfile' option specifies a lock +file directory with file name prefix. A ".LOCK" suffix will be appended. The +default is the configure filename with directory from the -f option or the +current working directory. +

Directory for Log Files

The '-l logdir' @@ -640,6 +665,13 @@

Start with Main Window

useful in conjunction with the `-filter f-opt' option to start Alarm Handlers from operator panels. The default is to start with the Runtime Window.

+

Colored Masks

+ +

The `-maskcolor' option makes the Alarm +display colored masks when the channel/group contains a silencing flag. This +makes it easier to find all the canceled/disabled/noAck channels. +

+

Do not use Popup Boxes for Displaying Errors

The `-noerrorpopup' option tells the Alarm @@ -673,6 +705,13 @@

TCP Printing

asynchronously by adding an additional task "alh_printer". (This option is still under construction and will use pipes in the future)

+

Wave File Sound

+ +

The '-p file' option specifies that alh should +play the specified wave sound file instead of alarm beeping. This option is +available for Linux systems only. +

+

Silent Mode

The '-s' @@ -787,7 +826,7 @@

Runtime Window

Exiting the Alarm Handler

To exit the Alarm Handler, -use the Window Manager Menu on +click on the X in the window title bar or use the Window Manager Menu on the Runtime Window and choose the Close menu item.

Message Area abbreviation codes and status data which appear in the group summary and channel status lines.

-

There are two Silence buttons which toggle beeping on or off. -The Silence Current button turns off current -alarm beeping until a new alarm occurs. The Silence -One Hour button toggles on/off beeping of current and future alarms for one -hour. When pushed in, beeping is turned off, when out, beeping is on. Beeping +

+There are two Silence buttons which toggle beeping on or off. The Silence Current +button turns off current alarm beeping until a new alarm occurs. The Silence Interval +button toggles beeping of current and future alarms off for a specified interval. +When pushed in, beeping is turned off, when out, beeping is toggled on. Beeping occurs only when there are unacknowledged alarms. The main window background -color is changed to pink when Silence One Hour is active.

+color is changed when beeping is turned off. Setup menu items can be used to +change the specified time interval.

Group Summary Line

This display line -summarizer the status of all alarms for the group named in this line and all +summarizes the status of all alarms for the group named in this line and all lower level groups. The group summary display consists of the following items:

Acknowledgment Button

@@ -1204,7 +1244,9 @@

Action Menu Commands

selections which affect the currently selected Alarm Group or Channel. The action selections "Acknowledge Alarm", "Display Guidance", and "Start Related Process" can also be accomplished by clicking -buttons on the tree structure or group contents display.

+buttons on the tree structure or group contents display. The "Send Message" +item is present only when the Message Broadcasting option, "-B", +is present on the command line.

@@ -1249,8 +1291,8 @@

Display Guidance

The guidance text display is a popup window displaying lines of ascii text if text was specified in the alarm configuration file. If a URL address was specified in the -configuration file, Netscape will be invoked and display the text at the -specified URL address.

+configuration file, the default browser will be invoked and display the text +at the specified URL address.

Start Related Process

@@ -1362,9 +1404,11 @@

Message Broadcasting

Message" menu item is selected. The operator can then type in a message that will be sent to other alh processes when OK is pressed. A popup message dialog containing the sent message will appear on other Alarm Handler processes -when they receive the message.

+when they receive the message. The "Send Message" menu item appears on +the Action menu only if the Message Broadcasting option, "-B", is +present on the alh command line.

-

View Menu Commands

Expand One Level

-

The user selects this -menu item to expand a collapsed the currently selected Alarm Group to -graphically display one level of its alarm subgroups on the alarm configuration -tree display.

+

The user selects this menu item to expand the +currently selected collapsed Alarm Group in the tree structure display to +graphically display one level of its alarm subgroups in the tree structure display.

Expand Branch

-

The user can choose this -item to expand the currently selected collapsed Alarm Group in the alarm -configuration tree display to graphically show all levels of its subgroups on -the alarm configuration tree structure display.

+

The user can choose this item to expand the +currently selected Alarm Group in the alarm configuration tree display to +graphically show all levels of its subgroups on the tree structure display.

-

Expend All

+

Expand All

-

The user uses this menu -item to expand all collapsed groups in the configuration tree structure display -to graphically show all the groups and subgroups in the current alarm -configuration.

+

The user uses this menu item to expand or collapse +all groups in the alarm configuration tree structure display to graphically +show all the groups and subgroups on the current alarm configuration tree +structure display.

Collapse Branch

@@ -1515,11 +1557,14 @@

Display Filter

The user is allowed to set an alarm filter to display active alarms only. When the filter is set to Active Alarms Only, only those groups or channels with an outstanding alarm -will be displayed. When the filter is set to Unacknowldged Alarms Only, only those +will be displayed. When the filter is set to Unacknowledged Alarms Only, only those groups or channels with an outstanding unacknowledged alarm will be displayed. When the selection is set to No Filter, all Alarm Groups and Alarm Channels in the current configuration will be available for display.

+

+

ALH Beep Severity

The operator can specify @@ -1534,13 +1579,33 @@

ALH Beep Severity

-

New Alarm Log File

+

Silence Time Interval

+ +

The Silence Time Interval menu item allows the user to +select a silence interval of 5, 10, 15, 30, or 60 minutes. The selected interval +determines the silence interval for the Silence Time Interval button on the Main +Window message area and text for the selected interval appears next to the Silence +Time Interval button. +

+ +

+ +

Silence Forever

+ +

The Silence Forever button toggles On/Off the +beeping of all current and future unacknowledged alarms. Beeping normally +occurs when there are unacknowledged alarms. +

+ +

New Alarm Log File

The alarm log file contains the log of alarm changes of states. The Alarm Handler allows the operator to specify an alarm log file name that differs from the current setting. If it does not exist, it will be automatically created. All new alarm state changes -will be logged to this file.

+will be logged to this file. A file selection dialog window is used to set a +new Alarm Log File name.

New Operation Modification Log File

@@ -1548,7 +1613,8 @@

New Operation Modification Log File

the operator to specify an operation modification log file that differs from the current setting. If it does not exist, it will be automatically created by ALH. All subsequent operation changes will be logged to this new operation -modification file.

+modification file. A file selection dialog window is used to set a new +Operation Modification Log File name.

Help Menu

@@ -1635,7 +1701,7 @@

Input Format

Heartbeat Process Variable

The line starting with $HEARTBEATPV is optional. -It is required only when a user wants a monitored pv to show weather or not +It is required only when a user wants a monitored pv to show whether or not ALH is running. If the $HEARTBEATPV line is present, ALH will do CA puts of the specified value to the specified pv at the specified rate (in seconds). The heartbeatPVName must be an existing PV in the EPICS database and can be @@ -1651,8 +1717,7 @@

Group or Channel

NULL as the parent group name. Group or Channel lines must start with the keyword GROUP or CHANNEL. The GroupName is the name of a user specified Alarm Group. The ChannelName must be the name of a specific record defined -in an EPICS database. The length of a GroupName or ChannelName must not -exceed 28 characters. The parentName is the name of the parent Alarm +in an EPICS database. The parentName is the name of the parent Alarm Group. There is no restriction on the number of group definitions.

GROUP parentName GroupName

@@ -1825,7 +1890,7 @@

Related Commands

names and command strings separated by exclamation points, "!", using the following syntax

$COMMAND   -cmd 1 name!cmd 1 string!cmd 2 name!cmd 2 string!...cmd n name!cmd n string +cmd_1_name!cmd_1_string!cmd_2_name!cmd_2_string!...cmd_n_name!cmd_n_string

Severity Command

@@ -1868,6 +1933,14 @@

Alarm Count Filter

channel must enter into an alarm state from a no-alarm state more than inputCount times within inputSeconds seconds.

+

If inputCounts is zero, inputCounts is not used +in determining alarm/no-alarm states, only inputSeconds is used to filter a +channel going in and out of alarm state. If inputCounts is -1, inputSeconds +only is used for filtering a channel going from no-alarm to alarm state, +and a change in channel from alarm state to no-alarm state is not filtered. + +

+

$ALARMCOUNTFILTER inputCount inputSeconds

Beep Severity

diff --git a/documentation/ALH.title.html b/documentation/ALH.title.html index d0ee639..f3defdf 100644 --- a/documentation/ALH.title.html +++ b/documentation/ALH.title.html @@ -10,8 +10,8 @@

Alarm Handler User's Guide



-

ALH 1.2.26

-

December 2010

+

ALH 1.2.35

+

August 2014




diff --git a/documentation/Makefile b/documentation/Makefile index 1a458b3..af5d9a1 100644 --- a/documentation/Makefile +++ b/documentation/Makefile @@ -1,9 +1,9 @@ # Makefile for generating published alhUserGuide files -HTMLDOC = "/home/phoebus/ANJ/bin/solaris-sparc/htmldoc" +HTMLDOC = "/home/phoebus/JBA/bin/solaris-sparc/htmldoc" WEBSITE = /net/epics/Public/epics/EpicsDocumentation/ExtensionsManuals/AlarmHandler -VERSION = 1.2.16 +VERSION = 1.2.35 # Content options: @@ -37,15 +37,15 @@ FILES = ALH.html # ALHUserGuide.html is name of file in alh/Makefile.Host -all: alhUserGuide.ps.gz alhUserGuide.pdf ALHUserGuide.html +all: alhUserGuide-$(VERSION).ps.gz alhUserGuide-$(VERSION).pdf ALHUserGuide-$(VERSION).html -alhUserGuide.ps: $(FILES) Makefile +alhUserGuide-$(VERSION).ps: $(FILES) Makefile $(HTMLDOC) $(PSOPTS) -f $@ $(FILES) -alhUserGuide.pdf: $(FILES) Makefile +alhUserGuide-$(VERSION).pdf: $(FILES) Makefile $(HTMLDOC) $(PDFOPTS) -f $@ $(FILES) -ALHUserGuide.html: $(FILES) Makefile +ALHUserGuide-$(VERSION).html: $(FILES) Makefile rm -rf $@ $(HTMLDOC) $(HTMLOPTS) -f $@ $(FILES) @@ -54,13 +54,13 @@ ALHUserGuide.html: $(FILES) Makefile gzip $< install: all - /bin/cp -f alhUserGuide.ps.gz $(WEBSITE)/alhUserGuide-$(VERSION).ps.gz - /bin/cp -f alhUserGuide.pdf $(WEBSITE)/alhUserGuide-$(VERSION).pdf - #/bin/cp -rf alhUserGuide $(WEBSITE)/alhUserGuide-$(VERSION) + /bin/cp -f alhUserGuide-$(VERSION).ps.gz $(WEBSITE)/alhUserGuide-$(VERSION).ps.gz + /bin/cp -f alhUserGuide-$(VERSION).pdf $(WEBSITE)/alhUserGuide-$(VERSION).pdf + /bin/cp -rf alhUserGuide $(WEBSITE)/alhUserGuide-$(VERSION) rm -rf $(WEBSITE)/alhUserGuide-$(VERSION) mkdir $(WEBSITE)/alhUserGuide-$(VERSION) /bin/cp -rf . $(WEBSITE)/alhUserGuide-$(VERSION) clean: - rm alhUserGuide.ps alhUserGuide.pdf ALHUserGuide.html \ - alhUserGuide.ps.gz alhUserGuide.pdf.gz + rm alhUserGuide-$(VERSION).ps alhUserGuide-$(VERSION).pdf ALHUserGuide-$(VERSION).html \ + alhUserGuide-$(VERSION).ps.gz alhUserGuide-$(VERSION).pdf.gz diff --git a/documentation/images/alhAlarmLogFile.gif b/documentation/images/alhAlarmLogFile.gif index 131b984..8379aac 100644 Binary files a/documentation/images/alhAlarmLogFile.gif and b/documentation/images/alhAlarmLogFile.gif differ diff --git a/documentation/images/alhCurrentAlarmHistory.gif b/documentation/images/alhCurrentAlarmHistory.gif index e4f6498..b0bce31 100644 Binary files a/documentation/images/alhCurrentAlarmHistory.gif and b/documentation/images/alhCurrentAlarmHistory.gif differ diff --git a/documentation/images/alhDisplayFilter.gif b/documentation/images/alhDisplayFilter.gif new file mode 100755 index 0000000..d1f9790 Binary files /dev/null and b/documentation/images/alhDisplayFilter.gif differ diff --git a/documentation/images/alhMainWindowAlarms.gif b/documentation/images/alhMainWindowAlarms.gif index f77aab8..e48a8c4 100644 Binary files a/documentation/images/alhMainWindowAlarms.gif and b/documentation/images/alhMainWindowAlarms.gif differ diff --git a/documentation/images/alhMainWindowNoAlarms.gif b/documentation/images/alhMainWindowNoAlarms.gif index 9a90dce..b2ee180 100644 Binary files a/documentation/images/alhMainWindowNoAlarms.gif and b/documentation/images/alhMainWindowNoAlarms.gif differ diff --git a/documentation/images/alhMessage.gif b/documentation/images/alhMessage.gif index ca4d242..0e27003 100644 Binary files a/documentation/images/alhMessage.gif and b/documentation/images/alhMessage.gif differ diff --git a/documentation/images/alhSendMessage.gif b/documentation/images/alhSendMessage.gif index 0873118..e0c64b2 100644 Binary files a/documentation/images/alhSendMessage.gif and b/documentation/images/alhSendMessage.gif differ diff --git a/documentation/images/alhSetupMenu.gif b/documentation/images/alhSetupMenu.gif index 98b9808..42ceef4 100644 Binary files a/documentation/images/alhSetupMenu.gif and b/documentation/images/alhSetupMenu.gif differ diff --git a/documentation/images/alhSilenceIntervalSelections.gif b/documentation/images/alhSilenceIntervalSelections.gif new file mode 100755 index 0000000..3bb769d Binary files /dev/null and b/documentation/images/alhSilenceIntervalSelections.gif differ diff --git a/fallback.h b/fallback.h index af1120d..949f5eb 100644 --- a/fallback.h +++ b/fallback.h @@ -39,6 +39,8 @@ static String fallbackResources[] = { "*scale.value: 50", "*scale.highlightOnEnter: FALSE", "*scale.scaleMultiple: 5", + "*CurrentTitle.fontList: 7x14", + "*CurrentAlarm.fontList: 7x14", "*treeSym.fontList: 12x24", "*XmCascadeButtonGadget.fontList: 8x13", "*XmCascadeButtonWidget.fontList: 8x13", diff --git a/file.c b/file.c index fa33789..254b253 100644 --- a/file.c +++ b/file.c @@ -135,6 +135,8 @@ int use_CMLOG_opmod = 0; #endif int _xml_flag = 0; /* Use XML-ish log format. SNS */ +int _mask_color_flag = 0; /* SLS (Andreas Luedeke): if channel/group mask disables sound, then change bg color of mask */ + /* this helps to quickly check for all disabled channels, e.g. before an application restart */ extern int DEBUG; @@ -148,13 +150,15 @@ struct command_line_data { char* configDir; char* logDir; + char* lockFileBase; /* Andreas Luedeke */ + char* soundFile; /* Andreas Luedeke */ char* configFile; char* logFile; char* opModFile; int alarmLogFileMaxRecords; }; static struct command_line_data commandLine = { - NULL,NULL,NULL,NULL,NULL,0}; + NULL,NULL,NULL,NULL,NULL,NULL,NULL,0}; #define PARM_DEBUG 0 #define PARM_ACT 1 @@ -182,6 +186,9 @@ static struct command_line_data commandLine = { #define PARM_ALARM_FILTER 23 #define PARM_DESC_FIELD 24 #define PARM_XML 25 +#define PARM_LOCK_FILE 26 +#define PARM_SOUND_FILE 27 +#define PARM_NOACK_MASK_COLOR 28 struct parm_data { char* parm; @@ -193,37 +200,40 @@ struct parm_data static struct parm_data ptable[] = { #ifdef CMLOG - { "-aCM", 4, PARM_ALARM_LOG_CMLOG }, + { "-aCM", 4, PARM_ALARM_LOG_CMLOG }, #endif - { "-a", 2, PARM_ALARM_LOG_FILE }, - { "-B", 2, PARM_MESSAGE_BROADCAST }, /* Albert */ - { "-c", 2, PARM_ACT }, - { "-caputackt", 10, PARM_CAPUT_ACK_TRANSIENTS }, - { "-D", 2, PARM_READONLY }, - { "-debug", 6 , PARM_DEBUG }, - { "-desc_field", 11 , PARM_DESC_FIELD }, - { "-filter", 7, PARM_ALARM_FILTER }, - { "-f", 2, PARM_ALL_FILES_DIR }, - { "-global", 7, PARM_GLOBAL }, - { "-help", 5, PARM_HELP }, - { "-L", 2, PARM_LOCK }, /* Albert */ - { "-l", 2, PARM_LOG_DIR }, + { "-a", 2, PARM_ALARM_LOG_FILE }, + { "-B", 2, PARM_MESSAGE_BROADCAST }, /* Albert */ + { "-c", 2, PARM_ACT }, + { "-caputackt", 10, PARM_CAPUT_ACK_TRANSIENTS }, + { "-D", 2, PARM_READONLY }, + { "-debug", 6 , PARM_DEBUG }, + { "-desc_field", 11 , PARM_DESC_FIELD }, + { "-f", 2, PARM_ALL_FILES_DIR }, + { "-filter", 7, PARM_ALARM_FILTER }, + { "-global", 7, PARM_GLOBAL }, + { "-help", 5, PARM_HELP }, + { "-L", 2, PARM_LOCK }, /* Albert */ + { "-Lfile", 6, PARM_LOCK_FILE }, /* Andreas Luedeke */ + { "-l", 2, PARM_LOG_DIR }, + { "-m", 2, PARM_ALARM_LOG_MAX }, { "-mainwindow", 11, PARM_MAIN_WINDOW }, - { "-m", 2, PARM_ALARM_LOG_MAX }, + { "-maskcolor", 10, PARM_NOACK_MASK_COLOR }, { "-noerrorpopup", 13, PARM_NO_ERROR_POPUP }, - { "-O", 2, PARM_DATABASE }, /* Albert */ + { "-O", 2, PARM_DATABASE }, /* Albert */ + { "-o", 2, PARM_OPMOD_LOG_FILE }, #ifdef CMLOG - { "-oCM", 4, PARM_OPMOD_LOG_CMLOG }, + { "-oCM", 4, PARM_OPMOD_LOG_CMLOG }, #endif - { "-o", 2, PARM_OPMOD_LOG_FILE }, - { "-P", 2, PARM_PRINTER }, - { "-S", 2, PARM_PASSIVE }, - { "-s", 2, PARM_SILENT }, - { "-T", 2, PARM_DATED }, - { "-v", 2, PARM_VERSION }, - { "-version", 8, PARM_VERSION }, - { "-xml", 4, PARM_XML }, /* SNS */ - { NULL, -1, -1 }}; + { "-p", 2, PARM_SOUND_FILE }, + { "-P", 2, PARM_PRINTER }, + { "-S", 2, PARM_PASSIVE }, + { "-s", 2, PARM_SILENT }, + { "-T", 2, PARM_DATED }, + { "-v", 2, PARM_VERSION }, + { "-version", 8, PARM_VERSION }, + { "-xml", 4, PARM_XML }, /* SNS */ + { NULL, -1, -1 }}; /* forward declarations */ static void saveConfigFile_callback(Widget widget,char *filename, @@ -233,7 +243,7 @@ static void fileSetup(char *filename,ALINK *area,int fileType,int programId, Widget widget); static int checkFilename(char *filename,int fileType); static int getCommandLineParms(int argc, char** argv); -int getUserInfo(); +static int getUserInfo(); /*************************************************** exit and quit application @@ -250,8 +260,8 @@ void exit_quit(Widget w, XtPointer clientdata, XtPointer calldata) } alLogOpModMessage(0,0,"Setup---Exit"); - fclose(fl); - fclose(fo); + if (fl) { fclose(fl); fl=0; } + if (fo) { fclose(fo); fo=0; } if (area && area->pmainGroup) proot = area->pmainGroup->p1stgroup; /* @@ -408,7 +418,7 @@ static int checkFilename(char *filename,int fileType) break; } - fclose(tt); + if (tt) fclose(tt); return 0; } @@ -479,7 +489,9 @@ int programId,Widget widget) strncat(filename, &buf[0], strlen(buf)); } /* _______ End. Albert______________________________*/ + error = checkFilename(filename,fileType); + if (error){ switch(fileType) { @@ -526,7 +538,7 @@ int programId,Widget widget) if (error){ fileSelectionBox = widget; /* Display file selection box */ - if ( XtIsShell(widget)) { + if (widget && XtIsShell(widget)) { long fileTypeLong=fileType; Atom WM_DELETE_WINDOW; fileSelectionBox = createFileDialog(widget, @@ -563,15 +575,27 @@ int programId,Widget widget) break; case 4: - /*createDialog(fileSelectionBox,XmDIALOG_ERROR,filename," write error.");*/ - fatalErrMsg("Write error for file %s.\n",filename); + errMsg("Error opening file %s\n",filename); + switch(fileType) { + case FILE_ALARMLOG: + errMsg("WARNING: Continuing without Alarm Log file\n"); + break; + case FILE_OPMOD: + errMsg("WARNING: Continuing without OpMod Log file\n"); + break; + default: + break; + } + + break; + default: break; } } else { /* unmanage the fileSelection dialog */ - if ( !XtIsShell(widget)) + if (widget && !XtIsShell(widget)) createFileDialog(0,0,0,0,0,0,0,0,0); switch(fileType) { @@ -585,8 +609,8 @@ int programId,Widget widget) if(_lock_flag) /* Albert */ { FILE *fp; - strcpy(lockFileName,psetup.configFile); - strcat(lockFileName,".LOCK"); + strcpy(lockFileName,psetup.lockFileBase); /* Andreas Luedeke */ + strcat(lockFileName,".LOCK"); /* allow lock to be generated outside logdir */ if (!(fp=fopen(lockFileName,"a"))) { perror("Can't open locking file for a"); @@ -698,24 +722,26 @@ int programId,Widget widget) break; case FILE_ALARMLOG: - if (fo) alLogOpModMessage(0,0,"Setup Alarm Log File : %s",filename); + alLogOpModMessage(0,0,"Setup Alarm Log File : %s",filename); strcpy(psetup.logFile,filename); if (fl) fclose(fl); /* RO-flag. Albert */ if(_read_only_flag) fl = fopen(psetup.logFile,"r"); else if((_time_flag)||(_lock_flag)) fl = fopen(psetup.logFile,"a"); else fl = fopen(psetup.logFile,"w+"); - if (!fl) perror("CAN'T OPEN LOG FILE"); /* Albert */ + if (!fl) perror("CAN'T OPEN ALARM LOG FILE"); /* Albert */ + if (!fl) errMsg("CAN'T OPEN ALARM LOG FILE"); if (alarmLogFileMaxRecords) alarmLogFileOffsetBytes = 0; break; case FILE_OPMOD: - if (fo) alLogOpModMessage(0,0,"Setup OpMod File : %s",filename); + alLogOpModMessage(0,0,"Setup OpMod File : %s",filename); strcpy(psetup.opModFile,filename); if (fo) fclose(fo); if(!_read_only_flag) fo=fopen(psetup.opModFile,"a"); /* RO-option. Albert */ else fo=fopen(psetup.opModFile,"r"); - if (!fo) perror("CAN'T OPEN OP FILE"); /* Albert */ + if (!fo) perror("CAN'T OPEN OPMOD LOG FILE"); /* Albert */ + if (!fo) errMsg("CAN'T OPEN OPMOD LOG FILE"); break; case FILE_SAVEAS: @@ -748,7 +774,7 @@ XmAnyCallbackStruct *cbs) XtVaGetValues(widget, XmNuserData, &area, NULL); - if (fo) alLogOpModMessage(0,0,"Setup Save New Config: %s",filename); + alLogOpModMessage(0,0,"Setup Save New Config: %s",filename); if ( DEBUG == 1 ) printf("\nSaving Config File to %s \n", filename); @@ -770,6 +796,7 @@ static int getCommandLineParms(int argc, char** argv) int i,j; int finished=0; int parm_error=0; + FILE *fp; alarmLogFileMaxRecords=commandLine.alarmLogFileMaxRecords=2000; /* Albert */ @@ -964,6 +991,38 @@ static int getCommandLineParms(int argc, char** argv) _xml_flag=1; finished=1; break; + case PARM_LOCK_FILE: /* Andreas Luedeke: place .LOCK file in special directory */ + if(++i>=argc) parm_error=1; + else + { + if(argv[i][0]=='-') parm_error=2; + else + { + commandLine.lockFileBase=argv[i]; + finished=1; + } + } + break; + case PARM_SOUND_FILE: /* Andreas Luedeke: WAV file as alarm sound (implemented for Linux with "play") */ + if(++i>=argc) parm_error=1; + else + { + if(argv[i][0]=='-') parm_error=2; + else + { + strncpy(psetup.soundFile,argv[i],NAMEDEFAULT_SIZE-1); + fp = fopen(psetup.soundFile,"r"); + if (!fp) perror("Can't open beep file\n"); + if (!fp) errMsg("Can't open beep file %s\n",psetup.soundFile); + finished=1; + } + } + break; + case PARM_NOACK_MASK_COLOR: /* Andreas Luedeke: if channel/group mask disables sound, then change bg color of mask */ + _mask_color_flag=1; + finished=1; + break; + default: parm_error=1; break; @@ -1012,7 +1071,7 @@ if(_DB_call_flag&&!_lock_flag) return 1; } - if (_xml_flag) puts ("XML!"); else puts("no XML!"); + if (_xml_flag) puts ("XML!"); return 0; } @@ -1045,15 +1104,18 @@ static void printUsage(char *pgm) fprintf(stderr," -global Global mode (acks and ackt fields) \n"); fprintf(stderr," -help Print usage\n"); fprintf(stderr," -L Locking system\n"); + fprintf(stderr," -Lfile lockfile Directory for lock files [configdir]\n"); /* Andreas Luedeke */ fprintf(stderr," -l logdir Directory for log files [.]\n"); fprintf(stderr," -m maxrecords Alarm log file max records [2000]\n"); fprintf(stderr," -mainwindow Start with main window\n"); + fprintf(stderr," -maskcolor Print mask colored when channel/group contains silencing flag\n"); fprintf(stderr," -noerrorpopup Do not display error popup window (errors are logged).\n"); fprintf(stderr," -O key Database call\n"); fprintf(stderr," -o opmodlogfile OpMod log filename ["DEFAULT_OPMOD"]\n"); #ifdef CMLOG fprintf(stderr," -oCM OpMod log using CMLOG\n"); #endif + fprintf(stderr," -p sound Use wave data from file instead of alarm beep (OS dependent)\n"); fprintf(stderr," -P key Print to TCP printer\n"); fprintf(stderr," -S Passive (no caputs - acks field, ackt field, sevrpv)\n"); fprintf(stderr," -s Silent (no alarm beeping)\n"); @@ -1077,6 +1139,7 @@ char *argv[]; char logFile[NAMEDEFAULT_SIZE]; char opModFile[NAMEDEFAULT_SIZE]; char *name = NULL; + programId = ALH; programName = (char *)calloc(1,4); strcpy(programName,"alh"); @@ -1118,7 +1181,7 @@ char *argv[]; strncat(psetup.opModFile,opModFile,NAMEDEFAULT_SIZE-len); } if (DEBUG == 1 ) printf("\nOpMod File is %s \n", psetup.opModFile); - fileSetup(psetup.opModFile,NULL,FILE_OPMOD,programId,widget); + fileSetup(psetup.opModFile,NULL,FILE_OPMOD,programId,0); /* ----- initialize and setup alarm log file ----- */ if (psetup.logDir) { @@ -1139,7 +1202,7 @@ char *argv[]; strncat(psetup.logFile,logFile,NAMEDEFAULT_SIZE-len); } if (DEBUG == 1 ) printf("\nAlarmLog File is %s \n", psetup.logFile); - fileSetup(psetup.logFile,NULL,FILE_ALARMLOG,programId,widget); + fileSetup(psetup.logFile,NULL,FILE_ALARMLOG,programId,0); /* ----- initialize and setup config file ----- */ if (psetup.configDir) { @@ -1161,6 +1224,14 @@ char *argv[]; } if (DEBUG == 1 ) printf("\nConfig File is %s \n", psetup.configFile); fileSetup(psetup.configFile,NULL,FILE_CONFIG,programId,widget); + + /* ----- initialize and setup lock file ----- */ + if (commandLine.lockFileBase) /* Andreas Luedeke */ + strncpy(psetup.lockFileBase,commandLine.lockFileBase,NAMEDEFAULT_SIZE-1); + else + strncpy(psetup.lockFileBase,psetup.configFile,NAMEDEFAULT_SIZE-1); + + if (DEBUG == 1 ) printf("\nLock File is %s.LOCK \n", psetup.lockFileBase); } @@ -1227,7 +1298,7 @@ fclose(fp); if(!amIsender) { createDialog(w,XmDIALOG_INFORMATION,"\nBROADCAST MESSAGE:\n",messBuff); - XBell(XtDisplay(w),50); + alBeep(XtDisplay(w)); } if(strncmp(messBuff,reloadMBString+2,strlen(reloadMBString)-3 )==0) { @@ -1282,7 +1353,7 @@ exit_quit(NULL,NULL,NULL); /* signal(SIGINT,broadcastMess_exit_quit); Albert */ } -int getUserInfo() +static int getUserInfo() { static char myhostname[256]; static char loginid[16]; diff --git a/force.c b/force.c index c60c816..607cc63 100644 --- a/force.c +++ b/force.c @@ -358,8 +358,7 @@ static void forcePVCreateDialog(ALINK *area) xmLabelGadgetClass, form, XmNalignment, XmALIGNMENT_END, XmNtopAttachment, XmATTACH_FORM, - XmNrightAttachment, XmATTACH_POSITION, - XmNrightPosition, 50, + XmNleftAttachment, XmATTACH_FORM, XmNrecomputeSize, True, NULL); @@ -367,8 +366,9 @@ static void forcePVCreateDialog(ALINK *area) xmLabelGadgetClass, form, XmNalignment, XmALIGNMENT_BEGINNING, XmNtopAttachment, XmATTACH_FORM, - XmNleftAttachment, XmATTACH_POSITION, - XmNleftPosition, 50, + XmNleftAttachment, XmATTACH_WIDGET, + XmNleftWidget, nameLabelW, + XmNrightAttachment, XmATTACH_FORM, XmNrecomputeSize, True, NULL); @@ -404,8 +404,8 @@ static void forcePVCreateDialog(ALINK *area) xmLabelGadgetClass, form2, XmNlabelString, string, XmNtopAttachment, XmATTACH_WIDGET, - XmNtopWidget, forcePVdisabledToggleButton, - XmNtopOffset, 10, + XmNtopWidget, forcePVdisabledToggleButton, + XmNtopOffset, 10, NULL); XmStringFree(string); @@ -413,12 +413,12 @@ static void forcePVCreateDialog(ALINK *area) xmTextFieldWidgetClass, form2, XmNspacing, 0, XmNmarginHeight, 0, - XmNcolumns, 30, XmNmaxLength, PVNAME_SIZE, XmNbackground, textBackground, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, forcePVnameLabel, XmNleftAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_FORM, (XtPointer)NULL); XtAddCallback(forcePVnameTextW, XmNactivateCallback, @@ -491,8 +491,8 @@ static void forcePVCreateDialog(ALINK *area) XmNbackground, textBackground, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, prev, - XmNleftAttachment, XmATTACH_WIDGET, - XmNleftWidget, forcePVforceValueLabel, + XmNleftAttachment, XmATTACH_POSITION, + XmNleftPosition, 40, NULL); XtAddCallback(forcePVforceValueTextW, XmNactivateCallback, @@ -516,8 +516,8 @@ static void forcePVCreateDialog(ALINK *area) XmNbackground, textBackground, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, forcePVforceValueTextW, - XmNleftAttachment, XmATTACH_WIDGET, - XmNleftWidget, forcePVresetValueLabel, + XmNleftAttachment, XmATTACH_POSITION, + XmNleftPosition, 40, NULL); XtAddCallback(forcePVresetValueTextW, XmNactivateCallback, @@ -595,17 +595,17 @@ static void forcePVCreateDialog(ALINK *area) xmTextFieldWidgetClass, form3, XmNspacing, 0, XmNmarginHeight, 0, - XmNcolumns, 30, XmNmaxLength, PVNAME_SIZE, XmNbackground, textBackground, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, prev, +#if 0 XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, forcePVCalcPVLabel[i], -#if 0 - XmNrightAttachment, XmATTACH_POSITION, - XmNrightPosition, 50, #endif + XmNleftAttachment, XmATTACH_POSITION, + XmNleftPosition, 10, + XmNrightAttachment, XmATTACH_FORM, (XtPointer)NULL); prev = forcePVCalcPVTextW[i]; diff --git a/mask.c b/mask.c index 3f08290..20839c1 100644 --- a/mask.c +++ b/mask.c @@ -235,19 +235,15 @@ static void maskCreateDialog(ALINK *area) --------------------------------- */ nameLabelW = XtVaCreateManagedWidget("nameLabelW", xmLabelGadgetClass, form, - XmNalignment, XmALIGNMENT_END, XmNtopAttachment, XmATTACH_FORM, - XmNrightAttachment, XmATTACH_POSITION, - XmNrightPosition, (TIGHTNESS*(num_buttons+3) - 1)/2, + XmNleftAttachment, XmATTACH_FORM, XmNrecomputeSize, True, (XtPointer)NULL); nameTextW = XtVaCreateManagedWidget("nameTextW", xmLabelGadgetClass, form, - XmNalignment, XmALIGNMENT_BEGINNING, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, nameLabelW, - XmNrightAttachment, XmATTACH_NONE, XmNrecomputeSize, True, NULL); diff --git a/os/Linux/alAudio.c b/os/Linux/alAudio.c new file mode 100644 index 0000000..da416d0 --- /dev/null +++ b/os/Linux/alAudio.c @@ -0,0 +1,49 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 Deutches Elektronen-Synchrotron in der Helmholtz- +* Gemelnschaft (DESY). +* Copyright (c) 2002 Berliner Speicherring-Gesellschaft fuer Synchrotron- +* Strahlung mbH (BESSY). +* Copyright (c) 2002 Southeastern Universities Research Association, as +* Operator of Thomas Jefferson National Accelerator Facility. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* This file is distributed subject to a Software License Agreement found +* in the file LICENSE that is included with this distribution. +\*************************************************************************/ +/* alAudio.c + * + * alAudio.c,v 1.3 2003/02/27 17:20:08 jba Exp + * + */ + +#include +#include + +#include "alh.h" +#include "ax.h" +#include + +/* Audio device not implemented */ + +/****************************************************** + alBeep +******************************************************/ +void alBeep(Display *displayBB) +{ + static char cmd[NAMEDEFAULT_SIZE+9]=""; + if(strlen(psetup.soundFile)>0 ) { + if(strlen(cmd)==0 ) { + strcat(cmd,"play -q "); + strcat(cmd,psetup.soundFile); + strcat(cmd," &"); + /*strcat(cmd," > /dev/null 2>&1 &");*/ + } + system(cmd); + } else { + XkbBell(displayBB,None,0,None); + } + return; +} + diff --git a/os/Linux/alAudio.h b/os/Linux/alAudio.h new file mode 100644 index 0000000..9d49b62 --- /dev/null +++ b/os/Linux/alAudio.h @@ -0,0 +1,20 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 Deutches Elektronen-Synchrotron in der Helmholtz- +* Gemelnschaft (DESY). +* Copyright (c) 2002 Berliner Speicherring-Gesellschaft fuer Synchrotron- +* Strahlung mbH (BESSY). +* Copyright (c) 2002 Southeastern Universities Research Association, as +* Operator of Thomas Jefferson National Accelerator Facility. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* This file is distributed subject to a Software License Agreement found +* in the file LICENSE that is included with this distribution. +\*************************************************************************/ +/* alAudio.h */ + +/* do not #define AUDIO_BEEP */ + +/*extern void alhAudioSetupCallback( Widget widget, XtPointer calldata, XtPointer cbs);*/ + diff --git a/os/WIN32/alAudio.c b/os/WIN32/alAudio.c index e8095b3..d4e4656 100644 --- a/os/WIN32/alAudio.c +++ b/os/WIN32/alAudio.c @@ -14,7 +14,7 @@ \*************************************************************************/ /* alAudio.c * - alAudio.c,v 1.2 2002/08/02 15:37:47 jba Exp + alAudio.c,v 1.3 2010/12/23 19:37:40 jba Exp */ /************************DESCRIPTION*********************************** @@ -71,10 +71,10 @@ static struct beepsetup { short balance; short beepSource; unsigned char *beep; - unsigned long beepLength; + size_t beepLength; char *beepFileName; unsigned char *beepFileData; - unsigned long beepFileLength; + size_t beepFileLength; } audioSetup={NULL,NULL,AUDIO_DEFAULT_OUTPUT,AUDIO_CHANNELS_STEREO, 8000,50,BEEP_AUDIO_SOURCE_INTERNAL,0,0,0,0,0} ; @@ -518,9 +518,9 @@ static int audioSetupNewFilename(Widget widget, char *string) { char * filename; char * plast; - int filenameSize; + size_t filenameSize; unsigned long fileSize; - unsigned long beepLength; + size_t beepLength; FILE * fp; unsigned char* beep; diff --git a/os/default/alAudio.c b/os/default/alAudio.c index 6e58266..c6e36ab 100644 --- a/os/default/alAudio.c +++ b/os/default/alAudio.c @@ -14,11 +14,15 @@ \*************************************************************************/ /* alAudio.c * - * alAudio.c,v 1.4 2009/10/15 14:50:20 jba Exp + * alAudio.c,v 1.6 2014/08/25 18:57:49 jba Exp * */ #include + +#include +#include + #include "alh.h" /* Audio device not implemented */ @@ -26,11 +30,11 @@ /****************************************************** alBeep ******************************************************/ -int alBeep(Display *displayBB) +void alBeep(Display *displayBB) { /* system("play /path/to/beep.wav"); */ - XBell(displayBB,0); - return 0; + XkbBell(displayBB,None,0,None); + return; } diff --git a/os/solaris/alAudio.c b/os/solaris/alAudio.c index 6114c34..6c43161 100644 --- a/os/solaris/alAudio.c +++ b/os/solaris/alAudio.c @@ -14,7 +14,7 @@ \*************************************************************************/ /* alAudio.c * - alAudio.c,v 1.3 2002/08/02 15:37:48 jba Exp + alAudio.c,v 1.4 2011/01/27 15:00:54 jba Exp */ /************************DESCRIPTION*********************************** @@ -31,6 +31,9 @@ #include #include +#include +#include + #include #include #include @@ -251,10 +254,10 @@ void alBeep(Display *displayBB) percent = 100; if (audioSetup.port==AUDIO_NONE){ - XBell(displayBB,percent); + XkbBell(displayBB,None,percent,None); } else { if (alAudioBeep()){ - XBell(displayBB,percent); + XkbBell(displayBB,None,percent,None); } } } diff --git a/process.c b/process.c index bc284be..ff41162 100644 --- a/process.c +++ b/process.c @@ -100,7 +100,7 @@ Else if you're master-alh-process -- the same errMsg("processSpawn_callback: Cannot find command processor\n"); return; } - status = _spawnl(_P_DETACH, ComSpec, ComSpec, "/C", buff, NULL); + status = (int)_spawnl(_P_DETACH, ComSpec, ComSpec, "/C", buff, NULL); #else sprintf(buff,"%s &",command); status=system(buff); diff --git a/property.c b/property.c index a2d4073..d46d3a6 100644 --- a/property.c +++ b/property.c @@ -582,17 +582,12 @@ static void propCreateDialog(ALINK *area) xmTextFieldWidgetClass, form, XmNspacing, 0, XmNmarginHeight, 0, -/* - XmNcolumns, 30, - XmNrecomputeSize, True, -*/ XmNmaxLength, PVNAME_SIZE, XmNbackground, textBackground, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, nameLabelW, - XmNrightAttachment, XmATTACH_POSITION, - XmNrightPosition, 50, + XmNrightAttachment, XmATTACH_FORM, NULL); XtAddCallback(nameTextW, XmNactivateCallback, @@ -685,7 +680,8 @@ static void propCreateDialog(ALINK *area) --------------------------------- */ countFilterFrame = XtVaCreateManagedWidget("countFilterFrame", xmFrameWidgetClass, form, - XmNtopAttachment, XmATTACH_FORM, + XmNtopAttachment, XmATTACH_WIDGET, + XmNtopWidget, nameTextW, XmNrightAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 50, @@ -769,7 +765,7 @@ static void propCreateDialog(ALINK *area) frame2 = XtVaCreateManagedWidget("frame2", xmFrameWidgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, - XmNtopWidget, prev, + XmNtopWidget, form1, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL); @@ -803,13 +799,15 @@ static void propCreateDialog(ALINK *area) xmTextFieldWidgetClass, form2, XmNspacing, 0, XmNmarginHeight, 0, - XmNcolumns, 30, +/* XmNmaxLength, PVNAME_SIZE, +*/ XmNbackground, textBackground, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, forcePVLabel, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, forcePVnameLabel, + XmNrightAttachment, XmATTACH_FORM, NULL); XtAddCallback(forcePVnameTextW, XmNactivateCallback, @@ -826,7 +824,9 @@ static void propCreateDialog(ALINK *area) XmStringFree(string); prev = forcePVForceMaskLabel; +/* string = XmStringCreateSimple("-----"); +*/ forcePVForceMaskStringLabelW = XtVaCreateManagedWidget("forcePVmaskStringLabelW", xmLabelGadgetClass, form2, XmNlabelString, string, @@ -835,7 +835,9 @@ static void propCreateDialog(ALINK *area) XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, forcePVForceMaskLabel, NULL); +/* XmStringFree(string); +*/ string = XmStringCreateSimple(" Force Value "); forcePVforceValueLabel = XtVaCreateManagedWidget("forcePVvalue", @@ -890,14 +892,14 @@ static void propCreateDialog(ALINK *area) (XtCallbackProc)XmProcessTraversal, (XtPointer)XmTRAVERSE_NEXT_TAB_GROUP); frame3 = XtVaCreateManagedWidget("frame3", - xmFrameWidgetClass, form2, + xmFrameWidgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, forcePVforceValueTextW, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL); - form3 = XtVaCreateWidget("form2", + form3 = XtVaCreateWidget("form3", xmFormWidgetClass, frame3, XmNspacing, 0, XmNmarginHeight, 0, @@ -926,8 +928,6 @@ static void propCreateDialog(ALINK *area) xmTextFieldWidgetClass, form3, XmNspacing, 0, XmNmarginHeight, 0, - XmNcolumns, 40, - XmNmaxLength, 100, XmNbackground, textBackground, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_WIDGET, @@ -985,12 +985,8 @@ static void propCreateDialog(ALINK *area) XmNlabelString, string, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, prev, - XmNleftAttachment, XmATTACH_POSITION, - XmNleftPosition, 50, -/* - XmNleftAttachment, XmATTACH_WIDGET, - XmNleftWidget, forcePVCalcPVTextW[i-6], -*/ + XmNleftAttachment, XmATTACH_POSITION, + XmNleftPosition, 50, NULL); XmStringFree(string); @@ -998,8 +994,6 @@ static void propCreateDialog(ALINK *area) xmTextFieldWidgetClass, form3, XmNspacing, 0, XmNmarginHeight, 0, - XmNcolumns, 30, - XmNmaxLength, PVNAME_SIZE, XmNbackground, textBackground, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, prev, @@ -1029,7 +1023,7 @@ static void propCreateDialog(ALINK *area) xmLabelGadgetClass, form, XmNlabelString, string, XmNtopAttachment, XmATTACH_WIDGET, - XmNtopWidget, frame2, + XmNtopWidget, frame3, XmNleftAttachment, XmATTACH_FORM, NULL); XmStringFree(string); @@ -1042,7 +1036,7 @@ static void propCreateDialog(ALINK *area) XmNmaxLength, 10, XmNbackground, textBackground, XmNtopAttachment, XmATTACH_WIDGET, - XmNtopWidget, frame2, + XmNtopWidget, frame3, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, beepSeverityLabel, NULL); @@ -1786,6 +1780,7 @@ void *area; static void propEditableDialogWidgets(ALINK *area) { struct propWindow *propWindow; + int i; propWindow = (struct propWindow *)area->propWindow; @@ -1798,6 +1793,10 @@ static void propEditableDialogWidgets(ALINK *area) XtVaSetValues(propWindow->forcePVnameTextW,XmNeditable, FALSE, NULL); XtVaSetValues(propWindow->forcePVforceValueTextW,XmNeditable, FALSE, NULL); XtVaSetValues(propWindow->forcePVresetValueTextW,XmNeditable, FALSE, NULL); + XtVaSetValues(propWindow->forcePVCalcExpressionTextW,XmNeditable, FALSE, NULL); + for (i=0;iforcePVCalcPVTextW[i],XmNeditable, FALSE, NULL); + } XtVaSetValues(propWindow->aliasTextW,XmNeditable, FALSE, NULL); XtVaSetValues(propWindow->processTextW,XmNeditable, FALSE, NULL); XtVaSetValues(propWindow->sevrProcessTextW,XmNeditable, FALSE, NULL); @@ -1813,6 +1812,10 @@ static void propEditableDialogWidgets(ALINK *area) XtVaSetValues(propWindow->forcePVnameTextW,XmNeditable, TRUE, NULL); XtVaSetValues(propWindow->forcePVforceValueTextW,XmNeditable, TRUE, NULL); XtVaSetValues(propWindow->forcePVresetValueTextW,XmNeditable, TRUE, NULL); + XtVaSetValues(propWindow->forcePVCalcExpressionTextW,XmNeditable, TRUE, NULL); + for (i=0;iforcePVCalcPVTextW[i],XmNeditable, TRUE, NULL); + } XtVaSetValues(propWindow->aliasTextW,XmNeditable, TRUE, NULL); XtVaSetValues(propWindow->processTextW,XmNeditable, TRUE, NULL); XtVaSetValues(propWindow->sevrProcessTextW,XmNeditable, TRUE, NULL); diff --git a/scroll.c b/scroll.c index 0d30f25..9bf8106 100644 --- a/scroll.c +++ b/scroll.c @@ -87,7 +87,6 @@ char *Strncat( # define MAX(a,b) ((a) > (b) ? a : b) #endif - static int viewFileUsedLength[N_LOG_FILES]; /* used length of file. */ static int viewFileMaxLength[N_LOG_FILES]; /* max length of file. */ static char *viewFileString[N_LOG_FILES]; /* contents of file. */ @@ -100,157 +99,68 @@ extern int alarmLogFileOffsetBytes; /* alarm log file current offset in bytes */ extern int alarmLogFileStringLength; /* alarm log file record length*/ extern int alarmLogFileMaxRecords; /* alarm log file maximum # records */ - extern int DEBUG; extern struct setup psetup; /* current file setup */ -static char error_file_size[] = { - " Sorry: file size too big to view." - }; - - -typedef struct fplistTag { - struct fplistTag *flink; - struct fplistTag *blink; - FILE *f; -} fplistType, *fplistPtr; - -static fplistPtr g_head; +static char error_file_size[] = { " Sorry: file size too big to view." }; #define MAXCONFIGFILELINE 1023 + #ifdef WIN32 #define strtok_r strtok_s #endif -static void readFile ( - fplistPtr cur, - char *buf, - int *max, - int *size, - int *depth -) { - -char line[MAXCONFIGFILELINE+1], *result, *tk, *ctx, incFile[1023+1]; -fplistPtr new; -int i, l; - - if ( cur->f ) { - - do { - - result = fgets( line, MAXCONFIGFILELINE, cur->f ); - if ( result ) { +/**************************************************************** +static void readFile +****************************************************************/ +static int readFile (char *filename, char **buf, int *max, int *fsize, int *depth) +{ + FILE *fp; + char line[MAXCONFIGFILELINE+1], *result, *tk, *ctx; + int i; + int status; + + /* open the file */ + if ((fp = fopen(filename, "r")) == NULL) { + errMsg("Cannot open file view: file %s not found\n",filename); + return -1; /* bail out if no file found */ + } - *size += strlen(line) + *depth * 3; + /* read the file */ + while ( (result = fgets( line, MAXCONFIGFILELINE, fp)) ) { - if ( *size+10 > *max ) { - *max = (int)(*size + 0.5 * *size); - buf = (char *) XtRealloc( buf, *max ); + /* realloc buf if fsize is not large enough */ + *fsize += (int)strlen(line) + *depth * 3; + if ( *fsize+1 > *max ) { + *max = (int)(*fsize + 0.5 * *fsize); + *buf = (char *) XtRealloc( *buf, *max ); } - for ( i=0; i<*depth; i++ ) strcat( buf, " " ); + /* indent lines of an embedded file by 3 blanks * depth of INCLUDE */ + for ( i=0; i<*depth; i++ ) strcat( *buf, " " ); - strcat( buf, line ); + strcat( *buf, line ); - ctx = NULL; - tk = strtok_r( line, " \t\n", &ctx ); - if ( tk ) { - if ( strcmp( tk, "INCLUDE" ) == 0 ) { - tk = strtok_r( NULL, " \t\n", &ctx ); + /* test for a "INCLUDE groupname filename" line */ + ctx = NULL; + tk = strtok_r( line, " \t\n", &ctx); + if ( tk && strcmp( tk, "INCLUDE" )==0 ) { + tk = strtok_r( NULL, " \t\n", &ctx); /* ignore groupname */ if ( tk ) { - tk = strtok_r( NULL, " \t\n", &ctx ); + tk = strtok_r( NULL, " \t\n", &ctx); /* filename */ if ( tk ) { - new = (fplistPtr) calloc( 1, sizeof(fplistType) ); - g_head->blink->flink = new; - new->blink = g_head->blink; - new->flink = g_head; - g_head->blink = new; - if ( psetup.configDir ) { - strncpy( incFile, psetup.configDir, 1023 ); - incFile[1023] = 0; - l = strlen( incFile ); - if ( l > 0 ) { - if ( incFile[l-1] != '/' ) { - Strncat( incFile, "/", 1023 ); - incFile[1023] = 0; - } - } - } - else { - strcpy( incFile, "" ); - } - Strncat( incFile, tk, 1023 ); - incFile[1023] = 0; - new->f = fopen( incFile, "r" ); (*depth)++; - *size += strlen("----------------------------\n") + - *depth * 3; - if ( *size+10 > *max ) { - *max = (int)(*size + 0.5 * *size); - buf = (char *) XtRealloc( buf, *max ); - } - for ( i=0; i<*depth; i++ ) strcat( buf, " " ); - strcat( buf, "----------------------------\n" ); - readFile( new, buf, max, size, depth ); - *size += strlen("----------------------------\n") + *depth * 3; - if ( *size+10 > *max ) { - *max = (int)(*size + 0.5 * *size); - buf = (char *) XtRealloc( buf, *max ); - } - for ( i=0; i<*depth; i++ ) strcat( buf, " " ); - strcat( buf, "----------------------------\n" ); + status = readFile ( tk, buf, max, fsize, depth); + if (status) return status; (*depth)--; - if ( new->f ) fclose( new->f ); - new->blink->flink = new->flink; - new->flink->blink = new->blink; - free( new ); } } - } } - - } - - } while ( result ); - } - + fclose(fp); + return 0; } -static void readAll ( - char *buf, - int max, - int num, - FILE *fp -) { - -fplistPtr cur; -int size = 0; -int depth = 0; - - g_head = (fplistPtr) calloc( 1, sizeof(fplistType) ); - g_head->f = NULL; - g_head->flink = g_head; - g_head->blink = g_head; - - cur = (fplistPtr) calloc( 1, sizeof(fplistType) ); - cur->f = fp; - - /* link */ - cur->blink = g_head->blink; - g_head->blink->flink = cur; - cur->flink = g_head; - g_head->blink = cur; - - readFile( cur, buf, &max, &size, &depth ); - - cur->blink->flink = cur->flink; - cur->flink->blink = cur->blink; - free( cur ); - - free( g_head ); - -} /************************************************************************** create scroll window for file view @@ -290,11 +200,10 @@ void fileViewWindow(Widget w,int option,Widget menuButton) viewFileUsedLength[option] = 0; viewFileMaxLength[option] = 0; - XtFree(viewFileString[option]); viewFileString[option]=NULL; - XtUnmanageChild(app_shell); + XtUnmanageChild(app_shell); XtVaSetValues(menuButton, XmNset, FALSE, NULL); return; @@ -303,52 +212,78 @@ void fileViewWindow(Widget w,int option,Widget menuButton) XtVaSetValues(menuButton, XmNset, TRUE, NULL); if (stat(filename, &statbuf) == 0) - viewFileUsedLength[operandFile] = statbuf.st_size; + viewFileUsedLength[operandFile] = statbuf.st_size +1; else viewFileUsedLength[operandFile] = 1000000; /* arbitrary file length */ if (statbuf.st_size > 1000000) { XtVaSetValues(menuButton, XmNset, FALSE, NULL); - createDialog(XtParent(w),XmDIALOG_ERROR,filename, &error_file_size[0]); + createDialog(XtParent(w),XmDIALOG_ERROR,filename, error_file_size); return; } - /* allocate space for the file string */ - viewFileMaxLength[operandFile] = MAX(INITIAL_FILE_LENGTH, - 2*viewFileUsedLength[operandFile]); - viewFileString[operandFile] = (char *) - XtCalloc(1,viewFileMaxLength[operandFile]); - if(!viewFileString[operandFile]) { - XtVaSetValues(menuButton, XmNset, FALSE, NULL); - createDialog(XtParent(w),XmDIALOG_ERROR,"no free memory",""); - return; - } - - /* read the file string */ - if ((fp = fopen(filename, "r")) == NULL) { - XtVaSetValues(menuButton, XmNset, FALSE, NULL); - fprintf(stderr,"fileViewWindow: file %s not found\n",filename); - return; /* bail out if no file found */ - } switch (option) { case CONFIG_FILE: - readAll( viewFileString[operandFile], - viewFileUsedLength[operandFile], 1, fp ); + + { + int size = 0; + int depth = 0; + + /* allocate space for the file string */ + viewFileString[operandFile] = (char *) + XtCalloc(1,viewFileUsedLength[operandFile]); + if(!viewFileString[operandFile]) { + XtVaSetValues(menuButton, XmNset, FALSE, NULL); + createDialog(XtParent(w),XmDIALOG_ERROR,"no free memory",""); + return; + } + + readFile(filename, &viewFileString[operandFile], + &viewFileUsedLength[operandFile], &size, &depth); + } + break; default: - fread(viewFileString[operandFile], - viewFileUsedLength[operandFile],1, fp); - break; + + + { + /* allocate space for the file string */ + viewFileMaxLength[operandFile] = MAX(INITIAL_FILE_LENGTH, + 2*viewFileUsedLength[operandFile]); + viewFileString[operandFile] = (char *) + XtCalloc(1,viewFileMaxLength[operandFile]); + if(!viewFileString[operandFile]) { + XtVaSetValues(menuButton, XmNset, FALSE, NULL); + createDialog(XtParent(w),XmDIALOG_ERROR,"no free memory",""); + return; + } + + /* Open the file */ + if ((fp = fopen(filename, "r")) == NULL) { + XtVaSetValues(menuButton, XmNset, FALSE, NULL); + errMsg("Cannot open file view: file %s not found\n",filename); + return; /* bail out if no file found */ + } + + /* read the file */ + fread(viewFileString[operandFile], + viewFileUsedLength[operandFile],1, fp); + + clearerr(fp); + if (fclose(fp)) { + fprintf(stderr, "fileViewWindow: unable to close file %s.\n",filename); + errMsg("Error: unable to close file %s.\n",filename); + } + + break; } - clearerr(fp); - if (fclose(fp)) fprintf(stderr, - "fileViewWindow: unable to close file %s.\n",filename); + } /* create view window dialog */ if (!app_shell) { @@ -585,7 +520,7 @@ void updateLog(int fileIndex,char *string) #endif char *tmp; - int stringLength = strlen(string); + int stringLength = (int)strlen(string); int oldUsedLength = viewFileUsedLength[fileIndex]; @@ -643,12 +578,15 @@ void updateLog(int fileIndex,char *string) /* read the file string */ if ((fp = fopen(filename, "r")) == NULL) { fprintf(stderr,"updateLog: file %s open error.\n",filename); + errMsg("Error opening file %s\n",filename); return; /* bail out if no file found */ } fread(viewFileString[fileIndex], sizeof(char), viewFileUsedLength[fileIndex], fp); - if (fclose(fp)) fprintf(stderr, - "updateLog: unable to close file %s.\n",filename); + if (fclose(fp)) { + fprintf(stderr, "updateLog: unable to close file %s.\n",filename); + errMsg("Error closing file %s\n",filename); + } /* add the file string to the text widget */ XmTextSetString(viewTextWidget[fileIndex], viewFileString[fileIndex]); @@ -717,8 +655,8 @@ void browser_fileViewWindow(Widget w,int option,Widget menuButton) static Widget opmod_shell=NULL; Widget app_shell=NULL,title=0,button,button1; Widget previous; - char sbuf[120]; #ifndef WIN32 + char sbuf[120]; DIR *directory; #endif struct stat statbuf; /* Information on a file. */ @@ -779,8 +717,7 @@ void browser_fileViewWindow(Widget w,int option,Widget menuButton) } #endif if ((fp = fopen(filename, "r")) == NULL) { - sprintf(sbuf, "fileViewWindow: Can't open file %s\n",filename); - createDialog(w,XmDIALOG_WARNING,sbuf," "); + errMsg("Can't open file %s\n",filename); fprintf(stderr, "Can't open file %s\n",filename); return; } @@ -1354,7 +1291,7 @@ XtPointer call_data) XChangeWindowAttributes(display,XtWindow((Widget)client_data),CWCursor,&attrs); XFlush(display); - len=strlen(FSnameshort)-10; /* length of name without "extension" */ + len=(int)strlen(FSnameshort)-10; /* length of name without "extension" */ #ifndef WIN32 while((rdr=readdir(directory))) { @@ -1572,7 +1509,7 @@ XtPointer call_data) } XmTextSetHighlight(text_w,positionSearch,positionSearch+lenSearch, XmHIGHLIGHT_NORMAL); - lenSearch=strlen(search_pat); + lenSearch=(int)strlen(search_pat); positionSearch = XmTextGetCursorPosition(text_w); for(p=&string[positionSearch+1];(p=strchr((const char *)p,*search_pat));p++) if (!strncmp(p, search_pat, lenSearch)) { @@ -1620,7 +1557,7 @@ XtPointer call_data) } XmTextSetHighlight(text_w,positionSearch,positionSearch+lenSearch, XmHIGHLIGHT_NORMAL); - lenSearch=strlen(search_pat); + lenSearch=(int)strlen(search_pat); if((positionSearch=XmTextGetCursorPosition(text_w))>0) { for (p = &string[positionSearch-1]; p >= string; p--) diff --git a/showmask.c b/showmask.c index 26d3b29..7f74447 100644 --- a/showmask.c +++ b/showmask.c @@ -307,17 +307,17 @@ ALINK *area; xmLabelGadgetClass, form, XmNalignment, XmALIGNMENT_END, XmNtopAttachment, XmATTACH_FORM, - XmNrightAttachment, XmATTACH_POSITION, - XmNrightPosition, 50, + XmNleftAttachment, XmATTACH_FORM, XmNrecomputeSize, True, - (XtPointer)NULL); + NULL); nameTextW = XtVaCreateManagedWidget("nameTextW", xmLabelGadgetClass, form, XmNalignment, XmALIGNMENT_BEGINNING, + XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, nameLabelW, - XmNrightAttachment, XmATTACH_NONE, + XmNrightAttachment, XmATTACH_FORM, XmNrecomputeSize, True, NULL); diff --git a/version.h b/version.h index 5c1c7b6..0b3d94f 100644 --- a/version.h +++ b/version.h @@ -23,9 +23,9 @@ #define ALH_VERSION 1 #define ALH_REVISION 2 -#define ALH_MODIFICATION 26 +#define ALH_MODIFICATION 35 -#define ALH_VERSION_STRING "ALH Version 1.2.26" +#define ALH_VERSION_STRING "ALH Version 1.2.35" #define ALH_CREDITS_STRING \ "Developed at Argonne National Laboratory\n\n" \ @@ -33,6 +33,8 @@ " Mark Anderson, Marty Kraimer,\n" \ " and Albert Kagarmanov\n\n" \ "(With SNS modifications as of 3/07 by\n" \ - "John Sinclair and Kay Kasemir)\n\n" + "John Sinclair and Kay Kasemir)\n" \ + "(With PSI modifications as of May 2012 by\n" \ + "Andreas Luedeke)\n\n" #endif /* INCversionh */