conNExions API Library v1.3
Copyright 1999-2000, GreyTrout Software, Inc.
Permission is hereby granted to copy this document without modification.
Contents
The NExS API library (also called the "NExS Connection" library) is a set of
C and Fortran-callable procedures for connecting external, user-written C and Fortran
programs to the NExS spreadsheet through the X Window client communication mechanisms. The
connection library provides each client program with up to 63 independent, simultaneous
connections to NExS spreadsheets running on up to 63 different displays.
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.
The Fortran interface to the NExS connection library is written to conform to the
Fortran 77 standard. One significant aspect of this is that all function and subroutine
identifiers are composed entirely of alphanumeric characters, and they all are unique
within the first six characters. All NExS Fortran function calls return integer values. In
keeping with Fortran tradition, the names of these functions all begin with "i".
These restrictions make the Fortran calls somewhat less mnemonic than their C
counterparts. (But that never bothered Fortran programmers!)
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.
A significant of the NExS Connection Library is that connections to multiple X servers
are supported. The Connection Library maintains an internal table of current server
connections that are referenced by their "displayID," which is a small integer
identifier. To deal with multiple displays without having to constantly refer to a
displayID, the Connection Library supports the notion of a "current active
display." To open a connection on a particular display, the program must set the
"current active display" using "nexs_set_display()" and then call
"nexs_open_connection()." This capability facilitates such things as "hot
links" between spreadsheets on different workstations and other forms of data
sharing. (The Connection Library's internal tables will support up to 63 independent X
Server connections; however, on some systems this number may exceed the allowable number
of open file descriptors. Consult your operating system manuals on how to resolve the
problem if this is an issue in your application.)
The NExS Connection Library allows connection programs to find out about and
communicate with other programs connected to an NExS spreadsheet. Also, one connection
program per X server can register itself as "Connection Manager" for the
display. The "Connection Manager" has certain special privileges, such as being
notified whenever a new instance of NExS is invoked on its display, and being able to
connect to NExS through a "back door." Functions which are exclusively
accessible to the "Connection Manager" are designated by the prefix
"mgr". These connection management and communication features combined make it
possible to create cooperative application suites of multiple NExS spreadsheets and
connection programs.
These functions open and close connections between connection client programs and NExS
instances running on an X Window display, and provide a callback mechanism for handling of
connections which unexpectedly close.
- int nexs_connect_init(Display *dp);
- 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.
- int nexs_establish_connection(char *name, int timeout);
- 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
- int nexs_open_connection(char *name, int 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
- void nexs_set_close_notify(void (*close_fn)());
- 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
- void nexs_close_connection(int port);
- Closes the specified connection to NExS.
FORTRAN equivalent:
subroutine xsclose(port)
integer port
- int nexs_test_connection(int 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().")
These functions retrieve data and formulas from a NExS spreadsheet.
- int nexs_get_value(int port, int row, int col, double *value, char **string);
- 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.)
- int nexs_get_string(int port, int row, int col, char **string);
- 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.)
- int nexs_get_number(int port, int row, int col, double *value);
- 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
- int nexs_get_numbers(int port, Range range, int start_row, int start_col, XSValBuf
xsvbuf[255], int *count);
- 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)
- int nexs_get_formula(int port, int row, int col, char **string);
- 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.)
These functions store data and formulas in a NExS spreadsheet.
- void nexs_store_number(int port, int row, int col, double value);
- 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
- void nexs_store_label(int port, int row, int col, char *s);
- 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
- void nexs_store_formula(int port, int row, int col, char *formula);
- 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
- void nexs_store_formatted_number(int port, int row, int col, double value, int
fnt_code, int fmt_code, int places);
- 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
- void nexs_store_tagged_number(int port, int row, int col, double 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
- void nexs_store_tagged_string(int port, int row, int col, char *s);
- 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;
}
NOTE: These functions are not meant for human consumption; they are designed primarily
for use with automated conNExion programming tools. They are listed here for the sake of
completeness, but the function descriptions are rather incomplete at this time. You would
be better served by using the functions for reading and storing sheet values presented in
the previous sections. Use these functions at your own risk!
- void nexs_io_error(nexs_io_errors err_num);
- Prints a NExS I/O error number and then exits the connection function that caused the
error.
FORTRAN equivalent:
NONE.
- void nexs_io_error_msg(char *msg);
- Prints a NExS I/O error message pointed to by "msg" and then exits the
connection function that caused the error.
FORTRAN equivalent:
NONE.
- char* rctotext(int col ,int row);
- 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.
- void nexs_io_op_error_msg(Operand* op,char* format,...);
- 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.
- int nexs_io_get_op_size(Operand *operand,int selector);
- Returns the number of cells in operand[selector].
FORTRAN equivalent:
NONE.
- int nexs_io_open_nexs_connection(char *connection_name,int wait_before_failure);
- 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.
- void nexs_io_operand_slice(Operand *src_op,int r0,int c0,int r1,int c1,Operand
*dst_op);
- 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.
- Number nexs_io_get_scalar(Operand *operand);
- Gets the single number value of "operand" from the NExS spreadsheet.
FORTRAN
equivalent:
NONE.
- void nexs_io_store_scalar(Number s,Operand *range);
- Stores the single number s into the operand "range" of the NExS spreadsheet.
FORTRAN
equivalent:
NONE.
- char *nexs_io_get_str(Operand *operand);
- Gets the single string of the operand from the NExS spreadsheet.
FORTRAN equivalent:
NONE.
- void nexs_io_fre_string(char *s,Operand *range);
- Frees the storage used by the string s.
FORTRAN equivalent:
NONE.
- void nexs_io_str_string(char *s,Operand *range);
- Stores the single string s into the operand of the NExS spreadsheet.
FORTRAN
equivalent:
NONE.
- void nexs_io_free_ivector (int *v,int nl,int nh);
- Frees the storage of a vector of integers.
FORTRAN equivalent:
NONE.
- void nexs_io_free_imatrix (int **m,int nrl,int nrh,int ncl,int nch);
- Frees the storage of a matrix of integers.
FORTRAN equivalent:
NONE.
- int * nexs_io_ivector (int nl,int nh);
- Creates a vector of integers.
FORTRAN equivalent:
NONE.
- int * nexs_io_ivector_realloc (int *v,int nl,int nh,int new_nl,int new_nh);
- Resizes a vector of integers.
FORTRAN equivalent:
NONE.
- int ** nexs_io_imatrix (int nrl,int nrh,int ncl,int nch);
- Creates a matrix of integers.
FORTRAN equivalent:
NONE.
- int * nexs_io_alo_int_vector (Operand *range,int lo,int hi);
- Allocates storage large enough to hold the integer vector from the NExS spreadsheet
pointed to by Operand range.
FORTRAN equivalent:
NONE.
- int ** nexs_io_alo_int_matrix (Operand *range,int rlo,int rhi,int clo,int chi);
- Allocates storage large enough to hold the integer matrix from the NExS spreadsheet
pointed to by Operand range.
FORTRAN equivalent:
NONE.
- int * nexs_io_get_int_vector (Operand *range,int lo,int hi);
- 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.
- int ** nexs_io_get_int_matrix (Operand *range,int rlo,int rhi,int clo,int chi);
- 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.
- void nexs_io_str_int_vector (int *v,Operand *range,int lo,int hi);
- Stores the values from a vector of integers into the NExS spreadsheet at a location
indicated by Operand range.
FORTRAN equivalent:
NONE.
- void nexs_io_str_int_matrix (int **m,Operand *range,int rlo,int rhi,int clo,int chi);
- Stores the values from a matrix of integers into the NExS spreadsheet at a location
indicated by Operand range.
FORTRAN equivalent:
NONE.
- void nexs_io_fre_int_vector (int *v,Operand *range,int lo,int hi);
- Frees the storage created when getting the vector of integer values from the NExS
spreadsheet indicated by Operand range.
FORTRAN equivalent:
NONE.
- void nexs_io_fre_int_matrix (int **m,Operand *range,int rlo,int rhi,int clo,int chi);
- Frees the storage created when getting the matrix of integer values from the NExS
spreadsheet indicated by Operand range.
FORTRAN equivalent:
NONE.
- void nexs_io_free_vector (float *v,int nl,int nh);
- Frees the storage of a vector of floats.
FORTRAN equivalent:
NONE.
- void nexs_io_free_matrix (float **m,int nrl,int nrh,int ncl,int nch);
- Frees the storage of a matrix of floats.
FORTRAN equivalent:
NONE.
- float * nexs_io_vector (int nl,int nh);
- Creates a vector of floats.
FORTRAN equivalent:
NONE.
- float * nexs_io_vector_realloc (float *v,int nl,int nh,int new_nl,int new_nh);
- Resizes a vector of floats.
FORTRAN equivalent:
NONE.
- float ** nexs_io_matrix (int nrl,int nrh,int ncl,int nch);
- Creates a matrix of floats.
FORTRAN equivalent:
NONE.
- float * nexs_io_alo_float_vector (Operand *range,int lo,int hi);
- Allocates storage large enough to hold the float vector from the NExS spreadsheet
pointed to by Operand range.
FORTRAN equivalent:
NONE.
- float ** nexs_io_alo_float_matrix (Operand *range,int rlo,int rhi,int clo,int chi);
- Allocates storage large enough to hold the float matrix from the NExS spreadsheet
pointed to by Operand range.
FORTRAN equivalent:
NONE.
- float * nexs_io_get_float_vector (Operand *range,int lo,int hi);
- 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.
- float ** nexs_io_get_float_matrix (Operand *range,int rlo,int rhi,int clo,int chi);
- 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.
- void nexs_io_str_float_vector (float *v,Operand *range,int lo,int hi);
- Stores the values from a vector of floats into the NExS spreadsheet at a location
indicated by Operand range.
FORTRAN equivalent:
NONE.
- void nexs_io_str_float_matrix (float **m,Operand *range,int rlo,int rhi,int clo,int
chi);
- Stores the values from a matrix of floats into the NExS spreadsheet at a location
indicated by Operand range.
FORTRAN equivalent:
NONE.
- void nexs_io_fre_float_vector (float *v,Operand *range,int lo,int hi);
- Frees the storage created when getting the vector of float values from the NExS
spreadsheet indicated by Operand range.
FORTRAN equivalent:
NONE.
- void nexs_io_fre_float_matrix (float **m,Operand *range,int rlo,int rhi,int clo,int
chi);
- Frees the storage created when getting the matrix of float values from the NExS
spreadsheet indicated by Operand range.
FORTRAN equivalent:
NONE.
- void nexs_io_free_dvector (double *v,int nl,int nh);
- Frees the storage of a vector of doubles.
FORTRAN equivalent:
NONE.
- void nexs_io_free_dmatrix (double **m,int nrl,int nrh,int ncl,int nch);
- Frees the storage of a matrix of doubles.
FORTRAN equivalent:
NONE.
- double * nexs_io_dvector (int nl,int nh);
- Creates a vector of doubles.
FORTRAN equivalent:
NONE.
- double * nexs_io_dvector_realloc (double *v,int nl,int nh,int new_nl,int new_nh);
- Resizes a vector of doubles.
FORTRAN equivalent:
NONE.
- double ** nexs_io_dmatrix (int nrl,int nrh,int ncl,int nch);
- Creates a matrix of doubles.
FORTRAN equivalent:
NONE.
- double * nexs_io_alo_double_vector (Operand *range,int lo,int hi);
- Allocates storage large enough to hold the double vector from the NExS spreadsheet
pointed to by Operand range.
FORTRAN equivalent:
NONE.
- double ** nexs_io_alo_double_matrix (Operand *range,int rlo,int rhi,int clo,int chi);
- Allocates storage large enough to hold the double matrix from the NExS spreadsheet
pointed to by Operand range.
FORTRAN equivalent:
NONE.
- double * nexs_io_get_double_vector (Operand *range,int lo,int hi);
- 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.
- double ** nexs_io_get_double_matrix (Operand *range,int rlo,int rhi,int clo,int chi);
- 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.
- void nexs_io_str_double_vector (double *v,Operand *range,int lo,int hi);
- Stores the values from a vector of doubles into the NExS spreadsheet at a location
indicated by Operand range.
FORTRAN equivalent:
NONE.
- void nexs_io_str_double_matrix (double **m,Operand *range,int rlo,int rhi,int clo,int
chi);
- Stores the values from a matrix of doubles into the NExS spreadsheet at a location
indicated by Operand range.
FORTRAN equivalent:
NONE.
- void nexs_io_fre_double_vector (double *v,Operand *range,int lo,int hi);
- Frees the storage created when getting the vector of double values from the NExS
spreadsheet indicated by Operand range.
FORTRAN equivalent:
NONE.
- void nexs_io_fre_double_matrix (double **m,Operand *range,int rlo,int rhi,int clo,int
chi);
- Frees the storage created when getting the matrix of double values from the NExS
spreadsheet indicated by Operand range.
FORTRAN equivalent:
NONE.
- char **svector(int nl,int nh);
- Creates a vector of string pointers.
FORTRAN equivalent:
NONE.
- char ***smatrix(int nrl,int nrh,int ncl,int nch);
- Creates a matrix of string pointers.
FORTRAN equivalent:
NONE.
- void free_svector(char **v,int nl,int nh);
- Frees a vector of string pointers.
FORTRAN equivalent:
NONE.
- void free_smatrix(char ***m,int nrl,int nrh,int ncl,int nch);
- Frees a matrix of string pointers.
FORTRAN equivalent:
NONE.
- char* * nexs_io_alo_string_vector (Operand *range,int lo,int hi);
- Allocates storage large enough to hold the string vector from the NExS spreadsheet
pointed to by Operand range.
FORTRAN equivalent:
NONE.
- char* ** nexs_io_alo_string_matrix (Operand *range,int rlo,int rhi,int clo,int chi);
- Allocates storage large enough to hold the string matrix from the NExS spreadsheet
pointed to by Operand range.
FORTRAN equivalent:
NONE.
- char* * nexs_io_get_string_vector (Operand *range,int lo,int hi);
- 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.
- char* ** nexs_io_get_string_matrix (Operand *range,int rlo,int rhi,int clo,int chi);
- 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.
- void nexs_io_str_string_vector (char* *v,Operand *range,int lo,int hi);
- Stores the values from a vector of strings into the NExS spreadsheet at a location
indicated by Operand range.
FORTRAN equivalent:
NONE.
- void nexs_io_str_string_matrix (char* **m,Operand *range,int rlo,int rhi,int clo,int
chi);
- Stores the values from a matrix of strings into the NExS spreadsheet at a location
indicated by Operand range.
FORTRAN equivalent:
NONE.
- void nexs_io_fre_string_vector (char* *v,Operand *range,int lo,int hi);
- Frees the storage created when getting the vector of strings from the NExS spreadsheet
indicated by Operand range.
FORTRAN equivalent:
NONE.
- void nexs_io_fre_string_matrix (char* **m,Operand *range,int rlo,int rhi,int clo,int
chi);
- Frees the storage created when getting the matrix of strings from the NExS spreadsheet
indicated by Operand range.
FORTRAN equivalent:
NONE.
The NExS Connection Library provides the ability to define new functions which are
syntactically and semantically identical NExS intrinsic functions. These user-defined
functions reside in NExS connection clients and thus are installed at run-time. The
connection library routine nexs_install_function() (described above and illustrated below)
accomplishes the installation. In the case of remote functions, the role of client and
server appears to be reversed: the NExS connection client acts as a "remote function
server." That is, during the recalculation of the NExS spreadsheet, NExS will invoke
the callback installed for the remote function and pass it the argument list entered in
the spreadsheet.
The arguments to the remote function are passed as an array of structures of type
"Operand." The details of the Operand structure may be found in the header file
"nexs.h" and its use is illustrated in the examples below. The first element of
the Operand array contains a count of the actual number of arguments passed. For example,
suppose we have a remote function callback declared as follows: "Operand remote_fn(
Operand argv[] )." The number of arguments to the function is then given by the
integer value "argv[0].val.count." The first argument is stored in argv[1], etc.
Each argument in the array has a type (argv[i].type) and value (argv[i].val) field. The
format of the value field depends on the type. The possible argument types are ARG_NUMBER,
ARG_STRING, ARG_CELL, and ARG_RANGE. The function must return a result with one of these
types (although it is rare to return ARG_CELL or ARG_RANGE). A function may also return
ARG_ERROR if it wishes to indicate an error condition. When returning a result of type
ARG_STRING or ARG_ERROR, the function must first copy the string value or error message to
the 512 byte buffer "nexs_sbuf."
When NExS invokes a remote function, it blocks any connection I/O on other ports until
the remote function returns. This is to prevent the state of the spreadsheet from changing
in some unpredictable way while its contents are being recalculated. Since it is almost
always necessary for a remote function to query NExS (e.g., to retrieve the contents of a
cell or range passed as an argument to the function), NExS will allow dialog to take place
on the port where the remote function was invoked, and ONLY that port. Whenever a remote
function (or remote menu callback) is invoked, the global variable "nexs_port"
is set to the port ID on which the function (or menu callback) is being invoked. This is
necessary when clients are connected to more than one instance of NExS (see "server.c" for an example). A simple rule of thumb is that
all dialog with NExS from within a remote function should take place on
"nexs_port."
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.
- void nexs_install_function(int port, char *name, Operand (*callback)(), int tag);
- 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
These functions allow a connection program to query the location of the cell cursor,
and also to move about the spreadsheet by moving the cell cursor.
- int nexs_get_location(int port, int *rowp, int *colp);
- 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
- void nexs_goto(int port, int row, int 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
- void nexs_moveto(int port, int row, int 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
These functions allow a connection program to establish new menu selections on the NExS
menu bar, and to associate buttons on the new menu selections with functions in the
connection program. There are also functions to control the sensitivity of menu buttons,
add mnemonics and accelerators, change the button labels, and delete the client menus and
buttons.
- long nexs_create_menu(int port, char *name);
- 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
- long nexs_create_button(int port, long menuID, char *name, void (*callback)(), int
tag);
- 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
- int nexs_button_accel(int port, long menuID, long buttonID, KeySym mnemonic, char
*accel, char *accel_text);
- 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");
- void nexs_delete_menu(int port, long menuID);
- Deletes the specified menu and all its associated buttons.
FORTRAN equivalent:
subroutine xsdmnu(port, menuid)
integer port, menuid
- void nexs_delete_button(port, menuID, buttonID);
- 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
- void nexs_menu_sensitivity(int port, long menuID, int sensitivity);
- 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.
- void nexs_button_sensitivity(int port, long menuID, long buttonID, int sensitivity);
- 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.
- void nexs_menu_label(int port, long menuID, char *label);
- 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.
- void nexs_button_label(int port, long menuID, long buttonID, char *label);
- 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.
These functions allow a connection client program to force the spreadsheet to
recalculate itself, update the calculated value of individual cells, compute the value of
arbitrary spreadsheet formulas, and recalculate spreadsheet constraints.
- void nexs_recalc(int port, int force, int n, Range ranges[]);
- 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.)
- int nexs_evaluate_cell(int port, int row, int col, double *value, char **str);
- 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.)
- int nexs_evaluate_expr(int port, char *expr, double *value, char **string);
- 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.)
- int nexs_evaluate_constraint(int port, int row, int col);
- 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
- int nexs_recalc_constraints(int port);
- 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
These functions allow the connection client to request a range to be selected on the
spreadsheet, to retrieve the current selected spreadsheet range, and to query the extent
of all cells in the spreadsheet.
- int nexs_get_range(int port, int *rminp, int *cminp, int *rmaxp, int *cmaxp);
- 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
- int nexs_get_selected(int port, int *rminp, int *cminp, int *rmaxp, int *cmaxp);
- 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
- int nexs_get_extent(int port, int *rminp, int *cminp, int *rmaxp, int *cmaxp);
- 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
These functions support efficient searching for "labels", which are text
strings stored in cells. Labels are often used as mnemonic tags for data in the
spreadsheet.
- int nexs_find_label(int port, char *label, int *rp, int *cp);
- 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
- int nexs_find_label_in_range(int port, char *label, int rmin, int cmin, int rmax, int
cmax, int *rp, int *cp);
- 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
These functions allow manipulation of named ranges. Range names can be created,
resolved, and deleted.
- int nexs_define_name(int port, Range *rangep, char *name);
- 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".)
- int nexs_resolve_name(int port, Range *rangep, char *name);
- 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".)
- void nexs_delete_name(int port, char *name);
- Deletes the specified "name" from the NExS range name list.
FORTRAN
equivalent:
subroutine xsdlnam(port, name)
integer port
character*(*) name
These functions control a dialog box that allows a connection client to query the user
for textual input.
- void nexs_dialog(int port, char *prompt, char *deflt, void (*callback)(int status,
char *string));
- 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.
- int nexs_dialog_no_echo(int port, char *prompt, char *deflt, void (*callback)(int
status, char *string));
- 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.
- int nexs_get_input(int port, char *prompt, char *buf, int maxchars);
- 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.
These functions support all NExS file I/O, including reading, writing, importing,
exporting, and printing spreadsheets. A function is also provided to reset the spreadsheet
to its initial (unloaded) state.
- int nexs_read_file(int port, char *name);
- 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
- int nexs_write_file(int port, char *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
- int nexs_print(int port, int filetype, Range range, char *filename);
- 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.
- int nexs_import(int port, int filetype, char *filename, int r, int c);
- 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.
- int nexs_export(int port, int filetype, char *filename, Range range);
- 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.
- int nexs_clear_sheet(int port);
- Clears the entire spreadsheet and returns all settable parameters to their default
values. Returns 1 if successful, 0 otherwise.
These functions allow ranges of cells to be copied, moved, or erased; rows and columns
to be inserted or deleted, and pagebreaks to be inserted in the spreadsheet.
- int nexs_copy_range(int port, int vflag, Range src, Range dst);
- 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.
- int nexs_erase_range(int port, Range range);
- Erases the specified "range". Returns 1 if successful, 0 otherwise.
- int nexs_move_range(int port, Range src, int r_dst, int c_dst);
- 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.
- int nexs_insert_rows(int port, int row, int num_rows);
- Inserts the specified number of rows starting at row number "row". Returns 1
if successful, 0 otherwise.
- int nexs_insert_cols(int port, int col, int num_cols);
- Inserts the specified number of columns starting at column number "col".
Returns 1 if successful, 0 otherwise.
- int nexs_delete_rows(int port, int start_row, int end_row);
- Deletes rows "start_row" through "end_row", inclusive. Returns 1 if
successful, 0 otherwise.
- int nexs_delete_cols(int port, int start_col, int end_col);
- Deletes columns "start_col" through "end_col", inclusive. Returns 1
if successful, 0 otherwise.
- int nexs_insert_pagebreak(int port, int row);
- 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.
These functions allow column widths to be queried and set.
- int nexs_set_width(int port, int c0, int c1, int width, int dflag);
- 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.)
- int nexs_get_width(int port, int col, int *width);
- 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.
These functions allow cell attributes, such as font and format, to be queried and
controlled. (NOTE: The nexs_cell_attributes() function provides control of all NExS
cell attributes. The other functions are provided for backwards compatibility with earlier
spreadsheet products.)
- int nexs_set_format(int port, int fmt_code, int places, Range range);
- 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.
- int nexs_set_font(int port, int fnt_code, Range range);
- 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.
- int nexs_protect(int port, int flag, Range range);
- 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.
- int nexs_cell_attributes(int port, Range range, CellAttributes *attr, int mask, int
resolve_defaults);
- 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);
These functions allow connection clients to query or set row and column title regions
on a spreadsheet.
- int nexs_set_titles(int port, int r, int c, int mode);
- 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.
- int nexs_clear_titles(int port, int mode);
- 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.
These functions provide interfaces to the NExS searching, sorting, extraction, and goal
seek tools.
- int nexs_goal_seek(int port, int vr, int vc, int tr, int tc, double target, double
*x1, double *x2, int maxit, double tolerance);
- 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:
- A bracket does not exist; i.e., for all possible values that can be stored in cell (vr,
vc) the value in (tr, tc) will either be always greater than "target" or always
less than "target".
- A bracket exists, but because the function is not continuous there is no value which can
be stored in (vr, vc) that will cause the value in (tr, tc) to be equal to
"target".
- A solution exists, but the function is not well behaved on the interval between the
bracket values "x1" and "x2". This generally means that somewhere
between "x1" and "x2" the value of (tr, tc) will go to plus or minus
infinity, which causes the algorithm to break down.
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.
- int nexs_sort(int port, int dir, int mode, Range range, int keycol1, int keycol2);
- 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.
- int nexs_find(int port, int order, int dir, Range range, char *condition, int type,
int *find_r, *find_c);
- 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".
- int nexs_extract(int port, Range range, int keycol, char *condition, int type, int
r_dst, int c_dst);
- 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".
These functions control the NExS default characteristics and options.
- int nexs_sheet_defaults(int port, SheetDefaults *defaults, int mask);
- 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.
- int nexs_cell_defaults(int port, CellDefaults *defaults, int mask);
- 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.
- int nexs_ps_char(int port, PSDefaults *defaults, int mask);
- 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.
- int nexs_print_char(int port, PrintDefaults *defaults, int mask);
- 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.
- int nexs_import_characteristics(int port, int *one_word_per_col, int *ws_threshold,
int mask);
- 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.
These functions support the creation and manipulation of spreadsheet graphs by a
connection client.
- int nexs_new_graph(int port, int *new_gid);
- 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.
- int nexs_display_graph(int port, int gid);
- Causes the graph specified by "gid" to be displayed. Returns 1 if successful,
0 otherwise.
- int nexs_redraw_graph(int port, int gid);
- 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.
- int nexs_name_graph(int port, int gid, char *name_buf);
- 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.
- int nexs_duplicate_graph(int port, int gid, int *new_gid);
- 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.
- int nexs_delete_graph(int port, int gid);
- Deletes the graph specified by "gid". The graph's ID is reclaimed by NExS.
Returns 1 if successful, 0 otherwise.
- int nexs_print_graph(int port, int gid, int type, char *name);
- 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.
- int nexs_cancel_graph(int port, int gid);
- 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.
- int nexs_ggen_char(int port, int gid, GrGenChar *gchar, int mask);
- 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.
- int nexs_axis_char(int port, int gid, int axis, GrAxisChar axischar, int mask);
- 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.
- int nexs_gdata_char(int port, int gid, int dataset, NEXSGrDataChar *dchar, unsigned
long mask);
- 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);
- int xs2_gdata_char(int port, int dataset, XS2GrDataChar dchar, int 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.
- int nexs_rotate_graph(int port, int gid, GrRotate3D *grotate, int mask);
- 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.
- int nexs_graph_geometry(int port, int gid, GrGeometry ggeom, int mask);
- 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.
These functions allow a connection client to register callbacks for spreadsheet events,
such as when the sheet is reset to its initial state.
- void nexs_set_action_callback(void (*callback)(int port, int action));
- 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...)
- int nexs_set_action_notify(int port, int action, int flag);
- 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);
These are convenience functions which convert between internal cell and range
representations and their external representations.
- char *col_to_text(int column);
- 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().
- int text_to_col(char *name);
- 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.
- int text_to_rc(char *name, int *row, int *col);
- 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.
- int out_of_range(int row, int col);
- Returns 1 if "row" and "col" do not represent a cell address within
the range supported by NExS; 0 otherwise.
- int text_to_range(char *name, Range *range);
- Parses a cell or range name and stores the result in the structure "range".
Returns 1 if successful, 0 otherwise.
- char *range_to_text(Range *range);
- 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().
- int sort_range(Range *range);
- 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.
These functions provide special capabilities that do not belong in the categories
previously described.
- void nexs_display_message(int port, char *s);
- Displays the string "s" on the message line of the NExS status display.
FORTRAN
equivalent:
subroutine xsdmsg(port, msg)
integer port
character*(*) msg
- void nexs_scroll_range(int port, int rmin, int cmin, int rmax, int cmax, int
direction);
- 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.
- void nexs_user_lock(int port, int lockflag);
- 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
The NExS API supports multiple simultaneos X Window display connections for each
connection client. These functions manage the list of display identifiers and set the
"current active display" through which all functions communicate with a NExS
spreadsheet.
- int nexs_new_display(Display *dp);
- 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.
- int nexs_set_display(int displayID);
- Sets the current active display to displayID. Returns 0 if displayID is not valid;
returns displayID otherwise.
- int nexs_get_display(void);
- Returns the displayID of the current active display.
- int nexs_remove_display(int displayID);
- 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.
These functions facilitate incorporating API library functions in an X Window program
by providing access to low level interfaces between the API functions and the X Window
system.
- int nexs_message_handler(XEvent *event);
- 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.
- void nexs_dispatcher(void (*callback)());
- 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.
- void nexs_flush_port(int port);
- 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.
- void nexs_flush();
- 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
- Window nexs_window(int port);
- 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
- Window nexs_top_window(int 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.
- Window nexs_graph_window(int port, int gid);
- 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.
- Display *nexs_display(int port);
- 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().
- Display *nexs_display_from_ID(int displayID);
- 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.
These functions provide a convenient mechanism for multiple connection clients
connected to a single instance of NExS to communicate with each other. This could be
useful in sophisticated applications where a NExS instance is connected to several client
programs, perhaps running on different computers on a network.
- int nexs_inquire_connections(int port, int status_list[MAX_PORTS+1], char
name_list[MAX_PORTS+1][11]);
- 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.
- int nexs_send_message(int port, int remote_port, char message[15]);
- 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.
- void nexs_set_receiver(void (*recv_fn)(int port, char message[15]));
- 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.
- int nexs_message_wait(int port, int remote_port, char msg_buf[15]);
- 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.
The NExS API supports the concept of a "NExS connection manager" running on
an X Window display. The "NExS connection manager" is analogous to a window
manager, such as "mwm" or "fvwm", in that it has access to all NExS
instances running on the display. Only one connection manager may run on the display at
any given time. Some connection managment functions have special privileges that allow the
connection manager special access to NExS instances that is not allowed for normal
connection clients. A NExS connection manager would typically run in the background and
automatically connect itself to any NExS instance invoked on the display. It could thus be
used to provide custom extensions for sophisticated NExS applications.
- int mgr_manage_display(int displayID);
- 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.
- int mgr_unmanage_display(int displayID);
- 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.
- int mgr_set_nexs_notify(void (*nexs_notify_fn)(int displayID, Window w));
- 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.
- int mgr_set_acceptor(int displayID, Window nexs_window);
- 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.
- int mgr_connect(int displayID, Window nexs_window, char *name);
- 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()":
- NExS need not be in "accepting connections" mode for the connection to be
established, and
- the connection is silent; i.e., no message appears on the NExS status line when the
connection is made.
The request will fail and return 0 if:
- NExS connections are locked,
- no ports are available, or
- the caller is not registered as manager for the display.
- Window nexs_get_acceptor(int displayID);
- 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.
- char *nexs_get_name(int displayID, Window nexs_window);
- 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.
- int nexs_scan_display(int displayID, Window **nexs_windows, int *num_windows);
- 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.
A few global variables are provided, mostly for historical reasons. They provide access
to current state information during NExS connection processing.
- int nexs_port
- 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.)
- int nexs_row, nexs_col
- 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.
- int nexs_recalc_flags
- 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.
- int nexs_conv_warn
- 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, 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);
}
The following example program creates three remote functions. The first, @NEXS(...), is
essentially a recreation of the built-in function @SUM(...), except that it treats string
arguments as errors rather than ignoring them. The second, @NEXS2(...), is similar to the
first except that it returns a string result. The third, @NEXS3(...), is an example of an
embedded tool which returns a two element vector containing (1) the sum of its arguments
and (2) two times the sum.
/*
*
* NExS Connection Library V1.0 (Beta release B, September 10, 1990)
* Copyright 1990, 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);
}
The following program illustrates how an NExS connection program can act as a remote
function "server" for multiple instances of NExS on a given display. The program
establishes an "alarm" which triggers periodic checks for a new copy of NExS to
connect to. If this program is run in the background, it will autmatically connect each
time NExS is run with connections enabled. Up to 63 instances of NExS may be
"served" simultaneously. (Some knowledge of UNIX system calls and X Window
programming is necessary to fully understand this example.)
/*
*
* NExS Connection Library V1.0 (Beta release B, September 10, 1990)
* Copyright 1990, 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);
}
|