1
/* $XConsortium: button.c /main/70 1996/01/14 16:52:34 kaleb $ */
2
/* $Id: button.c,v 6.2 1996/07/02 05:01:31 kagotani Rel $ */
4
* Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
8
* Permission to use, copy, modify, and distribute this software and its
9
* documentation for any purpose and without fee is hereby granted,
10
* provided that the above copyright notice appear in all copies and that
11
* both that copyright notice and this permission notice appear in
12
* supporting documentation, and that the name of Digital Equipment
13
* Corporation not be used in advertising or publicity pertaining to
14
* distribution of the software without specific, written prior permission.
17
* DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
18
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
19
* DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
20
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
27
button.c Handles button events in the terminal emulator.
28
does cut/paste operations, change modes via menu,
29
passes button events through to some applications.
33
#include "ptyx.h" /* Xlib headers included here. */
34
#include <X11/Xatom.h>
37
#include <X11/Xmu/Atoms.h>
38
#include <X11/Xmu/StdSel.h>
44
extern char *malloc();
46
extern void DoSecureKeyboard();
48
#define KeyState(x) (((x) & (ShiftMask|ControlMask)) + (((x) & Mod1Mask) ? 2 : 0))
49
/* adds together the bits:
59
#define SHIFTS 8 /* three keys, so eight combinations */
60
#define Coordinate(r,c) ((r) * (term->screen.max_col+1) + (c))
62
extern char *xterm_name;
64
static void PointToRowCol();
65
static void SelectionReceived();
66
static void TrackDown();
67
static void ComputeSelect();
68
static void EditorButton();
69
static void ExtendExtend();
70
static void ReHiliteText();
71
static void SelectSet();
72
static void StartSelect();
75
static Ichr *SaveText();
77
static char *SaveText();
80
extern XtermWidget term;
82
/* Selection/extension variables */
84
/* Raw char position where the selection started */
85
static int rawRow, rawCol;
87
/* Selected area before CHAR, WORD, LINE selectUnit processing */
88
static int startRRow, startRCol, endRRow, endRCol = 0;
90
/* Selected area after CHAR, WORD, LINE selectUnit processing */
91
static int startSRow, startSCol, endSRow, endSCol = 0;
93
/* Valid rows for selection clipping */
94
static int firstValidRow, lastValidRow;
96
/* Start, end of extension */
97
static int startERow, startECol, endERow, endECol;
99
/* Saved values of raw selection for extend to restore to */
100
static int saveStartRRow, saveStartRCol, saveEndRRow, saveEndRCol;
102
/* Multi-click handling */
103
static int numberOfClicks = 0;
104
#ifdef ENBUG /* kagotani */
105
static long int lastButtonUpTime = 0;
107
static Time lastButtonUpTime = 0;
109
typedef int SelectUnit;
113
#define NSELECTUNITS 3
114
static SelectUnit selectUnit;
116
/* Send emacs escape code when done selecting or extending? */
117
static int replyToEmacs;
119
#if defined(KTERM) && defined(KTERM_MBCC)
121
* by Kiyoshi KANAZAWA, Nov. 29, 1990.
122
* Support word-select for MBCS.
124
static int mbcsCharClass ();
125
#endif /* KTERM && KTERM_MBCC */
127
Boolean SendMousePosition(w, event)
131
register TScreen *screen = &((XtermWidget)w)->screen;
133
if (screen->send_mouse_pos == 0) return False;
135
if (event->type != ButtonPress && event->type != ButtonRelease)
138
#define KeyModifiers \
139
(event->xbutton.state & (ShiftMask | LockMask | ControlMask | Mod1Mask | \
140
Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask ))
142
#define ButtonModifiers \
143
(event->xbutton.state & (ShiftMask | LockMask | ControlMask | Mod1Mask | \
144
Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask ))
146
switch (screen->send_mouse_pos) {
147
case 1: /* X10 compatibility sequences */
149
if (KeyModifiers == 0) {
150
if (event->type == ButtonPress)
156
case 2: /* DEC vt200 compatible */
158
if (KeyModifiers == 0 || KeyModifiers == ControlMask) {
164
case 3: /* DEC vt200 hilite tracking */
165
if ( event->type == ButtonPress &&
167
event->xbutton.button == Button1 ) {
171
if (KeyModifiers == 0 || KeyModifiers == ControlMask) {
185
void HandleSelectExtend(w, event, params, num_params)
187
XEvent *event; /* must be XMotionEvent */
188
String *params; /* unused */
189
Cardinal *num_params; /* unused */
191
register TScreen *screen = &((XtermWidget)w)->screen;
194
screen->selection_time = event->xmotion.time;
197
case RIGHTEXTENSION :
198
PointToRowCol (event->xmotion.y, event->xmotion.x,
200
ExtendExtend (row, col);
203
/* will get here if send_mouse_pos != 0 */
208
static void EndExtend();
210
static void do_select_end (w, event, params, num_params, use_cursor_loc)
212
XEvent *event; /* must be XButtonEvent */
213
String *params; /* selections */
214
Cardinal *num_params;
217
((XtermWidget)w)->screen.selection_time = event->xbutton.time;
220
(void) SendMousePosition(w, event);
223
case RIGHTEXTENSION :
224
EndExtend(w, event, params, *num_params, use_cursor_loc);
230
void HandleSelectEnd(w, event, params, num_params)
232
XEvent *event; /* must be XButtonEvent */
233
String *params; /* selections */
234
Cardinal *num_params;
236
do_select_end (w, event, params, num_params, False);
240
void HandleKeyboardSelectEnd(w, event, params, num_params)
242
XEvent *event; /* must be XButtonEvent */
243
String *params; /* selections */
244
Cardinal *num_params;
246
do_select_end (w, event, params, num_params, True);
252
struct _SelectionList {
256
#ifdef KTERM /* from exterm */
263
static void _GetSelection(w, time, params, num_params)
266
String *params; /* selections in precedence order */
272
XmuInternStrings(XtDisplay(w), params, (Cardinal)1, &selection);
274
case XA_CUT_BUFFER0: cutbuffer = 0; break;
275
case XA_CUT_BUFFER1: cutbuffer = 1; break;
276
case XA_CUT_BUFFER2: cutbuffer = 2; break;
277
case XA_CUT_BUFFER3: cutbuffer = 3; break;
278
case XA_CUT_BUFFER4: cutbuffer = 4; break;
279
case XA_CUT_BUFFER5: cutbuffer = 5; break;
280
case XA_CUT_BUFFER6: cutbuffer = 6; break;
281
case XA_CUT_BUFFER7: cutbuffer = 7; break;
282
default: cutbuffer = -1;
284
if (cutbuffer >= 0) {
285
register TScreen *screen = &((XtermWidget)w)->screen;
287
unsigned long nbytes;
289
Atom type = XA_STRING;
290
char *line = XFetchBuffer(screen->display, &inbytes, cutbuffer);
291
nbytes = (unsigned long) inbytes;
293
SelectionReceived(w, NULL, &selection, &type, (XtPointer)line,
295
else if (num_params > 1)
296
_GetSelection(w, time, params+1, num_params-1);
298
struct _SelectionList* list;
300
list = XtNew(struct _SelectionList);
301
list->params = params + 1;
302
list->count = num_params; /* decremented above */
304
#ifdef KTERM /* from exterm */
306
list->selection = selection;
310
XtGetSelectionValue(w, selection, XA_TEXT(XtDisplay(w)), SelectionReceived,
311
(XtPointer)list, time);
313
XtGetSelectionValue(w, selection, XA_STRING, SelectionReceived,
314
(XtPointer)list, time);
319
/* SelectionReceived: stuff received selection text into pty */
322
static void SelectionReceived(w, client_data, selection, type,
323
value, length, format)
325
XtPointer client_data;
326
Atom *selection, *type;
328
unsigned long *length;
331
int pty = ((XtermWidget)w)->screen.respond; /* file descriptor of pty */
332
register char *lag, *cp, *end;
333
char *line = (char*)value;
338
if (*type == 0 /*XT_CONVERT_FAIL*/ || *length == 0 || value == NULL) {
339
/* could not get this selection, so see if there are more to try */
340
struct _SelectionList* list = (struct _SelectionList*)client_data;
342
#ifdef KTERM /* from exterm */
343
/* ask XA_STRING again.
344
* Warning: hope owner not triggered between the 2 requests
345
* XA_STRING and XA_COMPOUNT_TEXT.
349
XtGetSelectionValue(w, list->selection, XA_STRING,
350
SelectionReceived, (XtPointer)list, list->time);
352
_GetSelection(w, list->time, list->params, list->count);
356
_GetSelection(w, list->time, list->params, list->count);
364
if (*type == XA_COMPOUND_TEXT(XtDisplay(w))) {
365
Char *ct = (Char *)value;
370
# ifdef KTERM_KANJIMODE
371
int convCStoEUC(), convCStoSJIS();
372
# endif /* KTERM_KANJIMODE */
375
n = convCTtoCS(ct, *length, NULL);
376
if (n < 0) { /* data broken */
381
cs = (n > 256) ? (Ichr *)XtMalloc((n + 1) * sizeof(Ichr)) : cbuf;
382
(void)convCTtoCS(ct, *length, cs);
384
# ifdef KTERM_KANJIMODE
385
switch (((XtermWidget)w)->flags & (EUC_KANJI|SJIS_KANJI)) {
396
# else /* !KTERM_KANJIMODE */
398
# endif /* !KTERM_KANJIMODE */
400
n = (*func)(cs, NULL);
401
line = (n > 256) ? XtMalloc(n + 1) : lbuf;
402
(void)(*func)(cs, line);
404
if (cs != cbuf) XtFree((char *)cs);
405
} else { /* must be XA_STRING */
409
line = (n > 256) ? XtMalloc(n + 1) : lbuf;
410
memmove( line, (char *)value, n);
423
/* Write data to pty a line at a time. */
424
/* Doing this one line at a time may no longer be necessary
425
because v_write has been re-written. */
427
end = &line[*length];
430
for (cp = line; cp != end; cp++)
432
if (*cp != '\n') continue;
434
v_write(pty, lag, cp - lag + 1);
438
v_write(pty, lag, end - lag);
441
if (line != lbuf) XtFree(line);
449
HandleInsertSelection(w, event, params, num_params)
451
XEvent *event; /* assumed to be XButtonEvent* */
452
String *params; /* selections in precedence order */
453
Cardinal *num_params;
455
if (SendMousePosition(w, event)) return;
456
_GetSelection(w, event->xbutton.time, params, *num_params);
461
SetSelectUnit(buttonDownTime, defaultUnit)
463
SelectUnit defaultUnit;
465
#ifdef ENBUG /* kagotani */
466
/* Do arithmetic as integers, but compare as unsigned solves clock wraparound */
467
if ((long unsigned)((long int)buttonDownTime - lastButtonUpTime)
469
if (buttonDownTime - lastButtonUpTime
471
> term->screen.multiClickTime) {
473
selectUnit = defaultUnit;
476
selectUnit = ((selectUnit + 1) % NSELECTUNITS);
480
static void do_select_start (w, event, startrow, startcol)
482
XEvent *event; /* must be XButtonEvent* */
483
int startrow, startcol;
485
if (SendMousePosition(w, event)) return;
486
SetSelectUnit(event->xbutton.time, SELECTCHAR);
487
replyToEmacs = FALSE;
488
StartSelect(startrow, startcol);
493
HandleSelectStart(w, event, params, num_params)
495
XEvent *event; /* must be XButtonEvent* */
496
String *params; /* unused */
497
Cardinal *num_params; /* unused */
499
register TScreen *screen = &((XtermWidget)w)->screen;
500
int startrow, startcol;
503
lastValidRow = screen->max_row;
504
PointToRowCol(event->xbutton.y, event->xbutton.x, &startrow, &startcol);
505
do_select_start (w, event, startrow, startcol);
511
HandleKeyboardSelectStart(w, event, params, num_params)
513
XEvent *event; /* must be XButtonEvent* */
514
String *params; /* unused */
515
Cardinal *num_params; /* unused */
517
register TScreen *screen = &((XtermWidget)w)->screen;
519
do_select_start (w, event, screen->cursor_row, screen->cursor_col);
525
register XButtonEvent *event;
527
int startrow, startcol;
529
SetSelectUnit(event->time, SELECTCHAR);
530
if (numberOfClicks > 1 ) {
531
PointToRowCol(event->y, event->x, &startrow, &startcol);
533
StartSelect(startrow, startcol);
535
waitingForTrackInfo = 1;
541
#define boundsCheck(x) if (x < 0) \
543
else if (x >= screen->max_row) \
547
TrackMouse(func, startrow, startcol, firstrow, lastrow)
548
int func, startrow, startcol, firstrow, lastrow;
550
TScreen *screen = &term->screen;
552
if (!waitingForTrackInfo) { /* Timed out, so ignore */
555
waitingForTrackInfo = 0;
556
if (func == 0) return;
557
boundsCheck (startrow)
558
boundsCheck (firstrow)
559
boundsCheck (lastrow)
560
firstValidRow = firstrow;
561
lastValidRow = lastrow;
563
StartSelect(startrow, startcol);
567
StartSelect(startrow, startcol)
568
int startrow, startcol;
570
TScreen *screen = &term->screen;
572
if (screen->cursor_state)
574
if (numberOfClicks == 1) {
575
/* set start of selection */
579
} /* else use old values in rawRow, Col */
581
saveStartRRow = startERow = rawRow;
582
saveStartRCol = startECol = rawCol;
583
saveEndRRow = endERow = rawRow;
584
saveEndRCol = endECol = rawCol;
585
if (Coordinate(startrow, startcol) < Coordinate(rawRow, rawCol)) {
586
eventMode = LEFTEXTENSION;
587
startERow = startrow;
588
startECol = startcol;
590
eventMode = RIGHTEXTENSION;
594
ComputeSelect(startERow, startECol, endERow, endECol, False);
599
EndExtend(w, event, params, num_params, use_cursor_loc)
601
XEvent *event; /* must be XButtonEvent */
602
String *params; /* selections */
607
TScreen *screen = &term->screen;
610
if (use_cursor_loc) {
611
row = screen->cursor_row;
612
col = screen->cursor_col;
614
PointToRowCol(event->xbutton.y, event->xbutton.x, &row, &col);
616
ExtendExtend (row, col);
617
lastButtonUpTime = event->xbutton.time;
618
if (startSRow != endSRow || startSCol != endSCol) {
620
if (rawRow == startSRow && rawCol == startSCol
621
&& row == endSRow && col == endSCol) {
622
/* Use short-form emacs select */
623
strcpy(line, "\033[t");
624
line[3] = ' ' + endSCol + 1;
625
line[4] = ' ' + endSRow + 1;
626
v_write(screen->respond, line, 5);
628
/* long-form, specify everything */
629
strcpy(line, "\033[T");
630
line[3] = ' ' + startSCol + 1;
631
line[4] = ' ' + startSRow + 1;
632
line[5] = ' ' + endSCol + 1;
633
line[6] = ' ' + endSRow + 1;
634
line[7] = ' ' + col + 1;
635
line[8] = ' ' + row + 1;
636
v_write(screen->respond, line, 9);
638
TrackText(0, 0, 0, 0);
641
SelectSet(w, event, params, num_params);
646
HandleSelectSet(w, event, params, num_params)
650
Cardinal *num_params;
652
SelectSet (w, event, params, *num_params);
655
static void SaltTextAway();
659
SelectSet (w, event, params, num_params)
665
/* Only do select stuff if non-null select */
666
if (startSRow != endSRow || startSCol != endSCol) {
667
SaltTextAway(startSRow, startSCol, endSRow, endSCol,
670
DisownSelection(term);
673
#define Abs(x) ((x) < 0 ? -(x) : (x))
676
static void do_start_extend (w, event, params, num_params, use_cursor_loc)
678
XEvent *event; /* must be XButtonEvent* */
679
String *params; /* unused */
680
Cardinal *num_params; /* unused */
683
TScreen *screen = &((XtermWidget)w)->screen;
686
if (SendMousePosition(w, event)) return;
688
lastValidRow = screen->max_row;
689
SetSelectUnit(event->xbutton.time, selectUnit);
690
replyToEmacs = FALSE;
692
if (numberOfClicks == 1) {
693
/* Save existing selection so we can reestablish it if the guy
694
extends past the other end of the selection */
695
saveStartRRow = startERow = startRRow;
696
saveStartRCol = startECol = startRCol;
697
saveEndRRow = endERow = endRRow;
698
saveEndRCol = endECol = endRCol;
700
/* He just needed the selection mode changed, use old values. */
701
startERow = startRRow = saveStartRRow;
702
startECol = startRCol = saveStartRCol;
703
endERow = endRRow = saveEndRRow;
704
endECol = endRCol = saveEndRCol;
707
if (use_cursor_loc) {
708
row = screen->cursor_row;
709
col = screen->cursor_col;
711
PointToRowCol(event->xbutton.y, event->xbutton.x, &row, &col);
713
coord = Coordinate(row, col);
715
if (Abs(coord - Coordinate(startSRow, startSCol))
716
< Abs(coord - Coordinate(endSRow, endSCol))
717
|| coord < Coordinate(startSRow, startSCol)) {
718
/* point is close to left side of selection */
719
eventMode = LEFTEXTENSION;
723
/* point is close to left side of selection */
724
eventMode = RIGHTEXTENSION;
728
ComputeSelect(startERow, startECol, endERow, endECol, True);
732
ExtendExtend (row, col)
735
int coord = Coordinate(row, col);
737
if (eventMode == LEFTEXTENSION
738
&& (coord + (selectUnit!=SELECTCHAR)) > Coordinate(endSRow, endSCol)) {
739
/* Whoops, he's changed his mind. Do RIGHTEXTENSION */
740
eventMode = RIGHTEXTENSION;
741
startERow = saveStartRRow;
742
startECol = saveStartRCol;
743
} else if (eventMode == RIGHTEXTENSION
744
&& coord < Coordinate(startSRow, startSCol)) {
745
/* Whoops, he's changed his mind. Do LEFTEXTENSION */
746
eventMode = LEFTEXTENSION;
747
endERow = saveEndRRow;
748
endECol = saveEndRCol;
750
if (eventMode == LEFTEXTENSION) {
757
ComputeSelect(startERow, startECol, endERow, endECol, False);
761
void HandleStartExtend(w, event, params, num_params)
763
XEvent *event; /* must be XButtonEvent* */
764
String *params; /* unused */
765
Cardinal *num_params; /* unused */
767
do_start_extend (w, event, params, num_params, False);
770
void HandleKeyboardStartExtend(w, event, params, num_params)
772
XEvent *event; /* must be XButtonEvent* */
773
String *params; /* unused */
774
Cardinal *num_params; /* unused */
776
do_start_extend (w, event, params, num_params, True);
780
ScrollSelection(screen, amount)
781
register TScreen* screen;
784
register int minrow = -screen->savedlines - screen->topline;
785
register int maxrow = screen->max_row - screen->topline;
786
register int maxcol = screen->max_col;
788
#define scroll_update_one(row, col) \
790
if (row < minrow) { \
794
if (row > maxrow) { \
799
scroll_update_one(startRRow, startRCol);
800
scroll_update_one(endRRow, endRCol);
801
scroll_update_one(startSRow, startSCol);
802
scroll_update_one(endSRow, endSCol);
804
scroll_update_one(rawRow, rawCol);
806
scroll_update_one(screen->startHRow, screen->startHCol);
807
scroll_update_one(screen->endHRow, screen->endHCol);
809
screen->startHCoord = Coordinate (screen->startHRow, screen->startHCol);
810
screen->endHCoord = Coordinate (screen->endHRow, screen->endHCol);
815
ResizeSelection (screen, rows, cols)
819
rows--; /* decr to get 0-max */
822
if (startRRow > rows) startRRow = rows;
823
if (startSRow > rows) startSRow = rows;
824
if (endRRow > rows) endRRow = rows;
825
if (endSRow > rows) endSRow = rows;
826
if (rawRow > rows) rawRow = rows;
828
if (startRCol > cols) startRCol = cols;
829
if (startSCol > cols) startSCol = cols;
830
if (endRCol > cols) endRCol = cols;
831
if (endSCol > cols) endSCol = cols;
832
if (rawCol > cols) rawCol = cols;
836
PointToRowCol(y, x, r, c)
839
/* Convert pixel coordinates to character coordinates.
840
Rows are clipped between firstValidRow and lastValidRow.
841
Columns are clipped between to be 0 or greater, but are not clipped to some
844
register TScreen *screen = &term->screen;
847
row = (y - screen->border) / FontHeight(screen);
848
if(row < firstValidRow)
850
else if(row > lastValidRow)
852
col = (x - screen->border - screen->scrollbar) / FontWidth(screen);
855
else if(col > screen->max_col+1) {
856
col = screen->max_col+1;
866
register TScreen *screen = &term->screen;
874
for ( i = screen->max_col,
876
ch = screen->buf[row + screen->topline] + i ;
877
i >= 0 && !(ch->attr & CHARDRAWN) ;
880
ch = screen->buf[2 * (row + screen->topline) + 1] + i ;
881
i >= 0 && !(*ch & CHARDRAWN) ;
889
** double click table for cut and paste in 8 bits
891
** This table is divided in four parts :
893
** - control characters [0,0x1f] U [0x80,0x9f]
894
** - separators [0x20,0x3f] U [0xa0,0xb9]
895
** - binding characters [0x40,0x7f] U [0xc0,0xff]
898
static int charClass[256] = {
899
/* NUL SOH STX ETX EOT ENQ ACK BEL */
900
32, 1, 1, 1, 1, 1, 1, 1,
901
/* BS HT NL VT NP CR SO SI */
902
1, 32, 1, 1, 1, 1, 1, 1,
903
/* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */
904
1, 1, 1, 1, 1, 1, 1, 1,
905
/* CAN EM SUB ESC FS GS RS US */
906
1, 1, 1, 1, 1, 1, 1, 1,
907
/* SP ! " # $ % & ' */
908
32, 33, 34, 35, 36, 37, 38, 39,
909
/* ( ) * + , - . / */
910
40, 41, 42, 43, 44, 45, 46, 47,
911
/* 0 1 2 3 4 5 6 7 */
912
48, 48, 48, 48, 48, 48, 48, 48,
913
/* 8 9 : ; < = > ? */
914
48, 48, 58, 59, 60, 61, 62, 63,
915
/* @ A B C D E F G */
916
64, 48, 48, 48, 48, 48, 48, 48,
917
/* H I J K L M N O */
918
48, 48, 48, 48, 48, 48, 48, 48,
919
/* P Q R S T U V W */
920
48, 48, 48, 48, 48, 48, 48, 48,
921
/* X Y Z [ \ ] ^ _ */
922
48, 48, 48, 91, 92, 93, 94, 48,
923
/* ` a b c d e f g */
924
96, 48, 48, 48, 48, 48, 48, 48,
925
/* h i j k l m n o */
926
48, 48, 48, 48, 48, 48, 48, 48,
927
/* p q r s t u v w */
928
48, 48, 48, 48, 48, 48, 48, 48,
929
/* x y z { | } ~ DEL */
930
48, 48, 48, 123, 124, 125, 126, 1,
931
/* x80 x81 x82 x83 IND NEL SSA ESA */
932
1, 1, 1, 1, 1, 1, 1, 1,
933
/* HTS HTJ VTS PLD PLU RI SS2 SS3 */
934
1, 1, 1, 1, 1, 1, 1, 1,
935
/* DCS PU1 PU2 STS CCH MW SPA EPA */
936
1, 1, 1, 1, 1, 1, 1, 1,
937
/* x98 x99 x9A CSI ST OSC PM APC */
938
1, 1, 1, 1, 1, 1, 1, 1,
939
/* - i c/ L ox Y- | So */
940
160, 161, 162, 163, 164, 165, 166, 167,
941
/* .. c0 ip << _ R0 - */
942
168, 169, 170, 171, 172, 173, 174, 175,
943
/* o +- 2 3 ' u q| . */
944
176, 177, 178, 179, 180, 181, 182, 183,
945
/* , 1 2 >> 1/4 1/2 3/4 ? */
946
184, 185, 186, 187, 188, 189, 190, 191,
947
/* A` A' A^ A~ A: Ao AE C, */
948
48, 48, 48, 48, 48, 48, 48, 48,
949
/* E` E' E^ E: I` I' I^ I: */
950
48, 48, 48, 48, 48, 48, 48, 48,
951
/* D- N~ O` O' O^ O~ O: X */
952
48, 48, 48, 48, 48, 48, 48, 216,
953
/* O/ U` U' U^ U: Y' P B */
954
48, 48, 48, 48, 48, 48, 48, 48,
955
/* a` a' a^ a~ a: ao ae c, */
956
48, 48, 48, 48, 48, 48, 48, 48,
957
/* e` e' e^ e: i` i' i^ i: */
958
48, 48, 48, 48, 48, 48, 48, 48,
959
/* d n~ o` o' o^ o~ o: -: */
960
48, 48, 48, 48, 48, 48, 48, 248,
961
/* o/ u` u' u^ u: y' P y: */
962
48, 48, 48, 48, 48, 48, 48, 48};
964
int SetCharacterClassRange (low, high, value)
965
register int low, high; /* in range of [0..255] */
966
register int value; /* arbitrary */
969
if (low < 0 || high > 255 || high < low) return (-1);
971
for (; low <= high; low++) charClass[low] = value;
977
* sets startSRow startSCol endSRow endSCol
978
* ensuring that they have legal values
982
ComputeSelect(startRow, startCol, endRow, endCol, extend)
983
int startRow, startCol, endRow, endCol;
986
register TScreen *screen = &term->screen;
997
if (Coordinate(startRow, startCol) <= Coordinate(endRow, endCol)) {
998
startSRow = startRRow = startRow;
999
startSCol = startRCol = startCol;
1000
endSRow = endRRow = endRow;
1001
endSCol = endRCol = endCol;
1002
} else { /* Swap them */
1003
startSRow = startRRow = endRow;
1004
startSCol = startRCol = endCol;
1005
endSRow = endRRow = startRow;
1006
endSCol = endRCol = startCol;
1009
switch (selectUnit) {
1011
if (startSCol > (LastTextCol(startSRow) + 1)) {
1015
if (endSCol > (LastTextCol(endSRow) + 1)) {
1021
if (startSCol > (LastTextCol(startSRow) + 1)) {
1026
ptr = screen->buf[startSRow+screen->topline]
1029
if (ptr->gset == MBC2)
1030
{ /* 2nd byte of a mbcs character */
1034
if (ptr->gset != MBC2 && (ptr->gset & MBCS) != 0)
1035
{ /* 1st byte of a mbcs character */
1036
class = mbcsCharClass (ptr);
1041
} while (startSCol >= 0
1042
&& ptr->gset != MBC2 && (ptr->gset & MBCS) != 0
1043
&& class == mbcsCharClass (ptr));
1047
else if (ptr->gset == GSET_KANA)
1052
} while (startSCol >= 0
1053
&& ptr->gset == GSET_KANA);
1057
class = charClass[ptr->code];
1061
} while (startSCol >= 0
1062
&& ptr->gset == gset
1063
&& charClass[ptr->code] == class);
1065
#else /* !KTERM_MBCC */
1066
class = charClass[ptr->code];
1070
} while (startSCol >= 0
1071
&& charClass[ptr->code] == class);
1072
#endif /* !KTERM_MBCC */
1074
ptr = screen->buf[2*(startSRow+screen->topline)]
1076
class = charClass[*ptr];
1080
} while (startSCol >= 0
1081
&& charClass[*ptr] == class);
1085
if (endSCol > (LastTextCol(endSRow) + 1)) {
1089
length = LastTextCol(endSRow);
1091
ptr = screen->buf[endSRow+screen->topline]
1094
if (ptr->gset == MBC2)
1095
{ /* 2nd byte of a mbcs character */
1099
if (ptr->gset != MBC2 && (ptr->gset & MBCS) != 0)
1100
{ /* 1st byte of a mbcs character */
1101
class = mbcsCharClass (ptr);
1106
} while (endSCol < length
1107
&& ptr->gset != MBC2 && (ptr->gset & MBCS) != 0
1108
&& class == mbcsCharClass (ptr));
1110
else if (ptr->gset == GSET_KANA)
1115
} while (endSCol <= length
1116
&& ptr->gset == GSET_KANA);
1120
class = charClass[ptr->code];
1124
} while (endSCol <= length
1125
&& ptr->gset == gset
1126
&& charClass[ptr->code] == class);
1128
#else /* !KTERM_MBCC */
1129
class = charClass[ptr->code];
1133
} while (endSCol <= length
1134
&& charClass[ptr->code] == class);
1135
#endif /* !KTERM_MBCC */
1137
ptr = screen->buf[2*(endSRow+screen->topline)]
1139
class = charClass[*ptr];
1143
} while (endSCol <= length
1144
&& charClass[*ptr] == class);
1146
/* Word select selects if pointing to any char
1147
in "word", especially in that it includes
1148
the last character in a word. So no --endSCol
1149
and do special eol handling */
1150
if (endSCol > length+1) {
1157
if (term->screen.cutToBeginningOfLine) {
1159
} else if (!extend) {
1162
if (term->screen.cutNewline) {
1166
endSCol = LastTextCol(endSRow) + 1;
1171
TrackText(startSRow, startSCol, endSRow, endSCol);
1175
#if defined(KTERM) && defined(KTERM_MBCC)
1177
* by Kiyoshi KANAZAWA, Nov. 29, 1990.
1179
* MBCS is divided to ARABIAN-number, ENGLISH, HIRAGANA, KATAKANA,
1180
* KANJI (including both dai_1_suijun and dai_2_suijun), GREEK,
1181
* RUSSIAN, KEISEN and OTHERS.
1183
* It is assumed that
1184
* HIRAGANA, KATAKANA and KANJI belong to the same character class.
1185
* ARABIAN-number and ENGLISH belong to the same character class.
1186
* Each character in OTHERS makes one character class by itself.
1189
#define MBCS_ARABIAN 0 /* arabia suuji */
1190
#define MBCS_ENGLISH MBCS_ARABIAN /* eigo */
1191
#define MBCS_HIRAGANA (MBCS_ENGLISH + 1) /* hiragana */
1192
#define MBCS_KATAKANA MBCS_HIRAGANA /* katakana */
1193
#define MBCS_KANJI MBCS_KATAKANA /* kanji */
1194
#define MBCS_GREEK (MBCS_KANJI + 1) /* girisha moji */
1195
#define MBCS_RUSSIAN (MBCS_GREEK + 1) /* roshia moji */
1196
#define MBCS_KEISEN (MBCS_RUSSIAN + 1) /* keisen */
1198
static int mbcsCharClass (ptr)
1201
register unsigned char c1, c2;
1203
c2 = (ptr + 1)->code;
1204
switch (c1 = ptr->code)
1212
return (MBCS_KANJI);
1214
return (MBCS_KATAKANA);
1218
if (0x30 <= c2 && c2 <= 0x39)
1219
return (MBCS_ARABIAN);
1220
if (0x41 <= c2 && c2 <= 0x5a || 0x61 <= c2 && c2 <= 0x7a)
1221
return (MBCS_ENGLISH);
1224
if (0x21 <= c2 && c2 <= 0x73)
1225
return (MBCS_HIRAGANA);
1228
if (0x21 <= c2 && c2 <= 0x76)
1229
return (MBCS_KATAKANA);
1232
if (0x21 <= c2 && c2 <= 0x38 || 0x41 <= c2 && c2 <= 0x58)
1233
return (MBCS_GREEK);
1236
if (0x21 <= c2 && c2 <= 0x41 || 0x51 <= c2 && c2 <= 0x71)
1237
return (MBCS_RUSSIAN);
1240
if (0x21 <= c2 && c2 <= 0x40)
1241
return (MBCS_KEISEN);
1244
if (0x30 <= c1 && c1 <= 0x4e && 0x21 <= c2 && c2 <= 0x7e
1245
|| c1 == 0x4f && (0x21 <= c2 || c2 <= 0x53)) /* dai_1_suijun */
1246
return (MBCS_KANJI);
1247
if (0x50 <= c1 && c1 <= 0x73 && 0x21 <= c2 && c2 <= 0x7e
1248
|| c1 == 0x74 && (0x21 <= c2 || c2 <= 0x24)) /* dai_2_suijun */
1249
return (MBCS_KANJI);
1252
return ((c1 << 8) | c2); /* return mbcs code */
1255
#endif /* KTERM && KTERM_MBCC */
1257
TrackText(frow, fcol, trow, tcol)
1258
register int frow, fcol, trow, tcol;
1259
/* Guaranteed (frow, fcol) <= (trow, tcol) */
1261
register int from, to;
1262
register TScreen *screen = &term->screen;
1263
int old_startrow, old_startcol, old_endrow, old_endcol;
1265
old_startrow = screen->startHRow;
1266
old_startcol = screen->startHCol;
1267
old_endrow = screen->endHRow;
1268
old_endcol = screen->endHCol;
1269
if (frow == old_startrow && fcol == old_startcol &&
1270
trow == old_endrow && tcol == old_endcol) return;
1271
screen->startHRow = frow;
1272
screen->startHCol = fcol;
1273
screen->endHRow = trow;
1274
screen->endHCol = tcol;
1275
from = Coordinate(frow, fcol);
1276
to = Coordinate(trow, tcol);
1277
if (to <= screen->startHCoord || from > screen->endHCoord) {
1278
/* No overlap whatsoever between old and new hilite */
1279
ReHiliteText(old_startrow, old_startcol, old_endrow, old_endcol);
1280
ReHiliteText(frow, fcol, trow, tcol);
1282
if (from < screen->startHCoord) {
1283
/* Extend left end */
1284
ReHiliteText(frow, fcol, old_startrow, old_startcol);
1285
} else if (from > screen->startHCoord) {
1286
/* Shorten left end */
1287
ReHiliteText(old_startrow, old_startcol, frow, fcol);
1289
if (to > screen->endHCoord) {
1290
/* Extend right end */
1291
ReHiliteText(old_endrow, old_endcol, trow, tcol);
1292
} else if (to < screen->endHCoord) {
1293
/* Shorten right end */
1294
ReHiliteText(trow, tcol, old_endrow, old_endcol);
1297
screen->startHCoord = from;
1298
screen->endHCoord = to;
1302
ReHiliteText(frow, fcol, trow, tcol)
1303
register int frow, fcol, trow, tcol;
1304
/* Guaranteed that (frow, fcol) <= (trow, tcol) */
1306
register TScreen *screen = &term->screen;
1311
else if (frow > screen->max_row)
1312
return; /* nothing to do, since trow >= frow */
1315
return; /* nothing to do, since frow <= trow */
1316
else if (trow > screen->max_row) {
1317
trow = screen->max_row;
1318
tcol = screen->max_col+1;
1320
if (frow == trow && fcol == tcol)
1323
if(frow != trow) { /* do multiple rows */
1324
if((i = screen->max_col - fcol + 1) > 0) { /* first row */
1325
ScrnRefresh(screen, frow, fcol, 1, i, True);
1327
if((i = trow - frow - 1) > 0) { /* middle rows*/
1328
ScrnRefresh(screen, frow+1, 0,i, screen->max_col+1, True);
1330
if(tcol > 0 && trow <= screen->max_row) { /* last row */
1331
ScrnRefresh(screen, trow, 0, 1, tcol, True);
1333
} else { /* do single row */
1334
ScrnRefresh(screen, frow, fcol, 1, tcol - fcol, True);
1338
static void _OwnSelection();
1341
SaltTextAway(crow, ccol, row, col, params, num_params)
1342
/*register*/ int crow, ccol, row, col;
1343
String *params; /* selections */
1344
Cardinal num_params;
1345
/* Guaranteed that (crow, ccol) <= (row, col), and that both points are valid
1346
(may have row = screen->max_row+1, col = 0) */
1348
register TScreen *screen = &term->screen;
1349
register int i, j = 0;
1358
if (crow == row && ccol > col) {
1365
/* first we need to know how long the string is before we can save it*/
1368
ch = screen->buf[crow + screen->topline];
1369
if (ch[ccol].gset == MBC2)
1371
ch = screen->buf[row + screen->topline];
1372
if (ch[col].gset & MBCS && ch[col].gset != MBC2) /* MBC1 */
1375
if ( row == crow ) j = Length(screen, crow, ccol, col);
1376
else { /* two cases, cut is on same line, cut spans multiple lines */
1377
j += Length(screen, crow, ccol, screen->max_col) + 1;
1378
for(i = crow + 1; i < row; i++)
1379
j += Length(screen, i, 0, screen->max_col) + 1;
1381
j += Length(screen, row, 0, col);
1384
/* now get some memory to save it in */
1386
if (screen->selection_size <= j) {
1388
if((line = (Ichr *)malloc((unsigned)((j + 1) * sizeof(Ichr)))) == (Ichr *)NULL)
1389
SysError(ERROR_BMALLOC2);
1390
XtFree((char *)screen->selection);
1392
if((line = malloc((unsigned) j + 1)) == (char *)NULL)
1393
SysError(ERROR_BMALLOC2);
1394
XtFree(screen->selection);
1396
screen->selection = line;
1397
screen->selection_size = j + 1;
1398
} else line = screen->selection;
1399
if (!line || j < 0) return;
1402
line[j].code = '\0'; /* make sure it is null terminated */
1405
line[j] = '\0'; /* make sure it is null terminated */
1407
lp = line; /* lp points to where to save the text */
1408
if ( row == crow ) lp = SaveText(screen, row, ccol, col, lp, &eol);
1410
lp = SaveText(screen, crow, ccol, screen->max_col, lp, &eol);
1415
lp++->gset = GSET_ASCII;
1418
*lp ++ = '\n'; /* put in newline at end of line */
1420
for(i = crow +1; i < row; i++) {
1421
lp = SaveText(screen, i, 0, screen->max_col, lp, &eol);
1426
lp++->gset = GSET_ASCII;
1433
lp = SaveText(screen, row, 0, col, lp, &eol);
1436
lp->code = '\0'; /* make sure we have end marked */
1439
*lp = '\0'; /* make sure we have end marked */
1442
screen->selection_length = (lp - line);
1443
_OwnSelection(term, params, num_params);
1446
static Boolean ConvertSelection(w, selection, target,
1447
type, value, length, format)
1449
Atom *selection, *target, *type;
1451
unsigned long *length;
1454
Display* d = XtDisplay(w);
1455
XtermWidget xterm = (XtermWidget)w;
1457
if (xterm->screen.selection == NULL) return False; /* can this happen? */
1459
if (*target == XA_TARGETS(d)) {
1462
unsigned long std_length;
1463
XmuConvertStandardSelection(
1464
w, xterm->screen.selection_time, selection,
1465
target, type, (caddr_t*)&std_targets, &std_length, format
1467
*length = std_length + 5;
1468
*value = (XtPointer)XtMalloc(sizeof(Atom)*(*length));
1469
targetP = *(Atom**)value;
1470
*targetP++ = XA_STRING;
1471
*targetP++ = XA_TEXT(d);
1472
*targetP++ = XA_COMPOUND_TEXT(d);
1473
*targetP++ = XA_LENGTH(d);
1474
*targetP++ = XA_LIST_LENGTH(d);
1475
memmove( (char*)targetP, (char*)std_targets, sizeof(Atom)*std_length);
1476
XtFree((char*)std_targets);
1482
if (*target == XA_STRING ||
1483
*target == XA_TEXT(d) ||
1484
*target == XA_COMPOUND_TEXT(d)) {
1486
if (*target == XA_COMPOUND_TEXT(d) || *target == XA_TEXT(d)) {
1487
*type = XA_COMPOUND_TEXT(d);
1488
*length = convCStoCT(xterm->screen.selection, NULL);
1489
*value = (caddr_t)XtMalloc(*length + 1);
1490
(void)convCStoCT(xterm->screen.selection, (Char *)*value);
1493
*length = convCStoLatin1(xterm->screen.selection, NULL);
1494
*value = (caddr_t)XtMalloc(*length + 1);
1495
(void)convCStoLatin1(xterm->screen.selection, (Char *)*value);
1498
if (*target == XA_COMPOUND_TEXT(d))
1502
*value = xterm->screen.selection;
1503
*length = xterm->screen.selection_length;
1508
if (*target == XA_LIST_LENGTH(d)) {
1509
*value = XtMalloc(4);
1510
if (sizeof(long) == 4)
1514
memmove( (char*)*value, ((char*)&temp)+sizeof(long)-4, 4);
1521
if (*target == XA_LENGTH(d)) {
1522
*value = XtMalloc(4);
1523
if (sizeof(long) == 4)
1525
*(long*)*value = convCStoCT(xterm->screen.selection, NULL);
1527
*(long*)*value = xterm->screen.selection_length;
1531
long temp = convCStoCT(xterm->screen.selection, NULL);
1533
long temp = xterm->screen.selection_length;
1535
memmove( (char*)*value, ((char*)&temp)+sizeof(long)-4, 4);
1542
if (XmuConvertStandardSelection(w, xterm->screen.selection_time, selection,
1544
(caddr_t *)value, length, format))
1553
static void LoseSelection(w, selection)
1557
register TScreen* screen = &((XtermWidget)w)->screen;
1558
register Atom* atomP;
1560
for (i = 0, atomP = screen->selection_atoms;
1561
i < screen->selection_count; i++, atomP++)
1563
if (*selection == *atomP) *atomP = (Atom)0;
1565
case XA_CUT_BUFFER0:
1566
case XA_CUT_BUFFER1:
1567
case XA_CUT_BUFFER2:
1568
case XA_CUT_BUFFER3:
1569
case XA_CUT_BUFFER4:
1570
case XA_CUT_BUFFER5:
1571
case XA_CUT_BUFFER6:
1572
case XA_CUT_BUFFER7: *atomP = (Atom)0;
1576
for (i = screen->selection_count; i; i--) {
1577
if (screen->selection_atoms[i-1] != 0) break;
1579
screen->selection_count = i;
1581
for (i = 0, atomP = screen->selection_atoms;
1582
i < screen->selection_count; i++, atomP++)
1584
if (*atomP == (Atom)0) {
1585
*atomP = screen->selection_atoms[--screen->selection_count];
1589
if (screen->selection_count == 0)
1590
TrackText(0, 0, 0, 0);
1596
static void SelectionDone(w, selection, target)
1598
Atom *selection, *target;
1600
/* empty proc so Intrinsics know we want to keep storage */
1605
static void _OwnSelection(termw, selections, count)
1606
register XtermWidget termw;
1610
Atom* atoms = termw->screen.selection_atoms;
1612
Boolean have_selection = False;
1614
if (termw->screen.selection_length < 0) return;
1616
if (count > termw->screen.sel_atoms_size) {
1617
XtFree((char*)atoms);
1618
atoms = (Atom*)XtMalloc(count*sizeof(Atom));
1619
termw->screen.selection_atoms = atoms;
1620
termw->screen.sel_atoms_size = count;
1622
XmuInternStrings( XtDisplay((Widget)termw), selections, count, atoms );
1623
for (i = 0; i < count; i++) {
1626
case XA_CUT_BUFFER0: cutbuffer = 0; break;
1627
case XA_CUT_BUFFER1: cutbuffer = 1; break;
1628
case XA_CUT_BUFFER2: cutbuffer = 2; break;
1629
case XA_CUT_BUFFER3: cutbuffer = 3; break;
1630
case XA_CUT_BUFFER4: cutbuffer = 4; break;
1631
case XA_CUT_BUFFER5: cutbuffer = 5; break;
1632
case XA_CUT_BUFFER6: cutbuffer = 6; break;
1633
case XA_CUT_BUFFER7: cutbuffer = 7; break;
1634
default: cutbuffer = -1;
1637
if ( termw->screen.selection_length >
1638
4*XMaxRequestSize(XtDisplay((Widget)termw))-32)
1640
"%s: selection too big (%d bytes), not storing in CUT_BUFFER%d\n",
1641
xterm_name, termw->screen.selection_length, cutbuffer);
1645
/* Since type of a CUT_BUFFER is STRING, KANJI and KANA
1646
* characters can't be stored in a CUT_BUFFER
1652
p = termw->screen.selection;
1653
for (nw = termw->screen.selection_length; nw > 0; nw--, p++) {
1654
if (p->gset == GSET_ASCII)
1659
p = termw->screen.selection;
1660
s = q = (nc > 256) ? XtMalloc(nc) : buf;
1661
for (nw = termw->screen.selection_length; nw > 0; nw--, p++) {
1662
if (p->gset == GSET_ASCII)
1663
*q++ = p->code & 0x7f;
1665
XStoreBuffer( XtDisplay((Widget)termw), s, nc, cutbuffer );
1666
if (s != buf) XtFree(s);
1668
XStoreBuffer( XtDisplay((Widget)termw), NULL, nc, cutbuffer );
1671
XStoreBuffer( XtDisplay((Widget)termw), termw->screen.selection,
1672
termw->screen.selection_length, cutbuffer );
1674
else if (!replyToEmacs) {
1676
XtOwnSelection( (Widget)termw, atoms[i],
1677
termw->screen.selection_time,
1679
ConvertSelection, LoseSelection, NULL );
1681
ConvertSelection, LoseSelection, SelectionDone );
1686
termw->screen.selection_count = count;
1687
if (!have_selection)
1688
TrackText(0, 0, 0, 0);
1692
DisownSelection(termw)
1693
register XtermWidget termw;
1695
Atom* atoms = termw->screen.selection_atoms;
1696
Cardinal count = termw->screen.selection_count;
1699
for (i = 0; i < count; i++) {
1702
case XA_CUT_BUFFER0: cutbuffer = 0; break;
1703
case XA_CUT_BUFFER1: cutbuffer = 1; break;
1704
case XA_CUT_BUFFER2: cutbuffer = 2; break;
1705
case XA_CUT_BUFFER3: cutbuffer = 3; break;
1706
case XA_CUT_BUFFER4: cutbuffer = 4; break;
1707
case XA_CUT_BUFFER5: cutbuffer = 5; break;
1708
case XA_CUT_BUFFER6: cutbuffer = 6; break;
1709
case XA_CUT_BUFFER7: cutbuffer = 7; break;
1710
default: cutbuffer = -1;
1713
XtDisownSelection( (Widget)termw, atoms[i],
1714
termw->screen.selection_time );
1716
termw->screen.selection_count = 0;
1717
termw->screen.startHRow = termw->screen.startHCol = 0;
1718
termw->screen.endHRow = termw->screen.endHCol = 0;
1722
/* returns number of chars in line from scol to ecol out */
1725
Length(screen, row, scol, ecol)
1726
register int row, scol, ecol;
1727
register TScreen *screen;
1729
register int lastcol = LastTextCol(row);
1733
return (ecol - scol + 1);
1736
/* copies text into line, preallocated */
1742
SaveText(screen, row, scol, ecol, lp, eol)
1747
register Ichr *lp; /* pointer to where to put the text */
1749
register char *lp; /* pointer to where to put the text */
1755
register Bchr *ch = screen->buf[row + screen->topline];
1758
register Char *ch = screen->buf[2 * (row + screen->topline)];
1764
i = Length(screen, row, scol, ecol);
1767
if(ScrnGetAttributes(screen, row + screen->topline, 0, &attr, 1) == 1) {
1768
*eol = (attr & LINEWRAPPED) ? 0 : 1;
1770
/* If we can't get the attributes, assume no wrap */
1772
(void)fprintf(stderr, "%s: no attributes for %d, %d\n",
1773
xterm_name, row, ecol - 1);
1777
for (i = scol; i < ecol; i++) {
1779
c = ch[i].code & 0x7f;
1781
if (c < ' ' || c == 0x7f && !(g & CS96)) {
1783
lp->gset = GSET_ASCII;
1795
c = '#'; /* char on screen is pound sterling */
1797
c += 0x5f; /* char is from DEC drawing set */
1798
} else if(c == 0x7f)
1808
register XButtonEvent *event;
1810
register TScreen *screen = &term->screen;
1811
int pty = screen->respond;
1813
register unsigned row, col;
1816
button = event->button - 1;
1818
row = (event->y - screen->border)
1819
/ FontHeight(screen);
1820
col = (event->x - screen->border - screen->scrollbar)
1821
/ FontWidth(screen);
1822
(void) strcpy(line, "\033[M");
1823
if (screen->send_mouse_pos == 1) {
1824
line[3] = ' ' + button;
1826
line[3] = ' ' + (KeyState(event->state) << 2) +
1827
((event->type == ButtonPress)? button:3);
1829
line[4] = ' ' + col + 1;
1830
line[5] = ' ' + row + 1;
1831
v_write(pty, line, 6);
1837
void HandleGINInput (w, event, param_list, nparamsp)
1843
if (term->screen.TekGIN && *nparamsp == 1) {
1844
int c = param_list[0][0];
1846
case 'l': case 'm': case 'r':
1847
case 'L': case 'M': case 'R':
1850
Bell (XkbBI_MinorError,0); /* let them know they goofed */
1851
c = 'l'; /* provide a default */
1853
TekEnqMouse (c | 0x80);
1856
Bell (XkbBI_MinorError,0);
1859
#endif /* !KTERM_NOTEK */
1863
void HandleSecure(w, event, params, param_count)
1865
XEvent *event; /* unused */
1866
String *params; /* [0] = volume */
1867
Cardinal *param_count; /* 0 or 1 */
1869
Time time = CurrentTime;
1871
if ((event->xany.type == KeyPress) ||
1872
(event->xany.type == KeyRelease))
1873
time = event->xkey.time;
1874
else if ((event->xany.type == ButtonPress) ||
1875
(event->xany.type == ButtonRelease))
1876
time = event->xbutton.time;
1877
DoSecureKeyboard (time);