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 $
29 #include "opt_syscons.h"
32 #include <sys/param.h>
33 #include <sys/systm.h>
35 #include <sys/signalvar.h>
38 #include <sys/malloc.h>
40 #include <machine/console.h>
41 #include <machine/mouse.h>
43 #include <dev/syscons/syscons.h>
45 #ifdef SC_TWOBUTTON_MOUSE
46 #define SC_MOUSE_PASTEBUTTON MOUSE_BUTTON3DOWN /* right button */
47 #define SC_MOUSE_EXTENDBUTTON MOUSE_BUTTON2DOWN /* not really used */
49 #define SC_MOUSE_PASTEBUTTON MOUSE_BUTTON2DOWN /* middle button */
50 #define SC_MOUSE_EXTENDBUTTON MOUSE_BUTTON3DOWN /* right button */
51 #endif /* SC_TWOBUTTON_MOUSE */
53 #define SC_WAKEUP_DELTA 20
55 /* for backward compatibility */
56 #define OLD_CONS_MOUSECTL _IOWR('c', 10, old_mouse_info_t)
58 typedef struct old_mouse_data {
64 typedef struct old_mouse_info {
67 struct old_mouse_data data;
68 struct mouse_mode mode;
72 #ifndef SC_NO_SYSMOUSE
75 static int cut_buffer_size;
76 static u_char *cut_buffer;
79 static void set_mouse_pos(scr_stat *scp);
80 #ifndef SC_NO_CUTPASTE
81 static int skip_spc_right(scr_stat *scp, int p);
82 static int skip_spc_left(scr_stat *scp, int p);
83 static void mouse_cut(scr_stat *scp);
84 static void mouse_cut_start(scr_stat *scp);
85 static void mouse_cut_end(scr_stat *scp);
86 static void mouse_cut_word(scr_stat *scp);
87 static void mouse_cut_line(scr_stat *scp);
88 static void mouse_cut_extend(scr_stat *scp);
89 static void mouse_paste(scr_stat *scp);
90 #endif /* SC_NO_CUTPASTE */
92 #ifndef SC_NO_CUTPASTE
93 /* allocate a cut buffer */
95 sc_alloc_cut_buffer(scr_stat *scp, int wait)
99 if ((cut_buffer == NULL)
100 || (cut_buffer_size < scp->xsize * scp->ysize + 1)) {
105 cut_buffer_size = scp->xsize * scp->ysize + 1;
106 p = (u_char *)malloc(cut_buffer_size,
107 M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
113 #endif /* SC_NO_CUTPASTE */
117 sc_mouse_move(scr_stat *scp, int x, int y)
122 scp->mouse_xpos = scp->mouse_oldxpos = x;
123 scp->mouse_ypos = scp->mouse_oldypos = y;
124 if (scp->font_size <= 0)
125 scp->mouse_pos = scp->mouse_oldpos = 0;
127 scp->mouse_pos = scp->mouse_oldpos =
128 (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
129 scp->status |= MOUSE_MOVED;
133 /* adjust mouse position */
135 set_mouse_pos(scr_stat *scp)
137 if (scp->mouse_xpos < scp->xoff*8)
138 scp->mouse_xpos = scp->xoff*8;
139 if (scp->mouse_ypos < scp->yoff*scp->font_size)
140 scp->mouse_ypos = scp->yoff*scp->font_size;
141 if (ISGRAPHSC(scp)) {
142 if (scp->mouse_xpos > scp->xpixel-1)
143 scp->mouse_xpos = scp->xpixel-1;
144 if (scp->mouse_ypos > scp->ypixel-1)
145 scp->mouse_ypos = scp->ypixel-1;
148 if (scp->mouse_xpos > (scp->xsize + scp->xoff)*8 - 1)
149 scp->mouse_xpos = (scp->xsize + scp->xoff)*8 - 1;
150 if (scp->mouse_ypos > (scp->ysize + scp->yoff)*scp->font_size - 1)
151 scp->mouse_ypos = (scp->ysize + scp->yoff)*scp->font_size - 1;
154 if (scp->mouse_xpos != scp->mouse_oldxpos || scp->mouse_ypos != scp->mouse_oldypos) {
155 scp->status |= MOUSE_MOVED;
157 (scp->mouse_ypos/scp->font_size - scp->yoff)*scp->xsize
158 + scp->mouse_xpos/8 - scp->xoff;
159 #ifndef SC_NO_CUTPASTE
160 if ((scp->status & MOUSE_VISIBLE) && (scp->status & MOUSE_CUTTING))
166 #ifndef SC_NO_CUTPASTE
169 sc_draw_mouse_image(scr_stat *scp)
174 ++scp->sc->videoio_in_progress;
175 (*scp->rndr->draw_mouse)(scp, scp->mouse_xpos, scp->mouse_ypos, TRUE);
176 scp->mouse_oldpos = scp->mouse_pos;
177 scp->mouse_oldxpos = scp->mouse_xpos;
178 scp->mouse_oldypos = scp->mouse_ypos;
179 scp->status |= MOUSE_VISIBLE;
180 --scp->sc->videoio_in_progress;
184 sc_remove_mouse_image(scr_stat *scp)
192 ++scp->sc->videoio_in_progress;
193 (*scp->rndr->draw_mouse)(scp,
194 (scp->mouse_oldpos%scp->xsize + scp->xoff)*8,
195 (scp->mouse_oldpos/scp->xsize + scp->yoff)
198 size = scp->xsize*scp->ysize;
199 i = scp->mouse_oldpos;
200 mark_for_update(scp, i);
201 mark_for_update(scp, i);
203 if (i + scp->xsize + 1 < size) {
204 mark_for_update(scp, i + scp->xsize + 1);
205 } else if (i + scp->xsize < size) {
206 mark_for_update(scp, i + scp->xsize);
207 } else if (i + 1 < size) {
208 mark_for_update(scp, i + 1);
211 scp->status &= ~MOUSE_VISIBLE;
212 --scp->sc->videoio_in_progress;
216 sc_inside_cutmark(scr_stat *scp, int pos)
221 if (scp->mouse_cut_end < 0)
223 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
224 start = scp->mouse_cut_start;
225 end = scp->mouse_cut_end;
227 start = scp->mouse_cut_end;
228 end = scp->mouse_cut_start - 1;
230 return ((start <= pos) && (pos <= end));
234 sc_remove_cutmarking(scr_stat *scp)
239 if (scp->mouse_cut_end >= 0) {
240 mark_for_update(scp, scp->mouse_cut_start);
241 mark_for_update(scp, scp->mouse_cut_end);
243 scp->mouse_cut_start = scp->xsize*scp->ysize;
244 scp->mouse_cut_end = -1;
246 scp->status &= ~MOUSE_CUTTING;
250 sc_remove_all_cutmarkings(sc_softc_t *sc)
255 /* delete cut markings in all vtys */
256 for (i = 0; i < sc->vtys; ++i) {
257 scp = SC_STAT(sc->dev[i]);
260 sc_remove_cutmarking(scp);
265 sc_remove_all_mouse(sc_softc_t *sc)
270 for (i = 0; i < sc->vtys; ++i) {
271 scp = SC_STAT(sc->dev[i]);
274 if (scp->status & MOUSE_VISIBLE) {
275 scp->status &= ~MOUSE_VISIBLE;
281 #define IS_SPACE_CHAR(c) (((c) & 0xff) == ' ')
283 /* skip spaces to right */
285 skip_spc_right(scr_stat *scp, int p)
290 for (i = p % scp->xsize; i < scp->xsize; ++i) {
291 c = sc_vtb_getc(&scp->vtb, p);
292 if (!IS_SPACE_CHAR(c))
299 /* skip spaces to left */
301 skip_spc_left(scr_stat *scp, int p)
306 for (i = p-- % scp->xsize - 1; i >= 0; --i) {
307 c = sc_vtb_getc(&scp->vtb, p);
308 if (!IS_SPACE_CHAR(c))
315 /* copy marked region to the cut buffer */
317 mouse_cut(scr_stat *scp)
329 start = scp->mouse_cut_start;
330 end = scp->mouse_cut_end;
331 if (scp->mouse_pos >= start) {
333 to = end = scp->mouse_pos;
335 from = end = scp->mouse_pos;
338 for (p = from, i = blank = 0; p <= to; ++p) {
339 cut_buffer[i] = sc_vtb_getc(&scp->vtb, p);
340 /* remember the position of the last non-space char */
341 if (!IS_SPACE_CHAR(cut_buffer[i++]))
342 blank = i; /* the first space after the last non-space */
343 /* trim trailing blank when crossing lines */
344 if ((p % scp->xsize) == (scp->xsize - 1)) {
345 cut_buffer[blank] = '\r';
349 cut_buffer[i] = '\0';
351 /* scan towards the end of the last line */
353 for (i = p % scp->xsize; i < scp->xsize; ++i) {
354 c = sc_vtb_getc(&scp->vtb, p);
355 if (!IS_SPACE_CHAR(c))
359 /* if there is nothing but blank chars, trim them, but mark towards eol */
360 if (i >= scp->xsize) {
365 cut_buffer[blank++] = '\r';
366 cut_buffer[blank] = '\0';
369 /* remove the current marking */
371 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
372 mark_for_update(scp, scp->mouse_cut_start);
373 mark_for_update(scp, scp->mouse_cut_end);
374 } else if (scp->mouse_cut_end >= 0) {
375 mark_for_update(scp, scp->mouse_cut_end);
376 mark_for_update(scp, scp->mouse_cut_start);
379 /* mark the new region */
380 scp->mouse_cut_start = start;
381 scp->mouse_cut_end = end;
382 mark_for_update(scp, from);
383 mark_for_update(scp, to);
387 /* a mouse button is pressed, start cut operation */
389 mouse_cut_start(scr_stat *scp)
395 if (scp->status & MOUSE_VISIBLE) {
396 i = scp->mouse_cut_start;
397 j = scp->mouse_cut_end;
398 sc_remove_all_cutmarkings(scp->sc);
399 if (scp->mouse_pos == i && i == j) {
400 cut_buffer[0] = '\0';
401 } else if (skip_spc_right(scp, scp->mouse_pos) >= scp->xsize) {
402 /* if the pointer is on trailing blank chars, mark towards eol */
403 i = skip_spc_left(scp, scp->mouse_pos) + 1;
405 scp->mouse_cut_start =
406 (scp->mouse_pos / scp->xsize) * scp->xsize + i;
408 (scp->mouse_pos / scp->xsize + 1) * scp->xsize - 1;
410 cut_buffer[0] = '\r';
411 cut_buffer[1] = '\0';
412 scp->status |= MOUSE_CUTTING;
415 scp->mouse_cut_start = scp->mouse_pos;
416 scp->mouse_cut_end = scp->mouse_cut_start;
418 cut_buffer[0] = sc_vtb_getc(&scp->vtb, scp->mouse_cut_start);
419 cut_buffer[1] = '\0';
420 scp->status |= MOUSE_CUTTING;
422 mark_all(scp); /* this is probably overkill XXX */
426 /* end of cut operation */
428 mouse_cut_end(scr_stat *scp)
430 if (scp->status & MOUSE_VISIBLE)
431 scp->status &= ~MOUSE_CUTTING;
434 /* copy a word under the mouse pointer */
436 mouse_cut_word(scr_stat *scp)
448 * Because we don't have locale information in the kernel,
449 * we only distinguish space char and non-space chars. Punctuation
450 * chars, symbols and other regular chars are all treated alike.
452 if (scp->status & MOUSE_VISIBLE) {
453 /* remove the current cut mark */
455 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
456 mark_for_update(scp, scp->mouse_cut_start);
457 mark_for_update(scp, scp->mouse_cut_end);
458 } else if (scp->mouse_cut_end >= 0) {
459 mark_for_update(scp, scp->mouse_cut_end);
460 mark_for_update(scp, scp->mouse_cut_start);
462 scp->mouse_cut_start = scp->xsize*scp->ysize;
463 scp->mouse_cut_end = -1;
466 sol = (scp->mouse_pos / scp->xsize) * scp->xsize;
467 eol = sol + scp->xsize;
468 c = sc_vtb_getc(&scp->vtb, scp->mouse_pos);
469 if (IS_SPACE_CHAR(c)) {
471 for (j = scp->mouse_pos; j >= sol; --j) {
472 c = sc_vtb_getc(&scp->vtb, j);
473 if (!IS_SPACE_CHAR(c))
477 for (j = scp->mouse_pos; j < eol; ++j) {
478 c = sc_vtb_getc(&scp->vtb, j);
479 if (!IS_SPACE_CHAR(c))
485 for (j = scp->mouse_pos; j >= sol; --j) {
486 c = sc_vtb_getc(&scp->vtb, j);
487 if (IS_SPACE_CHAR(c))
491 for (j = scp->mouse_pos; j < eol; ++j) {
492 c = sc_vtb_getc(&scp->vtb, j);
493 if (IS_SPACE_CHAR(c))
499 /* copy the found word */
500 for (i = 0, j = start; j <= end; ++j)
501 cut_buffer[i++] = sc_vtb_getc(&scp->vtb, j);
502 cut_buffer[i] = '\0';
503 scp->status |= MOUSE_CUTTING;
505 /* mark the region */
507 scp->mouse_cut_start = start;
508 scp->mouse_cut_end = end;
509 mark_for_update(scp, start);
510 mark_for_update(scp, end);
515 /* copy a line under the mouse pointer */
517 mouse_cut_line(scr_stat *scp)
523 if (scp->status & MOUSE_VISIBLE) {
524 /* remove the current cut mark */
526 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
527 mark_for_update(scp, scp->mouse_cut_start);
528 mark_for_update(scp, scp->mouse_cut_end);
529 } else if (scp->mouse_cut_end >= 0) {
530 mark_for_update(scp, scp->mouse_cut_end);
531 mark_for_update(scp, scp->mouse_cut_start);
534 /* mark the entire line */
535 scp->mouse_cut_start =
536 (scp->mouse_pos / scp->xsize) * scp->xsize;
537 scp->mouse_cut_end = scp->mouse_cut_start + scp->xsize - 1;
538 mark_for_update(scp, scp->mouse_cut_start);
539 mark_for_update(scp, scp->mouse_cut_end);
542 /* copy the line into the cut buffer */
543 for (i = 0, j = scp->mouse_cut_start; j <= scp->mouse_cut_end; ++j)
544 cut_buffer[i++] = sc_vtb_getc(&scp->vtb, j);
545 cut_buffer[i++] = '\r';
546 cut_buffer[i] = '\0';
547 scp->status |= MOUSE_CUTTING;
551 /* extend the marked region to the mouse pointer position */
553 mouse_cut_extend(scr_stat *scp)
559 if ((scp->status & MOUSE_VISIBLE) && !(scp->status & MOUSE_CUTTING)
560 && (scp->mouse_cut_end >= 0)) {
561 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
562 start = scp->mouse_cut_start;
563 end = scp->mouse_cut_end;
565 start = scp->mouse_cut_end;
566 end = scp->mouse_cut_start - 1;
569 if (scp->mouse_pos > end) {
570 scp->mouse_cut_start = start;
571 scp->mouse_cut_end = end;
572 } else if (scp->mouse_pos < start) {
573 scp->mouse_cut_start = end + 1;
574 scp->mouse_cut_end = start;
576 if (scp->mouse_pos - start > end + 1 - scp->mouse_pos) {
577 scp->mouse_cut_start = start;
578 scp->mouse_cut_end = end;
580 scp->mouse_cut_start = end + 1;
581 scp->mouse_cut_end = start;
586 scp->status |= MOUSE_CUTTING;
590 /* paste cut buffer contents into the current vty */
592 mouse_paste(scr_stat *scp)
594 if (scp->status & MOUSE_VISIBLE)
595 sc_paste(scp, cut_buffer, strlen(cut_buffer));
598 #endif /* SC_NO_CUTPASTE */
601 sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
611 scp = SC_STAT(tp->t_dev);
615 case CONS_MOUSECTL: /* control mouse arrow */
616 case OLD_CONS_MOUSECTL:
618 mouse = (mouse_info_t*)data;
619 if (cmd == OLD_CONS_MOUSECTL) {
620 static u_char swapb[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
621 old_mouse_info_t *old_mouse = (old_mouse_info_t *)data;
624 mouse->operation = old_mouse->operation;
625 switch (mouse->operation) {
627 mouse->u.mode = old_mouse->u.mode;
635 mouse->u.data.x = old_mouse->u.data.x;
636 mouse->u.data.y = old_mouse->u.data.y;
638 mouse->u.data.buttons = swapb[old_mouse->u.data.buttons & 0x7];
641 old_mouse->u.data.x = scp->mouse_xpos;
642 old_mouse->u.data.y = scp->mouse_ypos;
643 old_mouse->u.data.buttons = swapb[scp->mouse_buttons & 0x7];
650 cur_scp = scp->sc->cur_scp;
652 switch (mouse->operation) {
654 if (ISSIGVALID(mouse->u.mode.signal)) {
655 scp->mouse_signal = mouse->u.mode.signal;
657 scp->mouse_pid = p->p_pid;
660 scp->mouse_signal = 0;
661 scp->mouse_proc = NULL;
668 if (!(scp->sc->flags & SC_MOUSE_ENABLED)) {
669 scp->sc->flags |= SC_MOUSE_ENABLED;
670 cur_scp->status &= ~MOUSE_HIDDEN;
671 if (!ISGRAPHSC(cur_scp))
683 if (scp->sc->flags & SC_MOUSE_ENABLED) {
684 scp->sc->flags &= ~SC_MOUSE_ENABLED;
685 sc_remove_all_mouse(scp->sc);
696 scp->mouse_xpos = mouse->u.data.x;
697 scp->mouse_ypos = mouse->u.data.y;
704 scp->mouse_xpos += mouse->u.data.x;
705 scp->mouse_ypos += mouse->u.data.y;
711 mouse->u.data.x = scp->mouse_xpos;
712 mouse->u.data.y = scp->mouse_ypos;
714 mouse->u.data.buttons = scp->mouse_buttons;
718 case MOUSE_MOTION_EVENT:
719 /* send out mouse event on /dev/sysmouse */
721 /* this should maybe only be settable from /dev/consolectl SOS */
722 if (SC_VTY(tp->t_dev) != SC_CONSOLECTL)
726 if (mouse->u.data.x != 0 || mouse->u.data.y != 0) {
727 cur_scp->mouse_xpos += mouse->u.data.x;
728 cur_scp->mouse_ypos += mouse->u.data.y;
729 set_mouse_pos(cur_scp);
732 if (mouse->operation == MOUSE_ACTION) {
733 f = cur_scp->mouse_buttons ^ mouse->u.data.buttons;
734 cur_scp->mouse_buttons = mouse->u.data.buttons;
738 if (sysmouse_event(mouse) == 0)
742 * If any buttons are down or the mouse has moved a lot,
743 * stop the screen saver.
745 if (((mouse->operation == MOUSE_ACTION) && mouse->u.data.buttons)
746 || (mouse->u.data.x*mouse->u.data.x
747 + mouse->u.data.y*mouse->u.data.y
748 >= SC_WAKEUP_DELTA*SC_WAKEUP_DELTA)) {
749 sc_touch_scrn_saver();
752 cur_scp->status &= ~MOUSE_HIDDEN;
754 if (cur_scp->mouse_signal) {
755 /* has controlling process died? */
756 if (cur_scp->mouse_proc &&
757 (cur_scp->mouse_proc != pfind(cur_scp->mouse_pid))){
758 cur_scp->mouse_signal = 0;
759 cur_scp->mouse_proc = NULL;
760 cur_scp->mouse_pid = 0;
762 psignal(cur_scp->mouse_proc, cur_scp->mouse_signal);
767 if (ISGRAPHSC(cur_scp) || (cut_buffer == NULL))
770 #ifndef SC_NO_CUTPASTE
771 if ((mouse->operation == MOUSE_ACTION) && f) {
772 /* process button presses */
773 if (cur_scp->mouse_buttons & MOUSE_BUTTON1DOWN)
774 mouse_cut_start(cur_scp);
776 mouse_cut_end(cur_scp);
777 if (cur_scp->mouse_buttons & MOUSE_BUTTON2DOWN ||
778 cur_scp->mouse_buttons & MOUSE_BUTTON3DOWN)
779 mouse_paste(cur_scp);
781 #endif /* SC_NO_CUTPASTE */
784 case MOUSE_BUTTON_EVENT:
785 if ((mouse->u.event.id & MOUSE_BUTTONS) == 0)
787 if (mouse->u.event.value < 0)
790 /* this should maybe only be settable from /dev/consolectl SOS */
791 if (SC_VTY(tp->t_dev) != SC_CONSOLECTL)
794 if (mouse->u.event.value > 0)
795 cur_scp->mouse_buttons |= mouse->u.event.id;
797 cur_scp->mouse_buttons &= ~mouse->u.event.id;
799 if (sysmouse_event(mouse) == 0)
802 /* if a button is held down, stop the screen saver */
803 if (mouse->u.event.value > 0)
804 sc_touch_scrn_saver();
806 cur_scp->status &= ~MOUSE_HIDDEN;
808 if (cur_scp->mouse_signal) {
809 if (cur_scp->mouse_proc &&
810 (cur_scp->mouse_proc != pfind(cur_scp->mouse_pid))){
811 cur_scp->mouse_signal = 0;
812 cur_scp->mouse_proc = NULL;
813 cur_scp->mouse_pid = 0;
815 psignal(cur_scp->mouse_proc, cur_scp->mouse_signal);
820 if (ISGRAPHSC(cur_scp) || (cut_buffer == NULL))
823 #ifndef SC_NO_CUTPASTE
824 switch (mouse->u.event.id) {
825 case MOUSE_BUTTON1DOWN:
826 switch (mouse->u.event.value % 4) {
828 mouse_cut_end(cur_scp);
830 case 1: /* single click: start cut operation */
831 mouse_cut_start(cur_scp);
833 case 2: /* double click: cut a word */
834 mouse_cut_word(cur_scp);
835 mouse_cut_end(cur_scp);
837 case 3: /* triple click: cut a line */
838 mouse_cut_line(cur_scp);
839 mouse_cut_end(cur_scp);
843 case SC_MOUSE_PASTEBUTTON:
844 switch (mouse->u.event.value) {
848 mouse_paste(cur_scp);
852 case SC_MOUSE_EXTENDBUTTON:
853 switch (mouse->u.event.value) {
855 if (!(cur_scp->mouse_buttons & MOUSE_BUTTON1DOWN))
856 mouse_cut_end(cur_scp);
859 mouse_cut_extend(cur_scp);
864 #endif /* SC_NO_CUTPASTE */
867 case MOUSE_MOUSECHAR:
868 if (mouse->u.mouse_char < 0) {
869 mouse->u.mouse_char = scp->sc->mouse_char;
871 if (mouse->u.mouse_char >= UCHAR_MAX - 4)
874 sc_remove_all_mouse(scp->sc);
875 #ifndef SC_NO_FONT_LOADING
876 if (ISTEXTSC(cur_scp) && (cur_scp->font != NULL))
877 sc_load_font(cur_scp, 0, cur_scp->font_size, cur_scp->font,
878 cur_scp->sc->mouse_char, 4);
880 scp->sc->mouse_char = mouse->u.mouse_char;
895 #endif /* SC_NO_SYSMOUSE */