CDK changes: Exclude the following source files: alphalist.c, button.c, calendar.c, cdk_compat.{c,h}, cdk_params.c, cdk_test.h, debug.c, dialog.c, {d,f}scale.{c,h}, fslider.{c,h}, gen-scale.{c,h}, get_index.c, get_string.c, graph.c, histogram.c, marquee.c, matrix.c, menu.c, popup_dialog.c, position.c, radio.c, scale.{c,h}, swindow.c, template.c, u{scale,slider}.{c,h}, view_{file,info}.c, and viewer.c. binding.c utilizes libtermkey for universal input. cdk.h does not #include matrix.h, viewer.h, and any headers labeled "Generated headers" due to their machine-dependence, except for slider.h. It also #defines "boolean" as "CDKboolean" on Windows platforms since the former is already a typedef. cdk_config.h no longer defines HAVE_SETLOCALE since Textadept handles locale settings, no longer defines HAVE_NCURSES_H and NCURSES since Textadept supports multiple curses implementations (not just ncurses), conditionally enables HAVE_GRP_H, HAVE_LSTAT, and HAVE_PWD_H definitions on *nix platforms since Windows does not have them, and explicitly undefines NCURSES_OPAQUE since newer versions of ncurses on macOS define it. cdk_util.h #defines "Beep" as "CDKBeep" on Windows platforms since Windows already defines Beep. The "baseName" and "dirName" functions in cdk.c recognize Window's '\' directory separator. Deactivated the "deleteFileCB" function in fselect.c. Removed some of CDK's initial screen handling code. cdk.c has some basic UTF-8 handling functions and draw.c, entry.c, and itemlist.c use them for UTF-8 drawing and character handling. (Note: mentry.c cannot handle UTF-8.) diff -r c40f79827990 binding.c --- a/binding.c Sun Nov 23 16:42:21 2014 -0500 +++ b/binding.c Sun Nov 23 16:45:38 2014 -0500 @@ -1,4 +1,6 @@ #include +#include "termkey.h" +extern TermKey *ta_tk; /* * $Author: tom $ @@ -167,7 +169,50 @@ { EObjectType cdktype = ObjTypeOf (obj); CDKOBJS *test = bindableObject (&cdktype, obj); - int result = wgetch (InputWindowOf (obj)); + int result = ERR; + TermKeyKey key; + int keysyms[] = {0,KEY_BACKSPACE,KEY_TAB,KEY_ENTER,KEY_ESC,0,0,KEY_UP,KEY_DOWN,KEY_LEFT,KEY_RIGHT,0,0,KEY_IC,KEY_DC,0,KEY_PPAGE,KEY_NPAGE,KEY_HOME,KEY_END}; + TermKeyResult res; +retry: + res = termkey_waitkey(ta_tk, &key); + switch (res) + { + case TERMKEY_RES_KEY: + switch (key.type) + { + case TERMKEY_TYPE_UNICODE: + result = key.code.codepoint; + if ((key.modifiers & TERMKEY_KEYMOD_CTRL) && + ((result >= 'a' && result <= 'z') || (result >= 'A' && result <= 'Z'))) + { + result = (result & ~0x60); + key.modifiers &= ~TERMKEY_KEYMOD_CTRL; + } + break; + case TERMKEY_TYPE_FUNCTION: + result = KEY_F(key.code.number); + break; + case TERMKEY_TYPE_KEYSYM: + result = keysyms[key.code.sym]; + if (key.code.sym == TERMKEY_SYM_TAB && key.modifiers & TERMKEY_KEYMOD_SHIFT) + result = KEY_BTAB; + break; + case TERMKEY_TYPE_UNKNOWN_CSI: + case TERMKEY_TYPE_MOUSE: + goto retry; + default: + result = ERR; + } + break; + case TERMKEY_RES_EOF: + case TERMKEY_RES_ERROR: + result = ERR; + break; + case TERMKEY_RES_NONE: + case TERMKEY_RES_AGAIN: + result = 0; + break; + } if (result >= 0 && test != 0 diff -r c40f79827990 cdk.c --- a/cdk.c Sun Nov 23 16:42:21 2014 -0500 +++ b/cdk.c Sun Nov 23 16:45:38 2014 -0500 @@ -453,6 +453,33 @@ return (from + (unsigned)(result - base)); } +unsigned int utf8charlen(unsigned char ch) +{ + if (ch < 0x80) { + return 1; + } else if (ch < 0x80 + 0x40 + 0x20) { + return 2; + } else if (ch < 0x80 + 0x40 + 0x20 + 0x10) { + return 3; + } else { + return 4; + } +} + +size_t utf8strlen(const char *s) +{ + size_t i, len = strlen(s), utf8len = 0; + for (i = 0; i < len; i+=utf8charlen(CharOf(s[i]))) utf8len++; + return utf8len; +} + +int utf8charpos(char *s, int pos) +{ + int i, len = (int)strlen(s), utf8len = 0; + for (i = 0; i < len; i+=utf8charlen(CharOf(s[i]))) if (utf8len++ >= pos) break; + return i; +} + /* * This function takes a character string, full of format markers * and translates them into a chtype * array. This is better suited @@ -472,6 +499,7 @@ chtype attrib; chtype lastChar; chtype mask; + char *s; (*to) = 0; *align = LEFT; @@ -763,7 +791,7 @@ result[0] = attrib; } } - *to = used; + for (int from = 0; from < used; from+=utf8charlen(CharOf(result[from]))) (*to)++; } else { @@ -1334,7 +1362,7 @@ for (x = pathLen - 1; x != 0; --x) { /* Find the last '/' in the pathname. */ - if (pathname[x] == '/') + if (pathname[x] == '/' || pathname[x] == '\\') { strcpy (base, pathname + x + 1); break; @@ -1361,7 +1389,7 @@ && (pathLen = strlen (pathname)) != 0) { size_t x = pathLen; - while ((dir[x] != '/') && (x > 0)) + while ((dir[x] != '/' && dir[x] != '\\') && (x > 0)) { dir[x--] = '\0'; } diff -r c40f79827990 cdk.h --- a/cdk.h Sun Nov 23 16:42:21 2014 -0500 +++ b/cdk.h Sun Nov 23 16:45:38 2014 -0500 @@ -226,6 +226,10 @@ */ typedef enum {vEARLY_EXIT, vESCAPE_HIT, vNORMAL, vNEVER_ACTIVATED, vERROR} EExitType; +#if _WIN32 +#define boolean CDKboolean +#endif + /* * This defines a boolean type. */ @@ -300,7 +304,7 @@ #include #include #include -#include +//#include #include #include #include @@ -308,21 +312,21 @@ #include #include #include -#include +//#include #include #include /* * Generated headers: */ -#include -#include -#include -#include - -#include -#include -#include +//#include +//#include +//#include +//#include +// +//#include +#include +//#include /* * Low-level object drawing diff -r c40f79827990 cdk_config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cdk_config.h Sun Nov 23 16:45:38 2014 -0500 @@ -0,0 +1,67 @@ +/* include/cdk_config.h. Generated automatically by configure. */ +/* + * $Id: config.hin,v 1.2 2000/01/17 14:48:19 tom Exp $ + */ + +#ifndef CDK_CONFIG_H +#define CDK_CONFIG_H 1 + + +#define CC_HAS_PROTOS 1 +#define CDK_CONST /*nothing*/ +#define CDK_CSTRING CDK_CONST char * +#define CDK_CSTRING2 CDK_CONST char * CDK_CONST * +#define CDK_PATCHDATE 20140118 +#define CDK_VERSION "5.0" +#define HAVE_DIRENT_H 1 +#define HAVE_GETBEGX 1 +#define HAVE_GETBEGY 1 +#define HAVE_GETCWD 1 +#define HAVE_GETLOGIN 1 +#define HAVE_GETMAXX 1 +#define HAVE_GETMAXY 1 +#define HAVE_GETOPT_H 1 +#define HAVE_GETOPT_HEADER 1 +#if !_WIN32 +#define HAVE_GRP_H 1 +#endif +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#if !_WIN32 +#define HAVE_LSTAT 1 +#endif +#define HAVE_MEMORY_H 1 +#define HAVE_MKTIME 1 +//#define HAVE_NCURSES_H 1 +#if !_WIN32 +#define HAVE_PWD_H 1 +#endif +#define HAVE_SETLOCALE 1 +#define HAVE_SLEEP 1 +#define HAVE_START_COLOR 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRDUP 1 +#define HAVE_STRERROR 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_TERM_H 1 +#define HAVE_TYPE_CHTYPE 1 +#define HAVE_UNCTRL_H 1 +#define HAVE_UNISTD_H 1 +#define MIXEDCASE_FILENAMES 1 +//#define NCURSES 1 +#define NCURSES_OPAQUE 0 +#define PACKAGE "cdk" +#define STDC_HEADERS 1 +#define SYSTEM_NAME "linux-gnu" +#define TYPE_CHTYPE_IS_SCALAR 1 +#define setbegyx(win,y,x) ((win)->_begy = (y), (win)->_begx = (x), OK) + +#if !defined(HAVE_LSTAT) && !defined(lstat) +#define lstat(f,b) stat(f,b) +#endif + +#endif /* CDK_CONFIG_H */ diff -r c40f79827990 cdk_util.h --- a/cdk_util.h Sun Nov 23 16:42:21 2014 -0500 +++ b/cdk_util.h Sun Nov 23 16:45:38 2014 -0500 @@ -53,6 +53,10 @@ * SUCH DAMAGE. */ +#if _WIN32 +#define Beep CDKBeep +#endif + /* * This beeps at the user. The standard curses beep() does not * flush the stream, so it will only beep until a force is made. @@ -280,6 +284,14 @@ int /* length */, chtype /* character */); +#define HAVE_CDKUTF8 1 +/* This takes the first byte of a UTF-8 character and returns the length of that character. */ +unsigned int utf8charlen(unsigned char /* char */); +/* This returns the length of the UTF-8 string. */ +size_t utf8strlen(const char * /* string */); +/** This returns the absolute position in a UTF-8 string of a character position. */ +int utf8charpos(char * /* string */, int /* pos */); + /* * This takes a chtype pointer and returns a char pointer. */ diff -r c40f79827990 cdk_version.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cdk_version.h Sun Nov 23 16:45:38 2014 -0500 @@ -0,0 +1,56 @@ +/* + * $Id: cdk_version.hin,v 1.2 2012/03/20 22:10:36 tom Exp $ + */ + +#ifndef CDK_VERSION_H +#define CDK_VERSION_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Copyright 2002,2012 Thomas E. Dickey + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgment: + * This product includes software developed by Thomas E. Dickey + * and contributors. + * 4. Neither the name of Thomas E. Dickey, nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THOMAS E. DICKEY AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THOMAS E. DICKEY OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#define CDK_VERSION_MAJOR "5" +#define CDK_VERSION_MINOR "0" +#define CDK_VERSION_PATCH "20140118" + +/* + * Runtime to return the same version information. + */ +const char *CDKVersion (void); + +#ifdef __cplusplus +} +#endif + +#endif /* CDK_VERSION_H */ diff -r c40f79827990 cdkscreen.c --- a/cdkscreen.c Sun Nov 23 16:42:21 2014 -0500 +++ b/cdkscreen.c Sun Nov 23 16:45:38 2014 -0500 @@ -180,24 +180,6 @@ ALL_SCREENS *item; CDKSCREEN *screen = 0; - /* initialization, for the first time */ - if (all_screens == 0 || stdscr == 0 || window == 0) - { - /* Set up basic curses settings. */ -#ifdef HAVE_SETLOCALE - setlocale (LC_ALL, ""); -#endif - /* Initialize curses after setting the locale, since curses depends - * on having a correct locale to reflect the terminal's encoding. - */ - if (stdscr == 0 || window == 0) - { - window = initscr (); - } - noecho (); - cbreak (); - } - if ((item = typeMalloc (ALL_SCREENS)) != 0) { if ((screen = typeCalloc (CDKSCREEN)) != 0) diff -r c40f79827990 draw.c --- a/draw.c Sun Nov 23 16:42:21 2014 -0500 +++ b/draw.c Sun Nov 23 16:45:38 2014 -0500 @@ -338,23 +338,34 @@ int diff = end - start; int display = 0; int x = 0; + char *s, *p; + attr_t current_attr; + short pair; + int charlen; + s = chtype2Char (string), p = s + start; + wattr_get (window, ¤t_attr, &pair, NULL); // save original attrs + wattr_set (window, (string[x] & ~A_CHARTEXT) | attr, pair, NULL); // set new attrs if (align == HORIZONTAL) { /* Draw the message on a horizontal axis. */ display = MINIMUM (diff, getmaxx (window) - xpos); - for (x = 0; x < display; x++) + for (x = 0; x < display; x++, p+=charlen) { - CDKmvwaddch (window, ypos, xpos + x, string[x + start], attr); + charlen = utf8charlen(*p); + (void)mvwaddnstr (window, ypos, xpos + x, (const char *)p, charlen); } } else { /* Draw the message on a vertical axis. */ display = MINIMUM (diff, getmaxy (window) - ypos); - for (x = 0; x < display; x++) + for (x = 0; x < display; x++, p+=charlen) { - CDKmvwaddch (window, ypos + x, xpos, string[x + start], attr); + charlen = utf8charlen(*p); + (void)mvwaddnstr (window, ypos + x, xpos, (const char *)p, charlen); } } + wattr_set (window, current_attr, pair, NULL); // restore original attrs + freeChar (s); } diff -r c40f79827990 entry.c --- a/entry.c Sun Nov 23 16:42:21 2014 -0500 +++ b/entry.c Sun Nov 23 16:45:38 2014 -0500 @@ -223,13 +223,13 @@ { int stringLen; - stringLen = (int)strlen (entry->info); + stringLen = (int)utf8strlen (entry->info); if (stringLen >= entry->fieldWidth) { if (stringLen < entry->max) { int charCount = entry->fieldWidth - 1; - entry->leftChar = stringLen - charCount; + entry->leftChar = stringLen - charCount; // horizontal scrolling with UTF8 does not work entry->screenCol = charCount; } else @@ -245,6 +245,8 @@ } } +static inline int isUtf8CharPart(unsigned int ch) { return (ch >= 0x80) && (ch < 0xc0); } + /* * This injects a single character into the widget. */ @@ -284,7 +286,7 @@ else { int infoLength = (int)strlen (widget->info); - int currPos = widget->screenCol + widget->leftChar; + int currPos = utf8charpos (widget->info, widget->screenCol) + widget->leftChar; switch (input) { @@ -332,6 +334,7 @@ else { wmove (widget->fieldWin, 0, --widget->screenCol); + drawCDKEntryField (widget); } break; @@ -350,6 +353,7 @@ { /* Move right. */ wmove (widget->fieldWin, 0, ++widget->screenCol); + drawCDKEntryField (widget); } break; @@ -364,22 +368,27 @@ bool success = FALSE; if (input == KEY_BACKSPACE) + { + while (currPos >= 1 && isUtf8CharPart(CharOf(widget->info[currPos - 1]))) currPos--; --currPos; + } if (currPos >= 0 && infoLength > 0) { if (currPos < infoLength) { int x; + int len = utf8charlen(widget->info[currPos]); for (x = currPos; x < infoLength; x++) { - widget->info[x] = widget->info[x + 1]; + widget->info[x] = widget->info[x + len]; } success = TRUE; } else if (input == KEY_BACKSPACE) { + while (infoLength >= 1 && isUtf8CharPart(CharOf(widget->info[infoLength - 1]))) infoLength--; widget->info[infoLength - 1] = '\0'; success = TRUE; } @@ -551,6 +560,23 @@ } } +static void toutf8(int code, char *s, int *len) { + int b; + if (code < 0x80) *len = 1; + else if (code < 0x800) *len = 2; + else if (code < 0x10000) *len = 3; + else if (code < 0x200000) *len = 4; + else if (code < 0x4000000) *len = 5; + else *len = 6; + for (b = *len - 1; b > 0; b--) s[b] = 0x80 | (code & 0x3F), code >>= 6; + if (*len == 1) s[0] = code & 0x7F; + else if (*len == 2) s[0] = 0xC0 | (code & 0x1F); + else if (*len == 3) s[0] = 0xE0 | (code & 0x0F); + else if (*len == 4) s[0] = 0xF0 | (code & 0x07); + else if (*len == 5) s[0] = 0xF8 | (code & 0x03); + else if (*len == 6) s[0] = 0xFC | (code & 0x01); +} + /* * This is a generic character parser for the entry field. It is used as a * callback function, so any personal modifications can be made by creating @@ -558,38 +584,42 @@ * a new function and calling the activation with its name. */ static void CDKEntryCallBack (CDKENTRY *entry, chtype character) { - int plainchar = filterByDisplayType (entry->dispType, character); + int plainchar = character; + char utf8[6]; + int len; if (plainchar == ERR || - ((int)strlen (entry->info) >= entry->max)) + ((int)utf8strlen (entry->info) >= entry->max)) { Beep (); } else { + toutf8(plainchar, utf8, &len); /* Update the screen and pointer. */ if (entry->screenCol != entry->fieldWidth - 1) { int x; + int pos = utf8charpos (entry->info, entry->screenCol) + entry->leftChar; - for (x = (int)strlen (entry->info); - x > (entry->screenCol + entry->leftChar); + for (x = (int)strlen (entry->info) + len - 1; + x > pos + len - 1; x--) { - entry->info[x] = entry->info[x - 1]; + entry->info[x] = entry->info[x - len]; } - entry->info[entry->screenCol + entry->leftChar] = (char)plainchar; + strncpy(entry->info + pos, utf8, len); entry->screenCol++; } else { /* Update the character pointer. */ size_t temp = strlen (entry->info); - entry->info[temp] = (char)plainchar; - entry->info[temp + 1] = '\0'; + strncpy(entry->info + temp, utf8, len); + entry->info[temp + len] = '\0'; /* Do not update the pointer if it's the last character */ - if ((int)(temp + 1) < entry->max) + if ((int)(temp + len + 1) < entry->max) entry->leftChar++; } @@ -660,6 +690,8 @@ { int infoLength = 0; int x = 0; + char *p; + int charlen; /* Draw in the filler characters. */ (void)mvwhline (entry->fieldWin, 0, x, entry->filler, entry->fieldWidth); @@ -667,7 +699,7 @@ /* If there is information in the field. Then draw it in. */ if (entry->info != 0) { - int infoLength = (int)strlen (entry->info); + int infoLength = (int)utf8strlen (entry->info); /* Redraw the field. */ if (isHiddenDisplayType (entry->dispType)) @@ -679,10 +711,12 @@ } else { - for (x = entry->leftChar; x < infoLength; x++) + p = entry->info + entry->leftChar; + for (x = entry->leftChar; x < infoLength; x++, p+=charlen) { - (void)mvwaddch (entry->fieldWin, 0, x - entry->leftChar, - CharOf (entry->info[x]) | entry->fieldAttr); + charlen = utf8charlen(CharOf (*p)); + (void)mvwaddnstr (entry->fieldWin, 0, x - entry->leftChar, + (const char *)p, charlen); } } wmove (entry->fieldWin, 0, entry->screenCol); diff -r c40f79827990 fselect.c --- a/fselect.c Sun Nov 23 16:42:21 2014 -0500 +++ b/fselect.c Sun Nov 23 16:45:38 2014 -0500 @@ -1104,7 +1104,7 @@ static char *make_pathname (const char *directory, const char *filename) { - size_t need = strlen (filename) + 2; + size_t need = strlen (filename) + 3; bool root = (strcmp (directory, "/") == 0); char *result; @@ -1316,6 +1316,7 @@ */ void deleteFileCB (EObjectType objectType GCC_UNUSED, void *object, void *clientData) { +#if 0 CDKSCROLL *fscroll = (CDKSCROLL *)object; CDKFSELECT *fselect = (CDKFSELECT *)clientData; const char *buttons[] = @@ -1374,6 +1375,7 @@ /* Redraw the file selector. */ drawCDKFselect (fselect, ObjOf (fselect)->box); +#endif } /* diff -r c40f79827990 gen-scale.c --- a/gen-scale.c Sun Nov 23 16:42:21 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,817 +0,0 @@ -#include - -/* - * $Author: tom $ - * $Date: 2016/11/20 18:32:34 $ - * $Revision: 1.25 $ - */ - -/* - * Declare file local prototypes. - */ -static void drawCDKField (CDK * widget); - -DeclareCDKObjects (, , setCdk, ); - -/* - * This function creates a widget. - */ -CDK *newCDK (CDKSCREEN *cdkscreen, - int xplace, - int yplace, - const char *title, - const char *label, - chtype fieldAttr, - int fieldWidth, - start, - low, - high, - inc, - fastInc, -#if - int digits, -#endif - boolean Box, - boolean shadow) -{ - /* *INDENT-EQLS* */ - CDK *widget = 0; - int parentWidth = getmaxx (cdkscreen->window); - int parentHeight = getmaxy (cdkscreen->window); - int boxHeight; - int boxWidth; - int horizontalAdjust, oldWidth; - int xpos = xplace; - int ypos = yplace; - int x, junk; - /* *INDENT-OFF* */ - static const struct { int from; int to; } bindings[] = { - { 'u', KEY_UP }, - { 'U', KEY_PPAGE }, - { CDK_BACKCHAR, KEY_PPAGE }, - { CDK_FORCHAR, KEY_NPAGE }, - { 'g', KEY_HOME }, - { '^', KEY_HOME }, - { 'G', KEY_END }, - { '$', KEY_END }, - }; - /* *INDENT-ON* */ - - - if ((widget = newCDKObject (CDK, &my_funcs)) == 0) - return (0); - - setCDKBox (widget, Box); - - boxHeight = (BorderOf (widget) * 2) + 1; - - /* Set some basic values of the widget's data field. */ - widget->label = 0; - widget->labelLen = 0; - widget->labelWin = 0; - - /* - * If the fieldWidth is a negative value, the fieldWidth will - * be COLS-fieldWidth, otherwise, the fieldWidth will be the - * given width. - */ - fieldWidth = setWidgetDimension (parentWidth, fieldWidth, 0); - boxWidth = fieldWidth + 2 * BorderOf (widget); - - /* Translate the label char *pointer to a chtype pointer. */ - if (label != 0) - { - widget->label = char2Chtype (label, &widget->labelLen, &junk); - boxWidth = widget->labelLen + fieldWidth + 2; - } - - oldWidth = boxWidth; - boxWidth = setCdkTitle (ObjOf (widget), title, boxWidth); - horizontalAdjust = (boxWidth - oldWidth) / 2; - - boxHeight += TitleLinesOf (widget); - - /* - * Make sure we didn't extend beyond the dimensions of the window. - */ - boxWidth = (boxWidth > parentWidth ? parentWidth : boxWidth); - boxHeight = (boxHeight > parentHeight ? parentHeight : boxHeight); - fieldWidth = (fieldWidth > (boxWidth - widget->labelLen - 2 * BorderOf (widget)) - ? (boxWidth - widget->labelLen - 2 * BorderOf (widget)) - : fieldWidth); - - /* Rejustify the x and y positions if we need to. */ - alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight); - - /* Make the widget's window. */ - widget->win = newwin (boxHeight, boxWidth, ypos, xpos); - - /* Is the main window null??? */ - if (widget->win == 0) - { - destroyCDKObject (widget); - return (0); - } - - /* Create the widget's label window. */ - if (widget->label != 0) - { - widget->labelWin = subwin (widget->win, - 1, widget->labelLen, - ypos + TitleLinesOf (widget) + BorderOf (widget), - xpos + horizontalAdjust + BorderOf (widget)); - if (widget->labelWin == 0) - { - destroyCDKObject (widget); - return (0); - } - } - - /* Create the widget's data field window. */ - widget->fieldWin = subwin (widget->win, - 1, fieldWidth, - (ypos + TitleLinesOf (widget) + BorderOf (widget)), - (xpos - + widget->labelLen - + horizontalAdjust - + BorderOf (widget))); - if (widget->fieldWin == 0) - { - destroyCDKObject (widget); - return (0); - } - keypad (widget->fieldWin, TRUE); - keypad (widget->win, TRUE); - - /* *INDENT-EQLS* Create the widget's data field. */ - ScreenOf (widget) = cdkscreen; - widget->parent = cdkscreen->window; - widget->shadowWin = 0; - widget->boxWidth = boxWidth; - widget->boxHeight = boxHeight; - widget->fieldWidth = fieldWidth; - widget->fieldAttr = (chtype)fieldAttr; - widget->current = low; - widget->low = low; - widget->high = high; - widget->current = start; - widget->inc = inc; - widget->fastinc = fastInc; -#if - widget->digits = digits; -#endif - initExitType (widget); - ObjOf (widget)->acceptsFocus = TRUE; - ObjOf (widget)->inputWindow = widget->win; - widget->shadow = shadow; - - /* Do we want a shadow??? */ - if (shadow) - { - widget->shadowWin = newwin (boxHeight, boxWidth, ypos + 1, xpos + 1); - if (widget->shadowWin == 0) - { - destroyCDKObject (widget); - return (0); - } - } - - /* Setup the key bindings. */ - for (x = 0; x < (int)SIZEOF (bindings); ++x) - bindCDKObject (v, - widget, - (chtype) bindings[x].from, - getcCDKBind, - (void *)(long)bindings[x].to); - - registerCDKObject (cdkscreen, v, widget); - - return (widget); -} - -/* - * This allows the person to use the widget's data field. - */ - activateCDK (CDK * widget, chtype *actions) -{ - ret; - - /* Draw the widget. */ - drawCDK (widget, ObjOf (widget)->box); - - if (actions == 0) - { - chtype input = 0; - boolean functionKey; - - for (;;) - { - input = (chtype) getchCDKObject (ObjOf (widget), &functionKey); - - /* Inject the character into the widget. */ - ret = () injectCDK (widget, input); - if (widget->exitType != vEARLY_EXIT) - { - return ret; - } - } - } - else - { - int length = chlen (actions); - int x = 0; - - /* Inject each character one at a time. */ - for (x = 0; x < length; x++) - { - ret = () injectCDK (widget, actions[x]); - if (widget->exitType != vEARLY_EXIT) - { - return ret; - } - } - } - - /* Set the exit type and return. */ - setExitType (widget, 0); - return unknown; -} - -/* - * Check if the value lies outside the low/high range. If so, force it in. - */ -static void limitCurrentValue (CDK * widget) -{ - if (widget->current < widget->low) - { - widget->current = widget->low; - Beep (); - } - else if (widget->current > widget->high) - { - widget->current = widget->high; - Beep (); - } -} - -/* - * Move the cursor to the given edit-position. - */ -static int moveToEditPosition (CDK * widget, int newPosition) -{ - return wmove (widget->fieldWin, 0, widget->fieldWidth - newPosition - 1); -} - -/* - * Check if the cursor is on a valid edit-position. This must be one of - * the non-blank cells in the field. - */ -static int validEditPosition (CDK * widget, int newPosition) -{ - chtype ch; - if (newPosition <= 0 || newPosition >= widget->fieldWidth) - return FALSE; - if (moveToEditPosition (widget, newPosition) == ERR) - return FALSE; - ch = winch (widget->fieldWin); - if (CharOf (ch) != ' ') - return TRUE; - if (newPosition > 1) - { - /* don't use recursion - only one level is wanted */ - if (moveToEditPosition (widget, newPosition - 1) == ERR) - return FALSE; - ch = winch (widget->fieldWin); - return CharOf (ch) != ' '; - } - return FALSE; -} - -/* - * Set the edit position. Normally the cursor is one cell to the right of - * the editable field. Moving it left, over the field allows the user to - * modify cells by typing in replacement characters for the field's value. - */ -static void setEditPosition (CDK * widget, int newPosition) -{ - if (newPosition < 0) - { - Beep (); - } - else if (newPosition == 0) - { - widget->fieldEdit = newPosition; - } - else if (validEditPosition (widget, newPosition)) - { - widget->fieldEdit = newPosition; - } - else - { - Beep (); - } -} - -/* - * Remove the character from the string at the given column, if it is blank. - * Returns true if a change was made. - */ -static bool removeChar (char *string, int col) -{ - bool result = FALSE; - - if ((col >= 0) && (string[col] != ' ')) - { - while (string[col] != '\0') - { - string[col] = string[col + 1]; - ++col; - } - result = TRUE; - } - return result; -} - -/* - * Perform an editing function for the field. - */ -static bool performEdit (CDK * widget, chtype input) -{ - bool result = FALSE; - bool modify = TRUE; - int need = widget->fieldWidth; - char *temp = (char *)malloc ((size_t) need + 2); - char test; - int col = need - widget->fieldEdit - 1; -#if - double value; -#define SCANF_FMT "%lg%c" -#endif -#if - value; -#define SCANF_FMT "%%c" -#endif - - if (temp != 0) - { - int base = 0; - - wmove (widget->fieldWin, 0, base); - winnstr (widget->fieldWin, temp, need); - strcpy (temp + need, " "); - if (isChar (input)) /* replace the char at the cursor */ - { - temp[col] = (char) (input); - } - else if (input == KEY_BACKSPACE) /* delete the char before the cursor */ - { - modify = removeChar (temp, col - 1); - } - else if (input == KEY_DC) /* delete the char at the cursor */ - { - modify = removeChar (temp, col); - } - else - { - modify = FALSE; - } - if (modify - && sscanf (temp, SCANF_FMT, &value, &test) == 2 - && test == ' ' - && value >= widget->low - && value <= widget->high) - { - setCDKValue (widget, () value); - result = TRUE; - } - free (temp); - } - return result; -} - -#define Decrement(value,by) if (value - by < value) value -= by -#define Increment(value,by) if (value + by > value) value += by - -/* - * This function injects a single character into the widget. - */ -static int _injectCDK (CDKOBJS *object, chtype input) -{ - CDK *widget = (CDK *) object; - int ppReturn = 1; - ret = unknown; - bool complete = FALSE; - - /* Set the exit type. */ - setExitType (widget, 0); - - /* Draw the field. */ - drawCDKField (widget); - - /* Check if there is a pre-process function to be called. */ - if (PreProcessFuncOf (widget) != 0) - { - /* Call the pre-process function. */ - ppReturn = PreProcessFuncOf (widget) (v, - widget, - PreProcessDataOf (widget), - input); - } - - /* Should we continue? */ - if (ppReturn != 0) - { - /* Check for a key binding. */ - if (checkCDKObjectBind (v, widget, input) != 0) - { - checkEarlyExit (widget); - complete = TRUE; - } - else - { - switch (input) - { - case KEY_LEFT: - setEditPosition (widget, widget->fieldEdit + 1); - break; - - case KEY_RIGHT: - setEditPosition (widget, widget->fieldEdit - 1); - break; - - case KEY_DOWN: - Decrement (widget->current, widget->inc); - break; - - case KEY_UP: - Increment (widget->current, widget->inc); - break; - - case KEY_PPAGE: - Increment (widget->current, widget->fastinc); - break; - - case KEY_NPAGE: - Decrement (widget->current, widget->fastinc); - break; - - case KEY_HOME: - widget->current = widget->low; - break; - - case KEY_END: - widget->current = widget->high; - break; - - case KEY_TAB: - case KEY_ENTER: - setExitType (widget, input); - ret = (widget->current); - complete = TRUE; - break; - - case KEY_ESC: - setExitType (widget, input); - complete = TRUE; - break; - - case KEY_ERROR: - setExitType (widget, input); - complete = TRUE; - break; - - case CDK_REFRESH: - eraseCDKScreen (ScreenOf (widget)); - refreshCDKScreen (ScreenOf (widget)); - break; - - default: - if (widget->fieldEdit) - { - if (!performEdit (widget, input)) - Beep (); - } - else - { - /* - * The cursor is not within the editable text. Interpret - * input as commands. - */ - switch (input) - { - case 'd': - case '-': - return _injectCDK (object, KEY_DOWN); - case '+': - return _injectCDK (object, KEY_UP); - case 'D': - return _injectCDK (object, KEY_NPAGE); - case '0': - return _injectCDK (object, KEY_HOME); - default: - Beep (); - break; - } - } - break; - } - } - limitCurrentValue (widget); - - /* Should we call a post-process? */ - if (!complete && (PostProcessFuncOf (widget) != 0)) - { - PostProcessFuncOf (widget) (v, - widget, - PostProcessDataOf (widget), - input); - } - } - - if (!complete) - { - drawCDKField (widget); - setExitType (widget, 0); - } - - ResultOf (widget).value = ret; - return (ret != unknown); -} - -/* - * This moves the widget's data field to the given location. - */ -static void _moveCDK (CDKOBJS *object, - int xplace, - int yplace, - boolean relative, - boolean refresh_flag) -{ - CDK *widget = (CDK *) object; - int currentX = getbegx (widget->win); - int currentY = getbegy (widget->win); - int xpos = xplace; - int ypos = yplace; - int xdiff = 0; - int ydiff = 0; - - /* - * If this is a relative move, then we will adjust where we want - * to move to. - */ - if (relative) - { - xpos = getbegx (widget->win) + xplace; - ypos = getbegy (widget->win) + yplace; - } - - /* Adjust the window if we need to. */ - alignxy (WindowOf (widget), &xpos, &ypos, widget->boxWidth, widget->boxHeight); - - /* Get the difference. */ - xdiff = currentX - xpos; - ydiff = currentY - ypos; - - /* Move the window to the new location. */ - moveCursesWindow (widget->win, -xdiff, -ydiff); - moveCursesWindow (widget->labelWin, -xdiff, -ydiff); - moveCursesWindow (widget->fieldWin, -xdiff, -ydiff); - moveCursesWindow (widget->shadowWin, -xdiff, -ydiff); - - /* Touch the windows so they 'move'. */ - refreshCDKWindow (WindowOf (widget)); - - /* Redraw the window, if they asked for it. */ - if (refresh_flag) - { - drawCDK (widget, ObjOf (widget)->box); - } -} - -/* - * This function draws the widget. - */ -static void _drawCDK (CDKOBJS *object, boolean Box) -{ - CDK *widget = (CDK *) object; - - /* Draw the shadow. */ - if (widget->shadowWin != 0) - { - drawShadow (widget->shadowWin); - } - - /* Box the widget if asked. */ - if (Box) - { - drawObjBox (widget->win, ObjOf (widget)); - } - - drawCdkTitle (widget->win, object); - - /* Draw the label. */ - if (widget->labelWin != 0) - { - writeChtype (widget->labelWin, 0, 0, - widget->label, - HORIZONTAL, 0, - widget->labelLen); - wrefresh (widget->labelWin); - } - wrefresh (widget->win); - - /* Draw the field window. */ - drawCDKField (widget); -} - -/* - * This draws the widget. - */ -static void drawCDKField (CDK * widget) -{ - char temp[256]; - - werase (widget->fieldWin); - - /* Draw the value in the field. */ -#if - { - char format[256]; - int digits = MINIMUM (widget->digits, 30); - sprintf (format, "%%.%i", digits); - sprintf (temp, format, widget->current); - } -#endif -#if - sprintf (temp, "%", widget->current); -#endif - writeCharAttrib (widget->fieldWin, - widget->fieldWidth - (int)strlen (temp) - 1, - 0, - temp, - widget->fieldAttr, - HORIZONTAL, - 0, - (int)strlen (temp)); - - moveToEditPosition (widget, widget->fieldEdit); - wrefresh (widget->fieldWin); -} - -/* - * This sets the background attribute of the widget. - */ -static void _setBKattr (CDKOBJS *object, chtype attrib) -{ - if (object != 0) - { - CDK *widget = (CDK *) object; - - wbkgd (widget->win, attrib); - wbkgd (widget->fieldWin, attrib); - if (widget->labelWin != 0) - { - wbkgd (widget->labelWin, attrib); - } - } -} - -/* - * This function destroys the widget. - */ -static void _destroyCDK (CDKOBJS *object) -{ - if (object != 0) - { - CDK *widget = (CDK *) object; - - cleanCdkTitle (object); - freeChtype (widget->label); - - /* Clean up the windows. */ - deleteCursesWindow (widget->fieldWin); - deleteCursesWindow (widget->labelWin); - deleteCursesWindow (widget->shadowWin); - deleteCursesWindow (widget->win); - - /* Clean the key bindings. */ - cleanCDKObjectBindings (v, widget); - - /* Unregister this object. */ - unregisterCDKObject (v, widget); - } -} - -/* - * This function erases the widget from the screen. - */ -static void _eraseCDK (CDKOBJS *object) -{ - if (validCDKObject (object)) - { - CDK *widget = (CDK *) object; - - eraseCursesWindow (widget->labelWin); - eraseCursesWindow (widget->fieldWin); - eraseCursesWindow (widget->win); - eraseCursesWindow (widget->shadowWin); - } -} - -/* - * This function sets the low/high/current values of the widget. - */ -void setCDK (CDK * widget, low, high, value, boolean Box) -{ - setCDKLowHigh (widget, low, high); - setCDKValue (widget, value); - setCDKBox (widget, Box); -} - -/* - * This sets the digits. - */ -#if -void setCDKDigits (CDK * widget, int digits) -{ - widget->digits = MAXIMUM (0, digits); -} - -int getCDKDigits (CDK * widget) -{ - return widget->digits; -} -#endif - -/* - * This sets the widget's value. - */ -void setCDKValue (CDK * widget, value) -{ - widget->current = value; - limitCurrentValue (widget); -} - getCDKValue (CDK * widget) -{ - return widget->current; -} - -/* - * This function sets the low/high values of the widget. - */ -void setCDKLowHigh (CDK * widget, low, high) -{ - /* Make sure the values aren't out of bounds. */ - if (low <= high) - { - widget->low = low; - widget->high = high; - } - else - { - widget->low = high; - widget->high = low; - } - - /* Make sure the user hasn't done something silly. */ - limitCurrentValue (widget); -} - getCDKLowValue (CDK * widget) -{ - return widget->low; -} - getCDKHighValue (CDK * widget) -{ - return widget->high; -} - -/* - * This sets the widget's box attribute. - */ -void setCDKBox (CDK * widget, boolean Box) -{ - ObjOf (widget)->box = Box; - ObjOf (widget)->borderSize = Box ? 1 : 0; -} -boolean getCDKBox (CDK * widget) -{ - return ObjOf (widget)->box; -} - -static void _focusCDK (CDKOBJS *object) -{ - CDK *widget = (CDK *) object; - - drawCDK (widget, ObjOf (widget)->box); -} - -static void _unfocusCDK (CDKOBJS *object) -{ - CDK *widget = (CDK *) object; - - drawCDK (widget, ObjOf (widget)->box); -} - -dummyRefreshData () - -dummySaveData () diff -r c40f79827990 gen-scale.h --- a/gen-scale.h Sun Nov 23 16:42:21 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,233 +0,0 @@ -/* - * $Id: gen-scale.h,v 1.8 2012/03/20 21:59:39 tom Exp $ - */ - -#ifndef CDKINCLUDES -#ifndef CDK_H -#define CDK_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef CDK_H -#define CDKINCLUDES -#include -#undef CDKINCLUDES -#include -#include -#include -#endif - -/* - * Copyright 2004,2012 Thomas E. Dickey - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgment: - * This product includes software developed by Thomas Dickey - * and contributors. - * 4. Neither the name of Thomas Dickey, nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THOMAS DICKEY AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THOMAS DICKEY OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Define the CDK widget structure. - */ -struct S { - CDKOBJS obj; - WINDOW * parent; - WINDOW * win; - WINDOW * shadowWin; - WINDOW * fieldWin; - WINDOW * labelWin; - int titleAdj; - chtype * label; - int labelLen; - int boxHeight; - int boxWidth; - int fieldWidth; - int fieldEdit; /* offset from right-margin of field */ - chtype fieldAttr; - low; - high; - inc; - fastinc; - current; -#if - int digits; -#endif - EExitType exitType; - boolean shadow; -}; -typedef struct S CDK; - -/* - * This creates a new pointer to a CDK - widget. - */ -CDK *newCDK ( - CDKSCREEN * /* cdkscreen */, - int /* xpos */, - int /* ypos */, - const char * /* title */, - const char * /* label */, - chtype /* fieldAttr */, - int /* fieldWidth */, - /* start */, - /* low */, - /* high */, - /* inc */, - /* fastInc */, -#if - int /* digits */, -#endif - boolean /* Box */, - boolean /* shadow */); - -/* - * This activates the widget. - */ - activateCDK ( - CDK * /* widget */, - chtype * /* actions */); - -/* - * This injects a single character into the widget. - */ -#define injectCDK(obj,input) injectCDKObject(obj,input,) - -/* - * This sets various attributes of the widget. - */ -void setCDK ( - CDK * /* widget */, - /* low */, - /* high */, - /* value */, - boolean /* Box */); - -/* - * These set/get the low and high values. - */ -void setCDKLowHigh ( - CDK * /* widget */, - /* low */, - /* high */); - - getCDKLowValue ( - CDK * /* widget */); - - getCDKHighValue ( - CDK * /* widget */); - -/* - * These set/get the digits. - */ -#if -void setCDKDigits ( - CDK * /* widget */, - int /* digits */); - -int getCDKDigits ( - CDK * /* widget */); -#endif - -/* - * These set/get the current value. - */ -void setCDKValue ( - CDK * /* widget */, - /* value */); - - getCDKValue ( - CDK * /* widget */); - -/* - * This sets the box attribute of the widget. - */ -void setCDKBox ( - CDK * /* widget */, - boolean /* Box */); - -boolean getCDKBox ( - CDK * /* widget */); - -/* - * These set the drawing characters of the widget. - */ -#define setCDKULChar(w,c) setULCharOf(w,c) -#define setCDKURChar(w,c) setURCharOf(w,c) -#define setCDKLLChar(w,c) setLLCharOf(w,c) -#define setCDKLRChar(w,c) setLRCharOf(w,c) -#define setCDKVerticalChar(w,c) setVTCharOf(w,c) -#define setCDKHorizontalChar(w,c) setHZCharOf(w,c) -#define setCDKBoxAttribute(w,c) setBXAttrOf(w,c) - -/* - * This sets the background color of the widget. - */ -#define setCDKBackgroundColor(w,c) setCDKObjectBackgroundColor(ObjOf(w),c) - -/* - * This sets the background attribute of the widget. - */ -#define setCDKBackgroundAttrib(w,c) setBKAttrOf(w,c) - -/* - * This draws the widget on the screen. - */ -#define drawCDK(obj,Box) drawCDKObject(obj,Box) - -/* - * This erases the widget from the screen. - */ -#define eraseCDK(obj) eraseCDKObject(obj) - -/* - * This moves the widget to the given location on the screen. - */ -#define moveCDK(obj,xpos,ypos,relative,refresh) moveCDKObject(obj,xpos,ypos,relative,refresh) - -/* - * This allows the user to interactively position the widget on the screen. - */ -#define positionCDK(widget) positionCDKObject(ObjOf(widget),widget->win) - -/* - * This destroys the widget and associated memory. - */ -#define destroyCDK(obj) destroyCDKObject(obj) - -/* - * These set the pre/post process callback functions. - */ -#define setCDKPreProcess(w,f,d) setCDKObjectPreProcess(ObjOf(w),f,d) -#define setCDKPostProcess(w,f,d) setCDKObjectPostProcess(ObjOf(w),f,d) - -#ifdef __cplusplus -} -#endif - -#endif /* CDK_H */ -#endif /* CDKINCLUDES */ diff -r c40f79827990 itemlist.c --- a/itemlist.c Sun Nov 23 16:42:21 2014 -0500 +++ b/itemlist.c Sun Nov 23 16:45:38 2014 -0500 @@ -449,6 +449,8 @@ int currentItem = itemlist->currentItem; int len; int x; + char *s, *p; + int charlen; /* Determine how much we have to draw. */ len = MINIMUM (itemlist->itemLen[currentItem], itemlist->fieldWidth); @@ -456,19 +458,25 @@ /* Erase the field window. */ werase (itemlist->fieldWin); + s = chtype2Char (itemlist->item[currentItem]), p = s; /* Draw in the current item in the field. */ - for (x = 0; x < len; x++) + for (x = 0; x < len; x++, p+=charlen) { - chtype c = itemlist->item[currentItem][x]; + charlen = utf8charlen(*p); if (highlight) { - c = CharOf (c) | A_REVERSE; + wattron(itemlist->fieldWin, A_REVERSE); } - (void)mvwaddch (itemlist->fieldWin, 0, + (void)mvwaddnstr (itemlist->fieldWin, 0, x + itemlist->itemPos[currentItem], - c); + (const char *)p, charlen); + + if (highlight) + { + wattroff(itemlist->fieldWin, A_REVERSE); + } } /* Redraw the field window. */ diff -r c40f79827990 matrix.c --- a/matrix.c Sun Nov 23 16:42:21 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1785 +0,0 @@ -#include - -/* - * $Author: tom $ - * $Date: 2016/12/10 15:18:01 $ - * $Revision: 1.198 $ - */ - -/* - * Declare file local prototypes. - */ -static void highlightCDKMatrixCell (CDKMATRIX *matrix); -static void CDKMatrixCallBack (CDKMATRIX *matrix, chtype input); -static void drawCDKMatrixCell (CDKMATRIX *matrix, - int srow, int scol, - int vrow, int vcol, - boolean Box); -static void drawCurCDKMatrixCell (CDKMATRIX *matrix); -static void drawEachCDKMatrixCell (CDKMATRIX *matrix); -static void drawEachColTitle (CDKMATRIX *matrix); -static void drawEachRowTitle (CDKMATRIX *matrix); -static void drawOldCDKMatrixCell (CDKMATRIX *matrix); -static void redrawTitles (CDKMATRIX *matrix, int row, int col); - -#define emptyString(s) ((s) == 0 || *(s) == '\0') - -#define CurMatrixCell(matrix) \ - MATRIX_CELL (matrix, matrix->crow, matrix->ccol) - -#define CurMatrixInfo(matrix) \ - MATRIX_INFO (matrix, \ - matrix->trow + matrix->crow - 1, \ - matrix->lcol + matrix->ccol - 1) - -DeclareCDKObjects (MATRIX, Matrix, setCdk, Int); - -#define WHOLE_BOX ACS_ULCORNER, ACS_URCORNER, ACS_LLCORNER, ACS_LRCORNER - -#define TOP_C_BOX ACS_ULCORNER, ACS_URCORNER, ACS_LTEE, ACS_RTEE -#define MID_C_BOX ACS_LTEE, ACS_RTEE, ACS_LTEE, ACS_RTEE -#define BOT_C_BOX ACS_LTEE, ACS_RTEE, ACS_LLCORNER, ACS_LRCORNER - -#define LFT_R_BOX ACS_ULCORNER, ACS_TTEE, ACS_LLCORNER, ACS_BTEE -#define MID_R_BOX ACS_TTEE, ACS_TTEE, ACS_BTEE, ACS_BTEE -#define RGT_R_BOX ACS_TTEE, ACS_URCORNER, ACS_BTEE, ACS_LRCORNER - -#define LFT_T_BOX ACS_ULCORNER, ACS_TTEE, ACS_LTEE, ACS_PLUS -#define MID_T_BOX ACS_TTEE, ACS_TTEE, ACS_PLUS, ACS_PLUS -#define RGT_T_BOX ACS_TTEE, ACS_URCORNER, ACS_PLUS, ACS_RTEE - -#define LFT_M_BOX ACS_LTEE, ACS_PLUS, ACS_LTEE, ACS_PLUS -#define MID_M_BOX ACS_PLUS, ACS_PLUS, ACS_PLUS, ACS_PLUS -#define RGT_M_BOX ACS_PLUS, ACS_RTEE, ACS_PLUS, ACS_RTEE - -#define LFT_B_BOX ACS_LTEE, ACS_PLUS, ACS_LLCORNER, ACS_BTEE -#define MID_B_BOX ACS_PLUS, ACS_PLUS, ACS_BTEE, ACS_BTEE -#define RGT_B_BOX ACS_PLUS, ACS_RTEE, ACS_BTEE, ACS_LRCORNER - -#define MyBox(cell,what,attr) attrbox(cell, what, ACS_HLINE, ACS_VLINE, attr) - -/* - * This function creates the matrix widget. - */ -CDKMATRIX *newCDKMatrix (CDKSCREEN *cdkscreen, - int xplace, - int yplace, - int rows, - int cols, - int vrows, - int vcols, - const char *title, - CDK_CSTRING2 rowtitles, - CDK_CSTRING2 coltitles, - int *colwidths, - int *colvalues, - int rspace, - int cspace, - chtype filler, - int dominant, - boolean Box, - boolean boxCell, - boolean shadow) -{ - /* *INDENT-EQLS* */ - CDKMATRIX *matrix = 0; - int parentWidth = getmaxx (cdkscreen->window); - int parentHeight = getmaxy (cdkscreen->window); - int boxHeight = 0; - int boxWidth = 0; - int xpos = xplace; - int ypos = yplace; - int maxWidth; - int maxRowTitleWidth = 0; - int rowSpace = MAXIMUM (0, rspace); - int colSpace = MAXIMUM (0, cspace); - int begx = 0; - int begy = 0; - int cellWidth = 0; - char **temp = 0; - int x, y; - int borderw = 0; - bool have_rowtitles = FALSE; - bool have_coltitles = FALSE; - /* *INDENT-OFF* */ - static const struct { int from; int to; } bindings[] = { - { CDK_FORCHAR, KEY_NPAGE }, - { CDK_BACKCHAR, KEY_PPAGE }, - }; - /* *INDENT-ON* */ - - if ((matrix = newCDKObject (CDKMATRIX, &my_funcs)) == 0) - { - return (0); - } - - setCDKMatrixBox (matrix, Box); - borderw = (ObjOf (matrix)->box) ? 1 : 0; - - /* Make sure that the number of rows/cols/vrows/vcols is not zero. */ - if (rows <= 0 || cols <= 0 || vrows <= 0 || vcols <= 0) - { - destroyCDKObject (matrix); - return (0); - } -#if NEW_CDKMATRIX - matrix->cell = typeCallocN (WINDOW *, (rows + 1) * (cols + 1)); - matrix->info = typeCallocN (char *, (rows + 1) * (cols + 1)); -#endif - - /* - * Make sure the number of virtual cells is not larger than - * the physical size. - */ - vrows = (vrows > rows ? rows : vrows); - vcols = (vcols > cols ? cols : vcols); - - /* Set these early, since they are used in matrix index computations */ - /* *INDENT-EQLS* */ - matrix->rows = rows; - matrix->cols = cols; - /* columns */ - matrix->colwidths = typeCallocN (int, cols + 1); - matrix->colvalues = typeCallocN (int, cols + 1); - matrix->coltitle = typeCallocN (chtype *, cols + 1); - matrix->coltitleLen = typeCallocN (int, cols + 1); - matrix->coltitlePos = typeCallocN (int, cols + 1); - /* titles */ - matrix->rowtitle = typeCallocN (chtype *, rows + 1); - matrix->rowtitleLen = typeCallocN (int, rows + 1); - matrix->rowtitlePos = typeCallocN (int, rows + 1); - - /* - * Count the number of lines in the title (see setCdkTitle). - */ - temp = CDKsplitString (title, '\n'); - TitleLinesOf (matrix) = (int)CDKcountStrings ((CDK_CSTRING2)temp); - CDKfreeStrings (temp); - - /* Determine the height of the box. */ - if (vrows == 1) - { - boxHeight = 6 + TitleLinesOf (matrix); - } - else - { - if (rowSpace == 0) - { - boxHeight = (6 + TitleLinesOf (matrix) + - ((vrows - 1) * 2)); - } - else - { - boxHeight = (3 + TitleLinesOf (matrix) + - (vrows * 3) + ((vrows - 1) * (rowSpace - 1))); - } - } - - /* Determine the maximum row title width */ - for (x = 1; x <= rows; x++) - { - if (rowtitles && !emptyString (rowtitles[x])) /*VR */ - have_rowtitles = TRUE; - matrix->rowtitle[x] = char2Chtype (rowtitles ? rowtitles[x] : 0, /*VR */ - &matrix->rowtitleLen[x], - &matrix->rowtitlePos[x]); - maxRowTitleWidth = MAXIMUM (maxRowTitleWidth, matrix->rowtitleLen[x]); - } - - if (have_rowtitles) - { - matrix->maxrt = maxRowTitleWidth + 2; - - /* We need to rejustify the row title cell info. */ - for (x = 1; x <= rows; x++) - { - matrix->rowtitlePos[x] = justifyString (matrix->maxrt, - matrix->rowtitleLen[x], - matrix->rowtitlePos[x]); - } - } - else - { - matrix->maxrt = 0; - } - - /* Determine the width of the matrix. */ - maxWidth = 2 + matrix->maxrt; - for (x = 1; x <= vcols; x++) - { - maxWidth += colwidths[x] + 2 + colSpace; - } - maxWidth -= (colSpace - 1); - boxWidth = MAXIMUM (maxWidth, boxWidth); - - boxWidth = setCdkTitle (ObjOf (matrix), title, boxWidth); - - /* - * Make sure the dimensions of the window didn't - * extend beyond the dimensions of the parent window. - */ - boxWidth = (boxWidth > parentWidth ? parentWidth : boxWidth); - boxHeight = (boxHeight > parentHeight ? parentHeight : boxHeight); - - /* Rejustify the x and y positions if we need to. */ - alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight); - - /* Make the pop-up window. */ - matrix->win = newwin (boxHeight, boxWidth, ypos, xpos); - - if (matrix->win == 0) - { - destroyCDKObject (matrix); - return (0); - } - - /* Make the subwindows in the pop-up. */ - begx = xpos; - begy = ypos + borderw + TitleLinesOf (matrix); - - /* Make the 'empty' 0x0 cell. */ - MATRIX_CELL (matrix, 0, 0) = subwin (matrix->win, 3, matrix->maxrt, begy, begx); - begx += matrix->maxrt + 1; - - /* Copy the titles into the structure. */ - for (x = 1; x <= cols; x++) - { - if (coltitles && !emptyString (coltitles[x])) /*VR */ - have_coltitles = TRUE; - matrix->coltitle[x] = char2Chtype (coltitles ? coltitles[x] : 0, /*VR */ - &matrix->coltitleLen[x], - &matrix->coltitlePos[x]); - matrix->coltitlePos[x] = (BorderOf (matrix) + - justifyString (colwidths[x], - matrix->coltitleLen[x], - matrix->coltitlePos[x])); - matrix->colwidths[x] = colwidths[x]; - } - - if (have_coltitles) - { - /* Make the column titles. */ - for (x = 1; x <= vcols; x++) - { - cellWidth = colwidths[x] + 3; - MATRIX_CELL (matrix, 0, x) = subwin (matrix->win, - borderw, - cellWidth, - begy, - begx); - - if (MATRIX_CELL (matrix, 0, x) == 0) - { - destroyCDKObject (matrix); - return (0); - } - begx += cellWidth + colSpace - 1; - } - begy++; - } - - /* Make the main cell body */ - for (x = 1; x <= vrows; x++) - { - if (have_rowtitles) - { - /* Make the row titles */ - MATRIX_CELL (matrix, x, 0) = subwin (matrix->win, - 3, matrix->maxrt, - begy, xpos + borderw); - - if (MATRIX_CELL (matrix, x, 0) == 0) - { - destroyCDKObject (matrix); - return (0); - } - } - - /* Set the start of the x position. */ - begx = xpos + matrix->maxrt + borderw; - - /* Make the cells */ - for (y = 1; y <= vcols; y++) - { - cellWidth = colwidths[y] + 3; - MATRIX_CELL (matrix, x, y) = subwin (matrix->win, - 3, cellWidth, - begy, begx); - - if (MATRIX_CELL (matrix, x, y) == 0) - { - destroyCDKObject (matrix); - return (0); - } - begx += cellWidth + colSpace - 1; - keypad (MATRIX_CELL (matrix, x, y), TRUE); - } - begy += rowSpace + 2; - } - keypad (matrix->win, TRUE); - - /* *INDENT-EQLS* Keep the rest of the info. */ - ScreenOf (matrix) = cdkscreen; - ObjOf (matrix)->acceptsFocus = TRUE; - ObjOf (matrix)->inputWindow = matrix->win; - matrix->parent = cdkscreen->window; - matrix->vrows = vrows; - matrix->vcols = vcols; - matrix->boxWidth = boxWidth; - matrix->boxHeight = boxHeight; - matrix->rowSpace = rowSpace; - matrix->colSpace = colSpace; - matrix->filler = filler; - matrix->dominant = dominant; - matrix->row = 1; - matrix->col = 1; - matrix->crow = 1; - matrix->ccol = 1; - matrix->trow = 1; - matrix->lcol = 1; - matrix->oldcrow = 1; - matrix->oldccol = 1; - matrix->oldvrow = 1; - matrix->oldvcol = 1; - initExitType (matrix); - matrix->boxCell = boxCell; - matrix->shadow = shadow; - matrix->highlight = A_REVERSE; - matrix->callbackfn = CDKMatrixCallBack; - - /* Make room for the cell information. */ - for (x = 1; x <= rows; x++) - { - for (y = 1; y <= cols; y++) - { - MATRIX_INFO (matrix, x, y) = typeCallocN (char, (colwidths[y] + 1)); - matrix->colvalues[y] = colvalues[y]; - matrix->colwidths[y] = colwidths[y]; - } - } - - /* Do we want a shadow??? */ - if (shadow) - { - matrix->shadowWin = newwin (boxHeight, boxWidth, ypos + 1, xpos + 1); - } - - /* Setup the key bindings. */ - for (x = 0; x < (int)SIZEOF (bindings); ++x) - bindCDKObject (vMATRIX, matrix, - (chtype)bindings[x].from, - getcCDKBind, - (void *)(long)bindings[x].to); - - /* Register this baby. */ - registerCDKObject (cdkscreen, vMATRIX, matrix); - - /* Return the matrix pointer */ - return (matrix); -} - -/* - * This activates the matrix. - */ -int activateCDKMatrix (CDKMATRIX *matrix, chtype *actions) -{ - int ret; - - /* Draw the matrix */ - drawCDKMatrix (matrix, ObjOf (matrix)->box); - - if (actions == 0) - { - chtype input = 0; - boolean functionKey; - - for (;;) - { - ObjOf (matrix)->inputWindow = CurMatrixCell (matrix); - keypad (ObjOf (matrix)->inputWindow, TRUE); - input = (chtype)getchCDKObject (ObjOf (matrix), &functionKey); - - /* Inject the character into the widget. */ - ret = injectCDKMatrix (matrix, input); - if (matrix->exitType != vEARLY_EXIT) - { - return ret; - } - } - } - else - { - int length = chlen (actions); - int x = 0; - - /* Inject each character one at a time. */ - for (x = 0; x < length; x++) - { - ret = injectCDKMatrix (matrix, actions[x]); - if (matrix->exitType != vEARLY_EXIT) - { - return ret; - } - } - } - - /* Set the exit type and exit. */ - setExitType (matrix, 0); - return -1; -} - -/* - * This injects a single character into the matrix widget. - */ -static int _injectCDKMatrix (CDKOBJS *object, chtype input) -{ - /* *INDENT-EQLS* */ - CDKMATRIX *widget = (CDKMATRIX *)object; - int refreshCells = FALSE; - int movedCell = FALSE; - int charcount = (int)strlen (MATRIX_INFO (widget, widget->row, widget->col)); - int ppReturn = 1; - int ret = unknownInt; - bool complete = FALSE; - - /* Set the exit type. */ - setExitType (widget, 0); - - /* Move the cursor to the correct position within the cell. */ - if (widget->colwidths[widget->ccol] == 1) - { - wmove (CurMatrixCell (widget), 1, 1); - } - else - { - wmove (CurMatrixCell (widget), - 1, - (int)strlen (MATRIX_INFO (widget, widget->row, widget->col)) + 1); - } - - /* Put the focus on the current cell */ - MyBox (CurMatrixCell (widget), WHOLE_BOX, A_BOLD); - wrefresh (CurMatrixCell (widget)); - highlightCDKMatrixCell (widget); - - /* Check if there is a pre-process function to be called. */ - if (PreProcessFuncOf (widget) != 0) - { - /* Call the pre-process function. */ - ppReturn = PreProcessFuncOf (widget) (vMATRIX, - widget, - PreProcessDataOf (widget), - input); - } - - /* Should we continue? */ - if (ppReturn != 0) - { - /* Check the key bindings. */ - if (checkCDKObjectBind (vMATRIX, widget, input) != 0) - { - checkEarlyExit (widget); - complete = TRUE; - } - else - { - switch (input) - { - case CDK_TRANSPOSE: - break; - - case KEY_HOME: - break; - - case KEY_END: - break; - - case KEY_BACKSPACE: - case KEY_DC: - if (widget->colvalues[widget->col] == vVIEWONLY || charcount <= 0) - { - Beep (); - } - else - { - charcount--; - (void)mvwdelch (CurMatrixCell (widget), 1, charcount + 1); - (void)mvwinsch (CurMatrixCell (widget), 1, charcount + 1, widget->filler); - wrefresh (CurMatrixCell (widget)); - MATRIX_INFO (widget, widget->row, widget->col)[charcount] = '\0'; - } - break; - - case KEY_RIGHT: - case KEY_TAB: - if (widget->ccol != widget->vcols) - { - /* We are moving to the right... */ - widget->col++; - widget->ccol++; - movedCell = TRUE; - } - else - { - /* We have to shift the columns to the right. */ - if (widget->col != widget->cols) - { - widget->lcol++; - widget->col++; - - /* Redraw the column titles. */ - if (widget->rows > widget->vrows) - { - redrawTitles (widget, FALSE, TRUE); - } - refreshCells = TRUE; - movedCell = TRUE; - } - else - { - /* We are at the far right column, we need */ - /* shift down one row, if we can. */ - if (widget->row == widget->rows) - { - Beep (); - } - else - { - /* Set up the columns info. */ - widget->col = 1; - widget->lcol = 1; - widget->ccol = 1; - - /* Shift the rows... */ - if (widget->crow != widget->vrows) - { - widget->row++; - widget->crow++; - } - else - { - widget->row++; - widget->trow++; - } - redrawTitles (widget, TRUE, TRUE); - refreshCells = TRUE; - movedCell = TRUE; - } - } - } - break; - - case KEY_LEFT: - case KEY_BTAB: - if (widget->ccol != 1) - { - /* We are moving to the left... */ - widget->col--; - widget->ccol--; - movedCell = TRUE; - } - else - { - /* Are we at the far left??? */ - if (widget->lcol != 1) - { - widget->lcol--; - widget->col--; - - /* Redraw the column titles. */ - if (widget->cols > widget->vcols) - { - redrawTitles (widget, FALSE, TRUE); - } - refreshCells = TRUE; - movedCell = TRUE; - } - else - { - /* Shift up one line if we can... */ - if (widget->row == 1) - { - Beep (); - } - else - { - /* Set up the columns info. */ - widget->col = widget->cols; - widget->lcol = widget->cols - widget->vcols + 1; - widget->ccol = widget->vcols; - - /* Shift the rows... */ - if (widget->crow != 1) - { - widget->row--; - widget->crow--; - } - else - { - widget->row--; - widget->trow--; - } - redrawTitles (widget, TRUE, TRUE); - refreshCells = TRUE; - movedCell = TRUE; - } - } - } - break; - - case KEY_UP: - if (widget->crow != 1) - { - widget->row--; - widget->crow--; - movedCell = TRUE; - } - else - { - if (widget->trow != 1) - { - widget->trow--; - widget->row--; - - /* Redraw the row titles. */ - if (widget->rows > widget->vrows) - { - redrawTitles (widget, TRUE, FALSE); - } - refreshCells = TRUE; - movedCell = TRUE; - } - else - { - Beep (); - } - } - break; - - case KEY_DOWN: - if (widget->crow != widget->vrows) - { - widget->row++; - widget->crow++; - movedCell = TRUE; - } - else - { - if ((widget->trow + widget->vrows - 1) != widget->rows) - { - widget->trow++; - widget->row++; - - /* Redraw the titles. */ - if (widget->rows > widget->vrows) - { - redrawTitles (widget, TRUE, FALSE); - } - refreshCells = TRUE; - movedCell = TRUE; - } - else - { - Beep (); - } - } - break; - - case KEY_NPAGE: - if (widget->rows > widget->vrows) - { - if ((widget->trow + ((widget->vrows - 1) * 2)) <= widget->rows) - { - widget->trow += widget->vrows - 1; - widget->row += widget->vrows - 1; - redrawTitles (widget, TRUE, FALSE); - refreshCells = TRUE; - movedCell = TRUE; - } - else - { - Beep (); - } - } - else - { - Beep (); - } - break; - - case KEY_PPAGE: - if (widget->rows > widget->vrows) - { - if ((widget->trow - ((widget->vrows - 1) * 2)) >= 1) - { - widget->trow -= widget->vrows - 1; - widget->row -= widget->vrows - 1; - redrawTitles (widget, TRUE, FALSE); - refreshCells = TRUE; - movedCell = TRUE; - } - else - { - Beep (); - } - } - else - { - Beep (); - } - break; - - case CTRL ('G'): - jumpToCell (widget, -1, -1); - drawCDKMatrix (widget, ObjOf (widget)->box); - break; - - case CDK_PASTE: - if (GPasteBuffer == 0 || - (int)strlen (GPasteBuffer) > widget->colwidths[widget->ccol]) - { - Beep (); - } - else - { - strcpy (CurMatrixInfo (widget), GPasteBuffer); - drawCurCDKMatrixCell (widget); - } - break; - - case CDK_COPY: - freeChar (GPasteBuffer); - GPasteBuffer = copyChar (CurMatrixInfo (widget)); - break; - - case CDK_CUT: - freeChar (GPasteBuffer); - GPasteBuffer = copyChar (CurMatrixInfo (widget)); - cleanCDKMatrixCell (widget, - widget->trow + widget->crow - 1, - widget->lcol + widget->ccol - 1); - drawCurCDKMatrixCell (widget); - break; - - case CDK_ERASE: - cleanCDKMatrixCell (widget, - widget->trow + widget->crow - 1, - widget->lcol + widget->ccol - 1); - drawCurCDKMatrixCell (widget); - break; - - case KEY_ENTER: - if (!widget->boxCell) - { - attrbox (MATRIX_CELL (widget, widget->oldcrow, widget->oldccol), - ' ', ' ', - ' ', ' ', - ' ', ' ', - A_NORMAL); - } - else - { - drawOldCDKMatrixCell (widget); - } - wrefresh (CurMatrixCell (widget)); - setExitType (widget, input); - ret = 1; - complete = TRUE; - break; - - case KEY_ERROR: - setExitType (widget, input); - complete = TRUE; - break; - - case KEY_ESC: - if (!widget->boxCell) - { - attrbox (MATRIX_CELL (widget, widget->oldcrow, widget->oldccol), - ' ', ' ', - ' ', ' ', - ' ', ' ', - A_NORMAL); - } - else - { - drawOldCDKMatrixCell (widget); - } - wrefresh (CurMatrixCell (widget)); - setExitType (widget, input); - complete = TRUE; - break; - - case CDK_REFRESH: - eraseCDKScreen (ScreenOf (widget)); - refreshCDKScreen (ScreenOf (widget)); - break; - - default: - (widget->callbackfn) (widget, input); - break; - } - } - - if (!complete) - { - /* Did we change cells? */ - if (movedCell) - { - /* un-highlight the old box */ - if (!widget->boxCell) - { - attrbox (MATRIX_CELL (widget, widget->oldcrow, widget->oldccol), - ' ', ' ', - ' ', ' ', - ' ', ' ', - A_NORMAL); - } - else - { - drawOldCDKMatrixCell (widget); - } - wrefresh (MATRIX_CELL (widget, widget->oldcrow, widget->oldccol)); - - /* Highlight the new cell. */ - MyBox (CurMatrixCell (widget), WHOLE_BOX, A_BOLD); - wrefresh (CurMatrixCell (widget)); - highlightCDKMatrixCell (widget); - } - - /* Redraw each cell. */ - if (refreshCells) - { - drawEachCDKMatrixCell (widget); - - /* Highlight the current cell. */ - MyBox (CurMatrixCell (widget), WHOLE_BOX, A_BOLD); - wrefresh (CurMatrixCell (widget)); - highlightCDKMatrixCell (widget); - } - - /* Move to the correct position in the cell. */ - if (refreshCells || movedCell) - { - if (widget->colwidths[widget->ccol] == 1) - { - wmove (CurMatrixCell (widget), 1, 1); - } - else - { - int infolen = (int)strlen (CurMatrixInfo (widget)); - wmove (CurMatrixCell (widget), 1, infolen + 1); - } - wrefresh (CurMatrixCell (widget)); - } - - /* Should we call a post-process? */ - if (PostProcessFuncOf (widget) != 0) - { - PostProcessFuncOf (widget) (vMATRIX, - widget, - PostProcessDataOf (widget), - input); - } - } - } - - if (!complete) - { - /* Set the variables we need. */ - widget->oldcrow = widget->crow; - widget->oldccol = widget->ccol; - widget->oldvrow = widget->row; - widget->oldvcol = widget->col; - - /* Set the exit type and exit. */ - setExitType (widget, 0); - } - - ResultOf (widget).valueInt = ret; - return (ret != unknownInt); -} - -/* - * This allows the programmer to define their own key mappings. - */ -static void CDKMatrixCallBack (CDKMATRIX *matrix, chtype input) -{ - EDisplayType disptype = (EDisplayType) matrix->colvalues[matrix->col]; - int plainchar = filterByDisplayType (disptype, input); - int charcount = (int)strlen (MATRIX_INFO (matrix, matrix->row, matrix->col)); - - if (plainchar == ERR) - { - Beep (); - } - else if (charcount == matrix->colwidths[matrix->col]) - { - Beep (); - } - else - { - /* Update the screen. */ - wmove (CurMatrixCell (matrix), - 1, - (int)strlen (MATRIX_INFO (matrix, matrix->row, matrix->col)) + 1); - waddch (CurMatrixCell (matrix), - (chtype)((isHiddenDisplayType (disptype)) - ? (int)matrix->filler - : plainchar)); - wrefresh (CurMatrixCell (matrix)); - - /* Update the character pointer. */ - MATRIX_INFO (matrix, matrix->row, matrix->col)[charcount++] = (char)plainchar; - MATRIX_INFO (matrix, matrix->row, matrix->col)[charcount] = '\0'; - } -} - -/* - * Highlight the new field. - */ -static void highlightCDKMatrixCell (CDKMATRIX *matrix) -{ - /* *INDENT-EQLS* */ - EDisplayType disptype = (EDisplayType) matrix->colvalues[matrix->col]; - chtype highlight = matrix->highlight; - int x = 0; - int infolen = (int)strlen (MATRIX_INFO (matrix, matrix->row, matrix->col)); - - /* - * Given the dominance of the colors/attributes, we need to set the - * current cell attribute. - */ - if (matrix->dominant == ROW) - { - highlight = matrix->rowtitle[matrix->crow][0] & A_ATTRIBUTES; - } - else if (matrix->dominant == COL) - { - highlight = matrix->coltitle[matrix->ccol][0] & A_ATTRIBUTES; - } - - /* If the column is only one char. */ - for (x = 1; x <= matrix->colwidths[matrix->ccol]; x++) - { - chtype ch = (((x <= infolen) && !isHiddenDisplayType (disptype)) - ? CharOf (MATRIX_INFO (matrix, - matrix->row, - matrix->col)[x - 1]) - : matrix->filler); - - (void)mvwaddch (CurMatrixCell (matrix), 1, x, ch | highlight); - } - wmove (CurMatrixCell (matrix), 1, infolen + 1); - wrefresh (CurMatrixCell (matrix)); -} - -/* - * This moves the matrix field to the given location. - */ -static void _moveCDKMatrix (CDKOBJS *object, - int xplace, - int yplace, - boolean relative, - boolean refresh_flag) -{ - /* *INDENT-EQLS* */ - CDKMATRIX *matrix = (CDKMATRIX *)object; - int currentX = getbegx (matrix->win); - int currentY = getbegy (matrix->win); - int xpos = xplace; - int ypos = yplace; - int xdiff = 0; - int ydiff = 0; - int x, y; - - /* - * If this is a relative move, then we will adjust where we want - * to move to. - */ - if (relative) - { - xpos = getbegx (matrix->win) + xplace; - ypos = getbegy (matrix->win) + yplace; - } - - /* Adjust the window if we need to. */ - alignxy (WindowOf (matrix), &xpos, &ypos, matrix->boxWidth, matrix->boxHeight); - - /* Get the difference. */ - xdiff = currentX - xpos; - ydiff = currentY - ypos; - - /* Move the window to the new location. */ - moveCursesWindow (matrix->win, -xdiff, -ydiff); - - for (x = 0; x <= matrix->vrows; x++) - { - for (y = 0; y <= matrix->vcols; y++) - { - moveCursesWindow (MATRIX_CELL (matrix, x, y), -xdiff, -ydiff); - } - } - - moveCursesWindow (matrix->shadowWin, -xdiff, -ydiff); - - /* Touch the windows so they 'move'. */ - refreshCDKWindow (WindowOf (matrix)); - - /* Redraw the window, if they asked for it. */ - if (refresh_flag) - { - drawCDKMatrix (matrix, ObjOf (matrix)->box); - } -} - -/* - * This draws a cell within a matrix. - */ -static void drawCDKMatrixCell (CDKMATRIX *matrix, - int row, - int col, - int vrow, - int vcol, - boolean Box) -{ - /* *INDENT-EQLS* */ - WINDOW *cell = MATRIX_CELL (matrix, row, col); - EDisplayType disptype = (EDisplayType) matrix->colvalues[matrix->col]; - chtype highlight = matrix->filler & A_ATTRIBUTES; - int rows = matrix->vrows; - int cols = matrix->vcols; - int infolen = (int)strlen (MATRIX_INFO (matrix, vrow, vcol)); - chtype attr = A_NORMAL; - int x; - - /* - * Given the dominance of the colors/attributes, we need to set the - * current cell attribute. - */ - if (matrix->dominant == ROW) - { - highlight = matrix->rowtitle[row][0] & A_ATTRIBUTES; - } - else if (matrix->dominant == COL) - { - highlight = matrix->coltitle[col][0] & A_ATTRIBUTES; - } - - /* Draw in the cell info. */ - for (x = 1; x <= matrix->colwidths[col]; x++) - { - chtype ch = (((x <= infolen) && !isHiddenDisplayType (disptype)) - ? (CharOf (MATRIX_INFO (matrix, vrow, vcol)[x - 1]) | highlight) - : matrix->filler); - - (void)mvwaddch (cell, 1, x, ch | highlight); - } - wmove (cell, 1, infolen + 1); - wrefresh (cell); - - /* Only draw the box iff the user asked for a box. */ - if (!Box) - { - return; - } - - /* - * If the value of the column spacing is greater than 0 then these - * are independent boxes. - */ - if (matrix->colSpace != 0) - { - if (matrix->rowSpace != 0) - { - MyBox (cell, WHOLE_BOX, attr); - } - else - { - if (row == 1) - { - MyBox (cell, TOP_C_BOX, attr); - } - else if (row > 1 && row < rows) - { - MyBox (cell, MID_C_BOX, attr); - } - else if (row == rows) - { - MyBox (cell, BOT_C_BOX, attr); - } - } - } - else if (matrix->rowSpace != 0) - { - if (col == 1) - { - MyBox (cell, LFT_R_BOX, attr); - } - else if (col > 1 && col < cols) - { - MyBox (cell, MID_R_BOX, attr); - } - else if (col == cols) - { - MyBox (cell, RGT_R_BOX, attr); - } - } - else - { - if (row == 1) - { - if (col == 1) - { - MyBox (cell, LFT_T_BOX, attr); /* top left corner */ - } - else if (col > 1 && col < cols) - { - MyBox (cell, MID_T_BOX, attr); /* top middle */ - } - else if (col == cols) - { - MyBox (cell, RGT_T_BOX, attr); /* top right corner */ - } - } - else if (row > 1 && row < rows) - { - if (col == 1) - { - MyBox (cell, LFT_M_BOX, attr); /* middle left */ - } - else if (col > 1 && col < cols) - { - MyBox (cell, MID_M_BOX, attr); /* middle */ - } - else if (col == cols) - { - MyBox (cell, RGT_M_BOX, attr); /* middle right */ - } - } - else if (row == rows) - { - if (col == 1) - { - MyBox (cell, LFT_B_BOX, attr); /* bottom left corner */ - } - else if (col > 1 && col < cols) - { - MyBox (cell, MID_B_BOX, attr); /* bottom middle */ - } - else if (col == cols) - { - MyBox (cell, RGT_B_BOX, attr); /* bottom right corner */ - } - } - } - - /* Highlight the current cell. */ - MyBox (CurMatrixCell (matrix), WHOLE_BOX, A_BOLD); - wrefresh (CurMatrixCell (matrix)); - highlightCDKMatrixCell (matrix); -} - -static void drawEachColTitle (CDKMATRIX *matrix) -{ - int x; - - for (x = 1; x <= matrix->vcols; x++) - { - if (MATRIX_CELL (matrix, 0, x)) - { - werase (MATRIX_CELL (matrix, 0, x)); /*VR */ - writeChtype (MATRIX_CELL (matrix, 0, x), - matrix->coltitlePos[matrix->lcol + x - 1], 0, - matrix->coltitle[matrix->lcol + x - 1], - HORIZONTAL, - 0, matrix->coltitleLen[matrix->lcol + x - 1]); - wrefresh (MATRIX_CELL (matrix, 0, x)); - } - } -} - -static void drawEachRowTitle (CDKMATRIX *matrix) -{ - int x; - - for (x = 1; x <= matrix->vrows; x++) - { - if (MATRIX_CELL (matrix, x, 0)) - { - werase (MATRIX_CELL (matrix, x, 0)); - writeChtype (MATRIX_CELL (matrix, x, 0), - matrix->rowtitlePos[matrix->trow + x - 1], 1, - matrix->rowtitle[matrix->trow + x - 1], - HORIZONTAL, - 0, matrix->rowtitleLen[matrix->trow + x - 1]); - wrefresh (MATRIX_CELL (matrix, x, 0)); - } - } -} - -static void drawEachCDKMatrixCell (CDKMATRIX *matrix) -{ - int y, x; - - /* Fill in the cells. */ - for (x = 1; x <= matrix->vrows; x++) - { - for (y = 1; y <= matrix->vcols; y++) - { - drawCDKMatrixCell (matrix, x, y, - matrix->trow + x - 1, - matrix->lcol + y - 1, - matrix->boxCell); - } - } -} - -static void drawCurCDKMatrixCell (CDKMATRIX *matrix) -{ - drawCDKMatrixCell (matrix, - matrix->crow, - matrix->ccol, - matrix->row, - matrix->col, - matrix->boxCell); -} - -static void drawOldCDKMatrixCell (CDKMATRIX *matrix) -{ - drawCDKMatrixCell (matrix, - matrix->oldcrow, - matrix->oldccol, - matrix->oldvrow, - matrix->oldvcol, - matrix->boxCell); -} - -/* - * This function draws the matrix widget. - */ -static void _drawCDKMatrix (CDKOBJS *object, boolean Box) -{ - CDKMATRIX *matrix = (CDKMATRIX *)object; - - /* Did we ask for a shadow??? */ - if (matrix->shadowWin != 0) - { - drawShadow (matrix->shadowWin); - } - - /* Should we box the matrix??? */ - if (Box) - { - drawObjBox (matrix->win, ObjOf (matrix)); - } - - drawCdkTitle (matrix->win, object); - - wrefresh (matrix->win); - - drawEachColTitle (matrix); - drawEachRowTitle (matrix); - drawEachCDKMatrixCell (matrix); - - /* Highlight the current cell. */ - MyBox (CurMatrixCell (matrix), WHOLE_BOX, A_BOLD); - wrefresh (CurMatrixCell (matrix)); - highlightCDKMatrixCell (matrix); -} - -/* - * This function destroys the matrix widget. - */ -static void _destroyCDKMatrix (CDKOBJS *object) -{ - if (object != 0) - { - CDKMATRIX *matrix = (CDKMATRIX *)object; - int x = 0; - int y = 0; - - cleanCdkTitle (object); - - /* Clear out the col titles. */ - for (x = 1; x <= matrix->cols; x++) - { - freeChtype (matrix->coltitle[x]); - } - - /* Clear out the row titles. */ - for (x = 1; x <= matrix->rows; x++) - { - freeChtype (matrix->rowtitle[x]); - } - - /* Clear out the matrix cells. */ - for (x = 1; x <= matrix->rows; x++) - { - for (y = 1; y <= matrix->cols; y++) - { - freeChar (MATRIX_INFO (matrix, x, y)); - } - } - - /* Clear the matrix windows. */ - deleteCursesWindow (MATRIX_CELL (matrix, 0, 0)); - for (x = 1; x <= matrix->vrows; x++) - { - deleteCursesWindow (MATRIX_CELL (matrix, x, 0)); - } - for (x = 1; x <= matrix->vcols; x++) - { - deleteCursesWindow (MATRIX_CELL (matrix, 0, x)); - } - for (x = 1; x <= matrix->vrows; x++) - { - for (y = 1; y <= matrix->vcols; y++) - { - deleteCursesWindow (MATRIX_CELL (matrix, x, y)); - } - } - -#if NEW_CDKMATRIX - freeChecked (matrix->cell); - freeChecked (matrix->info); -#endif - - freeChecked (matrix->colwidths); - freeChecked (matrix->colvalues); - - freeChecked (matrix->coltitle); - freeChecked (matrix->coltitleLen); - freeChecked (matrix->coltitlePos); - - freeChecked (matrix->rowtitle); - freeChecked (matrix->rowtitleLen); - freeChecked (matrix->rowtitlePos); - - deleteCursesWindow (matrix->shadowWin); - deleteCursesWindow (matrix->win); - - /* Clean the key bindings. */ - cleanCDKObjectBindings (vMATRIX, matrix); - - /* Unregister this object. */ - unregisterCDKObject (vMATRIX, matrix); - } -} - -/* - * This function erases the matrix widget from the screen. - */ -static void _eraseCDKMatrix (CDKOBJS *object) -{ - if (validCDKObject (object)) - { - CDKMATRIX *matrix = (CDKMATRIX *)object; - int x = 0; - int y = 0; - - /* Clear the matrix cells. */ - eraseCursesWindow (MATRIX_CELL (matrix, 0, 0)); - for (x = 1; x <= matrix->vrows; x++) - { - eraseCursesWindow (MATRIX_CELL (matrix, x, 0)); - } - for (x = 1; x <= matrix->vcols; x++) - { - eraseCursesWindow (MATRIX_CELL (matrix, 0, x)); - } - for (x = 1; x <= matrix->vrows; x++) - { - for (y = 1; y <= matrix->vcols; y++) - { - eraseCursesWindow (MATRIX_CELL (matrix, x, y)); - } - } - eraseCursesWindow (matrix->shadowWin); - eraseCursesWindow (matrix->win); - } -} - -/* - * Set the callback-function. - */ -void setCDKMatrixCB (CDKMATRIX *widget, MATRIXCB callback) -{ - widget->callbackfn = callback; -} - -/* - * This function sets the values of the matrix widget. - */ -void setCDKMatrixCells (CDKMATRIX *matrix, - CDK_CSTRING2 info, - int rows, - int maxcols, - int *subSize) -{ - int x = 0; - int y = 0; - - if (rows > matrix->rows) - rows = matrix->rows; - - /* Copy in the new info. */ - for (x = 1; x <= rows; x++) - { - for (y = 1; y <= matrix->cols; y++) - { - if (x <= rows && y <= subSize[x]) - { - const char *source = info[(x * maxcols) + y]; - - /* Copy in the new information. */ - if (source != 0) - { - char *target = MATRIX_INFO (matrix, x, y); - - if (target == 0) /* this should not happen... */ - { - target = typeCallocN (char, matrix->colwidths[y] + 1); - MATRIX_INFO (matrix, x, y) = target; - } - strncpy (MATRIX_INFO (matrix, x, y), - source, - (size_t) matrix->colwidths[y]); - } - } - else - cleanCDKMatrixCell (matrix, x, y); - } - } -} - -/* - * This sets the widget's box attribute. - */ -void setCDKMatrixBox (CDKMATRIX *matrix, boolean Box) -{ - ObjOf (matrix)->box = Box; - ObjOf (matrix)->borderSize = Box ? 1 : 0; -} -boolean getCDKMatrixBox (CDKMATRIX *matrix) -{ - return ObjOf (matrix)->box; -} - -/* - * This cleans out the information cells in the matrix widget. - */ -void cleanCDKMatrix (CDKMATRIX *matrix) -{ - int x = 0; - int y = 0; - - for (x = 1; x <= matrix->rows; x++) - { - for (y = 1; y <= matrix->cols; y++) - { - cleanCDKMatrixCell (matrix, x, y); - } - } -} - -/* - * This cleans one cell in the matrix widget. - */ -void cleanCDKMatrixCell (CDKMATRIX *matrix, int row, int col) -{ - if (row > 0 && row <= matrix->rows && - col > 0 && col <= matrix->cols) - cleanChar (MATRIX_INFO (matrix, row, col), matrix->colwidths[col], '\0'); -} - -/* - * This allows us to hyper-warp to a cell. - */ -int jumpToCell (CDKMATRIX *matrix, int row, int col) -{ - CDKSCALE *scale = 0; - int newRow = row; - int newCol = col; - - /* - * Only create the row scale if needed. - */ - if ((row == -1) || (row > matrix->rows)) - { - /* Create the row scale widget. */ - scale = newCDKScale (ScreenOf (matrix), - CENTER, CENTER, - "Jump to which row.", - "Row: ", A_NORMAL, 5, - 1, 1, matrix->rows, 1, 1, TRUE, FALSE); - - /* Activate the scale and get the row. */ - newRow = activateCDKScale (scale, 0); - destroyCDKScale (scale); - } - - /* - * Only create the column scale if needed. - */ - if ((col == -1) || (col > matrix->cols)) - { - /* Create the column scale widget. */ - scale = newCDKScale (ScreenOf (matrix), - CENTER, CENTER, - "Jump to which column", - "Col: ", A_NORMAL, 5, - 1, 1, matrix->cols, 1, 1, TRUE, FALSE); - - /* Activate the scale and get the column. */ - newCol = activateCDKScale (scale, 0); - destroyCDKScale (scale); - } - - /* Hyper-warp.... */ - if (newRow != matrix->row || newCol != matrix->col) - { - return (moveToCDKMatrixCell (matrix, newRow, newCol)); - } - else - { - return 1; - } -} - -/* - * This allows us to move to a given cell. - */ -int moveToCDKMatrixCell (CDKMATRIX *matrix, int newrow, int newcol) -{ - int rowShift = newrow - matrix->row; - int colShift = newcol - matrix->col; - - /* Make sure we arent asking to move out of the matrix. */ - if (newrow > matrix->rows || - newcol > matrix->cols || - newrow <= 0 || - newcol <= 0) - { - return 0; - } - - /* Did we move up/down???? */ - if (rowShift > 0) - { - /* We are moving down. */ - if (matrix->vrows == matrix->cols) - { - matrix->trow = 1; - matrix->crow = newrow; - matrix->row = newrow; - } - else - { - if ((rowShift + matrix->vrows) < matrix->rows) - { - /* Just shift down by rowShift... */ - matrix->trow += rowShift; - matrix->crow = 1; - matrix->row += rowShift; - } - else - { - /* We need to munge with the values... */ - matrix->trow = matrix->rows - matrix->vrows + 1; - matrix->crow = ((rowShift + matrix->vrows) - matrix->rows) + 1; - matrix->row = newrow; - } - } - } - else if (rowShift < 0) - { - /* We are moving up. */ - if (matrix->vrows == matrix->rows) - { - matrix->trow = 1; - matrix->row = newrow; - matrix->crow = newrow; - } - else - { - if ((rowShift + matrix->vrows) > 1) - { - /* Just shift up by rowShift... */ - matrix->trow += rowShift; - matrix->row += rowShift; - matrix->crow = 1; - } - else - { - /* We need to munge with the values... */ - matrix->trow = 1; - matrix->crow = 1; - matrix->row = 1; - } - } - } - - /* Did we move left/right ???? */ - if (colShift > 0) - { - /* We are moving right. */ - if (matrix->vcols == matrix->cols) - { - matrix->lcol = 1; - matrix->ccol = newcol; - matrix->col = newcol; - } - else - { - if ((colShift + matrix->vcols) < matrix->cols) - { - matrix->lcol += colShift; - matrix->ccol = 1; - matrix->col += colShift; - } - else - { - /* We need to munge with the values... */ - matrix->lcol = matrix->cols - matrix->vcols + 1; - matrix->ccol = ((colShift + matrix->vcols) - matrix->cols) + 1; - matrix->col = newcol; - } - } - } - else if (colShift < 0) - { - /* We are moving left. */ - if (matrix->vcols == matrix->cols) - { - matrix->lcol = 1; - matrix->col = newcol; - matrix->ccol = newcol; - } - else - { - if ((colShift + matrix->vcols) > 1) - { - /* Just shift left by colShift... */ - matrix->lcol += colShift; - matrix->col += colShift; - matrix->ccol = 1; - } - else - { - matrix->lcol = 1; - matrix->col = 1; - matrix->ccol = 1; - } - } - } - - /* Keep the 'old' values around for redrawing sake. */ - matrix->oldcrow = matrix->crow; - matrix->oldccol = matrix->ccol; - matrix->oldvrow = matrix->row; - matrix->oldvcol = matrix->col; - - /* Lets ... */ - return 1; -} - -/* - * This redraws the titles indicated... - */ -static void redrawTitles (CDKMATRIX *matrix, int rowTitles, int colTitles) -{ - /* Redraw the row titles. */ - if (rowTitles) - { - drawEachRowTitle (matrix); - } - - /* Redraw the column titles. */ - if (colTitles) - { - drawEachColTitle (matrix); - } -} - -/* - * This sets the value of a matrix cell. - */ -int setCDKMatrixCell (CDKMATRIX *matrix, int row, int col, const char *value) -{ - /* Make sure the row/col combination is within the matrix. */ - if (row > matrix->rows || col > matrix->cols || row <= 0 || col <= 0) - { - return -1; - } - - cleanCDKMatrixCell (matrix, row, col); - strncpy (MATRIX_INFO (matrix, row, col), - value, - (size_t) matrix->colwidths[col]); - return 1; -} - -/* - * This gets the value of a matrix cell. - */ -char *getCDKMatrixCell (CDKMATRIX *matrix, int row, int col) -{ - /* Make sure the row/col combination is within the matrix. */ - if (row > matrix->rows || col > matrix->cols || row <= 0 || col <= 0) - { - return 0; - } - return MATRIX_INFO (matrix, row, col); -} - -/* - * This returns the current row/col cell. - */ -int getCDKMatrixCol (CDKMATRIX *matrix) -{ - return matrix->col; -} -int getCDKMatrixRow (CDKMATRIX *matrix) -{ - return matrix->row; -} - -/* - * This sets the background attribute of the widget. - */ -static void _setBKattrMatrix (CDKOBJS *object, chtype attrib) -{ - if (object != 0) - { - CDKMATRIX *widget = (CDKMATRIX *)object; - int x, y; - - wbkgd (widget->win, attrib); - for (x = 0; x <= widget->vrows; x++) - { - for (y = 0; y <= widget->vcols; y++) - { - wbkgd (MATRIX_CELL (widget, x, y), attrib); - } - } - } -} - -static void _focusCDKMatrix (CDKOBJS *object) -{ - CDKMATRIX *widget = (CDKMATRIX *)object; - - drawCDKMatrix (widget, ObjOf (widget)->box); -} - -static void _unfocusCDKMatrix (CDKOBJS *object) -{ - CDKMATRIX *widget = (CDKMATRIX *)object; - - drawCDKMatrix (widget, ObjOf (widget)->box); -} - -dummyRefreshData (Matrix) - -dummySaveData (Matrix) diff -r c40f79827990 view_info.c --- a/view_info.c Sun Nov 23 16:42:21 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -#include - -/* - * $Author: tom $ - * $Date: 2016/11/20 18:35:56 $ - * $Revision: 1.3 $ - */ - -/* - * This allows the user to view information. - */ -int viewInfo (CDKSCREEN *screen, - const char *title, - CDK_CSTRING2 info, - int count, - CDK_CSTRING2 buttons, - int buttonCount, - boolean interpret) -{ - CDKVIEWER *viewer = 0; - int selected; - - /* Create the file viewer to view the file selected. */ - viewer = newCDKViewer (screen, CENTER, CENTER, -6, -16, - buttons, buttonCount, - A_REVERSE, TRUE, TRUE); - - /* Set up the viewer title, and the contents to the widget. */ - setCDKViewer (viewer, title, info, count, A_REVERSE, interpret, TRUE, TRUE); - - /* Activate the viewer widget. */ - selected = activateCDKViewer (viewer, 0); - - /* Make sure they exited normally. */ - if (viewer->exitType != vNORMAL) - { - destroyCDKViewer (viewer); - return (-1); - } - - /* Clean up and return the button index selected. */ - destroyCDKViewer (viewer); - return selected; -} diff -r c40f79827990 viewer.c --- a/viewer.c Sun Nov 23 16:42:21 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1307 +0,0 @@ -#include - -/* - * $Author: tom $ - * $Date: 2019/02/17 19:45:07 $ - * $Revision: 1.167 $ - */ - -/* - * Declare some local definitions. - */ -#define DOWN 0 -#define UP 1 - -/* - * Declare file local prototypes. - */ -static int createList (CDKVIEWER *swindow, int listSize); -static int searchForWord (CDKVIEWER *viewer, char *pattern, int direction); -static int jumpToLine (CDKVIEWER *viewer); -static void popUpLabel (CDKVIEWER *viewer, CDK_CSTRING2 mesg); -static void getAndStorePattern (CDKSCREEN *screen); -static void drawCDKViewerButtons (CDKVIEWER *viewer); -static void drawCDKViewerInfo (CDKVIEWER *viewer); - -/* - * Declare file local variables. - */ -static char *SearchPattern = 0; -static int SearchDirection = DOWN; - -DeclareCDKObjects (VIEWER, Viewer, setCdk, Unknown); - -/* - * This function creates a new viewer object. - */ -CDKVIEWER *newCDKViewer (CDKSCREEN *cdkscreen, - int xplace, - int yplace, - int height, - int width, - CDK_CSTRING2 buttons, - int buttonCount, - chtype buttonHighlight, - boolean Box, - boolean shadow) -{ - /* *INDENT-EQLS* */ - CDKVIEWER *viewer = 0; - int parentWidth = getmaxx (cdkscreen->window); - int parentHeight = getmaxy (cdkscreen->window); - int boxWidth; - int boxHeight; - int xpos = xplace; - int ypos = yplace; - int buttonAdj = 0; - int x = 0; - /* *INDENT-OFF* */ - static const struct { int from; int to; } bindings[] = { - { CDK_BACKCHAR, KEY_PPAGE }, - { 'b', KEY_PPAGE }, - { 'B', KEY_PPAGE }, - { CDK_FORCHAR, KEY_NPAGE }, - { SPACE, KEY_NPAGE }, - { 'f', KEY_NPAGE }, - { 'F', KEY_NPAGE }, - { '|', KEY_HOME }, - { '$', KEY_END }, - }; - /* *INDENT-ON* */ - - - if ((viewer = newCDKObject (CDKVIEWER, &my_funcs)) == 0) - return (0); - - setCDKViewerBox (viewer, Box); - - boxHeight = setWidgetDimension (parentHeight, height, 0); - boxWidth = setWidgetDimension (parentWidth, width, 0); - - /* Rejustify the x and y positions if we need to. */ - alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight); - - /* Make the viewer window. */ - viewer->win = newwin (boxHeight, boxWidth, ypos, xpos); - if (viewer->win == 0) - { - destroyCDKObject (viewer); - return (0); - } - - /* Turn the keypad on for the viewer. */ - keypad (viewer->win, TRUE); - - /* Create the buttons. */ - viewer->buttonCount = buttonCount; - if (buttonCount > 0) - { - int buttonWidth = 0; - int buttonPos = 1; - - if ((viewer->button = typeCallocN (chtype *, buttonCount + 1)) == 0 - || (viewer->buttonLen = typeCallocN (int, buttonCount + 1)) == 0 - || (viewer->buttonPos = typeCallocN (int, buttonCount + 1)) == 0) - { - destroyCDKObject (viewer); - return (0); - } - for (x = 0; x < buttonCount; x++) - { - viewer->button[x] = char2Chtype (buttons[x], &viewer->buttonLen[x], &buttonAdj); - buttonWidth += viewer->buttonLen[x] + 1; - } - buttonAdj = (int)((boxWidth - buttonWidth) / (buttonCount + 1)); - buttonPos = 1 + buttonAdj; - for (x = 0; x < buttonCount; x++) - { - viewer->buttonPos[x] = buttonPos; - buttonPos += buttonAdj + viewer->buttonLen[x]; - } - } - - /* *INDENT-EQLS* Set the rest of the variables */ - ScreenOf (viewer) = cdkscreen; - viewer->parent = cdkscreen->window; - viewer->shadowWin = 0; - viewer->buttonHighlight = buttonHighlight; - viewer->boxHeight = boxHeight; - viewer->boxWidth = boxWidth - 2; - viewer->viewSize = height - 2; - ObjOf (viewer)->inputWindow = viewer->win; - initExitType (viewer); - viewer->shadow = shadow; - viewer->currentButton = 0; - viewer->currentTop = 0; - viewer->length = 0; - viewer->leftChar = 0; - viewer->maxLeftChar = 0; - viewer->maxTopLine = 0; - viewer->characters = 0; - viewer->listSize = -1; - viewer->showLineInfo = 1; - viewer->exitType = vEARLY_EXIT; - - /* Do we need to create a shadow??? */ - if (shadow) - { - viewer->shadowWin = newwin (boxHeight, boxWidth + 1, ypos + 1, xpos + 1); - if (viewer->shadowWin == 0) - { - destroyCDKObject (viewer); - return (0); - } - } - - /* Setup the key bindings. */ - for (x = 0; x < (int)SIZEOF (bindings); ++x) - bindCDKObject (vVIEWER, - viewer, - (chtype)bindings[x].from, - getcCDKBind, - (void *)(long)bindings[x].to); - - registerCDKObject (cdkscreen, vVIEWER, viewer); - - return (viewer); -} - -/* - * This function sets various attributes of the widget. - */ -int setCDKViewer (CDKVIEWER *viewer, - const char *title, - CDK_CSTRING2 list, - int listSize, - chtype buttonHighlight, - boolean attrInterp, - boolean showLineInfo, - boolean Box) -{ - setCDKViewerTitle (viewer, title); - setCDKViewerHighlight (viewer, buttonHighlight); - setCDKViewerInfoLine (viewer, showLineInfo); - setCDKViewerBox (viewer, Box); - return setCDKViewerInfo (viewer, list, listSize, attrInterp); -} - -/* - * This sets the title of the viewer. (A null title is allowed. - * It just means that the viewer will not have a title when drawn.) - */ -void setCDKViewerTitle (CDKVIEWER *viewer, const char *title) -{ - (void)setCdkTitle (ObjOf (viewer), title, -(viewer->boxWidth + 1)); - viewer->titleAdj = TitleLinesOf (viewer); - - /* Need to set viewer->viewSize. */ - viewer->viewSize = viewer->boxHeight - (TitleLinesOf (viewer) + 1) - 2; -} -chtype **getCDKViewerTitle (CDKVIEWER *viewer) -{ - return TitleOf (viewer); -} - -static void setupLine (CDKVIEWER *viewer, boolean interpret, const char - *list, int x) -{ - /* Did they ask for attribute interpretation? */ - if (interpret) - { - viewer->list[x] = char2Chtype (list, &viewer->listLen[x], - &viewer->listPos[x]); - viewer->listPos[x] = justifyString (viewer->boxWidth, - viewer->listLen[x], - viewer->listPos[x]); - } - else - { - int len = (int)strlen (list); - int pass; - int y; - chtype *t = 0; - - /* - * We must convert tabs and other nonprinting characters. The curses - * library normally does this, but we are bypassing it by writing - * chtype's directly. - */ - for (pass = 0; pass < 2; ++pass) - { - len = 0; - for (y = 0; list[y] != '\0'; ++y) - { - if (list[y] == '\t') - { - do - { - if (pass) - t[len] = ' '; - ++len; - } - while (len & 7); - } - else if (isprint (CharOf (list[y]))) - { - if (pass) - t[len] = CharOf (list[y]); - ++len; - } - else - { - const char *s = unctrl ((chtype)list[y]); - while (*s != 0) - { - if (pass) - t[len] = CharOf (*s); - ++len; - ++s; - } - } - } - if (!pass) - { - viewer->list[x] = t = typeCallocN (chtype, len + 3); - if (t == 0) - { - len = 0; - break; - } - } - } - viewer->listLen[x] = len; - viewer->listPos[x] = 0; - } - viewer->widestLine = MAXIMUM (viewer->widestLine, viewer->listLen[x]); -} - -static void freeLine (CDKVIEWER *viewer, int x) -{ - if (x < viewer->listSize) - { - freeChtype (viewer->list[x]); - viewer->list[x] = 0; - } -} - -/* - * This function sets the contents of the viewer. - */ -int setCDKViewerInfo (CDKVIEWER *viewer, CDK_CSTRING2 list, int listSize, boolean interpret) -{ - /* *INDENT-EQLS* */ - char filename[CDK_PATHMAX + 2]; - int currentLine = 0; - int x = 0; - int viewerSize; - - /* - * If the list-size is negative, count the length of the null-terminated - * list of strings. - */ - if (listSize < 0) - { - listSize = (int)CDKcountStrings (list); - } - - /* compute the size of the resulting display */ - viewerSize = listSize; - if (list != 0 && interpret) - { - for (x = 0; x < listSize; ++x) - { - if (list[x] == 0) - { - viewerSize = x; /* oops - caller gave the wrong length */ - break; - } - if (checkForLink (list[x], filename) == 1) - { - char **fileContents = 0; - int fileLen = CDKreadFile (filename, &fileContents); - - if (fileLen >= 0) - viewerSize += (fileLen - 1); - CDKfreeStrings (fileContents); - } - } - } - - /* Clean out the old viewer info. (if there is any) */ - viewer->inProgress = TRUE; - cleanCDKViewer (viewer); - createList (viewer, viewerSize); - - /* Keep some semi-permanent info. */ - viewer->interpret = interpret; - - /* Copy the information given. */ - for (x = currentLine = 0; x < listSize && currentLine < viewerSize; x++) - { - if (list[x] == 0) - { - viewer->list[currentLine] = 0; - viewer->listLen[currentLine] = 0; - viewer->listPos[currentLine] = 0; - currentLine++; - } - else - { - /* Check if we have a file link in this line. */ - if (checkForLink (list[x], filename) == 1) - { - /* We have a link, open the file. */ - char **fileContents = 0; - int fileLen = 0; - - /* Open the file and put it into the viewer. */ - fileLen = CDKreadFile (filename, &fileContents); - if (fileLen == -1) - { -#ifdef HAVE_START_COLOR -#define FOPEN_FMT "Link Failed: Could not open the file %s" -#else -#define FOPEN_FMT "Link Failed: Could not open the file %s" -#endif - char *temp = (char *)malloc (80 + strlen (filename)); - sprintf (temp, FOPEN_FMT, filename); - setupLine (viewer, TRUE, temp, currentLine++); - free (temp); - } - else - { - int fileLine; - - /* For each line read, copy it into the viewer. */ - fileLen = MINIMUM (fileLen, (viewerSize - currentLine)); - for (fileLine = 0; fileLine < fileLen; fileLine++) - { - if (currentLine >= viewerSize) - break; - setupLine (viewer, FALSE, fileContents[fileLine], currentLine); - viewer->characters += viewer->listLen[currentLine]; - currentLine++; - } - CDKfreeStrings (fileContents); - } - } - else if (currentLine < viewerSize) - { - setupLine (viewer, viewer->interpret, list[x], currentLine); - viewer->characters += viewer->listLen[currentLine]; - currentLine++; - } - } - } - - /* - * Determine how many characters we can shift to the right - * before all the items have been viewer off the screen. - */ - if (viewer->widestLine > viewer->boxWidth) - { - viewer->maxLeftChar = (viewer->widestLine - viewer->boxWidth) + 1; - } - else - { - viewer->maxLeftChar = 0; - } - - /* Set up the needed vars for the viewer list. */ - viewer->inProgress = FALSE; - viewer->listSize = viewerSize; - if (viewer->listSize <= viewer->viewSize) - { - viewer->maxTopLine = 0; - } - else - { - viewer->maxTopLine = viewer->listSize - 1; - } - return viewer->listSize; -} -chtype **getCDKViewerInfo (CDKVIEWER *viewer, int *size) -{ - (*size) = viewer->listSize; - return viewer->list; -} - -/* - * This function sets the highlight type of the buttons. - */ -void setCDKViewerHighlight (CDKVIEWER *viewer, chtype buttonHighlight) -{ - viewer->buttonHighlight = buttonHighlight; -} -chtype getCDKViewerHighlight (CDKVIEWER *viewer) -{ - return viewer->buttonHighlight; -} - -/* - * This sets whether or not you want to set the viewer info line. - */ -void setCDKViewerInfoLine (CDKVIEWER *viewer, boolean showLineInfo) -{ - viewer->showLineInfo = showLineInfo; -} -boolean getCDKViewerInfoLine (CDKVIEWER *viewer) -{ - return viewer->showLineInfo; -} - -/* - * This sets the widgets box attribute. - */ -void setCDKViewerBox (CDKVIEWER *viewer, boolean Box) -{ - ObjOf (viewer)->box = Box; - ObjOf (viewer)->borderSize = Box ? 1 : 0; -} -boolean getCDKViewerBox (CDKVIEWER *viewer) -{ - return ObjOf (viewer)->box; -} - -/* - * This removes all the lines inside the scrolling window. - */ -void cleanCDKViewer (CDKVIEWER *viewer) -{ - int x; - - /* Clean up the memory used ... */ - for (x = 0; x < viewer->listSize; x++) - { - freeLine (viewer, x); - } - - /* *INDENT-EQLS* Reset some variables. */ - viewer->listSize = 0; - viewer->maxLeftChar = 0; - viewer->widestLine = 0; - viewer->currentTop = 0; - viewer->maxTopLine = 0; - - /* Redraw the window. */ - drawCDKViewer (viewer, ObjOf (viewer)->box); -} - -static void PatternNotFound (CDKVIEWER *viewer, const char *pattern) -{ - if (pattern == 0) - { - PatternNotFound (viewer, ""); - } - else - { - CDK_CSTRING tempInfo[2]; - char *temp = (char *)malloc (80 + strlen (pattern)); - tempInfo[0] = temp; - tempInfo[1] = 0; - sprintf (temp, "Pattern '%s' not found.", pattern); - popUpLabel (viewer, tempInfo); - free (temp); - } -} - -/* - * This function actually controls the viewer... - */ -int activateCDKViewer (CDKVIEWER *widget, chtype *actions GCC_UNUSED) -{ - char *fileInfo[10]; - CDK_CSTRING tempInfo[2]; - char temp[500]; - chtype input; - boolean functionKey; - int x; - - /* Create the information about the file stats. */ - sprintf (temp, " File Statistics "); - fileInfo[0] = copyChar (temp); - sprintf (temp, " "); - fileInfo[1] = copyChar (temp); - sprintf (temp, "Character Count: %-4ld ", widget->characters); - fileInfo[2] = copyChar (temp); - sprintf (temp, "Line Count : %-4d ", widget->listSize); - fileInfo[3] = copyChar (temp); - sprintf (temp, " "); - fileInfo[4] = copyChar (temp); - sprintf (temp, "Press Any Key To Continue."); - fileInfo[5] = copyChar (temp); - fileInfo[6] = 0; - - tempInfo[0] = temp; - tempInfo[1] = 0; - - /* Set the current button. */ - widget->currentButton = 0; - - /* Draw the widget list. */ - drawCDKViewer (widget, ObjOf (widget)->box); - - /* Do this until KEY_ENTER is hit. */ - for (;;) - { - /* Reset the refresh flag. */ - int REFRESH = FALSE; - - input = (chtype)getchCDKObject (ObjOf (widget), &functionKey); - if (!checkCDKObjectBind (vVIEWER, widget, input)) - { - switch (input) - { - case KEY_TAB: - if (widget->buttonCount > 1) - { - if (widget->currentButton == (widget->buttonCount - 1)) - { - widget->currentButton = 0; - } - else - { - widget->currentButton++; - } - - /* Redraw the buttons. */ - drawCDKViewerButtons (widget); - } - break; - - case CDK_PREV: - if (widget->buttonCount > 1) - { - if (widget->currentButton == 0) - { - widget->currentButton = widget->buttonCount - 1; - } - else - { - widget->currentButton--; - } - - /* Redraw the buttons. */ - drawCDKViewerButtons (widget); - } - break; - - case KEY_UP: - if (widget->currentTop > 0) - { - widget->currentTop--; - REFRESH = TRUE; - } - else - { - Beep (); - } - break; - - case KEY_DOWN: - if (widget->currentTop < widget->maxTopLine) - { - widget->currentTop++; - REFRESH = TRUE; - } - else - { - Beep (); - } - break; - - case KEY_RIGHT: - if (widget->leftChar < widget->maxLeftChar) - { - widget->leftChar++; - REFRESH = TRUE; - } - else - { - Beep (); - } - break; - - case KEY_LEFT: - if (widget->leftChar > 0) - { - widget->leftChar--; - REFRESH = TRUE; - } - else - { - Beep (); - } - break; - - case KEY_PPAGE: - if (widget->currentTop > 0) - { - if ((widget->currentTop - (widget->viewSize - 1)) > 0) - { - widget->currentTop = (widget->currentTop - - (widget->viewSize - 1)); - } - else - { - widget->currentTop = 0; - } - REFRESH = TRUE; - } - else - { - Beep (); - } - break; - - case KEY_NPAGE: - if (widget->currentTop < widget->maxTopLine) - { - if ((widget->currentTop + widget->viewSize) < widget->maxTopLine) - { - widget->currentTop = widget->currentTop + - (widget->viewSize - - 1); - } - else - { - widget->currentTop = widget->maxTopLine; - } - REFRESH = TRUE; - } - else - { - Beep (); - } - break; - - case KEY_HOME: - widget->leftChar = 0; - REFRESH = TRUE; - break; - - case KEY_END: - widget->leftChar = widget->maxLeftChar; - REFRESH = TRUE; - break; - - case 'g': - case '1': - case '<': - widget->currentTop = 0; - REFRESH = TRUE; - break; - - case 'G': - case '>': - widget->currentTop = widget->maxTopLine; - REFRESH = TRUE; - break; - - case 'L': - x = (int)((widget->listSize + widget->currentTop) / 2); - if (x < widget->maxTopLine) - { - widget->currentTop = x; - REFRESH = TRUE; - } - else - { - Beep (); - } - break; - - case 'l': - x = (int)(widget->currentTop / 2); - if (x >= 0) - { - widget->currentTop = x; - REFRESH = TRUE; - } - else - { - Beep (); - } - break; - - case '?': - SearchDirection = UP; - getAndStorePattern (ScreenOf (widget)); - if (!searchForWord (widget, SearchPattern, SearchDirection)) - { - PatternNotFound (widget, SearchPattern); - } - REFRESH = TRUE; - break; - - case '/': - SearchDirection = DOWN; - getAndStorePattern (ScreenOf (widget)); - if (!searchForWord (widget, SearchPattern, SearchDirection)) - { - PatternNotFound (widget, SearchPattern); - } - REFRESH = TRUE; - break; - - case 'N': - case 'n': - if (SearchPattern == 0) - { - sprintf (temp, "There is no pattern in the buffer."); - popUpLabel (widget, tempInfo); - } - else if (!searchForWord (widget, - SearchPattern, - ((input == 'n') - ? SearchDirection - : !SearchDirection))) - { - PatternNotFound (widget, SearchPattern); - } - REFRESH = TRUE; - break; - - case ':': - widget->currentTop = jumpToLine (widget); - REFRESH = TRUE; - break; - - case 'i': - case 's': - case 'S': - popUpLabel (widget, (CDK_CSTRING2)fileInfo); - REFRESH = TRUE; - break; - - case KEY_ESC: - freeCharList (fileInfo, 6); - setExitType (widget, input); - return -1; - - case KEY_ERROR: - freeCharList (fileInfo, 6); - setExitType (widget, input); - return -1; - - case KEY_ENTER: - freeCharList (fileInfo, 6); - setExitType (widget, input); - return widget->currentButton; - - case CDK_REFRESH: - eraseCDKScreen (ScreenOf (widget)); - refreshCDKScreen (ScreenOf (widget)); - break; - - default: - Beep (); - break; - } - } - - /* Do we need to redraw the screen??? */ - if (REFRESH) - { - drawCDKViewerInfo (widget); - } - } -} - -/* - * This searches the document looking for the given word. - */ -static void getAndStorePattern (CDKSCREEN *screen) -{ - /* *INDENT-EQLS* */ - CDKENTRY *getPattern = 0; - const char *temp = 0; - char *list = 0; - - /* Check the direction. */ - if (SearchDirection == UP) - { - temp = "Search Up : "; - } - else - { - temp = "Search Down: "; - } - - /* Pop up the entry field. */ - getPattern = newCDKEntry (screen, CENTER, CENTER, - 0, temp, - COLOR_PAIR (5) | A_BOLD, - '.' | COLOR_PAIR (5) | A_BOLD, - vMIXED, 10, 0, 256, TRUE, FALSE); - - /* Is there an old search pattern? */ - if (SearchPattern != 0) - { - setCDKEntry (getPattern, SearchPattern, getPattern->min, - getPattern->max, ObjOf (getPattern)->box); - } - freeChar (SearchPattern); - - /* Activate this baby. */ - list = activateCDKEntry (getPattern, 0); - - /* Save the list. */ - if ((list != 0) && (strlen (list) != 0)) - { - SearchPattern = copyChar (list); - } - - /* Clean up. */ - destroyCDKEntry (getPattern); -} - -/* - * This searches for a line containing the word and realigns the value on the - * screen. - */ -static int searchForWord (CDKVIEWER *viewer, char *pattern, int direction) -{ - int found = 0; - int plen; - - /* If the pattern is empty then return. */ - if (pattern != 0 && (plen = (int)strlen (pattern)) != 0) - { - int x, y, pos, len; - - if (direction == DOWN) - { - /* Start looking from 'here' down. */ - for (x = viewer->currentTop + 1; !found && (x < viewer->listSize); - x++) - { - len = chlen (viewer->list[x]); - for (y = pos = 0; y < len; y++) - { - int plainChar = CharOf (viewer->list[x][y]); - - if (CharOf (pattern[pos]) != plainChar) - { - y -= pos; - pos = 0; - } - else if (++pos == plen) - { - viewer->currentTop = (x < viewer->maxTopLine ? x : viewer->maxTopLine); - viewer->leftChar = (y < viewer->boxWidth ? 0 : viewer->maxLeftChar); - found = 1; - break; - } - - } - } - } - else - { - /* Start looking from 'here' up. */ - for (x = viewer->currentTop - 1; !found && (x >= 0); x--) - { - len = chlen (viewer->list[x]); - for (y = pos = 0; y < len; y++) - { - int plainChar = CharOf (viewer->list[x][y]); - - if (CharOf (pattern[pos]) != plainChar) - { - y -= pos; - pos = 0; - } - else if (++pos == plen) - { - viewer->currentTop = x; - viewer->leftChar = (y < viewer->boxWidth ? 0 : viewer->maxLeftChar); - found = 1; - break; - } - - } - } - } - } - return (found); -} - -/* - * This allows us to 'jump' to a given line in the file. - */ -static int jumpToLine (CDKVIEWER *viewer) -{ - /* *INDENT-EQLS* */ - int line = 0; - CDKSCALE *newline = newCDKScale (ScreenOf (viewer), CENTER, CENTER, - "Jump To Line", "Line :", A_BOLD, - intlen (viewer->listSize) + 1, - viewer->currentTop + 1, - 0, viewer->maxTopLine + 1, - 1, 10, TRUE, TRUE); - - line = activateCDKScale (newline, 0); - destroyCDKScale (newline); - return ((line - 1)); -} - -/* - * This pops a little message up on the screen. - */ -static void popUpLabel (CDKVIEWER *viewer, CDK_CSTRING2 mesg) -{ - CDKLABEL *label; - boolean functionKey; - - /* Set up variables. */ - label = newCDKLabel (ScreenOf (viewer), CENTER, CENTER, - (CDK_CSTRING2)mesg, - (int)CDKcountStrings (mesg), - TRUE, FALSE); - - /* Draw the label and wait. */ - drawCDKLabel (label, TRUE); - getchCDKObject (ObjOf (label), &functionKey); - - /* Clean up. */ - destroyCDKLabel (label); -} - -/* - * This moves the viewer field to the given location. - */ -static void _moveCDKViewer (CDKOBJS *object, int xplace, int yplace, boolean - relative, boolean refresh_flag) -{ - /* *INDENT-EQLS* */ - CDKVIEWER *viewer = (CDKVIEWER *)object; - int currentX = getbegx (viewer->win); - int currentY = getbegy (viewer->win); - int xpos = xplace; - int ypos = yplace; - int xdiff = 0; - int ydiff = 0; - - /* - * If this is a relative move, then we will adjust where we want - * to move to. - */ - if (relative) - { - xpos = getbegx (viewer->win) + xplace; - ypos = getbegy (viewer->win) + yplace; - } - - /* Adjust the window if we need to. */ - alignxy (WindowOf (viewer), &xpos, &ypos, viewer->boxWidth, viewer->boxHeight); - - /* Get the difference. */ - xdiff = currentX - xpos; - ydiff = currentY - ypos; - - /* Move the window to the new location. */ - moveCursesWindow (viewer->win, -xdiff, -ydiff); - moveCursesWindow (viewer->shadowWin, -xdiff, -ydiff); - - /* Touch the windows so they 'move'. */ - refreshCDKWindow (WindowOf (viewer)); - - /* Redraw the window, if they asked for it. */ - if (refresh_flag) - { - drawCDKViewer (viewer, ObjOf (viewer)->box); - } -} - -/* - * This function draws the viewer widget. - */ -static void _drawCDKViewer (CDKOBJS *object, boolean Box) -{ - CDKVIEWER *viewer = (CDKVIEWER *)object; - - /* Do we need to draw in the shadow??? */ - if (viewer->shadowWin != 0) - { - drawShadow (viewer->shadowWin); - } - - /* Box it if it was asked for. */ - if (Box) - { - drawObjBox (viewer->win, ObjOf (viewer)); - wrefresh (viewer->win); - } - - /* Draw the info in the viewer. */ - drawCDKViewerInfo (viewer); -} - -/* - * This redraws the viewer buttons. - */ -static void drawCDKViewerButtons (CDKVIEWER *viewer) -{ - chtype character; - int x; - - /* No buttons, no drawing. */ - if (viewer->buttonCount == 0) - { - return; - } - - /* Redraw the buttons. */ - for (x = 0; x < viewer->buttonCount; x++) - { - writeChtype (viewer->win, - viewer->buttonPos[x], - viewer->boxHeight - 2, - viewer->button[x], - HORIZONTAL, - 0, - viewer->buttonLen[x]); - } - - /* Highlight the current button. */ - for (x = 0; x < viewer->buttonLen[viewer->currentButton]; x++) - { - /* Strip the character of any extra attributes. */ - character = CharOf (viewer->button[viewer->currentButton][x]); - - /* Add the character into the window. */ - (void)mvwaddch (viewer->win, - viewer->boxHeight - 2, - viewer->buttonPos[viewer->currentButton] + x, - character | viewer->buttonHighlight); - } - - /* Refresh the window. */ - wrefresh (viewer->win); -} - -/* - * This sets the background attribute of the widget. - */ -static void _setBKattrViewer (CDKOBJS *object, chtype attrib) -{ - if (object != 0) - { - CDKVIEWER *widget = (CDKVIEWER *)object; - - wbkgd (widget->win, attrib); - } -} - -/* - * Free any storage associated with the info-list. - */ -static void destroyInfo (CDKVIEWER *viewer) -{ - CDKfreeChtypes (viewer->list); - freeChecked (viewer->listPos); - freeChecked (viewer->listLen); - - viewer->list = 0; - viewer->listPos = 0; - viewer->listLen = 0; -} - -/* - * This function destroys the viewer widget. - */ -static void _destroyCDKViewer (CDKOBJS *object) -{ - if (object != 0) - { - CDKVIEWER *viewer = (CDKVIEWER *)object; - - destroyInfo (viewer); - - cleanCdkTitle (object); - CDKfreeChtypes (viewer->button); - freeChecked (viewer->buttonLen); - freeChecked (viewer->buttonPos); - - /* Clean up the windows. */ - deleteCursesWindow (viewer->shadowWin); - deleteCursesWindow (viewer->win); - - /* Clean the key bindings. */ - cleanCDKObjectBindings (vVIEWER, viewer); - - /* Unregister this object. */ - unregisterCDKObject (vVIEWER, viewer); - } -} - -/* - * This function erases the viewer widget from the screen. - */ -static void _eraseCDKViewer (CDKOBJS *object) -{ - if (validCDKObject (object)) - { - CDKVIEWER *viewer = (CDKVIEWER *)object; - - eraseCursesWindow (viewer->win); - eraseCursesWindow (viewer->shadowWin); - } -} - -/* - * This draws the viewer info lines. - */ -static void drawCDKViewerInfo (CDKVIEWER *viewer) -{ - int listAdjust = 0; - int lastLine = 0; - int x; - - /* Clear the window. */ - werase (viewer->win); - - drawCdkTitle (viewer->win, ObjOf (viewer)); - - /* Draw in the current line at the top. */ - if (viewer->showLineInfo == TRUE) - { - char temp[256]; - - /* Set up the info line and draw it. */ - if (viewer->inProgress) - { - strcpy (temp, "processing..."); - } - else if (viewer->listSize != 0) - { - sprintf (temp, "%d/%d %2.0f%%", - (viewer->currentTop + 1), - viewer->listSize, - ((float)(viewer->currentTop + 1) - / (float)viewer->listSize) * 100); - } - else - { - sprintf (temp, "%d/%d %2.0f%%", 0, 0, 0.0); - } - - /* - * The listAdjust variable tells us if we have to shift down one line - * because the person asked for the line X of Y line at the top of the - * screen. We only want to set this to 1 if they asked for the info line - * and there is no title, or if the two items overlap. - */ - if (TitleLinesOf (viewer) == 0 - || TitlePosOf (viewer)[0] < ((int)strlen (temp) + 2)) - { - listAdjust = 1; - } - writeChar (viewer->win, 1, (listAdjust ? TitleLinesOf (viewer) : 0) + 1, - temp, HORIZONTAL, 0, (int)strlen (temp)); - } - - /* Determine the last line to draw. */ - lastLine = ((viewer->listSize <= viewer->viewSize) - ? viewer->listSize - : viewer->viewSize); - lastLine -= listAdjust; - - /* Redraw the list. */ - for (x = 0; x < lastLine; x++) - { - if (viewer->currentTop + x < viewer->listSize) - { - int screenPos = viewer->listPos[viewer->currentTop + x] + 1 - viewer->leftChar; - - writeChtype (viewer->win, - ((screenPos >= 0) - ? screenPos - : 1), - x + TitleLinesOf (viewer) + listAdjust + 1, - viewer->list[x + viewer->currentTop], - HORIZONTAL, - ((screenPos >= 0) - ? 0 - : (viewer->leftChar - - viewer->listPos[viewer->currentTop + x])), - viewer->listLen[x + viewer->currentTop]); - } - } - - /* Box it if we have to. */ - if (ObjOf (viewer)->box) - { - drawObjBox (viewer->win, ObjOf (viewer)); - wrefresh (viewer->win); - } - - /* Draw the separation line. */ - if (viewer->buttonCount > 0) - { - chtype boxattr = BXAttrOf (viewer); - - for (x = 1; x <= viewer->boxWidth; x++) - { - (void)mvwaddch (viewer->win, viewer->boxHeight - 3, x, - HZCharOf (viewer) | boxattr); - } - (void)mvwaddch (viewer->win, viewer->boxHeight - 3, 0, - ACS_LTEE | boxattr); - (void)mvwaddch (viewer->win, viewer->boxHeight - 3, - getmaxx (viewer->win) - 1, - ACS_RTEE | boxattr); - } - - /* Draw the buttons. This will call refresh on the viewer win. */ - drawCDKViewerButtons (viewer); -} - -/* - * The listSize may be negative, to assign no definite limit. - */ -static int createList (CDKVIEWER *swindow, int listSize) -{ - int status = 0; - - if (listSize >= 0) - { - chtype **newList = typeCallocN (chtype *, listSize + 1); - int *newPos = typeCallocN (int, listSize + 1); - int *newLen = typeCallocN (int, listSize + 1); - - if (newList != 0 - && newPos != 0 - && newLen != 0) - { - status = 1; - destroyInfo (swindow); - - swindow->list = newList; - swindow->listPos = newPos; - swindow->listLen = newLen; - } - if (!status) - { - CDKfreeChtypes (newList); - freeChecked (newPos); - freeChecked (newLen); - } - } - else - { - destroyInfo (swindow); - } - return status; -} - -dummyInject (Viewer) - -dummyFocus (Viewer) - -dummyUnfocus (Viewer) - -dummyRefreshData (Viewer) - -dummySaveData (Viewer)