gamin@larry.mcrcim.mcgill.edu (Martin Boyer) (03/01/90)
I am working on a replacement for shelltool with the following capabilities: - dynamic font selection (change font after tool creation) - cursor attributes (block/underline, solid/blinking) - control over highlighting (bold, reverse video, underscore, color) - color (background, foreground, mouse, etc.) It's in a pretty good shape now; I still have to add color, which will be no trouble (I've done it for emacs), and the interface to the selection service. The latter is causing me great pains; it seems that this is handled by default by the panel and tty windows, but I can't get it to work with a canvas window (which I need in order to have full control over the rendering of text). I am using SunOS 4.0.3 on a Sun 3. The problem is: Although I can set and retrieve the primary selection with the selection service, I can't do anything with the left function keys (COPY, PASTE, FIND, and CUT) because I can't register them properly with the selection service. The first subsection in section 9.5 of the May 88 version of the SunView System Programmer's Guide discusses `Reporting Function-Key Transitions'. I believe I am using seln_report_event() properly, but the key transitions do not seem to affect the state of the selection service (I verified with seln_get_function_state()). This prevents me from implementing the very common COPY and PASTE sequence of operations with the L6 and L8 keys. This also prevents the implementation of secondary selections (not that they are very useful in a terminal emulator, but I want it to be complete). What's more, it seems that my application somehow retains the caret too long since if I hit COPY in *another* window, my application's primary selection gets shelved. This reinforces my suspicion; my function key transitions are not reported properly to the selection service. By the way, I tried seln_dump_service(SELN_UNSPECIFIED), as described on page 114 of the Guide, but I keep getting core dumps in that function. Has anybody used the selection library? Can anybody give me a hint? I suppose that I am just trying to reinvent the wheel because the functionality is already standard for certain windows; perhaps some kind soul at Sun would care to send me the relevant portions of the code. In return, you'll be the first one to receive my sources once it is completed (it will make a very nice emacstool: ever dreamed about cursor, mouse, and modelines in color?). For starters, here's what I believe to be relevant portions of the code. The selection handlers (func_key_proc() and reply_proc()) are pretty much standard, adapted from seln_demo.c canvas = window_create(topwin, CANVAS, CANVAS_FIXED_IMAGE, FALSE, CANVAS_RETAINED, FALSE, CANVAS_REPAINT_PROC, canvas_repaint, CANVAS_RESIZE_PROC, canvas_resize, WIN_CONSUME_KBD_EVENTS, WIN_ASCII_EVENTS, WIN_LEFT_KEYS, WIN_UP_EVENTS, 0, WIN_CONSUME_PICK_EVENT, LOC_DRAG, WIN_IGNORE_PICK_EVENT, LOC_MOVE, WIN_EVENT_PROC, canvas_event_handler, 0); void init_selection() { int i; s_client = seln_create(func_key_proc, reply_proc, (caddr_t)NULL); if (s_client == NULL) { fprintf(stderr, "%s: seln_create failed!\n", Progname); exit(1); } } /* These event_ids are not standard SunView event_ids. * In my opinion, they should be; it would make mouse tracking SO much simpler. */ #define DRAG_LEFT 1000 #define DRAG_MIDDLE 1001 void canvas_event_handler(window, event, arg) Window window; Event *event; caddr_t arg; { static int left_pressed = FALSE; static int middle_pressed = FALSE; static int start_x, start_y; int action; action = event_action(event); /* User ASCII keystrokes. */ if (action <= 256) { char c; c = (char) action; typein(&c, 1); return; } if (event_is_up(event) && event_is_button(event)) { switch (action) { case MS_LEFT: if (left_pressed) { left_pressed = FALSE; start_x = event_x(event); start_y = event_y(event); set_selection(PRIMARY_SELECTION); } break; case MS_MIDDLE: if (middle_pressed) { middle_pressed = FALSE; set_selection(PRIMARY_SELECTION); } break; default: break; } return; } if (action == LOC_DRAG) { if (left_pressed) action = DRAG_LEFT; if (middle_pressed) action = DRAG_MIDDLE; } /* On left button down, track the beginning of the selection, * on middle button down, track the end of the selection, * clean up on exiting the window if button wasn't released. */ switch (action) { case MS_LEFT: left_pressed = TRUE; case DRAG_LEFT: select_region(event_x(event), event_y(event), event_x(event), event_y(event), PRIMARY_SELECTION); break; case MS_MIDDLE: middle_pressed = TRUE; case DRAG_MIDDLE: select_region(start_x, start_y, event_x(event), event_y(event), PRIMARY_SELECTION); break; case MS_RIGHT: insert_selection(PRIMARY_SELECTION); break; case LOC_RGNEXIT: break; case LOC_RGNENTER: seln_acquire(s_client, SELN_CARET); break; default: if (event_is_key_left(event)) printf("COPY is %s", seln_get_function_state(SELN_FN_PUT) ? "down" : "up"); seln_report_event(s_client, event); if (event_is_key_left(event)) printf(" then %s.\n", seln_get_function_state(SELN_FN_PUT) ? "down" : "up"); break; } } Thanks, Martin Boyer ireq-robot!mboyer@Larry.McRCIM.McGILL.EDU Institut de recherche d'Hydro-Quebec mboyer@ireq-robot.uucp Varennes, QC, Canada J3X 1S1 +1 514 652-8136