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 }