Remove some old ioctls and structs which were there for backwards
[dragonfly.git] / sys / dev / misc / syscons / scmouse.c
CommitLineData
984263bc
MD
1/*-
2 * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer as
10 * the first lines of this file unmodified.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * $FreeBSD: src/sys/dev/syscons/scmouse.c,v 1.12.2.3 2001/07/28 12:51:47 yokota Exp $
1da88f84 27 * $DragonFly: src/sys/dev/misc/syscons/scmouse.c,v 1.6 2005/01/28 20:17:18 swildner Exp $
984263bc
MD
28 */
29
30#include "opt_syscons.h"
31
984263bc
MD
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/conf.h>
35#include <sys/signalvar.h>
36#include <sys/proc.h>
37#include <sys/tty.h>
38#include <sys/malloc.h>
39
40#include <machine/console.h>
41#include <machine/mouse.h>
42
1f2de5d4 43#include "syscons.h"
984263bc
MD
44
45#ifdef SC_TWOBUTTON_MOUSE
46#define SC_MOUSE_PASTEBUTTON MOUSE_BUTTON3DOWN /* right button */
47#define SC_MOUSE_EXTENDBUTTON MOUSE_BUTTON2DOWN /* not really used */
48#else
49#define SC_MOUSE_PASTEBUTTON MOUSE_BUTTON2DOWN /* middle button */
50#define SC_MOUSE_EXTENDBUTTON MOUSE_BUTTON3DOWN /* right button */
51#endif /* SC_TWOBUTTON_MOUSE */
52
53#define SC_WAKEUP_DELTA 20
54
984263bc
MD
55#ifndef SC_NO_SYSMOUSE
56
57/* local variables */
58static int cut_buffer_size;
59static u_char *cut_buffer;
60
61/* local functions */
62static void set_mouse_pos(scr_stat *scp);
63#ifndef SC_NO_CUTPASTE
64static int skip_spc_right(scr_stat *scp, int p);
65static int skip_spc_left(scr_stat *scp, int p);
66static void mouse_cut(scr_stat *scp);
67static void mouse_cut_start(scr_stat *scp);
68static void mouse_cut_end(scr_stat *scp);
69static void mouse_cut_word(scr_stat *scp);
70static void mouse_cut_line(scr_stat *scp);
71static void mouse_cut_extend(scr_stat *scp);
72static void mouse_paste(scr_stat *scp);
73#endif /* SC_NO_CUTPASTE */
74
75#ifndef SC_NO_CUTPASTE
76/* allocate a cut buffer */
77void
78sc_alloc_cut_buffer(scr_stat *scp, int wait)
79{
80 u_char *p;
81
82 if ((cut_buffer == NULL)
83 || (cut_buffer_size < scp->xsize * scp->ysize + 1)) {
84 p = cut_buffer;
85 cut_buffer = NULL;
86 if (p != NULL)
87 free(p, M_DEVBUF);
88 cut_buffer_size = scp->xsize * scp->ysize + 1;
bf22d4c1 89 p = malloc(cut_buffer_size, M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
984263bc
MD
90 if (p != NULL)
91 p[0] = '\0';
92 cut_buffer = p;
93 }
94}
95#endif /* SC_NO_CUTPASTE */
96
97/* move mouse */
98void
99sc_mouse_move(scr_stat *scp, int x, int y)
100{
101 int s;
102
103 s = spltty();
104 scp->mouse_xpos = scp->mouse_oldxpos = x;
105 scp->mouse_ypos = scp->mouse_oldypos = y;
106 if (scp->font_size <= 0)
107 scp->mouse_pos = scp->mouse_oldpos = 0;
108 else
109 scp->mouse_pos = scp->mouse_oldpos =
110 (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
111 scp->status |= MOUSE_MOVED;
112 splx(s);
113}
114
115/* adjust mouse position */
116static void
117set_mouse_pos(scr_stat *scp)
118{
119 if (scp->mouse_xpos < scp->xoff*8)
120 scp->mouse_xpos = scp->xoff*8;
121 if (scp->mouse_ypos < scp->yoff*scp->font_size)
122 scp->mouse_ypos = scp->yoff*scp->font_size;
123 if (ISGRAPHSC(scp)) {
124 if (scp->mouse_xpos > scp->xpixel-1)
125 scp->mouse_xpos = scp->xpixel-1;
126 if (scp->mouse_ypos > scp->ypixel-1)
127 scp->mouse_ypos = scp->ypixel-1;
128 return;
129 } else {
130 if (scp->mouse_xpos > (scp->xsize + scp->xoff)*8 - 1)
131 scp->mouse_xpos = (scp->xsize + scp->xoff)*8 - 1;
132 if (scp->mouse_ypos > (scp->ysize + scp->yoff)*scp->font_size - 1)
133 scp->mouse_ypos = (scp->ysize + scp->yoff)*scp->font_size - 1;
134 }
135
136 if (scp->mouse_xpos != scp->mouse_oldxpos || scp->mouse_ypos != scp->mouse_oldypos) {
137 scp->status |= MOUSE_MOVED;
138 scp->mouse_pos =
139 (scp->mouse_ypos/scp->font_size - scp->yoff)*scp->xsize
140 + scp->mouse_xpos/8 - scp->xoff;
141#ifndef SC_NO_CUTPASTE
142 if ((scp->status & MOUSE_VISIBLE) && (scp->status & MOUSE_CUTTING))
143 mouse_cut(scp);
144#endif
145 }
146}
147
148#ifndef SC_NO_CUTPASTE
149
150void
151sc_draw_mouse_image(scr_stat *scp)
152{
153 if (ISGRAPHSC(scp))
154 return;
155
156 ++scp->sc->videoio_in_progress;
157 (*scp->rndr->draw_mouse)(scp, scp->mouse_xpos, scp->mouse_ypos, TRUE);
158 scp->mouse_oldpos = scp->mouse_pos;
159 scp->mouse_oldxpos = scp->mouse_xpos;
160 scp->mouse_oldypos = scp->mouse_ypos;
161 scp->status |= MOUSE_VISIBLE;
162 --scp->sc->videoio_in_progress;
163}
164
165void
166sc_remove_mouse_image(scr_stat *scp)
167{
168 int size;
169 int i;
170
171 if (ISGRAPHSC(scp))
172 return;
173
174 ++scp->sc->videoio_in_progress;
175 (*scp->rndr->draw_mouse)(scp,
176 (scp->mouse_oldpos%scp->xsize + scp->xoff)*8,
177 (scp->mouse_oldpos/scp->xsize + scp->yoff)
178 * scp->font_size,
179 FALSE);
180 size = scp->xsize*scp->ysize;
181 i = scp->mouse_oldpos;
182 mark_for_update(scp, i);
183 mark_for_update(scp, i);
184#ifndef PC98
185 if (i + scp->xsize + 1 < size) {
186 mark_for_update(scp, i + scp->xsize + 1);
187 } else if (i + scp->xsize < size) {
188 mark_for_update(scp, i + scp->xsize);
189 } else if (i + 1 < size) {
190 mark_for_update(scp, i + 1);
191 }
192#endif /* PC98 */
193 scp->status &= ~MOUSE_VISIBLE;
194 --scp->sc->videoio_in_progress;
195}
196
197int
198sc_inside_cutmark(scr_stat *scp, int pos)
199{
200 int start;
201 int end;
202
203 if (scp->mouse_cut_end < 0)
204 return FALSE;
205 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
206 start = scp->mouse_cut_start;
207 end = scp->mouse_cut_end;
208 } else {
209 start = scp->mouse_cut_end;
210 end = scp->mouse_cut_start - 1;
211 }
212 return ((start <= pos) && (pos <= end));
213}
214
215void
216sc_remove_cutmarking(scr_stat *scp)
217{
218 int s;
219
220 s = spltty();
221 if (scp->mouse_cut_end >= 0) {
222 mark_for_update(scp, scp->mouse_cut_start);
223 mark_for_update(scp, scp->mouse_cut_end);
224 }
225 scp->mouse_cut_start = scp->xsize*scp->ysize;
226 scp->mouse_cut_end = -1;
227 splx(s);
228 scp->status &= ~MOUSE_CUTTING;
229}
230
231void
232sc_remove_all_cutmarkings(sc_softc_t *sc)
233{
234 scr_stat *scp;
235 int i;
236
237 /* delete cut markings in all vtys */
238 for (i = 0; i < sc->vtys; ++i) {
239 scp = SC_STAT(sc->dev[i]);
240 if (scp == NULL)
241 continue;
242 sc_remove_cutmarking(scp);
243 }
244}
245
246void
247sc_remove_all_mouse(sc_softc_t *sc)
248{
249 scr_stat *scp;
250 int i;
251
252 for (i = 0; i < sc->vtys; ++i) {
253 scp = SC_STAT(sc->dev[i]);
254 if (scp == NULL)
255 continue;
256 if (scp->status & MOUSE_VISIBLE) {
257 scp->status &= ~MOUSE_VISIBLE;
258 mark_all(scp);
259 }
260 }
261}
262
263#define IS_SPACE_CHAR(c) (((c) & 0xff) == ' ')
264
265/* skip spaces to right */
266static int
267skip_spc_right(scr_stat *scp, int p)
268{
269 int c;
270 int i;
271
272 for (i = p % scp->xsize; i < scp->xsize; ++i) {
273 c = sc_vtb_getc(&scp->vtb, p);
274 if (!IS_SPACE_CHAR(c))
275 break;
276 ++p;
277 }
278 return i;
279}
280
281/* skip spaces to left */
282static int
283skip_spc_left(scr_stat *scp, int p)
284{
285 int c;
286 int i;
287
288 for (i = p-- % scp->xsize - 1; i >= 0; --i) {
289 c = sc_vtb_getc(&scp->vtb, p);
290 if (!IS_SPACE_CHAR(c))
291 break;
292 --p;
293 }
294 return i;
295}
296
297/* copy marked region to the cut buffer */
298static void
299mouse_cut(scr_stat *scp)
300{
301 int start;
302 int end;
303 int from;
304 int to;
305 int blank;
306 int c;
307 int p;
308 int s;
309 int i;
310
311 start = scp->mouse_cut_start;
312 end = scp->mouse_cut_end;
313 if (scp->mouse_pos >= start) {
314 from = start;
315 to = end = scp->mouse_pos;
316 } else {
317 from = end = scp->mouse_pos;
318 to = start - 1;
319 }
320 for (p = from, i = blank = 0; p <= to; ++p) {
321 cut_buffer[i] = sc_vtb_getc(&scp->vtb, p);
322 /* remember the position of the last non-space char */
323 if (!IS_SPACE_CHAR(cut_buffer[i++]))
324 blank = i; /* the first space after the last non-space */
325 /* trim trailing blank when crossing lines */
326 if ((p % scp->xsize) == (scp->xsize - 1)) {
327 cut_buffer[blank] = '\r';
328 i = blank + 1;
329 }
330 }
331 cut_buffer[i] = '\0';
332
333 /* scan towards the end of the last line */
334 --p;
335 for (i = p % scp->xsize; i < scp->xsize; ++i) {
336 c = sc_vtb_getc(&scp->vtb, p);
337 if (!IS_SPACE_CHAR(c))
338 break;
339 ++p;
340 }
341 /* if there is nothing but blank chars, trim them, but mark towards eol */
342 if (i >= scp->xsize) {
343 if (end >= start)
344 to = end = p - 1;
345 else
346 to = start = p;
347 cut_buffer[blank++] = '\r';
348 cut_buffer[blank] = '\0';
349 }
350
351 /* remove the current marking */
352 s = spltty();
353 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
354 mark_for_update(scp, scp->mouse_cut_start);
355 mark_for_update(scp, scp->mouse_cut_end);
356 } else if (scp->mouse_cut_end >= 0) {
357 mark_for_update(scp, scp->mouse_cut_end);
358 mark_for_update(scp, scp->mouse_cut_start);
359 }
360
361 /* mark the new region */
362 scp->mouse_cut_start = start;
363 scp->mouse_cut_end = end;
364 mark_for_update(scp, from);
365 mark_for_update(scp, to);
366 splx(s);
367}
368
369/* a mouse button is pressed, start cut operation */
370static void
371mouse_cut_start(scr_stat *scp)
372{
373 int i;
374 int j;
375 int s;
376
377 if (scp->status & MOUSE_VISIBLE) {
378 i = scp->mouse_cut_start;
379 j = scp->mouse_cut_end;
380 sc_remove_all_cutmarkings(scp->sc);
381 if (scp->mouse_pos == i && i == j) {
382 cut_buffer[0] = '\0';
383 } else if (skip_spc_right(scp, scp->mouse_pos) >= scp->xsize) {
384 /* if the pointer is on trailing blank chars, mark towards eol */
385 i = skip_spc_left(scp, scp->mouse_pos) + 1;
386 s = spltty();
387 scp->mouse_cut_start =
388 (scp->mouse_pos / scp->xsize) * scp->xsize + i;
389 scp->mouse_cut_end =
390 (scp->mouse_pos / scp->xsize + 1) * scp->xsize - 1;
391 splx(s);
392 cut_buffer[0] = '\r';
393 cut_buffer[1] = '\0';
394 scp->status |= MOUSE_CUTTING;
395 } else {
396 s = spltty();
397 scp->mouse_cut_start = scp->mouse_pos;
398 scp->mouse_cut_end = scp->mouse_cut_start;
399 splx(s);
400 cut_buffer[0] = sc_vtb_getc(&scp->vtb, scp->mouse_cut_start);
401 cut_buffer[1] = '\0';
402 scp->status |= MOUSE_CUTTING;
403 }
404 mark_all(scp); /* this is probably overkill XXX */
405 }
406}
407
408/* end of cut operation */
409static void
410mouse_cut_end(scr_stat *scp)
411{
412 if (scp->status & MOUSE_VISIBLE)
413 scp->status &= ~MOUSE_CUTTING;
414}
415
416/* copy a word under the mouse pointer */
417static void
418mouse_cut_word(scr_stat *scp)
419{
420 int start;
421 int end;
422 int sol;
423 int eol;
424 int c;
425 int s;
426 int i;
427 int j;
428
429 /*
430 * Because we don't have locale information in the kernel,
431 * we only distinguish space char and non-space chars. Punctuation
432 * chars, symbols and other regular chars are all treated alike.
433 */
434 if (scp->status & MOUSE_VISIBLE) {
435 /* remove the current cut mark */
436 s = spltty();
437 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
438 mark_for_update(scp, scp->mouse_cut_start);
439 mark_for_update(scp, scp->mouse_cut_end);
440 } else if (scp->mouse_cut_end >= 0) {
441 mark_for_update(scp, scp->mouse_cut_end);
442 mark_for_update(scp, scp->mouse_cut_start);
443 }
444 scp->mouse_cut_start = scp->xsize*scp->ysize;
445 scp->mouse_cut_end = -1;
446 splx(s);
447
448 sol = (scp->mouse_pos / scp->xsize) * scp->xsize;
449 eol = sol + scp->xsize;
450 c = sc_vtb_getc(&scp->vtb, scp->mouse_pos);
451 if (IS_SPACE_CHAR(c)) {
452 /* blank space */
453 for (j = scp->mouse_pos; j >= sol; --j) {
454 c = sc_vtb_getc(&scp->vtb, j);
455 if (!IS_SPACE_CHAR(c))
456 break;
457 }
458 start = ++j;
459 for (j = scp->mouse_pos; j < eol; ++j) {
460 c = sc_vtb_getc(&scp->vtb, j);
461 if (!IS_SPACE_CHAR(c))
462 break;
463 }
464 end = j - 1;
465 } else {
466 /* non-space word */
467 for (j = scp->mouse_pos; j >= sol; --j) {
468 c = sc_vtb_getc(&scp->vtb, j);
469 if (IS_SPACE_CHAR(c))
470 break;
471 }
472 start = ++j;
473 for (j = scp->mouse_pos; j < eol; ++j) {
474 c = sc_vtb_getc(&scp->vtb, j);
475 if (IS_SPACE_CHAR(c))
476 break;
477 }
478 end = j - 1;
479 }
480
481 /* copy the found word */
482 for (i = 0, j = start; j <= end; ++j)
483 cut_buffer[i++] = sc_vtb_getc(&scp->vtb, j);
484 cut_buffer[i] = '\0';
485 scp->status |= MOUSE_CUTTING;
486
487 /* mark the region */
488 s = spltty();
489 scp->mouse_cut_start = start;
490 scp->mouse_cut_end = end;
491 mark_for_update(scp, start);
492 mark_for_update(scp, end);
493 splx(s);
494 }
495}
496
497/* copy a line under the mouse pointer */
498static void
499mouse_cut_line(scr_stat *scp)
500{
501 int s;
502 int i;
503 int j;
504
505 if (scp->status & MOUSE_VISIBLE) {
506 /* remove the current cut mark */
507 s = spltty();
508 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
509 mark_for_update(scp, scp->mouse_cut_start);
510 mark_for_update(scp, scp->mouse_cut_end);
511 } else if (scp->mouse_cut_end >= 0) {
512 mark_for_update(scp, scp->mouse_cut_end);
513 mark_for_update(scp, scp->mouse_cut_start);
514 }
515
516 /* mark the entire line */
517 scp->mouse_cut_start =
518 (scp->mouse_pos / scp->xsize) * scp->xsize;
519 scp->mouse_cut_end = scp->mouse_cut_start + scp->xsize - 1;
520 mark_for_update(scp, scp->mouse_cut_start);
521 mark_for_update(scp, scp->mouse_cut_end);
522 splx(s);
523
524 /* copy the line into the cut buffer */
525 for (i = 0, j = scp->mouse_cut_start; j <= scp->mouse_cut_end; ++j)
526 cut_buffer[i++] = sc_vtb_getc(&scp->vtb, j);
527 cut_buffer[i++] = '\r';
528 cut_buffer[i] = '\0';
529 scp->status |= MOUSE_CUTTING;
530 }
531}
532
533/* extend the marked region to the mouse pointer position */
534static void
535mouse_cut_extend(scr_stat *scp)
536{
537 int start;
538 int end;
539 int s;
540
541 if ((scp->status & MOUSE_VISIBLE) && !(scp->status & MOUSE_CUTTING)
542 && (scp->mouse_cut_end >= 0)) {
543 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
544 start = scp->mouse_cut_start;
545 end = scp->mouse_cut_end;
546 } else {
547 start = scp->mouse_cut_end;
548 end = scp->mouse_cut_start - 1;
549 }
550 s = spltty();
551 if (scp->mouse_pos > end) {
552 scp->mouse_cut_start = start;
553 scp->mouse_cut_end = end;
554 } else if (scp->mouse_pos < start) {
555 scp->mouse_cut_start = end + 1;
556 scp->mouse_cut_end = start;
557 } else {
558 if (scp->mouse_pos - start > end + 1 - scp->mouse_pos) {
559 scp->mouse_cut_start = start;
560 scp->mouse_cut_end = end;
561 } else {
562 scp->mouse_cut_start = end + 1;
563 scp->mouse_cut_end = start;
564 }
565 }
566 splx(s);
567 mouse_cut(scp);
568 scp->status |= MOUSE_CUTTING;
569 }
570}
571
572/* paste cut buffer contents into the current vty */
573static void
574mouse_paste(scr_stat *scp)
575{
576 if (scp->status & MOUSE_VISIBLE)
577 sc_paste(scp, cut_buffer, strlen(cut_buffer));
578}
579
580#endif /* SC_NO_CUTPASTE */
581
582int
583sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
41c20dac 584 struct thread *td)
984263bc
MD
585{
586 mouse_info_t *mouse;
984263bc
MD
587 scr_stat *cur_scp;
588 scr_stat *scp;
589 int s;
590 int f;
591
592 scp = SC_STAT(tp->t_dev);
593
594 switch (cmd) {
595
596 case CONS_MOUSECTL: /* control mouse arrow */
984263bc 597 mouse = (mouse_info_t*)data;
984263bc
MD
598 cur_scp = scp->sc->cur_scp;
599
600 switch (mouse->operation) {
601 case MOUSE_MODE:
602 if (ISSIGVALID(mouse->u.mode.signal)) {
603 scp->mouse_signal = mouse->u.mode.signal;
41c20dac
MD
604 scp->mouse_proc = td->td_proc;
605 scp->mouse_pid = td->td_proc->p_pid;
984263bc
MD
606 }
607 else {
608 scp->mouse_signal = 0;
609 scp->mouse_proc = NULL;
610 scp->mouse_pid = 0;
611 }
612 return 0;
613
614 case MOUSE_SHOW:
615 s = spltty();
616 if (!(scp->sc->flags & SC_MOUSE_ENABLED)) {
617 scp->sc->flags |= SC_MOUSE_ENABLED;
618 cur_scp->status &= ~MOUSE_HIDDEN;
619 if (!ISGRAPHSC(cur_scp))
620 mark_all(cur_scp);
621 splx(s);
622 return 0;
623 } else {
624 splx(s);
625 return EINVAL;
626 }
627 break;
628
629 case MOUSE_HIDE:
630 s = spltty();
631 if (scp->sc->flags & SC_MOUSE_ENABLED) {
632 scp->sc->flags &= ~SC_MOUSE_ENABLED;
633 sc_remove_all_mouse(scp->sc);
634 splx(s);
635 return 0;
636 } else {
637 splx(s);
638 return EINVAL;
639 }
640 break;
641
642 case MOUSE_MOVEABS:
643 s = spltty();
644 scp->mouse_xpos = mouse->u.data.x;
645 scp->mouse_ypos = mouse->u.data.y;
646 set_mouse_pos(scp);
647 splx(s);
648 break;
649
650 case MOUSE_MOVEREL:
651 s = spltty();
652 scp->mouse_xpos += mouse->u.data.x;
653 scp->mouse_ypos += mouse->u.data.y;
654 set_mouse_pos(scp);
655 splx(s);
656 break;
657
658 case MOUSE_GETINFO:
659 mouse->u.data.x = scp->mouse_xpos;
660 mouse->u.data.y = scp->mouse_ypos;
661 mouse->u.data.z = 0;
662 mouse->u.data.buttons = scp->mouse_buttons;
663 return 0;
664
665 case MOUSE_ACTION:
666 case MOUSE_MOTION_EVENT:
667 /* send out mouse event on /dev/sysmouse */
668#if 0
669 /* this should maybe only be settable from /dev/consolectl SOS */
670 if (SC_VTY(tp->t_dev) != SC_CONSOLECTL)
671 return ENOTTY;
672#endif
673 s = spltty();
674 if (mouse->u.data.x != 0 || mouse->u.data.y != 0) {
675 cur_scp->mouse_xpos += mouse->u.data.x;
676 cur_scp->mouse_ypos += mouse->u.data.y;
677 set_mouse_pos(cur_scp);
678 }
679 f = 0;
680 if (mouse->operation == MOUSE_ACTION) {
681 f = cur_scp->mouse_buttons ^ mouse->u.data.buttons;
682 cur_scp->mouse_buttons = mouse->u.data.buttons;
683 }
684 splx(s);
685
686 if (sysmouse_event(mouse) == 0)
687 return 0;
688
689 /*
690 * If any buttons are down or the mouse has moved a lot,
691 * stop the screen saver.
692 */
693 if (((mouse->operation == MOUSE_ACTION) && mouse->u.data.buttons)
694 || (mouse->u.data.x*mouse->u.data.x
695 + mouse->u.data.y*mouse->u.data.y
696 >= SC_WAKEUP_DELTA*SC_WAKEUP_DELTA)) {
697 sc_touch_scrn_saver();
698 }
699
700 cur_scp->status &= ~MOUSE_HIDDEN;
701
702 if (cur_scp->mouse_signal) {
703 /* has controlling process died? */
704 if (cur_scp->mouse_proc &&
705 (cur_scp->mouse_proc != pfind(cur_scp->mouse_pid))){
706 cur_scp->mouse_signal = 0;
707 cur_scp->mouse_proc = NULL;
708 cur_scp->mouse_pid = 0;
709 } else {
710 psignal(cur_scp->mouse_proc, cur_scp->mouse_signal);
711 break;
712 }
713 }
714
715 if (ISGRAPHSC(cur_scp) || (cut_buffer == NULL))
716 break;
717
718#ifndef SC_NO_CUTPASTE
719 if ((mouse->operation == MOUSE_ACTION) && f) {
720 /* process button presses */
721 if (cur_scp->mouse_buttons & MOUSE_BUTTON1DOWN)
722 mouse_cut_start(cur_scp);
723 else
724 mouse_cut_end(cur_scp);
725 if (cur_scp->mouse_buttons & MOUSE_BUTTON2DOWN ||
726 cur_scp->mouse_buttons & MOUSE_BUTTON3DOWN)
727 mouse_paste(cur_scp);
728 }
729#endif /* SC_NO_CUTPASTE */
730 break;
731
732 case MOUSE_BUTTON_EVENT:
733 if ((mouse->u.event.id & MOUSE_BUTTONS) == 0)
734 return EINVAL;
735 if (mouse->u.event.value < 0)
736 return EINVAL;
737#if 0
738 /* this should maybe only be settable from /dev/consolectl SOS */
739 if (SC_VTY(tp->t_dev) != SC_CONSOLECTL)
740 return ENOTTY;
741#endif
742 if (mouse->u.event.value > 0)
743 cur_scp->mouse_buttons |= mouse->u.event.id;
744 else
745 cur_scp->mouse_buttons &= ~mouse->u.event.id;
746
747 if (sysmouse_event(mouse) == 0)
748 return 0;
749
750 /* if a button is held down, stop the screen saver */
751 if (mouse->u.event.value > 0)
752 sc_touch_scrn_saver();
753
754 cur_scp->status &= ~MOUSE_HIDDEN;
755
756 if (cur_scp->mouse_signal) {
757 if (cur_scp->mouse_proc &&
758 (cur_scp->mouse_proc != pfind(cur_scp->mouse_pid))){
759 cur_scp->mouse_signal = 0;
760 cur_scp->mouse_proc = NULL;
761 cur_scp->mouse_pid = 0;
762 } else {
763 psignal(cur_scp->mouse_proc, cur_scp->mouse_signal);
764 break;
765 }
766 }
767
768 if (ISGRAPHSC(cur_scp) || (cut_buffer == NULL))
769 break;
770
771#ifndef SC_NO_CUTPASTE
772 switch (mouse->u.event.id) {
773 case MOUSE_BUTTON1DOWN:
774 switch (mouse->u.event.value % 4) {
775 case 0: /* up */
776 mouse_cut_end(cur_scp);
777 break;
778 case 1: /* single click: start cut operation */
779 mouse_cut_start(cur_scp);
780 break;
781 case 2: /* double click: cut a word */
782 mouse_cut_word(cur_scp);
783 mouse_cut_end(cur_scp);
784 break;
785 case 3: /* triple click: cut a line */
786 mouse_cut_line(cur_scp);
787 mouse_cut_end(cur_scp);
788 break;
789 }
790 break;
791 case SC_MOUSE_PASTEBUTTON:
792 switch (mouse->u.event.value) {
793 case 0: /* up */
794 break;
795 default:
796 mouse_paste(cur_scp);
797 break;
798 }
799 break;
800 case SC_MOUSE_EXTENDBUTTON:
801 switch (mouse->u.event.value) {
802 case 0: /* up */
803 if (!(cur_scp->mouse_buttons & MOUSE_BUTTON1DOWN))
804 mouse_cut_end(cur_scp);
805 break;
806 default:
807 mouse_cut_extend(cur_scp);
808 break;
809 }
810 break;
811 }
812#endif /* SC_NO_CUTPASTE */
813 break;
814
815 case MOUSE_MOUSECHAR:
816 if (mouse->u.mouse_char < 0) {
817 mouse->u.mouse_char = scp->sc->mouse_char;
818 } else {
1f2de5d4 819 if (mouse->u.mouse_char >= (unsigned char)-1 - 4)
984263bc
MD
820 return EINVAL;
821 s = spltty();
822 sc_remove_all_mouse(scp->sc);
823#ifndef SC_NO_FONT_LOADING
824 if (ISTEXTSC(cur_scp) && (cur_scp->font != NULL))
825 sc_load_font(cur_scp, 0, cur_scp->font_size, cur_scp->font,
826 cur_scp->sc->mouse_char, 4);
827#endif
828 scp->sc->mouse_char = mouse->u.mouse_char;
829 splx(s);
830 }
831 break;
832
833 default:
834 return EINVAL;
835 }
836
837 return 0;
838 }
839
840 return ENOIOCTL;
841}
842
843#endif /* SC_NO_SYSMOUSE */