|
|
1.1 ! root 1: /* Interface from GDB to X windows. ! 2: Copyright (C) 1987 Free Software Foundation, Inc. ! 3: ! 4: GDB is distributed in the hope that it will be useful, but WITHOUT ANY ! 5: WARRANTY. No author or distributor accepts responsibility to anyone ! 6: for the consequences of using it or for whether it serves any ! 7: particular purpose or works at all, unless he says so in writing. ! 8: Refer to the GDB General Public License for full details. ! 9: ! 10: Everyone is granted permission to copy, modify and redistribute GDB, ! 11: but only under the conditions described in the GDB General Public ! 12: License. A copy of this license is supposed to have been given to you ! 13: along with GDB so you can know your rights and responsibilities. It ! 14: should be in a file named COPYING. Among other things, the copyright ! 15: notice and this notice must be preserved on all copies. ! 16: ! 17: In other words, go ahead and share GDB, but don't try to stop ! 18: anyone else from sharing it farther. Help stamp out software hoarding! ! 19: */ ! 20: ! 21: /* Original version was contributed by Derek Beatty, 30 June 87. */ ! 22: ! 23: #include "defs.h" ! 24: #include "initialize.h" ! 25: #include "param.h" ! 26: #include "symtab.h" ! 27: #include "frame.h" ! 28: ! 29: #include <X11/IntrinsicP.h> ! 30: #include <X11/StringDefs.h> ! 31: #include <X11/Label.h> ! 32: #include <X11/Command.h> ! 33: #include <X11/TextP.h> ! 34: #include <X11/Box.h> ! 35: #include <X11/VPaned.h> ! 36: ! 37: #include <stdio.h> ! 38: ! 39: /* Cursor used in GDB window. */ ! 40: ! 41: #define gdb_width 16 ! 42: #define gdb_height 16 ! 43: #define gdb_x_hot 7 ! 44: #define gdb_y_hot 0 ! 45: static short gdb_bits[] = { ! 46: 0x0000, 0x0140, 0x0220, 0x0220, ! 47: 0x23e2, 0x13e4, 0x09c8, 0x0ff8, ! 48: 0x0220, 0x3ffe, 0x0630, 0x03e0, ! 49: 0x0220, 0x1ffc, 0x2632, 0x01c0}; ! 50: ! 51: #define gdb_mask_width 16 ! 52: #define gdb_mask_height 16 ! 53: #define gdb_mask_x_hot 7 ! 54: #define gdb_mask_y_hot 0 ! 55: static short gdb_mask_bits[] = { ! 56: 0x0360, 0x07f0, 0x07f0, 0x77f7, ! 57: 0x7fff, 0x7fff, 0x1ffc, 0x1ffc, ! 58: 0x7fff, 0x7fff, 0x7fff, 0x0ff8, ! 59: 0x3ffe, 0x7fff, 0x7fff, 0x7fff}; ! 60: ! 61: /* The X display on which the window appears. */ ! 62: ! 63: static Display *screen_display; ! 64: ! 65: /* Windows manipulated by this package. */ ! 66: ! 67: static Widget main_widget; ! 68: static Widget containing_widget; ! 69: static Widget title_widget; ! 70: static Widget source_name_widget; ! 71: static Widget source_text_widget; ! 72: static Widget exec_name_widget; ! 73: static Widget button_box_widget; ! 74: ! 75: #ifdef VTFD ! 76: /* Interaction Window */ ! 77: ! 78: static Widget interactive_widget; ! 79: XtTextSource PseudoDiskSourceCreate(); ! 80: XtTextSource TSource; ! 81: static int vtfd[2], vifd[2]; ! 82: #endif ! 83: ! 84: /* Source text display. */ ! 85: ! 86: static struct symtab *source_window_symtab = 0; ! 87: ! 88: /* Forward declarations */ ! 89: ! 90: static Widget create_text_widget (); ! 91: ! 92: START_FILE ! 93: ! 94: /* Return number of text lines displayed in text widget W. */ ! 95: ! 96: int /* was XtTextPosition */ ! 97: XtTextLines (w) ! 98: Widget w; ! 99: { ! 100: TextWidget ctx = (TextWidget)w; ! 101: ! 102: return ctx->text.lt.lines; ! 103: } ! 104: ! 105: /* Display an appropriate piece of source code in the source window. */ ! 106: ! 107: xgdb_display_source () ! 108: { ! 109: char *filename; ! 110: Arg args[1]; ! 111: Arg labelArgs[1]; ! 112: int linenumbers_changed = 0; ! 113: int must_scroll = 0; ! 114: int height = XtTextLines (source_text_widget); ! 115: ! 116: struct symtab_and_line get_selected_frame_sal (); ! 117: struct symtab_and_line sal; ! 118: struct frame_info fi; ! 119: ! 120: /* Do nothing if called before we are initialized */ ! 121: ! 122: if (!containing_widget) return; ! 123: ! 124: /* Get the symtab and line number of the selected frame. */ ! 125: ! 126: fi = get_frame_info (selected_frame); ! 127: sal = find_pc_line (fi.pc, fi.next_frame); ! 128: ! 129: /* Strictly this is wrong, but better than a blank display */ ! 130: ! 131: if (sal.symtab == NULL) ! 132: { ! 133: sal.symtab = current_source_symtab; ! 134: /* current_source_line may be off by a small number like 4 */ ! 135: sal.line = current_source_line; ! 136: } ! 137: ! 138: /* Do a path search and get the exact filename of this source file. ! 139: Also scan it and find its source lines if not already done. */ ! 140: ! 141: if (sal.symtab) ! 142: linenumbers_changed = get_filename_and_charpos (sal.symtab, sal.line, ! 143: &filename); ! 144: ! 145: if (!filename) sal.symtab = NULL; ! 146: ! 147: /* If the source window may be wrong, destroy it (and make a new one). */ ! 148: ! 149: if (linenumbers_changed || source_window_symtab != sal.symtab) ! 150: { ! 151: Arg fileArgs[1]; ! 152: XtTextSource src; ! 153: ! 154: must_scroll = 1; ! 155: source_window_symtab = sal.symtab; ! 156: ! 157: src = XtTextGetSource (source_text_widget); ! 158: XtDiskSourceDestroy (src); ! 159: ! 160: XtSetArg (fileArgs[0], XtNfile, filename); ! 161: src = XtDiskSourceCreate (source_text_widget->core.parent, fileArgs, 1); ! 162: XtTextSetSource (source_text_widget, src, 0); ! 163: ! 164: XtSetArg (labelArgs[0], XtNlabel, ! 165: filename ? filename : "No source displayed."); ! 166: XtSetValues (source_name_widget, labelArgs, XtNumber (labelArgs)); ! 167: if (filename) free (filename); ! 168: } ! 169: ! 170: /* Update display and cursor positions as necessary. ! 171: Cursor should be placed on line sal.line. */ ! 172: ! 173: /* Find out where the display is positioned (in case user scrolled it). */ ! 174: ! 175: if (! must_scroll) ! 176: { ! 177: int top_line_number; ! 178: ! 179: XtSetArg (args[0], XtNdisplayPosition, NULL); ! 180: XtGetValues (source_text_widget, args, 1); ! 181: top_line_number = source_charpos_line (source_window_symtab, ! 182: (int) args[0].value); ! 183: /* If desired position is off screen, we must scroll. */ ! 184: if (sal.line < top_line_number ! 185: || sal.line >= top_line_number + height) ! 186: must_scroll = 1; ! 187: } ! 188: ! 189: /* If appropriate, scroll the text display. */ ! 190: ! 191: if (must_scroll) ! 192: { ! 193: int top_line_number = (sal.line > height/3) ? sal.line - height/3 : 1; ! 194: ! 195: XtSetArg (args[0], XtNdisplayPosition, ! 196: source_line_charpos (source_window_symtab, top_line_number)); ! 197: XtSetValues (source_text_widget, args, 1); ! 198: } ! 199: ! 200: /* Set the text display cursor position within the text. */ ! 201: ! 202: XtSetArg (args[0], XtNinsertPosition, ! 203: source_line_charpos (source_window_symtab, sal.line)); ! 204: XtSetValues (source_text_widget, args, 1); ! 205: } ! 206: ! 207: /* Display FILENAME in the title bar at bottom of window. */ ! 208: ! 209: xgdb_display_exec_file (filename) ! 210: char *filename; ! 211: { ! 212: static Arg labelArgs[1]; ! 213: ! 214: XtSetArg (labelArgs[0], XtNlabel, filename); ! 215: XtSetValues (exec_name_widget, labelArgs, XtNumber (labelArgs)); ! 216: } ! 217: ! 218: /* Do any necessary prompting, etc. */ ! 219: ! 220: static char *prompt_string; ! 221: ! 222: static void ! 223: print_prompt () ! 224: { ! 225: if (prompt_string) ! 226: { ! 227: printf ("%s", prompt_string); ! 228: fflush (stdout); ! 229: } ! 230: } ! 231: ! 232: /* Handlers for buttons. */ ! 233: ! 234: /* Subroutine used by "print" and "print*" buttons. ! 235: STARFLAG is 1 for print*, 0 for print. ! 236: Get the "selection" from X and use it as the operand of a print command. */ ! 237: ! 238: static void ! 239: print_button (w, starflag, call_data) ! 240: Widget w; ! 241: int starflag; ! 242: caddr_t call_data; ! 243: { ! 244: int selected_length; ! 245: char *selected_text; ! 246: char *cmd = starflag ? "print * " : "print "; ! 247: register int cmdlen = strlen (cmd); ! 248: ! 249: selected_text = XFetchBytes (screen_display, &selected_length); ! 250: if (selected_length) ! 251: { ! 252: char *line = xmalloc (cmdlen + selected_length + 1); ! 253: strcpy (line, cmd); ! 254: strncpy (line + cmdlen, selected_text, selected_length); ! 255: line[cmdlen + selected_length] = 0; ! 256: ! 257: execute_command (line, 0); ! 258: ! 259: free (selected_text); ! 260: free (line); ! 261: } ! 262: ! 263: print_prompt (); ! 264: } ! 265: ! 266: ! 267: /* Subroutine used by "stop at" and "go till" buttons. ! 268: Set a breakpoint at the position indicated by the "selection" ! 269: in the source window, and, if RUNFLAG is nonzero, continue. */ ! 270: ! 271: static void ! 272: breakpoint_button (w, runflag, call_data) ! 273: Widget w; ! 274: int runflag; ! 275: caddr_t call_data; ! 276: { ! 277: XtTextPosition start, finish; ! 278: ! 279: XtTextGetSelectionPos (source_text_widget, &start, &finish); ! 280: if (!source_window_symtab) ! 281: printf ("No source file displayed.\n"); ! 282: else ! 283: { ! 284: set_breakpoint (source_window_symtab, ! 285: source_charpos_line (source_window_symtab, start), ! 286: runflag); ! 287: if (runflag) ! 288: { ! 289: cont_command (0, 1); ! 290: xgdb_display_source (); ! 291: } ! 292: } ! 293: print_prompt (); ! 294: } ! 295: ! 296: /* decide if a character is trash */ ! 297: static int ! 298: garbage (c) ! 299: char c; ! 300: { ! 301: if ('a' <= c && c <= 'z') return 0; ! 302: if ('A' <= c && c <= 'Z') return 0; ! 303: if ('0' <= c && c <= '9') return 0; ! 304: if (c == '_') return 0; ! 305: return 1; ! 306: } ! 307: ! 308: /* Set a breakpoint at the place specified by the "selection" in X. */ ! 309: ! 310: static void ! 311: explicit_breakpoint_button () ! 312: { ! 313: int selected_length; ! 314: char *selected_text; ! 315: ! 316: selected_text = XFetchBytes (screen_display, &selected_length); ! 317: if (selected_length) ! 318: { ! 319: char *line = (char *) xmalloc (selected_length + 6); ! 320: register char *p, *sp, *end; ! 321: ! 322: strcpy (line, "break "); ! 323: ! 324: /* Copy selection but exclude "garbage" characters. */ ! 325: ! 326: p = selected_text; ! 327: end = p + selected_length; ! 328: sp = line + strlen (line); ! 329: ! 330: while (garbage (*p) && p != end) p++; ! 331: while (!garbage (*p) && p != end) ! 332: *sp++ = *p++; ! 333: *sp = 0; ! 334: ! 335: execute_command (line, 0); ! 336: free (selected_text); ! 337: free (line); ! 338: } ! 339: print_prompt (); ! 340: } ! 341: ! 342: /* Handle a button by running the command COMMAND. */ ! 343: ! 344: static void ! 345: do_command (w, command, call_data) ! 346: Widget w; ! 347: char *command; ! 348: caddr_t call_data; ! 349: { ! 350: execute_command (command, 0); ! 351: xgdb_display_source (); ! 352: print_prompt (); ! 353: } ! 354: ! 355: static void ! 356: redisplay_button() ! 357: { ! 358: xgdb_display_source(); ! 359: } ! 360: ! 361: /* Define and display all the buttons. */ ! 362: ! 363: static void ! 364: addbutton (parent, name, function, closure) ! 365: Widget parent; ! 366: char *name; ! 367: void (*function) (); ! 368: caddr_t closure; ! 369: { ! 370: static XtCallbackRec Callback[] = ! 371: { ! 372: {NULL, (caddr_t)NULL}, ! 373: {NULL, (caddr_t)NULL}, ! 374: }; ! 375: static Arg commandArgs[] = ! 376: { ! 377: {XtNlabel, (XtArgVal)NULL}, ! 378: {XtNcallback, (XtArgVal)Callback}, ! 379: }; ! 380: ! 381: Callback[0].callback = (XtCallbackProc)function; ! 382: Callback[0].closure = (caddr_t)closure; ! 383: commandArgs[0].value = (XtArgVal)name; ! 384: XtCreateManagedWidget (name, commandWidgetClass, parent, ! 385: commandArgs, XtNumber(commandArgs)); ! 386: } ! 387: ! 388: /* Create the button windows and store them in `buttons'. */ ! 389: ! 390: static void ! 391: create_buttons (parent) ! 392: Widget parent; ! 393: { ! 394: addbutton (parent, "run", do_command, "run"); ! 395: addbutton (parent, "quit", do_command, "quit"); ! 396: ! 397: addbutton (parent, "break in", explicit_breakpoint_button, NULL); ! 398: addbutton (parent, "break at", breakpoint_button, 0); ! 399: addbutton (parent, "go until", breakpoint_button, 1); ! 400: ! 401: addbutton (parent, "print", print_button, 0); ! 402: addbutton (parent, "print*", print_button, 1); ! 403: ! 404: addbutton (parent, "next", do_command, "next"); ! 405: addbutton (parent, "step", do_command, "step"); ! 406: addbutton (parent, "cont", do_command, "cont"); ! 407: addbutton (parent, "finish", do_command, "finish"); ! 408: ! 409: addbutton (parent, "up", do_command, "up"); ! 410: addbutton (parent, "down", do_command, "down"); ! 411: ! 412: addbutton (parent, "redisplay", redisplay_button, NULL); ! 413: } ! 414: ! 415: /* Create a "label window" that just displays the string LABEL. */ ! 416: ! 417: static Widget ! 418: create_label (name, label) ! 419: char *name, *label; ! 420: { ! 421: Arg labelArgs[2]; ! 422: Widget w; ! 423: ! 424: XtSetArg (labelArgs[0], XtNname, name); ! 425: XtSetArg (labelArgs[1], XtNlabel, label); ! 426: ! 427: w = XtCreateManagedWidget ("label", labelWidgetClass, containing_widget, ! 428: labelArgs, XtNumber (labelArgs)); ! 429: XtPanedSetMinMax (w, w->core.height, w->core.height); ! 430: return w; ! 431: } ! 432: ! 433: /* Create a subwindow of PARENT that displays and scrolls the contents ! 434: of file FILENAME. */ ! 435: ! 436: static Widget ! 437: create_text_widget (parent, filename) ! 438: Widget parent; ! 439: char *filename; ! 440: { ! 441: static Arg fileArgs[3]; ! 442: XtTextSource src; ! 443: XtTextSink sink; ! 444: ! 445: XtSetArg (fileArgs[0], XtNfile, filename); ! 446: src = XtDiskSourceCreate(parent, fileArgs, 1); ! 447: sink = XtAsciiSinkCreate(parent, NULL, 0); ! 448: ! 449: XtSetArg (fileArgs[0], XtNtextOptions, scrollVertical); ! 450: XtSetArg (fileArgs[1], XtNtextSource, src); ! 451: XtSetArg (fileArgs[2], XtNtextSink, sink); ! 452: return XtCreateManagedWidget ("disk", textWidgetClass, parent, ! 453: fileArgs, XtNumber (fileArgs)); ! 454: ! 455: #if 0 /* This is tucker's method. */ ! 456: ! 457: /* Create an empty source-display window and add to containing_widget */ ! 458: XtSetArg (argl[0], XtNfile, "/dev/null"); ! 459: XtSetArg (argl[1], XtNtextOptions, scrollVertical); ! 460: XtSetArg (argl[2], XtNheight, (XtArgVal)sheight); ! 461: source_text_widget = XtCreateManagedWidget (NULL, asciiDiskWidgetClass, ! 462: containing_widget, argl, ! 463: XtNumber (argl)); ! 464: ! 465: /* Create NULL disk source */ ! 466: XtSetArg (argl[0], XtNfile, "/dev/null"); ! 467: NullSource = XtDiskSourceCreate (source_text_widget, argl, ONE); ! 468: #endif ! 469: } ! 470: ! 471: /* window manager argument parsing */ ! 472: extern int *win_argc; ! 473: extern char **win_argv; ! 474: ! 475: /* Entry point to create the widgets representing our display. */ ! 476: int ! 477: xgdb_create_window () ! 478: { ! 479: int width, height; ! 480: int sheight; ! 481: Arg argl[3]; ! 482: ! 483: /* initialize toolkit, setup defaults */ ! 484: main_widget = XtInitialize ("gdb", "gdb", NULL, 0, win_argc, win_argv); ! 485: screen_display = XtDisplay (main_widget); ! 486: ! 487: /* Find out what size the user specified. */ ! 488: ! 489: XtSetArg (argl[0], XtNwidth, (XtArgVal)&width); ! 490: XtSetArg (argl[1], XtNheight, (XtArgVal)&height); ! 491: XtGetValues (main_widget, argl, XtNumber(argl)); ! 492: ! 493: /* If none specified, set a default size. */ ! 494: ! 495: if (!width || !height) ! 496: { ! 497: width = 500, height = 700; ! 498: XtSetArg (argl[0], XtNwidth, (XtArgVal)width); ! 499: XtSetArg (argl[1], XtNheight, (XtArgVal)height); ! 500: XtSetValues (main_widget, argl, XtNumber(argl)); ! 501: } ! 502: sheight = (float)height / 2.5; ! 503: ! 504: /* Create the (toplevel) main_widget */ ! 505: XtSetArg (argl[0], XtNwidth, (XtArgVal)width); ! 506: XtSetArg (argl[1], XtNheight, (XtArgVal)height); ! 507: containing_widget ! 508: = XtCreateManagedWidget ("vpaned", vPanedWidgetClass, ! 509: main_widget, argl, XtNumber (argl)); ! 510: XtPanedSetRefigureMode (containing_widget, FALSE); ! 511: ! 512: /* Create title */ ! 513: { ! 514: char buf[200]; ! 515: extern char *version; ! 516: sprintf (buf, "GDB %s", version); ! 517: title_widget = ! 518: create_label ("Title", buf); ! 519: } ! 520: ! 521: /* Create exec file name window and add */ ! 522: exec_name_widget = ! 523: create_label ("Executable", "No executable specified"); ! 524: ! 525: /* Create window full of buttons. */ ! 526: button_box_widget = XtCreateManagedWidget ("buttons", boxWidgetClass, ! 527: containing_widget, NULL, 0); ! 528: create_buttons (button_box_widget); ! 529: ! 530: /* Create source file name window and add to containing_widget */ ! 531: source_name_widget = ! 532: create_label ("Source File", "No source file yet."); ! 533: ! 534: /* Create an empty source-display window and add to containing_widget */ ! 535: source_text_widget = create_text_widget (containing_widget, "/dev/null"); ! 536: ! 537: #ifdef VFTD ! 538: /* Create Fake Text source */ ! 539: { ! 540: extern XtTextSource TCreateApAsSource(); ! 541: TSource = TCreateApAsSource(); ! 542: } ! 543: ! 544: /* Create interactive box */ ! 545: XtSetArg (argl[0], XtNtextSource, (XtArgVal)TSource); ! 546: XtSetArg (argl[1], XtNtextSink, ! 547: (XtArgVal)XtAsciiSinkCreate(containing_widget, NULL, 0)); ! 548: XtSetArg (argl[2], XtNtextOptions, ! 549: (XtArgVal)(scrollVertical | wordBreak)); ! 550: interactive_widget = XtCreateManagedWidget ("gdbWindow", textWidgetClass, ! 551: containing_widget, argl, THREE); ! 552: #endif ! 553: ! 554: /* Put them one screen */ ! 555: XtPanedSetRefigureMode(containing_widget, TRUE); ! 556: XtRealizeWidget (main_widget); ! 557: ! 558: /* Define GDB cursor */ ! 559: #if 0 ! 560: XDefineCursor (screen_display, XtWindow (main_widget), ! 561: XCreateFontCursor (screen_display, XC_circle)); ! 562: #endif ! 563: ! 564: XFlush (screen_display); ! 565: return 1; ! 566: } ! 567: ! 568: #define MAX_XGDB_READ 128 ! 569: ! 570: /* xgdb_dispatch -- Loop, dispatching on window events, ! 571: until data is available on FP (which is normally stdin). ! 572: Then return, so the data on FP can be processed. */ ! 573: ! 574: void ! 575: xgdb_dispatch (fp) ! 576: FILE *fp; ! 577: { ! 578: int inmask = 1 << fileno (fp); ! 579: int xmask = 1 << ConnectionNumber (screen_display); ! 580: int rfds = 0; ! 581: int nfds; ! 582: XEvent ev; ! 583: int pend; ! 584: int nread; ! 585: char buf[1024]; ! 586: int ipmask; ! 587: ! 588: #ifdef VTFD ! 589: ipmask = 1 << vtfd[0]; ! 590: #endif ! 591: ! 592: while (! (rfds & inmask)) ! 593: { ! 594: pend = XPending (screen_display); ! 595: if (!pend) ! 596: { ! 597: rfds = inmask | xmask | ipmask; ! 598: /* this isn't right for 4.3 but it works 'cuz of 4.2 compatibility */ ! 599: nfds = select (32, &rfds, 0, 0, (struct timeval *) 0); ! 600: } ! 601: if (pend || rfds & xmask) ! 602: { ! 603: XNextEvent (screen_display, &ev); ! 604: XtDispatchEvent (&ev); ! 605: } ! 606: ! 607: #ifdef VTFD ! 608: /* Handle I/O through the command window. */ ! 609: if (pend == 0 && (rfds & ipmask)) ! 610: { ! 611: nread = read (vtfd[0], buf, sizeof(buf)); ! 612: xgdb_write (buf, nread); ! 613: } ! 614: nread = xgdb_read (buf, MAX_XGDB_READ); ! 615: if (pend == 0 && nread > 0) ! 616: { ! 617: write (vifd[1], buf, nread); ! 618: } ! 619: #endif ! 620: } ! 621: } ! 622: ! 623: #ifdef VTFD ! 624: ! 625: static int output_size; ! 626: static int used_size; ! 627: static char *output_string; ! 628: ! 629: static void ! 630: xgdb_init_text () ! 631: { ! 632: Arg args[2]; ! 633: ! 634: output_size = 1000; ! 635: output_string = (char *) xmalloc (output_size); ! 636: used_size = 0; ! 637: ! 638: XtSetArg (args[0], XtNstring, (XtArgVal) output_string); ! 639: XtSetArg (args[1], XtNlength, (XtArgVal) output_size); ! 640: TSource ! 641: = XtStringSourceCreate (toplevel, args, 2); ! 642: ! 643: XtSetArg (args[0], XtNtextSource, TSource); ! 644: XtSetValues (interaction_widget, Args, 1); ! 645: } ! 646: ! 647: static void ! 648: xgdb_grow_text (size) ! 649: int size; ! 650: { ! 651: if (output_size < used_size + size + 200) ! 652: { ! 653: Arg args[2]; ! 654: ! 655: XtStringSourceDestroy (TSource); ! 656: ! 657: output_size = (used_size + size + 1010 + 512) / 1010 * 1010; ! 658: output_string = xrealloc (output_string, output_size); ! 659: ! 660: XtSetArg (args[0], XtNstring, (XtArgVal) output_string); ! 661: XtSetArg (args[1], XtNlength, (XtArgVal) output_size); ! 662: TSource ! 663: = XtStringSourceCreate (toplevel, args, 2); ! 664: ! 665: XtSetArg (args[0], XtNtextSource, TSource); ! 666: XtSetValues (interaction_widget, Args, 1); ! 667: } ! 668: } ! 669: ! 670: /*VARARGS*/ ! 671: xgdb_printf (fmt, arg1, arg2, arg3, arg4) ! 672: char *fmt; ! 673: { ! 674: char buf[1024]; ! 675: XtTextBlock text; ! 676: XtTextPosition pos; ! 677: ! 678: /* ??? This will crash on the wrong data. */ ! 679: pos = (*TSource->Scan)(TSource, 0, XtstAll, XtsdRight, 1, 0); ! 680: sprintf (buf, fmt, arg1, arg2, arg3, arg4); ! 681: text.length = strlen (buf); ! 682: text.ptr = buf; ! 683: xgdb_grow_text (text.length); ! 684: used_size += text.length; ! 685: XtTextReplace (interactive_widget, pos, pos, &text); ! 686: XtTextSetInsertionPoint (interactive_widget, pos + text.length); ! 687: XFlush (screen_display); ! 688: } ! 689: ! 690: int ! 691: xgdb_write (buf, len) ! 692: char *buf; ! 693: int len; ! 694: { ! 695: XtTextBlock text; ! 696: XtTextPosition pos; ! 697: ! 698: pos = (*TSource->Scan)(TSource, 0, XtstAll, XtsdRight, 1, 0); ! 699: text.length = len; ! 700: text.ptr = buf; ! 701: xgdb_grow_text (text.length); ! 702: used_size += text.length; ! 703: XtTextReplace (interactive_widget, pos, pos, &text); ! 704: XtTextSetInsertionPoint (interactive_widget, pos + text.length); ! 705: XFlush (screen_display); ! 706: } ! 707: ! 708: int ! 709: xgdb_read (buf, maxlen) ! 710: char *buf; ! 711: int maxlen; ! 712: { ! 713: XtTextBlock text; ! 714: XtTextPosition endpos; ! 715: int length = 0; ! 716: ! 717: xgdb_grow_text (maxlen); ! 718: endpos = XtTextGetInsertionPoint (interactive_widget); ! 719: length = endpos - used_size; ! 720: if (length > 0) ! 721: { ! 722: (*TSource->Read) (TSource, lastpos, &text, maxlen - 10); ! 723: length = text.length; ! 724: strncpy(buf, text.ptr, length); ! 725: buf[length] = NULL; ! 726: used_size += length; ! 727: } ! 728: return length; ! 729: } ! 730: #endif /* VTFD */ ! 731: ! 732: /* If we use an X window, the GDB command loop is told to call this function ! 733: before reading a command from stdin. ! 734: PROMPT is saved for later use so buttons can print a prompt-string. */ ! 735: ! 736: void ! 737: xgdb_window_hook (infile, prompt) ! 738: FILE *infile; ! 739: char *prompt; ! 740: { ! 741: prompt_string = prompt; ! 742: xgdb_display_source (); ! 743: xgdb_dispatch (infile); ! 744: } ! 745: ! 746: static ! 747: initialize () ! 748: { ! 749: extern void (*window_hook) (); ! 750: extern int inhibit_windows; ! 751: ! 752: if (getenv ("DISPLAY") && ! inhibit_windows) ! 753: if (xgdb_create_window ()) ! 754: window_hook = xgdb_window_hook; ! 755: ! 756: specify_exec_file_hook (xgdb_display_exec_file); ! 757: } ! 758: ! 759: END_FILE ! 760:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.