944 lines
27 KiB
C
944 lines
27 KiB
C
/*
|
||
* Xgraph Dialog Boxes
|
||
*
|
||
* This file constructs the hardcopy and error dialog
|
||
* boxes used by xgraph. It uses the mini-toolbox given
|
||
* in toolbox.c.
|
||
*/
|
||
|
||
#include "copyright.h"
|
||
#include "xgout.h"
|
||
#include "xgraph.h"
|
||
#include "hard_devices.h"
|
||
#include "xtb.h"
|
||
#include "params.h"
|
||
#include <stdio.h>
|
||
#include <X11/Xutil.h>
|
||
|
||
void do_error();
|
||
|
||
#define MAXCHBUF 1024
|
||
|
||
#ifdef SHADOW
|
||
#define gray_width 16
|
||
#define gray_height 16
|
||
static short gray_bits[] =
|
||
{
|
||
0x5555, 0xaaaa, 0x5555, 0xaaaa,
|
||
0x5555, 0xaaaa, 0x5555, 0xaaaa,
|
||
0x5555, 0xaaaa, 0x5555, 0xaaaa,
|
||
0x5555, 0xaaaa, 0x5555, 0xaaaa};
|
||
|
||
#endif
|
||
|
||
static void make_msg_box();
|
||
static void del_msg_box();
|
||
static int getline_xgraph(char**,char*);
|
||
|
||
|
||
#define D_VPAD 2
|
||
#define D_HPAD 2
|
||
#define D_INT 4
|
||
#define D_BRDR 2
|
||
#define D_INP 35
|
||
#define D_DSP 10
|
||
#define D_FS 10
|
||
|
||
struct d_info {
|
||
char *prog; /* Program name */
|
||
xtb_data cookie; /* Info used by do_harcopy */
|
||
Window choices; /* Output device choices */
|
||
Window fod; /* File or device flag */
|
||
Window fodspec; /* File or device spec */
|
||
Window docu_p; /* Document predicate */
|
||
Window dimspec; /* Maximum dimension spec */
|
||
Window tf_family; /* Title font family spec */
|
||
Window tf_size; /* Title font size spec */
|
||
Window af_family; /* Axis font family spec */
|
||
Window af_size; /* Axis font size spec */
|
||
};
|
||
|
||
#define BACKSPACE 0010
|
||
#define DELETE 0177
|
||
#define CONTROL_U 0025
|
||
#define CONTROL_X 0030
|
||
|
||
/*ARGSUSED*/
|
||
static xtb_hret
|
||
df_fun(win, ch, text, val)
|
||
Window win; /* Widget window */
|
||
int ch; /* Typed character */
|
||
char *text; /* Copy of text */
|
||
xtb_data val; /* User info */
|
||
|
||
/*
|
||
* This is the handler function for the text widget for
|
||
* specifing the file or device name. It supports simple
|
||
* line editing operations.
|
||
*/
|
||
{
|
||
if ((ch == BACKSPACE) || (ch == DELETE)) {
|
||
if (!xtb_ti_dch(win))
|
||
XBell(disp, 0);
|
||
}
|
||
else if ((ch == CONTROL_U) || (ch == CONTROL_X)) {
|
||
(void) xtb_ti_set(win, "", (xtb_data) 0);
|
||
}
|
||
else {
|
||
/* Insert if printable - ascii dependent */
|
||
if ((ch < ' ') || (ch >= DELETE) || !xtb_ti_ins(win, ch)) {
|
||
XBell(disp, 0);
|
||
}
|
||
}
|
||
return XTB_HANDLED;
|
||
}
|
||
|
||
/*ARGSUSED*/
|
||
static xtb_hret
|
||
ok_fun(win, bval, info)
|
||
Window win; /* Button window */
|
||
int bval; /* Button value */
|
||
xtb_data info; /* Local button info */
|
||
|
||
/*
|
||
* This is the handler function for when the `Ok' button
|
||
* is hit. It sets the button, does the hardcopy output,
|
||
* and turns the button off. It returns a status which
|
||
* deactivates the dialog.
|
||
*/
|
||
{
|
||
struct d_info *real_info = (struct d_info *) info;
|
||
int val,
|
||
dev_p,
|
||
doc_p;
|
||
char file_or_dev[MAXCHBUF],
|
||
dim_spec[MAXCHBUF],
|
||
*dev_spec;
|
||
char tfam[MAXCHBUF],
|
||
afam[MAXCHBUF];
|
||
char tsizstr[MAXCHBUF],
|
||
asizstr[MAXCHBUF];
|
||
double centimeters,
|
||
tsize,
|
||
asize;
|
||
xtb_hret rtn;
|
||
|
||
(void) xtb_bt_set(win, 1, (xtb_data) 0, 0);
|
||
val = xtb_br_get(real_info->choices);
|
||
if ((val >= 0) && (val < hard_count)) {
|
||
dev_p = xtb_br_get(real_info->fod);
|
||
if ((dev_p == 0) || (dev_p == 1)) {
|
||
xtb_ti_get(real_info->fodspec, file_or_dev, (xtb_data *) 0);
|
||
doc_p = xtb_bt_get(real_info->docu_p, (xtb_data *) 0, (int *) 0);
|
||
xtb_ti_get(real_info->dimspec, dim_spec, (xtb_data *) 0);
|
||
if (sscanf(dim_spec, "%lf", ¢imeters) == 1) {
|
||
xtb_ti_get(real_info->tf_family, tfam, (xtb_data *) 0);
|
||
xtb_ti_get(real_info->af_family, afam, (xtb_data *) 0);
|
||
xtb_ti_get(real_info->tf_size, tsizstr, (xtb_data *) 0);
|
||
if (sscanf(tsizstr, "%lf", &tsize) == 1) {
|
||
xtb_ti_get(real_info->af_size, asizstr, (xtb_data *) 0);
|
||
if (sscanf(asizstr, "%lf", &asize) == 1) {
|
||
/* Got all the info */
|
||
if (dev_p) {
|
||
dev_spec = (char *) 0;
|
||
}
|
||
else {
|
||
dev_spec = hard_devices[val].dev_spec;
|
||
}
|
||
do_hardcopy(real_info->prog, real_info->cookie,
|
||
hard_devices[val].dev_init, dev_spec,
|
||
file_or_dev, centimeters,
|
||
tfam, tsize, afam, asize, doc_p);
|
||
rtn = XTB_STOP;
|
||
}
|
||
else {
|
||
/* Bad axis size */
|
||
do_error("Bad axis font size\n");
|
||
rtn = XTB_HANDLED;
|
||
}
|
||
}
|
||
else {
|
||
/* Bad title size */
|
||
do_error("Bad title font size\n");
|
||
rtn = XTB_HANDLED;
|
||
}
|
||
}
|
||
else {
|
||
/* Bad max dimension */
|
||
do_error("Bad maximum dimension\n");
|
||
rtn = XTB_HANDLED;
|
||
}
|
||
}
|
||
else {
|
||
/* Bad device spec */
|
||
do_error("Must specify `To File' or `To Device'\n");
|
||
rtn = XTB_HANDLED;
|
||
}
|
||
}
|
||
else {
|
||
/* Bad value spec */
|
||
do_error("Must specify an output device\n");
|
||
rtn = XTB_HANDLED;
|
||
}
|
||
(void) xtb_bt_set(win, 0, (xtb_data) 0, 0);
|
||
return rtn;
|
||
}
|
||
|
||
/*ARGSUSED*/
|
||
static xtb_hret
|
||
can_fun(win, val, info)
|
||
Window win; /* Button window */
|
||
int val; /* Button value */
|
||
xtb_data info; /* Local button info */
|
||
|
||
/*
|
||
* This is the handler function for the cancel button. It
|
||
* turns itself on and off and then exits with a status
|
||
* which kills the dialog.
|
||
*/
|
||
{
|
||
(void) xtb_bt_set(win, 1, (xtb_data) 0, 0);
|
||
(void) xtb_bt_set(win, 0, (xtb_data) 0, 0);
|
||
return XTB_STOP;
|
||
}
|
||
|
||
|
||
/*ARGSUSED*/
|
||
static xtb_hret
|
||
docu_fun(win, val, info)
|
||
Window win; /* Button window */
|
||
int val; /* Button value */
|
||
xtb_data info; /* Local button info */
|
||
|
||
/*
|
||
* This is the handler function for the document button. It
|
||
* toggles it's state.
|
||
*/
|
||
{
|
||
int state;
|
||
|
||
state = xtb_bt_get(win, (xtb_data *) 0, (int *) 0);
|
||
xtb_bt_set(win, (state == 0), (xtb_data) 0, 0);
|
||
return XTB_HANDLED;
|
||
}
|
||
|
||
/*ARGSUSED*/
|
||
static xtb_hret
|
||
dev_fun(win, old, new, info)
|
||
Window win; /* Button row window */
|
||
int old; /* Previous button */
|
||
int new; /* Current button */
|
||
xtb_data info; /* User data */
|
||
|
||
/*
|
||
* This routine swaps the device specific information
|
||
* in the dialog based on what device is selected. The
|
||
* information passed is the information for the whole
|
||
* dialog.
|
||
*/
|
||
{
|
||
struct d_info *data = (struct d_info *) info;
|
||
char text[MAXCHBUF];
|
||
int fod_spot,
|
||
inactive;
|
||
|
||
fod_spot = xtb_br_get(data->fod);
|
||
if ((old >= 0) && (old < hard_count)) {
|
||
/* Save old info */
|
||
xtb_ti_get(data->fodspec, text, (xtb_data *) 0);
|
||
if (fod_spot == 1) {
|
||
strncpy(hard_devices[old].dev_file, text, MFNAME - 1);
|
||
}
|
||
else if (fod_spot == 0) {
|
||
strncpy(hard_devices[old].dev_printer, text, MFNAME - 1);
|
||
}
|
||
if (xtb_bt_get(data->docu_p, (xtb_data *) 0, &inactive)) {
|
||
if (inactive)
|
||
hard_devices[old].dev_docu = NONE;
|
||
else
|
||
hard_devices[old].dev_docu = YES;
|
||
}
|
||
else if (inactive)
|
||
hard_devices[old].dev_docu = NONE;
|
||
else
|
||
hard_devices[old].dev_docu = NO;
|
||
xtb_ti_get(data->dimspec, text, (xtb_data *) 0);
|
||
if (sscanf(text, "%lf", &hard_devices[old].dev_max_dim) != 1) {
|
||
do_error("Warning: can't read maximum dimension");
|
||
}
|
||
xtb_ti_get(data->tf_family, text, (xtb_data *) 0);
|
||
strncpy(hard_devices[old].dev_title_font, text, MFNAME - 1);
|
||
xtb_ti_get(data->tf_size, text, (xtb_data *) 0);
|
||
if (sscanf(text, "%lf", &hard_devices[old].dev_title_size) != 1) {
|
||
do_error("Warning: can't read title font size");
|
||
}
|
||
xtb_ti_get(data->af_family, text, (xtb_data *) 0);
|
||
strncpy(hard_devices[old].dev_axis_font, text, MFNAME - 1);
|
||
xtb_ti_get(data->af_size, text, (xtb_data *) 0);
|
||
if (sscanf(text, "%lf", &hard_devices[old].dev_axis_size) != 1) {
|
||
do_error("Warning: can't read axis font size");
|
||
}
|
||
}
|
||
/* Insert new info */
|
||
if ((new >= 0) && (new < hard_count)) {
|
||
if (fod_spot == 1) {
|
||
xtb_ti_set(data->fodspec, hard_devices[new].dev_file, (xtb_data) 0);
|
||
}
|
||
else if (fod_spot == 0) {
|
||
xtb_ti_set(data->fodspec, hard_devices[new].dev_printer,
|
||
(xtb_data) 0);
|
||
}
|
||
else {
|
||
xtb_ti_set(data->fodspec, "", (xtb_data) 0);
|
||
}
|
||
switch (hard_devices[new].dev_docu) {
|
||
case NONE:
|
||
(void) xtb_bt_set(data->docu_p, 0, (xtb_data) 0, 1);
|
||
break;
|
||
case NO:
|
||
(void) xtb_bt_set(data->docu_p, 0, (xtb_data) 0, 0);
|
||
break;
|
||
case YES:
|
||
(void) xtb_bt_set(data->docu_p, 1, (xtb_data) 0, 0);
|
||
break;
|
||
}
|
||
(void) sprintf(text, "%lg", hard_devices[new].dev_max_dim);
|
||
xtb_ti_set(data->dimspec, text, (xtb_data) 0);
|
||
xtb_ti_set(data->tf_family, hard_devices[new].dev_title_font,
|
||
(xtb_data) 0);
|
||
(void) sprintf(text, "%lg", hard_devices[new].dev_title_size);
|
||
xtb_ti_set(data->tf_size, text, (xtb_data) 0);
|
||
xtb_ti_set(data->af_family, hard_devices[new].dev_axis_font,
|
||
(xtb_data) 0);
|
||
(void) sprintf(text, "%lg", hard_devices[new].dev_axis_size);
|
||
xtb_ti_set(data->af_size, text, (xtb_data) 0);
|
||
}
|
||
return XTB_HANDLED;
|
||
}
|
||
|
||
/*ARGSUSED*/
|
||
static xtb_hret
|
||
fd_fun(win, old, new, info)
|
||
Window win; /* Button row window */
|
||
int old; /* Previous button */
|
||
int new; /* Current button */
|
||
xtb_data info; /* User data */
|
||
|
||
/*
|
||
* This routine swaps the default file or device names
|
||
* based on the state of the file or device buttons.
|
||
* The information passed is the information for the whole
|
||
* dialog.
|
||
*/
|
||
{
|
||
struct d_info *data = (struct d_info *) info;
|
||
char text[MAXCHBUF];
|
||
int which_one;
|
||
|
||
which_one = xtb_br_get(data->choices);
|
||
if ((which_one >= 0) && (which_one < hard_count)) {
|
||
if (old == 0) {
|
||
/* Save into device space */
|
||
xtb_ti_get(data->fodspec, text, (xtb_data *) 0);
|
||
strncpy(hard_devices[which_one].dev_printer, text, MFNAME - 1);
|
||
}
|
||
else if (old == 1) {
|
||
/* Save into file space */
|
||
xtb_ti_get(data->fodspec, text, (xtb_data *) 0);
|
||
which_one = xtb_br_get(data->choices);
|
||
strncpy(hard_devices[which_one].dev_file, text, MFNAME - 1);
|
||
}
|
||
if (new == 0) {
|
||
/* Restore into device */
|
||
xtb_ti_set(data->fodspec, hard_devices[which_one].dev_printer,
|
||
(xtb_data *) 0);
|
||
}
|
||
else if (new == 1) {
|
||
xtb_ti_set(data->fodspec, hard_devices[which_one].dev_file,
|
||
(xtb_data *) 0);
|
||
}
|
||
}
|
||
return XTB_HANDLED;
|
||
}
|
||
|
||
|
||
/* Indices for frames made in make_dialog */
|
||
enum d_frames_defn {
|
||
TITLE_F, ODEVLBL_F, ODEVROW_F, DISPLBL_F, DISPROW_F, FDLBL_F,
|
||
FDINP_F, OPTLBL_F, DOCU_F, MDIMLBL_F, MDIMI_F, TFLBL_F, TFFAMLBL_F, TFFAM_F,
|
||
TFSIZLBL_F, TFSIZ_F, AFLBL_F, AFFAMLBL_F, AFFAM_F, AFSIZLBL_F, AFSIZ_F,
|
||
OK_F, CAN_F, BAR_F, LAST_F
|
||
} d_frames;
|
||
|
||
#define AF(ix) af[(int) (ix)]
|
||
|
||
#define BAR_SLACK 10
|
||
|
||
static void
|
||
make_dialog(win, spawned, prog, cookie, okbtn, frame)
|
||
Window win; /* Parent window */
|
||
Window spawned; /* Spawned from window */
|
||
char *prog; /* Program name */
|
||
xtb_data cookie; /* Info for do_hardcopy */
|
||
xtb_frame *okbtn; /* Frame for OK button */
|
||
xtb_frame *frame; /* Returned window/size */
|
||
|
||
/*
|
||
* This routine constructs a new dialog for asking the user about
|
||
* hardcopy devices. The dialog and its size is returned in
|
||
* `frame'. The window of the `ok' button is returned in `btnwin'.
|
||
* This can be used to reset some of the button state to reuse the dialog.
|
||
*/
|
||
{
|
||
Window overall;
|
||
xtb_frame AF(LAST_F);
|
||
xtb_fmt *def,
|
||
*cntrl,
|
||
*mindim,
|
||
*tfarea,
|
||
*afarea;
|
||
Cursor diag_cursor;
|
||
XColor fg_color,
|
||
bg_color;
|
||
XSizeHints hints;
|
||
unsigned long wamask;
|
||
XSetWindowAttributes wattr;
|
||
struct d_info *info;
|
||
int i,
|
||
found,
|
||
max_width,
|
||
which_one,
|
||
fodi;
|
||
char **names;
|
||
static char *fodstrs[] =
|
||
{"To Device", "To File"};
|
||
XFontStruct *bigFont = PM_FONT("TitleFont");
|
||
XFontStruct *medFont = PM_FONT("LabelFont");
|
||
char *Odevice = PM_STR("Device");
|
||
char *Odisp = PM_STR("Disposition");
|
||
char *OfileDev = PM_STR("FileOrDev");
|
||
|
||
wamask = CWBackPixel | CWBorderPixel | CWOverrideRedirect |
|
||
CWSaveUnder | CWColormap;
|
||
wattr.background_pixel = PM_PIXEL("Background");
|
||
wattr.border_pixel = PM_PIXEL("Border");
|
||
wattr.override_redirect = True;
|
||
wattr.save_under = True;
|
||
wattr.colormap = cmap;
|
||
overall = XCreateWindow(disp, win, 0, 0, 1, 1, D_BRDR,
|
||
depth, InputOutput, vis,
|
||
wamask, &wattr);
|
||
frame->win = overall;
|
||
frame->width = frame->height = frame->x_loc = frame->y_loc = 0;
|
||
XStoreName(disp, overall, "Hardcopy Dialog");
|
||
XSetTransientForHint(disp, spawned, overall);
|
||
info = (struct d_info *) Malloc(sizeof(struct d_info));
|
||
info->prog = prog;
|
||
info->cookie = cookie;
|
||
|
||
/* Make all frames */
|
||
xtb_to_new(overall, "Hardcopy Options", bigFont, &AF(TITLE_F));
|
||
xtb_to_new(overall, "Output device:", medFont, &AF(ODEVLBL_F));
|
||
found = -1;
|
||
names = (char **) Malloc((unsigned) (sizeof(char *) * hard_count));
|
||
for (i = 0; i < hard_count; i++) {
|
||
names[i] = hard_devices[i].dev_name;
|
||
if (strcmp(Odevice, names[i]) == 0) {
|
||
found = i;
|
||
}
|
||
}
|
||
xtb_br_new(overall, hard_count, names, found,
|
||
dev_fun, (xtb_data) info, &AF(ODEVROW_F));
|
||
info->choices = AF(ODEVROW_F).win;
|
||
xtb_to_new(overall, "Disposition:", medFont, &AF(DISPLBL_F));
|
||
found = -1;
|
||
for (i = 0; i < 2; i++) {
|
||
if (strcmp(Odisp, fodstrs[i]) == 0) {
|
||
found = i;
|
||
}
|
||
}
|
||
xtb_br_new(overall, 2, fodstrs, found,
|
||
fd_fun, (xtb_data) info, &AF(DISPROW_F));
|
||
info->fod = AF(DISPROW_F).win;
|
||
xtb_to_new(overall, "File or Device Name:", medFont, &AF(FDLBL_F));
|
||
xtb_ti_new(overall, "", D_INP, df_fun, (xtb_data) 0, &AF(FDINP_F));
|
||
if (OfileDev && strlen(OfileDev)) {
|
||
which_one = xtb_br_get(info->choices);
|
||
if ((which_one >= 0) && (which_one < hard_count)) {
|
||
fodi = xtb_br_get(info->fod);
|
||
if (fodi == 0) {
|
||
strncpy(hard_devices[which_one].dev_printer, OfileDev, MFNAME - 1);
|
||
}
|
||
else if (fodi == 1) {
|
||
strncpy(hard_devices[which_one].dev_file, OfileDev, MFNAME - 1);
|
||
}
|
||
}
|
||
}
|
||
info->fodspec = AF(FDINP_F).win;
|
||
xtb_to_new(overall, "Optional Parameters", bigFont, &AF(OPTLBL_F));
|
||
xtb_bt_new(overall, "Include in Document", docu_fun, (xtb_data) 0, &AF(DOCU_F));
|
||
info->docu_p = AF(DOCU_F).win;
|
||
xtb_to_new(overall, "Maximum Dimension (cm):", medFont, &AF(MDIMLBL_F));
|
||
xtb_ti_new(overall, "", D_DSP, df_fun, (xtb_data) 0, &AF(MDIMI_F));
|
||
info->dimspec = AF(MDIMI_F).win;
|
||
xtb_to_new(overall, "Title Font", medFont, &AF(TFLBL_F));
|
||
xtb_to_new(overall, "Family:", medFont, &AF(TFFAMLBL_F));
|
||
xtb_ti_new(overall, "", MFNAME, df_fun, (xtb_data) 0, &AF(TFFAM_F));
|
||
info->tf_family = AF(TFFAM_F).win;
|
||
xtb_to_new(overall, "Size (pnts):", medFont, &AF(TFSIZLBL_F));
|
||
xtb_ti_new(overall, "", D_FS, df_fun, (xtb_data) 0, &AF(TFSIZ_F));
|
||
info->tf_size = AF(TFSIZ_F).win;
|
||
xtb_to_new(overall, "Axis Font", medFont, &AF(AFLBL_F));
|
||
xtb_to_new(overall, "Family:", medFont, &AF(AFFAMLBL_F));
|
||
xtb_ti_new(overall, "", MFNAME, df_fun, (xtb_data) 0, &AF(AFFAM_F));
|
||
info->af_family = AF(AFFAM_F).win;
|
||
xtb_to_new(overall, "Size (pnts):", medFont, &AF(AFSIZLBL_F));
|
||
xtb_ti_new(overall, "", D_FS, df_fun, (xtb_data) 0, &AF(AFSIZ_F));
|
||
info->af_size = AF(AFSIZ_F).win;
|
||
xtb_bt_new(overall, " Ok ", ok_fun, (xtb_data) info, &AF(OK_F));
|
||
xtb_bt_new(overall, "Cancel", can_fun, (xtb_data) 0, &AF(CAN_F));
|
||
/* Dividing bar */
|
||
max_width = 0;
|
||
for (i = 0; i < ((int) BAR_F); i++) {
|
||
if (AF(i).width > max_width)
|
||
max_width = AF(i).width;
|
||
}
|
||
xtb_bk_new(overall, max_width - BAR_SLACK, 1, &AF(BAR_F));
|
||
|
||
/* Set device specific info */
|
||
(void) dev_fun(info->choices, -1, xtb_br_get(info->choices), (xtb_data) info);
|
||
(void) fd_fun(info->fod, -1, xtb_br_get(info->fod), (xtb_data) info);
|
||
|
||
/*
|
||
* Now place elements - could make this one expression but pcc is too
|
||
* wimpy.
|
||
*/
|
||
cntrl = xtb_vert(XTB_LEFT, D_VPAD, D_INT,
|
||
xtb_hort(XTB_CENTER, D_HPAD, D_INT,
|
||
xtb_w(&AF(ODEVLBL_F)),
|
||
xtb_w(&AF(ODEVROW_F)), NE),
|
||
xtb_hort(XTB_CENTER, D_HPAD, D_INT,
|
||
xtb_w(&AF(DISPLBL_F)),
|
||
xtb_w(&AF(DISPROW_F)), NE),
|
||
xtb_hort(XTB_CENTER, D_HPAD, D_INT,
|
||
xtb_w(&AF(FDLBL_F)),
|
||
xtb_w(&AF(FDINP_F)), NE),
|
||
NE);
|
||
|
||
mindim = xtb_vert(XTB_LEFT, D_VPAD, D_INT,
|
||
xtb_hort(XTB_CENTER, D_HPAD, D_INT,
|
||
xtb_w(&AF(MDIMLBL_F)),
|
||
xtb_w(&AF(MDIMI_F)),
|
||
NE),
|
||
NE);
|
||
|
||
tfarea = xtb_vert(XTB_LEFT, D_VPAD, D_INT,
|
||
xtb_hort(XTB_CENTER, D_HPAD, D_INT,
|
||
xtb_w(&AF(TFFAMLBL_F)),
|
||
xtb_w(&AF(TFFAM_F)),
|
||
xtb_w(&AF(TFSIZLBL_F)),
|
||
xtb_w(&AF(TFSIZ_F)), NE),
|
||
NE);
|
||
|
||
afarea = xtb_vert(XTB_LEFT, D_VPAD, D_INT,
|
||
xtb_hort(XTB_CENTER, D_HPAD, D_INT,
|
||
xtb_w(&AF(AFFAMLBL_F)),
|
||
xtb_w(&AF(AFFAM_F)),
|
||
xtb_w(&AF(AFSIZLBL_F)),
|
||
xtb_w(&AF(AFSIZ_F)), NE),
|
||
NE);
|
||
|
||
def = xtb_fmt_do
|
||
(xtb_vert(XTB_CENTER, D_VPAD, D_INT,
|
||
xtb_w(&AF(TITLE_F)),
|
||
cntrl,
|
||
xtb_w(&AF(BAR_F)),
|
||
xtb_w(&AF(OPTLBL_F)),
|
||
mindim,
|
||
xtb_w(&AF(DOCU_F)),
|
||
xtb_w(&AF(TFLBL_F)),
|
||
tfarea,
|
||
xtb_w(&AF(AFLBL_F)),
|
||
afarea,
|
||
xtb_hort(XTB_CENTER, D_HPAD, D_INT,
|
||
xtb_w(&AF(OK_F)), xtb_w(&AF(CAN_F)), NE),
|
||
NE),
|
||
&frame->width, &frame->height);
|
||
xtb_mv_frames(LAST_F, af);
|
||
xtb_fmt_free(def);
|
||
|
||
/* Make window large enough to contain the info */
|
||
XResizeWindow(disp, overall, frame->width, frame->height);
|
||
hints.flags = PSize;
|
||
hints.width = frame->width;
|
||
hints.height = frame->height;
|
||
XSetNormalHints(disp, overall, &hints);
|
||
diag_cursor = XCreateFontCursor(disp, XC_dotbox);
|
||
fg_color.pixel = PM_PIXEL("Foreground");
|
||
XQueryColor(disp, cmap, &fg_color);
|
||
bg_color.pixel = PM_PIXEL("Background");
|
||
XQueryColor(disp, cmap, &bg_color);
|
||
XRecolorCursor(disp, diag_cursor, &fg_color, &bg_color);
|
||
XDefineCursor(disp, overall, diag_cursor);
|
||
frame->width += (2 * D_BRDR);
|
||
frame->height += (2 * D_BRDR);
|
||
*okbtn = AF(OK_F);
|
||
}
|
||
|
||
|
||
|
||
#ifdef SHADOW
|
||
Window
|
||
make_shadow(w, h)
|
||
int w,
|
||
h;
|
||
|
||
/*
|
||
* Makes a shadow window for a pop-up window of the specified size.
|
||
* Needs hint work as well. Try no background window.
|
||
*/
|
||
{
|
||
Window shadow;
|
||
Bitmap gray_bm;
|
||
Pixmap gray_pm;
|
||
|
||
gray_bm = XStoreBitmap(gray_width, gray_height, gray_bits);
|
||
gray_pm = XMakePixmap(gray_bm, PM_PIXEL("Foreground"), PM_PIXEL("Background"));
|
||
shadow = XCreateWindow(RootWindow, 0, 0, w, h, 0, BlackPixmap, gray_pm);
|
||
XFreePixmap(gray_pm);
|
||
XFreeBitmap(gray_bm);
|
||
return shadow;
|
||
}
|
||
|
||
#endif
|
||
|
||
|
||
|
||
#define SH_W 5
|
||
#define SH_H 5
|
||
|
||
void
|
||
ho_dialog(parent, prog, cookie)
|
||
Window parent; /* Parent window */
|
||
char *prog; /* Program name */
|
||
xtb_data cookie; /* Info passed to do_hardcopy */
|
||
|
||
/*
|
||
* Asks the user about hardcopy devices. A table of hardcopy
|
||
* device names and function pointers to their initialization
|
||
* functions is assumed to be in the global `hard_devices' and
|
||
* `hard_count'. Returns a non-zero status if the dialog was
|
||
* sucessfully posted. Calls do_hardcopy in xgraph to actually
|
||
* output information.
|
||
*/
|
||
{
|
||
#ifdef SHADOW
|
||
static Window shadow;
|
||
|
||
#endif
|
||
static Window dummy;
|
||
static xtb_frame overall =
|
||
{(Window) 0, 0, 0, 0, 0};
|
||
static xtb_frame okbtn;
|
||
XEvent evt;
|
||
XWindowAttributes winInfo;
|
||
XSizeHints hints;
|
||
struct d_info *info;
|
||
|
||
if (!overall.win) {
|
||
make_dialog(RootWindow(disp, screen), parent, prog, cookie,
|
||
&okbtn, &overall);
|
||
#ifdef SHADOW
|
||
shadow = make_shadow(d_w, d_h);
|
||
#endif
|
||
}
|
||
else {
|
||
/* Change the button information */
|
||
(void) xtb_bt_get(okbtn.win, (xtb_data *) & info, (int *) 0);
|
||
info->prog = prog;
|
||
info->cookie = cookie;
|
||
}
|
||
XGetWindowAttributes(disp, parent, &winInfo);
|
||
XTranslateCoordinates(disp, parent, RootWindow(disp, screen),
|
||
0, 0, &winInfo.x, &winInfo.y, &dummy);
|
||
XMoveWindow(disp, overall.win,
|
||
(int) (winInfo.x + winInfo.width / 2 - overall.width / 2),
|
||
(int) (winInfo.y + winInfo.height / 2 - overall.height / 2));
|
||
hints.flags = PPosition;
|
||
hints.x = winInfo.x + winInfo.width / 2 - overall.width / 2;
|
||
hints.y = winInfo.y + winInfo.height / 2 - overall.height / 2;
|
||
XSetNormalHints(disp, overall.win, &hints);
|
||
#ifdef SHADOW
|
||
XMoveWindow(disp, shadow, winInfo.x + winInfo.width / 2 - d_w / 2 + SH_W,
|
||
winInfo.y + winInfo.height / 2 - d_h / 2 + SH_H);
|
||
hints.flags = PPosition;
|
||
hints.x = winInfo.x + winInfo.width / 2 - d_w / 2 + SH_W;
|
||
hints.y = winInfo.y + winInfo.height / 2 - d_h / 2 + SH_H;
|
||
XSetNormalHints(disp, shadow, &hints);
|
||
XRaiseWindow(disp, shadow);
|
||
XMapWindow(disp, shadow);
|
||
#endif
|
||
XRaiseWindow(disp, overall.win);
|
||
XMapWindow(disp, overall.win);
|
||
do {
|
||
XNextEvent(disp, &evt);
|
||
} while (xtb_dispatch(&evt) != XTB_STOP);
|
||
XUnmapWindow(disp, overall.win);
|
||
#ifdef SHADOW
|
||
XUnmapWindow(disp, shadow);
|
||
#endif
|
||
}
|
||
|
||
|
||
|
||
/*ARGSUSED*/
|
||
static xtb_hret
|
||
err_func(win, bval, info)
|
||
Window win; /* Button window */
|
||
int bval; /* Button value */
|
||
xtb_data info; /* Local button info */
|
||
|
||
/*
|
||
* Handler function for button in error box. Simply stops dialog.
|
||
*/
|
||
{
|
||
(void) xtb_bt_set(win, 1, (xtb_data) 0, 0);
|
||
(void) xtb_bt_set(win, 0, (xtb_data) 0, 0);
|
||
return XTB_STOP;
|
||
}
|
||
|
||
|
||
struct err_info {
|
||
Window title;
|
||
Window contbtn;
|
||
int num_lines;
|
||
int alloc_lines;
|
||
Window *lines;
|
||
};
|
||
|
||
#define E_LINES 2
|
||
#define E_VPAD 3
|
||
#define E_HPAD 3
|
||
#define E_INTER 1
|
||
#define ML 256
|
||
|
||
static void
|
||
make_msg_box(text, title, frame)
|
||
char *text; /* Error text */
|
||
char *title; /* Title text */
|
||
xtb_frame *frame; /* Returned frame */
|
||
|
||
/*
|
||
* Makes an error box with a title.
|
||
*/
|
||
{
|
||
XSizeHints hints;
|
||
struct err_info *new_info;
|
||
xtb_frame tf,
|
||
cf,
|
||
lf;
|
||
char *lineptr,
|
||
line[ML];
|
||
int y,
|
||
i;
|
||
unsigned long wamask;
|
||
XSetWindowAttributes wattr;
|
||
XFontStruct *bigFont = PM_FONT("TitleFont");
|
||
XFontStruct *medFont = PM_FONT("LabelFont");
|
||
|
||
wamask = CWBackPixel | CWBorderPixel | CWOverrideRedirect |
|
||
CWSaveUnder | CWColormap;
|
||
wattr.background_pixel = PM_PIXEL("Background");
|
||
wattr.border_pixel = PM_PIXEL("Border");
|
||
wattr.override_redirect = True;
|
||
wattr.save_under = True;
|
||
wattr.colormap = cmap;
|
||
frame->win = XCreateWindow(disp, RootWindow(disp, screen),
|
||
0, 0, 1, 1, D_BRDR,
|
||
depth, InputOutput, vis,
|
||
wamask, &wattr);
|
||
frame->x_loc = frame->y_loc = frame->width = frame->height = 0;
|
||
XStoreName(disp, frame->win, "Error Dialog");
|
||
XSetTransientForHint(disp, RootWindow(disp, screen), frame->win);
|
||
new_info = (struct err_info *) Malloc((unsigned) sizeof(struct err_info));
|
||
xtb_to_new(frame->win, title, bigFont, &tf);
|
||
new_info->title = tf.win;
|
||
if (tf.width > frame->width)
|
||
frame->width = tf.width;
|
||
|
||
xtb_bt_new(frame->win, "Dismiss", err_func, (xtb_data) 0, &cf);
|
||
new_info->contbtn = cf.win;
|
||
if (cf.width > frame->width)
|
||
frame->width = cf.width;
|
||
|
||
new_info->alloc_lines = E_LINES;
|
||
new_info->num_lines = 0;
|
||
new_info->lines = (Window *) Malloc((unsigned) (sizeof(Window) * E_LINES));
|
||
/* zero the memory out of paranoia */
|
||
memset(new_info->lines, 0, sizeof(Window) * E_LINES);
|
||
|
||
lineptr = text;
|
||
while (getline_xgraph(&lineptr, line)) {
|
||
if (new_info->num_lines >= new_info->alloc_lines) {
|
||
int old_alloc_lines_size = new_info->alloc_lines * sizeof(Window);
|
||
new_info->alloc_lines *= 2;
|
||
new_info->lines = (Window *) Realloc((char *) new_info->lines,
|
||
(unsigned)
|
||
(new_info->alloc_lines *
|
||
sizeof(Window)));
|
||
memset(((char*)new_info->lines) + old_alloc_lines_size,
|
||
0, old_alloc_lines_size);
|
||
}
|
||
xtb_to_new(frame->win, line, medFont, &lf);
|
||
new_info->lines[new_info->num_lines] = lf.win;
|
||
new_info->num_lines += 1;
|
||
if (lf.width > frame->width)
|
||
frame->width = lf.width;
|
||
}
|
||
|
||
|
||
/* Placement */
|
||
frame->width += (2 * E_HPAD);
|
||
y = E_VPAD;
|
||
/* Title */
|
||
XMoveWindow(disp, new_info->title, (int) (frame->width / 2 - tf.width / 2), y);
|
||
y += (tf.height + E_INTER);
|
||
/* All lines */
|
||
for (i = 0; i < new_info->num_lines; i++) {
|
||
XMoveWindow(disp, new_info->lines[i], E_HPAD, y);
|
||
y += (lf.height + E_INTER);
|
||
}
|
||
/* Button */
|
||
XMoveWindow(disp, new_info->contbtn, (int) (frame->width / 2 - cf.width / 2), y);
|
||
y += (cf.height + E_INTER);
|
||
|
||
/* Make dialog the right size */
|
||
y += (E_VPAD - E_INTER);
|
||
XResizeWindow(disp, frame->win, frame->width, (unsigned int) y);
|
||
hints.flags = PSize;
|
||
hints.width = frame->width;
|
||
hints.height = (unsigned int) y;
|
||
XSetNormalHints(disp, frame->win, &hints);
|
||
frame->width += (2 * D_BRDR);
|
||
frame->height = y + (2 * D_BRDR);
|
||
xtb_register(frame->win, (xtb_hret(*) ()) 0, (xtb_data) new_info);
|
||
}
|
||
|
||
void
|
||
msg_box(title, text)
|
||
char *title,
|
||
*text;
|
||
|
||
/*
|
||
* This posts a dialog that contains lines of text and a continue
|
||
* button. The text may be multiple lines. The dialog is remade
|
||
* each time.
|
||
*/
|
||
{
|
||
#ifdef SHADOW
|
||
Window shadow;
|
||
|
||
#endif
|
||
XWindowAttributes info;
|
||
XEvent evt;
|
||
XSizeHints hints;
|
||
xtb_frame text_frame;
|
||
|
||
make_msg_box(text, title, &text_frame);
|
||
#ifdef SHADOW
|
||
shadow = make_shadow(w, h);
|
||
#endif
|
||
XGetWindowAttributes(disp, RootWindow(disp, screen), &info);
|
||
XMoveWindow(disp, text_frame.win, (int) (info.width / 2 - text_frame.width / 2),
|
||
(int) (info.height / 2 - text_frame.height / 2));
|
||
hints.flags = PPosition;
|
||
hints.x = info.width / 2 - text_frame.width / 2;
|
||
hints.y = info.height / 2 - text_frame.height / 2;
|
||
XSetNormalHints(disp, text_frame.win, &hints);
|
||
#ifdef SHADOW
|
||
XMoveWindow(disp, shadow, info.width / 2 - w / 2 + SH_W,
|
||
info.height / 2 - h / 2 + SH_H);
|
||
hints.flags = PPosition;
|
||
hints.x = info.width / 2 - w / 2 + SH_W;
|
||
hints.y = info.height / 2 - h / 2 + SH_H;
|
||
XSetNormalHints(disp, text_frame.win, &hints);
|
||
XRaiseWindow(disp, shadow);
|
||
XMapWindow(disp, shadow);
|
||
#endif
|
||
XRaiseWindow(disp, text_frame.win);
|
||
XMapWindow(disp, text_frame.win);
|
||
do {
|
||
XNextEvent(disp, &evt);
|
||
} while (xtb_dispatch(&evt) != XTB_STOP);
|
||
#ifdef SHADOW
|
||
XDestroyWindow(disp, shadow);
|
||
#endif
|
||
del_msg_box(text_frame.win);
|
||
}
|
||
|
||
void
|
||
do_error(err_text)
|
||
char *err_text;
|
||
{
|
||
if (PM_INT("Output Device") == D_XWINDOWS)
|
||
msg_box("Xgraph Error", err_text);
|
||
else
|
||
fputs(err_text, stderr);
|
||
}
|
||
|
||
|
||
|
||
static int
|
||
getline_xgraph(tptr, lptr)
|
||
char **tptr;
|
||
char *lptr;
|
||
|
||
/*
|
||
* Returns next line from tptr. Assumes `lptr' is large enough to
|
||
* accept the line.
|
||
*/
|
||
{
|
||
char *start;
|
||
|
||
start = *tptr;
|
||
while (*tptr && **tptr && (**tptr != '\n')) {
|
||
(*tptr)++;
|
||
}
|
||
if (*tptr > start) {
|
||
(void) strncpy(lptr, start, (*tptr - start));
|
||
lptr[*tptr - start] = '\0';
|
||
if (**tptr == '\n')
|
||
(*tptr)++;
|
||
return 1;
|
||
}
|
||
else {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
static void
|
||
del_msg_box(msg)
|
||
Window msg;
|
||
|
||
/*
|
||
* Deletes all components of an msg box
|
||
*/
|
||
{
|
||
struct err_info *info;
|
||
char *dummy;
|
||
int i;
|
||
|
||
if (xtb_unregister(msg, (xtb_data *) & info)) {
|
||
xtb_to_del(info->title);
|
||
xtb_bt_del(info->contbtn, (xtb_data *) & dummy);
|
||
for (i = 0; i < info->num_lines; i++) {
|
||
xtb_to_del(info->lines[i]);
|
||
}
|
||
Free((char *) info->lines);
|
||
Free((char *) info);
|
||
XDestroyWindow(disp, msg);
|
||
}
|
||
}
|