Small addition to console driver
Hi all:
Disclaimer:
I'm new here, sorry if I doing something wrong.
What I'm looking for:
I'm looking for comments and approval for a small addition to the console
driver (drivers/char/console.c).
Small description:
The attached patches adds a couple of new services to the TIOCLINUX ioctl
call, they are:
13 (get selection into a buffer): It copies the contents of the selection buffer (maintained in kernel space) into a user space provided buffer. Is something like "paste to a buffer" instead of just paste to the current console.
14 (get selection length): Returns the length of the selection buffer (0 if none selected).
-----------
The attached file (patch.diff) contains diffs that apply without offsets into 2.4.7 kernel, they are valid for 2.2.18 too (with offset). I also attached a simple test. It is in spanish but the code is quite obvious.
Additional question: Why the switch uses numbers? Shouldn't these values be defined as something like TIOCLINUX_GET_SELECTION in a header?
What's the purpose? Just allow pasting in text editors using menues or without the mouse middle button.
SET
--
Salvador Eduardo Tropea (SET). (Electronics Engineer) Visit my home page: http://welcome.to/SetSoft or
http://www.geocities.com/SiliconValley/Vista/6552/
Alternative e-mail: [email protected] [email protected]
[email protected]
Address: Curapaligue 2124, Caseros, 3 de Febrero Buenos Aires, (1678), ARGENTINA Phone: +(5411) 4759 0013
char/console.c renamed from char/console.c.ori +6 -0
@@ -14,6 +14,8 @@* * Copy and paste function by Andrew Haylett, * some enhancements by Alessandro Rubini. +* get selection into a buffer and length by +* Salvador E. Tropea <[email protected]> * * Code to check for different video-cards mostly by Galen Hunt, * <[email protected]>
@@ -2204,6 +2206,10 @@return 0 ;case 12 :/* get fg_console */ return fg_console; +case 13 :/* get selection into a buffer */ +return get_selection_buffer (arg); +case 14 :/* get selection length */ +return put_user (get_selection_length (), (unsigned int *)((char *)arg +1 )); }return -EINVAL ; }
char/selection.c renamed from char/selection.c.ori +35 -0
@@ -288,6 +288,41 @@return 0 ; } +/* Copy the contents of the selection buffer into a +* user space buffer. +* Invoked by ioctl(). +*/ +int get_selection_buffer (const unsigned long arg) +{ +char *dest; +unsigned int length; + +if (get_user (length, (unsigned int *)(arg +sizeof (char )))) +return -EFAULT ; + + dest = (char *)(arg +sizeof (char ) +sizeof (unsigned int )); + +if (length > sel_buffer_lth) + length = sel_buffer_lth; + +if (sel_buffer) { +if (copy_to_user (dest, sel_buffer, length)) +return -EFAULT ; + }else { + length =0 ; + } +__put_user (length, (unsigned long *)(arg +sizeof (char ))); +return 0 ; +} + +/* Get the selection buffer length. +* Invoked by ioctl(). +*/ +unsigned int get_selection_length (void ) +{ +return sel_buffer ? sel_buffer_lth :0 ; +} +/* Insert the contents of the selection buffer into the * queue of the tty associated with the current console. * Invoked by ioctl().
linux/selection.h renamed from linux/selection.h.ori +2 -0
@@ -17,6 +17,8 @@extern int sel_loadlut (const unsigned long arg);extern int mouse_reporting (void );extern void mouse_report (struct tty_struct * tty,int butt,int mrx,int mry); +extern int get_selection_buffer (const unsigned long arg); +extern unsigned int get_selection_length (void );#define video_num_columns (vc_cons[currcons].d->vc_cols)#define video_num_lines (vc_cons[currcons].d->vc_rows)
#include <stdio.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int i,res,fd,largo;
char buffer[sizeof(unsigned int)+2],*s;
unsigned int *lg=(unsigned int *)(buffer+1);
fd=open("/dev/tty1",O_RDWR);
printf("Averiguando el largo de la seleccion:\n"); buffer[0]=14; res=ioctl(fd,TIOCLINUX,&buffer); printf("La iotcl devuelve %d\n",res); printf("Largo: %u\n",*lg);
largo=*lg;
if (*lg==0) return 0;
printf("Pidiendo la seleccion:\n");
s=(char *)malloc(largo+sizeof(unsigned int)+2);
s[0]=13;
lg=(unsigned int *)(s+1);
*lg=largo;
res=ioctl(fd,TIOCLINUX,s);
printf("La iotcl devuelve %d\n",res);
largo=*lg;
printf("Largo devuelto: %d\n",largo);
s+=1+sizeof(unsigned int);
s[largo]=0;
for (i=0; s[i]; i++)
if (s[i]==13) s[i]=10;
printf("Dice esto: '%s' (%d)\n",s,s[0]);
return 0;
}