1 
2 
3 /* This version of microEmacs is based on the public domain C
4  * version written by Dave G. Conroy.
5  * The D programming language version is written by Walter Bright.
6  * http://www.digitalmars.com/d/
7  * This program is in the public domain.
8  */
9 
10 
11 module mouse;
12 
13 import disp;
14 import core.stdc.time;
15 
16 import ed;
17 import window;
18 import line;
19 import main;
20 import terminal;
21 import display;
22 import word;
23 
24 //#include	<msmouse.h>
25 
26 static int clicks = 0;		/* number of clicks we've seen		*/
27 static clock_t lastclick;	/* time of last click			*/
28 
29 /*********************************
30  * Call this routine in the main command loop.
31  * It handles any mouse commands.
32  * Returns:
33  *	0	no mouse input
34  *	!=0	value is a keystroke
35  */
36 
37 int mouse_command()
38 {   uint x,y;
39     WINDOW *wp;
40     LINE *lp;
41     int status;
42 
43     if (!hasmouse)			/* if no mouse installed	*/
44 	return 0;
45     status = msm_getstatus(&x,&y);	/* read button status		*/
46     mouse_tocursor(&x,&y);		/* collect real cursor coords	*/
47     if (status & 1)			/* if left button is down	*/
48     {	int doto;
49 
50 	mouse_findpos(x,y,&wp,&lp,&doto);
51 	if (wp && lp)
52 	{   markcol = wp.w_startcol + x;
53 	    mouse_markdrag(wp,lp,doto);
54 	}
55 	else
56 	{   if (wp)
57 	    {
58 		curbp = wp.w_bufp;
59 		curwp = wp;
60 		/* Examine window action buttons	*/
61 		switch (x)
62 		{   case 0:
63 			window_only(FALSE,1);
64 			goto L2;
65 		    case 1:
66 			window_split(FALSE,1);
67 			goto L2;
68 		    case 2:
69 			delwind(FALSE,1);
70 		    L2:	update();
71 			goto L1;
72 		    case 3:
73 			do
74 			{   window_mvup(FALSE,1);
75 			    update();
76 			} while (mouse_leftisdown());
77 			break;
78 		    case 4:
79 			do
80 			{   window_mvdn(FALSE,1);
81 			    update();
82 			} while (mouse_leftisdown());
83 			break;
84 		    default:
85 			mouse_windrag(wp);
86 			break;
87 		}
88 		update();
89 	    }
90 	    else
91 	    L1:
92 		while (mouse_leftisdown())	/* wait till button goes up */
93 		{ }
94 	    clicks = 0;
95 	}
96     }
97     else if (status & 2)		/* if right button is down	*/
98     {
99 	//return memenu_mouse(y,x);
100     }
101     return 0;
102 }
103 
104 /*******************************
105  * Convert from Microsoft coordinates to proper cursor coordinates.
106  */
107 
108 static void mouse_tocursor(uint* px, uint* py)
109 {
110 }
111 
112 /***************************
113  * Set cursor at row,col.
114  */
115 
116 static void mouse_findpos(uint col, uint row, WINDOW** p_wp, LINE** p_lp, int* p_doto)
117 {   int r;
118     int i;
119     LINE *lp;
120 
121     *p_wp = null;
122     *p_lp = null;
123     *p_doto = 0;			/* default cases		*/
124     r = 0;				/* starting row for window	*/
125     foreach (wp; windows)
126     {
127 	if (row <= r + wp.w_ntrows)
128 	{
129 	    *p_wp = wp;
130 	    if (row == r + wp.w_ntrows)
131 		return;
132 	    for (lp = wp.w_linep; lp != wp.w_bufp.b_linep; lp = lforw(lp))
133 	    {	if (row == r)
134 		    break;
135 		r++;
136 	    }
137 	    *p_lp = lp;
138 	    /* Determine offset into line corresponding to col		*/
139 	    *p_doto = coltodoto(lp,wp.w_startcol + col);
140 	    return;
141 	}
142 	r += wp.w_ntrows + 1;
143     }
144 }
145 
146 
147 /*****************************
148  * Given an initial position, drag the mouse, marking
149  * text as we go.
150  */
151 
152 static void mouse_markdrag(WINDOW* wp, LINE* lp, int doto)
153 {   uint x,y;
154 
155     curbp = wp.w_bufp;
156     curwp = wp;
157     if (lp != wp.w_dotp)	/* if on different line		*/
158     {   wp.w_dotp = lp;
159 	wp.w_flag |= WFMOVE;
160     }
161     wp.w_doto = doto;
162     wp.w_markp = lp;
163     wp.w_marko = doto;		/* set new mark			*/
164     curwp.w_flag |= WFHARD;
165     update();
166 
167     /* Continue marking until button goes up			*/
168     while (msm_getstatus(&x,&y) & 1)
169     {
170 	mouse_tocursor(&x,&y);	/* collect real cursor coords	*/
171 	mouse_findpos(x,y,&wp,&lp,&doto);
172 	if (wp && wp == curwp && lp)
173 	{
174 	    if (wp.w_markp || lp != wp.w_dotp) /* if on different line */
175 	    {
176 		wp.w_dotp = lp;
177 		wp.w_flag |= WFMOVE;
178 	    }
179 	    wp.w_doto = doto;
180 	}
181 	else if (!wp ||
182 	    wp != curwp && wp.w_toprow > curwp.w_toprow ||
183 	    wp == curwp && !lp)
184 		window_mvdn(FALSE,1);
185 	else
186 		window_mvup(FALSE,1);
187 	curgoal = curwp.w_startcol + x;
188 	lastflag |= CFCPCN;	/* behave as if forwline() or backline() */
189 	update();
190     }
191     /* If mark start and mark end match, then no mark		*/
192     if (wp.w_markp == wp.w_dotp &&
193 	wp.w_marko == wp.w_doto)
194     {	clock_t thisclick;
195 
196 	wp.w_markp = null;
197 	thisclick = clock();
198 	if (clicks)
199 	{   if (thisclick - lastclick > 500) //CLOCKS_PER_SEC / 2)
200 		clicks = 0;
201 	}
202 	clicks++;
203 	lastclick = thisclick;
204 
205 	switch (clicks)
206 	{   case 1:
207 		break;
208 	    case 2:
209 		word_select(FALSE,1);
210 		goto L1;
211 	    case 3:
212 		word_lineselect(FALSE,1);
213 	    L1:
214 		mlerase();
215 		update();
216 		break;
217 	    default:
218 		clicks = 0;
219 		break;
220 	}
221     }
222     else
223 	clicks = 0;
224 }
225 
226 /*****************************
227  * Given an initial position, drag the border of the window around.
228  */
229 
230 static void mouse_windrag(WINDOW* wp)
231 {   uint x,y;
232     LINE *lp;
233     int doto;
234 
235     /* Continue dragging window until button goes up			*/
236     while (msm_getstatus(&x,&y) & 1)
237     {
238 	mouse_tocursor(&x,&y);		/* collect real cursor coords	*/
239 	mouse_findpos(x,y,&wp,&lp,&doto);
240 	if (wp && wp == curwp && lp ||
241 	    wp != curwp && wp && wp.w_toprow < curwp.w_toprow)
242 	    window_shrink(FALSE,1);
243 	else if (!wp ||
244 	    wp != curwp && wp.w_toprow > curwp.w_toprow)
245 	    window_enlarge(FALSE,1);
246 	update();
247     }
248 }
249 
250 /*****************************
251  * Return !=0 if left button is down.
252  */
253 
254 static int mouse_leftisdown()
255 {   uint x,y;
256 
257     return msm_getstatus(&x,&y) & 1;
258 }