/* SCCS-info %W% %E% */ /*--------------------------------------------------------------------*/ /* */ /* VCG : Visualization of Compiler Graphs */ /* -------------------------------------- */ /* */ /* file: X11devfe.c */ /* version: 1.00.00 */ /* creation: 29.12.94 */ /* author: I. Lemke (...-Version 0.99.99) */ /* G. Sander (Version 1.00.00-...) */ /* Universitaet des Saarlandes, 66041 Saarbruecken */ /* ESPRIT Project #5399 Compare */ /* description: Follow Edge and Edge History Dialog Box */ /* status: in work */ /* */ /*--------------------------------------------------------------------*/ #ifndef lint static char *id_string="$Id: X11devfe.c,v 1.2 1995/02/08 18:38:09 sander Exp $"; #endif /* * Copyright (C) 1993-2005 Saarland University * * This program and documentation is free software; you can redistribute * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * The software is available per anonymous ftp at ftp.cs.uni-sb.de. * Contact sander@cs.uni-sb.de for additional information. */ /* * $Log: X11devfe.c,v $ * Revision 1.2 1995/02/08 18:38:09 sander * Small bug for K&R C solved. * * Revision 1.1 1995/02/08 11:11:14 sander * Initial revision * */ /************************************************************************ * Device driver for X11: Follow Edge Management and History Dialog Box * -------------------------------------------------------------------- * * This module contains the management of the dialog box that appears * if we want to select a node from the follow edge history. * * This file provides the following functions: * ------------------------------------------ * * x11_init_fedge_dialog(rd,rs) initialize the dialogbox. * x11_destroy_fedge_dialog(rd,rs) destroys the dialogbox. * * x11_print_fedge_dialog() * * This function opens the dialog box that allows to enter the * title of a node to be centered. Alternatively, we can also * look at the label, etc. * ************************************************************************/ #include #include #include #include "globals.h" #ifdef X11 #include #include #include #include #include #include #include #include "main.h" #include "options.h" #include "grammar.h" #include "alloc.h" #include "steps.h" #include "X11devfe.h" /*--------------------------------------------------------------------*/ #undef EVENT_DEBUG /* Types * ===== */ /* Selection points: On/Off-Buttons, Radio/Buttons, Touch Buttons * Radio-Buttons are On-buttons, i.e. they don't go off, if we retouch * them. Further, all radio buttons of one section have the same glob. */ typedef struct gs_selection_point { Window w; /* Window of the point */ char *t; /* Text of the point */ int x; /* X-Position */ int y; /* Y-Position */ int is; /* actual value */ int sel; /* value, if the point is selected */ int *glob; /* corresponding global value */ char key; /* key action */ } GS_SEL_POINT; /* Horizontal integer scroll bars */ typedef struct gs_scroll_bar { Window ws; /* Window of the bar itself */ Window wt; /* Window of the scroll thumb */ char *t; /* Text of the scroll bar */ char *f; /* Format of the value */ int yt; /* Y-Position of the text */ int yv; /* Y-Position of the value */ int yb; /* Y-Position of the bar */ int x; /* X-Position */ int len; /* Length of scrollbar */ int is; /* actual value */ int *glob; /* corresponding global value */ #ifdef ANSI_C void (*rf)(int); /* read function */ void (*sf)(void); /* set function */ #else void (*rf)(); void (*sf)(); #endif } GS_SCROLL_BAR; /* Prototypes * ========== */ /* from X11dev.c */ void gs_exit _PP((int x)); void do_gblExpose _PP((XEvent *eventp)); void do_gblConfigureNotify _PP((XEvent *eventp)); void set_act_follow_node _PP((GNODE v,int i)); void set_next_follow_edge _PP((void)); void do_act_follow_edge _PP((void)); extern int act_follow_edge_visible; static void allocateDialogBox _PP((void)); static Window allocate_selection_point _PP((int x,int y)); static Window allocate_button _PP((int x,int y)); static Window allocate_general_button _PP((int x,int y,int w,int h)); static Window allocate_scroll_bar _PP((int x,int y,int len)); static void draw_dialog_box _PP((void)); static void draw_text _PP(( int x, int y, char *m)); static void draw_underl_text _PP(( int x, int y, char *m)); static void draw_dialog_point _PP((Window w, int color)); static void draw_sizes _PP((void)); static void draw_textwin _PP((void)); static void normalize_point _PP((Window w)); #ifdef EVENT_DEBUG static void prologue _PP((XEvent *eventp, char *event_name)); #else #define prologue(a,b) #endif static void dialog_main_loop _PP((void)); static void do_KeyPress _PP((XEvent *eventp)); static void do_ButtonPress _PP((XEvent *eventp)); static void do_ButtonRelease _PP((XEvent *eventp)); static void do_EnterNotify _PP((XEvent *eventp)); static void do_LeaveNotify _PP((XEvent *eventp)); static void do_Expose _PP((XEvent *eventp)); static void do_ConfigureNotify _PP((XEvent *eventp)); static void do_MotionNotify _PP((XEvent *eventp)); static void read_fedge_scrollbar _PP((int val)); static void set_fedge_scrollbar _PP((void)); /* Positions and Sizes * =================== */ /* Size of a normal point */ #define POINT_W 10 /* Size of a normal button */ #define BUTTON_W 130 /* Sizes of a scrollbar and its thumb */ #define SCROLL_W 250 #define SCROLLBAR_LEN 20 /* Sizes of the scroll window */ #define SCROLLW_W 350 #define SCROLLW_H SCROLL_W /* Positions of the radio points */ #define SEL_POS SCROLLW_W+35 /* Position of the input text */ #define TEXT_POS 55+SCROLLW_H /* Size of the dialog box */ #define DIAL_W 530 #define DIAL_H TEXT_POS+10 /* Variables * ========= */ #define MAXHISTORY 50 static GNODE fedge_history[MAXHISTORY]; static int fedge_top = 0; static int fedge_pos; /* Dialog handling: On success (i.e. Okay-Button), success becomes 1 */ static int dialog_notready = 1; static GNODE act_node; static char act_title[256]; static int act_selection = 0; /* Radio buttons are partitioned into those that have the same global * variable. If a radio-button is selected, all other radio buttons * of the same partition became unselected. */ static int sel_mode = 0; #define MAX_RADIO_POINTS 5 static GS_SEL_POINT radio_point[MAX_RADIO_POINTS] = { /* window, text , xpos, ypos, isval, selval , globvar , key */ { 0 , "title" , SEL_POS, 41, 0, 0 , &sel_mode , 't' }, { 0 , "label" , SEL_POS, 59, 0, 1 , &sel_mode , 'l' }, { 0 , "info field 1" , SEL_POS, 77, 0, 2 , &sel_mode , '1' }, { 0 , "info_field 2" , SEL_POS, 95, 0, 3 , &sel_mode , '2' }, { 0 , "info field 3" , SEL_POS, 113, 0, 4 , &sel_mode , '3' } }; /* Horizontal integer scrollbars are used to change a value by the read and * set functions. Here, these values must be integer values. */ static int my_scroll_val = 0; #define MAX_VSCROLLBARS 1 #ifdef ANSI_C static GS_SCROLL_BAR vscrollbar[MAX_VSCROLLBARS] = { { 0, 0, "" ,"", 27 , 27, 27, SCROLLW_W+5, SCROLL_W, 0, &my_scroll_val , &read_fedge_scrollbar, &set_fedge_scrollbar } }; #else static GS_SCROLL_BAR vscrollbar[MAX_VSCROLLBARS] = { { 0, 0, "" ,"", 27 , 27, 27, SCROLLW_W+5, SCROLL_W, 0, &my_scroll_val , read_fedge_scrollbar, set_fedge_scrollbar } }; #endif /* Root displays */ static Display *root_display; /* Root display */ static int root_screen; /* and its screen number */ /* Windows */ static Window dialog_window; static Window scroll_show_window; static Window text_window; static Window snode_button; static Window nedge_button; static Window fedge_button; static Window cancel_button; static Window next_button; static Window prev_button; /* Cursors */ static Cursor scrollCursor; /* Mouse Buttons */ #define G_MOUSE_LEFT 1 #define G_MOUSE_RIGHT 3 /* the panel font */ extern char Xfontname[512]; static XFontStruct *dialog_font = NULL; /* Flag wheter the dialog_box is initialized */ static int dialog_box_there = 0; /*--------------------------------------------------------------------*/ /* Follow Edge Operations */ /*--------------------------------------------------------------------*/ #ifdef ANSI_C static void do_follow_node(GNODE v) #else static void do_follow_node(v) GNODE v; #endif { GEDGE afe; XEvent event; int notready; int x,y,width,height; int i; if (!v) return; set_act_follow_node(v,2); act_selection = 0; fedge_pos = 0; set_fedge_scrollbar(); draw_sizes(); } #ifdef ANSI_C static void do_next_follow_edge(void) #else static void do_next_follow_edge() #endif { set_next_follow_edge(); } #ifdef ANSI_C static void do_apply_follow_edge(void) #else static void do_apply_follow_edge() #endif { do_act_follow_edge(); act_selection = 0; fedge_pos = 0; set_fedge_scrollbar(); draw_sizes(); } /*--------------------------------------------------------------------*/ /* History Management functions */ /*--------------------------------------------------------------------*/ /* Initialize the history * ---------------------- */ #ifdef ANSI_C void init_fedge_history(void) #else void init_fedge_history() #endif { fedge_top = 0; } /* Add a node to the top of the history * ------------------------------------ */ #ifdef ANSI_C void add_fedge_history(GNODE v) #else void add_fedge_history(v) GNODE v; #endif { int i; for (i=MAXHISTORY-1; i>0; i--) fedge_history[i] = fedge_history[i-1]; fedge_history[0] = v; fedge_top++; if (fedge_top > MAXHISTORY) fedge_top = MAXHISTORY; } /*--------------------------------------------------------------------*/ /* Dialog box initialization and entry points */ /*--------------------------------------------------------------------*/ static Window myframe_win; static Window mypix_win; /* Initialize the dialog box * ------------------------- * This is done once at the beginning. */ #ifdef ANSI_C void x11_init_fedge_dialog(Display *rd, int rs, Window mf, Window mp) #else void x11_init_fedge_dialog(rd, rs, mf, mp) Display *rd; int rs; Window mf; Window mp; #endif { if (dialog_box_there) return; myframe_win = mf; mypix_win = mp; root_display = rd; root_screen = rs; dialog_font = XLoadQueryFont(root_display,Xfontname); if (!dialog_font) { Fatal_error("Font not found. Please use option -font",""); } allocateDialogBox(); dialog_box_there = 1; } /* Destroy the dialog box * ---------------------- * This is done once on ExitDevice. */ #ifdef ANSI_C void x11_destroy_fedge_dialog(Display *rd, int rs) #else void x11_destroy_fedge_dialog(rd, rs) Display *rd; int rs; #endif { if (!dialog_box_there) return; XDestroyWindow(root_display,dialog_window); dialog_box_there = 0; } /* Allocate the Dialog Box * ----------------------- * Scrollbar-Thumbs are returned in last_tmb; */ static Window last_tmb; static char x11_win_label[1024]; #ifdef ANSI_C static void allocateDialogBox(void) #else static void allocateDialogBox() #endif { Window rret1, rret2; XSetWindowAttributes attr; unsigned long mask = 0L; int i; unsigned int j; int xpos, ypos; XSizeHints hints; /* select for all events */ attr.event_mask = KeyPressMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | ExposureMask | StructureNotifyMask | SubstructureNotifyMask | FocusChangeMask | OwnerGrabButtonMask; attr.background_pixel = XWhitePixel(root_display,root_screen); attr.border_pixel = XBlackPixel(root_display,root_screen); mask |= (CWBackPixel | CWBorderPixel | CWEventMask); (void)XQueryPointer(root_display,RootWindow(root_display, root_screen), &rret1, &rret2,&xpos, &ypos, &i, &i, &j); dialog_window = XCreateWindow(root_display, RootWindow(root_display, root_screen), xpos, ypos, DIAL_W, DIAL_H, Xmyborderwidth, (int)CopyFromParent, InputOutput, (Visual *)CopyFromParent, mask, &attr); hints.flags = PPosition; hints.x = xpos; hints.y = ypos; strcpy(x11_win_label, "VCG "); strcat(x11_win_label, Dataname); strcat(x11_win_label, " FEdge"); XStoreName(root_display, dialog_window, x11_win_label); XSetNormalHints(root_display, dialog_window, &hints); text_window = XCreateWindow(root_display, dialog_window, 5, TEXT_POS-22, DIAL_W-10, 25, 1, (int)CopyFromParent, InputOutput, (Visual *)CopyFromParent, mask, &attr); scroll_show_window = XCreateWindow(root_display, dialog_window, 5, 27, SCROLLW_W, SCROLLW_H, 1, (int)CopyFromParent, InputOutput, (Visual *)CopyFromParent, mask, &attr); XDefineCursor(root_display,text_window, XCreateFontCursor(root_display,XC_xterm)); XDefineCursor(root_display,dialog_window, XCreateFontCursor(root_display,XC_left_ptr)); scrollCursor = XCreateFontCursor(root_display,XC_sb_v_double_arrow); for (i=0; i=fedge_top) act_selection = fedge_top-1-fedge_pos; if (act_selection<0) act_selection = 0; if (act_selection>SCROLLW_H/18) act_selection = SCROLLW_H/18; for (i=0; i<(SCROLLW_H/18+1); i++) { if (fedge_pos+iserial, e->send_event ? "Yes" : "No", e->window); } #endif /* EVENT_DEBUG */ /* Keypress Events * --------------- */ #ifdef ANSI_C static void do_KeyPress (XEvent *eventp) #else static void do_KeyPress (eventp) XEvent *eventp; #endif { XKeyEvent *e = (XKeyEvent *) eventp; KeySym ks; int nbytes, i, j, old_sel_mode; char str[256+1]; char lk, uk; old_sel_mode = sel_mode; nbytes = XLookupString (e, str, 256, &ks, NULL); if (nbytes < 0) nbytes = 0; if (nbytes > 256) nbytes = 256; str[nbytes] = '\0'; if (ks==0xff54) { /* Down */ if (vscrollbar[0].is0) vscrollbar[0].is--; else act_selection--; set_fedge_scrollbar(); draw_sizes(); return; } else if (ks==0xff51) { /* Left */ if (vscrollbar[0].is>0) vscrollbar[0].is--; else act_selection--; set_fedge_scrollbar(); draw_sizes(); return; } if (nbytes==1) { if (e->window == text_window) { i = 0; while ((act_title[i]) && (i<253)) i++; if (act_title[i-1]=='_') i--; act_title[i]=0; XSetForeground(root_display, XDefaultGC(root_display, root_screen), XWhitePixel(root_display, root_screen)); XFillRectangle(root_display, (Drawable)text_window, XDefaultGC(root_display, root_screen), 5+XTextWidth(dialog_font,act_title,strlen(act_title)), 0, DIAL_W, 25); if ((ks==0xff08)||(ks==0xffff)) { i--; if (i<13) i=13; act_title[i]=0; } else if ((ks==0xff0a)||(ks==0xff0d)) { dialog_notready = 0; i=0; while ((act_title[i]) && (i<253)) i++; if (act_title[i-1]=='_') i--; act_title[i]=0; act_node = search_visible_node(&(act_title[13])); do_follow_node(act_node); return; } else if (str[0]==27) { dialog_notready = 0; } else { /* assert((i<=253)); */ act_title[i] = str[0]; act_title[i+1]= 0; } act_title[255] = 0; draw_textwin(); return; } /* No operation on ' ' */ if (str[0]==' ') return; for (i=0; i0) vscrollbar[0].is--; else act_selection--; set_fedge_scrollbar(); draw_sizes(); return; case '*' : case '+' : case 'n' : case 'N' : if (vscrollbar[0].iswindow; act_scroll_window = w; old_sel_mode = sel_mode; for (i=0; iy); draw_sizes(); } } if (w==nedge_button) { do_next_follow_edge(); } else if (w==fedge_button) { do_apply_follow_edge(); } else if (w==cancel_button) { dialog_notready = 0; } else if (w==snode_button) { i=0; while ((act_title[i]) && (i<253)) i++; if (act_title[i-1]=='_') i--; act_title[i]=0; act_node = search_visible_node(&(act_title[13])); do_follow_node(act_node); } else if (w==next_button) { if (vscrollbar[0].is0) vscrollbar[0].is--; else act_selection--; set_fedge_scrollbar(); draw_sizes(); } else if (w==scroll_show_window) { act_selection = (e->y)/18; draw_sizes(); } else if ((w==myframe_win) || (w==mypix_win)) { if (e->button==G_MOUSE_LEFT) { do_next_follow_edge(); } if (e->button==G_MOUSE_RIGHT) { if (!act_follow_edge_visible) dialog_notready = 0; else do_apply_follow_edge(); } } } /* Button Release * -------------- */ #ifdef ANSI_C static void do_ButtonRelease (XEvent *eventp) #else static void do_ButtonRelease (eventp) XEvent *eventp; #endif { XButtonEvent *e = (XButtonEvent *) eventp; int i; if (act_scroll_window && (e->window!=act_scroll_window)) { for (i=0; iy); break; } } if (iwindow; for (i=0; iwindow; for (i=0; iwindow==dialog_window) { if ((e->width>12)&&(e->height>12)&&(!box_exposed)) { draw_dialog_box(); box_exposed = 1; } } else box_exposed = 0; do_gblExpose(eventp); } /* Resize or move a window * ----------------------- */ #ifdef ANSI_C static void do_ConfigureNotify (XEvent *eventp) #else static void do_ConfigureNotify (eventp) XEvent *eventp; #endif { XConfigureEvent *e = (XConfigureEvent *) eventp; if (e->window==dialog_window) { XResizeWindow(root_display,dialog_window,DIAL_W,DIAL_H); draw_dialog_box(); } else do_gblConfigureNotify(eventp); } /* Motion with pressed button * -------------------------- */ #ifdef ANSI_C static void do_MotionNotify (XEvent *eventp) #else static void do_MotionNotify (eventp) XEvent *eventp; #endif { int i; XMotionEvent *e = (XMotionEvent *) eventp; for (i=0; iy); break; } } if (i= vscrollbar[0].len) val = vscrollbar[0].len - SCROLLBAR_LEN; XMoveResizeWindow(root_display,vscrollbar[0].wt,0,val,6,SCROLLBAR_LEN); vscrollbar[0].is = fedge_top*val/(vscrollbar[0].len-SCROLLBAR_LEN); } #ifdef ANSI_C static void set_fedge_scrollbar(void) #else static void set_fedge_scrollbar() #endif { int val; val = (vscrollbar[0].is)*(vscrollbar[0].len-SCROLLBAR_LEN)/fedge_top; if (val<0) val = 0; if (val+SCROLLBAR_LEN >= vscrollbar[0].len) val = vscrollbar[0].len - SCROLLBAR_LEN; XMoveResizeWindow(root_display, vscrollbar[0].wt,0,val,6,SCROLLBAR_LEN); } /*--------------------------------------------------------------------*/ #endif /* X11 */