📄 xmenus.c
字号:
/* Copyright (c) 1995 Entropic Research Laboratory, Inc. *//* Copyright (c) 1987 through 1993 AT&T, *//* Entropic Speech, Inc., and *//* Entropic Research Laboratory, Inc. *//* All Rights Reserved. *//* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T *//* AND ENTROPIC RESEARCH LABORATORY, INC. *//* The copyright notice above does not evidence any *//* actual or intended publication of such source code. *//* xmenus.c *//* Use walking menus to change button operation modes. Implement menu choice vectoring in a general way. A linked list of menu text items and associated operations is set up (and possibly dynamically modified). When the "mode switch" is pulled right, a menu is generated based on this list and vectoring to the function appropriate for the mode is implemented by setting the menu item value to the function pointer. Each function has the form of a window event proc. */#ifndef lintstatic char *sccs_id = "@(#)xmenus.c 1.14 11/13/95 ATT/ERL";#endif#include <Objects.h>#include <xview/font.h>#include <esps/unix.h>#include <esps/limits.h>#define SINGLE_HIT if(((event_id(event) == LOC_MOVE)||event_is_down(event)) && (event_id(event) != LOC_DRAG))char *savestring();extern char *checking_selectors();#define CHECK_QUERY(a,b) { char *cret; if((cret = checking_selectors(a,b))) return(cret); }extern Menuop *spect_get_ops();Event *last_event;int run_esps_prog();void markers_to_common(), menu_operate();extern double ref_size;extern Signal *get_playable_signal();extern int write_common; /* in globals.c */extern int menu_item_key; /* key for storing last selected menu item as XV_KEY_DATA for canvas. */extern Menu wave_menu, spect_menu;Menu w_button_submenu, s_button_submenu;static struct named_menu {char *name; Menu *menu; struct named_menu *submenus;} w_menl[] = {{NULL, &w_button_submenu, NULL}, {NULL, NULL, NULL}}, s_menl[] = {{NULL, &s_button_submenu, NULL}, {NULL, NULL, NULL}}, menl[] = {{"wave", &wave_menu, w_menl}, {"spect", &spect_menu, s_menl}, {NULL, NULL, NULL}};extern int w_verbose, debug_level; void e_play_between_marks(), e_play_window(), e_play_file(), e_play_from_cursor(), e_page_ahead(), e_page_back(), e_align_views(), e_position_view(), e_zoom_in(), e_zoom_out(), e_wb_spectrogram(), e_nb_spectrogram(), e_output_bitmap(), e_save_segment(), e_delete_segment(), e_insert_file(), e_kill(), e_forward_window(), e_backward_window(), e_zoom_full_out(), e_repeat_previous(), e_blow_up(), e_blow_up_call_function(), e_up_down_move_marks(), e_move_closest_mark(), e_modify_signal(), c_print_graphic(), e_print_ensemble();extern void e_print_graphic(), do_print_ensemble();static Menu wave_submenu = (Menu)NULL;#ifdef TESTING_HANDLERSvoid bus_err(){ int it[4], *pit = it; int nut; fprintf(stderr,"bus_err:\n"); nut = (int)pit; nut++; pit = (int*)nut; *pit = 5; fprintf(stderr,"bus_err:%x %d\n",pit,*pit);}void seg_viol(){ int it[4], *pit = it; int nut; fprintf(stderr,"seg_viol:\n"); pit = (int*)3; *pit = 5; fprintf(stderr,"seg_viol:%x %d\n",pit,*pit);}void zero_divide(){ double t2, t=1.23456, t3=0.0; fprintf(stderr,"zero_divide\n"); t2 = t/t3; fprintf(stderr,"zero_divide: t:%f t2:%f t3:%f\n",t,t2,t3);}void underflow(){ double big=1.12345678, bigger = 111.11111, sum; int trouble = 0; fprintf(stderr,"underflow\n"); while (trouble++ < 100000) { sum = big + bigger; bigger = bigger * bigger; } fprintf(stderr,"underflow: i:%d sum:%f\n",trouble,sum);}#endif /* This list comprises the "built-in" xwaves waveform view menu commands. *//* The arguments for the called routines are (canvas, event, arg). */Menuop#ifdef TESTING_HANDLERStesth5 = {"violate2",seg_viol, NULL, NULL},testh4 = {"underflow",underflow, NULL, &testh5},testh3 = {"div. by 0",zero_divide, NULL, &testh4},testh2 = {"buss error",bus_err, NULL, &testh3},testh1 = {"seg violate",seg_viol, NULL, &testh2}, rbo14 = {"kill window", e_kill, NULL, &testh1},#else rbo14 = {"kill window", e_kill, NULL, NULL},#endif rbo13c = {"print ensemble", e_print_ensemble, NULL, &rbo14}, rbo13b = {"print graphic", c_print_graphic, NULL, &rbo13c}, rbo13 = {"insert file", e_insert_file, NULL, &rbo13b}, rbo12 = {"delete segment", e_delete_segment, NULL, &rbo13}, rbo11 = {"save segment in file", e_save_segment, NULL, &rbo12}, rbo10 = {"output bitmap",NULL /* e_output_bitmap*/, NULL, &rbo11}, rbo9 = {"spectrogram (N.B.)", e_nb_spectrogram, NULL, &rbo10}, rbo8 = {"spectrogram (W.B.)", e_wb_spectrogram, NULL, &rbo9}, rbo7a = {"zoom full out", e_zoom_full_out, NULL, &rbo8}, rbo7 = {"zoom out", e_zoom_out, NULL, &rbo7a}, rbo6b = {"zoom in", e_zoom_in, NULL, &rbo7}, rbo6 = {"bracket markers", e_position_view, NULL, &rbo6b}, rbo5c = {"align & rescale", e_align_views, NULL, &rbo6}, rbo5b = {"window back", e_backward_window, NULL, &rbo5c}, rbo5a = {"window ahead", e_forward_window, NULL, &rbo5b}, rbo5 = {"page back", e_page_back, NULL, &rbo5a}, rbo4 = {"page ahead", e_page_ahead, NULL, &rbo5}, rbo3 = {"play to end of file", e_play_from_cursor, NULL, &rbo4}, rbo2 = {"play entire file", e_play_file, NULL, &rbo3}, rbo1 = {"play window contents", e_play_window, NULL, &rbo2}, right_but_menu = {"play between marks", e_play_between_marks, NULL, &rbo1}, wave_operators = {"repeat previous", e_repeat_previous, NULL, &right_but_menu};/* The following menu ops. are specific to left and middle buttons. */Menuop mbo3 = {"blow up time", e_blow_up, NULL, &wave_operators}, mbo4 = {"up/down move", e_up_down_move_marks, NULL, &mbo3}, mbo5 = {"blow up; function", e_blow_up_call_function, NULL, &mbo4}, lbo3 = {"modify signal", e_modify_signal, NULL, &mbo5}, def_aux_but_ops = {"move closest", e_move_closest_mark, NULL, &lbo3}, *aux_but_ops = &def_aux_but_ops;void (*right_button_proc)() = menu_operate;Menuop *blowup_op = NULL;/*********************************************************************/Menuop *wave_get_ops(){ return(&wave_operators);}/*********************************************************************/Canvas menu_get_canvas(event) Event *event;{ Xv_object win; Canvas canvas; win = event_window(event); canvas = xv_get(win, CANVAS_PAINT_CANVAS_WINDOW); /* Sometimes (e.g. if you fiddle with a pullright item before making a final selection) the xv_get(menu, MENU_FIRST_EVENT) returns a LOC_DRAG event for which event_window returns the actual canvas, rather than an MS_RIGHT event for which event_window returns the canvas paint window. (XView BUG???) */ if (!canvas) canvas = win; return(canvas);}/*********************************************************************/View *menu_get_view(menu) Menu menu;{ Event *event = (Event *) xv_get(menu, MENU_FIRST_EVENT); Canvas canvas = menu_get_canvas(event); View *v = (View *)xv_get(canvas, WIN_CLIENT_DATA); return(v);}/*********************************************************************/Menuop *last_menuop(mo) Menuop *mo;{ while(mo) { if( ! mo->next) return(mo); mo = mo->next; } return(NULL);}/*********************************************************************/Menuop *find_operator(ml, opname) Menuop *ml; char *opname;{ if(opname && *opname) { while(ml) { if(!strcmp(ml->name, opname)) return(ml); ml = ml->next; } } return(NULL);}void donothing(){ return;}Menuop null_menu_operator = {"NO OP", donothing, NULL, NULL};/*********************************************************************/Menuop *get_null_op(){ return(&null_menu_operator);}/*********************************************************************/void menu_set_blowup_op(val) char *val;{ if(val && *val) { Moplist *menu_get_op_lists(), *mol = menu_get_op_lists(); while(mol) { if((blowup_op = find_operator(mol->first_op, val)) && blowup_op->proc) return; mol = mol->next; } if(!(blowup_op && blowup_op->proc)) blowup_op = &null_menu_operator; if(w_verbose > 1) fprintf(stderr, "Can't find an operator called \"%s\" in menu_set_blowup_op(); ignoring\n", val); }} /*********************************************************************/Menuop *find_some_operator(ml, opname) Menuop *ml; char *opname;{ if((ml = find_operator(ml, opname))) return(ml); else return(&null_menu_operator);}extern Menuop spect_operators, def_aux_sbut_ops;Moplist mol2 = {"wave", &wave_operators, &def_aux_but_ops, NULL}, mol1 = {"spect", &spect_operators, &def_aux_sbut_ops, &mol2};/*********************************************************************/Moplist *menu_get_op_lists(){ return(&mol1);}/*********************************************************************/Menuop *new_menuop(menu, name, proc, data) char *name, *menu; void (*proc)(); void *data;{ if(name && *name) { Menuop *mo, *moe; Moplist *mol = &mol1; char *mname; if(!(menu && *menu)) mname = "all"; else mname = menu; while(mol) { if(!strcmp(mname, mol->name)) break; mol = mol->next; } if(!mol) { Moplist *m = &mol1; while(m->next) m = m->next; m->next = mol = (Moplist*)malloc(sizeof(Moplist)); mol->name = savestring(mname); mol->next = NULL; mol->reserve_ops = mol->first_op = mo = (Menuop*)calloc(1, sizeof(Menuop)); mo->name = savestring(name); } else if(!(mo = find_operator(mol->first_op, name))) { moe = last_menuop(mol->first_op); mo = moe->next = (Menuop*)calloc(1, sizeof(Menuop)); mo->name = savestring(name); } mo->proc = proc; mo->data = data; return(mo); } return(NULL);} /*********************************************************************/char *get_menu_label(mi,ml) register void (*mi)(); register Menuop *ml;{ while(ml) { if(mi == ml->proc) return(ml->name); ml = ml->next; } return(NULL);}/*********************************************************************/static caddr_t menu_null_proc(m, mi) Menu m; Menu_item mi;{ if(debug_level) fprintf(stderr,"Menu null proc\n"); return(NULL);}/*********************************************************************//* Notify_proc called when an item in the waveform or spectrogram window menu is selected. Heller shows the return type as Xv_opaque in version 1, changed to void in version 2. Nevertheless, the code for version 2 (in .../lib/libxvol/menu) still shows the type as Xv_opaque. The value apparently is used as an argument for the menu_done_proc, if any, and is irrelevant if no menu_done_proc is defined. */Xv_opaquedo_menu(menu, item) Menu menu; Menu_item item;{ Event *event; Canvas canvas; Menuop *mo; int i; View *v; Signal *s; Object *o; if (debug_level) (void) fprintf(stderr, "do_menu: function entered\n"); event = (Event *) xv_get(menu, MENU_FIRST_EVENT); canvas = menu_get_canvas(event); if(canvas && (v = (View *)xv_get(canvas, WIN_CLIENT_DATA)) && (s = v->sig) && (o = (Object*)(s->obj))) set_current_obj_name(o->name); if((mo = (Menuop*)xv_get(item, MENU_VALUE)) && mo->proc) { xv_set(canvas, XV_KEY_DATA, menu_item_key, mo, 0); xv_set(event_window(event), WIN_MOUSE_XY, event_x(event), event_y(event), 0); mo->proc(canvas, event, mo->data); } return XV_NULL; /* Value irrelevant. */}/***********************************************************************//* Find top-level menu item, if any, named name. xv_find won't work because, among other reasons, it looks in submenus. */Menu_itemfind_menu_item(menu, name) Menu menu; char *name;{ int i; Menu_item item; char *str; for (i = (int) xv_get(menu, MENU_NITEMS); i >= 1 && !((item = (Menu_item) xv_get(menu, MENU_NTH_ITEM, i)) != MENU_ITEM_NULL && (str = (char *) xv_get(item, MENU_STRING)) && !strcmp(str, name)); i-- ) { } return (i >= 1) ? item : MENU_ITEM_NULL;} /*********************************************************************/static caddr_t op_select_proc(m, mi) Menu m; Menu_item mi;{ Menuop *selected_op = NULL; Menu mp = m, mpp; if(debug_level) fprintf(stderr,"op_select_proc %s\n",xv_get(mi, MENU_STRING)); if((selected_op = (Menuop*)xv_get(mi, MENU_VALUE)) && (m = (Menu)xv_get(m, MENU_PARENT))) { View *v; extern char def_left_op[], def_middle_op[]; while((mpp = (Menu)xv_get(mp, MENU_PARENT))) mp = mpp; v = menu_get_view(mp); if(debug_level) fprintf(stderr,"Item: %s\n",xv_get(m, MENU_STRING)); if(v) if( !strcmp("left", (char*)xv_get(m, MENU_STRING))) v->left_but_proc = selected_op; else v->mid_but_proc = selected_op; if(v->sig) update_window_titles(v->sig); } return(NULL);}/*********************************************************************/Menu make_generic_menu(mo, callback) void (*callback)(); Menuop *mo;{ Menu menu; menu = xv_create(XV_NULL, MENU, 0); if (menu == MENU_NULL) { printf("make_generic_menu: couldn't create menu.\n"); exit_lm(); } for ( ; mo; mo = mo->next) if(mo->proc) xv_set(menu, MENU_ITEM, MENU_STRING, mo->name, MENU_NOTIFY_PROC, callback, MENU_VALUE, mo, 0, 0); return(menu); }/*********************************************************************/typedef struct but_it { Menu ops; char *name;} Button_items;/*********************************************************************/Menu make_op_list(mi, op) Menu_item mi; Menu_generate op;{ Button_items *bi = (Button_items*)xv_get(mi, MENU_CLIENT_DATA); if(bi) { Menu allops = bi->ops; switch(op) { case MENU_DISPLAY: { Menuop *mo; Menu_item item; if( !allops ) { allops = xv_create(XV_NULL, MENU, MENU_NOTIFY_PROC, op_select_proc, 0); bi->ops = allops; } if(allops) { Moplist *menu_get_op_lists(), *mol = menu_get_op_lists(); while(mol) { if(!strcmp(mol->name,"all") || !strcmp(mol->name,bi->name)) { for (mo = mol->reserve_ops; mo; mo = mo->next) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -