📄 textsw_input.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)textsw_input.c 1.1 92/07/30";#endif#endif/* * Copyright (c) 1986 by Sun Microsystems, Inc. *//* * User input interpreter for text subwindows. */#include <suntool/primal.h>#include <suntool/textsw_impl.h>#include <suntool/entity_view.h>#include <errno.h>#include <sundev/kbd.h> /* Only needed for SHIFTMASK and CTRLMASK */#include <pixrect/pr_util.h>#include <pixrect/memvar.h>#include <suntool/alert.h>#include <suntool/frame.h>#include <sunwindow/win_cursor.h>#include <sunwindow/win_struct.h>#include <sunwindow/win_input.h> /* needed for event_shift_is_down() */#ifdef KEYMAP_DEBUG#include "../../libsunwindow/win/win_keymap.h"#else#include <sunwindow/win_keymap.h>#endifextern int errno;extern Key_map_handle textsw_do_filter();extern struct pixrect *textsw_get_stopsign_icon();extern struct pixrect *textsw_get_textedit_icon();extern Textsw_enum textsw_get_menu_style_internal();extern int textsw_load_done_proc();pkg_private void textsw_init_timer();#define SPACE_CHAR 0x20pkg_private inttextsw_flush_caches(view, flags) register Textsw_view view; register int flags;{ register Textsw_folio textsw = FOLIO_FOR_VIEW(view); register int count; register int end_clear = (flags & TFC_SEL); count = (textsw->func_state & TXTSW_FUNC_FILTER) ? 0 : (textsw->to_insert_next_free - textsw->to_insert); if (flags & TFC_DO_PD) { if ((count > 0) || ((flags & TFC_PD_IFF_INSERT) == 0)) { ev_set(0, textsw->views, EV_CHAIN_DELAY_UPDATE, TRUE, 0); (void) textsw_do_pending_delete(view, EV_SEL_PRIMARY, end_clear|TFC_INSERT); ev_set(0, textsw->views, EV_CHAIN_DELAY_UPDATE, FALSE, 0); end_clear = 0; } } if (end_clear) { if ((count > 0) || ((flags & TFC_SEL_IFF_INSERT) == 0)) { (void) textsw_set_selection( VIEW_REP_TO_ABS(view), ES_INFINITY, ES_INFINITY, EV_SEL_PRIMARY); } } if (flags & TFC_INSERT) { if (count > 0) { /* WARNING! The cache pointers must be updated BEFORE * calling textsw_do_input, so that if the client is being * notified of edits and it calls textsw_get, it will not * trigger an infinite recursion of textsw_get calling * textsw_flush_caches calling textsw_do_input calling * the client calling textsw_get calling ... */ textsw->to_insert_next_free = textsw->to_insert; (void) textsw_do_input(view, textsw->to_insert, count, TXTSW_UPDATE_SCROLLBAR_IF_NEEDED); } }}pkg_private voidtextsw_read_only_msg(textsw, locx, locy) Textsw_folio textsw; int locx, locy;{ (void) alert_prompt( (Frame)window_get(VIEW_FROM_FOLIO_OR_VIEW(textsw), WIN_OWNER), (Event *) 0, ALERT_MESSAGE_STRINGS, "The text is read-only and cannot be edited.", "Press \"Continue\" to proceed.", 0, ALERT_BUTTON_YES, "Continue", ALERT_TRIGGER, ACTION_STOP, 0);}pkg_private inttextsw_note_event_shifts(textsw, ie) register Textsw_folio textsw; register struct inputevent *ie;{ int result = 0; if (ie->ie_shiftmask & SHIFTMASK) textsw->state |= TXTSW_SHIFT_DOWN; else {#ifdef VT_100_HACK if (textsw->state & TXTSW_SHIFT_DOWN) { /* Hack for VT-100 keyboard until PIT is available. */ result = 1; }#endif textsw->state &= ~TXTSW_SHIFT_DOWN; } if (ie->ie_shiftmask & CTRLMASK) textsw->state |= TXTSW_CONTROL_DOWN; else textsw->state &= ~TXTSW_CONTROL_DOWN; return(result);}#ifdef GPROFstatictextsw_gprofed_routine(view, ie) register Textsw_view view; register Event *ie;{}#endif#define CTRL_D 004#define CTRL_F 006#define CTRL_G 007#define CTRL_P 020extern inttextsw_process_event(abstract, ie, arg) Textsw abstract; register Event *ie; Notify_arg arg;{ extern void textsw_update_scrollbars(); static int textsw_win_event(); static int textsw_scroll_event(); static int textsw_function_key_event(); static int textsw_mouse_event(); static int textsw_edit_function_key_event(); static int textsw_caret_motion_event(); static int textsw_field_event(); int caret_was_up; int result = TEXTSW_PE_USED; register Textsw_view view = VIEW_ABS_TO_REP(abstract); register Textsw_folio textsw = FOLIO_FOR_VIEW(view); char current_selection[200], err_msg[300]; int action = event_action(ie);/* * Since the keymapping system no longer supports full translation of event * ids, shiftmasks and flags we must revert to keymapping 3.x accelerators * directly. This stuff should really be coalesced together somewhere * rather than these local patches. */ static short keyboard_accel_state_cached; static short keyboard_accel_state; static int is_cmdtool; if (!keyboard_accel_state_cached) { keyboard_accel_state = (!strcmp("Enabled", (char *) defaults_get_string( "/Compatibility/New_keyboard_accelerators", "Enabled", 0))) ? 1 : 0; keyboard_accel_state_cached = 1; is_cmdtool = (textsw->state & TXTSW_NO_RESET_TO_SCRATCH); } if (!keyboard_accel_state) { switch (action) { case CTRL_D: if (is_cmdtool) break; event_set_id(ie, TXTSW_DELETE); event_set_shiftmask(ie, 0); break; case CTRL_F: if (is_cmdtool) break; /* The FIND function expects up/down transitions but ascii * up transitions are not generated so we must synthesize * the appropriate up event */ if (event_shift_is_down(ie)) { event_set_id(ie, TXTSW_FIND_BACKWARD); event_set_shiftmask(ie, LEFTSHIFT|RIGHTSHIFT); textsw_function_key_event(view, ie, &result); event_set_up(ie); } else { event_set_id(ie, TXTSW_FIND_FORWARD); event_set_shiftmask(ie, 0); /*textsw_function_key_event(view, ie, &result); event_set_up(ie);*/ } break; case CTRL_G: if (is_cmdtool) break; event_set_id(ie, TXTSW_GET); event_set_shiftmask(ie, 0); break; case CTRL_P: event_set_id(ie, TXTSW_PUT_THEN_GET); event_set_shiftmask(ie, 0); break; default: break; } } caret_was_up = textsw->caret_state & TXTSW_CARET_ON; /* Watch out for caret turds */ if ((action == LOC_MOVE || action == LOC_STILL || action == LOC_WINENTER || action == LOC_WINEXIT || action == LOC_RGNENTER || action == LOC_RGNEXIT || action == SCROLL_ENTER || action == SCROLL_EXIT) && !TXTSW_IS_BUSY(textsw)) { /* leave caret up */ } else if ( !((action == TXTSW_MOVE_RIGHT || action == TXTSW_MOVE_LEFT || action == TXTSW_MOVE_UP || action == TXTSW_MOVE_DOWN || action == TXTSW_MOVE_WORD_BACKWARD || action == TXTSW_MOVE_WORD_FORWARD || action == TXTSW_MOVE_WORD_END || action == TXTSW_MOVE_TO_LINE_START || action == TXTSW_MOVE_TO_LINE_END || action == TXTSW_MOVE_TO_NEXT_LINE_START || action == TXTSW_MOVE_TO_DOC_START || action == TXTSW_MOVE_TO_DOC_END) && !win_inputposevent(ie)) ) { textsw_take_down_caret(textsw); } switch (textsw_note_event_shifts(textsw, ie)) {#ifdef VT_100_HACK case 1: if (textsw->func_state & TXTSW_FUNC_GET) { textsw_end_get(view); }#endif default: break; } /* NOTE: This is just a hack for performance */ if ((action >= SPACE_CHAR) && (action <= ASCII_LAST)) goto Process_ASCII; if (action == TXTSW_STOP) { textsw_abort(textsw); } else if (action == TXTSW_HELP) { if (win_inputposevent(ie)) help_request(WINDOW_FROM_VIEW(view), textsw->help_data, ie);#ifdef GPROF } else if (action == KEY_RIGHT(13)) { if (win_inputposevent(ie)) { if (textsw->state & TXTSW_SHIFT_DOWN) { moncontrol(0); } } else { if ((textsw->state & TXTSW_SHIFT_DOWN) == 0) { moncontrol(1); } } } else if (action == KEY_RIGHT(15)) { if (win_inputposevent(ie)) { } else { moncontrol(1); textsw_gprofed_routine(view, ie); moncontrol(0); }#endif /* * Check Resize/Repaint early to avoid skipping due to 2nd-ary Seln. */ } else if (textsw_win_event(view, ie, caret_was_up)) { /* Its already taken care by the procedure */ } else if (textsw_scroll_event(view, ie, arg)) { /* Its already taken care by the procedure */ } else if ((textsw->track_state & (TXTSW_TRACK_ADJUST|TXTSW_TRACK_POINT)) && track_selection(view, ie) ) { /* * Selection tracking and function keys. * track_selection() always called if tracking. It consumes * the event unless function key up while tracking secondary * selection, which stops tracking and then does function. */ } else if (textsw_function_key_event(view, ie, &result)) { /* Its already taken care by the procedure */ } else if (textsw_mouse_event(view, ie)) { /* Its already taken care by the procedure */ } else if (textsw_edit_function_key_event(view, ie, &result)) { /* Its already taken care by the procedure */ } else if (textsw_caret_motion_event (view, ie, &action)) { /* Its already taken care by the procedure */ } else if (action == TXTSW_CAPS_LOCK) { if (TXTSW_IS_READ_ONLY(textsw)) goto Read_Only; if (win_inputposevent(ie)) { } else { textsw->state ^= TXTSW_CAPS_LOCK_ON; textsw_notify(view, TEXTSW_ACTION_CAPS_LOCK, (textsw->state & TXTSW_CAPS_LOCK_ON), 0); } /* * Type-in */ } else if (textsw->track_state & TXTSW_TRACK_SECONDARY) { /* No type-in processing during secondary (function) selections */ } else if (textsw_field_event(view, ie, &action)) { /* Its already taken care by the procedure */ } else if (action == TXTSW_PUT_THEN_GET) { if (win_inputposevent(ie)) { if (TXTSW_IS_READ_ONLY(textsw)) goto Read_Only; textsw_put_then_get(view); } } else if (action == TXTSW_EMPTY_DOCUMENT) { if (win_inputposevent(ie)) { textsw_empty_document(abstract, ie); goto Done; } } else if (action == TXTSW_INCLUDE_FILE) { int primary_selection_exists = textsw_is_seln_nonzero( textsw, EV_SEL_PRIMARY); if (win_inputposevent(ie)) { if (primary_selection_exists) { textsw_file_stuff(view, ie->ie_locx, ie->ie_locy); } else textsw_post_need_selection(abstract, ie); } } else if (action == TXTSW_LOAD_FILE_AS_MENU) { if (win_inputposevent(ie)) { textsw_load_file_as_menu(abstract, ie); goto Done; } } else if (action == TXTSW_LOAD_FILE) { int event_is_shifted = event_shift_is_down(ie); int result; if (win_inputposevent(ie)) { if ((textsw->state & TXTSW_NO_LOAD) && (!(event_is_shifted))) goto Insert; textsw_flush_caches(view, TFC_STD); result = textsw_handle_esc_accelerators(abstract, ie); switch (result) { case (0): goto Read_Only; case (1): goto Insert; /*default: ie == 2 let drop through */ } } } else if (textsw_file_operation(view, ie)) { } else if ((action <= META_LAST || (action >= ISO_FIRST && action <= ISO_LAST) || action == ACTION_ERASE_CHAR_BACKWARD || action == ACTION_ERASE_CHAR_FORWARD || action == ACTION_ERASE_WORD_BACKWARD || action == ACTION_ERASE_WORD_FORWARD || action == ACTION_ERASE_LINE_BACKWARD || action == ACTION_ERASE_LINE_END) && win_inputposevent(ie)) { unsigned edit_unit; if (action >= ISO_FIRST && action <= ISO_LAST) action -= ISO_FIRST; /* get ISO character code */ if (textsw->func_state & TXTSW_FUNC_FILTER) { if (textsw->to_insert_next_free < textsw->to_insert + sizeof(textsw->to_insert)) { *textsw->to_insert_next_free++ = (char) action; } } else { int direction = 0 /* forward direction */; switch (action) { case ACTION_ERASE_CHAR_BACKWARD: edit_unit = EV_EDIT_CHAR; direction = EV_EDIT_BACK; break; case ACTION_ERASE_CHAR_FORWARD: edit_unit = EV_EDIT_CHAR; break; case ACTION_ERASE_WORD_BACKWARD: edit_unit = EV_EDIT_WORD; direction = EV_EDIT_BACK; break; case ACTION_ERASE_WORD_FORWARD: edit_unit = EV_EDIT_WORD; break; case ACTION_ERASE_LINE_BACKWARD: edit_unit = EV_EDIT_LINE; direction = EV_EDIT_BACK; break; case ACTION_ERASE_LINE_END: edit_unit = EV_EDIT_LINE; break; default: edit_unit = 0; } if (edit_unit != 0) { if (TXTSW_IS_READ_ONLY(textsw)) goto Read_Only; textsw_flush_caches(view, TFC_INSERT|TFC_PD_IFF_INSERT|TFC_DO_PD|TFC_SEL); (void) textsw_do_edit(view, edit_unit, direction); } else {Process_ASCII: switch (action) { case (short) '\r': /* Fall through */ case (short) '\n': if ((textsw->state & TXTSW_CONTROL_DOWN) && (win_get_vuid_value(WIN_FD_FOR_VIEW(view), 'm') == 0) && (win_get_vuid_value(WIN_FD_FOR_VIEW(view), 'j') == 0) && (win_get_vuid_value(WIN_FD_FOR_VIEW(view), 'M') == 0) && (win_get_vuid_value(WIN_FD_FOR_VIEW(view), 'J') == 0) ) { /* do nothing */ } else { if (TXTSW_IS_READ_ONLY(textsw)) goto Read_Only; (void) textsw_do_newline(view); } break; default: if (TXTSW_IS_READ_ONLY(textsw)) goto Read_Only; if (textsw->state & TXTSW_CAPS_LOCK_ON) { if ((char)action >= 'a' && (char)action <= 'z') ie->ie_code += 'A' - 'a'; /*BUG ALERT: above may need to set event_id*/ }Insert: *textsw->to_insert_next_free++ = (char) event_action( ie); if (textsw->to_insert_next_free == textsw->to_insert + sizeof(textsw->to_insert)) { textsw_flush_caches(view, TFC_STD); } break; } } } /* * User filters */ } else if (textsw_do_filter(view, ie)) { /* * Miscellaneous */ } else { result &= ~TEXTSW_PE_USED; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -