rsalz@bbn.com (Rich Salz) (04/15/88)
Submitted-by: island!argv@sun.com (Dan Heller) Posting-number: Volume 14, Issue 38 Archive-name: mush6.0/part06 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 6 (of 14)." # Contents: cmd_help fkeys.c select.c # Wrapped by rsalz@fig.bbn.com on Wed Apr 13 20:04:47 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'cmd_help' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'cmd_help'\" else echo shar: Extracting \"'cmd_help'\" \(16430 characters\) sed "s/^X//" >'cmd_help' <<'END_OF_FILE' X/* @(#)cmd_help 1.4 10/28/86 (Dan heller) */ X X%?% The `?' will give you a list of legal commands. Most commands accept -? as an option. This will give you specialized help with that particular command. X%% X X%ignore% usage: ignore/unignore [headers] Use this command to set the message headers you would like not to be printed when you read a message. If no header specified, then a list of all headers currently being ignored is printed. You must specify a header for unignore. X You can set the variable "alwaysignore" to force normally ignored headers to be ignored while saving messages, forwarding messages or including messages into message buffers. X%% X X%set% usage: set/unset [variable] [= value] set by itself prints values for variables in its group To set a boolean variable (on or off), "set variable" To set a variable's value to a string, use: set variable = 'value' X If you want double-quote's or white-space embedded in a string, encase the string in single quotes. If you want single quotes in a string, encase the string in double quotes. X Type "set ?all" for a list of all settable variables. X"set ?variable_name" for help on a single variable. X%% X X%readmsg% You can read messages in different ways. "type" and "print" will print the current message. "top" will only print the first N lines of the current message where N is the value of the variable "crt". "next" will go to the next unread message and print that. "previous" will go back and read the first unread message previous to the current. ^ will print the first message, $ will print the last. All can be followed by a message list and each message in that list will be printed (or piped to other commands). X%% X X%alts_help% usage: alts [hostnames] alts contains a list of hostnames on which you have an account Normally, when you respond to all recipients of mail, your account name will be listed and you send yourself mail. If you don't have metoo set, then your name will be removed from the mailing list if your login name is on the list and the host specified is in the alternates list. `*' matches all hostnames and only the login name is tested. X%% X X%source_help% usage: source/saveopts [file] source/saveopts will load/save all variable settings, options, aliases, cmd's, ignored headers ... everything you can set, it loads or saves. The file named used follows these rules: X X1) if a filename is given, that file is used. X2) file described by the environment variable MAILRC X3) user's home directory: .mailrc X%% X X%general% This is the general help message. To get help on a specific command, try "command -?". Extended help is given by typing X`help item' where item is one of: X path, msg_list, prompt, hdr_format. Help with msg_list is highly advisable! X Type "?" to get a list of available commands. Try "? command" to get help on the particular command that you specify. X%% X X%path% Whenever "path" is specified, the following syntax is legal besides the normal path addressing scheme used by unix. X~[user] -- the home directory of specified user (yours by default) X%[user] --/usr/spool/mail/login_name [user_name] (yours by default) X+file --the directory described by `set folder'; file is `file' X%% X X%msg_list% A "msg_list" references one or more messages. The user specifies a group of messages according to a special syntax. X X* All messages. X^ The first message. X$ The last message. X. The current message. N-M A range of messages between N and M. X In the last case, N and M may be * ^ $ . or digits referencing explicit message numbers. The range must be in ascending order. X You can also negate messages by placing the message list inside braces, `{' `}' -- thus, the expression "2-19 {11-14}" references messages 2 through 19 except for those between 11 through 14. X Commands can be "piped" to one another, because the return value of a command is a msg_list, not text. pick -f fred | lpr will find all messages "from fred" and send them to the printer. X Commands dealing with more than one message process them in order -- not necessarily the order specified. Thus, the command, save 1-5 9 7 6 file will save the messages in ascending order; not as specified. X%% X X%preserve_help% usage: preserve [msg_list] Preserve saves deleted or read messages in your mailbox. Without explicitely setting preserve, all mail that you read will be saved in ~/mbox (or set mbox). If you set X"hold", then this is equivalent to preserving each message as you read it. X%% X X%save_help% usage: save/write/copy [!] [msg_list] [filename] X If no filename is specified, ~/mbox (or set mbox) is used. Save and write will append msg if `file' already exists Specifying the `!' will overwrite file (e.g. erasing it first). To save messages to a filename beginning with a digit, escape the filename with a backslash (\) X`write' will write message without the headers (msg body only). Save and write both mark messages for deletion unless "keepsave" is set. Copy is identical to save except that messages are not marked for deletion (identical to having keepsave set). X%% X X%lpr% use: lpr [-n] [-h] [msg_list] X -n print body of message only (not headers) X -h print all headers with message body (default true) X -Pxx print on printer xx X%% X X%respond_help% usage: replysender/replyall [msg_list] [mail_flags] [users] Replysender only replies to the sender and replyall responds to everyone on the To: and Cc: lines of the message. X The commands "repond", "reply", and "r" are identical to X"replysender." The command, "R" is identical to "replyall." X If a message list is indicated, then each message on the list is replied to in the same manner. All other arguments are passed to the mail command ('mail_flags' and 'users'). X Type "mail -?" for information on legal mail flags. X%% X X%sort_help% usage: sort [-] [d | a | s | S | R] X d sort according to date received X a author (alphabetical) X s subject ignoring Re: as part of the subject X R subject (alphabetical) X S by status The optional `-' flag will reverse the order of sorting By default (no arguments), sort sorts messages by status: New, unread messages are first, followed by preserved messages and finally the deleted messages are placed at the end X%% X X%pick% use: pick [-r msg_list] [-d [-][date] ] [-s|f|t]] [-x] [-i] [-h hdr] [<pat>] Search for patterns within messages. Entire messages are searched for <pattern> unless -s, -f, -t, or -h is specified. Only one of -s, -f, -t, -d and -h can be specified at once. X-r msg_list restrict the range of messages search to msg_list X-d: print message headers on or after [`-' before] `date' (no patterns). X-h hdr requires a header to be searched for. Pattern searched in that hdr. X `date' is of the form: month/date/year X Omitted fields default to today's values. Examples: X pick -d 4/20 msgs on or after Apr 20, this year X pick -d -/2/85 on or before the 2nd, this month, 1985 X pick -d / finds today's messages only. X At least one `/' char must be used in date. X There is no strong date checking; 2/30 would be considered valid X-s search for pattern in the "subject" headers only. X-f search for pattern in the "from" field (author) only. X-t search for pattern in the "to" field. X-i ignore case of letters. X-x return those messages which do NOT match. X%% X X%alias% options for alias: alias print all namelists alias name print namelist associated with name alias name namelist set "name" to value of namelist. unalias namelist unalias names in namelist X A "namelist" consists of one or more addresses. An address may be a name already set to another list, valid user, file or program. Filenames must be full pathnames beginning with a '/' (or a ~ expanding to a home directory). A "program" must start with a pipe and be encased in quotes: X X "|program_name" X The command, "expand", will print addresses (including sublists) associated with the given alias. X%% X X%from% With no arguments, from will print the current message's header. If given a message list, from will print the headers of those messages which are in the list. X The special arguments, `-' and `+' can be given to move the current message pointer to the previous or next message respectively while also printing that message's header. X If a message list was given in addition to `-' or `+', then the current message pointer will be set to the first or last message, respectively, in the message list given. X from - 10-30 {16} will print the headers of messages 10 through 30 except for message 16 and set the current message pointer to 10. X pick -f Dan | from + will print the headers of all messages that contain Dan in in the author's name and set the current message pointer to the last one of that kind in the list. X from + will print the header of the message after the current message and increment the current message pointer to the next message. X%% X X%own_hdrs% Here is where you set, unset or view your own message headers. These headers are included in all your outgoing mail. X options for my_hdrs: my_hdr all headers my_hdr header value associated with header my_hdr header: string set header to string un_hdr header unset header X%% X X%fkey_help% fkey's are function key settings in Suntools (graphics) mode When run as a tool (-t on command line), choose the Options Item, and the function key menu option. X%% X X%func_help% cmd's are just like aliases in the c-shell. cmd view all commands cmd `command' value associated with command cmd `command' "value" set command to value uncmd `command' unset command X If you want to reference history commands within a cmd, escape the ! with a backslant. For example: X mail> cmd r 'replysender \!* ; delete -t' X will reply using whatever arguments you will have given on the command line and then delete that message and then print the next message (-t argument to "delete"). X%% X X%headers% usage: headers [+ | - | N] [-H:c] print out a screenful of headers. X+ print the next screenful. X- print the previous screenful. N (where N is a number) print a screenful starting at N. set show_deleted to list deleted messages. cmd h headers look like UCB-Mail cmd H Headers show deleted messages (or set show_deleted) cmd z headers + `z' is next screenful X Arguments to the headers command include -H:c where `c' is one of X n just print messages headers of NEW messages X d deleted messages X u unread messages X o old messages X r messages that have been replied to X a all messages (mostly for the command line argument -H:c) X piping to headers will print the headers of the "output" messages. X%% X X%hdr_format% set hdr_format="string" for changing the display of message headers. The string uses printf style formatting and follows these conventions: X %f "from" field (author). X %a the address of the author. X %n the name of the author. X %t "to" field (recipients). X %d date of the message. X %T the time only of the message X %N the day number of the month of the message X %D the day or the week (Sun, Mon, etc.) X %M the month name of the message X %Y the year of the message X %s subject of the message. X %l number of lines in the message. X %c number of characters (bytes) in the message. X \n a newline X \t a tab. A field specifier may be used. Thus, %20f will print the first 20 characters of the from line. No matter what the formatting string, the message number followed by a '>' (if current message) is printed. X%% X X%folder_help% usage: folder [-N] [-r] [!] [ %[user] | # | & | file ] Change current folder. No arguments prints current folder. X-N: No headers are displayed upon entering new folder (also command line). X-r: read only mode (you won't be able to write changes to this folder). If `!' is specified, current folder is not updated. X%[user] folder to /usr/spool/mail/[user] (you default) X# folder accessed previous to current folder X& "mbox" -- default is ~/mbox; or set mbox = "file" X%% X X%prompt% set prompt = "string" X"string" is follows printf style formatting conventions: X \t, \n will be replaced by a tab or newline respectively. X %m current message number X %t total number of messages X %d number of deleted messages X %u number of unread messages X %n number of new messages X %f name of the current working folder X %T current time X %D day of the week X %Y year X %M month X %N number of the day in the month (date) X%% X X%quit_help% usage: quit/exit", quit will update your mailbox; if new mail has come in, you will be told so and given an option whether to really quit or not. X"exit" will leave mail not updating your mailbox nor check for new mail. X%% X X%ls% The ls command is exactly like the UNIX command, "ls." All arguments are the same. The variable "lister" can be set to always default to the same arguments avoiding having to specify them all the time. The "folders" command is nothing more than doing "ls $folder" from the Mush prompt. X%% X X%shell% usage: sh [command] If a "command" is given, that UNIX command will be executed under the Bourne shell. If no command is specified, then an interactive shell will be started. The environment variable SHELL or the local mail shell variable shell describes the shell to invoke. If none is set, then the default shell is defined by the system administrator (currently set to csh). X Users on systems with job control will probably have little use for the sh command. X%% X X%stop% The stop command sends a stop signal to the mail shell. It is equivalent to ^Z as it will stop the process. Since the shell never needs to be exited, the command X'q' may be aliased to "stop" and the shell may have, X% alias 'mail ?mush' which will bring mush into the foreground rather than having to invoke a new shell. New mail will be read into the shell automatically and much time and energy is saved. X%% X X%curses% The curses-based interface for Mush does not require a graphics display, but does requires a terminal which can handle upline cursor movement capabilities. All commands are one key-stroke commands and are executed instantaneously. A list of curses commands is given by using the `?' key in curses mode. X%% X X%bind% Binding is done for the curses interface only. It allows the user to bind keystrokes or key sequences to commands. X To bind keystrokes that are control characters, you must use the notation: "\CX" where "X" is in upper-case and it represents the control key you want to use. "\CN" would be control-N; "\n" is carriage return. You may not bind keyboard generated signals; for most users, those key sequences are control-C and control-\. For users with job control, control-Z and control-Y are ignored. To reference the escape key, use the string, "\E". X The spacebar may not be bound since it is the only way to return to the main level from the "...continue..." prompt. X Trying to bind a key sequence which prefixes another sequence is an error and the user is warned that the longer binding will not work. X As always, -? will give help. X%% X X%msg_flags% usage: flags [msg_list [N O R D P U R r] ] This command displays the state of messages as seen by the internals of Mush. This is not a documented command, so don't tell anyone. If a list is given (or piped), it will tell which bits of the message are set: New, Old, Read, Deleted, Preserved, Unread, Read, and replied. If any (one or more) of the optional bits are given, then it will set the appropriate bit in the list given. As usual, if no list is given, then the current message is used (or set bits on a pipe). X%% X X%setenv% usage: setenv VARIABLE [value] X Variable names may be any string, but traditionally environment variables are all upper case. If no "value" is specified, then the variable name will be set to an empty string. If the value contains spaces, you should enclose the string in quotation marks. Use printenv to print a list of all your environment variables. X%% X X%unsetenv% usage: unsetenv VARIABLE X You must specify one and only one variable to unset in your environment variable settings. Use printenv to print a list of all your environment variables. X%% END_OF_FILE if test 16430 -ne `wc -c <'cmd_help'`; then echo shar: \"'cmd_help'\" unpacked with wrong size! fi # end of 'cmd_help' fi if test -f 'fkeys.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'fkeys.c'\" else echo shar: Extracting \"'fkeys.c'\" \(13831 characters\) sed "s/^X//" >'fkeys.c' <<'END_OF_FILE' X/* @(#)fkeys.c (c) copyright 10/18/86 (Dan Heller) */ X X#include "mush.h" X#define draw(x1,y1,x2,y2,OP) pw_vector(msg_win, x1,y1,x2,y2,OP,1) X#define box(x1,y1,x2,y2,OP) \ X draw(x1,y1, x1,y2,OP), draw(x1,y2, x2,y2,OP), \ X draw(x2,y2, x2,y1,OP), draw(x2,y1, x1,y1,OP) X struct cmd fkey_cmds[] = { X { "top", fkey_cmd }, { "close", fkey_cmd }, { "bottom", fkey_cmd }, X { "move", fkey_cmd }, { "stretch", fkey_cmd }, { "repaint", fkey_cmd }, X { "settings", fkey_settings }, { NULL, quit } X}; X X#define L(n) KEY_LEFTFIRST+(n)-1 X#define R(n) KEY_RIGHTFIRST+(n)-1 X#define F(n) KEY_TOPFIRST+(n)-1 X#define BREAK_KEY KEY_TOPLAST X char *leftkey_default_settings[] = { X "Left Function Key Settings", X "Unused", /* L1 */ "next", /* L2 */ X "undelete", /* L3 */ "delete", /* L4 */ X "replyall", /* L5 */ "replysender", /* L6 */ X "mail", /* L7 */ "Unset", /* L8 */ X "lpr", /* L9 */ "settings L", /* L10 */ X 0 X}; X char *topkey_default_settings[] = { X "Top Function Key Settings", X "top", /* T1 */ "close", /* T2 */ X "move", /* T3 */ "stretch", /* T4 */ X "bottom", /* T5 */ "repaint", /* T6 */ X "Unset", /* T7 */ "Unset", /* T8 */ X "settings F", /* T9 */ X 0 X}; X char *rightkey_default_settings[] = { X "Right Function Key Settings", X "Unset", /* R1 */ "Unset", /* R2 */ X "Unset", /* R3 */ "Unset", /* R4 */ X "Unset", /* R5 */ "Unset", /* R6 */ X "Unset", /* R7 */ "Unset", /* R8 */ X "Unset", /* R9 */ "Unset", /* R10 */ X "Unset", /* R11 */ "Unset", /* R12 */ X "Unset", /* R13 */ "Unset", /* R14 */ X "settings R", /* R15 */ X 0 X}; X X/* X * Execute commands defined by a function key. X * Left keys: X * L1 = (null) can't be set X * L2 ... L10 X * Top function keys X * F1 ... F9, BREAK/backspace (key not definable) X * Right function keys X * R1 ... R15 X * Usually, the last Function key displays the others' settings. X */ fkey(key) register char *key; X{ X register char **argv, *p; X char buf[256]; X int n; X X /* user defined here... ... default settings here */ X if (!strncmp((p = key_set_to(key)), "Un", 2)) { X print("Funciton key: %s %s", key, p); X return 0; X } X /* make_command will screw up "p", so copy it first */ X (void) strcpy(buf, p); X Debug("(%s) \"%s\": ", key, p), turnon(glob_flags, CONT_PRNT); X if (argv = make_command(buf, TRPL_NULL, &n)) X (void) do_command(n, argv, msg_list); X return -1; X} X fkey_settings(i, argv) register char i; register char **argv; X{ X register char key, *p, **fkey_str; X char buf[256]; X char *help_args[17]; X X if (!*++argv) { X print("Must specify one of L, F or R to identify a function key set"); X return -1; X } X key = **argv; X switch(Upper(key)) { X when 'L': fkey_str = leftkey_default_settings; X when 'F': fkey_str = topkey_default_settings; X when 'R': fkey_str = rightkey_default_settings; X otherwise: print("Invalid key set: %c (choose L, F or R)", key); X return -1; X } X help_args[0] = fkey_str[0]; X for (i = 1; fkey_str[i]; i++) { X p = key_set_to(sprintf(buf, "%c%d", key, i)); X help_args[i] = savestr(sprintf(buf, "%c%-2.d %s", key, i, p)); X } X help_args[i] = 0; /* null terminate list */ X (void) help(print_sw->ts_windowfd, help_args, NULL); X X free_vec(help_args+1); X return 0; X} X char * key_set_to(p) register char *p; X{ X register char *p2, **fkey_str; X X switch(*p) { X when 'L': fkey_str = leftkey_default_settings; X when 'F': fkey_str = topkey_default_settings; X when 'R': fkey_str = rightkey_default_settings; X } X p2 = do_set(fkeys, p); X return (p2)? p2: fkey_str[atoi(p+1)]; X} X fkey_cmd(x, p) register char **p; X{ X if (!strcmp(*p, "close")) X toolquit(NO_ITEM, 0, NO_EVENT); X else if (!strcmp(*p, "top")) X wmgr_top(tool->tl_windowfd, rootfd); X else if (!strcmp(*p, "move")) X wmgr_move(tool->tl_windowfd, rootfd); X else if (!strcmp(*p, "stretch")) X wmgr_stretch(tool->tl_windowfd, rootfd); X else if (!strcmp(*p, "bottom")) X wmgr_bottom(tool->tl_windowfd, rootfd); X else if (!strcmp(*p, "repaint")) X wmgr_refreshwindow(tool->tl_windowfd, rootfd); X return -1; X} X X/* execute a command given a function key, if the key is user defined, X * call fkey() at top of file. Parameter is the key number in "ascii" X */ func_key(key) register int key; X{ X register char *p; X char buf[4]; X int nkey; X X if (key >= KEY_LEFTFIRST && key <= KEY_LEFTLAST) X buf[0] = 'L', nkey = key - KEY_LEFTFIRST; X else if (key >= KEY_TOPFIRST && key <= KEY_TOPLAST) X buf[0] = 'F', nkey = key - KEY_TOPFIRST; X else if (key >= KEY_RIGHTFIRST && key <= KEY_RIGHTLAST) X buf[0] = 'R', nkey = key - KEY_RIGHTFIRST; X (void) sprintf(buf+1, "%d", nkey+1); X X return fkey(buf); X} X void set_fkeys() X{ X ready(display_keys() + 10); X print_valid_functions(txt.y+20); X getting_opts = 2; X win_setcursor(msg_sw->ts_windowfd, &checkmark); X} X char *MSG = "Click the appropriate mouse button over a function key"; ready(Y) X{ X static int y; X int x = (msg_rect.r_width - strlen(MSG)*l_width(LARGE))/2; X if (Y) X y = Y; X Clrtoeol(msg_win, (txt.x = 0), (txt.y = y), LARGE); X highlight(msg_win, x, y, LARGE, MSG); X} X X/* number of pixels in x and y directions describing the size of a graphical X * function key. they represent the little keys and big keys respectively. X */ X/* static struct pr_pos fkey_sizes[2] = { { 23, 23 }, { 50, 23 } }; */ static struct pr_pos fkey_sizes[2] = { { 24, 23 }, { 52, 23 } }; X X#define BORDER 4 /* border (distance) between keys */ X#define KEYTOP 15 /* distance from top to start drawing */ X#define LEFT_START 15 /* pixels from left to start drawing boxes */ X#define TOP_START (LEFT_START+2*fkey_sizes[0].x + fkey_sizes[1].x+BORDER) X#define RIGHT_START (TOP_START + 5*(fkey_sizes[0].x+BORDER) + \ X 5*(fkey_sizes[1].x+BORDER)) X X/* X * if !p, we're setting key at location x,y. X * else Set that key to this string (p). X */ void set_key(p, x,y) register char *p; register int x,y; X{ X char buf[256], **argv; X static char *key; X int argc; X X static int key_x, key_y; X if (!p) { X if (key = find_key(x,y)) { X print("Type new setting for key: %s", key); X (void) sprintf(buf, "Function key \"%s\": ", key); X highlight(msg_win, 20, txt.y, LARGE, buf); X txt.x = 20 + strlen(buf)*l_width(LARGE); X Clrtoeol(msg_win, txt.x, txt.y, LARGE); X type_cursor(PIX_SRC); X } else X ready(0); X key_x = x, key_y = y; X } else { X u_long save_bang = ison(glob_flags, IGN_BANG); X if (!*p) X (void) sprintf(buf, "unfkey %s", key); X else X (void) sprintf(buf, "fkey %s \"%s\"", key, p); X turnon(glob_flags, IGN_BANG); X if (argv = make_command(buf, TRPL_NULL, &argc)) { X (void) do_command(argc, argv, msg_list); X print("Function key %s: %s", key, key_set_to(key)); X } X if (!save_bang) X turnoff(glob_flags, IGN_BANG); X ready(0); X } X} X X/* passed the x and y coords of a mouse click, return the function key X * that exists in that position. NULL if no key there. string will be X * something like "L6" or "F9" or "R12" X */ char * find_key(x,y) int x, y; X{ X static char buf[6]; X int row, col; X static int old_left, old_top, old_right, old_bot; X X if (!(row = find_y(&y))) X return NULL; X if (x < LEFT_START || x > RIGHT_START + 3*(fkey_sizes[0].x+BORDER)) X return NULL; /* out of range */ X if (x > LEFT_START && x < TOP_START-fkey_sizes[0].x - BORDER) { X if ((col = (x > LEFT_START + fkey_sizes[0].x + BORDER)+1) == 1) X x = LEFT_START+1; X else x = LEFT_START + fkey_sizes[0].x + BORDER + 1; X if (col == 1 && row == 1) X return NULL; X /* unhighlight the old function key image */ X if (old_left) X box(old_left, old_top, old_right, old_bot, PIX_CLR); X old_left = x, old_top = y; X old_right = x+fkey_sizes[(col != 1)].x-2, old_bot = y+fkey_sizes[0].y-2; X /* highlight most recently selected function key image */ X box(x,y, old_right, old_bot, PIX_SRC); X X return sprintf(buf, "L%d", col + 2*(row-1)); X } X if (x > TOP_START && x < RIGHT_START - fkey_sizes[0].x - BORDER) { X int which; X if (row > 1) X return NULL; X which = (x - TOP_START) / (fkey_sizes[0].x + BORDER) + 1; X if (which == 15) X return NULL; /* Can't set break key (backspace on a sun3) */ X if (which == 14) X x = TOP_START + ((which = 9)-2) * (fkey_sizes[1].x+BORDER) - X fkey_sizes[0].x - BORDER + 1; X else if (which <= 2) X x = TOP_START + (which-1) * (fkey_sizes[0].x+BORDER) + 1; X else { X which = (which+3)/2; X x = TOP_START + (which-2) * (fkey_sizes[1].x+BORDER) + 1; X } X X /* unhighlight the old function key image */ X if (old_left) X box(old_left, old_top, old_right, old_bot, PIX_CLR); X old_left = x, old_top = y; X old_right = x+fkey_sizes[(which > 2 && which < 8)].x-2; X old_bot = y+fkey_sizes[0].y-2; X /* highlight most recently selected function key image */ X box(x,y, old_right, old_bot, PIX_SRC); X X return sprintf(buf, "F%d", which); X } X if (x > RIGHT_START) { X if (x < RIGHT_START + fkey_sizes[0].x) X x = RIGHT_START+1, col = 1; X else if (x < RIGHT_START + fkey_sizes[0].x + BORDER) X return NULL; /* cursor was clicked between keys */ X else if (x < RIGHT_START + 2*fkey_sizes[0].x + BORDER) X x = RIGHT_START+fkey_sizes[0].x+BORDER+1, col = 2; X else if (x < RIGHT_START + 2 * (fkey_sizes[0].x+BORDER)) X return NULL; /* click between keys again */ X else x = RIGHT_START + 2*(fkey_sizes[0].x+BORDER)+1, col = 3; X X /* unhighlight the old function key image */ X if (old_left) X box(old_left, old_top, old_right, old_bot, PIX_CLR); X old_left = x, old_top = y; X old_right = x+fkey_sizes[0].x-2, old_bot = y+fkey_sizes[0].y-2; X /* highlight most recently selected function key image */ X box(x,y, old_right, old_bot, PIX_SRC); X X return sprintf(buf, "R%d", col + 3*(row-1)); X } X return NULL; X} X X/* find_y will find which row in a function key pad a y coordinate X * represents. return 1,2,3,4, or 5 0 if inbetween rows X */ find_y(y) register int *y; X{ X int Y, y_incr = fkey_sizes[0].y, ret_value = 0; X for (Y = KEYTOP; Y <= KEYTOP + 6*y_incr + 4 * BORDER; Y += y_incr + BORDER) X if (*y < Y) { X *y = (Y - y_incr - BORDER) + 1; X return ret_value; X } else ret_value++; X return 0; X} X char *l_msg = "Specifies which function key for setting value"; char *m_msg = "Display current value for function key"; char *r_msg = "Help setting and viewing function key values"; X display_keys() X{ X register int i, x,y; X register char *p; X X do_clear(); X X x = LEFT_START, y = KEYTOP; X /* print left keys */ X for (i = 0; i < 10; i++) { X box(x, y, x + fkey_sizes[i%2].x, y + fkey_sizes[i%2].y, PIX_SRC); X box(x+2, y+2, x+fkey_sizes[i%2].x-2, y+fkey_sizes[i%2].y-2, PIX_SRC); X if (i && (p = find_key(x+4,y+4))) X pw_text(msg_win, x+3, y+3+l_height(SMALL), PIX_SRC,fonts[SMALL], p); X else pw_replrop(msg_win, x+3, y+3, fkey_sizes[0].x-5, fkey_sizes[0].y-5, X PIX_SRC | PIX_DST, &shade_50, 0,0); X if (i % 2) X y += fkey_sizes[0].y + BORDER, x = LEFT_START; X else X x += fkey_sizes[0].x + BORDER; X } X X x = TOP_START, y = KEYTOP; X /* print top keys */ X for (i = 1; i <= 10; i++) { X register int n = (i >= 3 && i <= 7); X box(x, y, x + fkey_sizes[n].x, y + fkey_sizes[n].y, PIX_SRC); X box(x+2, y+2, x + fkey_sizes[n].x-2, y + fkey_sizes[n].y-2, PIX_SRC); X if (i != 10 && (p = find_key(x+4,y+4))) X pw_text(msg_win, x+3, y+3+l_height(SMALL), PIX_SRC,fonts[SMALL], p); X /* shade the break key (backspace on sun3's) -- can't set */ X else if (i == 10) X pw_replrop(msg_win, x+3, y+3, fkey_sizes[n].x-5, fkey_sizes[n].y-5, X PIX_SRC | PIX_DST, &shade_50, 0,0); X x += fkey_sizes[n].x + BORDER; X } X X x = RIGHT_START; X /* print right keys */ X for (i = 0; i < 15; i++) { X box(x, y, x + fkey_sizes[0].x, y + fkey_sizes[0].y, PIX_SRC); X box(x+2, y+2, x + fkey_sizes[0].x-2, y + fkey_sizes[0].y-2, PIX_SRC); X if (p = find_key(x+4,y+4)) X pw_text(msg_win, x+3, y+3+l_height(SMALL),PIX_SRC, fonts[SMALL], p); X if (!((i+1) % 3)) X y += fkey_sizes[0].y + BORDER, x -= 2*(fkey_sizes[0].x + BORDER); X else X x += fkey_sizes[0].x + BORDER; X } X x = TOP_START; X y = KEYTOP + BORDER + fkey_sizes[0].y + l_height(DEFAULT); X pw_rop(msg_win, x, y-11, 16,16, PIX_SRC, &mouse_left, 0,0); X pw_text(msg_win, x+30, y, PIX_SRC, fonts[DEFAULT], l_msg); X X y += BORDER + fkey_sizes[0].y; X pw_rop(msg_win, x,y-11, 16,16, PIX_SRC, &mouse_middle, 0,0); X pw_text(msg_win, x+30, y, PIX_SRC, fonts[DEFAULT], m_msg); X X y += BORDER + fkey_sizes[0].y; X pw_rop(msg_win, x,y-11, 16,16, PIX_SRC, &mouse_right, 0,0); X pw_text(msg_win, x+30, y, PIX_SRC, fonts[DEFAULT], r_msg); X X x = (msg_rect.r_width - 26*l_width(DEFAULT))/2; X y += BORDER + fkey_sizes[0].y; X highlight(msg_win, x, y, DEFAULT, "You may not set shaded keys"); X X y += BORDER + fkey_sizes[0].y + 15; X for (i = 0; i < BORDER; i++) X draw(0, y+i, msg_rect.r_width, y+i, PIX_SRC); X y += 10; X for (i = 0; i < BORDER; i++) X draw(0, y+l_height(LARGE)+i, msg_rect.r_width, y+l_height(LARGE)+i, X PIX_SRC); X return y; X} X print_valid_functions(y) register int y; X{ X register int x, n, cmd_len = 12 * l_width(DEFAULT); X register char *p; X X y += 20, x = (msg_rect.r_width - 25*l_width(LARGE))/2; X highlight (msg_win, x, y, LARGE, "Available Command Names"); X y += 20, x = 30; X for (n = 0; p = cmds[n].command; n++) { X if (x + cmd_len > msg_rect.r_width - 5) X y += l_height(DEFAULT), x = 30; X pw_text(msg_win, x, y, PIX_SRC, fonts[DEFAULT], p); X x += cmd_len; X } X for (n = 0; p = fkey_cmds[n].command; n++) { X if (x + cmd_len > msg_rect.r_width - 5) X y += l_height(DEFAULT), x = 30; X pw_text(msg_win, x, y, PIX_SRC, fonts[DEFAULT], p); X x += cmd_len; X } X} END_OF_FILE if test 13831 -ne `wc -c <'fkeys.c'`; then echo shar: \"'fkeys.c'\" unpacked with wrong size! fi # end of 'fkeys.c' fi if test -f 'select.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'select.c'\" else echo shar: Extracting \"'select.c'\" \(13055 characters\) sed "s/^X//" >'select.c' <<'END_OF_FILE' X/* select.c (c) copyright 1986 (Dan Heller) */ X X/* X * Routine which handle io (selection on file descriptors) between user and X * the various windows. X * X * In toolmode, the user types characters and each character is interpreted X * here and, if applicable, is sent to rite.c where it is appended to a X * string similar to a tty driver and fgets. When the user types a '\n' the X * rite() routine returns the string and we call add_to_letter to append the X * string to the letter. Signals are caught here as well. that is the signal X * characters setup by the user are checked and if one matches, call the signal X * handling routine as if there were a real signal. X * X * Mouse handling is done here. See code for more detail. X */ X#include "mush.h" X X#define READ_MSG (char *)'r' X#define DEL_MSG (char *)'d' X#define UNDEL_MSG (char *)'u' X#define REPL_MSG (char *)'R' X#define SAVE_MSG (char *)'s' X#define PRNT_MSG (char *)'p' X#define PRE_MSG (char *)'P' X#define E_EDIT (char *)'e' X#define E_VIEW (char *)'v' X#define E_INCLUDE (char *)'i' X#define E_SEND (char *)'S' X#define E_ABORT (char *)'a' X#define MENU_HELP (char *)'h' X#define O_SAVE (char *)'s' X#define O_QUIT (char *)'q' X#define O_RSTR (char *)'r' X X#define N_MENU_ITEMS 8 X#define E_MENU_ITEMS 6 X msg_io(gfxsw, ibits, obits, ebits, timer) register struct gfxsubwindow *gfxsw; register int *ibits,*obits,*ebits; struct timeval **timer; X{ X register char *p; X struct inputevent event; X static char lastchar; X static int line, count; X X if (*ibits & ~(1 << gfxsw->gfx_windowfd)) { X *ibits = *obits = *ebits = 0; X return; X } X if (input_readevent(msg_sw->ts_windowfd, &event) == -1) { X error("input event"); X return; X } X /* X if (ID == LOC_WINENTER) { X int x; X struct inputmask im; X win_getinputmask(gfxsw->gfx_windowfd, &im, &x); X win_setinputmask(hdr_sw->ts_windowfd, &im, &im, x); X } X */ X if (ID >= KEY_LEFTFIRST) X if (ison(glob_flags, IS_GETTING)) X print("Finish editing letter first"); X else X (void) func_key(ID); X else if (isascii(ID) && (msg_pix || ison(glob_flags, IS_GETTING) || X getting_opts)) { X if (getting_opts) { X /* X * txt.x <= 5 indicates not to accept typed input for options X * and function key setting. X */ X if (txt.x > 5) { X /* ^C, ^\ or ^U kills line */ X type_cursor(PIX_XOR); X if (ID == tchars.t_intrc || ID == tchars.t_quitc || X ID == _tty.sg_kill) { X rite(_tty.sg_kill), txt.x = 5; X if (getting_opts == 1) X option_line(line), display_opts(0); X else X set_key(0, 0, 0); X } else if (p = rite((char)ID)) { X /* if no string entered, preserve old value */ X if (*p && getting_opts == 1) X add_opt(p, line); X if (getting_opts == 2) X set_key(p, 0,0); X } else X type_cursor(PIX_XOR); X } X } X /* X * This section MUST BE BEFORE the following "is_getting" section. X * If user displays a message while editing a letter, he must hit 'q' X * to return to edit mode. He may not edit a new letter while one is X * already being edited. X */ X else if (msg_pix) X if (isdigit(ID)) { X if (!isdigit(lastchar)) X count = 0; X count = count * 10 + ID - '0'; X } else { X /* scroll <count> lines */ X if (!count || count > msg_pix->pr_size.y / l_height(curfont)) X count = 1; X if (ID == 'k' || ID == 'K' || ID == '-') X scroll_win(-count); X else if (ID == '\n' || ID == '\r' || ID == 'j') X scroll_win(count); X else if (ID == ' ') X scroll_win(crt); X else if ((ID == 'q' || ID == 'Q') && X ison(glob_flags, IS_GETTING)) { X pr_destroy(msg_pix), msg_pix = (struct pixrect *)NULL; X win_setcursor(msg_sw->ts_windowfd, &write_cursor); X txt.x = 5, txt.y = msg_rect.r_height - l_height(curfont); X wprint("\n(continue editing letter)\n"); X clr_bot_line(); X type_cursor(PIX_SRC); X } X } X /* X * If msg_pix is NULL, then we are not reading a message. If we are X * editing a letter, then enter the keys typed. If we are doing X * nothing, ignore this in X */ do_menu(event, fd, message) caddr_t event; X{ X static char buf[20]; X struct menuitem *m_item; X char *action; X static struct menuitem msg_menu_items[] = { X { MENU_IMAGESTRING, "Read", READ_MSG }, X { MENU_IMAGESTRING, "Delete", DEL_MSG }, X { MENU_IMAGESTRING, "Undelete", UNDEL_MSG }, X { MENU_IMAGESTRING, "Reply", REPL_MSG }, X { MENU_IMAGESTRING, "Save", SAVE_MSG }, X { MENU_IMAGESTRING, "Preserve", PRE_MSG }, X { MENU_IMAGESTRING, "Print", PRNT_MSG }, X { MENU_IMAGESTRING, "Help", MENU_HELP } X }; X static struct menu help_menu = { X MENU_IMAGESTRING, "Item Help", X N_MENU_ITEMS, msg_menu_items, X (struct menu *)NULL, NULL X }; X static struct menu msgs_menu = { X MENU_IMAGESTRING, buf, N_MENU_ITEMS, X msg_menu_items, &help_menu, NULL X }; X /* to have the menu stack maintain order of menus upon each invokation, X * declare menu_ptr to be static and remove the following two lines X * after the declaration. X */ X struct menu *menu_ptr = &msgs_menu; X msgs_menu.m_next = &help_menu; X help_menu.m_next = (struct menu *)NULL; X X if (!msg_cnt) { X print("No Messages."); X return; X } X if (fd) { X (void) sprintf(buf, "Message #%d", message+1); X if (m_item = menu_display(&menu_ptr, (struct inputevent *)event, fd)) X action = m_item->mi_data; X else X return; X } else X action = event; X X if (menu_ptr == &help_menu || action == MENU_HELP) { X switch(action) { X when DEL_MSG: case UNDEL_MSG: X (void) help(fd, "menu_delete", tool_help); X when READ_MSG: (void) help(fd, "next", tool_help); X when REPL_MSG: (void) help(fd, "menu_respond", tool_help); X when SAVE_MSG: (void) help(fd, "save", tool_help); X when PRE_MSG: (void) help(fd, "preserve", tool_help); X when PRNT_MSG: (void) help(fd, "printer", tool_help); X when MENU_HELP: X if (menu_ptr == &help_menu) X (void) help(fd, "help_menu_help_msg", tool_help); X else X (void) help(fd, "msg_menu", tool_help); X } X return; X } X set_isread(message); X if (action == SAVE_MSG) { X panel_set(msg_num_item, PANEL_VALUE, sprintf(buf, "%d", message+1), 0); X ((struct inputevent *)event)->ie_code = MS_LEFT; X do_file_dir(save_item, 0, event); X panel_set(msg_num_item, PANEL_VALUE, NO_STRING, 0); X return; X } else if (action == PRNT_MSG || action == PRE_MSG || X action == UNDEL_MSG || action == DEL_MSG) { X fkey_misc(action, message); X return; X } X if (isoff(glob_flags, IS_GETTING)) { X current_msg = message; X (void) do_hdrs(0, DUBL_NULL, NULL); X } X if (action == REPL_MSG) { X respond_mail(respond_item, 0, event); X return; X } else if (ison(glob_flags, IS_GETTING)) { X if (exec_pid) X /* User can read a message as long as he's not in an editor */ X print("Finish editing message first"); X else { X (void) do_hdrs(0, DUBL_NULL, NULL); X display_msg(message, (long)0); X } X return; X } X display_msg(current_msg, (long)0); X} X X/* miscellaneous function key actions there are here because the defines X * for DEL_MSG, etc are here in this file and the function is called from X * here more often. X */ fkey_misc(action, message) char *action; X{ X int argc; X register char **argv; X char buf[30]; X X print("Message #%d ", message+1); X if (action == UNDEL_MSG || action == DEL_MSG) X print_more("%sd. ", sprintf(buf, "%selete", X (action == DEL_MSG)? "d": "und")); X else if (action == PRNT_MSG) { X print_more("sent to printer"); X (void) strcpy(buf, "lpr"); X } else if (action == PRE_MSG) X print_more("%sd", strcpy(buf, "preseve")); X (void) sprintf(&buf[strlen(buf)], " %d", message+1); X if (message == current_msg && action == DEL_MSG) X do_clear(); X X if (argv = make_command(buf, DUBL_NULL, &argc)) X (void) do_command(argc, argv, msg_list); X return; X} X view_opts_menu(event, fd) struct inputevent *event; X{ X static char buf[5]; X struct menuitem *m_item; X char *action; X static struct menuitem opts_items[] = { X { MENU_IMAGESTRING, "Save Options", O_SAVE }, X { MENU_IMAGESTRING, "Restore Options", O_RSTR }, X { MENU_IMAGESTRING, "Quit Options", O_QUIT }, X { MENU_IMAGESTRING, "Help", MENU_HELP } X }; X static struct menu msgs_menu = { X MENU_IMAGESTRING, "Options", 4, opts_items, (struct menu *)NULL, NULL X }; X struct menu *menu_ptr = &msgs_menu; X X if (m_item = menu_display(&menu_ptr, event, fd)) X action = m_item->mi_data; X else X return; X switch(action) { X case O_SAVE: X save_opts(0, DUBL_NULL); X when O_RSTR: X init(); X if (getting_opts == 1) X view_options(); X else X set_fkeys(); X when O_QUIT: X do_clear(); X unlock_cursors(); /* actually resets msg_win's cursor */ X if (isoff(glob_flags, IS_GETTING) && msg_cnt) X if (isoff(msg[current_msg].m_flags, DELETE)) X display_msg(current_msg, (long)0); X else X (void) read_mail(NO_ITEM, 0, NO_EVENT); X when MENU_HELP: X (void) help(fd, (getting_opts == 1)? "options": "fkeys", tool_help); X } X} END_OF_FILE if test 13055 -ne `wc -c <'select.c'`; then echo shar: \"'select.c'\" unpacked with wrong size! fi # end of 'select.c' fi echo shar: End of archive 6 \(of 14\). cp /dev/null ark6isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 14 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.