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.5 2004/05/13 19:44:33 dillon Exp $
30 #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>
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 = malloc(cut_buffer_size, M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
112 #endif /* SC_NO_CUTPASTE */
116 sc_mouse_move(scr_stat *scp, int x, int y)
121 scp->mouse_xpos = scp->mouse_oldxpos = x;
122 scp->mouse_ypos = scp->mouse_oldypos = y;
123 if (scp->font_size <= 0)
124 scp->mouse_pos = scp->mouse_oldpos = 0;
126 scp->mouse_pos = scp->mouse_oldpos =
127 (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
128 scp->status |= MOUSE_MOVED;
132 /* adjust mouse position */
134 set_mouse_pos(scr_stat *scp)
136 if (scp->mouse_xpos < scp->xoff*8)
137 scp->mouse_xpos = scp->xoff*8;
138 if (scp->mouse_ypos < scp->yoff*scp->font_size)
139 scp->mouse_ypos = scp->yoff*scp->font_size;
140 if (ISGRAPHSC(scp)) {
141 if (scp->mouse_xpos > scp->xpixel-1)
142 scp->mouse_xpos = scp->xpixel-1;
143 if (scp->mouse_ypos > scp->ypixel-1)
144 scp->mouse_ypos = scp->ypixel-1;
147 if (scp->mouse_xpos > (scp->xsize + scp->xoff)*8 - 1)
148 scp->mouse_xpos = (scp->xsize + scp->xoff)*8 - 1;
149 if (scp->mouse_ypos > (scp->ysize + scp->yoff)*scp->font_size - 1)
150 scp->mouse_ypos = (scp->ysize + scp->yoff)*scp->font_size - 1;
153 if (scp->mouse_xpos != scp->mouse_oldxpos || scp->mouse_ypos != scp->mouse_oldypos) {
154 scp->status |= MOUSE_MOVED;
156 (scp->mouse_ypos/scp->font_size - scp->yoff)*scp->xsize
157 + scp->mouse_xpos/8 - scp->xoff;
158 #ifndef SC_NO_CUTPASTE
159 if ((scp->status & MOUSE_VISIBLE) && (scp->status & MOUSE_CUTTING))
165 #ifndef SC_NO_CUTPASTE
168 sc_draw_mouse_image(scr_stat *scp)
173 ++scp->sc->videoio_in_progress;
174 (*scp->rndr->draw_mouse)(scp, scp->mouse_xpos, scp->mouse_ypos, TRUE);
175 scp->mouse_oldpos = scp->mouse_pos;
176 scp->mouse_oldxpos = scp->mouse_xpos;
177 scp->mouse_oldypos = scp->mouse_ypos;
178 scp->status |= MOUSE_VISIBLE;
179 --scp->sc->videoio_in_progress;
183 sc_remove_mouse_image(scr_stat *scp)
191 ++scp->sc->videoio_in_progress;
192 (*scp->rndr->draw_mouse)(scp,
193 (scp->mouse_oldpos%scp->xsize + scp->xoff)*8,
194 (scp->mouse_oldpos/scp->xsize + scp->yoff)
197 size = scp->xsize*scp->ysize;
198 i = scp->mouse_oldpos;
199 mark_for_update(scp, i);
200 mark_for_update(scp, i);
202 if (i + scp->xsize + 1 < size) {
203 mark_for_update(scp, i + scp->xsize + 1);
204 } else if (i + scp->xsize < size) {
205 mark_for_update(scp, i + scp->xsize);
206 } else if (i + 1 < size) {
207 mark_for_update(scp, i + 1);
210 scp->status &= ~MOUSE_VISIBLE;
211 --scp->sc->videoio_in_progress;
215 sc_inside_cutmark(scr_stat *scp, int pos)
220 if (scp->mouse_cut_end < 0)
222 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
223 start = scp->mouse_cut_start;
224 end = scp->mouse_cut_end;
226 start = scp->mouse_cut_end;
227 end = scp->mouse_cut_start - 1;
229 return ((start <= pos) && (pos <= end));
233 sc_remove_cutmarking(scr_stat *scp)
238 if (scp->mouse_cut_end >= 0) {
239 mark_for_update(scp, scp->mouse_cut_start);
240 mark_for_update(scp, scp->mouse_cut_end);
242 scp->mouse_cut_start = scp->xsize*scp->ysize;
243 scp->mouse_cut_end = -1;
245 scp->status &= ~MOUSE_CUTTING;
249 sc_remove_all_cutmarkings(sc_softc_t *sc)
254 /* delete cut markings in all vtys */
255 for (i = 0; i < sc->vtys; ++i) {
256 scp = SC_STAT(sc->dev[i]);
259 sc_remove_cutmarking(scp);
264 sc_remove_all_mouse(sc_softc_t *sc)
269 for (i = 0; i < sc->vtys; ++i) {
270 scp = SC_STAT(sc->dev[i]);
273 if (scp->status & MOUSE_VISIBLE) {
274 scp->status &= ~MOUSE_VISIBLE;
280 #define IS_SPACE_CHAR(c) (((c) & 0xff) == ' ')
282 /* skip spaces to right */
284 skip_spc_right(scr_stat *scp, int p)
289 for (i = p % scp->xsize; i < scp->xsize; ++i) {
290 c = sc_vtb_getc(&scp->vtb, p);
291 if (!IS_SPACE_CHAR(c))
298 /* skip spaces to left */
300 skip_spc_left(scr_stat *scp, int p)
305 for (i = p-- % scp->xsize - 1; i >= 0; --i) {
306 c = sc_vtb_getc(&scp->vtb, p);
307 if (!IS_SPACE_CHAR(c))
314 /* copy marked region to the cut buffer */
316 mouse_cut(scr_stat *scp)
328 start = scp->mouse_cut_start;
329 end = scp->mouse_cut_end;
330 if (scp->mouse_pos >= start) {
332 to = end = scp->mouse_pos;
334 from = end = scp->mouse_pos;
337 for (p = from, i = blank = 0; p <= to; ++p) {
338 cut_buffer[i] = sc_vtb_getc(&scp->vtb, p);
339 /* remember the position of the last non-space char */
340 if (!IS_SPACE_CHAR(cut_buffer[i++]))
341 blank = i; /* the first space after the last non-space */
342 /* trim trailing blank when crossing lines */
343 if ((p % scp->xsize) == (scp->xsize - 1)) {
344 cut_buffer[blank] = '\r';
348 cut_buffer[i] = '\0';
350 /* scan towards the end of the last line */
352 for (i = p % scp->xsize; i < scp->xsize; ++i) {
353 c = sc_vtb_getc(&scp->vtb, p);
354 if (!IS_SPACE_CHAR(c))
358 /* if there is nothing but blank chars, trim them, but mark towards eol */
359 if (i >= scp->xsize) {
364 cut_buffer[blank++] = '\r';
365 cut_buffer[blank] = '\0';
368 /* remove the current marking */
370 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
371 mark_for_update(scp, scp->mouse_cut_start);
372 mark_for_update(scp, scp->mouse_cut_end);
373 } else if (scp->mouse_cut_end >= 0) {
374 mark_for_update(scp, scp->mouse_cut_end);
375 mark_for_update(scp, scp->mouse_cut_start);
378 /* mark the new region */
379 scp->mouse_cut_start = start;
380 scp->mouse_cut_end = end;
381 mark_for_update(scp, from);
382 mark_for_update(scp, to);
386 /* a mouse button is pressed, start cut operation */
388 mouse_cut_start(scr_stat *scp)
394 if (scp->status & MOUSE_VISIBLE) {
395 i = scp->mouse_cut_start;
396 j = scp->mouse_cut_end;
397 sc_remove_all_cutmarkings(scp->sc);
398 if (scp->mouse_pos == i && i == j) {
399 cut_buffer[0] = '\0';
400 } else if (skip_spc_right(scp, scp->mouse_pos) >= scp->xsize) {
401 /* if the pointer is on trailing blank chars, mark towards eol */
402 i = skip_spc_left(scp, scp->mouse_pos) + 1;
404 scp->mouse_cut_start =
405 (scp->mouse_pos / scp->xsize) * scp->xsize + i;
407 (scp->mouse_pos / scp->xsize + 1) * scp->xsize - 1;
409 cut_buffer[0] = '\r';
410 cut_buffer[1] = '\0';
411 scp->status |= MOUSE_CUTTING;
414 scp->mouse_cut_start = scp->mouse_pos;
415 scp->mouse_cut_end = scp->mouse_cut_start;
417 cut_buffer[0] = sc_vtb_getc(&scp->vtb, scp->mouse_cut_start);
418 cut_buffer[1] = '\0';
419 scp->status |= MOUSE_CUTTING;
421 mark_all(scp); /* this is probably overkill XXX */
425 /* end of cut operation */
427 mouse_cut_end(scr_stat *scp)
429 if (scp->status & MOUSE_VISIBLE)
430 scp->status &= ~MOUSE_CUTTING;
433 /* copy a word under the mouse pointer */
435 mouse_cut_word(scr_stat *scp)
447 * Because we don't have locale information in the kernel,
448 * we only distinguish space char and non-space chars. Punctuation
449 * chars, symbols and other regular chars are all treated alike.
451 if (scp->status & MOUSE_VISIBLE) {
452 /* remove the current cut mark */
454 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
455 mark_for_update(scp, scp->mouse_cut_start);
456 mark_for_update(scp, scp->mouse_cut_end);
457 } else if (scp->mouse_cut_end >= 0) {
458 mark_for_update(scp, scp->mouse_cut_end);
459 mark_for_update(scp, scp->mouse_cut_start);
461 scp->mouse_cut_start = scp->xsize*scp->ysize;
462 scp->mouse_cut_end = -1;
465 sol = (scp->mouse_pos / scp->xsize) * scp->xsize;
466 eol = sol + scp->xsize;
467 c = sc_vtb_getc(&scp->vtb, scp->mouse_pos);
468 if (IS_SPACE_CHAR(c)) {
470 for (j = scp->mouse_pos; j >= sol; --j) {
471 c = sc_vtb_getc(&scp->vtb, j);
472 if (!IS_SPACE_CHAR(c))
476 for (j = scp->mouse_pos; j < eol; ++j) {
477 c = sc_vtb_getc(&scp->vtb, j);
478 if (!IS_SPACE_CHAR(c))
484 for (j = scp->mouse_pos; j >= sol; --j) {
485 c = sc_vtb_getc(&scp->vtb, j);
486 if (IS_SPACE_CHAR(c))
490 for (j = scp->mouse_pos; j < eol; ++j) {
491 c = sc_vtb_getc(&scp->vtb, j);
492 if (IS_SPACE_CHAR(c))
498 /* copy the found word */
499 for (i = 0, j = start; j <= end; ++j)
500 cut_buffer[i++] = sc_vtb_getc(&scp->vtb, j);
501 cut_buffer[i] = '\0';
502 scp->status |= MOUSE_CUTTING;
504 /* mark the region */
506 scp->mouse_cut_start = start;
507 scp->mouse_cut_end = end;
508 mark_for_update(scp, start);
509 mark_for_update(scp, end);
514 /* copy a line under the mouse pointer */
516 mouse_cut_line(scr_stat *scp)
522 if (scp->status & MOUSE_VISIBLE) {
523 /* remove the current cut mark */
525 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
526 mark_for_update(scp, scp->mouse_cut_start);
527 mark_for_update(scp, scp->mouse_cut_end);
528 } else if (scp->mouse_cut_end >= 0) {
529 mark_for_update(scp, scp->mouse_cut_end);
530 mark_for_update(scp, scp->mouse_cut_start);
533 /* mark the entire line */
534 scp->mouse_cut_start =
535 (scp->mouse_pos / scp->xsize) * scp->xsize;
536 scp->mouse_cut_end = scp->mouse_cut_start + scp->xsize - 1;
537 mark_for_update(scp, scp->mouse_cut_start);
538 mark_for_update(scp, scp->mouse_cut_end);
541 /* copy the line into the cut buffer */
542 for (i = 0, j = scp->mouse_cut_start; j <= scp->mouse_cut_end; ++j)
543 cut_buffer[i++] = sc_vtb_getc(&scp->vtb, j);
544 cut_buffer[i++] = '\r';
545 cut_buffer[i] = '\0';
546 scp->status |= MOUSE_CUTTING;
550 /* extend the marked region to the mouse pointer position */
552 mouse_cut_extend(scr_stat *scp)
558 if ((scp->status & MOUSE_VISIBLE) && !(scp->status & MOUSE_CUTTING)
559 && (scp->mouse_cut_end >= 0)) {
560 if (scp->mouse_cut_start <= scp->mouse_cut_end) {
561 start = scp->mouse_cut_start;
562 end = scp->mouse_cut_end;
564 start = scp->mouse_cut_end;
565 end = scp->mouse_cut_start - 1;
568 if (scp->mouse_pos > end) {
569 scp->mouse_cut_start = start;
570 scp->mouse_cut_end = end;
571 } else if (scp->mouse_pos < start) {
572 scp->mouse_cut_start = end + 1;
573 scp->mouse_cut_end = start;
575 if (scp->mouse_pos - start > end + 1 - scp->mouse_pos) {
576 scp->mouse_cut_start = start;
577 scp->mouse_cut_end = end;
579 scp->mouse_cut_start = end + 1;
580 scp->mouse_cut_end = start;
585 scp->status |= MOUSE_CUTTING;
589 /* paste cut buffer contents into the current vty */
591 mouse_paste(scr_stat *scp)
593 if (scp->status & MOUSE_VISIBLE)
594 sc_paste(scp, cut_buffer, strlen(cut_buffer));
597 #endif /* SC_NO_CUTPASTE */
600 sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
610 scp = SC_STAT(tp->t_dev);
614 case CONS_MOUSECTL: /* control mouse arrow */
615 case OLD_CONS_MOUSECTL:
617 mouse = (mouse_info_t*)data;
618 if (cmd == OLD_CONS_MOUSECTL) {
619 static u_char swapb[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
620 old_mouse_info_t *old_mouse = (old_mouse_info_t *)data;
623 mouse->operation = old_mouse->operation;
624 switch (mouse->operation) {
626 mouse->u.mode = old_mouse->u.mode;
634 mouse->u.data.x = old_mouse->u.data.x;
635 mouse->u.data.y = old_mouse->u.data.y;
637 mouse->u.data.buttons = swapb[old_mouse->u.data.buttons & 0x7];
640 old_mouse->u.data.x = scp->mouse_xpos;
641 old_mouse->u.data.y = scp->mouse_ypos;
642 old_mouse->u.data.buttons = swapb[scp->mouse_buttons & 0x7];
649 cur_scp = scp->sc->cur_scp;
651 switch (mouse->operation) {
653 if (ISSIGVALID(mouse->u.mode.signal)) {
654 scp->mouse_signal = mouse->u.mode.signal;
655 scp->mouse_proc = td->td_proc;
656 scp->mouse_pid = td->td_proc->p_pid;
659 scp->mouse_signal = 0;
660 scp->mouse_proc = NULL;
667 if (!(scp->sc->flags & SC_MOUSE_ENABLED)) {
668 scp->sc->flags |= SC_MOUSE_ENABLED;
669 cur_scp->status &= ~MOUSE_HIDDEN;
670 if (!ISGRAPHSC(cur_scp))
682 if (scp->sc->flags & SC_MOUSE_ENABLED) {
683 scp->sc->flags &= ~SC_MOUSE_ENABLED;
684 sc_remove_all_mouse(scp->sc);
695 scp->mouse_xpos = mouse->u.data.x;
696 scp->mouse_ypos = mouse->u.data.y;
703 scp->mouse_xpos += mouse->u.data.x;
704 scp->mouse_ypos += mouse->u.data.y;
710 mouse->u.data.x = scp->mouse_xpos;
711 mouse->u.data.y = scp->mouse_ypos;
713 mouse->u.data.buttons = scp->mouse_buttons;
717 case MOUSE_MOTION_EVENT:
718 /* send out mouse event on /dev/sysmouse */
720 /* this should maybe only be settable from /dev/consolectl SOS */
721 if (SC_VTY(tp->t_dev) != SC_CONSOLECTL)
725 if (mouse->u.data.x != 0 || mouse->u.data.y != 0) {
726 cur_scp->mouse_xpos += mouse->u.data.x;
727 cur_scp->mouse_ypos += mouse->u.data.y;
728 set_mouse_pos(cur_scp);
731 if (mouse->operation == MOUSE_ACTION) {
732 f = cur_scp->mouse_buttons ^ mouse->u.data.buttons;
733 cur_scp->mouse_buttons = mouse->u.data.buttons;
737 if (sysmouse_event(mouse) == 0)
741 * If any buttons are down or the mouse has moved a lot,
742 * stop the screen saver.
744 if (((mouse->operation == MOUSE_ACTION) && mouse->u.data.buttons)
745 || (mouse->u.data.x*mouse->u.data.x
746 + mouse->u.data.y*mouse->u.data.y
747 >= SC_WAKEUP_DELTA*SC_WAKEUP_DELTA)) {
748 sc_touch_scrn_saver();
751 cur_scp->status &= ~MOUSE_HIDDEN;
753 if (cur_scp->mouse_signal) {
754 /* has controlling process died? */
755 if (cur_scp->mouse_proc &&
756 (cur_scp->mouse_proc != pfind(cur_scp->mouse_pid))){
757 cur_scp->mouse_signal = 0;
758 cur_scp->mouse_proc = NULL;
759 cur_scp->mouse_pid = 0;
761 psignal(cur_scp->mouse_proc, cur_scp->mouse_signal);
766 if (ISGRAPHSC(cur_scp) || (cut_buffer == NULL))
769 #ifndef SC_NO_CUTPASTE
770 if ((mouse->operation == MOUSE_ACTION) && f) {
771 /* process button presses */
772 if (cur_scp->mouse_buttons & MOUSE_BUTTON1DOWN)
773 mouse_cut_start(cur_scp);
775 mouse_cut_end(cur_scp);
776 if (cur_scp->mouse_buttons & MOUSE_BUTTON2DOWN ||
777 cur_scp->mouse_buttons & MOUSE_BUTTON3DOWN)
778 mouse_paste(cur_scp);
780 #endif /* SC_NO_CUTPASTE */
783 case MOUSE_BUTTON_EVENT:
784 if ((mouse->u.event.id & MOUSE_BUTTONS) == 0)
786 if (mouse->u.event.value < 0)
789 /* this should maybe only be settable from /dev/consolectl SOS */
790 if (SC_VTY(tp->t_dev) != SC_CONSOLECTL)
793 if (mouse->u.event.value > 0)
794 cur_scp->mouse_buttons |= mouse->u.event.id;
796 cur_scp->mouse_buttons &= ~mouse->u.event.id;
798 if (sysmouse_event(mouse) == 0)
801 /* if a button is held down, stop the screen saver */
802 if (mouse->u.event.value > 0)
803 sc_touch_scrn_saver();
805 cur_scp->status &= ~MOUSE_HIDDEN;
807 if (cur_scp->mouse_signal) {
808 if (cur_scp->mouse_proc &&
809 (cur_scp->mouse_proc != pfind(cur_scp->mouse_pid))){
810 cur_scp->mouse_signal = 0;
811 cur_scp->mouse_proc = NULL;
812 cur_scp->mouse_pid = 0;
814 psignal(cur_scp->mouse_proc, cur_scp->mouse_signal);
819 if (ISGRAPHSC(cur_scp) || (cut_buffer == NULL))
822 #ifndef SC_NO_CUTPASTE
823 switch (mouse->u.event.id) {
824 case MOUSE_BUTTON1DOWN:
825 switch (mouse->u.event.value % 4) {
827 mouse_cut_end(cur_scp);
829 case 1: /* single click: start cut operation */
830 mouse_cut_start(cur_scp);
832 case 2: /* double click: cut a word */
833 mouse_cut_word(cur_scp);
834 mouse_cut_end(cur_scp);
836 case 3: /* triple click: cut a line */
837 mouse_cut_line(cur_scp);
838 mouse_cut_end(cur_scp);
842 case SC_MOUSE_PASTEBUTTON:
843 switch (mouse->u.event.value) {
847 mouse_paste(cur_scp);
851 case SC_MOUSE_EXTENDBUTTON:
852 switch (mouse->u.event.value) {
854 if (!(cur_scp->mouse_buttons & MOUSE_BUTTON1DOWN))
855 mouse_cut_end(cur_scp);
858 mouse_cut_extend(cur_scp);
863 #endif /* SC_NO_CUTPASTE */
866 case MOUSE_MOUSECHAR:
867 if (mouse->u.mouse_char < 0) {
868 mouse->u.mouse_char = scp->sc->mouse_char;
870 if (mouse->u.mouse_char >= (unsigned char)-1 - 4)
873 sc_remove_all_mouse(scp->sc);
874 #ifndef SC_NO_FONT_LOADING
875 if (ISTEXTSC(cur_scp) && (cur_scp->font != NULL))
876 sc_load_font(cur_scp, 0, cur_scp->font_size, cur_scp->font,
877 cur_scp->sc->mouse_char, 4);
879 scp->sc->mouse_char = mouse->u.mouse_char;
894 #endif /* SC_NO_SYSMOUSE */