envbvs@epb2.lbl.gov (Brian V. Smith) (07/04/90)
Submitted-by: envbvs@epb2.lbl.gov (Brian V. Smith) Posting-number: Volume 8, Issue 27 Archive-name: xfig2.8/part18 #! /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 18 (of 21)." # Contents: change.c # Wrapped by envbvs@epb2.lbl.gov on Thu Jun 28 08:53:23 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'change.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'change.c'\" else echo shar: Extracting \"'change.c'\" \(39119 characters\) sed "s/^X//" >'change.c' <<'END_OF_FILE' X/* X * FIG : Facility for Interactive Generation of figures X * X * Created March 1990 by Jon Tombs <jon@uk.ac.oxford.robots> X * This is my first X program please excuse the style, probably X * only works with X11R4 X * Last Update 1st April 1989 X * X * %W% %G% X * X * Based on the file of the same name from the fig-fs distribution: X * X * Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU) X * January 1985. X * 1st revision : Aug 1985. X * X * Change function implemented by Frank Schmuck (schmuck@svax.cs.cornell.edu) X * July 1988. X*/ X X#include "fig.h" X#include "resources.h" X#include "func.h" X#include "object.h" X#include "paintop.h" X#include "font.h" X#include "psfonts.h" X X#define TOLERANCE 7 X#define min(a, b) (((a) < (b)) ? (a) : (b)) X#define max(a, b) (((a) > (b)) ? (a) : (b)) X Xextern char *panel_get_value(); Xextern Widget make_popup_menu(); Xextern void toggle(); X Xextern (*canvas_kbd_proc)(); Xextern (*canvas_locmove_proc)(); Xextern (*canvas_leftbut_proc)(); Xextern (*canvas_middlebut_proc)(); Xextern (*canvas_rightbut_proc)(); Xextern (*return_proc)(); Xextern null_proc(); Xextern set_popupmenu(); X Xextern F_text *text_search(); X Xextern int foreground_color, background_color; Xextern Pixmap font_menu_bitmaps[]; Xextern int *font_sel; /* pointer to store font selected from popup */ Xextern Widget image_widget; /* which widget to store image of font in */ Xextern Window canvas_win; X Xextern change_text(); Xextern change_item(); Xextern change_depth_up(); Xextern change_depth_down(); Xextern void Quit(); Xstatic void new_generic_values(); Xstatic generic_window(); Xstatic font_image_panel(); Xstatic int_panel(); Xstatic str_panel(); Xstatic toggle_panel(); Xstatic xy_panel(); Xstatic f_pos_panel(); Xstatic get_f_pos(); Xstatic points_panel(); Xstatic get_points(); Xstatic void line_style_select(); Xstatic void text_adjust_select(); Xstatic Widget popup, form; Xstatic Widget below, beside; X Xextern F_line *line_search(), *copy_line(); Xextern F_arc *arc_search(), *copy_arc(); Xextern F_ellipse *ellipse_search(), *copy_ellipse(); Xextern F_text *text_search(), *copy_text(); Xextern F_spline *spline_search(), *copy_spline(); Xextern F_compound *compound_search(); Xextern F_arrow *forward_arrow(), *backward_arrow(); Xextern F_compound objects; X X#define NUM_IMAGES 15 Xextern PIXRECT cirrad_ic, cirdia_ic, ellrad_ic, elldia_ic, X c_spl_ic, spl_ic, c_intspl_ic, intspl_ic, X line_ic, polygon_ic, box_ic, arc_box_ic, X arc_ic, text_ic, blank_ic; X Xextern int SIDERULER_WIDTH, PANL_WID; Xextern int RHS_PANL; Xextern float cur_dashlength; Xextern float cur_dotgap; X X/* not use init_change();*/ Xstatic int done_compound(); Xstatic int done_line(); Xstatic int done_text(); Xstatic int done_arc(); Xstatic int done_ellipse(); Xstatic int done_spline(); X Xstatic F_line *new_line; Xstatic F_ellipse *new_ellipse; Xstatic F_text *new_text; Xstatic F_spline *new_spline; Xstatic F_arc *new_arc; Xstatic F_compound *new_compound; X Xstatic Widget label; Xstatic Widget thickness_panel; Xstatic Widget color_panel; Xstatic Widget depth_panel; Xstatic Widget angle_panel; Xstatic Widget adjust_panel; Xstatic Widget area_fill_panel; Xstatic Widget fill_pct_label; Xstatic Widget style_panel; Xstatic Widget style_val_panel; Xstatic Widget for_arrow_panel; Xstatic Widget back_arrow_panel; Xstatic Widget text_panel; Xstatic Widget x1_panel, y1_panel; Xstatic Widget x2_panel, y2_panel; Xstatic Widget x3_panel, y3_panel; Xstatic Widget font_panel; Xstatic Widget font_size_panel; Xstatic Widget filled_panel; Xstatic Widget radius; Xstatic Widget entry, menu, adjust_menu; Xstatic Widget but1; X XArg args[12]; X X X#define MAX_POINTS 100 Xstatic Widget px_panel[MAX_POINTS]; Xstatic Widget py_panel[MAX_POINTS]; X Xstatic int ellipse_flag; Xstatic int no_fill_flag; Xstatic int (*done_proc)(); Xstatic int button_result; Xstatic int text_adjust; Xstatic int new_font; X#define CANCEL 0 X#define DONE 1 X#define APPLY 2 X Xstatic struct { X int thickness; X int color; X int depth; X int style; X float style_val; X int pen; X int area_fill; X int for_arrow; X int back_arrow; X} generic_vals; X X#define put_generic_vals(x) \ X generic_vals.thickness = x->thickness; \ X generic_vals.color = x->color; \ X generic_vals.depth = x->depth; \ X generic_vals.style = x->style; \ X generic_vals.style_val = x->style_val; \ X generic_vals.pen = x->pen; \ X generic_vals.area_fill = x->area_fill X X#define get_generic_vals(x) \ X new_generic_values(NULL, NULL); \ X x->thickness = generic_vals.thickness; \ X x->color = generic_vals.color; \ X x->depth = generic_vals.depth; \ X x->style = generic_vals.style; \ X x->style_val = generic_vals.style_val; \ X x->pen = generic_vals.pen; \ X x->area_fill = generic_vals.area_fill X X#define put_generic_arrows(x) \ X generic_vals.for_arrow = (x->for_arrow != NULL); \ X generic_vals.back_arrow = (x->back_arrow != NULL) X X#define get_generic_arrows(x) \ X if (x->for_arrow) \ X free((char*)x->for_arrow); \ X if (x->back_arrow) \ X free((char*)x->back_arrow); \ X x->for_arrow = (generic_vals.for_arrow)? forward_arrow(): NULL; \ X x->back_arrow = (generic_vals.back_arrow)? backward_arrow(): NULL X X Xchange_item_selected() X{ X canvas_kbd_proc = null_proc; X canvas_locmove_proc = null_proc; X canvas_leftbut_proc = change_item; X canvas_middlebut_proc = null_proc; X canvas_rightbut_proc = set_popupmenu; X return_proc = change_item_selected; X set_cursor(&pick9_cursor); X reset_action_on(); X} X X Xchange_item(x, y) Xint x, y; X{ X extern F_line *line_search(); X extern F_arc *arc_search(); X extern F_ellipse *ellipse_search(); X extern F_text *text_search(); X extern F_spline *spline_search(); X extern F_compound *compound_search(); X F_line *l; X F_arc *a; X F_ellipse *e; X F_text *t; X F_spline *s; X F_compound *c; X int dummy; X X X if ((l = line_search(x, y, TOLERANCE, &dummy, &dummy)) != NULL) { X make_window_line(l); X } X else if ((t = text_search(x, y)) != NULL) { X make_window_text(t); X } X else if ((e = ellipse_search(x, y, TOLERANCE, &dummy, &dummy)) != NULL){ X make_window_ellipse(e); X } X else if ((a = arc_search(x, y, TOLERANCE, &dummy, &dummy)) != NULL){ X make_window_arc(a); X } X else if ((s = spline_search(x, y, TOLERANCE, &dummy, &dummy)) != NULL) { X make_window_spline(s); X } X else if ((c = compound_search(x, y, TOLERANCE, &dummy, &dummy)) != NULL) X make_window_compound(c); X else X return; X X XtPopup(popup, XtGrabExclusive); X} X X Xmake_window_compound(c) XF_compound *c; X{ X generic_window("COMPOUND", "Cannot be changed!", &blank_ic, X done_compound, 0, 0); X } X Xstatic Xdone_compound() X{ X if (button_result != APPLY) { X clean_up(); X show_pointmarker(); X } X } X Xmake_window_line(l) XF_line *l; X{ X struct f_point p1, p2; X X new_line = copy_line(l); X new_line->next = l; X put_generic_vals(new_line); X switch (new_line->type) { X case T_POLYLINE: X put_generic_arrows(new_line); X generic_window("POLYLINE", "Polyline", &line_ic, done_line, 1, 1); X points_panel(new_line->points, 0); X break; X case T_POLYGON: X put_generic_arrows(new_line); X generic_window("POLYLINE", "Polygon", &polygon_ic, done_line, 1, 1); X points_panel(new_line->points, 1); X break; X case T_BOX: X generic_window("POLYLINE", "Box", &box_ic, done_line, 1, 0); X p1 = *new_line->points; X p2 = *new_line->points->next->next; X xy_panel(p1.x, p1.y, "Top Left", &x1_panel, &y1_panel); X xy_panel(p2.x, p2.y, "Bottom Right", &x2_panel, &y2_panel); X break; X case T_ARC_BOX: X generic_window("POLYLINE", "ArcBox", &arc_box_ic, done_line, 1, 0); X p1 = *new_line->points; X p2 = *new_line->points->next->next; X xy_panel(p1.x, p1.y, "Top Left", &x1_panel, &y1_panel); X xy_panel(p2.x, p2.y, "Bottom Right", &x2_panel, &y2_panel); X int_panel(new_line->radius, "Radius:", &radius); X break; X } X } X Xstatic Xget_new_line_values() X{ X struct f_point p1, p2, *p; X X get_generic_vals(new_line); X if ((new_line->type != T_BOX) && (new_line->type != T_ARC_BOX)) { X get_generic_arrows(new_line); X get_points(new_line->points, (new_line->type == T_POLYGON)); X } X else { X p1.x = atoi(panel_get_value(x1_panel)); X p1.y = atoi(panel_get_value(y1_panel)); X p2.x = atoi(panel_get_value(x2_panel)); X p2.y = atoi(panel_get_value(y2_panel)); X p = new_line->points; X p->x = p1.x; p->y = p1.y; p = p->next; X p->x = p2.x; p->y = p1.y; p = p->next; X p->x = p2.x; p->y = p2.y; p = p->next; X p->x = p1.x; p->y = p2.y; p = p->next; X p->x = p1.x; p->y = p1.y; X if (new_line->type == T_ARC_BOX) X new_line->radius = atoi(panel_get_value(radius)); X } X } X Xstatic Xdone_line() X{ X F_line *old_line; X X X draw_line(new_line, ERASE); X old_line = new_line->next; X switch (button_result) { X case APPLY: X get_new_line_values(); X draw_line(new_line, PAINT); X break; X case DONE: X clean_up(); X get_new_line_values(); X set_action_object(F_CHANGE, O_POLYLINE); X new_line->next = NULL; X delete_line(&objects.lines, old_line); X insert_line(&objects.lines, new_line); X set_latestline(old_line); X old_line->next = new_line; X draw_line(new_line, PAINT); X show_pointmarker(); X set_modifiedflag(); X break; X case CANCEL: X clean_up(); X new_line->next = NULL; X free_line(&new_line); X draw_line(old_line, PAINT); X show_pointmarker(); X break; X } X X } X X#define round(x) ((int) ((x) + ((x >= 0)? 0.5: -0.5))) X Xmake_window_text(t) XF_text *t; X{ X PIX_FONT temp_font; X int i,cw; X static char * adjust_item_names[] = { X "Left Justified ", "Centered ", "Right Justified"}; X X new_text = copy_text(t); X new_text->next = t; X generic_window("TEXT", "", &text_ic, done_text, 0, 0); X#ifdef notdef X subtype_panel = panel_create_item(change_panel, PANEL_CYCLE, X PANEL_LABEL_X, ATTR_COL(2), X PANEL_LABEL_Y, ATTR_ROW(2), X PANEL_VALUE_X, ATTR_COL(20), X PANEL_VALUE_Y, ATTR_ROW(2), X PANEL_LABEL_STRING, "Text alignment:", X PANEL_CHOICE_STRINGS, "left justified", "center justified", X "right justified", 0, X PANEL_VALUE, new_text->type, X 0); X font_panel = panel_create_item(change_panel, PANEL_CYCLE, X PANEL_LABEL_X, ATTR_COL(2), X PANEL_LABEL_Y, ATTR_ROW(3), X PANEL_VALUE_X, ATTR_COL(20), X PANEL_VALUE_Y, ATTR_ROW(3), X PANEL_LABEL_STRING, "Font:", X PANEL_CHOICE_STRINGS, "default", "roman", X "bold", "italic", X "modern", "typewriter", 0, X PANEL_VALUE, new_text->font, X 0); X#endif X X text_adjust = new_text->type; /* get current justification */ X new_font = new_text->font; /* get current font */ X X int_panel(new_text->size, "Size:", &font_size_panel); X int_panel(new_text->color, "Color:", &color_panel); X int_panel(new_text->depth, "Depth:", &depth_panel); X int_panel(round(180/M_PI * new_text->angle), "Angle:", &angle_panel); X X /* make text justification menu */ X X XtSetArg(args[0], XtNfromVert, below); X adjust_panel = XtCreateManagedWidget( X adjust_item_names[text_adjust], menuButtonWidgetClass, X form, args, ONE); X below = adjust_panel; X adjust_menu = make_popup_menu(adjust_item_names, XtNumber(adjust_item_names), X adjust_panel, text_adjust_select); X X xy_panel(new_text->base_x,new_text->base_y, "Origin:", &x1_panel, &y1_panel); X font_image_panel(font_menu_bitmaps[new_text->font], "Font:", &font_panel); X str_panel(new_text->cstring, "Text:", &text_panel); X } X Xstatic Xget_new_text_values() X{ X char *s; X X PR_SIZE size; X X#ifdef notdef X new_text->type = atoi(panel_get_value(subtype_panel)); X new_text->font = atoi(panel_get_value(font_panel)); X#else X new_text->type = text_adjust; X new_text->font = new_font; X#endif X new_text->size = atoi(panel_get_value(font_size_panel)); X if (new_text->size < 1) X { X new_text->size = 1; X panel_set_value(font_size_panel, "1"); X } X new_text->color = atoi(panel_get_value(color_panel)); X new_text->depth = atoi(panel_get_value(depth_panel)); X new_text->angle = M_PI/180*atoi(panel_get_value(angle_panel)); X new_text->base_x = atoi(panel_get_value(x1_panel)); X new_text->base_y = atoi(panel_get_value(y1_panel)); X if (new_text->cstring) X cfree(new_text->cstring); X s = panel_get_value(text_panel); X new_text->cstring = (char *) calloc((unsigned)(strlen(s)+1), sizeof(char)); X strcpy(new_text->cstring, s); X size = pf_textwidth(new_text->font, new_text->size, strlen(s), s); X new_text->height = size.y; X new_text->length = size.x; X } X Xstatic Xdone_text() X{ X F_text *old_text; X X draw_text(new_text, INV_PAINT); X old_text = new_text->next; X switch (button_result) { X case APPLY: X get_new_text_values(); X break; X case DONE: X clean_up(); X get_new_text_values(); X set_action_object(F_CHANGE, O_TEXT); X new_text->next = NULL; X delete_text(&objects.texts, old_text); X insert_text(&objects.texts, new_text); X set_latesttext(old_text); X old_text->next = new_text; X X show_pointmarker(); X set_modifiedflag(); X break; X case CANCEL: X clean_up(); X new_text->next = NULL; X free_text(&new_text); X new_text = old_text; X X show_pointmarker(); X break; X } X draw_text(new_text, PAINT); X } X Xmake_window_ellipse(e) XF_ellipse *e; X{ X char *s1, *s2; X PIXRECT *image; X X new_ellipse = copy_ellipse(e); X new_ellipse->next = e; X switch (new_ellipse->type) { X case T_ELLIPSE_BY_RAD: X s1 = "ELLIPSE"; X s2 = "specified by radius"; X ellipse_flag = 1; X image = &ellrad_ic; X break; X case T_ELLIPSE_BY_DIA: X s1 = "ELLIPSE"; X s2 = "specified by diameter"; X ellipse_flag = 1; X image = &elldia_ic; X break; X case T_CIRCLE_BY_RAD: X s1 = "CIRCLE"; X s2 = "specified by radius"; X ellipse_flag = 0; X image = &cirrad_ic; X break; X case T_CIRCLE_BY_DIA: X s1 = "CIRCLE"; X s2 = "specified by diameter"; X ellipse_flag = 0; X image = &cirdia_ic; X break; X } X put_generic_vals(new_ellipse); X generic_window(s1, s2, image, done_ellipse, 1, 0); X int_panel(round(180/M_PI * new_ellipse->angle), "Angle:", &angle_panel); X X if (ellipse_flag) { X f_pos_panel(&new_ellipse->center, "Center ", X &x1_panel, &y1_panel); X f_pos_panel(&new_ellipse->radiuses, "Radiuses", X &x2_panel, &y2_panel); X } X else { X f_pos_panel(&new_ellipse->center,"Center", X &x1_panel, &y1_panel); X int_panel(new_ellipse->radiuses.x, "Radius", X &x2_panel); X } X } X Xstatic Xget_new_ellipse_values() X{ X F_pos old_center; X F_pos old_radiuses; X X# define adjust_ref(s,f) \ X s.f = new_ellipse->center.f + \ X ((s.f - old_center.f)*new_ellipse->radiuses.f)/old_radiuses.f X X get_generic_vals(new_ellipse); X new_ellipse->angle = M_PI/180*atoi(panel_get_value(angle_panel)); X old_center = new_ellipse->center; X old_radiuses = new_ellipse->radiuses; X get_f_pos(&new_ellipse->center, x1_panel, y1_panel); X if (ellipse_flag) X get_f_pos(&new_ellipse->radiuses, x2_panel, y2_panel); X X else X new_ellipse->radiuses.x = new_ellipse->radiuses.y = X atoi(panel_get_value(x2_panel)); X X adjust_ref(new_ellipse->start, x); X adjust_ref(new_ellipse->start, y); X adjust_ref(new_ellipse->end, x); X adjust_ref(new_ellipse->end, y); X } X Xstatic Xdone_ellipse() X{ X F_ellipse *old_ellipse; X X X draw_ellipse(new_ellipse, background_color); X old_ellipse = new_ellipse->next; X switch (button_result) { X case APPLY: X get_new_ellipse_values(); X draw_ellipse(new_ellipse, foreground_color); X break; X case DONE: X clean_up(); X get_new_ellipse_values(); X set_action_object(F_CHANGE, O_ELLIPSE); X new_ellipse->next = NULL; X delete_ellipse(&objects.ellipses, old_ellipse); X insert_ellipse(&objects.ellipses, new_ellipse); X set_latestellipse(old_ellipse); X old_ellipse->next = new_ellipse; X draw_ellipse(new_ellipse, foreground_color); X show_pointmarker(); X set_modifiedflag(); X break; X case CANCEL: X clean_up(); X new_ellipse->next = NULL; X free_ellipse(&new_ellipse); X draw_ellipse(old_ellipse, foreground_color); X show_pointmarker(); X break; X } X X } X Xmake_window_arc(a) XF_arc *a; X{ X new_arc = copy_arc(a); X new_arc->next = a; X put_generic_vals(new_arc); X put_generic_arrows(new_arc); X generic_window("ARC", "Specified by 3 points", &arc_ic, done_arc, 1, 1); X f_pos_panel(&new_arc->point[0], "p1", &x1_panel, &y1_panel); X f_pos_panel(&new_arc->point[1], "p2", &x2_panel, &y2_panel); X f_pos_panel(&new_arc->point[2], "p3", &x3_panel, &y3_panel); X } X Xstatic Xget_new_arc_values() X{ X F_pos p0, p1, p2; X float cx, cy; X X get_generic_vals(new_arc); X get_generic_arrows(new_arc); X get_f_pos(&p0, x1_panel, y1_panel); X get_f_pos(&p1, x2_panel, y2_panel); X get_f_pos(&p2, x3_panel, y3_panel); X if (compute_arccenter(p0, p1, p2, &cx, &cy)) { X new_arc->point[0] = p0; X new_arc->point[1] = p1; X new_arc->point[2] = p2; X new_arc->center.x = cx; X new_arc->center.y = cy; X new_arc->direction = compute_direction(p0, p1, p2); X } X else X put_msg("Invalid ARC points!"); X } X Xstatic Xdone_arc() X{ X F_arc *old_arc; X X X draw_arc(new_arc, background_color); X old_arc = new_arc->next; X switch (button_result) { X case APPLY: X get_new_arc_values(); X draw_arc(new_arc, foreground_color); X break; X case DONE: X clean_up(); X get_new_arc_values(); X set_action_object(F_CHANGE, O_ARC); X new_arc->next = NULL; X delete_arc(&objects.arcs, old_arc); X insert_arc(&objects.arcs, new_arc); X set_latestarc(old_arc); X old_arc->next = new_arc; X draw_arc(new_arc, foreground_color); X show_pointmarker(); X set_modifiedflag(); X break; X case CANCEL: X clean_up(); X new_arc->next = NULL; X free_arc(&new_arc); X draw_arc(old_arc, foreground_color); X show_pointmarker(); X break; X } X X } X Xmake_window_spline(s) XF_spline *s; X{ X new_spline = copy_spline(s); X new_spline->next = s; X put_generic_vals(new_spline); X put_generic_arrows(new_spline); X switch (new_spline->type) { X case T_OPEN_NORMAL: X generic_window("SPLINE", "Normal open", &spl_ic, X done_spline, 1, 1); X points_panel(new_spline->points, 0); X break; X case T_CLOSED_NORMAL: X generic_window("SPLINE", "Normal closed", &c_spl_ic, X done_spline, 1, 1); X points_panel(new_spline->points, 1); X break; X case T_OPEN_INTERPOLATED: X generic_window("SPLINE", "Interpolated open", &intspl_ic, X done_spline, 1, 1); X points_panel(new_spline->points, 0); X break; X case T_CLOSED_INTERPOLATED: X generic_window("SPLINE","Interpolated closed", &c_intspl_ic, X done_spline, 1,1); X points_panel(new_spline->points, 1); X break; X } X } X Xstatic Xdone_spline() X{ X F_spline *old_spline; X X draw_spline(new_spline, ERASE); X old_spline = new_spline->next; X switch (button_result) { X case APPLY: X get_generic_vals(new_spline); X get_generic_arrows(new_spline); X get_points(new_spline->points, closed_spline(new_spline)); X if (int_spline(new_spline)) X remake_control_points(new_spline); X draw_spline(new_spline, PAINT); X break; X case DONE: X clean_up(); X get_generic_vals(new_spline); X get_generic_arrows(new_spline); X get_points(new_spline->points, closed_spline(new_spline)); X set_action_object(F_CHANGE, O_SPLINE); X if (int_spline(new_spline)) X remake_control_points(new_spline); X new_spline->next = NULL; X delete_spline(&objects.splines, old_spline); X insert_spline(&objects.splines, new_spline); X set_latestspline(old_spline); X old_spline->next = new_spline; X draw_spline(new_spline, PAINT); X show_pointmarker(); X set_modifiedflag(); X break; X case CANCEL: X clean_up(); X new_spline->next = NULL; X free_spline(&new_spline); X draw_spline(old_spline, PAINT); X show_pointmarker(); X break; X } X } X X X/* X * The following routines X * change_line, change_arc, change_ellipse, change_spline, X * change_text X * are called by the UNDO function (undo.c). X * saved_objects.xxxx contains a pointer to the original, unchanged version X * of the object. saved_objects.xxxx->next contains a pointer to the new, X * changed version of the object. X */ X Xchange_line(lold, lnew) XF_line *lold, *lnew; X{ X lnew->next = NULL; X delete_line(&objects.lines, lold); X insert_line(&objects.lines, lnew); X set_latestline(lold); X lold->next = lnew; X draw_line(lold, ERASE); X draw_line(lnew, PAINT); X } X Xchange_arc(aold, anew) XF_arc *aold, *anew; X{ X anew->next = NULL; X delete_arc(&objects.arcs, aold); X insert_arc(&objects.arcs, anew); X set_latestarc(aold); X aold->next = anew; X draw_arc(aold, background_color); X draw_arc(anew, foreground_color); X } X Xchange_ellipse(eold, enew) XF_ellipse *eold, *enew; X{ X enew->next = NULL; X delete_ellipse(&objects.ellipses, eold); X insert_ellipse(&objects.ellipses, enew); X set_latestellipse(eold); X eold->next = enew; X draw_ellipse(eold, background_color); X draw_ellipse(enew, foreground_color); X } X Xchange_spline(sold, snew) XF_spline *sold, *snew; X{ X snew->next = NULL; X delete_spline(&objects.splines, sold); X insert_spline(&objects.splines, snew); X set_latestspline(sold); X sold->next = snew; X draw_spline(sold, ERASE); X draw_spline(snew, PAINT); X } X Xchange_text(told, tnew) XF_text *told, *tnew; X{ X tnew->next = NULL; X delete_text(&objects.texts, told); X insert_text(&objects.texts, tnew); X set_latesttext(told); X told->next = tnew; X draw_text(told, INV_PAINT); X draw_text(tnew, PAINT); X } X X Xstatic void Xnew_generic_values() X{ X int fill; X char buf[5]; X char *val; X X generic_vals.thickness = atoi(panel_get_value(thickness_panel)); X generic_vals.color = atoi(panel_get_value(color_panel)); X generic_vals.depth = atoi(panel_get_value(depth_panel)); X if (!no_fill_flag) X { X val = panel_get_value(area_fill_panel); X if (*val >= ' ' && *val <= '9') X { X if ((fill = atoi(val)) > 100) X fill = 100; X generic_vals.area_fill = NUMFILLPATS - (fill / (100/(NUMFILLPATS-1))); X } X fill = (NUMFILLPATS - generic_vals.area_fill) * (100/(NUMFILLPATS-1)); X sprintf(buf,"%d",fill); X panel_set_value(area_fill_panel,buf); X } X else X generic_vals.area_fill = 0; X} X Xstatic Xnew_arrow_values() X{ X generic_vals.for_arrow = (int)panel_get_value(for_arrow_panel); X generic_vals.back_arrow = (int)panel_get_value(back_arrow_panel); X} X Xstatic char * Xstyle_val_string(s, v) Xint s; Xdouble v; X{ X static char buf[64]; X switch(s) { X case SOLID_LINE: X sprintf(buf, " "); X return buf; X case DASH_LINE: X sprintf(buf, "dash length = %3.1f", v); X return buf; X case DOTTED_LINE: X sprintf(buf, "dot gap = %3.1f", v); X return buf; X } X return NULL; X } X X Xstatic Xdone_button(panel_local,item, event) XWidget panel_local; XWidget *item; Xint *event; X{ X button_result = DONE; X done_proc(); X Quit(); X} X Xstatic Xapply_button(panel_local,item, event) XWidget panel_local; XWidget *item; Xint *event; X{ X button_result = APPLY; X done_proc(); X} X Xstatic Xcancel_button(panel_local,item, event) XWidget panel_local; XWidget *item; Xint *event; X{ X button_result = CANCEL; X done_proc(); X Quit(); X} X X/* X the following pix_table entries are guaranteed to be X initialized to 0 by the compiler X*/ X Xstatic struct { X PIXRECT image; X Pixmap image_pm; X } pix_table[NUM_IMAGES]; X Xstatic Xgeneric_window(object_type, sub_type, icon, d_proc, generics, arrows) Xchar *object_type, *sub_type; XPIXRECT icon; Xint (*d_proc)(); Xint generics, arrows; X{ X char buf[64]; X Position x_val, y_val; X Dimension width, height; X Dimension label_height, image_height; X int button_distance; X Cardinal n; X int i, fill, dist; X Widget image; X Pixmap image_pm; X X static char * menu_item_names[] = { X "Solid Line ", "Dashed Line", "Dotted Line"}; X X XtSetArg(args[0], XtNwidth, &width); X XtSetArg(args[1], XtNheight, &height); X XtGetValues(tool, args, TWO); X XtTranslateCoords(tool, (Position) (width / 2), (Position) (height / 5), X &x_val, &y_val); X X n=0; X XtSetArg(args[n], XtNx, x_val); n++; X XtSetArg(args[n], XtNy, y_val); n++; X X popup = XtCreatePopupShell("change", transientShellWidgetClass, tool, X args, n); X X form = XtCreateManagedWidget("form", formWidgetClass, popup,NULL, 0); X X done_proc = d_proc; X X sprintf(buf,"%s:%s",object_type, sub_type); X label = XtCreateManagedWidget(buf, labelWidgetClass, form, NULL, 0); X X /* put in the image */ X /* search to see if that pixmap has already been created */ X image_pm = NULL; X for (i=0; i<NUM_IMAGES; i++) X { X if (pix_table[i].image == 0) X break; X if (pix_table[i].image == icon) X { X image_pm = pix_table[i].image_pm; X break; X } X } X /* doesn't already exist, create a pixmap from the data (ala panel.c) */ X if (!image_pm) X { X image_pm = XCreateBitmapFromData(tool_d, canvas_win, X icon->data, icon->width, icon->height); X pix_table[i].image_pm = image_pm; X pix_table[i].image = icon; X } X n=0; X XtSetArg(args[n], XtNbitmap, image_pm); n++; X XtSetArg(args[n], XtNfromHoriz, label); n++; X XtSetArg(args[n], XtNtop, XtChainTop); n++; X XtSetArg(args[n], XtNbottom, XtChainTop); n++; X XtSetArg(args[n], XtNleft, XtChainRight); n++; X XtSetArg(args[n], XtNright, XtChainRight); n++; X image = XtCreateManagedWidget("image", labelWidgetClass, form, args, n); X X /* get height of label widget and distance between widgets */ X n = 0; X XtSetArg(args[n], XtNheight, &label_height); n++; X XtSetArg(args[n], XtNvertDistance, &button_distance); n++; X XtGetValues(label, args, n); X /* do the same for the image widget */ X n = 0; X XtSetArg(args[n], XtNheight, &image_height); n++; X XtGetValues(image, args, n); X X if (image_height > label_height) X dist = image_height - label_height + button_distance; X else X dist = button_distance; X n=0; X XtSetArg(args[n], XtNfromVert, label); n++; X XtSetArg(args[n], XtNvertDistance, dist); n++; X but1= XtCreateManagedWidget("done", commandWidgetClass, form, args, n); X XtAddCallback(but1, XtNcallback, done_button, NULL); X X below = but1; X n=0; X XtSetArg(args[n], XtNfromHoriz, but1); n++; X XtSetArg(args[n], XtNfromVert,label); n++; X XtSetArg(args[n], XtNvertDistance, dist); n++; X but1= XtCreateManagedWidget("apply", commandWidgetClass, form, args, n); X XtAddCallback(but1, XtNcallback, apply_button, NULL); X X n=0; X XtSetArg(args[0], XtNfromHoriz, but1); n++; X XtSetArg(args[1], XtNfromVert,label); n++; X XtSetArg(args[n], XtNvertDistance, dist); n++; X but1= XtCreateManagedWidget("cancel",commandWidgetClass, form, args, n); X XtAddCallback(but1, XtNcallback, cancel_button, NULL); X X if (generics) { X int_panel(generic_vals.thickness, "Width:", &thickness_panel); X int_panel(generic_vals.color, "Color:", &color_panel); X int_panel(generic_vals.depth, "Depth:", &depth_panel); X X if (generic_vals.area_fill == 0 || X strcmp(sub_type,"Polyline") == 0) /* no area fill for polyline */ X { X fill = 100; X no_fill_flag = TRUE; X } X else X { X fill = (NUMFILLPATS-generic_vals.area_fill) * (100/(NUMFILLPATS-1)); X no_fill_flag = FALSE; X } X X if (strcmp(sub_type,"Polyline") != 0) /* no area fill for polyline */ X { X toggle_panel(no_fill_flag, no_fill_flag? "Not Filled": "Filled ", X &filled_panel); X int_panel(fill,"Fill%:", &area_fill_panel); X fill_pct_label = beside; /* save pointer to Fill% label */ X XtSetArg(args[0], XtNsensitive, no_fill_flag? False: True); X XtSetArg(args[1], XtNvertDistance, 2); X XtSetValues(area_fill_panel, args, TWO); X XtSetValues(fill_pct_label, args, TWO); X if (no_fill_flag) X sprintf(buf," "); X else X sprintf(buf,"%d",fill); X panel_set_value(area_fill_panel,buf); X } X X /* make popup line style menu */ X X XtSetArg(args[0], XtNfromVert, below); X style_panel = XtCreateManagedWidget( X menu_item_names[generic_vals.style], menuButtonWidgetClass, X form, args, ONE); X below = style_panel; X menu = make_popup_menu(menu_item_names, XtNumber(menu_item_names), X style_panel, line_style_select); X#ifdef notdef X X } X if (arrows) X { X for_arrow_panel = panel_create_item(change_panel, PANEL_TOGGLE, X PANEL_LABEL_X, ATTR_COL(2), X PANEL_LABEL_Y, ATTR_ROW(10), X PANEL_VALUE_X, ATTR_COL(20), X PANEL_VALUE_Y, ATTR_ROW(10), X PANEL_LABEL_STRING, "Forward arrow:", X PANEL_VALUE, generic_vals.for_arrow, X PANEL_FEEDBACK, PANEL_MARKED, X PANEL_NOTIFY_PROC, new_arrow_values, X 0); X back_arrow_panel = panel_create_item(change_panel, PANEL_TOGGLE, X PANEL_LABEL_X, ATTR_COL(2), X PANEL_LABEL_Y, ATTR_ROW(11), X PANEL_VALUE_X, ATTR_COL(20), X PANEL_VALUE_Y, ATTR_ROW(11), X PANEL_LABEL_STRING, "Backward arrow:", X PANEL_VALUE, generic_vals.back_arrow, X PANEL_FEEDBACK, PANEL_MARKED, X PANEL_NOTIFY_PROC, new_arrow_values, X 0); X#endif /* not def */ X } X X} X X/* make a button panel with the image 'pixmap' in it */ X/* for the font selection */ X Xvoid f_menu_popup(); X Xstatic XtCallbackRec f_sel_callback[] = X{ X { f_menu_popup, NULL }, X { NULL, NULL }, X}; X Xstatic Xfont_image_panel(pixmap, label, pi_x) XPixmap pixmap; Xchar *label; XWidget *pi_x; X { X char buf[32]; X X XtSetArg(args[0], XtNfromVert, below); X XtSetArg(args[1], XtNlabel, label); X below = XtCreateManagedWidget(label, labelWidgetClass, form, args, TWO); X X XtSetArg(args[0], XtNfromVert, below); X XtSetArg(args[1], XtNvertDistance, 2); X XtSetArg(args[2], XtNbitmap, pixmap); X XtSetArg(args[3], XtNcallback, f_sel_callback); X *pi_x = XtCreateManagedWidget(label, commandWidgetClass, form, args, FOUR); X below = *pi_x; X } X X/* come here when user presses font image button */ X Xvoid Xf_menu_popup() X { X font_sel = &new_font; /* store selected font number in new_font */ X image_widget = font_panel; /* and image in this widget */ X XtPopup(fontmenu,XtGrabNonexclusive); /* popup the font menu */ X setup_fontmenu_cursor(); /* now define the cursor for the font menu */ X } X X/* X make a popup menu with "nent" button entries (labels) that call X "callback" when pressed X*/ X XWidget Xmake_popup_menu(entries, nent, parent, callback) Xchar *entries[]; Xint nent; XWidget parent; XXtCallbackProc callback; X { X Widget pop_menu,entry; X int i; X X pop_menu = XtCreatePopupShell("menu", simpleMenuWidgetClass, parent, X NULL, ZERO); X X for (i = 0; i < nent ; i++) X { X entry = XtCreateManagedWidget(entries[i], smeBSBObjectClass, pop_menu, X NULL, ZERO); X XtAddCallback(entry, XtNcallback, callback, (XtPointer) i); X } X return pop_menu; X } X Xstatic Xint_panel(x, label, pi_x) Xint x; Xchar *label; XWidget *pi_x; X{ X char buf[32]; X X XtSetArg(args[0], XtNfromVert, below); X XtSetArg(args[1], XtNlabel, label); X beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, TWO); X X sprintf(buf, "%d", x); X XtSetArg(args[1], XtNstring, buf); X XtSetArg(args[2], XtNinsertPosition, strlen(buf)); X XtSetArg(args[3], XtNfromHoriz, beside); X XtSetArg(args[4], XtNeditType, "append"); X XtSetArg(args[5], XtNwidth, 40); X *pi_x = XtCreateManagedWidget(label, asciiTextWidgetClass, form, args, SIX); X below = *pi_x; X } X X/* don't allow newlines in text until we handle multiple line texts */ X Xstatic String text_translations = X "<Key>Return: no-op(RingBell)\n\ X Ctrl<Key>J: no-op(RingBell)\n\ X Ctrl<Key>M: no-op(RingBell)\n"; X Xstatic Xstr_panel(string, label, pi_x) Xchar *string; Xchar *label; XWidget *pi_x; X{ X int width,nlines,i,n; X Dimension pwidth; X PIX_FONT temp_font; X X XtSetArg(args[0], XtNfromVert, below); X XtSetArg(args[1], XtNlabel, label); X beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, TWO); X X /* get the font and width of above label widget */ X n=0; X XtSetArg(args[n], XtNfont, &temp_font); n++; X XtSetArg(args[n], XtNwidth, &pwidth); n++; X XtGetValues(beside, args, n); X /* make panel as wide as image pane above less the label widget's width */ X /* but at least 200 pixels wide */ X width = max(FONT_PANE_WIDTH-pwidth+2, 200); X X /* count number of lines in this text string */ X nlines=1; /* number of lines in string */ X for (i=0; i<strlen(string); i++) X { X if (string[i]=='\n') X { X nlines++; X } X } X if (nlines > 6) /* limit to displaying 6 lines and show scrollbars */ X nlines=6; X n=0; X XtSetArg(args[n], XtNfromVert, below); n++; X XtSetArg(args[n], XtNstring, string); n++; X XtSetArg(args[n], XtNinsertPosition, strlen(string)); n++; X XtSetArg(args[n], XtNfromHoriz, beside); n++; X XtSetArg(args[n], XtNeditType, "edit"); n++; X XtSetArg(args[n], XtNwidth, width); n++; X XtSetArg(args[n], XtNheight, char_height(temp_font)*nlines+4); n++; X XtSetArg(args[n], XtNscrollHorizontal, XawtextScrollWhenNeeded);n++; X XtSetArg(args[n], XtNscrollVertical, XawtextScrollWhenNeeded); n++; X *pi_x = XtCreateManagedWidget(label, asciiTextWidgetClass, form, args, n); X X /* make Newline do nothing for now */ X XtOverrideTranslations(*pi_x,XtParseTranslationTable(text_translations)); X X below = *pi_x; X } X Xstatic Xtoggle_panel(x, label, pi_x) Xint x; Xchar *label; XWidget *pi_x; X{ X XtSetArg(args[0], XtNfromVert, below); X XtSetArg(args[1], XtNlabel, label); X XtSetArg(args[2], XtNvalue, x); X *pi_x = XtCreateManagedWidget(label, toggleWidgetClass, form, args, THREE); X XtAddCallback(*pi_x, XtNcallback, toggle, NULL); X below = *pi_x; X } X Xstatic Xxy_panel(x, y, label, pi_x, pi_y) Xint x, y; Xchar *label; XWidget *pi_x, *pi_y; X{ X char buf[32]; X X XtSetArg(args[0], XtNfromVert, below); X XtSetArg(args[1], XtNlabel, label); X below = XtCreateManagedWidget(label, labelWidgetClass, form, args, TWO); X XtSetArg(args[0], XtNfromVert, below); X XtSetArg(args[1], XtNvertDistance, 2); X XtSetArg(args[2], XtNlabel, "X:"); X beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, THREE); X X sprintf(buf, "%d", x); X XtSetArg(args[2], XtNstring, buf); X XtSetArg(args[3], XtNinsertPosition, strlen(buf)); X XtSetArg(args[4], XtNfromHoriz, beside); X XtSetArg(args[5], XtNeditType, "append"); X XtSetArg(args[6], XtNwidth, 40); X *pi_x = XtCreateManagedWidget(label, asciiTextWidgetClass, form, args, SEVEN); X X XtSetArg(args[2], XtNlabel, "Y:"); X XtSetArg(args[3], XtNfromHoriz, *pi_x); X beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, FOUR); X X sprintf(buf, "%d", y); X XtSetArg(args[2], XtNstring, buf); X XtSetArg(args[3], XtNfromHoriz, beside); X XtSetArg(args[4], XtNinsertPosition, strlen(buf)); X XtSetArg(args[5], XtNeditType, "append"); X XtSetArg(args[6], XtNwidth, 40); X *pi_y = XtCreateManagedWidget(label, asciiTextWidgetClass, form, args ,SEVEN); X X below = *pi_x; X } X Xstatic Xf_pos_panel(fp, label, pi_x, pi_y) XF_pos *fp; Xchar *label; XWidget *pi_x, *pi_y; X{ X char buf[32]; X X XtSetArg(args[0], XtNfromVert, below); X below = XtCreateManagedWidget(label, labelWidgetClass, form, args, ONE); X XtSetArg(args[0], XtNfromVert, below); X XtSetArg(args[1], XtNlabel, "X:"); X beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, TWO); X sprintf(buf, "%d", fp->x); X XtSetArg(args[1], XtNstring, buf); X XtSetArg(args[2], XtNinsertPosition, strlen(buf)); X XtSetArg(args[3], XtNfromHoriz, beside); X XtSetArg(args[4], XtNeditType, "append"); X XtSetArg(args[5], XtNwidth, 40); X *pi_x = XtCreateManagedWidget(label, asciiTextWidgetClass, form, args, SIX); X XtSetArg(args[1], XtNlabel, "Y:"); X XtSetArg(args[2], XtNfromHoriz, *pi_x); X beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, THREE); X sprintf(buf, "%d", fp->y); X XtSetArg(args[1], XtNstring, buf); X XtSetArg(args[2], XtNinsertPosition, strlen(buf)); X XtSetArg(args[3], XtNfromHoriz, beside); X XtSetArg(args[4], XtNeditType, "append"); X XtSetArg(args[5], XtNwidth, 40); X *pi_y = XtCreateManagedWidget(label, asciiTextWidgetClass, form, args ,SIX); X below = *pi_x; X } X Xstatic Xget_f_pos(fp, pi_x, pi_y) XF_pos *fp; XWidget pi_x, pi_y; X{ X fp->x = (atoi(panel_get_value(pi_x))); X fp->y = (atoi(panel_get_value(pi_y))); X } X Xstatic Xpoints_panel(p, closed) Xstruct f_point *p; Xint closed; X{ X char buf[32]; X char bufxy[32]; X int i; X X for (i = 0; p != NULL; i++) { X if (i >= MAX_POINTS) X break; X XtSetArg(args[0], XtNfromVert,below); X sprintf(buf,"X:%d",i); X XtSetArg(args[1], XtNlabel, buf); X beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, TWO); X sprintf(bufxy, "%d", p->x); X XtSetArg(args[1], XtNstring, bufxy); X XtSetArg(args[2], XtNinsertPosition, strlen(bufxy)); X XtSetArg(args[3], XtNfromHoriz, beside); X XtSetArg(args[4], XtNeditType, "append"); X XtSetArg(args[5], XtNwidth, 40); X px_panel[i] = XtCreateManagedWidget("xy", asciiTextWidgetClass, X form, args, SIX); X X sprintf(buf,"Y:%d",i); X XtSetArg(args[1], XtNlabel, buf); X XtSetArg(args[2], XtNfromHoriz, px_panel[i]); X beside = XtCreateManagedWidget(label, labelWidgetClass, X form, args, THREE); X X sprintf(bufxy, "%d", p->y); X XtSetArg(args[1], XtNstring, bufxy); X XtSetArg(args[2], XtNinsertPosition, strlen(bufxy)); X XtSetArg(args[3], XtNfromHoriz,beside); X XtSetArg(args[4], XtNeditType, "append"); X XtSetArg(args[5], XtNwidth, 40); X X py_panel[i] = XtCreateManagedWidget("xy", asciiTextWidgetClass, X form, args, SIX); X below = px_panel[i]; X X p = p->next; X if (closed && (p == NULL || p->next == NULL)) X break; X X X } X } X Xstatic Xget_points(p, closed) Xstruct f_point *p; X{ X struct f_point *q; X int i; X X for (q = p, i = 0; q != NULL; i++) { X if (i >= MAX_POINTS) X break; X q->x = (atoi(panel_get_value(px_panel[i]))); X q->y = (atoi(panel_get_value(py_panel[i]))); X q = q->next; X if (closed) { X if (q == NULL) X break; X else if (q->next == NULL) { X q->x = p->x; X q->y = p->y; X break; X } X } X } X } X X Xvoid XQuit(widget, client_data, call_data) XWidget widget; XXtPointer client_data, call_data; X{ X X XtDestroyWidget(popup); X} X Xchar * Xpanel_get_value(widg) XWidget widg; X{ X char *val; X X XtSetArg(args[0], XtNstring, &val); X XtGetValues(widg, args, ONE); X if(atol(val) < 0) X { X panel_set_value(widg,"0"); X return "0"; X } X return val; X X} X X Xpanel_set_value(widg, val) XWidget widg; Xchar *val; X{ X X XtSetArg(args[0], XtNstring, val); X XtSetValues(widg, args, ONE); X XtSetArg(args[0], XtNinsertPosition, strlen(val)); X XtSetValues(widg, args, ONE); X} X X Xstatic void Xline_style_select(w, style, garbage) XWidget w; XXtPointer style, garbage; X{ X X XtSetArg(args[0], XtNlabel, XtName(w)); X XtSetValues(style_panel, args, ONE); X X generic_vals.style = (int) style; X X switch(generic_vals.style) X { X case SOLID_LINE: X generic_vals.style_val = 0.0; X break; X case DASH_LINE: X generic_vals.style_val = cur_dashlength; X break; X case DOTTED_LINE: X generic_vals.style_val = cur_dotgap; X break; X } X} X Xstatic void Xtext_adjust_select(w, adjust, garbage) XWidget w; XXtPointer adjust, garbage; X{ X X XtSetArg(args[0], XtNlabel, XtName(w)); X XtSetValues(adjust_panel, args, ONE); X text_adjust = (int) adjust; X} X X Xvoid Xtoggle(w, clos, garbage) XWidget w; XXtPointer clos, garbage; X{ X char buf[5]; X int fill; X X if(no_fill_flag == TRUE) X no_fill_flag = FALSE; X else X no_fill_flag = TRUE; X X /* set label to reflect fill flag */ X XtSetArg(args[0], XtNlabel, no_fill_flag? "Not Filled": "Filled "); X XtSetValues(w, args, ONE); X X /* make fill% panel sensitive or insensitive depending on fill flag */ X XtSetArg(args[0], XtNsensitive, no_fill_flag? False: True); X XtSetValues(area_fill_panel, args, ONE); X XtSetValues(fill_pct_label, args, ONE); X fill = (NUMFILLPATS - generic_vals.area_fill) * (100/(NUMFILLPATS-1)); X if (fill > 100) X fill = 100; X if (no_fill_flag) X sprintf(buf," "); X else X sprintf(buf,"%d",fill); X panel_set_value(area_fill_panel,buf); X} END_OF_FILE if test 39119 -ne `wc -c <'change.c'`; then echo shar: \"'change.c'\" unpacked with wrong size! fi # end of 'change.c' fi echo shar: End of archive 18 \(of 21\). cp /dev/null ark18isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 21 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 dan ---------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com Opinions expressed reflect those of the author only.