///////////////////////////////////////////////////////////// // // Source file for Checkpoint // // This file is generated by RapidApp 1.2 // // This class is derived from CheckpointUI which // implements the user interface created in // RapidApp. This class contains virtual // functions that are called from the user interface. // // When you modify this source, limit your changes to // modifying the sections between the // "//---- Start/End editable code block" markers // // This will allow RapidApp to integrate changes more easily // // This class is a ViewKit user interface "component". // For more information on how components are used, see the // "ViewKit Programmers' Manual", and the RapidApp // User's Guide. ///////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Checkpoint.h" #include "Cview.h" #include #include #include #include #include #include #include #include #include #include #include #include #include extern void VkUnimplemented ( Widget, const char * ); /////////////////////////////////////////////////////////////////////////////// // The following non-container elements are created by CheckpointUI and are // available as protected data members inherited by this class // // XmList _psList // XmLabel _label1 // XmSeparator _separator1 // XmPushButton _but_ps // SgFinder _finderUid // VkOptionMenu * _idMenu // VkMenuItem * _opt_pid // VkMenuItem * _opt_gid // VkMenuItem * _opt_sid // VkMenuItem * _opt_ash // VkMenuItem * _opt_hid // VkMenuItem * _opt_sgp // SgFinder _finderStatef // XmLabel _label2 // XmSeparator _separator2 // XmPushButton _but_file // VkOptionMenu * _fileMenu // VkMenuItem * _opt_merge // VkMenuItem * _opt_ignore // VkMenuItem * _opt_append // VkMenuItem * _opt_replace // VkMenuItem * _opt_substitute // XmList _fileList // XmSeparator _separator3 // XmPushButton _but_ok // VkOptionMenu * _willMenu // VkMenuItem * _exit // VkMenuItem * _cont // XmLabel _pstitle // XmPushButton _but_abort // XmToggleButton _tog_upgrade // /////////////////////////////////////////////////////////////////////////////// //---- Start editable code block: headers and declarations #define PATH_PROCFS "/proc/pinfo" //---- End editable code block: headers and declarations //---- Checkpoint Constructor Checkpoint::Checkpoint(const char *name, Widget parent) : CheckpointUI(name, parent) { // This constructor calls CheckpointUI(parent, name) // which calls CheckpointUI::create() to create // the widgets for this component. Any code added here // is called after the component's interface has been built //---- Start editable code block: Checkpoint constructor CkptNumOpenfiles = CkptOpenfilesSelectBegin = CkptOpenfilesSelectEnd = 0; CkptPsLine[0] = CkptID[0] = CkptPath[0] = CkptUser[0] = 0; CkptType = 0; CkptFlags = 0; CkptWaiter = 0; getpasswd(); SgFinderSetTextString(_finderUid, finduname(getuid())); //---- End editable code block: Checkpoint constructor } // End Constructor Checkpoint::Checkpoint(const char *name) : CheckpointUI(name) { // This constructor calls CheckpointUI(name) // which does not create any widgets. Usually, this // constructor is not used //---- Start editable code block: Checkpoint constructor 2 //---- End editable code block: Checkpoint constructor 2 } // End Constructor Checkpoint::~Checkpoint() { // The base class destructors are responsible for // destroying all widgets and objects used in this component. // Only additional items created directly in this class // need to be freed here. //---- Start editable code block: Checkpoint destructor //---- End editable code block: Checkpoint destructor } // End Destructor const char * Checkpoint::className() // classname { return ("Checkpoint"); } // End className() void Checkpoint::cv_abort ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint cv_abort XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) callData; if (CkptWaiter == 0) { printf("Nothing to abort\n"); return; } kill(CkptWaiter, SIGABRT); if (unblockproc(CkptWaiter)) { perror("Failed to unblockproc"); kill(CkptWaiter, SIGKILL); } CkptWaiter = 0; //---- End editable code block: Checkpoint cv_abort } // End Checkpoint::cv_abort() void Checkpoint::cv_file ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint cv_file XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) callData; int i, pfd[2]; char buf[CPATHLEN]; XmString *display; int stat; // Clear the file display if (callData == NULL) { XtVaSetValues(w, XmNitems, NULL, XmNitemCount, 0, NULL); return; } if (ckpt_prepare_checkpoint()) return; if (pipe(pfd) < 0) { perror("Failed to open pipe"); return; } if ((CkptWaiter = fork()) == 0) { char s_id[PSARGSZ]; char pipe_str[16]; // signal(SIGCHLD, SIG_DFL); sprintf(s_id, "%s:%s", CkptID, ckpt_type_str(CkptType)); //printf("CkptType=%d (%s)\n", CkptType, ckpt_type_str(CkptType)); sprintf(pipe_str, "%d", pfd[1]); printf("cpr -c %s -p %s\n", CkptPath, s_id); if (CkptFlags & CKPT_CHECKPOINT_UPGRADE) execl(CPR, CPR, "-c", CkptPath, "-p", s_id, "-U", "-S", "-P", pipe_str, 0); else execl(CPR, CPR, "-c", CkptPath, "-p", s_id, "-S", "-P", pipe_str, 0); fprintf(stderr, "Failed to checkpoint (%s)\n", STRERR); close(pfd[0]); close(pfd[1]); CkptWaiter = 0; return; } close(pfd[1]); if (read(pfd[0], buf, sizeof(buf)) < 0) { perror("Failed to read"); CkptWaiter = 0; return; } // If cpr fails, abort reading as well if (buf[0] == NULL) { close(pfd[0]); kill(CkptWaiter, SIGABRT); wait(&stat); CkptWaiter = 0; return; } // printf("Number of Openfiles: %s\n", buf); CkptNumOpenfiles = atoi(buf); free(CkptOpenfiles); CkptOpenfiles = (char *)malloc(CkptNumOpenfiles*sizeof(char)*CPATHLEN); display = (XmString *)malloc(CkptNumOpenfiles*sizeof(XmString)); i = 0; while (read(pfd[0], CkptOpenfiles+i*CPATHLEN, CPATHLEN) > 0) { if (!strcmp(CkptOpenfiles+i*CPATHLEN, CKPT_GUI_SYNC_POINT)) break; display[i++] = XmStringCreateLocalized(CkptOpenfiles+i*CPATHLEN); } CkptNumOpenfiles = i; XtVaSetValues(w, XmNitems, display, XmNitemCount, CkptNumOpenfiles, NULL); free(display); close(pfd[0]); //---- End editable code block: Checkpoint cv_file } // End Checkpoint::cv_file() void Checkpoint::cv_upgrade ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint cv_upgrade XmToggleButtonCallbackStruct *cbs = (XmToggleButtonCallbackStruct*) callData; static char select = 0; if (select == 0) { CkptFlags |= CKPT_CHECKPOINT_UPGRADE; select = 1; } else { CkptFlags &= ~CKPT_CHECKPOINT_UPGRADE; select = 0; } //---- End editable code block: Checkpoint cv_upgrade } // End Checkpoint::cv_upgrade() void Checkpoint::cv_ok ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint cv_ok XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) callData; int stat, i; char attrfile[CPATHLEN]; char buf[64]; int fd; // If user didn't ask to change the options, checkpoint now if (CkptWaiter == 0) { if (ckpt_prepare_checkpoint()) return; if ((CkptWaiter = fork()) == 0) { char s_id[PSARGSZ]; sprintf(s_id, "%s:%s", CkptID, ckpt_type_str(CkptType)); // printf("CkptType=%d\n", CkptType); if (CkptFlags & CKPT_CHECKPOINT_UPGRADE) execl(CPR, CPR, "-c", CkptPath, "-p", s_id, "-U", 0); else execl(CPR, CPR, "-c", CkptPath, "-p", s_id, 0); fprintf(stderr, "Failed to checkpoint (%s)\n", STRERR); } wait(&stat); CkptWaiter = 0; return; } // Otherwise, save the new options // write out to CKPT_ATTRFILE_GUI sprintf(attrfile, "%s.%d.%s", CKPT_ATTRFILE_GUI, getuid(), CkptID); unlink(attrfile); // clean up left-overs if ((fd = open(attrfile, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) { perror("Failed to open"); kill(CkptWaiter, SIGABRT); CkptWaiter = 0; return; } sprintf(buf, "CKPT %s %s {\n", ckpt_type_str(CkptType), CkptID); write(fd, buf, strlen(buf)); // Create a priority attribute file in /tmp for (i = 0; i < CkptNumOpenfiles; i++) { char *p; p = (char *)(CkptOpenfiles + i * CPATHLEN); if (*p != '*') continue; FINDSPACE(p); /* skip PID */ SKIPSPACE(p); FINDSPACE(p); /* skip PID # */ SKIPSPACE(p); FINDSPACE(p); /* skip FD */ SKIPSPACE(p); FINDSPACE(p); /* skip FD number */ SKIPSPACE(p); write(fd, "\t", 1); write(fd, p, strlen(p)); write(fd, "\n", 1); } // Write out WILL option to be non-default (continue) if (CkptWill) { sprintf(buf, "\t%s\n", CkptWill); write(fd, buf, strlen(buf)); } write(fd, "}\n", 2); if (unblockproc(CkptWaiter)) { perror("Failed to unblockproc"); kill(CkptWaiter, SIGKILL); } wait(&stat); close(fd); // keep the file excl opened until restart has read it CkptWaiter = 0; //---- End editable code block: Checkpoint cv_ok } // End Checkpoint::cv_ok() /* Pointer to user data */ struct udata *ud; static int nud = 0; /* number of valid ud structures */ static int maxud = 0; /* number of ud's allocated */ void getpasswd() { struct passwd *pw; ud = NULL; nud = 0; maxud = 0; while ((pw = getpwent()) != NULL) { while (nud >= maxud) { maxud += UDQ; ud = (struct udata *) ((ud == NULL) ? malloc(sizeof(struct udata ) * maxud) : realloc(ud, sizeof(struct udata ) * maxud)); if (ud == NULL) { perror("malloc"); endpwent(); return; } } /* * Copy fields from pw file structure to udata. */ ud[nud].uid = pw->pw_uid; (void) strncpy(ud[nud].name, pw->pw_name, MAXLOGIN); nud++; } endpwent(); } char * finduname(register uid_t uid) { register uid_t i; for (i = 0; i < nud; i++) if (ud[i].uid == uid) return (ud[i].name); return (0); } void Checkpoint::cv_ps ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint cv_ps XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) callData; int n; char buf[128]; struct direct *direct; DIR *dirp; int procfd; char dir[64]; static XmString *linePtrs; static int numString = 0; if ((dirp = opendir(PATH_PROCFS)) == NULL) { fprintf(stderr,"Cannot open /proc/pinfo directory (%s)\n", STRERR); return; } for (n = 0; n < numString; n++) XmStringFree(linePtrs[n]); free(linePtrs); numString = 0; while (direct = readdir(dirp)) { if (!strcmp(direct->d_name, ".") || !strcmp(direct->d_name, "..")) continue; numString++; } getpasswd(); linePtrs = (XmString *)malloc(numString*sizeof(XmString)); n = 0; rewinddir(dirp); while ((direct = readdir(dirp)) && n < numString) { struct prpsinfo info; struct prcred cred; ostrstream line; char *lineStr; ash_t ash; if (!strcmp(direct->d_name, ".") || !strcmp(direct->d_name, "..")) continue; sprintf(dir, "%s/%s", PATH_PROCFS, direct->d_name); if ((procfd = open(dir, O_RDONLY)) == -1) { fprintf(stderr, "Cannot open %s (%s)\n", dir, STRERR); continue; } if (ioctl(procfd, PIOCPSINFO, (char *) &info) == -1) { fprintf(stderr, "Cannot read psinfo for %s (%s)\n", dir, STRERR); close(procfd); continue; } if (CkptUser[0] != 0 && strcmp(CkptUser, finduname(info.pr_uid))) { close(procfd); continue; } if (syssgi(SGI_GETASH, info.pr_pid, &ash)) { // perror("Failed to read ASH"); ash = 0; } sprintf(buf, "%9s %5d %5d %5d %5d 0x%016llx %.50s\n", finduname(info.pr_uid), info.pr_pid, info.pr_ppid, info.pr_pgrp, info.pr_sid, ash, info.pr_psargs); line << buf; lineStr = line.str(); linePtrs[n++] = XmStringCreateLocalized(lineStr); close(procfd); } closedir(dirp); XtVaSetValues(w, XmNitems, linePtrs, XmNitemCount, n, NULL); numString = n; //---- End editable code block: Checkpoint cv_ps } // End Checkpoint::cv_ps() void Checkpoint::cv_select ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint cv_select int i; XmListCallbackStruct *cbs = (XmListCallbackStruct*) callData; CkptOpenfilesSelectBegin = *cbs->selected_item_positions - 1; CkptOpenfilesSelectEnd = CkptOpenfilesSelectBegin + cbs->selected_item_count - 1; // printf("Begin=%d End=%d\n", CkptOpenfilesSelectBegin, CkptOpenfilesSelectEnd); //---- End editable code block: Checkpoint cv_select } // End Checkpoint::cv_select() void Checkpoint::cv_select_one ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint cv_select_one XmListCallbackStruct *cbs = (XmListCallbackStruct*) callData; char *p; int i; // read and decode a ps line p = (char *)cbs->item; i = 0; FINDSPACE(p); /* skip locale */ SKIPSPACE(p); strncpy(CkptPsLine, p, 128); // If someone selects a ps line again before hitting step III, abort if (CkptWaiter) { kill(CkptWaiter, SIGABRT); unblockproc(CkptWaiter); CkptWaiter = 0; } //---- End editable code block: Checkpoint cv_select_one } // End Checkpoint::cv_select_one() int Checkpoint::ckpt_prepare_checkpoint (void) { char *p; int i = 0; // ignore if we have started checkpoint if (CkptWaiter) { printf("There is one checkpoint process %d running. Please try again.\n", CkptWaiter); return (-1); } if (CkptPath[0] == 0) { printf("Please specify your statefile name\n"); return (-1);; } if (CkptPsLine[0] == 0) { printf("Please select your checkpoint target\n"); return (-1); } p = CkptPsLine; FINDSPACE(p); /* skip user */ SKIPSPACE(p); if (CkptType == CKPT_PROCESS || CkptType == CKPT_HIERARCHY || CkptType == CKPT_SGROUP) goto loadid; FINDSPACE(p); /* skip pid */ SKIPSPACE(p); FINDSPACE(p); /* skip ppid */ SKIPSPACE(p); if (CkptType == CKPT_PGROUP) goto loadid; FINDSPACE(p); /* skip pgid */ SKIPSPACE(p); if (CkptType == CKPT_SESSION) goto loadid; FINDSPACE(p); /* skip sid */ SKIPSPACE(p); if (CkptType == CKPT_ARSESSION) goto loadid; loadid: while (!SPACE(*p)) CkptID[i++] = *(p++); CkptID[i] = 0; // printf("Decoded CkptID=%s\n", CkptID); return (0); //---- End editable code block: Checkpoint cv_select_one } // End Checkpoint::cv_select_one() void Checkpoint::cv_statef ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint cv_statef XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct*) callData; char *p; int i = 0; p = SgFinderGetTextString(w); while (SPACE(*(p+i)) && !ISEND(*(p+i))) i++; strcpy(CkptPath, p+i); XtFree(p); printf("Using statefile: %s\n", CkptPath); //---- End editable code block: Checkpoint cv_statef } // End Checkpoint::cv_statef() void Checkpoint::cv_statef_change ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint cv_statef_change XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct*) callData; char *p; int i = 0; p = SgFinderGetTextString(w); while (SPACE(*(p+i)) && !ISEND(*(p+i))) i++; strcpy(CkptPath, p+i); XtFree(p); } // End Checkpoint::cv_statef_change() void Checkpoint::cv_uid ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint cv_uid XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct*) callData; char *p = SgFinderGetTextString(w); int i = 0; while (SPACE(*(p+i)) && !ISEND(*(p+i))) i++; strcpy(CkptUser, p+i); XtFree(p); //---- End editable code block: Checkpoint cv_statef_change } // End Checkpoint::cv_uid() void Checkpoint::cv_uid_change ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint cv_uid_change XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct*) callData; char *p = SgFinderGetTextString(w); int i = 0; while (SPACE(*(p+i)) && !ISEND(*(p+i))) i++; strcpy(CkptUser, p+i); XtFree(p); //---- End editable code block: Checkpoint cv_uid_change } // End Checkpoint::cv_uid_change() void Checkpoint::doCont ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint doCont XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) callData; sprintf(CkptWill, "WILL: CONTINUE"); //---- End editable code block: Checkpoint doCont } // End Checkpoint::doCont() void Checkpoint::doExit ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint doExit XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) callData; CkptWill[0] = 0; //---- End editable code block: Checkpoint doExit } // End Checkpoint::doExit() void Checkpoint::doOpt_append ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint doOpt_append XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) callData; ckpt_change_file_disposition(w, "APPEND"); //---- End editable code block: Checkpoint doOpt_append } // End Checkpoint::doOpt_append() void Checkpoint::doOpt_ash ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint doOpt_ash XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) callData; CkptType = CKPT_ARSESSION; //---- End editable code block: Checkpoint doOpt_ash } // End Checkpoint::doOpt_ash() void Checkpoint::doOpt_gid ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint doOpt_gid XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) callData; CkptType = CKPT_PGROUP; //---- End editable code block: Checkpoint doOpt_gid } // End Checkpoint::doOpt_gid() void Checkpoint::doOpt_hid ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint doOpt_hid XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) callData; CkptType = CKPT_HIERARCHY; //---- End editable code block: Checkpoint doOpt_hid } // End Checkpoint::doOpt_hid() void Checkpoint::ckpt_change_file_disposition(Widget w, char *mode) { XmString *display; int i; //printf("Being=%d End=%d\n", CkptOpenfilesSelectBegin, CkptOpenfilesSelectEnd); if ((CkptOpenfilesSelectEnd - CkptOpenfilesSelectBegin) < 0) return; if(CkptOpenfiles == NULL) return; for (i = CkptOpenfilesSelectBegin; i <= CkptOpenfilesSelectEnd; i++) { char *p; p = (char *)(CkptOpenfiles + i * CPATHLEN); *p = '*'; /* mark it changed */ FINDSPACE(p); /* skip PID */ SKIPSPACE(p); FINDSPACE(p); /* skip PID # */ SKIPSPACE(p); FINDSPACE(p); /* skip FD */ SKIPSPACE(p); FINDSPACE(p); /* skip FD number */ SKIPSPACE(p); FINDSPACE(p); /* skip FILE: */ SKIPSPACE(p); FINDSPACE(p); /* skip "...": */ SKIPSPACE(p); strcpy(p, mode); // printf("New item %d: %s\n", i, (CkptOpenfiles + i * CPATHLEN)); } display = (XmString *)malloc(CkptNumOpenfiles*sizeof(XmString)); for (i = 0; i < CkptNumOpenfiles; i++) { display[i] = XmStringCreateLocalized(CkptOpenfiles+i*CPATHLEN); } XtVaSetValues(w, XmNitems, display, XmNitemCount, CkptNumOpenfiles, NULL); free(display); } void Checkpoint::doOpt_ignore ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint doOpt_ignore XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) callData; ckpt_change_file_disposition(w, "IGNORE"); //---- End editable code block: Checkpoint doOpt_ignore } // End Checkpoint::doOpt_ignore() void Checkpoint::doOpt_merge ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint doOpt_merge XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) callData; ckpt_change_file_disposition(w, "MERGE"); //---- End editable code block: Checkpoint doOpt_merge } // End Checkpoint::doOpt_merge() void Checkpoint::doOpt_pid ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint doOpt_pid XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) callData; CkptType = CKPT_PROCESS; //---- End editable code block: Checkpoint doOpt_pid } // End Checkpoint::doOpt_pid() void Checkpoint::doOpt_replace ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint doOpt_replace XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) callData; ckpt_change_file_disposition(w, "REPLACE"); //---- End editable code block: Checkpoint doOpt_replace } // End Checkpoint::doOpt_replace() void Checkpoint::doOpt_sgp ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint doOpt_sgp XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) callData; CkptType = CKPT_SGROUP; //---- End editable code block: Checkpoint doOpt_sgp } // End Checkpoint::doOpt_sgp() void Checkpoint::doOpt_sid ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint doOpt_sid XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) callData; CkptType = CKPT_SESSION; //---- End editable code block: Checkpoint doOpt_sid } // End Checkpoint::doOpt_sid() void Checkpoint::doOpt_substitute ( Widget w, XtPointer callData ) { //---- Start editable code block: Checkpoint doOpt_substitute XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) callData; ckpt_change_file_disposition(w, "SUBSTITUTE"); //---- End editable code block: Checkpoint doOpt_substitute } // End Checkpoint::doOpt_substitute() /////////////////////////////////////////////////////////////////// // static creation function, for importing class into rapidapp // or dynamically loading, using VkComponent::loadComponent /////////////////////////////////////////////////////////////////// VkComponent *Checkpoint::CreateCheckpoint( const char *name, Widget parent ) { VkComponent *obj = new Checkpoint ( name, parent ); return ( obj ); } // End CreateCheckpoint /////////////////////////////////////////////////////////////////// // Function for accessing a description of the dynamic interface // to this class. /////////////////////////////////////////////////////////////////// // WARNING: This structure is different than that used with 1.1 RapidApp. // See the RapidApp release notes for details struct InterfaceMap { char *resourceName; char *methodName; char *argType; char *definingClass; // Optional, if not this class void (VkCallbackObject::*method)(...); // Reserved, do not set }; void *Checkpoint::RegisterCheckpointInterface() { // This structure registers information about this class // that allows RapidApp to create and manipulate an instance. // Each entry provides a resource name that will appear in the // resource manager palette when an instance of this class is // selected, the name of the member function as a string, // the type of the single argument to this function, and an. // optional argument indicating the class that defines this function. // All member functions must have the form // // void memberFunction ( Type ); // // where "Type" is one of: // const char * (Use XmRString) // Boolean (Use XmRBoolean) // int (Use XmRInt) // float (Use XmRFloat) // No argument (Use VkRNoArg or "NoArg" // A filename (Use VkRFilename or "Filename") // An enumeration (Use "Enumeration:ClassName:Type: VALUE1, VALUE2, VALUE3") // A callback (Use XmRCallback) static InterfaceMap map[] = { //---- Start editable code block: CheckpointUI resource table // { "resourceName", "setAttribute", XmRString}, //---- End editable code block: CheckpointUI resource table { NULL }, // MUST be NULL terminated }; return map; } // End RegisterCheckpointInterface() //---- End of generated code //---- Start editable code block: End of generated code //---- End editable code block: End of generated code