2 * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
26 * $FreeBSD: src/sys/dev/syscons/scmouse.c,v 1.12.2.3 2001/07/28 12:51:47 yokota Exp $
27 * $DragonFly: src/sys/dev/misc/syscons/scmouse.c,v 1.2 2003/06/17 04:28:31 dillon Exp $
30 #include "opt_syscons.h"
33 #include <sys/param.h>
34 #include <sys/systm.h>
36 #include <sys/signalvar.h>
39 #include <sys/malloc.h>
41 #include <machine/console.h>
42 #include <machine/mouse.h>
44 #include <dev/syscons/syscons.h>
46 #ifdef SC_TWOBUTTON_MOUSE
47 #define SC_MOUSE_PASTEBUTTON MOUSE_BUTTON3DOWN /* right button */
48 #define SC_MOUSE_EXTENDBUTTON MOUSE_BUTTON2DOWN /* not really used */
50 #define SC_MOUSE_PASTEBUTTON MOUSE_BUTTON2DOWN /* middle button */
51 #define SC_MOUSE_EXTENDBUTTON MOUSE_BUTTON3DOWN /* right button */
52 #endif /* SC_TWOBUTTON_MOUSE */
54 #define SC_WAKEUP_DELTA 20
56 /* for backward compatibility */
57 #define OLD_CONS_MOUSECTL _IOWR('c', 10, old_mouse_info_t)
59 typedef struct old_mouse_data {
65 typedef struct old_mouse_info {
68 struct old_mouse_data data;
69 struct mouse_mode mode;
73 #ifndef SC_NO_SYSMOUSE
76 static int cut_buffer_size;
77 static u_char *cut_buffer;
80 static void set_mouse_pos(scr_stat *scp);
81 #ifndef SC_NO_CUTPASTE
82 static int skip_spc_right(scr_stat *scp, int p);
83 static int skip_spc_left(scr_stat *scp, int p);
84 static void mouse_cut(scr_stat *scp);
85 static void mouse_cut_start(scr_stat *scp);
86 static void mouse_cut_end(scr_stat *scp);
87 static void mouse_cut_word(scr_stat *scp);
88 static void mouse_cut_line(scr_stat *scp);
89 static void mouse_cut_extend(scr_stat *scp);
90 static void mouse_paste(scr_stat *scp);
91 #endif /* SC_NO_CUTPASTE */
93 #ifndef SC_NO_CUTPASTE
94 /* allocate a cut buffer */
96 sc_alloc_cut_buffer(scr_stat *scp, int wait)
100 if ((cut_buffer == NULL)
101 || (cut_buffer_size < scp->xsize * scp->ysize + 1)) {
106 cut_buffer_size = scp->xsize * scp->ysize + 1;
107 p = (u_char *)malloc(cut_buffer_size,
108 M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
114 #endif /* SC_NO_CUTPASTE */
118 sc_mouse_move(scr_stat *scp, int x, int y)
123 scp->mouse_xpos = scp->mouse_oldxpos = x;
124 scp->mouse_ypos = scp->mouse_oldypos = y;
125 if (scp->font_size <= 0)
126 scp->mouse_pos = scp->mouse_oldpos = 0;
128 scp->mouse_pos = scp->mouse_oldpos =
129 (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
130 scp->status |= MOUSE_MOVED;
134 /* adjust mouse position */
136 set_mouse_pos(scr_stat *scp)
138 if (scp->mouse_xpos < scp->xoff*8)
139 scp->mouse_xpos = scp->xoff*8;
140 if (scp->mouse_ypos < scp->yoff*scp->font_size)
141 scp->mouse_ypos = scp->yoff*scp->font_size;
142 if (ISGRAPHSC(scp)) {
143 if (scp->mouse_xpos > scp->xpixel-1)
144 scp->mouse_xpos = scp->xpixel-1;
145 if (scp->mouse_ypos > scp->ypixel-1)
146 scp->mouse_ypos = scp->ypixel-1;
149 if (scp->mouse_xpos > (scp->xsize + scp->xoff)*8 - 1)
150 scp->mouse_xpos = (scp->xsize + scp->xoff)*8 - 1;
151 if (scp->mouse_ypos > (scp->ysize + scp->yoff)*scp->font_size - 1)
152 scp->mouse_ypos = (scp->ysize + scp->yoff)*scp->font_size - 1;
155 if (scp->mouse_xpos != scp->mouse_oldxpos || scp->mouse_ypos != scp->mouse_oldypos) {
156 scp->status |= MOUSE_MOVED;
158 (scp->mouse_ypos/scp->font_size - scp->yoff)*scp->xsize
159 + scp->mouse_xpos/8 - scp->xoff;
160 #ifndef SC_NO_CUTPASTE
161 if ((scp->status & MOUSE_VISIBLE) && (scp->status & MOUSE_CUTTING))
167 #ifndef SC_NO_CUTPASTE
170 sc_draw_mouse_image(scr_stat *scp)
175 ++scp->sc->videoio_in_progress;
176 (*scp->rndr->draw_mouse)(scp, scp->mouse_xpos, scp->mouse_ypos, TRUE);
177 scp->mouse_oldpos = scp->mouse_pos;
178 scp->mouse_oldxpos = scp->mouse_xpos;
179 scp->mouse_oldypos = scp->mouse_ypos;
180 scp->status |= MOUSE_VISIBLE;
181 --scp->sc->videoio_in_progress;
185 sc_remove_mouse_image(scr_stat *scp)
193 ++scp->sc->videoio_in_progress;
194 (*scp->rndr->draw_mouse)(scp,
195 (scp->mouse_oldpos%scp->xsize + scp->xoff)*8,
196 (scp->mouse_oldpos/scp->xsize + scp->yoff)
199 size = scp->xsize*scp->ysize;
200 i = scp->mouse_oldpos;
201 mark_for_update(scp, i);
202 mark_for_update(scp, i);
204 if (i + scp->xsize + 1 < size) {
205 mark_for_update(scp, i + scp->xsize + 1);
206 } else if (i + scp->xsize < size) {
207 mark_for_update(scp, i + scp->xsize);
208 } else if (i + 1 < size) {
209 mark_for_update(scp, i + 1);
212 scp->status &= ~MOUSE_VISIBLE;
213 --scp->sc->videoio_in_progress;
217 sc_inside_cutmark(scr_stat *scp, int pos)
222 if (scp->mouse_cut_end < 0)
224 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
225 start = scp->mouse_cut_start;
226 end = scp->mouse_cut_end;
228 start = scp->mouse_cut_end;
229 end = scp->mouse_cut_start - 1;
231 return ((start <= pos) && (pos <= end));
235 sc_remove_cutmarking(scr_stat *scp)
240 if (scp->mouse_cut_end >= 0) {
241 mark_for_update(scp, scp->mouse_cut_start);
242 mark_for_update(scp, scp->mouse_cut_end);
244 scp->mouse_cut_start = scp->xsize*scp->ysize;
245 scp->mouse_cut_end = -1;
247 scp->status &= ~MOUSE_CUTTING;
251 sc_remove_all_cutmarkings(sc_softc_t *sc)
256 /* delete cut markings in all vtys */
257 for (i = 0; i < sc->vtys; ++i) {
258 scp = SC_STAT(sc->dev[i]);
261 sc_remove_cutmarking(scp);
266 sc_remove_all_mouse(sc_softc_t *sc)
271 for (i = 0; i < sc->vtys; ++i) {
272 scp = SC_STAT(sc->dev[i]);
275 if (scp->status & MOUSE_VISIBLE) {
276 scp->status &= ~MOUSE_VISIBLE;
282 #define IS_SPACE_CHAR(c) (((c) & 0xff) == ' ')
284 /* skip spaces to right */
286 skip_spc_right(scr_stat *scp, int p)
291 for (i = p % scp->xsize; i < scp->xsize; ++i) {
292 c = sc_vtb_getc(&scp->vtb, p);
293 if (!IS_SPACE_CHAR(c))
300 /* skip spaces to left */
302 skip_spc_left(scr_stat *scp, int p)
307 for (i = p-- % scp->xsize - 1; i >= 0; --i) {
308 c = sc_vtb_getc(&scp->vtb, p);
309 if (!IS_SPACE_CHAR(c))
316 /* copy marked region to the cut buffer */
318 mouse_cut(scr_stat *scp)
330 start = scp->mouse_cut_start;
331 end = scp->mouse_cut_end;
332 if (scp->mouse_pos >= start) {
334 to = end = scp->mouse_pos;
336 from = end = scp->mouse_pos;
339 for (p = from, i = blank = 0; p <= to; ++p) {
340 cut_buffer[i] = sc_vtb_getc(&scp->vtb, p);
341 /* remember the position of the last non-space char */
342 if (!IS_SPACE_CHAR(cut_buffer[i++]))
343 blank = i; /* the first space after the last non-space */
344 /* trim trailing blank when crossing lines */
345 if ((p % scp->xsize) == (scp->xsize - 1)) {
346 cut_buffer[blank] = '\r';
350 cut_buffer[i] = '\0';
352 /* scan towards the end of the last line */
354 for (i = p % scp->xsize; i < scp->xsize; ++i) {
355 c = sc_vtb_getc(&scp->vtb, p);
356 if (!IS_SPACE_CHAR(c))
360 /* if there is nothing but blank chars, trim them, but mark towards eol */
361 if (i >= scp->xsize) {
366 cut_buffer[blank++] = '\r';
367 cut_buffer[blank] = '\0';
370 /* remove the current marking */
372 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
373 mark_for_update(scp, scp->mouse_cut_start);
374 mark_for_update(scp, scp->mouse_cut_end);
375 } else if (scp->mouse_cut_end >= 0) {
376 mark_for_update(scp, scp->mouse_cut_end);
377 mark_for_update(scp, scp->mouse_cut_start);
380 /* mark the new region */
381 scp->mouse_cut_start = start;
382 scp->mouse_cut_end = end;
383 mark_for_update(scp, from);
384 mark_for_update(scp, to);
388 /* a mouse button is pressed, start cut operation */
390 mouse_cut_start(scr_stat *scp)
396 if (scp->status & MOUSE_VISIBLE) {
397 i = scp->mouse_cut_start;
398 j = scp->mouse_cut_end;
399 sc_remove_all_cutmarkings(scp->sc);
400 if (scp->mouse_pos == i && i == j) {
401 cut_buffer[0] = '\0';
402 } else if (skip_spc_right(scp, scp->mouse_pos) >= scp->xsize) {
403 /* if the pointer is on trailing blank chars, mark towards eol */
404 i = skip_spc_left(scp, scp->mouse_pos) + 1;
406 scp->mouse_cut_start =
407 (scp->mouse_pos / scp->xsize) * scp->xsize + i;
409 (scp->mouse_pos / scp->xsize + 1) * scp->xsize - 1;
411 cut_buffer[0] = '\r';
412 cut_buffer[1] = '\0';
413 scp->status |= MOUSE_CUTTING;
416 scp->mouse_cut_start = scp->mouse_pos;
417 scp->mouse_cut_end = scp->mouse_cut_start;
419 cut_buffer[0] = sc_vtb_getc(&scp->vtb, scp->mouse_cut_start);
420 cut_buffer[1] = '\0';
421 scp->status |= MOUSE_CUTTING;
423 mark_all(scp); /* this is probably overkill XXX */
427 /* end of cut operation */
429 mouse_cut_end(scr_stat *scp)
431 if (scp->status & MOUSE_VISIBLE)
432 scp->status &= ~MOUSE_CUTTING;
435 /* copy a word under the mouse pointer */
437 mouse_cut_word(scr_stat *scp)
449 * Because we don't have locale information in the kernel,
450 * we only distinguish space char and non-space chars. Punctuation
451 * chars, symbols and other regular chars are all treated alike.
453 if (scp->status & MOUSE_VISIBLE) {
454 /* remove the current cut mark */
456 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
457 mark_for_update(scp, scp->mouse_cut_start);
458 mark_for_update(scp, scp->mouse_cut_end);
459 } else if (scp->mouse_cut_end >= 0) {
460 mark_for_update(scp, scp->mouse_cut_end);
461 mark_for_update(scp, scp->mouse_cut_start);
463 scp->mouse_cut_start = scp->xsize*scp->ysize;
464 scp->mouse_cut_end = -1;
467 sol = (scp->mouse_pos / scp->xsize) * scp->xsize;
468 eol = sol + scp->xsize;
469 c = sc_vtb_getc(&scp->vtb, scp->mouse_pos);
470 if (IS_SPACE_CHAR(c)) {
472 for (j = scp->mouse_pos; j >= sol; --j) {
473 c = sc_vtb_getc(&scp->vtb, j);
474 if (!IS_SPACE_CHAR(c))
478 for (j = scp->mouse_pos; j < eol; ++j) {
479 c = sc_vtb_getc(&scp->vtb, j);
480 if (!IS_SPACE_CHAR(c))
486 for (j = scp->mouse_pos; j >= sol; --j) {
487 c = sc_vtb_getc(&scp->vtb, j);
488 if (IS_SPACE_CHAR(c))
492 for (j = scp->mouse_pos; j < eol; ++j) {
493 c = sc_vtb_getc(&scp->vtb, j);
494 if (IS_SPACE_CHAR(c))
500 /* copy the found word */
501 for (i = 0, j = start; j <= end; ++j)
502 cut_buffer[i++] = sc_vtb_getc(&scp->vtb, j);
503 cut_buffer[i] = '\0';
504 scp->status |= MOUSE_CUTTING;
506 /* mark the region */
508 scp->mouse_cut_start = start;
509 scp->mouse_cut_end = end;
510 mark_for_update(scp, start);
511 mark_for_update(scp, end);
516 /* copy a line under the mouse pointer */
518 mouse_cut_line(scr_stat *scp)
524 if (scp->status & MOUSE_VISIBLE) {
525 /* remove the current cut mark */
527 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
528 mark_for_update(scp, scp->mouse_cut_start);
529 mark_for_update(scp, scp->mouse_cut_end);
530 } else if (scp->mouse_cut_end >= 0) {
531 mark_for_update(scp, scp->mouse_cut_end);
532 mark_for_update(scp, scp->mouse_cut_start);
535 /* mark the entire line */
536 scp->mouse_cut_start =
537 (scp->mouse_pos / scp->xsize) * scp->xsize;
538 scp->mouse_cut_end = scp->mouse_cut_start + scp->xsize - 1;
539 mark_for_update(scp, scp->mouse_cut_start);
540 mark_for_update(scp, scp->mouse_cut_end);
543 /* copy the line into the cut buffer */
544 for (i = 0, j = scp->mouse_cut_start; j <= scp->mouse_cut_end; ++j)
545 cut_buffer[i++] = sc_vtb_getc(&scp->vtb, j);
546 cut_buffer[i++] = '\r';
547 cut_buffer[i] = '\0';
548 scp->status |= MOUSE_CUTTING;
552 /* extend the marked region to the mouse pointer position */
554 mouse_cut_extend(scr_stat *scp)
560 if ((scp->status & MOUSE_VISIBLE) && !(scp->status & MOUSE_CUTTING)
561 && (scp->mouse_cut_end >= 0)) {
562 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
563 start = scp->mouse_cut_start;
564 end = scp->mouse_cut_end;
566 start = scp->mouse_cut_end;
567 end = scp->mouse_cut_start - 1;
570 if (scp->mouse_pos > end) {
571 scp->mouse_cut_start = start;
572 scp->mouse_cut_end = end;
573 } else if (scp->mouse_pos < start) {
574 scp->mouse_cut_start = end + 1;
575 scp->mouse_cut_end = start;
577 if (scp->mouse_pos - start > end + 1 - scp->mouse_pos) {
578 scp->mouse_cut_start = start;
579 scp->mouse_cut_end = end;
581 scp->mouse_cut_start = end + 1;
582 scp->mouse_cut_end = start;
587 scp->status |= MOUSE_CUTTING;
591 /* paste cut buffer contents into the current vty */
593 mouse_paste(scr_stat *scp)
595 if (scp->status & MOUSE_VISIBLE)
596 sc_paste(scp, cut_buffer, strlen(cut_buffer));
599 #endif /* SC_NO_CUTPASTE */
602 sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
612 scp = SC_STAT(tp->t_dev);
616 case CONS_MOUSECTL: /* control mouse arrow */
617 case OLD_CONS_MOUSECTL:
619 mouse = (mouse_info_t*)data;
620 if (cmd == OLD_CONS_MOUSECTL) {
621 static u_char swapb[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
622 old_mouse_info_t *old_mouse = (old_mouse_info_t *)data;
625 mouse->operation = old_mouse->operation;
626 switch (mouse->operation) {
628 mouse->u.mode = old_mouse->u.mode;
636 mouse->u.data.x = old_mouse->u.data.x;
637 mouse->u.data.y = old_mouse->u.data.y;
639 mouse->u.data.buttons = swapb[old_mouse->u.data.buttons & 0x7];
642 old_mouse->u.data.x = scp->mouse_xpos;
643 old_mouse->u.data.y = scp->mouse_ypos;
644 old_mouse->u.data.buttons = swapb[scp->mouse_buttons & 0x7];
651 cur_scp = scp->sc->cur_scp;
653 switch (mouse->operation) {
655 if (ISSIGVALID(mouse->u.mode.signal)) {
656 scp->mouse_signal = mouse->u.mode.signal;
658 scp->mouse_pid = p->p_pid;
661 scp->mouse_signal = 0;
662 scp->mouse_proc = NULL;
669 if (!(scp->sc->flags & SC_MOUSE_ENABLED)) {
670 scp->sc->flags |= SC_MOUSE_ENABLED;
671 cur_scp->status &= ~MOUSE_HIDDEN;
672 if (!ISGRAPHSC(cur_scp))
684 if (scp->sc->flags & SC_MOUSE_ENABLED) {
685 scp->sc->flags &= ~SC_MOUSE_ENABLED;
686 sc_remove_all_mouse(scp->sc);
697 scp->mouse_xpos = mouse->u.data.x;
698 scp->mouse_ypos = mouse->u.data.y;
705 scp->mouse_xpos += mouse->u.data.x;
706 scp->mouse_ypos += mouse->u.data.y;
712 mouse->u.data.x = scp->mouse_xpos;
713 mouse->u.data.y = scp->mouse_ypos;
715 mouse->u.data.buttons = scp->mouse_buttons;
719 case MOUSE_MOTION_EVENT:
720 /* send out mouse event on /dev/sysmouse */
722 /* this should maybe only be settable from /dev/consolectl SOS */
723 if (SC_VTY(tp->t_dev) != SC_CONSOLECTL)
727 if (mouse->u.data.x != 0 || mouse->u.data.y != 0) {
728 cur_scp->mouse_xpos += mouse->u.data.x;
729 cur_scp->mouse_ypos += mouse->u.data.y;
730 set_mouse_pos(cur_scp);
733 if (mouse->operation == MOUSE_ACTION) {
734 f = cur_scp->mouse_buttons ^ mouse->u.data.buttons;
735 cur_scp->mouse_buttons = mouse->u.data.buttons;
739 if (sysmouse_event(mouse) == 0)
743 * If any buttons are down or the mouse has moved a lot,
744 * stop the screen saver.
746 if (((mouse->operation == MOUSE_ACTION) && mouse->u.data.buttons)
747 || (mouse->u.data.x*mouse->u.data.x
748 + mouse->u.data.y*mouse->u.data.y
749 >= SC_WAKEUP_DELTA*SC_WAKEUP_DELTA)) {
750 sc_touch_scrn_saver();
753 cur_scp->status &= ~MOUSE_HIDDEN;
755 if (cur_scp->mouse_signal) {
756 /* has controlling process died? */
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;
763 psignal(cur_scp->mouse_proc, cur_scp->mouse_signal);
768 if (ISGRAPHSC(cur_scp) || (cut_buffer == NULL))
771 #ifndef SC_NO_CUTPASTE
772 if ((mouse->operation == MOUSE_ACTION) && f) {
773 /* process button presses */
774 if (cur_scp->mouse_buttons & MOUSE_BUTTON1DOWN)
775 mouse_cut_start(cur_scp);
777 mouse_cut_end(cur_scp);
778 if (cur_scp->mouse_buttons & MOUSE_BUTTON2DOWN ||
779 cur_scp->mouse_buttons & MOUSE_BUTTON3DOWN)
780 mouse_paste(cur_scp);
782 #endif /* SC_NO_CUTPASTE */
785 case MOUSE_BUTTON_EVENT:
786 if ((mouse->u.event.id & MOUSE_BUTTONS) == 0)
788 if (mouse->u.event.value < 0)
791 /* this should maybe only be settable from /dev/consolectl SOS */
792 if (SC_VTY(tp->t_dev) != SC_CONSOLECTL)
795 if (mouse->u.event.value > 0)
796 cur_scp->mouse_buttons |= mouse->u.event.id;
798 cur_scp->mouse_buttons &= ~mouse->u.event.id;
800 if (sysmouse_event(mouse) == 0)
803 /* if a button is held down, stop the screen saver */
804 if (mouse->u.event.value > 0)
805 sc_touch_scrn_saver();
807 cur_scp->status &= ~MOUSE_HIDDEN;
809 if (cur_scp->mouse_signal) {
810 if (cur_scp->mouse_proc &&
811 (cur_scp->mouse_proc != pfind(cur_scp->mouse_pid))){
812 cur_scp->mouse_signal = 0;
813 cur_scp->mouse_proc = NULL;
814 cur_scp->mouse_pid = 0;
816 psignal(cur_scp->mouse_proc, cur_scp->mouse_signal);
821 if (ISGRAPHSC(cur_scp) || (cut_buffer == NULL))
824 #ifndef SC_NO_CUTPASTE
825 switch (mouse->u.event.id) {
826 case MOUSE_BUTTON1DOWN:
827 switch (mouse->u.event.value % 4) {
829 mouse_cut_end(cur_scp);
831 case 1: /* single click: start cut operation */
832 mouse_cut_start(cur_scp);
834 case 2: /* double click: cut a word */
835 mouse_cut_word(cur_scp);
836 mouse_cut_end(cur_scp);
838 case 3: /* triple click: cut a line */
839 mouse_cut_line(cur_scp);
840 mouse_cut_end(cur_scp);
844 case SC_MOUSE_PASTEBUTTON:
845 switch (mouse->u.event.value) {
849 mouse_paste(cur_scp);
853 case SC_MOUSE_EXTENDBUTTON:
854 switch (mouse->u.event.value) {
856 if (!(cur_scp->mouse_buttons & MOUSE_BUTTON1DOWN))
857 mouse_cut_end(cur_scp);
860 mouse_cut_extend(cur_scp);
865 #endif /* SC_NO_CUTPASTE */
868 case MOUSE_MOUSECHAR:
869 if (mouse->u.mouse_char < 0) {
870 mouse->u.mouse_char = scp->sc->mouse_char;
872 if (mouse->u.mouse_char >= UCHAR_MAX - 4)
875 sc_remove_all_mouse(scp->sc);
876 #ifndef SC_NO_FONT_LOADING
877 if (ISTEXTSC(cur_scp) && (cur_scp->font != NULL))
878 sc_load_font(cur_scp, 0, cur_scp->font_size, cur_scp->font,
879 cur_scp->sc->mouse_char, 4);
881 scp->sc->mouse_char = mouse->u.mouse_char;
896 #endif /* SC_NO_SYSMOUSE */