Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!aramis.rutgers.edu!dartagnan.rutgers.edu!mcgrew From: mcgrew@dartagnan.rutgers.edu (Charles Mcgrew) Newsgroups: comp.sources.sun Subject: v01i025: Tooltool - a suntools user interface builder, Part 06/13 Message-ID: Date: 7 Jun 89 04:16:07 GMT Organization: Rutgers Univ., New Brunswick, N.J. Lines: 925 Approved: mcgrew@aramis.rutgers.edu Submitted-by: Chuck Musciano Posting-number: Volume 1, Issue 25 Archive-name: tooltool2.1c/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 'samples/keytool' <<'END_OF_FILE' X#!/bin/sh X# X# ***keytool - Ken Laprade - 31 Oct 88 *** X# X# A tooltool application to run a command with interactively redefineable X# function keys. C-S-M-right-mouse brings up a menu that controls key X# definition. Two keysets may be defined called primary and secondary. X# Any undefined C-S-M-function-key will toggle between the two keysets. X# Typical useful commands: /bin/ssh, /usr/ucb/telnet, /usr/ucb/rlogin. X# X# Xif test "$1" = "-i" ; then X shift; X if test "$1" = "" ; then X echo "Usage: keytool [-i init_file] command [args ...]"; exit X fi X initfile=$1; shift; Xelse X initfile="$HOME/.keytool" Xfi Xcmd=$1 Xif /bin/test "$cmd" = "" ; then X echo "Usage: keytool [-i init_file] command [args ...]"; exit Xfi Xif test ! -x $cmd ; then X echo "keytool: bad command: $cmd."; exit Xfi Xshift; X Xtooltool $@ << END X Xapplication "$cmd" Xlabel "keytool" X X/* Fonts: */ X#define POPUP_FONT "/usr/lib/fonts/fixedwidthfonts/screen.b.14" X#define TEXT_FONT "/usr/lib/fonts/fixedwidthfonts/screen.r.14" X#define SPECIAL_FONT "./keytool.r.14" X#define MENU_FONT "/usr/lib/fonts/fixedwidthfonts/screen.b.14" X X#define DEFAULT_INIT_FILE "./keytool.defaults" X X/* Macros for repetitive functions: */ X#define init_keys() { \ X /* Initialize all keys, both primary and secondary keysets. */ \ X for (i = 0; i ",init_file," << 'END-OF-FILE'\n",lines,"\n"); X delimiters = " \t\r\n"; X } X } X shift " LOAD" { X /* Read key definitions from initialization file. */ X init_keys(); X read_init_file(); X } X control " Copy Primary -> Secondary" { X keypress[1] = keypress[0]; X definition = keypress[active_keyset][keyname[selected_key]][selected_shift]; X } X shift control " Copy Secondary -> Primary" { X keypress[0] = keypress[1]; X definition = keypress[active_keyset][keyname[selected_key]][selected_shift]; X } X meta "Default File" { X if (exists("$initfile")) init_file = "$initfile"; X else init_file = DEFAULT_INIT_FILE; X } X end_button X choice displayed_separator at XTEXT4 YTEXT3 X display current X "Item Separator" { remove line_separator; display item_separator; } X "Line Separator" { remove item_separator; display line_separator; } X end_choice X text item_separator at XTEXT5 YTEXT3 X label ":" X display 1 X retain 1 X font SPECIAL_FONT X trigger "" X ignore "" X end_text X text line_separator at XTEXT5 YTEXT3 X label ":" X display 1 X retain 1 X font SPECIAL_FONT X trigger "" X ignore "" X end_text X button at XTEXT6 Y3 X#define set_separator(S) { if (displayed_separator) line_separator = S; \ X else item_separator = S; } X normal "\t":SPECIAL_FONT set_separator("\t") X shift "\177":SPECIAL_FONT set_separator("\177") X control "^U":SPECIAL_FONT set_separator("^U") X shift control "^W":SPECIAL_FONT set_separator("^W") X end_button X end_gadgets Xend_dialog X Xkeys X#define keydef(K) key K \ X normal send keypress[active_keyset]["K"][0]; \ X shift send keypress[active_keyset]["K"][1]; \ X control send keypress[active_keyset]["K"][2]; \ X shift control send keypress[active_keyset]["K"][3]; \ X meta send keypress[active_keyset]["K"][4]; \ X meta shift send keypress[active_keyset]["K"][5]; \ X meta control send keypress[active_keyset]["K"][6]; \ X meta shift control { \ X if (keypress[active_keyset]["K"][7] == "") { \ X active_keyset = !active_keyset; \ X definition = keypress[active_keyset][keyname[selected_key]][selected_shift]; \ X } \ X else send keypress[active_keyset]["K"][7]; \ X } \ X end_key X X keydef(L2) X keydef(L3) X keydef(L4) X keydef(L9) X keydef(L10) X keydef(F1) X keydef(F2) X keydef(F3) X keydef(F4) X keydef(F5) X keydef(F6) X keydef(F7) X keydef(F8) X keydef(F9) X keydef(R1) X keydef(R2) X keydef(R3) X keydef(R4) X keydef(R5) X keydef(R6) X keydef(R7) X keydef(R8) X keydef(R9) X keydef(R10) X keydef(R11) X keydef(R12) X keydef(R13) X keydef(R14) X keydef(R15) Xend_keys X Xmouse X base 0 characters X#define mousedef(K) button K \ X /* Normal is left to perform the suntools functions. */ \ X shift send format(keypress[active_keyset]["K"][1],mouse_x,mouse_y); \ X control send format(keypress[active_keyset]["K"][2],mouse_x,mouse_y); \ X shift control send format(keypress[active_keyset]["K"][3],mouse_x,mouse_y); \ X meta send format(keypress[active_keyset]["K"][4],mouse_x,mouse_y); \ X meta shift send format(keypress[active_keyset]["K"][5],mouse_x,mouse_y); \ X meta control send format(keypress[active_keyset]["K"][6],mouse_x,mouse_y); \ X meta shift control send format(keypress[active_keyset]["K"][7],mouse_x,mouse_y); \ X end_button X X mousedef(LEFT) X mousedef(MIDDLE) X button RIGHT X /* Normal is left to perform the suntools functions. */ X shift send format(keypress[active_keyset]["RIGHT"][1],mouse_x,mouse_y); X control send format(keypress[active_keyset]["RIGHT"][2],mouse_x,mouse_y); X shift control send format(keypress[active_keyset]["RIGHT"][3],mouse_x,mouse_y); X meta send format(keypress[active_keyset]["RIGHT"][4],mouse_x,mouse_y); X meta shift send format(keypress[active_keyset]["RIGHT"][5],mouse_x,mouse_y); X meta control send format(keypress[active_keyset]["RIGHT"][6],mouse_x,mouse_y); X meta shift control menu X "Define Keys":MENU_FONT X display key_definition_window; X "Use Primary":MENU_FONT X { active_keyset = 0; definition = keypress[0][keyname[selected_key]][selected_shift]; } X "Use Secondary":MENU_FONT X { active_keyset = 1; definition = keypress[1][keyname[selected_key]][selected_shift]; } X "Read Init File":MENU_FONT { X /* Read key definitions from initialization file. */ X init_keys(); X read_init_file(); X } X end_menu X end_button Xend_mouse XEND END_OF_FILE if test 15432 -ne `wc -c <'samples/keytool'`; then echo shar: \"'samples/keytool'\" unpacked with wrong size! fi chmod +x 'samples/keytool' # end of 'samples/keytool' fi if test -f 'windows.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'windows.c'\" else echo shar: Extracting \"'windows.c'\" \(14642 characters\) sed "s/^X//" >'windows.c' <<'END_OF_FILE' X/************************************************************************/ X/* Copyright 1988 by Chuck Musciano and Harris Corporation */ X/* */ X/* Permission to use, copy, modify, and distribute this software */ X/* and its documentation for any purpose and without fee is */ X/* hereby granted, provided that the above copyright notice */ X/* appear in all copies and that both that copyright notice and */ X/* this permission notice appear in supporting documentation, and */ X/* that the name of Chuck Musciano and Harris Corporation not be */ X/* used in advertising or publicity pertaining to distribution */ X/* of the software without specific, written prior permission. */ X/* Chuck Musciano and Harris Corporation make no representations */ X/* about the suitability of this software for any purpose. It is */ X/* provided "as is" without express or implied warranty. */ X/* */ X/* The sale of any product based wholely or in part upon the */ X/* technology provided by tooltool is strictly forbidden without */ X/* specific, prior written permission from Harris Corporation. */ X/* Tooltool technology includes, but is not limited to, the source */ X/* code, executable binary files, specification language, and */ X/* sample specification files. */ X/************************************************************************/ X X X#include X X#include "tooltool.h" X X#include X X#define TOOLTOOL_ICON "tooltool.icon" X XPRIVATE short icon_bits[] = { X#include TOOLTOOL_ICON X }; Xmpr_static(tt_default_icon_pr, 64, 64, 1, icon_bits); X XEXPORT Tty tty = NULL; X XPUBLIC event_proc(), X notify_proc(), X background_proc(), X close_proc(), X tty_handler(), X tt_dialog_done(); X X/************************************************************************/ X/* This group of routines deals with laying out the tooltool windows */ X/************************************************************************/ X X/************************************************************************/ XPRIVATE gadget_rows(d) X Xd_ptr d; X X{ int j, k, extra, count, row, height; X g_ptr b, next, start; X X tt_build_images(d); X for (next = d->gadgets, row = 4, count = 0; next; row += height + 4) { X extra = (int) window_get(d->panel, WIN_WIDTH) - 4; X for (b = start = next, height = 0; b; b = b->next) X if (b->width + 4 > extra) { /* no room for this gadget */ X next = b; X break; X } X else { X extra -= b->width + 4; X count++; X if (b->height > height) X height = b->height; X } X if (b == NULL) X next = NULL; X if (next == start) { X next = start->next; X height = start->height; X count++; X } X if (!d->justified) X extra = 0; X for (b = start, j = 4, count--; b != next; b = b->next) { X if (d->g_align == ALIGN_TOP) X k = row; X else if (d->g_align == ALIGN_MIDDLE) X k = row + (height - b->height) / 2; X else X k = row + height - b->height; X tt_make_gadget(d, b, j, k); X if (count > 0) { X j += b->width + 4 + (extra / count); X extra -= extra / count--; X } X } X } X panel_fit_height(d->panel); X} X X/************************************************************************/ XPRIVATE gadget_columns(d) X Xd_ptr d; X X{ int j, k, extra, count, col, width; X g_ptr b, next, start; X X tt_build_images(d); X for (next = d->gadgets, col = count = 0; next; col += width + 4) { X extra = (int) window_get(d->panel, WIN_HEIGHT) - 4; X for (b = start = next, width = 0; b; b = b->next) X if (b->height + 4 > extra) { /* no room for this gadget */ X next = b; X break; X } X else { X extra -= b->height + 4; X count++; X if (b->width > width) X width = b->width; X } X if (b == NULL) X next = NULL; X if (next == start) { X next = start->next; X width = start->width; X count++; X } X if (!d->justified) X extra = 0; X for (b = start, j = 4, count--; b != next; b = b->next) { X if (d->g_align == ALIGN_TOP) X k = 4 + col; X else if (d->g_align == ALIGN_MIDDLE) X k = 4 + col + (width - b->width) / 2; X else X k = 4 + col + width - b->width; X tt_make_gadget(d, b, k, j); X if (count > 0) { X j += b->height + 4 + (extra / count); X extra -= extra / count--; X } X } X } X panel_fit_width(d->panel); X} X X/************************************************************************/ XEXPORT build_window(argc, argv) X Xint argc; Xchar **argv; X X{ int i, j, w, h; X g_ptr b, start, next; X char *args[64]; X struct pixrect *icon_pr; X Icon ic; X Rect *fr, *sr; X d_ptr d; X static char *pos_hack[5]; X X if (tt_icon != NULL) X icon_pr = tt_load_icon(tt_icon); X else X icon_pr = &tt_default_icon_pr; X ic = icon_create(ICON_IMAGE, icon_pr, X ICON_LABEL, "", X ICON_WIDTH, icon_pr->pr_size.x, X ICON_HEIGHT, icon_pr->pr_size.y, X 0); X tt_base_window->frame = window_create(NULL, FRAME, X FRAME_ARGC_PTR_ARGV, &argc, argv, X FRAME_ICON, ic, X WIN_CLIENT_DATA, tt_base_window, X 0); X if (tt_base_window->label) X window_set(tt_base_window->frame, FRAME_LABEL, tt_base_window->label, 0); X if (tt_base_window->win_x != -1) X window_set(tt_base_window->frame, WIN_X, tt_base_window->win_x, WIN_Y, tt_base_window->win_y, 0); X X args[0] = tt_program; X args[1] = POLLING_MAGIC_NUMBER; X args[2] = safe_malloc(10); X args[3] = safe_malloc(10); X sprintf(args[2], "%d", tt_base_window->columns / (tt_base_window->is_chars? 1 : charwidth_of(tt_a_font))); X sprintf(args[3], "%d", tt_base_window->rows / (tt_base_window->is_chars? 1 : charheight_of(tt_a_font))); X tokenize(tt_application, &i, args + 4, 60); X for (j = 1, i += 4; j < argc; j++) X args[i++] = argv[j]; X args[i] = NULL; X if (tt_base_window->gadgets == NULL) { X if (*tt_application) X tty = window_create(tt_base_window->frame, TTY, X tt_base_window->is_chars? WIN_ROWS : WIN_HEIGHT, tt_base_window->rows, X tt_base_window->is_chars? WIN_COLUMNS : WIN_WIDTH, tt_base_window->columns, X WIN_FONT, tt_a_font, X TTY_QUIT_ON_CHILD_DEATH, TRUE, X TTY_ARGV, args, X 0); X } X else if (tt_base_window->gadget_pos == G_TOP) { X tt_base_window->panel = window_create(tt_base_window->frame, PANEL, X WIN_ROWS, 24, X WIN_WIDTH, tt_base_window->is_chars? charwidth_of(tt_a_font) * tt_base_window->columns : tt_base_window->columns, X WIN_FONT, tt_base_window->g_font, X WIN_CLIENT_DATA, tt_base_window, X PANEL_ACCEPT_KEYSTROKE, !tt_base_window->text_items_exist, X PANEL_BACKGROUND_PROC, background_proc, X PANEL_NOTIFY_PROC, notify_proc, X PANEL_EVENT_PROC, event_proc, X 0); X gadget_rows(tt_base_window); X if (*tt_application) X tty = window_create(tt_base_window->frame, TTY, X tt_base_window->is_chars? WIN_ROWS : WIN_HEIGHT, tt_base_window->rows, X tt_base_window->is_chars? WIN_COLUMNS : WIN_WIDTH, tt_base_window->columns, X WIN_BELOW, tt_base_window->panel, X WIN_X, 0, X WIN_FONT, tt_a_font, X TTY_QUIT_ON_CHILD_DEATH, TRUE, X TTY_ARGV, args, X 0); X } X else if (tt_base_window->gadget_pos == G_BOTTOM) { X if (*tt_application) X tty = window_create(tt_base_window->frame, TTY, X tt_base_window->is_chars? WIN_ROWS : WIN_HEIGHT, tt_base_window->rows, X tt_base_window->is_chars? WIN_COLUMNS : WIN_WIDTH, tt_base_window->columns, X WIN_FONT, tt_a_font, X TTY_QUIT_ON_CHILD_DEATH, TRUE, X TTY_ARGV, args, X 0); X if (tty && tt_base_window->rows > 0 && tt_base_window->columns > 0) X tt_base_window->panel = window_create(tt_base_window->frame, PANEL, X WIN_BELOW, tty, X WIN_X, 0, X 0); X else X tt_base_window->panel = window_create(tt_base_window->frame, PANEL, X WIN_X, 0, X WIN_Y, 0, X 0); X window_set(tt_base_window->panel, X WIN_ROWS, 24, X WIN_WIDTH, tt_base_window->is_chars? charwidth_of(tt_a_font) * tt_base_window->columns : tt_base_window->columns, X WIN_FONT, tt_base_window->g_font, X WIN_CLIENT_DATA, tt_base_window, X PANEL_ACCEPT_KEYSTROKE, !tt_base_window->text_items_exist, X PANEL_BACKGROUND_PROC, background_proc, X PANEL_NOTIFY_PROC, notify_proc, X PANEL_EVENT_PROC, event_proc, X 0); X gadget_rows(tt_base_window); X } X else if (tt_base_window->gadget_pos == G_LEFT) { X tt_base_window->panel = window_create(tt_base_window->frame, PANEL, X WIN_HEIGHT, tt_base_window->is_chars? charheight_of(tt_a_font) * tt_base_window->rows : tt_base_window->rows, X WIN_COLUMNS, 80, X WIN_FONT, tt_base_window->g_font, X WIN_CLIENT_DATA, tt_base_window, X PANEL_ACCEPT_KEYSTROKE, !tt_base_window->text_items_exist, X PANEL_BACKGROUND_PROC, background_proc, X PANEL_NOTIFY_PROC, notify_proc, X PANEL_EVENT_PROC, event_proc, X 0); X gadget_columns(tt_base_window); X if (*tt_application) X tty = window_create(tt_base_window->frame, TTY, X tt_base_window->is_chars? WIN_ROWS : WIN_HEIGHT, tt_base_window->rows, X tt_base_window->is_chars? WIN_COLUMNS : WIN_WIDTH, tt_base_window->columns, X WIN_RIGHT_OF, tt_base_window->panel, X WIN_Y, 0, X WIN_FONT, tt_a_font, X TTY_QUIT_ON_CHILD_DEATH, TRUE, X TTY_ARGV, args, X 0); X } X else if (tt_base_window->gadget_pos == G_RIGHT) { X if (*tt_application) X tty = window_create(tt_base_window->frame, TTY, X tt_base_window->is_chars? WIN_ROWS : WIN_HEIGHT, tt_base_window->rows, X tt_base_window->is_chars? WIN_COLUMNS : WIN_WIDTH, tt_base_window->columns, X WIN_FONT, tt_a_font, X TTY_QUIT_ON_CHILD_DEATH, TRUE, X TTY_ARGV, args, X 0); X if (tty && tt_base_window->rows > 0 && tt_base_window->columns > 0) X tt_base_window->panel = window_create(tt_base_window->frame, PANEL, X WIN_RIGHT_OF, tty, X WIN_Y, 0, X 0); X else X tt_base_window->panel = window_create(tt_base_window->frame, PANEL, X WIN_X, 0, X WIN_Y, 0, X 0); X window_set(tt_base_window->panel, X WIN_HEIGHT, tt_base_window->is_chars? charheight_of(tt_a_font) * tt_base_window->rows : tt_base_window->rows, X WIN_COLUMNS, 80, X WIN_FONT, tt_base_window->g_font, X WIN_CLIENT_DATA, tt_base_window, X PANEL_ACCEPT_KEYSTROKE, !tt_base_window->text_items_exist, X PANEL_BACKGROUND_PROC, background_proc, X PANEL_NOTIFY_PROC, notify_proc, X PANEL_EVENT_PROC, event_proc, X 0); X gadget_columns(tt_base_window); X } X window_fit(tt_base_window->frame); X X fr = (Rect *) window_get(tt_base_window->frame, FRAME_OPEN_RECT); X sr = (Rect *) window_get(tt_base_window->frame, WIN_SCREEN_RECT); X if (fr->r_left + fr->r_width > sr->r_width) X window_set(tt_base_window->frame, WIN_X, max(sr->r_width - fr->r_width, 0), 0); X if (fr->r_top + fr->r_height > sr->r_height) X window_set(tt_base_window->frame, WIN_Y, max(sr->r_height - fr->r_height, 0), 0); X X fr = (Rect *) window_get(tt_base_window->frame, FRAME_CLOSED_RECT); X for (d = tt_base_window->next; d; d = d->next) { X if (d->g_align == NO_ALIGN) X d->g_align = ALIGN_TOP; X pos_hack[0] = ""; X pos_hack[1] = "-WP"; X pos_hack[2] = safe_malloc(7); X pos_hack[3] = safe_malloc(7); X pos_hack[4] = NULL; X sprintf(pos_hack[2], "%d", fr->r_left); X sprintf(pos_hack[3], "%d", fr->r_top); X d->frame = window_create(tt_base_window->frame, FRAME, X FRAME_SHOW_LABEL, FALSE, X FRAME_DONE_PROC, tt_dialog_done, X FRAME_ARGS, 4, pos_hack, X WIN_CLIENT_DATA, d, X 0); X if (d->label) X window_set(d->frame, FRAME_LABEL, d->label, FRAME_SHOW_LABEL, TRUE, 0); X d->panel = window_create(d->frame, PANEL, X WIN_HEIGHT, d->is_chars? charwidth_of(d->g_font) * d->rows : d->rows, X WIN_WIDTH, d->is_chars? charwidth_of(d->g_font) * d->columns : d->columns, X WIN_FONT, d->g_font, X WIN_CLIENT_DATA, d, X PANEL_ACCEPT_KEYSTROKE, !d->text_items_exist, X PANEL_BACKGROUND_PROC, background_proc, X PANEL_NOTIFY_PROC, notify_proc, X PANEL_EVENT_PROC, event_proc, X 0); X if (d->gadget_pos == G_TOP || d->gadget_pos == G_BOTTOM) X gadget_rows(d); X else X gadget_columns(d); X window_fit(d->panel); X window_fit(d->frame); X } X X notify_interpose_event_func(tt_base_window->frame, close_proc, NOTIFY_SAFE); X if (tt_base_window->panel) X notify_interpose_event_func(tt_base_window->panel, close_proc, NOTIFY_SAFE); X X if (tty) { X notify_interpose_event_func(tty, tty_handler, NOTIFY_SAFE); X tt_ttymenu = (Menu) window_get(tty, WIN_MENU); X } X X if (tty == NULL || tt_base_window->rows <= 0 || tt_base_window->columns <= 0) { X if (tty) X window_set(tty, WIN_SHOW, FALSE, 0); X if (tt_base_window->panel) X window_fit(tt_base_window->panel); X window_fit(tt_base_window->frame); X } X X fr = (Rect *) window_get(tt_base_window->frame, FRAME_OPEN_RECT); X window_set(tt_base_window->frame, WIN_X, 0, WIN_Y, 0, 0); X for (d = tt_base_window->next; d; d = d->next) X if (d->win_x != -1) { X window_set(d->frame, WIN_X, d->win_x, WIN_Y, d->win_y, 0); X w = (int) window_get(d->frame, WIN_WIDTH); X h = (int) window_get(d->frame, WIN_HEIGHT); X if (d->win_x + w > sr->r_width) X window_set(d->frame, WIN_X, max(sr->r_width - w, 0), 0); X if (d->win_y + h > sr->r_height) X window_set(d->frame, WIN_Y, max(sr->r_height - h, 0), 0); X } X else X window_set(d->frame, X WIN_X, (sr->r_width - (int) window_get(d->frame, WIN_WIDTH)) / 2, X WIN_Y, (sr->r_height - (int) window_get(d->frame, WIN_HEIGHT)) / 2, X 0); X window_set(tt_base_window->frame, WIN_X, fr->r_left, WIN_Y, fr->r_top, 0); X X init_function_fix(tt_base_window->frame); X if (tty) X init_function_fix(tty); X if (tt_base_window->panel) X init_function_fix(tt_base_window->panel); X for (d = tt_base_window->next; d; d = d->next) { X init_function_fix(d->frame); X init_function_fix(d->panel); X } X X tt_do_action(tt_initial_action); X} END_OF_FILE if test 14642 -ne `wc -c <'windows.c'`; then echo shar: \"'windows.c'\" unpacked with wrong size! fi # end of 'windows.c' fi echo shar: End of archive 6 \(of 13\). cp /dev/null ark6isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 13 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 Chuck Musciano ARPA : chuck@trantor.harris-atd.com Harris Corporation Usenet: ...!uunet!x102a!trantor!chuck PO Box 37, MS 3A/1912 AT&T : (407) 727-6131 Melbourne, FL 32902 FAX : (407) 727-{5118,5227,4004}