1 /* $Aumix: aumix/src/mouse.c,v 1.5 2002/05/07 08:41:38 trevor Exp $
2  * copyright (c) 1993, 1996-2000, 2002 the authors--see AUTHORS file
3  *
4  * This file is part of aumix.
5  *
6  * Aumix is free software; you can redistribute it and/or modify it under the
7  * terms of the GNU General Public License as published by the Free Software
8  * Foundation; either version 2 of the License, or (at your option) any later
9  * version.
10  *
11  * Aumix is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13  * A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * aumix; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
17  * Suite 330, Boston, MA 02111-1307, USA.
18  */
19 
20 #include "common.h"
21 #if HAVE_CURSES
22 #if HAVE_SYSMOUSE
23 #if HAVE_SYS_CONSIO_H
24 #include <sys/consio.h>
25 #include <sys/fbio.h>
26 #else
27 #include <machine/console.h>
28 #endif	/* HAVE_SYS_CONSIO_H */
29 #include <errno.h>
30 #endif				/* HAVE_SYSMOUSE */
31 #include "interactive.h"
32 #include "curses.h"
33 #include "mouse.h"
34 #if HAVE_SYSMOUSE
35 extern void     SysmouseHandler(int sig);
36 extern int      Sysm_Wgetch(WINDOW * win);
37 
38 static int      xpos, ypos, buttons;
39 static int      cwidth = 8, cheight = 16;
40 #endif				/* HAVE_SYSMOUSE */
41 
StartMouse(void)42 void            StartMouse(void)
43 {
44 	Gpm_Connect     conn;
45 #if HAVE_SYSMOUSE
46 	mouse_info_t    mi;
47 	video_info_t    vi;
48 	int             fd = STDIN_FILENO;
49 #ifndef FBIO_GETMODE		/* FreeBSD 3.x */
50 #define FBIO_GETMODE	CONS_GET
51 #define FBIO_MODEINFO	CONS_MODEINFO
52 #endif				/* HAVE_SYSMOUSE */
53 	if (ioctl(fd, FBIO_GETMODE, &vi.vi_mode) != -1 && ioctl(fd, FBIO_MODEINFO, &vi) != -1) {
54 		cwidth = vi.vi_cwidth;
55 		cheight = vi.vi_cheight;
56 	}
57 	/* Have sysmouse send us SIGUSR2 for mouse state changes. */
58 	signal(SIGUSR2, SIG_IGN);
59 	mi.operation = MOUSE_MODE;
60 	mi.u.mode.mode = 0;
61 	mi.u.mode.signal = SIGUSR2;
62 	/*
63 	 * If successful, register signal handler and our wgetch() replacement.
64 	 */
65 	if (ioctl(fd, CONS_MOUSECTL, &mi) != -1) {
66 		signal(SIGUSR2, SysmouseHandler);
67 		mi.operation = MOUSE_SHOW;
68 		ioctl(fd, CONS_MOUSECTL, &mi);
69 		Wgetch = Sysm_Wgetch;
70 		return;
71 	}
72 #endif				/* HAVE_SYSMOUSE */
73 	conn.eventMask = (unsigned short) ~0;
74 	conn.defaultMask = GPM_MOVE | GPM_HARD;
75 	conn.maxMod = 0;
76 	conn.minMod = 0;
77 	/* don't check for < 0, gpm-xterm returns -2 */
78 	if (Gpm_Open(&conn, 0) != -1) {
79 		gpm_handler = MouseHandler;
80 		Wgetch = Gpm_Wgetch;
81 	} else
82 		Wgetch = wgetch;
83 #if HAVE_GETMOUSE
84 	/* enable ncurses mouse reporting */
85 #define MMASK	(BUTTON1_PRESSED | BUTTON1_CLICKED | \
86 		 BUTTON2_PRESSED | BUTTON2_CLICKED)
87 	(void) mousemask(MMASK, (mmask_t *) NULL);
88 #endif				/* HAVE_GETMOUSE */
89 }
90 
MouseHandler(Gpm_Event * event,void * data)91 int             MouseHandler(Gpm_Event * event, void *data)
92 {
93 	if ((event->type & GPM_DOWN) || (event->type & GPM_DRAG)) {
94 		if (in_keysbox)
95 			return ' ';	/* Simulate keyboard event. */
96 		else
97 			DoMouse(event->x - 1, event->y - 1, GPM_TO_DOMOUSE(event->buttons));
98 	}
99 	return 0;
100 }
101 #if HAVE_SYSMOUSE
102 /*
103  * Signal handler for SIGUSR2: Retrieves mouse coordinates; converts pixels
104  * to rows and columns.
105  */
SysmouseHandler(int sig)106 void            SysmouseHandler(int sig)
107 {
108 	int             fd = STDIN_FILENO;
109 	struct mouse_info mi;
110 	mi.operation = MOUSE_GETINFO;
111 	if (ioctl(fd, CONS_MOUSECTL, &mi) == -1)
112 		return;
113 	xpos = mi.u.data.x;
114 	ypos = mi.u.data.y;
115 	/* for cosmetic bug in syscons.c on FreeBSD 3.3/3.4 */
116 	mi.operation = MOUSE_HIDE;
117 	ioctl(fd, CONS_MOUSECTL, &mi);
118 	mi.operation = MOUSE_SHOW;
119 	ioctl(fd, CONS_MOUSECTL, &mi);
120 	buttons = mi.u.data.buttons & 3;
121 }
122 /*
123  * Wait in select() loop.  If interrupted, check for mouse button press and
124  * construct a minimal gpm pseudo-event and call MouseHandler(). Otherwise
125  * hand over to wgetch().
126  */
Sysm_Wgetch(WINDOW * win)127 int             Sysm_Wgetch(WINDOW * win)
128 {
129 	fd_set          rfds;
130 	Gpm_Event       event;
131 	int             key;
132 	FD_ZERO(&rfds);
133 	FD_SET(STDIN_FILENO, &rfds);
134 	while (select(STDIN_FILENO + 1, &rfds, (fd_set *) NULL, (fd_set *) NULL, (struct timeval *) NULL) <= 0) {
135 		if (errno == EINTR && buttons) {
136 			event.buttons = SYSMOUSE_TO_GPM(buttons);
137 			event.x = xpos / cwidth + 1;
138 			event.y = ypos / cheight + 1;
139 			event.type = GPM_DOWN;
140 			if ((key = MouseHandler(&event, (void *) NULL)) != 0)
141 				return key;
142 		}
143 	}
144 	return wgetch(win);
145 }
146 #endif				/* HAVE_SYSMOUSE */
147 
148 /* assumes upper left corner is (0, 0) */
DoMouse(int x,int y,int b)149 void            DoMouse(int x, int y, int b)
150 {
151 	int             dev_orig, mouse_dev, ii, jj;
152 	if ((x < XOFFSET + menu_width) && (b & BUTTON1)) {	/* menu */
153 		switch (y) {
154 		case 2:	/* quit */
155 			Gpm_Close();
156 			close(mixer_fd);
157 			CloseScreen();
158 			exit(EXIT_SUCCESS);
159 		case 3:	/* load */
160 			LoadSettings();
161 			return;
162 		case 4:	/* save */
163 			SaveSettings();
164 			return;
165 		case 5:	/* keys */
166 			KeysBox();
167 			return;
168 		case 6:	/* mute */
169 			Muting(MUTE_NO_DEVICE, MUTE_GLOBAL);
170 			return;
171 		case 7:	/* only */
172 			Muting(current_dev, MUTE_ONLY);
173 			return;
174 		case 8:	/* undo */
175 			Muting(MUTE_NO_DEVICE, MUTE_OFF);
176 		default:
177 			return;
178 		}
179 	}
180 	mouse_dev = y - YOFFSET;
181 	jj = 0;
182 	dev_orig = mouse_dev;
183 	for (ii = 0; jj <= dev_orig; ii++) {
184 		if (!((devmask | recmask) & (1 << ii))) {
185 			mouse_dev++;
186 		} else {
187 			jj++;
188 		}
189 	}
190 	if (mouse_dev >= SOUND_MIXER_NRDEVICES)
191 		return;
192 	x = x - (XOFFSET + menu_width + R_P_WIDTH);
193 	if ((x < 0) && (b & BUTTON1)) {
194 		SwitchRecordPlay(mouse_dev);
195 		return;
196 	}
197 	if ((x < level_width) && (b & BUTTON1)) {
198 		x = x * level_increment;
199 		AdjustLevel(mouse_dev, 0, x);
200 		return;
201 	}
202 	x = x - (level_width + label_width + ARROW_WIDTH * 2);
203 	if (x >= 0 && x < balance_width) {	/* balance */
204 		x = x * balance_increment;
205 		if ((((1 << mouse_dev) & stereodevs) && ((1 << mouse_dev) & devmask))) {
206 			if (b & BUTTON1) {
207 				AdjustBalance(mouse_dev, 0, x);
208 			} else {
209 				if (b & BUTTON2)
210 					AdjustBalance(mouse_dev, -1, (MAXLEVEL / 2));
211 			}
212 		}
213 		return;
214 	}
215 	return;
216 }
217 #endif				/* HAVE_CURSES */
218