📄 xemc.cc
字号:
/********************************************************************* Description: xemc.cc* X GUI for the EMC** Derived from a work by Fred Proctor & Will Shackleford* Brought forward and adapted to emc2 by Alex Joni** Author: * License: GPL Version 2* System: Linux* * Copyright (c) 2004 All rights reserved.** Last change:* $Revision: 1.8 $* $Author: jepler $* $Date: 2007/03/22 22:15:32 $********************************************************************/#include <stdio.h>#include <string.h>#include <stdlib.h>#include <ctype.h>#include <values.h> // DBL_MAX, maybe#include <limits.h> // DBL_MAX, maybe#include <stdarg.h>#include <sys/stat.h> // struct stat, stat()#include <unistd.h>#include <fcntl.h> // O_CREAT#include "rcs.hh" // etime()#include "emc.hh" // EMC NML#include "emc_nml.hh"#include "emcglb.h" // EMC_NMLFILE, TRAJ_MAX_VELOCITY, TOOL_TABLE_FILE#include "emccfg.h" // DEFAULT_TRAJ_MAX_VELOCITY#include "inifile.hh" // INIFILE#include "rcs_print.hh"#include "nml_oi.hh"#include "timer.hh"/* * Include files required for all Toolkit programs */#include <X11/Intrinsic.h> /* Intrinsics Definitions */#include <X11/StringDefs.h> /* Standard Name-String definitions *//* * Public include file for widgets we actually use in this file. */#include <X11/Xaw/Form.h>#include <X11/Xaw/Box.h>#include <X11/Xaw/Command.h>#include <X11/Xaw/Label.h>#include <X11/Xaw/AsciiText.h>#include <X11/Xaw/MenuButton.h>#include <X11/Xaw/SimpleMenu.h>#include <X11/Xaw/SmeBSB.h>#include <X11/Xaw/SmeLine.h>#include <X11/Xaw/Dialog.h>#define UPDATE_MSECS 100// the NML channels to the EMC taskstatic RCS_CMD_CHANNEL *emcCommandBuffer = 0;static RCS_STAT_CHANNEL *emcStatusBuffer = 0;EMC_STAT *emcStatus = 0;// the NML channel for errorsstatic NML *emcErrorBuffer = 0;static char error_string[LINELEN] = "";// the current command numbers, set up updateStatus(), used in main()static int emcCommandSerialNumber = 0;// forward decls// forward decls for error popupstatic void errorReturnAction(Widget w, XEvent *event, String *params, Cardinal *num_params);static void errorDoneCB(Widget w, XtPointer client_data, XtPointer call_data);static int createErrorShell();static int destroyErrorShell();static void popupError(const char *fmt, ...);// forward decl for quit() functionstatic void quit();static int emcTaskNmlGet(){ int retval = 0; // try to connect to EMC cmd if (emcCommandBuffer == 0) { emcCommandBuffer = new RCS_CMD_CHANNEL(emcFormat, "emcCommand", "xemc", EMC_NMLFILE); if (! emcCommandBuffer->valid()) { delete emcCommandBuffer; emcCommandBuffer = 0; retval = -1; } } // try to connect to EMC status if (emcStatusBuffer == 0) { emcStatusBuffer = new RCS_STAT_CHANNEL(emcFormat, "emcStatus", "xemc", EMC_NMLFILE); if (! emcStatusBuffer->valid() || EMC_STAT_TYPE != emcStatusBuffer->peek()) { delete emcStatusBuffer; emcStatusBuffer = 0; emcStatus = 0; retval = -1; } else { emcStatus = (EMC_STAT *) emcStatusBuffer->get_address(); } } return retval;}static int emcErrorNmlGet(){ int retval = 0; if (emcErrorBuffer == 0) { emcErrorBuffer = new NML(nmlErrorFormat, "emcError", "xemc", EMC_NMLFILE); if (! emcErrorBuffer->valid()) { delete emcErrorBuffer; emcErrorBuffer = 0; retval = -1; } } return retval;}static void printError(char *error){ printf("%s\n", error);}static int updateStatus(){ NMLTYPE type; if (0 == emcStatus || 0 == emcStatusBuffer || ! emcStatusBuffer->valid()) { return -1; } switch (type = emcStatusBuffer->peek()) { case -1: // error on CMS channel return -1; break; case 0: // no new data case EMC_STAT_TYPE: // new data // new data break; default: return -1; break; } return 0;}static int updateError(){ NMLTYPE type; if (0 == emcErrorBuffer || ! emcErrorBuffer->valid()) { return -1; } switch (type = emcErrorBuffer->read()) { case -1: // error reading channel return -1; break; case 0: // nothing new error_string[0] = 0; break; case EMC_OPERATOR_ERROR_TYPE: strncpy(error_string, ((EMC_OPERATOR_ERROR *) (emcErrorBuffer->get_address()))->error, LINELEN - 1); error_string[LINELEN - 1] = 0; break; case EMC_OPERATOR_TEXT_TYPE: strncpy(error_string, ((EMC_OPERATOR_TEXT *) (emcErrorBuffer->get_address()))->text, LINELEN - 1); error_string[LINELEN - 1] = 0; break; case EMC_OPERATOR_DISPLAY_TYPE: strncpy(error_string, ((EMC_OPERATOR_DISPLAY *) (emcErrorBuffer->get_address()))->display, LINELEN - 1); error_string[LINELEN - 1] = 0; break; case NML_ERROR_TYPE: strncpy(error_string, ((NML_ERROR *) (emcErrorBuffer->get_address()))->error, NML_ERROR_LEN - 1); error_string[NML_ERROR_LEN - 1] = 0; break; case NML_TEXT_TYPE: strncpy(error_string, ((NML_TEXT *) (emcErrorBuffer->get_address()))->text, NML_ERROR_LEN - 1); error_string[NML_ERROR_LEN - 1] = 0; break; case NML_DISPLAY_TYPE: strncpy(error_string, ((NML_DISPLAY *) (emcErrorBuffer->get_address()))->display, NML_ERROR_LEN - 1); error_string[NML_ERROR_LEN - 1] = 0; break; default: sprintf(error_string, "unrecognized error %ld",type); return -1; break; } return 0;}#define EMC_COMMAND_TIMEOUT 1.0 // how long to wait until timeout#define EMC_COMMAND_DELAY 0.1 // how long to sleep between checksstatic int emcCommandWaitDone(int serial_number){ double start = etime(); while (etime() - start < EMC_COMMAND_TIMEOUT) { updateStatus(); if (emcStatus->echo_serial_number == serial_number) { if (emcStatus->status == RCS_DONE) { return 0; } else if (emcStatus->status == RCS_ERROR) { return -1; } } esleep(EMC_COMMAND_DELAY); } return -1;}/* functions for handling the windowing of a file, where you give the line you wish to window and it produces an array of string, or single string, of the file's contents at that point and some lines beyond */#define LF 10#define CR 13typedef struct { /* the array holding the window of lines in the file */ char *fileWindow; /* the number of lines in the window */ int maxWindowLines; /* the max length of each line */ int maxLineLen; /* which array index holds the first filled slot */ int windowStart; /* which array index holds the next open slot */ int windowEnd; /* number in ring, also used to differentiate start = end as full/empty */ int windowCount; /* the file to window */ FILE * fileFp; /* the line currently at the top of the window */ int fileFpLine; /* flag that the line should be kept */ int keepNextLine;} FILE_WINDOW;static int fwClear(FILE_WINDOW *fw){ int t; if (NULL == fw) { return -1; } for (t = 0; t < fw->maxWindowLines; t++) { fw->fileWindow[t * fw->maxLineLen] = 0; } fw->windowStart = 0; fw->windowEnd = 0; fw->windowCount = 0; fw->fileFpLine = 0; fw->keepNextLine = 1; return 0;}static int fwInit(FILE_WINDOW *fw, int _maxWindowLines, int _maxLineLen){ if (NULL == fw) { return -1; } fw->fileWindow = (char *) malloc(_maxLineLen * _maxWindowLines); fw->maxWindowLines = _maxWindowLines; fw->maxLineLen = _maxLineLen; /* clear out the remaining vars */ if (0 != fwClear(fw)) { return -1; } /* mark the file closed */ fw->fileFp = NULL; return 0;}static int fwOpen(FILE_WINDOW *fw, const char *file){ if (NULL == fw) { return -1; } /* close any open file */ if (NULL != fw->fileFp) { fclose(fw->fileFp); fw->fileFp = NULL; } if (NULL == (fw->fileFp = fopen(file, "r"))) { return -1; } fw->keepNextLine = 1; return 0;}static int fwClose(FILE_WINDOW *fw){ int retval = 0; if (NULL == fw) { return -1; } /* first clear out the window */ if (0 != fwClear(fw)) { retval = -1; } if (NULL != fw->fileFp) { fclose(fw->fileFp); } fw->fileFp = NULL; return retval;}#if 0static int fwDelete(FILE_WINDOW *fw){ if (NULL == fw) { return -1; } /* should have been closed by call to fwClose(), but make sure */ if (NULL != fw->fileFp) { fclose(fw->fileFp); fw->fileFp = NULL; } free(fw->fileWindow); return 0;}static int fwPrintWindow(FILE_WINDOW *fw){ int start; if (NULL == fw) { return -1; } start = fw->windowStart; if (0 == fw->windowCount) { return 0; } do { printf("%s\n", &(fw->fileWindow[start * fw->maxLineLen])); if (++start >= fw->maxWindowLines) { start = 0; } } while (start != fw->windowEnd); return 0;}#endifstatic int fwAddLine(FILE_WINDOW *fw, const char *line){ if (NULL == fw) { return -1; } strncpy(&fw->fileWindow[fw->windowEnd * fw->maxLineLen], line, fw->maxLineLen - 1); fw->fileWindow[fw->windowEnd * fw->maxLineLen + fw->maxLineLen - 1] = 0; if (fw->windowEnd == fw->windowStart && 0 != fw->windowCount) { /* we're full, so move fw->windowStart up */ /* and don't increment fw->windowCount */ if (++fw->windowStart >= fw->maxWindowLines) { fw->windowStart = 0; } } else { /* we're not full, so no need to move fw->windowStart up */ /* but do increment fw->windowCount */ ++fw->windowCount; } /* now increment fw->windowEnd to point to next slot */ if (++fw->windowEnd >= fw->maxWindowLines) { fw->windowEnd = 0; } return 0;}#if 0static int fwDeleteLine(FILE_WINDOW *fw){ if (NULL == fw) { return -1; } if (0 == fw->windowCount) { return 0; } fw->fileWindow[fw->windowStart * fw->maxLineLen] = 0; if (++fw->windowStart >= fw->maxWindowLines) { fw->windowStart = 0; } --fw->windowCount; return 0;}#endifstatic int fwSyncLine(FILE_WINDOW *fw, int syncLine){ char line[256]; // FIXME-- hardcoded int pad; int len; int sawEol; if (NULL == fw) { return -1; } if (NULL == fw->fileFp) { return -1; } /* if syncLine is <= 0, make it 1 */ if (syncLine <= 0) { syncLine = 1; } /* reset syncLine so that it means the first line is synched */ syncLine += fw->maxWindowLines - 1; /* check if our window is ahead of file, and rewind if so */ if (syncLine < fw->fileFpLine) { /* we're ahead of program, so rewind */ rewind(fw->fileFp); /* and clear out fw->fileWindow */ fwClear(fw); } /* now the window is at or behind the file */ /* so fill it up */ while (fw->fileFpLine < syncLine) { if (NULL == fgets(line, fw->maxLineLen, fw->fileFp)) { /* end file */ /* pad remainder if any */ pad = syncLine - fw->fileFpLine; while (pad-- > 0) { fwAddLine(fw, ""); } fw->fileFpLine = syncLine;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -