REPOST: v11i055: xxgdb - X front end for gdb, Part08/08
Pierre Willard
pierre at tce.COM
Thu Mar 7 18:20:08 AEST 1991
Submitted-by: pierre at tce.COM (Pierre Willard)
Posting-number: Volume 11, Issue 55
Archive-name: xxgdb/part08
#! /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 7 (of 8)."
# Contents: command.c datadpy.c
# Wrapped by gilbert at phi on Tue Jan 15 13:12:50 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'command.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'command.c'\"
else
echo shar: Extracting \"'command.c'\" \(23715 characters\)
sed "s/^X//" >'command.c' <<'END_OF_FILE'
X/*****************************************************************************
X *
X * xdbx - X Window System interface to the dbx debugger
X *
X * Copyright 1989 The University of Texas at Austin
X * Copyright 1990 Microelectronics and Computer Technology Corporation
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and that
X * both that copyright notice and this permission notice appear in
X * supporting documentation, and that the name of The University of Texas
X * and Microelectronics and Computer Technology Corporation (MCC) not be
X * used in advertising or publicity pertaining to distribution of
X * the software without specific, written prior permission. The
X * University of Texas and MCC makes no representations about the
X * suitability of this software for any purpose. It is provided "as is"
X * without express or implied warranty.
X *
X * THE UNIVERSITY OF TEXAS AND MCC DISCLAIMS ALL WARRANTIES WITH REGARD TO
X * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
X * FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TEXAS OR MCC BE LIABLE FOR
X * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
X * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
X * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
X * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
X *
X * Author: Po Cheung
X * Created: March 10, 1989
X *
X *****************************************************************************
X *
X * xxgdb - X Window System interface to the gdb debugger
X *
X * Copyright 1990 Thomson Consumer Electronics, Inc.
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and that
X * both that copyright notice and this permission notice appear in
X * supporting documentation, and that the name of Thomson Consumer
X * Electronics (TCE) not be used in advertising or publicity pertaining
X * to distribution of the software without specific, written prior
X * permission. TCE makes no representations about the suitability of
X * this software for any purpose. It is provided "as is" without express
X * or implied warranty.
X *
X * TCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
X * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
X * SHALL TCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES
X * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
X * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
X * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
X * SOFTWARE.
X *
X * Adaptation to GDB: Pierre Willard
X * XXGDB Created: December, 1990
X *
X *****************************************************************************/
X
X/* command.c
X *
X * Create the command window, the command buttons and their callbacks.
X *
X * CreateCommandPanel() : Create a window with command buttons
X * CreateButtons() : Create command buttons in panel
X * AddButton() : Add a command button into the command window
X * ButtonSet() : Action proc for command button translation
X *
X * Command callbacks for the command buttons:
X *
X * forwardSearch() : forward string search
X * reverseSearch() : reverse string search
X * Search() : call either forwardSearch() or reverseSearch()
X * PopupSearch() : command callback for search button
X * DoneSearch() : command callback for DONE button in search panel
X * CreateSearchPopup() : create search panel
X *
X * Command queue manipulation routines:
X * send_command(): send a command to dbx and record in the queue
X * get_command(): read command off head of queue
X * insert_command(): insert command at the head of queue
X * delete_command(): delete command from head of queue
X */
X
X#include <signal.h>
X#include <ctype.h>
X#include <sys/wait.h>
X#include "global.h"
X
X#define REVERSE 0
X#define FORWARD 1
X
XWidget commandWindow; /* command panel with buttons */
XBoolean PopupMode = False;
Xstatic int Button;
Xstatic Widget searchPopupShell, searchPopup;
Xstatic Widget AddButton();
Xstatic Widget button[30];
Xstatic char SearchString[BUFSIZ] = ""; /* search string buffer */
Xstatic char command[LINESIZ];
Xstatic CommandRec *commandQueue = NULL;
X#ifdef BSD
Xstatic char savedCommand[LINESIZ] = "";
X#endif
X
X/* ARGSUSED */
Xstatic void ButtonSet(w, event, params, num_params)
X Widget w;
X XEvent *event;
X String *params;
X Cardinal *num_params;
X{
X Button = atoi(params[0]);
X}
X
X/* ARGSUSED */
X/* Execute the dbx command specifed in client_data
X */
Xstatic void DoIt (w, command, call_data)
X Widget w;
X XtPointer command;
X XtPointer call_data;
X{
X /* run, cont, next, step, where, up, down, status */
X send_command(command);
X AppendDialogText(command);
X}
X
X#ifndef GDB /* >>>>>>>>>> NOT USED FOR GDB <<<<<<<<<<<<<<< */
X/* ARGSUSED */
Xstatic void Return (w, client_data, call_data)
X Widget w;
X XtPointer client_data;
X XtPointer call_data;
X{
X char *funcname;
X int nbytes;
X
X funcname = XFetchBytes(display, &nbytes); /* from CUT_BUFFER0 */
X if (nbytes == 0)
X strcpy(command, "return\n");
X else
X sprintf(command, "return %s\n", funcname);
X send_command(command);
X AppendDialogText(command);
X}
X#endif /* NOT GDB */
X
X#ifdef GDB /* >>>>>>>>>>>>>> GDB ONLY <<<<<<<<<<<<<<<< */
X/*
X here client_data is "break" or "tbreak"
X
X*/
Xstatic void Break(w, client_data, call_data)
X Widget w;
X XtPointer client_data;
X XtPointer call_data;
X{
X XawTextPosition pos;
X int line;
X char *funcname;
X int nbytes;
X char *s;
X
X funcname = XFetchBytes(display, &nbytes); /* from CUT_BUFFER0 */
X if (nbytes)
X {
X s = funcname;
X while (*s == ' ') s++; /* skip leading spaces (if any) */
X if ((*s >= '0') && (*s <= '9'))
X sprintf(command, "%s *%s\n",client_data,funcname);
X else
X sprintf(command, "%s %s\n",client_data,funcname);
X }
X else
X {
X if (displayedFile != NULL)
X {
X pos = XawTextGetInsertionPoint(sourceWindow);
X line = TextPositionToLine(pos);
X sprintf(command, "%s %d\n",client_data,line);
X }
X else
X {
X UpdateMessageWindow(BREAK_HELP, NULL);
X bell(0);
X return;
X }
X }
X
X send_command(command);
X AppendDialogText(command);
X}
X
X#else /* >>>>>>>>>> NOT USED FOR GDB <<<<<<<<<<<<<<< */
X
X/* ARGSUSED */
Xstatic void Stop_at(w, client_data, call_data)
X Widget w;
X XtPointer client_data;
X XtPointer call_data;
X{
X XawTextPosition pos;
X int line;
X
X if (displayedFile == NULL) {
X UpdateMessageWindow(STOP_AT_HELP, NULL);
X bell(0);
X return;
X }
X pos = XawTextGetInsertionPoint(sourceWindow);
X line = TextPositionToLine(pos);
X sprintf(command, "stop at %d\n", line);
X send_command(command);
X AppendDialogText(command);
X}
X
X/* ARGSUSED */
Xstatic void Stop_in(w, client_data, call_data)
X Widget w;
X XtPointer client_data;
X XtPointer call_data;
X{
X char *funcname;
X int nbytes;
X
X funcname = XFetchBytes(display, &nbytes); /* from CUT_BUFFER0 */
X if (nbytes == 0) {
X UpdateMessageWindow(STOP_IN_HELP, NULL);
X bell(0);
X return;
X }
X sprintf(command, "stop in %s\n", funcname);
X send_command(command);
X AppendDialogText(command);
X}
X
X#endif /* NOT GDB */
X
X/* Delete removes the stop_no associated with a given line number.
X * RemoveStop() is called to undisplay the stop sign only when there
X * are no more stop_no's associated with that line number.
X */
X/* ARGSUSED */
Xstatic void Delete(w, client_data, call_data)
X Widget w;
X XtPointer client_data;
X XtPointer call_data;
X{
X XawTextPosition pos;
X char *string;
X int stop_no, line, nbytes;
X
X string = XFetchBytes(display, &nbytes);
X if (nbytes > 0 && (stop_no = atoi(string)) > 0) {
X sprintf(command, "delete %d\n", stop_no);
X send_command(command);
X AppendDialogText(command);
X return;
X }
X else if (displayedFile) {
X pos = XawTextGetInsertionPoint(sourceWindow);
X line = TextPositionToLine(pos);
X if (stop_no = LineToStop_no(line)) {
X sprintf(command, "delete %d\n", stop_no);
X send_command(command);
X AppendDialogText(command);
X return;
X }
X }
X UpdateMessageWindow(DELETE_HELP, NULL);
X bell(0);
X}
X
X/* ARGSUSED */
Xstatic void Print(w, client_data, call_data)
X Widget w;
X XtPointer client_data;
X XtPointer call_data;
X{
X char *string;
X int nbytes;
X
X if (Button == 3) PopupMode = True;
X
X string = XFetchBytes(display, &nbytes);
X if (nbytes == 0) {
X UpdateMessageWindow(PRINT_HELP, NULL);
X bell(0);
X return;
X }
X if (client_data == (XtPointer)0)
X sprintf(command, "print %s\n", string);
X else if (client_data == (XtPointer)1)
X sprintf(command, "print *%s\n", string);
X send_command(command);
X#ifdef GDB
X if (!PopupMode) /* for GDB don't display print if everything goes in a window */
X#endif
X AppendDialogText(command);
X}
X
X#ifndef GDB /* >>>>>>>>>> NOT USED FOR GDB <<<<<<<<<<<<<<< */
X/* ARGSUSED */
Xstatic void Func(w, client_data, call_data)
X Widget w;
X XtPointer client_data;
X XtPointer call_data;
X{
X char *funcname;
X int nbytes;
X
X funcname = XFetchBytes(display, &nbytes);
X if (nbytes == 0)
X strcpy(command, "func\n");
X else
X sprintf(command, "func %s\n", funcname);
X send_command(command);
X AppendDialogText(command);
X}
X#endif /* NOT GDB */
X
X/* ARGSUSED */
Xstatic void Quit(w, client_data, call_data)
X Widget w;
X XtPointer client_data;
X XtPointer call_data;
X{
X union wait status;
X
X write_dbx("quit\n");
X XtDestroyApplicationContext(app_context);
X kill(dbxpid, SIGKILL);
X wait3(&status, WNOHANG, NULL);
X exit(0);
X}
X
X
X/* ARGSUSED */
Xstatic void Display_(w, client_data, call_data)
X Widget w;
X XtPointer client_data;
X XtPointer call_data;
X{
X char *string;
X int nbytes;
X
X string = XFetchBytes(display, &nbytes);
X sprintf(command, "display %s\n", string);
X send_command(command);
X AppendDialogText(command);
X}
X
X#ifdef GDB /* >>>>>>>>>>>>>> GDB ONLY <<<<<<<<<<<<<<<< */
X/* ARGSUSED */
Xstatic void Undisplay(w, client_data, call_data)
X Widget w;
X XtPointer client_data;
X XtPointer call_data;
X{
X char *string;
X int stop_no, nbytes;
X
X string = XFetchBytes(display, &nbytes);
X if (nbytes != 0)
X {
X if ((stop_no = atoi(string)) > 0)
X sprintf(command, "undisplay %d\n", stop_no);
X else
X {
X UpdateMessageWindow(UNDISPLAY_HELP, NULL);
X bell(0);
X return;
X }
X }
X else
X sprintf(command, "undisplay\n");
X
X send_command(command);
X AppendDialogText(command);
X}
X
X#else /* >>>>>>>>>> NOT USED FOR GDB <<<<<<<<<<<<<<< */
X
X/* ARGSUSED */
Xstatic void Undisplay(w, client_data, call_data)
X Widget w;
X XtPointer client_data;
X XtPointer call_data;
X{
X char *string;
X int stop_no, nbytes;
X
X string = XFetchBytes(display, &nbytes);
X if (nbytes == 0) {
X UpdateMessageWindow(UNDISPLAY_HELP, NULL);
X bell(0);
X return;
X }
X if ((stop_no = atoi(string)) > 0)
X sprintf(command, "undisplay %d\n", stop_no);
X else
X sprintf(command, "undisplay %s\n", string);
X send_command(command);
X AppendDialogText(command);
X}
X#endif /* NOT GDB */
X
X#ifndef GDB /* >>>>>>>>>> NOT USED FOR GDB <<<<<<<<<<<<<<< */
X/* ARGSUSED */
Xstatic void Dump(w, client_data, call_data)
X Widget w;
X XtPointer client_data;
X XtPointer call_data;
X{
X char *funcname;
X int nbytes;
X
X funcname = XFetchBytes(display, &nbytes);
X if (nbytes == 0)
X strcpy(command, "dump\n");
X else
X sprintf(command, "dump %s\n", funcname);
X send_command(command);
X AppendDialogText(command);
X}
X#endif /* NOT GDB */
X
X
X/* Beginning from startpos, this routine searches text forward for
X * searchstring, and returns 1 if searchstring is found, also returning
X * the left and right positions of the matched string in left and right;
X * else 0 is returned.
X * It also does wrap-around search.
X */
Xstatic forwardSearch(text, startpos, searchstring, left, right)
X char *text;
X int startpos;
X char *searchstring;
X XawTextPosition *left, *right;
X{
X int searchlength, searchsize, i, n=0;
X char *s1, *s2;
X
X searchlength = strlen(searchstring);
X searchsize = strlen(text) - searchlength;
X for (i=startpos; i < searchsize; i++) {
X n = searchlength;
X s1 = &text[i];
X s2 = searchstring;
X while (--n >= 0 && *++s1 == *s2++);
X if (n < 0) break;
X }
X if (n < 0) {
X *left = i+1;
X *right = i+1+searchlength;
X return 1;
X }
X else {
X for (i=0; i < startpos; i++) {
X n = searchlength;
X s1 = &text[i];
X s2 = searchstring;
X while (--n >= 0 && *++s1 == *s2++);
X if (n < 0) break;
X }
X if (n < 0) {
X *left = i+1;
X *right = i+1+searchlength;
X return 1;
X }
X return 0;
X }
X}
X
X
X/* Similar to forwardSearch(), except that it does a reverse search
X */
Xstatic reverseSearch(text, startpos, searchstring, left, right)
X char *text;
X XawTextPosition startpos;
X char *searchstring;
X XawTextPosition *left, *right;
X{
X int searchlength, i, n=0;
X char *s1, *s2;
X
X searchlength = strlen(searchstring);
X for (i=startpos; i > searchlength; i--) {
X n = searchlength;
X s1 = &text[i];
X s2 = &searchstring[searchlength-1];
X while (--n >= 0 && *--s1 == *s2--);
X if (n < 0) break;
X }
X if (n < 0) {
X *right = i;
X *left = *right-searchlength;
X return 1;
X }
X else {
X for (i=strlen(text)-1; i > startpos; i--) {
X n = searchlength;
X s1 = &text[i];
X s2 = &searchstring[searchlength-1];
X while (--n >= 0 && *--s1 == *s2--);
X if (n < 0) break;
X }
X if (n < 0) {
X *right = i;
X *left = *right-searchlength;
X return 1;
X }
X return 0;
X }
X}
X
X/* ARGSUSED */
Xstatic void PopupSearch(w, client_data, call_data)
X Widget w;
X XtPointer client_data;
X XtPointer call_data;
X{
X Arg args[MAXARGS];
X Cardinal n;
X Dimension popup_width, dialog_width;
X Position x, y;
X
X if (!displayedFile) {
X UpdateMessageWindow(SEARCH_HELP, NULL);
X bell(0);
X }
X else {
X XtRealizeWidget(searchPopupShell);
X n = 0;
X XtSetArg(args[n], XtNwidth, &popup_width); n++;
X XtGetValues(searchPopupShell, args, n);
X n = 0;
X XtSetArg(args[n], XtNwidth, &dialog_width); n++;
X XtGetValues(dialogWindow, args, n);
X XtTranslateCoords(dialogWindow,
X (Position)(dialog_width - popup_width)/2, 10, &x, &y);
X n = 0;
X XtSetArg(args[n], XtNx, x); n++;
X XtSetArg(args[n], XtNy, y); n++;
X XtSetValues(searchPopupShell, args, n);
X XtPopup(searchPopupShell, XtGrabNone);
X }
X}
X
X
X/* ARGSUSED */
X/* This routine handles both forward and reverse text search.
X * If no text has been entered, the contents of the cut buffer are used
X * for searching.
X */
Xstatic void Search(w, direction, call_data)
X Widget w;
X XtPointer direction;
X XtPointer call_data;
X{
X XawTextBlock textblock;
X XawTextPosition pos, left, right;
X char *searchString;
X
X searchString = XawDialogGetValueString(searchPopup);
X if (strlen(searchString) == 0) {
X textblock.ptr = XFetchBytes(display, &textblock.length);
X if (!textblock.ptr) {
X UpdateMessageWindow("No search string selected", NULL);
X bell(0);
X return;
X }
X searchString = textblock.ptr;
X }
X pos = XawTextGetInsertionPoint(sourceWindow);
X if ((direction == (XtPointer)FORWARD &&
X forwardSearch(displayedFile->buf, pos, searchString, &left, &right)) ||
X (direction == (XtPointer)REVERSE &&
X reverseSearch(displayedFile->buf, pos, searchString, &left, &right))) {
X AdjustText(TextPositionToLine(left));
X XawTextSetSelection(sourceWindow, left, right);
X XawTextSetInsertionPoint(sourceWindow, left);
X }
X else {
X if (direction == (XtPointer)FORWARD)
X UpdateMessageWindow("String not found", NULL);
X else if (direction == (XtPointer)REVERSE)
X UpdateMessageWindow("String not found", NULL);
X else
X#ifdef GDB
X UpdateMessageWindow("xxgdb error: illegal search direction", NULL);
X#else
X UpdateMessageWindow("xdbx error: illegal search direction", NULL);
X#endif
X bell(0);
X }
X}
X
X/* ARGSUSED */
Xstatic void DoneSearch(w, client_data, call_data)
X Widget w;
X XtPointer client_data;
X XtPointer call_data;
X{
X XtPopdown(client_data);
X}
X
X/* ARGSUSED */
Xstatic void Activate(w, event, params, num_params)
X Widget w;
X XEvent *event;
X String *params;
X Cardinal *num_params;
X{
X Search(w, (XtPointer)FORWARD, NULL);
X DoneSearch(w, (XtPointer)searchPopupShell, NULL);
X}
X
Xstatic void CreateSearchPopup()
X{
X Widget dialogValue;
X Arg args[MAXARGS];
X Cardinal n;
X
X static XtActionsRec search_actions[] = {
X {"Activate", Activate},
X {NULL, NULL}
X };
X
X static String translations = "#override\n\
X <Key>Return: Activate() \n\
X ";
X
X n = 0;
X XtSetArg(args[n], XtNinput, True); n++;
X XtSetArg(args[n], XtNallowShellResize, True); n++;
X searchPopupShell = XtCreatePopupShell("Search", transientShellWidgetClass,
X toplevel, args, n);
X
X n = 0;
X XtSetArg(args[n], XtNlabel, "Enter search string :"); n++;
X XtSetArg(args[n], XtNvalue, SearchString); n++;
X searchPopup = XtCreateManagedWidget("searchPopup", dialogWidgetClass,
X searchPopupShell, args, n);
X
X AddButton(searchPopup, "<<", Search, (XtPointer) REVERSE);
X AddButton(searchPopup, ">>", Search, (XtPointer) FORWARD);
X AddButton(searchPopup, "DONE", DoneSearch, (XtPointer)searchPopupShell);
X
X dialogValue = XtNameToWidget(searchPopup, "value");
X XtOverrideTranslations(dialogValue, XtParseTranslationTable(translations));
X XtAppAddActions(app_context, search_actions, XtNumber(search_actions));
X}
X
X
X
Xstatic Widget AddButton(parent, name, function, client_data)
XWidget parent;
Xchar *name;
Xvoid (*function) ();
XXtPointer client_data; /* callback registered data */
X{
X Widget button;
X Arg args[MAXARGS];
X Cardinal n;
X
X static XtActionsRec command_actions[] = {
X {"ButtonSet", (XtActionProc) ButtonSet},
X {NULL, NULL}
X };
X
X static String translations = "\
X <EnterWindow>: highlight() \n\
X <LeaveWindow>: reset() \n\
X <Btn1Down>: set()\n\
X <Btn1Up>: ButtonSet(1) notify() unset() \n\
X <Btn3Down>: set()\n\
X <Btn3Up>: ButtonSet(3) notify() unset()\n\
X ";
X
X n = 0;
X XtSetArg(args[n], XtNresize, (XtArgVal) False); n++;
X if (strcmp(name, "print") == NULL || strcmp(name, "print *") == NULL) {
X XtSetArg(args[n], XtNtranslations,
X XtParseTranslationTable(translations)); n++;
X }
X button = XtCreateManagedWidget(name, commandWidgetClass, parent, args, n);
X XtAddCallback(button, XtNcallback, function, client_data);
X XtAppAddActions(app_context, command_actions, XtNumber(command_actions));
X return (button);
X}
X
X
Xstatic void CreateButtons (parent)
XWidget parent;
X{
X int i=0;
X
X#ifdef GDB /* >>>>>>>>>>>>>> GDB ONLY <<<<<<<<<<<<<<<< */
X button[i++] = AddButton (parent, "run", DoIt, "run\n");
X button[i++] = AddButton (parent, "cont", DoIt, "cont\n");
X button[i++] = AddButton (parent, "next", DoIt, "next\n");
X button[i++] = AddButton (parent, "step", DoIt, "step\n");
X button[i++] = AddButton (parent, "finish", DoIt, "finish\n");
X button[i++] = AddButton (parent, "break", Break, "break");
X button[i++] = AddButton (parent, "tbreak", Break, "tbreak");
X button[i++] = AddButton (parent, "delete", Delete, NULL);
X button[i++] = AddButton (parent, "up", DoIt, "up\n");
X button[i++] = AddButton (parent, "down", DoIt, "down\n");
X button[i++] = AddButton (parent, "print", Print, (XtPointer)0);
X button[i++] = AddButton (parent, "print *", Print, (XtPointer)1);
X button[i++] = AddButton (parent, "display", Display_, NULL);
X button[i++] = AddButton (parent, "undisplay", Undisplay, NULL);
X button[i++] = AddButton (parent, "args", DoIt, "info args\n");
X button[i++] = AddButton (parent, "locals", DoIt, "info locals\n");
X button[i++] = AddButton (parent, "stack", DoIt, "info stack\n");
X button[i++] = AddButton (parent, "search", PopupSearch, NULL);
X button[i++] = AddButton (parent, "file", File, NULL);
X button[i++] = AddButton (parent, "quit", Quit, NULL);
X#else /* >>>>>>>>>> IF NOT GDB <<<<<<<<<<<<<<< */
X
X
X button[i++] = AddButton (parent, "run", DoIt, "run\n");
X button[i++] = AddButton (parent, "cont", DoIt, "cont\n");
X button[i++] = AddButton (parent, "next", DoIt, "next\n");
X button[i++] = AddButton (parent, "step", DoIt, "step\n");
X#ifdef BSD
X button[i++] = AddButton (parent, "return", Return, "return\n");
X#endif
X button[i++] = AddButton (parent, "stop at", Stop_at, NULL);
X button[i++] = AddButton (parent, "stop in", Stop_in, NULL);
X button[i++] = AddButton (parent, "delete", Delete, NULL);
X button[i++] = AddButton (parent, "where", DoIt, "where\n");
X button[i++] = AddButton (parent, "up", DoIt, "up\n");
X button[i++] = AddButton (parent, "down", DoIt, "down\n");
X button[i++] = AddButton (parent, "print", Print, (XtPointer)0);
X button[i++] = AddButton (parent, "print *", Print, (XtPointer)1);
X button[i++] = AddButton (parent, "func", Func, NULL);
X button[i++] = AddButton (parent, "file", File, NULL);
X button[i++] = AddButton (parent, "status", DoIt, "status\n");
X#ifndef BSD
X button[i++] = AddButton (parent, "display", Display_, NULL);
X button[i++] = AddButton (parent, "undisplay", Undisplay, NULL);
X#endif
X button[i++] = AddButton (parent, "dump", Dump, NULL);
X button[i++] = AddButton (parent, "search", PopupSearch, NULL);
X button[i++] = AddButton (parent, "quit", Quit, NULL);
X#endif /* NOT GDB */
X
X button[i++] = NULL;
X CreateSearchPopup();
X}
X
X
X/* Create a command widget, and the buttons. */
X
Xvoid CreateCommandPanel(parent)
XWidget parent;
X{
X Arg args[10];
X Cardinal n;
X
X n = 0;
X commandWindow = XtCreateManagedWidget("commandWindow", boxWidgetClass,
X parent, args, n);
X CreateButtons(commandWindow);
X getwd(cwd);
X}
X
X/**************************************************************************
X *
X * Command queue functions
X *
X **************************************************************************/
X
X/* Append command to end of the command queue and send the command to dbx */
X
Xvoid send_command(command)
Xchar *command;
X{
X CommandRec *p, *q, *r;
X
X#ifdef BSD
X /* Save the command if it is not a blank command; else use the
X last saved command instead */
X if (strcspn(command, " \n"))
X strcpy(savedCommand, command);
X else
X strcpy(command, savedCommand);
X#endif
X
X p = (CommandRec *)XtNew(CommandRec);
X p->command = XtNewString(command);
X p->next = NULL;
X if (!commandQueue)
X commandQueue = p;
X else {
X q = commandQueue;
X while (r = q->next)
X q = r;
X q->next = p;
X }
X write_dbx(command);
X}
X
X/* Read command at the head of the command queue */
X
Xchar *get_command()
X{
X if (commandQueue) {
X return (commandQueue->command);
X }
X else
X return NULL;
X}
X
X/* Delete command from the head of the command queue */
X
Xvoid delete_command()
X{
X CommandRec *p;
X
X if (p = commandQueue) {
X commandQueue = p->next;
X XtFree(p->command);
X XtFree(p);
X }
X}
X
X/* Insert command into head of queue */
X
Xvoid insert_command(command)
Xchar *command;
X{
X CommandRec *p;
X
X p = (CommandRec *)XtNew(CommandRec);
X p->command = XtNewString(command);
X p->next = NULL;
X if (!commandQueue)
X commandQueue = p;
X else {
X p->next = commandQueue;
X commandQueue = p;
X }
X}
END_OF_FILE
if test 23715 -ne `wc -c <'command.c'`; then
echo shar: \"'command.c'\" unpacked with wrong size!
fi
# end of 'command.c'
fi
if test -f 'datadpy.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'datadpy.c'\"
else
echo shar: Extracting \"'datadpy.c'\" \(21580 characters\)
sed "s/^X//" >'datadpy.c' <<'END_OF_FILE'
X/*****************************************************************************
X *
X * xdbx - X Window System interface to the dbx debugger
X *
X * Copyright 1989 The University of Texas at Austin
X * Copyright 1990 Microelectronics and Computer Technology Corporation
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and that
X * both that copyright notice and this permission notice appear in
X * supporting documentation, and that the name of The University of Texas
X * and Microelectronics and Computer Technology Corporation (MCC) not be
X * used in advertising or publicity pertaining to distribution of
X * the software without specific, written prior permission. The
X * University of Texas and MCC makes no representations about the
X * suitability of this software for any purpose. It is provided "as is"
X * without express or implied warranty.
X *
X * THE UNIVERSITY OF TEXAS AND MCC DISCLAIMS ALL WARRANTIES WITH REGARD TO
X * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
X * FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TEXAS OR MCC BE LIABLE FOR
X * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
X * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
X * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
X * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
X *
X * Author: Po Cheung
X * Created: March 10, 1989
X *
X *****************************************************************************
X *
X * xxgdb - X Window System interface to the gdb debugger
X *
X * Copyright 1990 Thomson Consumer Electronics, Inc.
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and that
X * both that copyright notice and this permission notice appear in
X * supporting documentation, and that the name of Thomson Consumer
X * Electronics (TCE) not be used in advertising or publicity pertaining
X * to distribution of the software without specific, written prior
X * permission. TCE makes no representations about the suitability of
X * this software for any purpose. It is provided "as is" without express
X * or implied warranty.
X *
X * TCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
X * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
X * SHALL TCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES
X * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
X * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
X * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
X * SOFTWARE.
X *
X * Adaptation to GDB: Pierre Willard
X * XXGDB Created: December, 1990
X *
X *****************************************************************************/
X
X/* dataDpy.c:
X *
X * Provide graphical display of C pointers and structures.
X *
X * BuildLinePos(): Construct an array indexing the character position of
X * each line.
X * PositionToLine(): Return the character position of a given line.
X * SelectPointer(): Action proc for double click on a pointer value,
X * CreateDataPopup(): Create a popup to display the object pointed to by a
X * pointer.
X * UpdateDataPopup(): Update an unused popupshell to display data.
X * AppendList(): Append a popup to the list.
X * DeleteList(): Delete a popup from the list.
X * pop_down(): pop down the popup and free storage.
X * DestroyDataPopup():event handler for destroying a popup, call DeleteList()
X * and pop_down().
X * MovePopup(): Position the popup.
X * print_handler(): Action handler for displaying pointers and structures.
X */
X
X#include "global.h"
X#include "regex.h"
X#include "datadpy.h"
X
X#define MAXLEVELS 20 /* max level of indentation */
X#ifdef GDB
X#define INDENT 2 /* # of spaces for each indentation */
X#else
X#define INDENT 8 /* # of spaces for each indentation */
X#endif /* GDB */
X#define EMPTY 0
X#define UNUSED 1
X#define USED 2
X#define LEFT_MARGIN 10
X#define SCROLLBAR_WIDTH 15
X
X
Xstatic DataDpyRec **dataDpyTable;
Xstatic int dataDpyTableSize = 0;
Xstatic DataDpyRec *Parent = NULL;
Xstatic DataDpyList *TopParentList = NULL;
Xstatic int font_height, font_width;
Xstatic void DestroyDataPopup();
X
X/*
X * Build an array which gives the starting text position of each line.
X * Very similar to the routine in source.c.
X */
Xstatic void BuildLinePos(dataDpy)
XDataDpyRec *dataDpy;
X{
X char *p;
X int line, nlines;
X int max=0;
X
X nlines = MAX(1, dataDpy->buflen/CHARS_PER_LINE);
X dataDpy->linepos = (XawTextPosition *)
X XtMalloc ((nlines+2) * sizeof(XawTextPosition));
X p = dataDpy->buf;
X line = 0;
X dataDpy->linepos[line++] = 0;
X dataDpy->linepos[line++] = 0;
X while (*p) {
X if (*p++ == '\n') {
X if (line == nlines) { /* buffer full, need more memory */
X dataDpy->linepos = (XawTextPosition *)XtRealloc(dataDpy->linepos,
X (nlines + ADD_LINES) * sizeof(XawTextPosition));
X nlines += ADD_LINES;
X }
X dataDpy->linepos[line] = p - dataDpy->buf;
X AssignMax(max, dataDpy->linepos[line] - dataDpy->linepos[line-1]);
X line++;
X }
X }
X dataDpy->numlines = line - 2;
X dataDpy->maxLineLength = max;
X /* shrink to min size */
X dataDpy->linepos = (XawTextPosition *) XtRealloc
X (dataDpy->linepos, line * sizeof(XawTextPosition));
X}
X
X/*
X * Return the line number for the specified text position.
X */
Xstatic int PositionToLine(dataDpy, pos)
XDataDpyRec *dataDpy;
XXawTextPosition pos;
X{
X int line;
X
X if (dataDpy && pos >= 0) {
X for (line = 1; pos >= dataDpy->linepos[line]; line++);
X return (line-1);
X }
X else
X return (0);
X}
X
X/* ARGSUSED */
X/*
X * Called by double click of pointer button.
X * If the selected text is a valid pointer, this routine parses the data
X * output to obtain the full qualified name of the pointer, and asks
X * dbx to print the value of the object the pointer is pointing to.
X */
Xstatic void SelectPointer(w, event, params, num_params)
X Widget w;
X XEvent *event;
X String *params;
X Cardinal *num_params;
X{
X struct re_registers regs;
X XawTextPosition left, right;
X char *selection, *p, *field[MAXLEVELS];
X DataDpyRec *dataDpy;
X int fromLine, line;
X int i, n, nbytes, r, level, newlevel;
X char name[LINESIZ], command[LINESIZ];
X
X /* Find out which data display output does the selection belong to */
X dataDpy = NULL;
X for (i=0; dataDpyTable[i]; i++)
X if ((Widget) w == (Widget) dataDpyTable[i]->dataDpyWindow) {
X dataDpy = dataDpyTable[i];
X Parent = dataDpy;
X break;
X }
X if (!dataDpy) return;
X
X /* Get the selection and check if it's a pointer value, 0x???? */
X selection = XFetchBytes(display, &nbytes);
X if (re_match(dataPattern[D_POINTER].buf, selection, strlen(selection), 0, 0)
X < 0) {
X Parent = NULL;
X return;
X }
X
X /* Parse the output to get the fully qualified name of the pointer */
X XawTextGetSelectionPos(w, &left, &right);
X fromLine = PositionToLine(dataDpy, left);
X p = dataDpy->buf + dataDpy->linepos[fromLine];
X
X if (re_match(dataPattern[D_FIELD].buf, p, strlen(p), 0, ®s) >= 0) {
X r = dataPattern[D_FIELD].reg_token[TK_POINTER];
X if (strncmp(selection, p+regs.start[r], regs.end[r]-regs.start[r]))
X return;
X r = dataPattern[D_FIELD].reg_token[TK_INDENT];
X level = regs.end[r]/INDENT;
X field[level+1] = NULL;
X
X r = dataPattern[D_FIELD].reg_token[TK_FIELD];
X n = regs.end[r] - regs.start[r];
X field[level] = (char *) XtMalloc ((n+1) * sizeof(char));
X strncpy(field[level], p+regs.start[r], n);
X field[level][n] = '\0';
X
X for (line = fromLine-1; line > 0; line--) {
X p = dataDpy->buf + dataDpy->linepos[line];
X if (re_match(dataPattern[D_STRUCT].buf, p, strlen(p), 0, ®s)>=0){
X r = dataPattern[D_STRUCT].reg_token[TK_INDENT];
X newlevel = regs.end[r]/INDENT;
X if (newlevel == level-1) {
X level--;
X r = dataPattern[D_STRUCT].reg_token[TK_FIELD];
X n = regs.end[r] - regs.start[r];
X field[level] = (char *) XtMalloc ((n+1) * sizeof(char));
X strncpy(field[level], p+regs.start[r], n);
X field[level][n] = '\0';
X }
X }
X }
X if (*field[0] == '*' && field[1])
X sprintf(name, "(%s)", field[0]+1);
X else
X strcpy(name, field[0]);
X for (i=1; field[i]; i++) {
X strcat(name, ".");
X strcat(name, field[i]);
X }
X sprintf(command, "print *(%s)\n", name);
X PopupMode = True;
X query_dbx(command);
X }
X}
X
X
X/*
X * Create a data display with a label.
X * The popupshell has a form widget which consists of a label and a text
X * widget.
X */
Xstatic void CreateDataPopup(dataDpy, label)
XDataDpyRec *dataDpy;
Xchar *label;
X{
X Arg args[MAXARGS];
X Cardinal n;
X Dimension dataDpyHeight, dataDpyWidth;
X XFontStruct *text_font;
X
X static XtActionsRec datadpy_actions[] = {
X {"SelectPointer", (XtActionProc) SelectPointer},
X {NULL, NULL}
X };
X
X static String translations = "#override \n\
X <Btn1Down>: SelectStart() SelectWord() SelectPointer() \n\
X <Btn1Up>: SelectEnd() \n\
X ";
X
X n = 0;
X dataDpy->popupshell = XtCreatePopupShell("Data Popup",
X transientShellWidgetClass, toplevel, args, n);
X
X n = 0;
X XtSetArg(args[n], XtNdefaultDistance, 0); n++;
X dataDpy->popup = XtCreateManagedWidget("popup", formWidgetClass,
X dataDpy->popupshell, args, n);
X
X /* Create the label */
X n = 0;
X XtSetArg(args[n], XtNtop, (XtArgVal) XawChainTop); n++;
X XtSetArg(args[n], XtNbottom, (XtArgVal) XawChainTop); n++;
X XtSetArg(args[n], XtNright, (XtArgVal) XawChainRight); n++;
X XtSetArg(args[n], XtNleft, (XtArgVal) XawChainLeft); n++;
X XtSetArg(args[n], XtNlabel, (XtArgVal) label); n++;
X XtSetArg(args[n], XtNresize, (XtArgVal) False); n++;
X XtSetArg(args[n], XtNjustify, (XtArgVal) XtJustifyCenter); n++;
X dataDpy->label = XtCreateManagedWidget("label", labelWidgetClass,
X dataDpy->popup, args, n);
X XtAddEventHandler(dataDpy->label, (EventMask) ButtonPressMask, False,
X DestroyDataPopup, dataDpy);
X
X /* Create the text window */
X n = 0;
X XtSetArg(args[n], XtNfromVert, (XtArgVal) dataDpy->label); n++;
X XtSetArg(args[n], XtNtop, (XtArgVal) XawChainTop); n++;
X XtSetArg(args[n], XtNbottom, (XtArgVal) XawChainBottom); n++;
X XtSetArg(args[n], XtNright, (XtArgVal) XawChainRight); n++;
X XtSetArg(args[n], XtNleft, (XtArgVal) XawChainLeft); n++;
X
X XtSetArg(args[n], XtNleftMargin, (XtArgVal) LEFT_MARGIN); n++;
X XtSetArg(args[n], XtNuseStringInPlace, (XtArgVal) True); n++;
X XtSetArg(args[n], XtNstring, (XtArgVal) dataDpy->buf); n++;
X XtSetArg(args[n], XtNlength, (XtArgVal) dataDpy->buflen); n++;
X XtSetArg(args[n], XtNeditType, (XtArgVal) XawtextRead); n++;
X XtSetArg(args[n], XtNscrollHorizontal, XawtextScrollWhenNeeded); n++;
X XtSetArg(args[n], XtNscrollVertical, XawtextScrollWhenNeeded); n++;
X XtSetArg(args[n], XtNtranslations, XtParseTranslationTable(translations));
X n++;
X dataDpy->dataDpyWindow = XtCreateManagedWidget("dataDpyWindow",
X asciiTextWidgetClass, dataDpy->popup, args, n);
X XtAppAddActions(app_context, datadpy_actions, XtNumber(datadpy_actions));
X
X /* Get the text font */
X n = 0;
X XtSetArg(args[n], XtNfont, &text_font); n++;
X XtGetValues(dataDpy->dataDpyWindow, args, n);
X
X /* Estimate the size of the text widget, dataDpyWindow, with the number
X of lines and the maximum length of a line. Assume fixed font width.
X */
X font_height = text_font->ascent + text_font->descent;
X font_width = text_font->max_bounds.width;
X dataDpyHeight = dataDpy->numlines * font_height + 5;
X dataDpyWidth = dataDpy->maxLineLength * font_width + LEFT_MARGIN;
X if (dataDpyHeight > app_resources.dataDpyMaxHeight)
X dataDpyWidth += SCROLLBAR_WIDTH;
X
X#if 1 /*(PW)17DEC90 : bug ! */
X#define SCROLLBAR_HEIGHT 15
X if (dataDpyWidth > app_resources.dataDpyMaxWidth)
X dataDpyHeight += SCROLLBAR_HEIGHT;
X#endif
X
X AssignMin(dataDpyHeight, app_resources.dataDpyMaxHeight);
X AssignMin(dataDpyWidth, app_resources.dataDpyMaxWidth);
X
X n = 0;
X XtSetArg(args[n], XtNheight, (XtArgVal) dataDpyHeight); n++;
X XtSetArg(args[n], XtNwidth, (XtArgVal) dataDpyWidth); n++;
X XtSetValues(dataDpy->dataDpyWindow, args, n);
X
X n = 0;
X XtSetArg(args[n], XtNwidth, (XtArgVal) dataDpyWidth); n++;
X XtSetValues(dataDpy->label, args, n);
X}
X
X/*
X * Instead of creating a new popupshell, this routine uses an already
X * existing popupshell for data display.
X * It changes the label, calculates the size of the popupshell,
X * and sets the source of the text window to that of the new data.
X */
Xstatic void UpdateDataPopup(dataDpy, label)
XDataDpyRec *dataDpy;
Xchar *label;
X{
X Arg args[MAXARGS];
X Cardinal n;
X Dimension popupHeight, popupWidth, dataDpyHeight, dataDpyWidth,
X labelHeight, labelBorderWidth, dataDpyBorderWidth;
X
X /* Update the label */
X n = 0;
X XtSetArg(args[n], XtNlabel, (XtArgVal) label); n++;
X XtSetValues(dataDpy->label, args, n);
X
X /* Calculate the size of popupshell */
X dataDpyHeight = dataDpy->numlines * font_height + 5;
X dataDpyWidth = dataDpy->maxLineLength * font_width + 2*10;
X
X#if 1 /*(PW)18DEC90 : bug ! */
X if (dataDpyHeight > app_resources.dataDpyMaxHeight)
X dataDpyWidth += SCROLLBAR_WIDTH;
X
X if (dataDpyWidth > app_resources.dataDpyMaxWidth)
X dataDpyHeight += SCROLLBAR_HEIGHT;
X#endif
X
X AssignMin(dataDpyHeight, app_resources.dataDpyMaxHeight);
X AssignMin(dataDpyWidth, app_resources.dataDpyMaxWidth);
X
X n = 0;
X XtSetArg(args[n], XtNheight, (XtArgVal) &labelHeight); n++;
X XtSetArg(args[n], XtNborderWidth, (XtArgVal) &labelBorderWidth); n++;
X XtGetValues(dataDpy->label, args, n);
X n = 0;
X XtSetArg(args[n], XtNborderWidth, (XtArgVal) &dataDpyBorderWidth); n++;
X XtGetValues(dataDpy->dataDpyWindow, args, n);
X
X popupHeight = dataDpyHeight + labelHeight + 2*labelBorderWidth +
X 2*dataDpyBorderWidth;
X popupWidth = dataDpyWidth;
X
X n = 0;
X XtSetArg(args[n], XtNheight, (XtArgVal) popupHeight); n++;
X XtSetArg(args[n], XtNwidth, (XtArgVal) popupWidth); n++;
X XtSetValues(dataDpy->popupshell, args, n);
X
X /* Set the text source */
X n = 0;
X XtSetArg(args[n], XtNstring, (XtArgVal) dataDpy->buf); n++;
X XtSetArg(args[n], XtNlength, (XtArgVal) dataDpy->buflen); n++;
X XawTextSetSource(dataDpy->dataDpyWindow,
X XtCreateWidget("textsrc", asciiSrcObjectClass,
X dataDpy->dataDpyWindow, args, n),
X 0);
X}
X
X/*
X * Append dataDpy to a DataDpyList pointed to by head.
X */
Xstatic void AppendList(head, dataDpy)
XDataDpyList **head;
XDataDpyRec *dataDpy;
X{
X DataDpyList *p, *q, *r;
X
X p = (DataDpyList *) XtNew (DataDpyList);
X p->dataDpy = dataDpy;
X p->next = NULL;
X q = *head;
X if (!q)
X *head = p;
X else {
X while (r = q->next)
X q = r;
X q->next = p;
X }
X}
X
X/*
X * Removes a dataDpy from its parent's list of children.
X */
Xstatic void DeleteList(head, dataDpy)
XDataDpyList **head;
XDataDpyRec *dataDpy;
X{
X DataDpyList *p, *q;
X
X if (p = *head) {
X if (p->dataDpy == dataDpy)
X *head = p->next;
X else {
X for (q = p->next; q && q->dataDpy != dataDpy;) {
X p = q;
X q = p->next;
X }
X if (q) p->next = q->next;
X }
X }
X}
X
X/*
X * Pop down a dataDpy and all its descendants, freeing storage and
X * reinitializing fields.
X */
Xstatic void pop_down(dataDpy)
XDataDpyRec *dataDpy;
X{
X DataDpyList *p, *q;
X
X XtPopdown(dataDpy->popupshell);
X XtFree(dataDpy->linepos);
X XtFree(dataDpy->buf);
X dataDpy->buf = NULL;
X dataDpy->buflen = 0;
X dataDpy->linepos = NULL;
X dataDpy->state = UNUSED;
X dataDpy->parent = NULL;
X for (p = dataDpy->childlist; p;) {
X pop_down(p->dataDpy);
X q = p;
X p = p->next;
X XtFree(q);
X }
X dataDpy->childlist = NULL;
X}
X
X/*
X * Invoked by a ButtonPress event on the label of a data display to
X * pop down itself and its descendants.
X */
X/* ARGSUSED */
Xstatic void DestroyDataPopup(w, dataDpy, event)
X Widget w;
X DataDpyRec *dataDpy;
X XEvent *event;
X{
X if (!dataDpy->parent)
X DeleteList(&TopParentList, dataDpy);
X else
X DeleteList(&dataDpy->parent->childlist, dataDpy);
X pop_down(dataDpy);
X}
X
X/*
X * Position the data display on the screen to reflect the parent-child
X * relationship.
X */
Xstatic void MovePopup(dataDpy)
XDataDpyRec *dataDpy;
X{
X Arg args[MAXARGS];
X Cardinal n;
X Screen *screen;
X int popupHeight, popupWidth, screenHeight, screenWidth;
X Position x, y;
X Dimension dataDpyWidth, dataDpyHeight, dataDpyBorderWidth,
X labelHeight, labelBorderWidth, width, height, borderWidth;
X DataDpyList *p, *q;
X
X Parent = NULL;
X if (!dataDpy->parent)
X p = TopParentList;
X else
X p = dataDpy->parent->childlist;
X
X /* Look for its previous sibling */
X for (q = p->next; q && q->dataDpy != dataDpy;) {
X p = q;
X q = q->next;
X }
X /* If a sibling exists, place the new popup right next to it */
X if (q) {
X n = 0;
X XtSetArg(args[n], XtNwidth, (XtArgVal) &width); n++;
X XtSetArg(args[n], XtNborderWidth, (XtArgVal) &borderWidth); n++;
X XtGetValues(p->dataDpy->popupshell, args, n);
X XtTranslateCoords(p->dataDpy->popupshell, 0, 0, &x, &y);
X x += width;
X y -= borderWidth;
X }
X else { /* no siblings */
X /* this is the very first popup */
X if (!dataDpy->parent) {
X x = 0;
X y = 0;
X }
X /* place it under its parent */
X else {
X n = 0;
X XtSetArg(args[n], XtNheight, (XtArgVal) &height); n++;
X XtGetValues(dataDpy->parent->popupshell, args, n);
X XtTranslateCoords(dataDpy->parent->popupshell, 30, (Position)height,
X &x, &y);
X }
X }
X
X /* Make sure the popup does not go outside of the screen */
X n = 0;
X XtSetArg(args[n], XtNwidth, (XtArgVal) &dataDpyWidth); n++;
X XtSetArg(args[n], XtNheight, (XtArgVal) &dataDpyHeight); n++;
X XtSetArg(args[n], XtNborderWidth, (XtArgVal) &dataDpyBorderWidth); n++;
X XtGetValues(dataDpy->dataDpyWindow, args, n);
X
X n = 0;
X XtSetArg(args[n], XtNheight, (XtArgVal) &labelHeight); n++;
X XtSetArg(args[n], XtNborderWidth, (XtArgVal) &labelBorderWidth); n++;
X XtGetValues(dataDpy->label, args, n);
X
X popupHeight = dataDpyHeight + labelHeight + 2*labelBorderWidth +
X 2*dataDpyBorderWidth;
X popupWidth = dataDpyWidth;
X
X screen = XtScreen(toplevel);
X screenHeight = XHeightOfScreen(screen);
X screenWidth = XWidthOfScreen(screen);
X
X if (x + popupWidth > screenWidth && y + popupHeight > screenHeight) {
X x = screenWidth - popupWidth;
X y = screenHeight - popupHeight;
X }
X else if (x + popupWidth > screenWidth)
X x = screenWidth - popupWidth;
X else if (y + popupHeight > screenHeight)
X y = screenHeight - popupHeight;
X
X n = 0;
X XtSetArg(args[n], XtNx, x); n++;
X XtSetArg(args[n], XtNy, y); n++;
X XtSetValues(dataDpy->popupshell, args, n);
X}
X
X/*
X * Handler procedure called by parse().
X * The main function to popup a data display.
X */
Xvoid print_handler(output)
Xchar *output;
X{
X DataDpyRec *dataDpy;
X int i, j;
X
X if (!output) return;
X if (!PopupMode) return;
X PopupMode = False;
X XDefineCursor(display, XtWindow(toplevel), watch);
X if (Parent)
X XDefineCursor(display, XtWindow(Parent->dataDpyWindow), watch);
X UpdateMessageWindow("Click the label to pop down the data popup");
X
X /* Searches the table for an unused or empty slot */
X for (i=0; dataDpyTable && dataDpyTable[i] && dataDpyTable[i]->state == USED
X && i < dataDpyTableSize; i++);
X if (i == dataDpyTableSize) { /* Table full */
X dataDpyTableSize += ADD_SIZE;
X dataDpyTable = (DataDpyRec **) XtRealloc (dataDpyTable,
X dataDpyTableSize * sizeof(DataDpyRec *));
X for (j=i; j<dataDpyTableSize; j++)
X dataDpyTable[j] = NULL;
X }
X
X /* Empty slot found, allocate a data structure and initializes some
X of the fields. */
X if (dataDpyTable[i] == NULL) {
X dataDpyTable[i] = (DataDpyRec *) XtMalloc (sizeof(DataDpyRec));
X dataDpyTable[i]->state = EMPTY;
X dataDpyTable[i]->parent = NULL;
X dataDpyTable[i]->childlist = NULL;
X }
X
X dataDpy = dataDpyTable[i];
X dataDpy->id = i; /* not needed */
X dataDpy->buf = XtNewString(output);
X dataDpy->buflen = strlen(output);
X BuildLinePos(dataDpy);
X
X if (dataDpy->state == EMPTY)
X CreateDataPopup(dataDpy, Token.mesg);
X else if (dataDpy->state == UNUSED)
X UpdateDataPopup(dataDpy, Token.mesg);
X
X dataDpy->state = USED; /* mark it used */
X if (dataDpy->parent = Parent)
X AppendList(&Parent->childlist, dataDpy);
X else
X AppendList(&TopParentList, dataDpy);
X
X MovePopup(dataDpy);
X XtPopup(dataDpy->popupshell, XtGrabNone);
X if (dataDpy->parent)
X XUndefineCursor(display, XtWindow(dataDpy->parent->dataDpyWindow));
X XUndefineCursor(display, XtWindow(toplevel));
X}
END_OF_FILE
if test 21580 -ne `wc -c <'datadpy.c'`; then
echo shar: \"'datadpy.c'\" unpacked with wrong size!
fi
# end of 'datadpy.c'
fi
echo shar: End of archive 7 \(of 8\).
cp /dev/null ark7isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 8 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Dan Heller
------------------------------------------------
O'Reilly && Associates Z-Code Software
Senior Writer President
argv at ora.com argv at zipcode.com
More information about the Comp.sources.x
mailing list