1 ////////////////////////////////////////////////////////////////////////////////
2 static int x2tab (int x
) {
3 if (x
>= 0 && x
< xw
.w
&& xw
.tabheight
> 0) {
4 x
/= (xw
.w
/opt_tabcount
)+firstVisibleTab
;
5 return (x
>= 0 && x
< term_count
) ? x
: -1;
11 static void msTabSwitch (XEvent
*e
) {
12 int tabn
= x2tab(e
->xbutton
.x
)+firstVisibleTab
;
14 if (tabn
>= 0 && tabn
!= termidx
) switchToTerm(tabn
, 1);
18 static void msTabScrollLeft (void) {
19 if (firstVisibleTab
> 0) {
27 static void msTabScrollRight (void) {
28 int newidx
= firstVisibleTab
+1;
30 if (newidx
> term_count
-opt_tabcount
) return;
31 firstVisibleTab
= newidx
;
37 ////////////////////////////////////////////////////////////////////////////////
38 static void xdoMouseReport (K8Term
*term
, XEvent
*e
) {
39 int x
= K8T_X2COL(e
->xbutton
.x
);
40 int y
= K8T_Y2ROW(term
, e
->xbutton
.y
);
41 int button
= e
->xbutton
.button
-Button1
+K8T_MOUSE_BUTTON_LEFT
;
44 if (e
->xbutton
.type
== MotionNotify
) event
= K8T_MOUSE_EVENT_MOTION
;
45 else if (e
->xbutton
.type
== ButtonPress
) event
= K8T_MOUSE_EVENT_DOWN
;
46 else if (e
->xbutton
.type
== ButtonRelease
) event
= K8T_MOUSE_EVENT_UP
;
50 (e
->xbutton
.state
&ShiftMask
? K8T_MOUSE_STATE_SHIFT
: 0) |
51 (e
->xbutton
.state
&Mod1Mask
? K8T_MOUSE_STATE_ALT
: 0) |
52 (e
->xbutton
.state
&ControlMask
? K8T_MOUSE_STATE_CTRL
: 0) |
53 (e
->xbutton
.state
&Mod4Mask
? K8T_MOUSE_STATE_WIN
: 0);
55 k8t_mouseReport(term
, x
, y
, event
, button
, state
);
59 static void getButtonInfo (K8Term
*term
, XEvent
*e
, int *b
, int *x
, int *y
) {
60 if (b
!= NULL
) *b
= e
->xbutton
.button
;
61 if (x
!= NULL
) *x
= K8T_X2COL(e
->xbutton
.x
);
62 if (y
!= NULL
) *y
= K8T_Y2ROW(term
, e
->xbutton
.y
);
63 term
->sel
.b
.x
= (term
->sel
.by
< term
->sel
.ey
? term
->sel
.bx
: term
->sel
.ex
);
64 term
->sel
.b
.y
= K8T_MIN(term
->sel
.by
, term
->sel
.ey
);
65 term
->sel
.e
.x
= (term
->sel
.by
< term
->sel
.ey
? term
->sel
.ex
: term
->sel
.bx
);
66 term
->sel
.e
.y
= K8T_MAX(term
->sel
.by
, term
->sel
.ey
);
70 static void xevtcbbpress (XEvent
*e
) {
71 if (curterm
== NULL
) return;
73 if (xw
.tabheight
> 0) {
74 if ((opt_tabposition
== 0 && e
->xbutton
.y
>= xw
.h
-xw
.tabheight
) ||
75 (opt_tabposition
!= 0 && e
->xbutton
.y
< xw
.tabheight
)) {
76 switch (e
->xbutton
.button
) {
80 case Button4
: // wheel up
83 case Button5
: // wheel down
90 // <shift|alt>+mouse: some cool shit
91 if ((e
->xbutton
.state
&(ShiftMask
|Mod1Mask
)) != 0) {
92 switch (e
->xbutton
.button
) {
94 if (curterm
->sel
.bx
!= -1) k8t_tmDirty(curterm
, curterm
->sel
.b
.y
, curterm
->sel
.e
.y
);
95 curterm
->sel
.mode
= 1;
96 curterm
->sel
.b
.y
= curterm
->sel
.e
.y
= curterm
->row
+1;
97 curterm
->sel
.ex
= curterm
->sel
.bx
= K8T_X2COL(e
->xbutton
.x
);
98 curterm
->sel
.ey
= curterm
->sel
.by
= K8T_Y2ROW(curterm
, e
->xbutton
.y
);
99 //fprintf(stderr, "x=%d; y=%d\n", curterm->sel.bx, curterm->sel.by);
100 k8t_drawTerm(curterm
, 1);
103 case Button3: // middle
104 curterm->sel.bx = -1;
105 k8t_selCopy(curterm);
106 k8t_drawTerm(curterm, 1);
109 case Button4
: // wheel up
110 scrollHistory(curterm
, 3);
112 case Button5
: // wheel down
113 scrollHistory(curterm
, -3);
119 if (K8T_ISSET(curterm
, K8T_MODE_MOUSE
)) xdoMouseReport(curterm
, e
);
123 static void xevtcbbrelease (XEvent
*e
) {
124 if (curterm
== NULL
) return;
126 switch (opt_tabposition
) {
128 if (e
->xbutton
.y
>= xw
.h
-xw
.tabheight
) return;
131 if (e
->xbutton
.y
< xw
.tabheight
) return;
135 if ((e
->xbutton
.state
&ShiftMask
) == 0 && !curterm
->sel
.mode
) {
136 if (K8T_ISSET(curterm
, K8T_MODE_MOUSE
)) xdoMouseReport(curterm
, e
);
140 if (e
->xbutton
.button
== Button2
) {
141 selpaste(curterm
, XA_PRIMARY
);
142 } else if (e
->xbutton
.button
== Button1
) {
143 curterm
->sel
.mode
= 0;
144 getButtonInfo(curterm
, e
, NULL
, &curterm
->sel
.ex
, &curterm
->sel
.ey
); // this sets sel.b and sel.e
146 if (curterm
->sel
.bx
== curterm
->sel
.ex
&& curterm
->sel
.by
== curterm
->sel
.ey
) {
147 // single line, single char selection
150 k8t_tmDirtyMark(curterm
, curterm
->sel
.ey
, 2);
151 curterm
->sel
.bx
= -1;
152 now
= mclock_ticks();
153 if (now
-curterm
->sel
.tclick2
<= opt_tripleclick_timeout
) {
154 /* triple click on the line */
155 curterm
->sel
.b
.x
= curterm
->sel
.bx
= 0;
156 curterm
->sel
.e
.x
= curterm
->sel
.ex
= curterm
->col
;
157 curterm
->sel
.b
.y
= curterm
->sel
.e
.y
= curterm
->sel
.ey
;
158 } else if (now
-curterm
->sel
.tclick1
<= opt_doubleclick_timeout
) {
159 /* double click to select word */
160 K8TLine l
= k8t_selGet(curterm
, curterm
->sel
.ey
);
163 //FIXME: write better word selection code
164 curterm
->sel
.bx
= curterm
->sel
.ex
;
165 if (K8T_ISGFX(l
[curterm
->sel
.bx
].attr
)) {
166 while (curterm
->sel
.bx
> 0 && K8T_ISGFX(l
[curterm
->sel
.bx
-1].attr
)) --curterm
->sel
.bx
;
167 curterm
->sel
.b
.x
= curterm
->sel
.bx
;
168 while (curterm
->sel
.ex
< curterm
->col
-1 && K8T_ISGFX(l
[curterm
->sel
.ex
+1].attr
)) ++curterm
->sel
.ex
;
170 while (curterm
->sel
.bx
> 0 && !K8T_ISGFX(l
[curterm
->sel
.bx
-1].attr
) && l
[curterm
->sel
.bx
-1].c
[0] != ' ') --curterm
->sel
.bx
;
171 curterm
->sel
.b
.x
= curterm
->sel
.bx
;
172 while (curterm
->sel
.ex
< curterm
->col
-1 && !K8T_ISGFX(l
[curterm
->sel
.ex
+1].attr
) && l
[curterm
->sel
.ex
+1].c
[0] != ' ') ++curterm
->sel
.ex
;
174 curterm
->sel
.e
.x
= curterm
->sel
.ex
;
175 curterm
->sel
.b
.y
= curterm
->sel
.e
.y
= curterm
->sel
.ey
;
179 k8t_selCopy(curterm
);
180 k8t_drawTerm(curterm
, 1);
182 // multiline or multichar selection
183 k8t_selCopy(curterm
);
186 curterm
->sel
.tclick2
= curterm
->sel
.tclick1
;
187 curterm
->sel
.tclick1
= mclock_ticks();
192 static void xevtcbbmotion (XEvent
*e
) {
193 if (curterm
== NULL
) return;
195 switch (opt_tabposition
) {
197 if (e
->xbutton
.y
>= xw
.h
-xw
.tabheight
) { changeXCursor(1); return; }
200 if (e
->xbutton
.y
< xw
.tabheight
) { changeXCursor(1); return; }
205 if (curterm
->sel
.mode
) {
206 int oldey
= curterm
->sel
.ey
, oldex
= curterm
->sel
.ex
;
208 getButtonInfo(curterm
, e
, NULL
, &curterm
->sel
.ex
, &curterm
->sel
.ey
); // this sets sel.b and sel.e
209 if (oldey
!= curterm
->sel
.ey
|| oldex
!= curterm
->sel
.ex
) {
210 int starty
= K8T_MIN(oldey
, curterm
->sel
.ey
);
211 int endy
= K8T_MAX(oldey
, curterm
->sel
.ey
);
213 k8t_tmDirty(curterm
, starty
, endy
);
214 k8t_drawTerm(curterm
, 1);
218 //if (K8T_ISSET(curterm, K8T_MODE_MOUSE) && e->xbutton.button != 0) xdoMouseReport(curterm, e);