Index: sys/dev/vt/hw/ofwfb/ofwfb.c =================================================================== --- sys/dev/vt/hw/ofwfb/ofwfb.c +++ sys/dev/vt/hw/ofwfb/ofwfb.c @@ -53,7 +53,7 @@ phandle_t sc_node; ihandle_t sc_handle; - bus_space_tag_t sc_memt; + bus_space_tag_t sc_memt; }; static vd_probe_t ofwfb_probe; Index: sys/dev/vt/logo/logo_freebsd.c =================================================================== --- sys/dev/vt/logo/logo_freebsd.c +++ sys/dev/vt/logo/logo_freebsd.c @@ -637,5 +637,5 @@ 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, }; Index: sys/dev/vt/vt.h =================================================================== --- sys/dev/vt/vt.h +++ sys/dev/vt/vt.h @@ -113,11 +113,17 @@ struct vt_mouse_cursor; #endif +struct vt_pastebuf { + term_char_t *vpb_buf; /* Copy-paste buffer. */ + unsigned int vpb_bufsz; /* Buffer size. */ + unsigned int vpb_len; /* Length of a last selection. */ +}; + struct vt_device { struct vt_window *vd_windows[VT_MAXWINDOWS]; /* (c) Windows. */ struct vt_window *vd_curwindow; /* (d) Current window. */ struct vt_window *vd_savedwindow;/* (?) Saved for suspend. */ - struct vt_window *vd_markedwin; /* (?) Copy/paste buf owner. */ + struct vt_pastebuf vd_pastebuf; /* (?) Copy/paste buf. */ const struct vt_driver *vd_driver; /* (c) Graphics driver. */ void *vd_softc; /* (u) Driver data. */ #ifndef SC_NO_CUTPASTE @@ -151,6 +157,10 @@ unsigned int vd_unit; /* (c) Device unit. */ }; +#define VD_PASTEBUF(vd) ((vd)->vd_pastebuf.vpb_buf) +#define VD_PASTEBUFSZ(vd) ((vd)->vd_pastebuf.vpb_bufsz) +#define VD_PASTEBUFLEN(vd) ((vd)->vd_pastebuf.vpb_len) + /* * Per-window terminal screen buffer. * Index: sys/dev/vt/vt_buf.c =================================================================== --- sys/dev/vt/vt_buf.c +++ sys/dev/vt/vt_buf.c @@ -603,7 +603,7 @@ ei = e.tp_row * vb->vb_scr_size.tp_col + e.tp_col; /* Number symbols and number of rows to inject \n */ - sz = ei - si + ((e.tp_row - s.tp_row) * 2) + 1; + sz = ei - si + ((e.tp_row - s.tp_row) * 2); return (sz * sizeof(term_char_t)); } Index: sys/dev/vt/vt_consolectl.c =================================================================== --- sys/dev/vt/vt_consolectl.c +++ sys/dev/vt/vt_consolectl.c @@ -51,7 +51,7 @@ { switch (cmd) { - case CONS_GETVERS: + case CONS_GETVERS: *(int*)data = 0x200; return 0; case CONS_MOUSECTL: { Index: sys/dev/vt/vt_core.c =================================================================== --- sys/dev/vt/vt_core.c +++ sys/dev/vt/vt_core.c @@ -162,6 +162,7 @@ static int vt_proc_alive(struct vt_window *); static void vt_resize(struct vt_device *); static void vt_update_static(void *); +static void vt_mouse_paste(); SET_DECLARE(vt_drv_set, struct vt_driver); @@ -176,10 +177,14 @@ .vd_flags = VDF_INVALID, .vd_windows = { [VT_CONSWINDOW] = &vt_conswindow, }, .vd_curwindow = &vt_conswindow, - .vd_markedwin = NULL, .vd_kbstate = 0, #ifndef SC_NO_CUTPASTE + .vd_pastebuf = { + .vpb_buf = NULL, + .vpb_bufsz = 0, + .vpb_len = 0 + }, .vd_mcursor = &vt_default_mouse_pointer, .vd_mcursor_fg = TC_WHITE, .vd_mcursor_bg = TC_BLACK, @@ -508,7 +513,7 @@ case SPCLKEY | PASTE: /* kbdmap(5) keyword `paste`. */ #ifndef SC_NO_CUTPASTE /* Insert text from cut-paste buffer. */ - /* TODO */ + vt_mouse_paste(); #endif break; case SPCLKEY | PDWN: /* kbdmap(5) keyword `pdwn`. */ @@ -1576,7 +1581,7 @@ mouseb[4] = '!' + x; mouseb[5] = '!' + y; - for (i = 0; i < sizeof(mouseb); i++ ) + for (i = 0; i < sizeof(mouseb); i++) terminal_input_char(vw->vw_terminal, mouseb[i]); } @@ -1614,6 +1619,23 @@ } } +static void +vt_mouse_paste() +{ + term_char_t *buf; + int i, len; + + len = VD_PASTEBUFLEN(main_vd); + buf = VD_PASTEBUF(main_vd); + len /= sizeof(term_char_t); + for (i = 0; i < len; i++) { + if (buf[i] == '\0') + continue; + terminal_input_char(main_vd->vd_curwindow->vw_terminal, + buf[i]); + } +} + void vt_mouse_event(int type, int x, int y, int event, int cnt, int mlevel) { @@ -1621,8 +1643,7 @@ struct vt_window *vw; struct vt_font *vf; term_pos_t size; - term_char_t *buf; - int i, len, mark; + int len, mark; vd = main_vd; vw = vd->vd_curwindow; @@ -1665,17 +1686,10 @@ vd->vd_mx = x; vd->vd_my = y; - if ((vd->vd_mstate & MOUSE_BUTTON1DOWN) && - (vtbuf_set_mark(&vw->vw_buf, VTB_MARK_MOVE, - vd->vd_mx / vf->vf_width, - vd->vd_my / vf->vf_height) == 1)) { - - /* - * We have something marked to copy, so update pointer - * to window with selection. - */ - vd->vd_markedwin = vw; - } + if (vd->vd_mstate & MOUSE_BUTTON1DOWN) + vtbuf_set_mark(&vw->vw_buf, VTB_MARK_MOVE, + vd->vd_mx / vf->vf_width, + vd->vd_my / vf->vf_height); vt_resume_flush_timer(vw->vw_device, 0); return; /* Done */ @@ -1708,27 +1722,7 @@ case 0: /* up */ break; default: - if (vd->vd_markedwin == NULL) - return; - /* Get current selecton size in bytes. */ - len = vtbuf_get_marked_len(&vd->vd_markedwin->vw_buf); - if (len <= 0) - return; - - buf = malloc(len, M_VT, M_WAITOK | M_ZERO); - /* Request copy/paste buffer data, no more than `len' */ - vtbuf_extract_marked(&vd->vd_markedwin->vw_buf, buf, - len); - - len /= sizeof(term_char_t); - for (i = 0; i < len; i++ ) { - if (buf[i] == '\0') - continue; - terminal_input_char(vw->vw_terminal, buf[i]); - } - - /* Done, so cleanup. */ - free(buf, M_VT); + vt_mouse_paste(); break; } return; /* Done */ @@ -1761,8 +1755,38 @@ * We have something marked to copy, so update pointer to * window with selection. */ - vd->vd_markedwin = vw; vt_resume_flush_timer(vw->vw_device, 0); + + switch (mark) { + case VTB_MARK_END: + case VTB_MARK_WORD: + case VTB_MARK_ROW: + case VTB_MARK_EXTEND: + break; + default: + /* Other types of mark do not require to copy data. */ + return; + } + + /* Get current selection size in bytes. */ + len = vtbuf_get_marked_len(&vw->vw_buf); + if (len <= 0) + return; + + /* Reallocate buffer only if old one is too small. */ + if (len > VD_PASTEBUFSZ(vd)) { + VD_PASTEBUF(vd) = realloc(VD_PASTEBUF(vd), len, M_VT, + M_WAITOK | M_ZERO); + /* Update buffer size. */ + VD_PASTEBUFSZ(vd) = len; + } + /* Request copy/paste buffer data, no more than `len' */ + vtbuf_extract_marked(&vw->vw_buf, VD_PASTEBUF(vd), + VD_PASTEBUFSZ(vd)); + + VD_PASTEBUFLEN(vd) = len; + + /* XXX VD_PASTEBUF(vd) have to be freed on shutdown/unload. */ } }