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