Permission is hereby granted to copy this document without modification.
An architecture independent messaging protocol is utilized so that client applications may connect to NExS spreadsheets running on any of the supported operating systems and hardware platforms. For example, a client application running on VAX/VMS or CRAY/UNICOS may connect to and exchange data with an NExS spreadsheet running on a SPARCstation under Unix. The only prerequisites for creating a client application which utilizes the NExS connection library are a C or Fortran compiler and the X11 (release 3 or higher) object library.
Another significant aspect of conformance is that the Fortran 77 standard doesn't support structures. Structure references occur at several places in the C interface to the library. The most important place is in passing and returning arguments to and from NExS remote functions. A special set of Fortran calls has been designed to provide this functionality without violating the standard. The only library functions which have no Fortran interface are those few which reference X Window structures directly. However, these calls are only useful if your Fortran program itself is directly calling X. In that case your Fortran compiler must include extensions to support structures and long identifiers, which means you can call the C interface routines from Fortran directly.
Called once at startup to initialize the connection mechanism. The dp parameter is a pointer to the Display structure for the X server on which the connection to NExS is to take place. Simple (non-X) clients usually do not call this procedure directly (see nexs_open_connection).
FORTRAN equivalent:
There is no Fortran equivalent to this function since the Fortran 77 standard does not support structures. Some Fortran compilers include extensions which provide support for structures, in which case a program may call nexs_connect_init directly. Consult the Fortran manual for your workstation to see if this is possible.
Attempts to establish a connection to an NExS spreadsheet opened on the X server defined by the call to nexs_connect_init. The "name" parameter is a mnemonic identifier for the connection. "Name" may be up to 10 characters in length. If NExS is not running, or is not currently accepting connections, the value 0 will be returned after the specified "timeout" period (in seconds). If the connection to NExS is established, a port ID in the range 1 to MAX_PORTS will be returned. (Note: Multiple connections to NExS may be opened from a single connection client, each of which may "talk" to a different instance of NExS running on the same server. Connections across multiple X servers are not currently supported.)
FORTRAN equivalent:
function ixsestc(name, timeout) character *(*) name integer timeout
A convenience routine which opens a connection to the default X server (defined on UNIX systems by the DISPLAY environment variable), calls nexs_connect_init, and then calls nexs_establish_connection. Returns a port ID in the range 1 to MAX_PORTS if successful; 0 otherwise.
FORTRAN equivalent:
function ixsopen(name, timeout) character *(*) name integer timeout
Establishes a call-back procedure "close_fn" which is invoked in the event that the NExS connection is closed from the other end (i.e., NExS exits unexpectedly). This allows orderly clean-up on the client side if necessary.
FORTRAN equivalent:
subroutine xssetcn(close_fn) external close_fn
Closes the specified connection to NExS.
FORTRAN equivalent:
subroutine xsclose(port) integer port
Returns 1 if there is a live connection on the specified port; 0 otherwise. Clients which do not continuously listen to the X11 server through nexs_dispatcher or a client supplied event loop should generally call nexs_test connection() before sending data to make sure that NExS has not been closed by the user. For clients which do listen to the X server, setting up a "close notify" callback should be used instead. (See "nexs_set_close_notify().")
Reads the current "value" of the cell in the specified "row" and "col" of the NExS spreadsheet connected to "port". Returns NEXS_NUMBER (1) if a value was read, NEXS_STRING (2) if a string was read, or NEXS_EMPTY (0) if the specified cell is empty or the connection to nexs was lost. At most one of "value" or "string" are affected by this call. If the result is NEXS_STRING, the client is responsible for freeing the string when it is no longer needed. (Note: NExS row indices are 1 through 9999. NExS column indices are 0 through 701; column A is 0, column ZZ is 701.)
FORTRAN equivalent:
function ixsvget(port, row, col, value, string) integer port, row, col real*8 value character*(*) string
(Fortran programs should not free the "string" argument. The actual string returned to the Fortran caller will be truncated to the declared length of the "string" parameter if necessary.)
Reads the string value of the specified cell. The string read is the formatted contents of the cell (even if it contains a number). If the cell is empty, a null string is read and NEXS_EMPTY is returned. Otherwise, NEXS_STRING is returned. The client is responsible for freeing the string when it is no longer needed.
FORTRAN equivalent:
function ixssget(port, row, col, string) integer port, row, col character*(*) string
(Fortran programs should not free the "string" argument. The actual string returned to the Fortran caller will be truncated to the declared length of the "string" parameter if necessary.)
Reads the numeric value of the specified cell. If the cell contains a numeric formula or constant, it is assigned to "value" and NEXS_NUMBER is returned. Otherwise, "value" is set to zero and NEXS_EMPTY is returned.
FORTRAN equivalent:
function ixsnget(port, row, col, value) integer port, row, col real*8 value
Retrieves up to 255 numeric values from the specified "range", starting at the cell specified by "start_row" and "start_col". For each cell containing a numeric value, the cell's row, column and current value will be recorded in "xsvbuf" structure array. (See "nexs.h" for details of the XSValBuf structure.) The number of values retrieved is returned in "count". If count equals 255, the buffer is full and another call to nexs_get_numbers() should be made after adjusting "start_row" and "start_col". The cells are retrieved in column-major order, so the proper adjustment for "start_row" and "start_col" to perform a subsequent scan is:
start_col = xsvbuf[count-1].col; start_row = xsvbuf[count-1].row + 1;
This function is much faster than repeated calls to nexs_get_number for retrieving large blocks of data from the spreadsheet. The function return value is set to 1 if the call is successful; 0 otherwise.
FORTRAN equivalent:
function ixsnsget(port, rmin, cmin, rmax, cmax, rstart, cstart, + rbuf, cbuf, vbuf, count) integer port, rmin, cmin, rmax, cmax, rstart, cstart, count integer rbuf(255), cbuf(255) real*8 vbuf(255)
Reads the formula or label stored in the specified cell. Returns NEXS_FORMULA if a numeric or string formula was read, NEXS_LABEL if a label was read, or NEXS_EMPTY if the cell is empty. If NEXS_EMPTY is returned, "string" is not assigned. Otherwise, the client is responsible for freeing the string when it is no longer needed.
FORTRAN equivalent:
function ixsfget(port, row, col, string) integer port, row, col character*(*) string
(Fortran programs should not free the "string" argument. The actual string returned to the Fortran caller will be truncated to the declared length of the "string" parameter if necessary.)
Stores "value" in the specified "row" and "col" of the NExS spreadsheet connected to "port".
FORTRAN equivalent:
subroutine xsnstore(port, row, col, value) integer port, row, col real*8 value
Stores the string "s" in the specified "row" and "col" of the NExSs spreadsheet connected to "port". If the first character of "s" is ', ", or ^, the string is left, right, or center justified, respectively. Otherwise it is justified according to the current NExS default.
FORTRAN equivalent:
subroutine xslstore(port, row, col, label) integer port, row, col character*(*) label
Stores the NExS formula contained in the string "formula" in the specified cell. (Note: In beta release 1.0A, "formula" must be syntactically correct or NExS will crash.)
FORTRAN equivalent:
subroutine xsfstore(port, row, col, formula) integer port, row, col character*(*) formula
Like nexs_store_number(), but overrides the default cell format. The font is specified by "fnt_code," the cell format is specified by "fmt_code," and the number of decimal places is specified by "places." Possible values for "fnt_code" and "fmt_code" are found in "nexs.h". "Places" must be in the range 0 to 15.
FORTRAN equivalent:
subroutine xsnfstore(port, row, col, value, fntcode, fmtcode, places) integer port, row, col, fntcode, fmtcode, places real*8 value
Like nexs_store_number(), but tags the number with a reference to "nexs_row" and "nexs_col" (see Client @-Functions). This function is specifically for use in implementing remote embedded tools.
FORTRAN equivalent:
subroutine xsntstore(port, row, col, value) integer port, row, col real*8 value
This function is similar to nexs_store_tagged_number(), except that it stores a tagged string value in the cell specified by "row, col". This function is specifically for use in remote embedded tools which return strings.
Example:
Operand myfunc(Operand argv[]) /* remote embedded tool which returns string */ { char *s1, *s2; /* two strings to be returned by the embedded tool */ Operand op; /* Body of function goes here... */ /* Copy the 1st return string into nexs_sbuf. */ strcpy(nexs_sbuf, s1); /* Store the 2nd return string as a tagged value in the cell immediately below the current one. */ nexs_store_tagged_string(nexs_port, nexs_row+1, nexs_col, s2); /* Set the return type and return... */ op.type = ARG_STRING; return op; }
Prints a NExS I/O error number and then exits the connection function that caused the error.
FORTRAN equivalent:
NONE.
Prints a NExS I/O error message pointed to by "msg" and then exits the connection function that caused the error.
FORTRAN equivalent:
NONE.
Converts a NExS row,column pair into a text string like "A5". (Note: NExS row indices are 1 through 9999. NExS column indices are 0 through 701; column A is 0, column ZZ is 701.)
FORTRAN equivalent:
NONE.
Prints an error message relating to operand "op" that was passed to the connection function. The error message is displayed using a printf-like format.
FORTRAN equivalent:
NONE.
Returns the number of cells in operand[selector].
FORTRAN equivalent:
NONE.
Opens a connection to NExS with the name "connection_name" and waits up to "wait_before_failure" seconds before giving up. If a connection is made, it checks to make sure the connection is made with NExS and not some other spreadsheet.
FORTRAN equivalent:
NONE.
Extracts a submatrix of cells bounded by rows "r0", "r1" and columns "c0", "c1" from the source operand. The cells are stored into the destination operand.
FORTRAN equivalent:
NONE.
Gets the single number value of "operand" from the NExS spreadsheet.
FORTRAN equivalent:
NONE.
Stores the single number s into the operand "range" of the NExS spreadsheet.
FORTRAN equivalent:
NONE.
Gets the single string of the operand from the NExS spreadsheet.
FORTRAN equivalent:
NONE.
Frees the storage used by the string s.
FORTRAN equivalent:
NONE.
Stores the single string s into the operand of the NExS spreadsheet.
FORTRAN equivalent:
NONE.
Frees the storage of a vector of integers.
FORTRAN equivalent:
NONE.
Frees the storage of a matrix of integers.
FORTRAN equivalent:
NONE.
Creates a vector of integers.
FORTRAN equivalent:
NONE.
Resizes a vector of integers.
FORTRAN equivalent:
NONE.
Creates a matrix of integers.
FORTRAN equivalent:
NONE.
Allocates storage large enough to hold the integer vector from the NExS spreadsheet pointed to by Operand range.
FORTRAN equivalent:
NONE.
Allocates storage large enough to hold the integer matrix from the NExS spreadsheet pointed to by Operand range.
FORTRAN equivalent:
NONE.
Allocates storage large enough to hold the integer vector from the NExS spreadsheet pointed to by Operand range and reads the integers from the spreadsheet into the vector.
FORTRAN equivalent:
NONE.
Allocates storage large enough to hold the integer matrix from the NExS spreadsheet pointed to by Operand range and reads the integers from the spreadsheet into the matrix.
FORTRAN equivalent:
NONE.
Stores the values from a vector of integers into the NExS spreadsheet at a location indicated by Operand range.
FORTRAN equivalent:
NONE.
Stores the values from a matrix of integers into the NExS spreadsheet at a location indicated by Operand range.
FORTRAN equivalent:
NONE.
Frees the storage created when getting the vector of integer values from the NExS spreadsheet indicated by Operand range.
FORTRAN equivalent:
NONE.
Frees the storage created when getting the matrix of integer values from the NExS spreadsheet indicated by Operand range.
FORTRAN equivalent:
NONE.
Frees the storage of a vector of floats.
FORTRAN equivalent:
NONE.
Frees the storage of a matrix of floats.
FORTRAN equivalent:
NONE.
Creates a vector of floats.
FORTRAN equivalent:
NONE.
Resizes a vector of floats.
FORTRAN equivalent:
NONE.
Creates a matrix of floats.
FORTRAN equivalent:
NONE.
Allocates storage large enough to hold the float vector from the NExS spreadsheet pointed to by Operand range.
FORTRAN equivalent:
NONE.
Allocates storage large enough to hold the float matrix from the NExS spreadsheet pointed to by Operand range.
FORTRAN equivalent:
NONE.
Allocates storage large enough to hold the float vector from the NExS spreadsheet pointed to by Operand range and reads the floats from the spreadsheet into the vector.
FORTRAN equivalent:
NONE.
Allocates storage large enough to hold the float matrix from the NExS spreadsheet pointed to by Operand range and reads the floats from the spreadsheet into the matrix.
FORTRAN equivalent:
NONE.
Stores the values from a vector of floats into the NExS spreadsheet at a location indicated by Operand range.
FORTRAN equivalent:
NONE.
Stores the values from a matrix of floats into the NExS spreadsheet at a location indicated by Operand range.
FORTRAN equivalent:
NONE.
Frees the storage created when getting the vector of float values from the NExS spreadsheet indicated by Operand range.
FORTRAN equivalent:
NONE.
Frees the storage created when getting the matrix of float values from the NExS spreadsheet indicated by Operand range.
FORTRAN equivalent:
NONE.
Frees the storage of a vector of doubles.
FORTRAN equivalent:
NONE.
Frees the storage of a matrix of doubles.
FORTRAN equivalent:
NONE.
Creates a vector of doubles.
FORTRAN equivalent:
NONE.
Resizes a vector of doubles.
FORTRAN equivalent:
NONE.
Creates a matrix of doubles.
FORTRAN equivalent:
NONE.
Allocates storage large enough to hold the double vector from the NExS spreadsheet pointed to by Operand range.
FORTRAN equivalent:
NONE.
Allocates storage large enough to hold the double matrix from the NExS spreadsheet pointed to by Operand range.
FORTRAN equivalent:
NONE.
Allocates storage large enough to hold the double vector from the NExS spreadsheet pointed to by Operand range and reads the doubles from the spreadsheet into the vector.
FORTRAN equivalent:
NONE.
Allocates storage large enough to hold the double matrix from the NExS spreadsheet pointed to by Operand range and reads the doubles from the spreadsheet into the matrix.
FORTRAN equivalent:
NONE.
Stores the values from a vector of doubles into the NExS spreadsheet at a location indicated by Operand range.
FORTRAN equivalent:
NONE.
Stores the values from a matrix of doubles into the NExS spreadsheet at a location indicated by Operand range.
FORTRAN equivalent:
NONE.
Frees the storage created when getting the vector of double values from the NExS spreadsheet indicated by Operand range.
FORTRAN equivalent:
NONE.
Frees the storage created when getting the matrix of double values from the NExS spreadsheet indicated by Operand range.
FORTRAN equivalent:
NONE.
Creates a vector of string pointers.
FORTRAN equivalent:
NONE.
Creates a matrix of string pointers.
FORTRAN equivalent:
NONE.
Frees a vector of string pointers.
FORTRAN equivalent:
NONE.
Frees a matrix of string pointers.
FORTRAN equivalent:
NONE.
Allocates storage large enough to hold the string vector from the NExS spreadsheet pointed to by Operand range.
FORTRAN equivalent:
NONE.
Allocates storage large enough to hold the string matrix from the NExS spreadsheet pointed to by Operand range.
FORTRAN equivalent:
NONE.
Allocates storage large enough to hold the string vector from the NExS spreadsheet pointed to by Operand range and reads the strings from the spreadsheet into the vector.
FORTRAN equivalent:
NONE.
Allocates storage large enough to hold the string matrix from the NExS spreadsheet pointed to by Operand range and reads the strings from the spreadsheet into the matrix.
FORTRAN equivalent:
NONE.
Stores the values from a vector of strings into the NExS spreadsheet at a location indicated by Operand range.
FORTRAN equivalent:
NONE.
Stores the values from a matrix of strings into the NExS spreadsheet at a location indicated by Operand range.
FORTRAN equivalent:
NONE.
Frees the storage created when getting the vector of strings from the NExS spreadsheet indicated by Operand range.
FORTRAN equivalent:
NONE.
Frees the storage created when getting the matrix of strings from the NExS spreadsheet indicated by Operand range.
FORTRAN equivalent:
NONE.
A spreadsheet function is responsible for calculating a result based upon its input arguments (if any). The result thus calculated then becomes the value of the cell which contains the function reference. Other than returning its result, a "normal" spreadsheet function should do nothing to change the state of the spreadsheet. NExS extends the boundaries of what a "normal" function is allowed to do with the concept of embedded tools. In addition to returning a result, an embedded tool is allowed to store "tagged data" elsewhere in the spreadsheet. "Tagged data" are numeric or string formulas which consist of a constant value followed by a backslash ("\"), followed by a reference to cell which generated them. The "tag" following the backslash serves as a means of ensuring proper recalculation order during subsequent calculations.
The advantage of embedded tools is that they provide a means for spreadsheet functions to "return" something other than a scalar. In practice, implementing embedded tools is very simple. In the example presented below, "nexs_fn" demonstrates the proper design of a remote embedded tool. This function effectively returns a vector whose first element is the sum of the arguments of NEXS3, and whose second element is two times the first. The second element is generated by the call to nexs_store_tagged_number, which automatically appends a reference to the cell containing the call to NEXS3. The first element is then returned as the value of the remote function.
Remote functions which deviate from the "normal" behavior described in the preceding paragraph should do so with care and should be very well documented. For example, it would not be considered normal for a remote function to call "nexs_goto" or "nexs_moveto." Such calls would not cause any damage to the contents of the spreadsheet, but they would most likely confuse the user considerably! Remote functions should typically not store data in other cells, except by the rules of embedded tools as described above. Remote functions should never attempt to initiate a recalculation by calling "nexs_recalc," however, they may call "nexs_evaluate_cell" and "nexs_evaluate_expr" (NExS allows one level of recursion). This makes it possible to implement remote functions which require iterative evaluation of spreadsheet formulas, such as with the built-in conditional statistical functions.
Installs a remote function in the NExS spreadsheet. The function's "name" and entry point ("callback") are specified. Remote functions are syntactically and behaviorally identical to NExS intrinsic functions. Remote function names may contain up to 127 alphanumeric characters and underscore (_) characters. Remote embedded tools may also be implemented with this mechanism. (See Client @-Functions.)
FORTRAN equivalent:
subroutine xsinsfn(port, name, cb) integer port character*(*) name external cb integer tag
Returns the current position of the NExS cursor in "*rowp" and "*colp". The value 1 is always returned, unless the port has closed unexpectedly, in which case 0 is returned.
FORTRAN equivalent:
function ixslget(port, row, col) integer port, row, col
Equivalent to a "Goto" command from the NExS utility menu. Causes the specified "row" and "col" to become the current cursor position and upper left corner of the NExS spreadsheet.
FORTRAN equivalent:
subroutine xsgoto(port, row, col) integer port, row, col
Like nexs_goto(), but does not cause the new cursor position to become the upper left corner of the spreadsheet. This function is more analogous to ordinary movement with the mouse, scrollbars, or arrow keys.
FORTRAN equivalent:
subroutine xsmovto(port, row, col) integer port, row, col
Creates a new menu which is added to the NExS menu bar. The text of the new menu is specified by "name", which may be up to 10 characters in length.
FORTRAN equivalent:
function ixscmnu(port, name) integer port character*(*) name
Creates a new button which is added to the specified menuID (returned by nexs_create_menu). The label for the button is specified by "name", which may be up to 15 characters in length. "Callback" is a client- supplied procedure that is called whenever the button is activated. "Tag" is a client-supplied integer that is passed back to the callback procedure through the connection library global variable "nexs_tag" to allow a single callback procedure to handle multiple buttons.
FORTRAN equivalent:
function ixscbtn(port, menuid, name, cb) integer port, menuid character*(*) name external cb integer tag
This function adds Motif mnemonics and/or keyboard accelerators to menu buttons created with nexs_create_button().
The "menuID" and "buttonID" parameters are the values returned by nexs_create_menu() and nexs_create_button(), respectively.
The "mnemonic" parameter sets the Motif mnemonic key for the button. It is normally a single ASCII character. The mnemonic should be chosen to be one of the characters in the name string for the button. The first occurrence of the mnemonic character in the name string will be underlined when the button is displayed. If "mnemonic" is set to 0, no mnemonic will be defined for the button.
The "accel" and "accel_text" parameters set the keyboard accelerator for the button. The "accel" string must contain a valid Motif KeyPress translation. The "accel_text" string contains the actual string that will be displayed on the button to indicate the accelerator. If either "accel" or "accel_text" is zero-length or NULL, no accelerator will be set for the button.
The function returns 1 if successful, 0 otherwise.
Examples:
/* * Create a menu named "My Menu", with a button named "My Button". */ void my_button_cb(int tag) { /* this function called when "My Button" is activated */ } long menuID, buttonID; menuID = nexs_create_menu(port, "My Menu"); buttonID = nexs_create_button(port, menuID, "My Button", my_button_cb, 0); /* * Add "B" as the mnemonic for "My Button", and Meta-b as the accelerator. */ nexs_button_accel(port, menuID, buttonID, 'B', "Meta<Key>B", "Meta-b");
Deletes the specified menu and all its associated buttons.
FORTRAN equivalent:
subroutine xsdmnu(port, menuid) integer port, menuid
Deletes the specified button on the specified menu. All other buttons on the menu (if any) remain intact.
FORTRAN equivalent:
subroutine xsdbtn(port, menuid, btnid) integer port, menuid, btnid
Enables (sensitivity = 1) or disables (sensitivity = 0) sensitivity of the specificied client menu. Menus are initially sensitive when created with nexs_create_menu(). A menu which has been set insensitive appears "greyed-out" and does not respond to mouse clicks.
Enables (sensitivity = 1) or disables (sensitivity = 0) sensitivity of the specificied button on the specified client menu. Buttons are initially sensitive when created with nexs_create_button(). A button which has been set insensitive appears "greyed-out" on the menu and does not respond to mouse clicks.
Changes the label on the specified client menu to the null-terminates string pointed to by "label." The length of the menu label is restricted to 10 characters. If the string passed is longer than 10 characters it will be truncated.
Changes the label on the specified button of the specified client menu to the null-terminates string pointed to by "label." The length of the button label is restricted to 15 characters. If the string passed is longer than 15 characters it will be truncated.
Causes the NExS spreadsheet connected to "port" to recalculate with respect to cell locations covered by the array "ranges", which is of length "n". This routine would typically be called after the client loads new data into NExS. The "force" parameter can be used to override manual recalculation mode if desired. If "force" is non-zero, recalculation will be performed regardless of the current recalculation mode setting (automatic or manual). If "n" is zero, a full recalculation is performed. (Example: a remote application uses nexs_store_number() to place data in cells A1 and A2. To recalculate only those formulas which depend on cells A1 and A2, the application should set ranges[0].r0 = 1, ranges[0].r1 = 2, ranges[0].c0 = 0, and ranges[0].c1 = 0, and then call "nexs_recalc(port, 0, 1, ranges);")
FORTRAN equivalent:
subroutine xsrcalc(port, force, n, rmin, cmin, rmax, cmax) integer port, force, n, rmin(n), cmin(n), rmax(n), cmax(n)
(Note that xsrcalc accepts four integer arrays (rmin(n), cmin(n), rmax(n), and cmax(n)) corresponding to the single Range array in nexs_recalc. If only one range is needed, arrays need not be used. For example, "call xsrecalc(port, force, 1, 1, 0, 2, 1)" will recalculate all formulas which depend on cells in the range A1..B2.)
Causes the formula in the specified cell to be evaluated without performing a recalculation of the spreadsheet. The return value is NEXS_NUMBER if evaluation of the cell produced a numeric result, in which case "value" is assigned. The return value is NEXS_STRING if if evaluation of the cell produced a string result, in which case "str" is set to point to the string result, which should be freed when it is no longer needed. The return value is NEXS_EMPTY if the target cell is empty. (Note that nexs_evaluate_cell is identical to to nexs_get_value, except that the latter does not cause the cell to be evaluated before retrieving its contents.)
FORTRAN equivalent:
function ixscleval(port, row, col, value, string) integer port, row, col real*8 value character*(*) string
(Fortran programs should not free the "string" argument. The actual string returned to the Fortran caller will be truncated to the declared length of the "string" parameter if necessary.)
Evaluates "expr" as an NExS expression. If "expr" contains one or more occurrences of the symbol '#', it will be evaluated as an NExS constraint expression. If the result of the evaluation is a number, it is stored in "value" and NEXS_NUMBER is returned. If the result is a string, it is stored in "*string" and NEXS_STRING is returned. Otherwise, 0 is returned. (If NEXS_STRING is returned, the client is responsible for freeing "*string" when it is no longer needed.)
FORTRAN equivalent:
function ixsexeval(port, expr, value, string) integer port character*(*) expr, string real*8 value
(Fortran programs should not free the "string" argument. The actual string returned to the Fortran caller will be truncated to the declared length of the "string" parameter if necessary.)
This function causes NEXS to evaluate the constraint formula attached to the specified to cell. If the cell has no constraint attached to it, or if the constraint formula evaluates "True", then 0 is returned. If the constraint formula evaluates "False" (thus indicating a constraint violation) then 1 is returned.
FORTRAN equivalent:
function ixscteval(port, row, col) integer port, row, col
This function causes NEXS to evaluate all cell constraint formulas. The return value is the total number of constraint violations which resulted.
FORTRAN equivalent:
function ixscrcalc(port) integer port
Blocks until the user selects a range on the spreadsheet. The upper left corner of the selected range is returned in *rminp and *cminp, and the lower right corner in *rmaxp and *cmaxp. The return value of the function is 1 if successful, otherwise 0.
FORTRAN equivalent:
function ixsgrng(port, rmin, cmin, rmax, cmax) integer port, rmin, cmin, rmax, cmax
Retrieves the currently selected range, or the current cell if no range is selected. The return value of the function is 1 if successful, otherwise 0. (Note: nexs_get_selected() together with nexs_get_range() allow a remote application to easily implement the select-operate-store semantics in a manner consistent with NExS intrinsic operations.)
FORTRAN equivalent:
function ixsgsel(port, rmin, cmin, rmax, cmax) integer port, rmin, cmin, rmax, cmax
Finds the range which defines the bounding box of all non-empty cells in the spreadsheet. Returns 0 if the spreadsheet is entirely empty, 1 otherwise.
FORTRAN equivalent:
function ixsgext(port, rmin, cmin, rmax, cmax) integer port, rmin, cmin, rmax, cmax
Searches the spreadsheet for an occurrence of the specified "label". If the "label" is found, 1 is returned and *rp and *cp are set to the row and column where the label was found. (Note: only one instance of "label" will be found even if multiple instances are contained in the spreadsheet.)
FORTRAN equivalent:
function ixsfl(port, label, row, col) integer port, row, col character*(*) label
Similar to nexs_find_label(), but restricts the search to the range specified by rmin, cmin, rmax, and cmax.
FORTRAN equivalent:
function ixsflir(port, label, rmin, cmin, rmax, cmax, row, col) integer port, rmin, cmin, rmax, cmax, row, col character*(*) label
Creates or redefines a range name. "Name" will be added to the NExS range name list as referring to the range specified by "*rangep". If "name" was previously defined its old definition will be lost. Returns 1 if successful, 0 otherwise.
FORTRAN equivalent:
function ixsdnam(port, rmin, cmin, rmax, cmax, flags, name) integer port, rmin, cmin, rmax, cmax, flags character*(*) name
(Note that the "rangep" argument is replaced in the Fortran interface by the arguments "rmin", "cmin", "rmax", "cmax", and "flags".)
Retrieves the current definition of "name" from the NExS range name list and stores it in "*rangep". Returns 1 if successful, 0 otherwise.
FORTRAN equivalent:
function ixsrnam(port, rmin, cmin, rmax, cmax, flags, name) integer port, rmin, cmin, rmax, cmax, flags character*(*) name
(Note that the "rangep" argument is replaced in the Fortran interface by the arguments "rmin", "cmin", "rmax", "cmax", and "flags".)
Deletes the specified "name" from the NExS range name list.
FORTRAN equivalent:
subroutine xsdlnam(port, name) integer port character*(*) name
Instantiates a Motif dialog box with with "prompt" as the prompt string, and "deflt" as the initial contents of the text widget. Only one connection may have an active NExS dialog box at any given point in time. The "callback" function is invoked when user interaction with the dialog box is completed. The "status" argument indicates how the dialog was terminated. A value of NEXS_DIALOG_BUSY (0) indicates that the dialog could not take place (most likely, there was another dialog in progress). A value of NEXS_DIALOG_OK (1) indicates that the dialog completed normally with "OK" status, and a value of NEXS_DIALOG_CANCELED (2) indicates that the dialog completed normally with "Cancel" status. The "string" passed to the callback is the contents of the dialog box if completion status was "OK", or a null string otherwise. It is the callback's responsibility to free the string when it is no longer needed. Note that nexs_dialog() is non-blocking; it does not wait for the dialog with the user to complete before returning. Execution of the callback is the only indication that the user has completed the interaction with the dialog box.
FORTRAN equivalent:
There is no Fortran equivalent to this function, due to the fact that the callback arguments are not compatible with the Fortran calling convention. Fortran connection programs may use the blocking version of this call, ixsginput, described below.
This function is identical to nexs_dialog() except that the information entered from the keyboard does not echo on the dialog box's text widget, making this dialog suitable for entering "secret" information, such as a password. Note that while the function accepts a default string, this string is invisible on the text widget.
This function causes NExS to prompt the user for input and waits until the input is returned. A Motif dialog box is instantiated, with "prompt" as the prompt string and the characters in "buf" as the initial contents of the text widget. The contents of "buf" are replaced by the contents of the dialog box's text widget when the function returns. The "maxchars" parameter indicates the maximum number of characters which should be returned, including the null terminator. A return value of NEXS_DIALOG_BUSY (0) indicates that the dialog could not take place (most likely, there was another dialog in progress). A return value of NEXS_DIALOG_OK (1) indicates that the dialog completed normally with "OK" status, and a return value of NEXS_DIALOG_CANCELED (2) indicates that the dialog completed normally with "Cancel" status. Clients which cannot afford to block while waiting for user input (i.e., X Window applications) should use nexs_dialog instead of nexs_get_input.
FORTRAN equivalent:
function ixsginput(port, prompt, buf) integer port character*(*) prompt, buf
Note that the Fortran call does not include the "maxchars" argument. Instead, the declared length of the "buf" argument is taken as the limit.
This function causes NExS to attempt to read the named file. The return value is 1 if the file was successfully read; 0 otherwise. The previous contents of the spreadsheet are lost.
FORTRAN equivalent:
function ixsread(port, name) integer port character*(*) name
This function causes NExS to attempt to write its contents to the file "name." The return value is 1 if the file was successfully written, 0 otherwise. The contents of the spreadsheet are unchanged.
FORTRAN equivalent:
function ixswrite(port, name) integer port character*(*) name
Causes the specified "range" to be printed. "Filetype" must be set to either "PRINT_ASCII" or "PRINT_PS". If "filename" is set to NULL or is zero length the output is sent directly to the printer as specified on the Printer Characteristics dialog. Otherwise the output is sent to the named file. Returns 1 if successful, 0 otherwise.
Causes NExS to attempt to import the named file. "Filetype" must be set to one of WKS_FILE (Lotus Release 1), WK1_FILE (Lotus Release 2), TEXT_FILE (plain old ASCII text), XSC_FILE (NExS Cells format), CSV_FILE (comma separated values), or TSV_FILE (tab separated values). For all file types except WKS_FILE and WK1_FILE, "r" and "c" specify the upper left corner of the import destination. Returns 1 if successful, 0 otherwise.
Causes NExS to attempt to export the named file. "Filetype" must be set to one of WKS_FILE (Lotus Release 1), WK1_FILE (Lotus Release 2), TEXT_FILE (plain old ASCII text), XSC_FILE (NExS Cells format), CSV_FILE (comma separated values), TSV_FILE (tab separated values), TEX_FILE (LaTeX 2.09 tabular format), TEX2E_FILE (LaTeX 2e tabular format), HTML_FILE (HTML 2.0 table with Netscape (R) extensions), or HTML3_FILE (HTML 3.0 table). For all file types except WKS_FILE and WK1_FILE, "range" specifies the region to be exported. Returns 1 if successful, 0 otherwise.
Clears the entire spreadsheet and returns all settable parameters to their default values. Returns 1 if successful, 0 otherwise.
Copies the specified source range "src" to the destination "dst". If "vflag" is set to zero formulas are copied; otherwise, values are copied. Expansion of the destination range and translation of relative cell and range references behave identically to copies performed from the NExS menu. Returns 1 if successful, 0 otherwise.
Erases the specified "range". Returns 1 if successful, 0 otherwise.
Moves the range "src" to the destination whose upper left corner is (r_dst, c_dst). Translation of relative cell and range references behave identically to moves performed from the NExS menu. Returns 1 if successful, 0 otherwise.
Inserts the specified number of rows starting at row number "row". Returns 1 if successful, 0 otherwise.
Inserts the specified number of columns starting at column number "col". Returns 1 if successful, 0 otherwise.
Deletes rows "start_row" through "end_row", inclusive. Returns 1 if successful, 0 otherwise.
Deletes columns "start_col" through "end_col", inclusive. Returns 1 if successful, 0 otherwise.
This function inserts a pagebreak code in the specified row. Note that this function does not handshake with NExS, and requires a call to nexs_flush() or nexs_flush_port() if used outside of an event loop. The return value is 1 if "port" is valid, 0 otherwise.
Sets the widths of columns "c0" through "c1", inclusive, to the value of the "width" argument, which must be in the range 1 to 511. If "dflag" is non-zero, the widths columns "c0" through "c1" are set to the global default value and the "width" argument is ignored. Returns 1 if successful, 0 otherwise.
(Note: NExS column widths are sized according to the currently active font. When using variable width fonts, the width of numeric digits is used for the basis of the column width; i.e., a column with width 10 is wide enough to display 10 numeric digits, but may not be wide enough to display 10 upper case `W's.)
Retrieves the current width setting for the column specified by "col". If the call is successful, the retrieved value is stored in location specified by "width". Returns 1 if successful, 0 otherwise.
Formats the specified "range". See the include file "nexs.h" for possible settings of "fmt_code". "Places" sets the number of displayed digits (if applicable) and must be in the range 0 to 15. Returns 1 if successful, 0 otherwise.
Sets the font for the specified "range". See the include file "nexs.h" for possible settings of "fnt_code". Returns 1 if successful, 0 otherwise.
Sets protection for the specified "range". If "flag" is 0, the range is unprotected; otherwise, the range is protected. Returns 1 if successful, 0 otherwise.
This function is used to set or get the attributes for a cell or range for NExS version 3.
The "attr" parameter points to a CellAttributes structure which contains attribute values to be set for all cells in "range". The attributes selected from "attr" are defined by "mask". If mask is 0, no attributes are set.
When the function returns, the "attr" structure contains all attributes of the upper left cell in "range". If the upper left cell contains some attributes which are set to default, the actual values returned in "attr" will depend on the setting of the "resolve_defaults" parameter. If "resolve_defaults" is True (i.e., non-zero), the default attributes will be resolved to their actual values.
The cell attributes that can be set or read by this function are font family, font style, font size, foreground and background color, justification, protection level, auto word wrap, underlining, format and precision. (See the header file nexs.h for definitions of all attribute and mask values.)
The function returns 1 if successful, 0 otherwise.
Examples:
/* * Set the foreground of range c3..d100 to color 3 (normally red) and * the background to color 4 (normally green). */ CellAttributes attr; Range range; text_to_range("c3..d100", &range); attr.fg = 3; attr.bg = 4; nexs_cell_attributes(port, range, &attr, NEXS_COLOR_MASK, 0); /* * Read the attributes of cell a1, resolving all default attributes. */ text_to_range("a1", &range); nexs_cell_attributes(port, range, &attr, 0, 1); /* * Set the font of cell zz1 to helvetica bold, 24 point. */ text_to_range("zz1", &range); attr.font_family = NEXS_FONT_FAMILY_HELVETICA; attr.font_style = NEXS_FONT_STYLE_BOLD; attr.font_size = NEXS_FONT_SIZE_24PT; nexs_cell_attributes(port, range, &attr, NEXS_FONT_FAMILY_MASK | NEXS_FONT_STYLE_MASK | NEXS_FONT_SIZE_MASK, 0);
Causes rows above row "r" and/or columns to the left of column "c" to become title fields. "Mode" must be set to TITLE_ROWS, TITLE_COLS, or TITLE_BOTH. Row 1 must be visible if "mode" is TITLE_ROWS or TITLE_BOTH, and column A must be visible if "mode" is TITLE_COLS or TITLE_BOTH. Returns 1 if successful, 0 otherwise.
Undoes the work of "nexs_set_titles()". "Mode" must be set to TITLE_ROWS, TITLE_COLS, or TITLE_BOTH. Returns 1 if successful, 0 otherwise.
Causes NExS to perform a "Goal Seek" operation. The cell that is to be varied during the goal seek is indicated by (vr, vc). The cell whose value is intended to match the "target" value is indicated by (tr, tc). The NExS goal seek algorithm uses the "regula falsa" (false position) method which requires the target to be bracketed, in this case by the variables "x1" and "x2". The way it works is as follows: If storing some value "x1" in cell (vr, vc) caused the value in cell (tr, tc) to be less than the value "target", and storing some other value "x2" in (vr, vc) caused the value of (tr, tc) to be greater than "target", then we say that "target" is bracketed by "x1" and "x2". Goal seek works by iteratively closing down the gap between "x1" and "x2" in such a way that the target always remains bracketed. As the gap narrows, the algorithm will eventually find a value which when stored in (vr, vc) will cause the value in (tr, tc) to be equal (within the numerical precision of the computer) to "target". Since that degree of precision is seldom required in real applications, a "tolerance" parameter is provided. The goal seek algorithm terminates when the absolute value of the difference between the value in (tr, tc) and "target" is less than or equal to "tolerance".
The NExS goal seek algorithm does not require "x1" and "x2" to bracket "target" initially. If it is determined that the target is not bracketed, the gap between "x1" and "x2" is expanded in an attempt to bracket "target". Once bracketing has been achieved, the gap is narrowed until the solution is found.
There are a few pathological cases for which goal seek can not find a solution:
To limit the work expended by goal seek in difficult or pathological cases, the parameter "maxit" will cause the algorithm to give up if a bracket can not be found within "maxit" iterations, or once a bracket is found, a solution can not be found within "maxit" iterations. Since the final values of "x1" and "x2" are returned to the calling program, a failed "nexs_goal_seek()" may be continued simply by calling it again. While most functions converge very quickly (linear functions always converge in one or two iterations, some complex functions may simply require more iterations to find a solution. The user (or programmer) must decide what action to take in the event that goal seek fails. To assist in this, "nexs_goal_seek()" provides the following return codes:
1 - success. 0 - general failure (e.g., the port has closed). less than 0 - goal seek has failed for one of the following reasons (defined in "nexs.h"): GS_FORMULA_ERR - the target cell (tr, tc) does not contain a numeric formula and therefore a solution does not exist. GS_VARIABLE_ERR - the variable cell (vr, vc) does not contain a numeric constant. GS_FP_ERR - a machine floating point error has occurred during the goal seek process, most likely indicating pathological case 3 above. GS_TARGET_ERR - the target cell's value could not be obtained, most likely indicating that it contains an "Error!" condition. GS_BRACKET_ERR - a bracket was not be found after "maxit" iterations, possibly indicating pathological case 1 above. GS_ITER_ERR - the target is bracketed, but a solution was not found after "maxit" iterations, possibly indicating pathological case 2 above.To facilitate continuation, "nexs_goal_seek()" does not restore the original contents of cell (vr, vc) in the event of failure. It is therefore the programmer's responsibility to save this value if desired.
Sorts "range". The "dir" parameter must be set to one of SORT_ASCENDING or SORT_DESCENDING. The "mode" parameter must be set to one of SORT_UPDATE or SORT_NO_UPDATE. "Keycol1" indicates the column containing the primary key for the sort, and "keycol2" indicates the column containing the secondary key. See the documentation on the NExS Sort Tool in Chapter 9 of the NExS Spreadsheet User Guide for an explanation of these parameters. The return code is 1 if successful, 0 otherwise.
Searches "range" for cells whose contents match "condition". The "order" parameter indicates the order in which the range is scanned and must be one of FIND_BY_ROW or FIND_BY_COL. The "dir" parameter indicates the direction of the scan and must be one of FIND_NEXT or FIND_PREV. The "condition" may be either a Unix-style regular expression (in which case "type" must be set to FIND_REGEX), or an NExS constraint expression (in which case "type" must be set to FIND_NUMERIC). A return code of 1 indicates that "nexs_find()" was successful and the cell which matched condition is indicated by (find_r, find_c). A return code of 0 indicates that find was unsuccessful (or the connection closed unexpectedly, which may be verified by "nexs_test_connection()"). A negative return code indicates that an error occurred in the evaluation of "condition".
Extracts the rows in "range" which match "condition" and stores them in successive rows starting at cell (r_dst, c_dst). The "condition" may be either a Unix-style regular expression (in which case "type" must be set to FIND_REGEX), or an NExS constraint expression (in which case "type" must be set to FIND_NUMERIC). The "keycol" parameter indicates the column that contains the cells to which "condition" is to be applied. A return code of 0 indicates that zero rows were extracted (or the connection closed unexpectedly, which may be verified by "nexs_test_connection()"). A positive return code indicates the number of rows that were extracted, while a negative return code indicates that an error occurred in the evaluation of "condition".
Gets and/or sets all fields on the NExS "Default Sheet Characteristics" dialog. To set fields on the Default Sheet Characteristics dialog box, the corresponding values should be stored in the "defaults" structure and the corresponding bits in "mask" should be set to 1. See "nexs.h" for details of the SheetDefaults structure and mask. Upon return, the "defaults" structure will be filled in with all current values of the Default Sheet Characteristics dialog box. Returns 1 if successful, 0 otherwise.
Gets and/or sets all fields on the NExS "Default Cell Characteristics" dialog. To set fields on the Default Cell Characteristics dialog box, the corresponding values should be stored in the "defaults" structure and the corresponding bits in "mask" should be set to 1. See "nexs.h" for details of the CellDefaults structure and mask. Upon return, the "defaults" structure will be filled in with all current values of the Default Cell Characteristics dialog box. Returns 1 if successful, 0 otherwise.
Gets and/or sets all fields on the NExS "PostScript Output Characteristics" dialog. To set fields on the PostScript Output Characteristics dialog box, the corresponding values should be stored in the "defaults" structure and the corresponding bits in "mask" should be set to 1. See "nexs.h" for details of the PSDefaults structure and mask. Upon return, the "defaults" structure will be filled in with all current values of the PostScript Output Characteristics dialog box. Returns 1 if successful, 0 otherwise.
Gets and/or sets all fields on the NExS "Printer Characteristics" dialog. To set fields on the Printer Characteristics dialog box, the corresponding values should be stored in the "defaults" structure and the corresponding bits in "mask" should be set to 1. See "nexs.h" for details of the PrintDefaults structure and mask. Upon return, the "defaults" structure will be filled in with all current values of the Printer Characteristics dialog box. Returns 1 if successful, 0 otherwise.
This function sets and gets values in the NExS Import Characteristics dialog. The variable parameter "*one_word_per_col" is a boolean corresponding to the "One word per column" toggle on the Import Characteristics dialog. The variable parameter "*ws_threshold" is a value between 0 and 100 corresponding to the "Whitespace threshold" slider. The parameter "mask" is a bit mask formed from zero or more of the following values defined in nexs.h:
ONE_WORD_PER_COL WHITESPACE_THRESHOLD IMPORTCHAR_RESET
If the mask contains IMPORTCHAR_RESET, the import characteristics will be reset to their default values. The other two mask values determine whether their corresponding variables will alter the current settings of the import characteristics. If "mask" is set to zero, then the current import characteristics are not changed. In all cases, the new (current) import characteristics settings are retrieved from the dialog and stored in the corresponding variables. The function returns 1 if successful, 0 otherwise.
Creates a new graph. The gid for the graph is returned in "new_gid". The newly created graph is empty, and it's name is set to "Untitled". The function return value is 1 if successful, 0 otherwise.
Causes the graph specified by "gid" to be displayed. Returns 1 if successful, 0 otherwise.
Causes the graph specified by "gid" to be redrawn. This function would typically be called after changing the graph's characteristics or data ranges. A graph must be displayed before it can be redrawn. Returns 1 if successful, 0 otherwise.
Sets the name of the graph specified by "gid" to the name contained in "namebuf". If "namebuf" is an empty string (length == 0), the existing graph name is unchanged. In either case, the new (or existing graph name is retrieved into "namebuf". Therefore, "namebuf" must point to a character array of sufficient size to hold the graph name. Note that the name does not take effect on the graph window's Motif title bar until the graph is redisplayed using nexs_display_graph(). Returns 1 if successful, 0 otherwise.
Produces a new graph which is a clone of the graph specified by "gid". The new graph's ID is returned in "new_gid". The new graph will not be automatically displayed, even if the graph it is cloning is currently displayed. Returns 1 if successful, 0 otherwise.
Deletes the graph specified by "gid". The graph's ID is reclaimed by NExS. Returns 1 if successful, 0 otherwise.
Prints the graph specified by "gid" in the format specified by "type", which must be one of the following values defined in "nexs.h":
GR_EPS - encapsulated PostScript, or GR_IDRAW_PS - idraw-compatible PostScript.
If "name" is a non-empty string, it is taken to be a file name to which the output is to be sent. If "name" is empty or NULL, the output is sent to the printer, as specified by the "Print Command" on the "Printer Characteristics" dialog. Note that the graph must be displayed to be printed, and that the aspect ratio of the printed graph will match the aspect ratio of the graph on the X Window display. Returns 1 if successful, 0 otherwise.
The graph specified by "gid" is unmapped from the display. The graph may be subsequently redisplayed by calling nexs_display_graph() or by selecting it from the NExS Graph menu. Returns 1 if successful, 0 otherwise.
Gets and/or sets all fields on the "General Characteristics" dialog of the graph specified by "gid". To set fields on the graph's General Characteristics dialog, the desired values should be stored in the "gchar" structure and the corresponding bits in "mask" should be set to 1. See "nexs.h" for details of the GrGenChar structure and mask. Upon return, the "gchar" structure will be filled in with all current values of the graph's General Characteristics dialog. Note that the "title_text" member of "gchar" is dynamically allocated and should be freed when no longer needed by the client. Returns 1 if successful, 0 otherwise.
Gets and/or sets all fields on the "X|Y|Z Axis Characteristics" dialog of the graph specified by "gid". The axis to be manipulated is specified by the parameter "axis", which must be set to one the following valued defined in "nexs.h": X_AXIS, Y_AXIS, Z_AXIS, AUX_Y_AXIS. To set fields on the graph's X|Y|Z Axis Characteristics dialog, the desired values should be stored in the "axischar" structure and the corresponding bits in "mask" should be set to 1. See "nexs.h" for details of the GrAxisChar structure and mask. Upon return, the "axischar" structure will be filled in with all current values of the graph's General Characteristics dialog. Note that the "label_text" member of "axischar" is dynamically allocated and should be freed when no longer needed by the client. Returns 1 if successful, 0 otherwise.
This function provides access to all of the features on the Graph Data Set Characteristics dialog. It is similar to the NExS v2.1 compatible call xs2_gdata_char(), except that it provides access to all of the version 3 data set features, and it DOES NOT use dynmically allocated strings. DO NOT free strings returned in the NEXSGrDataChar structure.
The structure members and mask values are defined in "nexs.h".
Example:
/* * Set the legend text of dataset 3 on graph 1 to 18pt Helvetica bold italic */ NEXSGrDataChar dchar; unsigned long mask; dchar.legend_size = NEXS_FONT_SIZE_18PT; dchar.legend_family = NEXS_FONT_FAMILY_HELVETICA; dchar.legend_style = NEXS_FONT_STYLE_BOLDITALIC; mask = NEXS_GDATA_LEGEND_SIZE | NEXS_GDATA_LEGEND_FAMILY | NEXS_GDATA_LEGEND_STYLE; nexs_gdata_char(port, 1, 3, &dchar, mask);
(This function is included only for backwards compatibility with earlier spreadsheet products. New programs should use nexs_gdata_char().)
Gets and/or sets all fields on the "Data Ranges" dialog for the specified "dataset" the graph specified by "gid". The "dataset" must be an integer in the range 1 to 5. To set fields on the graph's Data Ranges dialog, the desired values should be stored in the "dchar" structure and the corresponding bits in "mask" should be set to 1. See "nexs.h" for details of the XS2GrDataChar structure and mask. Upon return, the "dchar" structure will be filled in with all current values of the graph's Data Ranges dialog for the specified "dataset". Note that the "x_range", "y_range", and "z_range" members of the XS2GrDataChar structure are strings rather than Range structures. This feature allows named ranges to be specified if desired. the "x_range", "y_range", "z_range", and "legend_text" members of "dchar" are dynamically allocated and should be freed when no longer needed by the client. Returns 1 if successful, 0 otherwise.
Gets and/or sets the rotation angles for the 3-D surface graph specified by "gid". See "nexs.h" for details on the GrRotate3D structure. Returns 1 if successful, 0 otherwise.
Gets and/or sets the screen coordinates and window size for the graph window specified by "gid". See "nexs.h" for details on the GrGeometry structure. Note that this function does not correspond with any NExS dialog; moving and resizing windows are normally handled by interaction with the Window Manager. Note also that the values set by this function may be overidden by the Window Manager. Returns 1 if successful, 0 otherwise.
This function registers a function to be called upon notification of an "action" occurring on an NExS spreadsheet for which action notification has been reqested (see nexs_set_action_notify()). When such an action occurs, the registered function is called with two integer parameters. The first parameter is the port number on which the NExS spreadsheet reporting the action is connected, and the second parameter is an action code specifying the action being reported. These codes are defined in nexs.h. (Note: the only action code currently defined is ACTION_NEW_SHEET, which indicates the loading of a new spreadsheet, or resetting the NExS to its initial state via the "File->New" button.)
Notification of actions is asynchronous; that is, NExS does not block and wait for "callback" to return from processing an action notification. If "callback" is set to NULL (it's initial value), then any incoming action notifications are discarded.
Example: (see nexs_set_action_notify...)
This function requests the NExS instanced connected on the specified port to report the occurence of events specified by the "action" parameter. If "flag" is set to 1, notification for the specified action is turned on; if "flag" is 0, notification for the action is turned off. Codes for "action" parameter are defined in nexs.h. (Note: the only action code currently defined is ACTION_NEW_SHEET, which indicates the loading of a new spreadsheet, or resetting the NExS to its initial state via the "File->New" button.)
The call to nexs_set_action_notify() must be accompanied by a call to nexs_set_action_callback() to register a function to be called when action notification events occur. It is recommended (but not required) that nexs_set_action_callback() be called first to avoid the loss of any action notification events.
The function returns 1 if the call was processed successfully, or 0 if the port number or the action code is invalid.
Example:
/* Here is my function to be called upon action notification... */ void my_action_callback(int port, int action) { switch (action) { case ACTION_NEW_SHEET: printf("A \"New Sheet\" action occurred on port %d\n", port); break; default: printf("An unknown action occurred on port %d!!!\n", port); } } /* Here are the calls to request notification of the New Sheet action... */ nexs_set_action_callback(my_action_callback); nexs_set_action_notify(port, ACTION_NEW_SHEET, 1);
Returns a pointer to the nul-terminated string containing the one or two character identifier for the specified column number. The column number must be in the range 0 ("A") to 701 ("ZZ"). If the specified column number is out of this range, then NULL is returned. Note that the location of the returned string is statically allocated and will be overwritten with each call to col_to_text().
Returns the column number corresponding to the one or two character alphabetic character sequence pointed at by "name". The first character must be alphabetic. If the second character is alphabetic it is taken to be part of the column identfier, otherwise it is ignored. For example, text_to_col("C") == text_to_col("C100") == 2. If name does not point to a valid column identifier, -1 is returned.
Interprets "name" as a cell reference and returns the row and column numbers in "row" and "col". The function return value is 1 if successful, 0 otherwise.
Returns 1 if "row" and "col" do not represent a cell address within the range supported by NExS; 0 otherwise.
Parses a cell or range name and stores the result in the structure "range". Returns 1 if successful, 0 otherwise.
Returns a pointer to the nul-terminated string representing the name of the cell or range reference specified in the structure "range". If the contents of "range" do not represent a valid cell or range reference, then NULL is returned. Note that the location of the returned string is statically allocated and will be overwritten with each call to range_to_text().
Sorts the row and column references contained in the structure "range" so that they are in "standard" order. In NExS standard order, range->r0 and range->c0 specify the upper left corner of the range and range->r1 and range->c1 specify the lower right corner of the range. The bits in range->flags (which mark absolute row and column references) are transposed appropriately.
Displays the string "s" on the message line of the NExS status display.
FORTRAN equivalent:
subroutine xsdmsg(port, msg) integer port character*(*) msg
Scroll the range defined by rmin, cmin, rmax, and cmax one unit in the specified direction (NEXS_SCROLL_UP, NEXS_SCROLL_DOWN, NEXS_SCROLL_RIGHT, NEXS_SCROLL_LEFT). Cells outside of the scrolled range are unaffected. Typically, the remote application will place new data in the position or positions vacated by the scroll operation.
FORTRAN equivalent:
subroutine xsscroll(port, rmin, cmin, rmax, cmax, dir) integer port, rmin, cmin, rmax, cmax, dir
(The Fortran names for the scrolling directions, defined in "xsparams.f[or]", are nexsup, nexsdown, nexsright, and nexsleft.
This function sets or clears the "lock flag" associated with the specified port. Each port has the ability to lock out all mouse and keyboard input (i.e., user input) to NExS. The lock state of NExS is the logical "or" of all of its ports' lock flags. Thus, if any port's lock flag is set, then no user input can occur. To avoid data coherence problems, a port's lock flag is automatically set when any of its remote menu buttons are invoked, and cleared when the remote process completes. The nexs_user_lock function is provided as a means to override this automatic behavior.
FORTRAN equivalent:
subroutine xsulock(port, lock) integer port, lock
Registers a new server connection with NExS and returns an integer displayID. If the server connection is already registered, the existing displayID value is returned. If the maximum number of displayIDs has been exceeded, 0 is returned. NExS_new_display() will automatically initialize the the connection library if nexs_connect_init() has not been called previously.
Sets the current active display to displayID. Returns 0 if displayID is not valid; returns displayID otherwise.
Returns the displayID of the current active display.
Removes displayID from the connection libraries internal list of display connections. A displayID may be removed only if there are no active connections on that display. If any of the connection ports are using the specified display, then nexs_remove_display returns 0 and the displayID remains intact. Also, if the displayID is not valid, 0 is returned. Otherwise, the displayID is removed from the connection library's internal list and its value is returned.
This procedure is for the convenience of clients which are themselves X Window applications. The "event" is examined to see if it is an NExS client message. If so, it is handled appropriately by the connection library and a 1 is returned. Otherwise, it is left untouched and a 0 is returned.
FORTRAN equivalent:
There is no Fortran equivalent to this function since the Fortran 77 standard does not support structures. Some Fortran compilers include extensions which provide support for structures, in which case a program may call nexs_message_handler directly. Consult the Fortran manual for your workstation to see if this is possible.
This procedure waits for X events on the server specified by nexs_connect_init, handles the ones destined for the NExS connection library, and passes all other events to the specified callback for further processing. Simple (non-X) applications should pass NULL (0) as the callback function to indicate that they are not interest in non-NExS library related events.
FORTRAN equivalent:
subroutine xsdispatch subroutine xscbdispatch(callback) external callback
The first form of this call is used for connection programs which do not need to respond to X Window events other than those related to NExS. The second form registers a callback subroutine to which all non-NExS related X events are passed.
This function flushes the output buffer on the server connection associated with port. It should be called whenever an output-only operation occurs that is not followed by an input operation. This simply replaces nexs_flush() in the multi-server model. The old form, nexs_flush(), flushes the current active display.
Flushes all output to NExS on the current active display. Most applications should use nexs_flush_port() instead of nexs_flush(), which has been included for compatibility with version 1.0 of the NExS Connection Library.
FORTRAN equivalent:
subroutine xsflush
Returns the X11 window ID of the NExS instance associated with the specified "port". If "port" is 0, returns the client's own window ID.
FORTRAN equivalent:
function ixswndo(port) integer port
Returns the top-level X window ID of the NExS instance connected to the specified port. Returns the window ID if successful; "None" otherwise.
Returns the top-level X window ID of graph number "gid" on the NExS instance connected to the specified port. Returns the window ID if successful; "None" otherwise.
Returns the X11 display pointer associated with the connection on the specified port. If the port is 0, the display pointer associated with the current active display is returned. Note that this call is incompatible with previous versions of the NExS connection library.
NOTE: In version 1.0 of the NExS connection library nexs_display() Did not take an argument since only one display connection was allowed. Programs written for version 1.0 of the library can be compiled under version 2.0 if they are modified to pass the value 0 to nexs_display().
Returns the X11 display pointer associated with the specified displayID. Returns NULL if the displayID is not valid.
FORTRAN equivalent:
There is no Fortran equivalent to this routine since it returns a pointer to a structure, which is not supported by the Fortran 77 standard. Some Fortran compilers include extensions to support structure references, in which case "nexs_display" may be called directly.
Queries NExS about its current connections. "status_list[n]" is set to 1 if a connection exists on NExS port "n" (n is between 1 and MAX_PORTS+1), or 0 if no connection exists on port "n". "Name_list[n]" is set to the null-terminated name of the connection on port "n". The function returns 1 if the inquiry is successful, 0 otherwise.
Sends an arbitrary 15-byte message to another NExS connection client. "Remote_port" is the NExS port number obtained from "nexs_inquire_connections()". Returns 1 if the message is sent successfully, 0 otherwise.
Establishes "recv_fn()" as a callback function to be invoked when a message is received from another NExS connection client. The NExS port number of the sending client and the 15-byte message are passed to "recv_fn()" when a message is received. Interpretation of the 15-byte messages is entirely up to the clients.
Blocks and waits for a message from the specified remote port. When a message from "remote_port" is received, the message is stored in msg_buf and 1 is returned. If the call is unsuccessful (i.e., nothing is connected to "remote_port") 0 is returned. Note that messages received in this way will not trigger the "recv_fn()" callback described above. The combination of "nexs_send_message()", "nexs_set_receiver()" and "nexs_message_wait()" provide a convenient mechanism for cooperating NExS clients to establish their own private dialogs.
Attempts to register the caller as NExS Connection Manager for the X11 display server indicated by the specified displayID. The request will succeed only if no other process is currently registered as manager for the indicated display. Returns 1 if successful; 0 otherwise.
Unregisters the caller as NExS Connection Manager for the display indicated by "displayID". Returns 1 if successful; 0 if "displayID" is not valid, or if the caller was not registered as manager for the indicated display in the first place.
Establishes a callback function to notify the NExS Connection Manager that a new instance of NExS has started. The callback function has two arguments, the first is the integer "displayID" to indicate the display on which the new instance resides; the second is the connection window ID "w" of the new instance. The caller will be notified of new instances of NExS only on displays for which it is registered as NExS Connection Manager. Returns 1 if successful, 0 if the program is not a Connection Manager for any display.
Requests the instance of NExS whose connection window ID is "nexs_window" on the display indicated by "displayID" to accept connections. NExS will comply with the request if its connections are not explicitly locked. Returns 1 if the NExS instance complied with the request; 0 otherwise.
Provides a "back door" mechanism for the NExS Connection Manager to connect to an instance of NExS. The parameters "displayID" and "nexs_window" specify the NExS instance to which the manager desires to connect. "Name" is the 10-character name of the connection as seen by NExS. The connection port ID is returned if a connection is established; otherwise 0 is returned. Two features distinguish "mgr_connect()" from "nexs_establish_connection()":
Returns the connection window ID of the NExS instance which is currently accepting connections on the display indicated by "displayID", or None if the displayID is invalid or no NExS instance is accepting connections on the indicated display.
Get the name of the specified NExS instance. The name of an NExS instance is explicitly defined by the command line option "-xsname" when NExS is started. If the name is not explicitly set, it defaults to "NExS v2.0". It is not necessary to be connected to an NExS instance to retrieve its name. The string returned by "nexs_get_name()" is dynamically allocated and should be freed (using "free()") when no longer needed. NULL is returned if the call fails.
The display indicated by "displayID" is scanned for instances of NExS. A dynamically allocated array of connection window IDs for all NExS instances found is returned in "nexs_windows". The length of the array is returned in "num_windows". Returns 1 if the call is successful; 0 otherwise. The array returned by "nexs_scan_display()" should be freed (using "free()") when it is no longer needed.
When a message is received from NExS (such as a remote function call) "nexs_port" is set to the port ID of the connection over which the message is received. This is useful for NExS connection programs that open more than one connection to NExS. (See the demo program "server.c" for an example of how this variable can be used.)
When NExS issues a remote function call, "nexs_row" and "nexs_col" are set to the indices of the cell from which the remote function was invoked.
This variable contains a set of six 1-bit flags which are set during a remote function call to tell the client something about the status of the NExS calculation that caused the invocation of the remote function. The flag bits are defined as follows (bit #0 is the least significant bit):
Bit # C name Description Fortran name 0 NEXS_RECALC - set if a recalculation is in progress. nexsrecalc 1 NEXS_FORCE_RECALC - set if a "forced" recalculation is nexsforcerecalc in progress. A "forced" recalculation is one initiated by selecting "Recalculate" from the Utilities menu, or by typing "meta R", or by pressing the "Do" key on some systems. 2 NEXS_FULL_RECALC - set if a full recalculation of all nexsfullrecalc cells containing formulas is in effect. NExS normally only recalculates cells whose value may have changed as a result of the most recent operation. 3 NEXS_MANUAL_MODE - indicates the state of the nexsmmanual "Automatic Recalculation" toggle button on the "Default Sheet Characteristics" dialog. If this bit is set, it means that "Automatic Recalculation" has been deselected. 4 NEXS_CONSTRAINT_MODE - indicates the state of the nexsmconstraint "Constraint Checking Enabled" toggle button on the "Default Sheet Characteristics" dialog. If this bit is set, it means that "Constraint Checking" has been deselected. 5 NEXS_CONSTRAINT - indicates that the remote function nexsconstraint was invoked from within a constraint expression.
Connection clients which need to optimize their execution may find these flags useful. For example, a remote function which takes a very long time to compute might be designed to respond only to a forced recalculation to avoid unwanted delays during setup and editing of the spreadsheet.
NExS allows connections to operate between machines with different floating point architectures. The floating point architectures currently supported are IEEE double precision and VAX (PDP-11) double precision format (D-float). The VAX format provides about one extra digit of precision at the expense of considerable dynamic range. "nexs_conv_warn" is only meaningful if an NExS client on a VAX is connected to NExS running on an IEEE floating point machine or vice-versa. It is set when a number whose magnitude is too large (> 1.7e+38) or too small (< 2.9e-39) to represent in the VAX D-float format is passed over a connection from an IEEE floating point machine. The numbers themselves are actually converted silently to their most "reasonable" representations - numbers greater than 1.7e+38 are truncated to 1.7e+38, and numbers less than 2.9e-39 are set to zero.
/* * This application opens a connection to NExS and establishes a * new menu with four buttons. The application simulates a * real-time data monitoring application which loads new information * into the spreadsheet every 5 seconds. The buttons control starting * and stopping of the monitor, whether or not recalculation is * performed automatically when new data is loaded, and closing of * the connection. */ /* * * NExS Connection Library V1.0 (Beta release B, September 10, 1990) * Copyright 1990, X Engineering Software Systems Corporation * Copyright 1999, GreyTrout Software, Inc. * All rights reserved. * * file: test2.c * */ #include <stdio.h> #include <signal.h> #include <nexs.h> int portID, mon_row, mon_col, recalc_flag = 0; void b1_fn(), b2_fn(), b3_fn(), b4_fn(); long menu1ID, button1ID, button2ID, button3ID, button4ID; void doit() { static int n = 0; double sin(); int net, disk; Range range; /* defines range affecting partial recalculation */ /* fake some data to monitor */ net = 10000.0 * (sin(1.0 * n) + 1.0); disk = 1000.0 * (sin(1.5 * n) + 1.0); nexs_store_number(portID, mon_row+1, mon_col+1, (double) n++); nexs_store_number(portID, mon_row+2, mon_col+1, (double) net); nexs_store_number(portID, mon_row+3, mon_col+1, (double) disk); if (recalc_flag) { range.r0 = mon_row + 1; range.r1 = mon_row + 3; range.c0 = range.c1 = mon_col + 1; range.flags = 0; nexs_recalc(portID, 0, 1, &range); } nexs_flush(); signal(SIGALRM, doit); alarm(5); } void close_notify_fn(port) int port; { fprintf(stderr, "Port number %d closed; exiting...\n", port); exit(0); } void b1_fn() /* start "monitoring" at current location */ { nexs_get_location(portID, &mon_row, &mon_col); nexs_display_message(portID, "Monitoring Enabled"); nexs_store_label(portID, mon_row, mon_col, "\'System Stats"); nexs_store_label(portID, mon_row+1, mon_col, "\'Interval #"); nexs_store_label(portID, mon_row+2, mon_col, "\'Network I/O:"); nexs_store_label(portID, mon_row+2, mon_col+2, "\'packets"); nexs_store_label(portID, mon_row+3, mon_col, "\'Disk I/O:"); nexs_store_label(portID, mon_row+3, mon_col+2, "\'seeks"); doit(); } void b2_fn() /* stop "monitoring" */ { alarm(0); nexs_display_message(portID, "Monitoring Disabled"); } void b3_fn() /* Toggle recalculation flag */ { if (recalc_flag) { recalc_flag = 0; nexs_display_message(portID, "Monitor recalculation set to manual"); } else { recalc_flag = 1; nexs_display_message(portID, "Monitor recalculation set to automatic"); } } void b4_fn() /* disconnect and exit */ { nexs_close_connection(portID); exit(0); } main() { nexs_set_close_notify(close_notify_fn); portID = nexs_open_connection("SysMon", 10); if (portID == 0) { printf("could not connect to NExS after 10 seconds...\n"); exit(0); } menu1ID = nexs_create_menu(portID, "Monitor"); button1ID = nexs_create_button(portID, menu1ID, "Start Monitor", b1_fn, 0); button2ID = nexs_create_button(portID, menu1ID, "Stop Monitor", b2_fn, 0); button3ID = nexs_create_button(portID, menu1ID, "Toggle Recalc", b3_fn, 0); button4ID = nexs_create_button(portID, menu1ID, "Disconnect", b4_fn, 0); nexs_dispatcher(NULL); }
/* * * NExS Connection Library V1.0 (Beta release B, September 10, 1990) * Copyright 1990, X Engineering Software Systems Corporation * Copyright 1999, GreyTrout Software, Inc. * All rights reserved. * * The author hereby grants permission to use, modify, and distribute * this program so long as the above copyright message is retained. * * file: test5.c * * (This example program has been edited for compactness and clarity. * - TKM 10/15/95) * */ #include <stdio.h> #include <nexs.h> int portID; static int error_flag; /* set if any function arg is a string */ static Number sum_args(Operand *argv) /* compute sum of function args */ { Number sum, x; int i, n = argv->val.count; int r, c; sum = 0.; error_flag = 0; for (i=0; i<n; i++) { switch ((++argv)->type) { case ARG_NUMBER: /* add the number to the sum */ sum += argv->val.number; break; case ARG_CELL: /* add the cell contents to the sum */ if (nexs_get_number(portID, argv->val.range.r0, argv->val.range.c0, &x)) sum += x; break; case ARG_RANGE: /* sum the cell values in the range */ for (r = argv->val.range.r0; r <= argv->val.range.r1; r++) for (c = argv->val.range.c0; c <= argv->val.range.c1; c++) if (nexs_get_number(portID, r, c, &x)) sum += x; break; case ARG_STRING: /* make it an error message */ strcpy(nexs_sbuf, argv->val.string); error_flag = 1; return 0.0; default: break; /* ignore it */ } } } Operand nexs_fn(Operand *argv) /* identical to @sum(...) */ { Operand op; op.val.number = sum_args(argv); if (error_flag) op.type = ARG_ERROR; else op.type = ARG_NUMBER; return op; } Operand nexs2_fn(Operand *argv) /* returns a string */ { Operand op; if (error_flag) op.type = ARG_ERROR; else { op.type = ARG_STRING; sprintf(nexs_sbuf, "The sum is %lg", sum_args(argv)); } return op; } Operand nexs3_fn(Operand *argv) /* stores a "tagged number" (embedded tool) */ { Operand op; if (error_flag) op.type = ARG_ERROR; else { op.val.number = sum_args(argv); nexs_store_tagged_number(portID, nexs_row+1, nexs_col, op.val.number*2); op.type = ARG_NUMBER; } return op; } void close_notify_fn(port) int port; { fprintf(stderr, "Port number %d closed; exiting...\n", port); exit(0); } main() { nexs_set_close_notify(close_notify_fn); portID = nexs_open_connection("Functions", 10); if (portID == 0) { printf("could not connect to NExS after 10 seconds...\n"); exit(0); } nexs_install_function(portID, "NEXS", nexs_fn, 0); nexs_install_function(portID, "NEXS2", nexs2_fn, 0); nexs_install_function(portID, "NEXS3", nexs_fn, 0); nexs_dispatcher(NULL); }
/* * * NExS Connection Library V1.0 (Beta release B, September 10, 1990) * Copyright 1990, X Engineering Software Systems Corporation * Copyright 1999, GreyTrout Software, Inc. * All rights reserved. * * file: server.c * */ #include <stdio.h> #include <signal.h> #include <X11/Xlib.h> #include <X11/Xatom.h> #include <nexs.h> Atom xsConnectAtom; Display *display; Window nexs_window(); double number = 0.0; char *strptr = NULL; int status; Operand fn_demo1(argv) Operand argv[]; /* Function @DEMO1(x). Returns 2 times its argument, if the argument is a number or a cell. Returns 0 otherwise. */ { Operand op; double x; switch (argv[1].type) { case ARG_NUMBER: op.val.number = argv[1].val.number * 2.0; break; case ARG_CELL: nexs_get_number(nexs_port, argv[1].val.range.r0, argv[1].val.range.c0, &x); op.val.number = 2.0 * x; break; default: op.val.number = 0.0; } op.type = ARG_NUMBER; return op; } Operand fn_demo2(argv) Operand argv[]; /* Function @DEMO2(x). Returns 0.5 times its argument, if the argument is a number or a cell. Returns 0 otherwise. */ { Operand op; double x; switch (argv[1].type) { case ARG_NUMBER: op.val.number = argv[1].val.number * 0.5; break; case ARG_CELL: nexs_get_number(nexs_port, argv[1].val.range.r0, argv[1].val.range.c0, &x); op.val.number = 0.5 * x; break; default: op.val.number = 0.0; } op.type = ARG_NUMBER; return op; } void cut_button() { int r, c; nexs_get_location(nexs_port, &r, &c); if (strptr) { free(strptr); strptr = NULL; } status = nexs_get_value(nexs_port, r, c, &number, &strptr); } void paste_button() { int r, c; nexs_get_location(nexs_port, &r, &c); switch (status) { case NEXS_NUMBER: nexs_store_number(nexs_port, r, c, number); break; case NEXS_STRING: nexs_store_label(nexs_port, r, c, strptr); break; } } void check_for_nexs() /* Checks for a new nexs "client". A new client is identified by the fact that it owns the xsConnectAtom and its window ID is different from any of the currently active ports. */ { Window w; int portID, i; long menu; if ((w = XGetSelectionOwner(display, xsConnectAtom)) != None) { for (i=1; i<=MAX_PORTS; i++) if (w == nexs_window(i)) return; portID = nexs_establish_connection("ServerDemo", 0); if (portID) { nexs_install_function(portID, "DEMO1", fn_demo1, 0); nexs_install_function(portID, "DEMO2", fn_demo2, 0); menu = nexs_create_menu(portID, "Server"); nexs_create_button(portID, menu, "Cut", cut_button, 0); nexs_create_button(portID, menu, "Paste", paste_button, 0); } } } void send_time2check() /* Send a ClientMessage event to this process once every second which says its time to look and see if any new copies of nexs have come up which need to be served. */ { XClientMessageEvent cm_event; cm_event.type = ClientMessage; cm_event.display = display; cm_event.window = nexs_window(0); /* returns client window */ cm_event.message_type = xsConnectAtom; /* irrelevant */ cm_event.format = 32; XSendEvent(display, cm_event.window, False, None, &cm_event); XFlush(display); signal(SIGALRM, send_time2check); /* set up to check again */ alarm(1); /* in one second */ } void check_event(event) XEvent *event; { if (event->type == ClientMessage && event->xclient.message_type == xsConnectAtom) check_for_nexs(); } main() { if ((display = XOpenDisplay("")) == NULL) { fprintf(stderr, "Could not open display!\n"); exit(0); } nexs_connect_init(display); xsConnectAtom = XInternAtom(display, "XS_Connect", False); send_time2check(); nexs_dispatcher(check_event); }