From: Petr B. <pa...@uc...> - 2002-11-02 20:56:56
Attachments:
chsel.c
|
Hello, this patch (against 2.5.45) extends the selection interface, so that userland programs can directly save the data into the buffer and fetch them from it. This way, it is possible for userland programs to handle cutting and pasting on their own (not necessarily working with the screen content and getting the content of the selection on stdin) or to implement shared selection buffer between X11 and console etc. This patch is roughly based on some very ancient diff I found lying on my disk, however unfortunately I can't remember anymore who implemented this idea originally; I made a lot of changes to the original patch anyway. I wrote a trivial commandline-driven userland interface for this in order to demonstrate the functionality. It is attached and it can be also found at http://pasky.ji.cz/~pasky/dev/kernel/chsel.c. Note that it's possibly totally flawed (I don't know anything about this piece of code), but it looks to work ok. Please review, test and comment. Kind regards, Petr Baudis --- linux-2.5.45/include/linux/selection.h Sat Nov 2 18:31:31 2002 +++ linux-2.5.45+pasky/include/linux/selection.h Sat Nov 2 19:18:40 2002 @@ -18,6 +18,9 @@ extern int mouse_reporting(void); extern void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry); +extern int set_selection_user(const unsigned long arg); +extern int get_selection_user(const unsigned long arg); + #define video_num_columns (vc_cons[currcons].d->vc_cols) #define video_num_lines (vc_cons[currcons].d->vc_rows) #define video_size_row (vc_cons[currcons].d->vc_size_row) --- linux-2.5.45/drivers/char/vt.c Sat Nov 2 18:31:12 2002 +++ linux-2.5.45+pasky/drivers/char/vt.c Sat Nov 2 19:17:27 2002 @@ -2255,6 +2255,12 @@ case 12: /* get fg_console */ ret = fg_console; break; + case 13: /* set selection to data provided by user */ + ret = set_selection_user(arg); + break; + case 14: /* get selection */ + ret = get_selection_user(arg); + break; default: ret = -EINVAL; break; --- linux-2.5.45/drivers/char/selection.c Sat Nov 2 18:31:22 2002 +++ linux-2.5.45+pasky/drivers/char/selection.c Sat Nov 2 20:20:30 2002 @@ -7,8 +7,13 @@ * 'void clear_selection(void)' * 'int paste_selection(struct tty_struct *tty)' * 'int sel_loadlut(const unsigned long arg)' + * 'int get_selection_user(const unsigned long arg)' + * 'int set_selection_user(const unsigned long arg)' * * Now that /dev/vcs exists, most of this can disappear again. + * + * Introduced usable userland selection interface + * 2002-11-02 Petr Baudis <pa...@uc...> */ #include <linux/module.h> @@ -310,5 +315,75 @@ return 0; } +/* Fill the current selection buffer with the data provided in user buffer. + * The maximal size of the selection buffer is trimmed to 65535 here; could + * anyone possibly want more? + * Invoked by ioctl(). */ +int set_selection_user(const unsigned long arg) +{ + unsigned int buf_length; + char *new_sel_buffer = NULL; + char *args; + + clear_selection(); + + args = (char *) (arg + 1); + get_user(buf_length, (unsigned int *) args); + args += sizeof(unsigned int); + + if (buf_length > 0 && buf_length < 65536) { + new_sel_buffer = kmalloc(buf_length, GFP_KERNEL); + if (!new_sel_buffer) { + printk(KERN_WARNING "selection: kmalloc() failed\n"); + return -ENOMEM; + } + if (copy_from_user(new_sel_buffer, (char *) args, buf_length)){ + kfree(new_sel_buffer); + return -EFAULT; + } + } else if (buf_length) { + return -EINVAL; + } + + if (sel_buffer) + kfree(sel_buffer); + + sel_buffer = new_sel_buffer; + sel_buffer_lth = buf_length; + + return 0; +} + +/* Get (start of) content of the current selection buffer. Users should + * re-fetch if return_value > buf_length. + * Invoked by ioctl(). */ +int get_selection_user(const unsigned long arg) +{ + unsigned int buf_length; + char *args; + + args = (char *) (arg + 1); + get_user(buf_length, (unsigned int *) args); + if (buf_length > sel_buffer_lth) { + buf_length = sel_buffer_lth; + if (copy_to_user((char *) args, &buf_length, + sizeof(unsigned int))) { + return -EFAULT; + } + } + args += sizeof(unsigned int); + + if (!sel_buffer) + return 0; + + if (copy_to_user((char *) args, sel_buffer, buf_length)) { + return -EFAULT; + } + + return sel_buffer_lth; +} + EXPORT_SYMBOL(set_selection); EXPORT_SYMBOL(paste_selection); +EXPORT_SYMBOL(set_selection_user); +EXPORT_SYMBOL(get_selection_user); |
From: James S. <jsi...@ph...> - 2002-11-14 00:36:44
|
Vojtech I have a few changes that I want your approval for. I first removed aux_device_present. We don't need it anymore. The second change is I toke a hack at porting the mips keyboard drivers over to input api. I do have the hardware to test it out but the mips platform is sadly way behind Linus tree. I still like to submit it tho. Do you want me to commit it or me post a diff first. |
From: Vojtech P. <vo...@uc...> - 2002-12-04 01:05:02
|
On Thu, Nov 14, 2002 at 12:36:35AM +0000, James Simmons wrote: > > Vojtech I have a few changes that I want your approval for. I first > removed aux_device_present. We don't need it anymore. The second change is > I toke a hack at porting the mips keyboard drivers over to input api. I do > have the hardware to test it out but the mips platform is sadly way > behind Linus tree. I still like to submit it tho. Do you want me to commit > it or me post a diff first. Sorry for replying with a delay, but vo...@su... (note the 'z') didn't work as an e-mail address that'd reach me. Send me a diff ... -- Vojtech Pavlik SuSE Labs |