* Fix an error in compilation when Alpine is not built with S/MIME
[alpine.git] / pico / osdep / mouse.c
blob12d9d3b75d66188de04d9fbf8935cd26b218f5e2
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: mouse.c 769 2007-10-24 00:15:40Z hubert@u.washington.edu $";
3 #endif
5 /*
6 * ========================================================================
7 * Copyright 2006-2007 University of Washington
8 * Copyright 2013-2016 Eduardo Chappa
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
19 #include <system.h>
20 #include <general.h>
22 #include "../headers.h"
24 #include "getkey.h"
26 #ifdef _WINDOWS
27 #include "mswin.h"
28 #endif
30 #include "mouse.h"
32 #ifdef MOUSE
35 #ifndef _WINDOWS
37 /* useful definitions */
38 #define XTERM_MOUSE_ON "\033[?1000h" /* DECSET with parm 1000 */
39 #define XTERM_MOUSE_OFF "\033[?1000l" /* DECRST with parm 1000 */
42 /* useful declarations */
43 static int mexist = 0; /* is the mouse driver installed? */
44 static unsigned mnoop;
48 /* internal prototypes */
49 void mouseon(void);
50 void mouseoff(void);
54 /*
55 * init_mouse - check for xterm and initialize mouse tracking if present...
57 int
58 init_mouse(void)
60 if(mexist)
61 return(TRUE);
63 if(getenv("DISPLAY")){
64 mouseon();
65 kpinsert("\033[M", KEY_XTERM_MOUSE, 1);
66 return(mexist = TRUE);
68 else
69 return(FALSE);
73 /*
74 * end_mouse - clear xterm mouse tracking if present...
76 void
77 end_mouse(void)
79 if(mexist){
80 mexist = 0; /* just see if it exists here. */
81 mouseoff();
87 * mouseexist - function to let outsiders know if mouse is turned on
88 * or not.
90 int
91 mouseexist(void)
93 return(mexist);
98 * mouseon - call made available for programs calling pico to turn ON the
99 * mouse cursor.
101 void
102 mouseon(void)
104 fputs(XTERM_MOUSE_ON, stdout);
109 * mouseon - call made available for programs calling pico to turn OFF the
110 * mouse cursor.
112 void
113 mouseoff(void)
115 fputs(XTERM_MOUSE_OFF, stdout);
120 * checkmouse - look for mouse events in key menu and return
121 * appropriate value.
124 checkmouse(unsigned long *ch, int down, int mcol, int mrow)
126 static int oindex;
127 int i = 0, rv = 0;
128 MENUITEM *mp;
130 if(!mexist || mcol < 0 || mrow < 0)
131 return(FALSE);
133 if(down) /* button down */
134 oindex = -1;
136 for(mp = mfunc; mp; mp = mp->next)
137 if(mp->action && M_ACTIVE(mrow, mcol, mp))
138 break;
140 if(mp){
141 unsigned long r;
143 r = (*mp->action)(down ? M_EVENT_DOWN : M_EVENT_UP,
144 mrow, mcol, M_BUTTON_LEFT, 0);
145 if(r){
146 *ch = r;
147 rv = TRUE;
150 else{
151 while(1){ /* see if we understand event */
152 if(i >= 12){
153 i = -1;
154 break;
157 if(M_ACTIVE(mrow, mcol, &menuitems[i]))
158 break;
160 i++;
163 if(down){ /* button down */
164 oindex = i; /* remember where */
165 if(i != -1
166 && menuitems[i].label_hiliter != NULL
167 && menuitems[i].val != mnoop) /* invert label */
168 (*menuitems[i].label_hiliter)(1, &menuitems[i]);
170 else{ /* button up */
171 if(oindex != -1){
172 if(i == oindex){
173 *ch = menuitems[i].val;
174 rv = TRUE;
180 /* restore label */
181 if(!down
182 && oindex != -1
183 && menuitems[oindex].label_hiliter != NULL
184 && menuitems[oindex].val != mnoop)
185 (*menuitems[oindex].label_hiliter)(0, &menuitems[oindex]);
187 return(rv);
192 * invert_label - highlight the label of the given menu item.
194 void
195 invert_label(int state, MENUITEM *m)
197 unsigned i, j;
198 int col_offset, savettrow, savettcol;
199 char *lp;
201 get_cursor(&savettrow, &savettcol);
204 * Leave the command name bold
206 col_offset = (state || !(lp=strchr(m->label, ' '))) ? 0 : (lp - m->label);
207 movecursor((int)m->tl.r, (int)m->tl.c + col_offset);
208 flip_inv(state);
210 for(i = m->tl.r; i <= m->br.r; i++)
211 for(j = m->tl.c + col_offset; j <= m->br.c; j++)
212 if(i == m->lbl.r && j == m->lbl.c + col_offset && m->label){
213 lp = m->label + col_offset; /* show label?? */
214 while(*lp && j++ < m->br.c)
215 putc(*lp++, stdout);
217 continue;
219 else
220 putc(' ', stdout);
222 if(state)
223 flip_inv(FALSE);
225 movecursor(savettrow, savettcol);
228 #else /* _WINDOWS */
230 #define MOUSE_BUTTONS 3
232 static int mexist = 0; /* is the mouse driver installed? */
233 static int nbuttons; /* number of buttons on the mouse */
234 static unsigned mnoop;
237 * init_mouse - check for and initialize mouse driver...
241 init_mouse(void)
243 nbuttons = MOUSE_BUTTONS;
244 return (mexist = TRUE); /* Mouse always exists under windows */
248 * end_mouse - a no-op on Windows
250 void
251 end_mouse(void)
256 * mouseexist - function to let outsiders know if mouse is turned on
257 * or not.
260 mouseexist(void)
262 return(mexist);
266 * checkmouse - Check mouse and return maped command.
268 * EXPORTED to pico.
269 * NOTE: "down", "xxx", and "yyy" aren't used under windows.
271 int
272 checkmouse (unsigned long *ch, int ddd, int xxx, int yyy)
274 static int oindex; /* Index of previous mouse down. */
275 int mcol; /* current mouse column */
276 int mrow; /* current mouse row */
277 unsigned long r;
278 int rv = 0; /* TRUE when we have something to return. */
279 MEvent mouse;
280 int i = 0;
281 MENUITEM *mp;
284 *ch = 0;
286 /* Mouse installed? */
287 if (!mexist)
288 return (FALSE);
290 if (!mswin_getmouseevent (&mouse))
291 return (FALSE);
294 /* Location of mouse event. */
295 mcol = mouse.nColumn;
296 mrow = mouse.nRow;
301 * If there is a tracking function it gets all the mouse events
302 * reguardless of where they occur.
304 if (mtrack != NULL) {
305 r = mtrack (mouse.event, mrow, mcol, mouse.button, mouse.keys);
306 if (r & 0xffff){
307 *ch = r;
308 rv = TRUE;
310 return (rv);
316 /* Mouse down or up? */
317 if (mouse.event == M_EVENT_DOWN) { /* button down */
318 oindex = -1; /* No Previous mouse down. */
322 /* In special screen region? */
323 for(mp = mfunc; mp; mp = mp->next)
324 if(mp->action && M_ACTIVE(mrow, mcol, mp))
325 break;
327 if(mp){
329 r = (*mp->action)(mouse.event, mrow, mcol, mouse.button, mouse.keys);
330 if (r){
331 *ch = r;
332 rv = TRUE;
335 else if(mouse.button == M_BUTTON_LEFT){
337 /* In any of the menuitems? */
338 while(1){ /* see if we understand event */
339 if(i >= 12){
340 i = -1; /* Not Found. */
341 break;
344 if(M_ACTIVE(mrow, mcol, &menuitems[i]))
345 break; /* Found. */
347 i++; /* Next. */
350 /* Now, was that a mouse down or mouse up? */
351 if (mouse.event == M_EVENT_DOWN) { /* button down */
352 oindex = i; /* remember where */
353 if(i != -1){ /* invert label */
354 if(menuitems[i].label_hiliter != NULL)
355 (*menuitems[i].label_hiliter)(1, &menuitems[i]);
356 else
357 invert_label(1, &menuitems[i]);
360 else if (mouse.event == M_EVENT_UP) {/* button up */
361 if (oindex != -1) { /* If up in menu item. */
362 if (i == oindex){ /* And same item down in. */
363 *ch = menuitems[i].val; /* Return menu character. */
364 rv = 1;
369 else if(mouse.button == M_BUTTON_RIGHT){
370 if (mouse.event == M_EVENT_UP) {
371 mswin_keymenu_popup();
375 /* If this is mouse up AND there was a mouse down in a menu item
376 * then uninvert that menu item */
377 if(mouse.event == M_EVENT_UP && oindex != -1){
378 if(menuitems[oindex].label_hiliter != NULL)
379 (*menuitems[oindex].label_hiliter)(0, &menuitems[oindex]);
380 else
381 invert_label(0, &menuitems[oindex]);
384 return(rv);
388 * invert_label - highlight the label of the given menu item.
390 void
391 invert_label(int state, MENUITEM *m)
393 int r, c;
394 unsigned i, j;
395 char *lp;
396 int old_state;
397 int wasShown;
398 int col_offset;
399 COLOR_PAIR *lastc = NULL;
400 if(m->val == mnoop)
401 return;
404 mswin_getpos (&r, &c); /* get cursor position */
405 wasShown = mswin_showcaret (0);
406 old_state = mswin_getrevstate ();
408 * Leave the command name bold
410 col_offset = (state || !(lp=strchr(m->label, ' '))) ? 0 : (lp - m->label);
411 (*term.t_move)(m->tl.r, m->tl.c + col_offset);
412 if(state && m->kncp)
413 lastc = pico_set_colorp(m->kncp, PSC_REV|PSC_RET);
414 else if(!state && m->klcp)
415 lastc = pico_set_colorp(m->klcp, PSC_NORM|PSC_RET);
416 else
417 (*term.t_rev)(state);
419 for(i = m->tl.r; i <= m->br.r; i++) {
420 for(j = m->tl.c + col_offset; j <= m->br.c; j++) {
421 if(i == m->lbl.r && j == m->lbl.c + col_offset){ /* show label?? */
422 lp = m->label + col_offset;
423 while(*lp && j++ < m->br.c)
424 (*term.t_putchar)(*lp++);
426 continue;
428 else
429 (*term.t_putchar)(' ');
433 if(lastc){
434 (void)pico_set_colorp(lastc, PSC_NONE);
435 free_color_pair(&lastc);
437 else
438 (*term.t_rev)(old_state);
439 mswin_move (r, c);
440 mswin_showcaret (wasShown);
444 #endif /* _WINDOWS */
446 #endif /* MOUSE */