diff -uNr gpm-1.20.0-orig/src/gpm.c gpm-1.20.0/src/gpm.c --- gpm-1.20.0-orig/src/gpm.c 2002-02-23 17:42:23.000000000 +0200 +++ gpm-1.20.0/src/gpm.c 2002-11-20 05:26:37.000000000 +0200 @@ -21,6 +21,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ********/ +/* + * Xwindow Copy&Paste patch + * (c) 2002 Alex Efros + */ + #include #include #include /* strerror(); ?!? */ @@ -38,12 +43,17 @@ #include /* struct sockaddr_un */ #include /* VT_GETSTATE */ -#include /* KDGETMODE */ +#include /* KDGETMODE */ /* XCaP: E_TABSZ GIO_SCRNMAP */ #include /* winsize */ #include "headers/gpmInt.h" #include "headers/message.h" +/* XCaP start */ +#include /* isspace() */ +#include "headers/xcap.h" +/* XCaP end */ + #if !defined(__GLIBC__) typedef unsigned int __socklen_t; #endif /* __GLIBC__ */ @@ -186,6 +196,20 @@ } /*-------------------------------------------------------------------*/ + +/* XCaP start */ +/* inword() from /usr/src/linux-2.4.19/drivers/char/selection.c */ +static inline int inword(const unsigned char c) { + return ( inwordLut[c>>5] >> (c & 0x1F) ) & 1; +} +/* atedge() from /usr/src/linux-2.4.19/drivers/char/selection.c */ +static inline int atedge(const int p, int size_row) +{ + /* p+2 changed to p+1 because kernel operate with screen address */ + return (!(p % size_row) || !((p + 1) % size_row)); +} +/* XCaP end */ + static inline void selection_copy(int x1, int y1, int x2, int y2, int mode) { /* @@ -195,7 +219,107 @@ unsigned char buf[6*sizeof(short)]; unsigned short *arg = (unsigned short *)buf + 1; int fd; - + + /* XCaP start */ + int i, j; /* loop variables */ + FILE *co_fptr; /* file with current console image */ + char scr[SCR_SIZE]; /* current console image */ + int scr_lth; /* current console image size */ + char scrmap[E_TABSZ]; /* current screen map for inverse translation */ + int p1, p2; /* cursor top/left and bottom/right position */ + int n1, n2; /* selection top/left and bottom/right position */ + int tmp; /* temp integer */ + char *bp, *obp; /* temp pointers to fill sel_buffer */ + + /* read data from the console */ + if( ((co_fptr=fopen("/dev/vcs0","r"))==NULL) && /* usual /dev/ */ + ((co_fptr=fopen("/dev/vcc/0","r"))==NULL) ) /* devfs /dev/ */ + gpm_report(GPM_PR_OOPS, "open /dev/vcs0 or /dev/vcc/0"); + scr_lth = fread(&scr, sizeof(char), SCR_SIZE-1, co_fptr); + fclose(co_fptr); + scr[scr_lth] = 0; + /* unmap font translation */ + /* ... is it possible to use kernel's inverse_translate() here? */ + if ((fd=open_console(O_RDONLY))<0) + gpm_report(GPM_PR_OOPS,GPM_MESS_OPEN_CON); + if (ioctl(fd,GIO_SCRNMAP,&scrmap)) + gpm_report(GPM_PR_OOPS,"GIO_SCRNMAP"); + close(fd); + for (j=0; jy2) { tmp=y1; y1=y2; y2=tmp; tmp=x1; x1=x2; x2=tmp; } + if (y1==y2 && x1>x2) { tmp=x1; x1=x2; x2=tmp; } + p1 = (y1-1)*win.ws_col+x1-1; + p2 = (y2-1)*win.ws_col+x2-1; + n1 = 0; + n2 = 0; + /* selection logic from /usr/src/linux-2.4.19/drivers/char/selection.c */ + if (mode==0) { /* character-by-character selection */ + n1=p1; + n2=p2; + } + if (mode==1) { /* word-by-word selection */ + tmp = isspace(scr[p1]); + for (n1 = p1; ; p1--) { + if ((tmp && !isspace(scr[p1])) || (!tmp && !inword(scr[p1]))) + break; + n1 = p1; + if (!(p1 % win.ws_col)) + break; + } + tmp = isspace(scr[p2]); + for (n2 = p2; ; p2++) { + if ((tmp && !isspace(scr[p2])) || (!tmp && !inword(scr[p2]))) + break; + n2 = p2; + if (!((p2+1) % win.ws_col)) + break; + } + } + if (mode==2) { /* line-by-line selection */ + n1 = p1 - p1 % win.ws_col; + n2 = p2 + win.ws_col - p2 % win.ws_col - 1; + } + /* select to end of line if on trailing space */ + if (n2 > n1 && !atedge(n2, win.ws_col) && isspace(scr[n2])) { + for (p2 = n2+1; ; p2++) + if (!isspace(scr[p2]) || atedge(p2, win.ws_col)) + break; + if (isspace(scr[p2])) + n2 = p2; + } + /* save selection to sel_buffer */ + if (mode<3) { + /* is the buffer big enough? */ + if(((n2-n1+1)>=sel_buffer_lth) && ((n2-n1+1)>=SCR_SIZE)) { + free(sel_buffer); + sel_buffer=malloc((n2-n1+1)+1); + } + /* save selection, replacÅ trailing spaces to \n in each line */ + bp = sel_buffer; + obp= sel_buffer; + for (i = n1; i <= n2; i++ ) { + *bp = scr[i]; + if (!isspace(*bp++)) + obp = bp; + if (! ((i+1) % win.ws_col)) { + if (obp != bp) { + bp = obp; + *bp++ = '\n'; + } + obp = bp; + } + } + sel_buffer_lth = bp - sel_buffer; + *(sel_buffer+sel_buffer_lth) = 0; + } + /* XCaP end */ + buf[sizeof(short)-1] = 2; /* set selection */ arg[0]=(unsigned short)x1; @@ -227,6 +351,12 @@ char c=3; int fd; + /* XCaP start */ + int i; + struct stat X0; + FILE *xclip; + /* XCaP start */ + if (!opt_aged && (0 != opt_age_limit) && (last_selection_time + opt_age_limit < time(0))) { opt_aged = 1; @@ -237,20 +367,69 @@ return; } + /* XCaP start */ + /* check Xwindow: if Xwindow not active - xclip freeze for 6 sec :( */ + if (stat("/tmp/.X11-unix/X0", &X0) != -1) { + if (!(xclip=popen("/usr/X11R6/bin/xclip -d :0 -o", "r"))) + gpm_report(GPM_PR_OOPS,"open pipe"); + /* read Xwindow clipboard into current selection */ + if ((i = fread(sel_buffer, sizeof(char), SCR_SIZE-1, xclip)) > 0) + *(sel_buffer+(sel_buffer_lth=i)) = 0; + if (!WIFEXITED(pclose(xclip))) + gpm_report(GPM_PR_OOPS,"close pipe"); + } + fd=open_console(O_WRONLY); + for(i=0; ix; y2=event->y; switch(GPM_BARE_EVENTS(event->type)) { + + /* XCaP start */ + case GPM_UP: + if(event->buttons==GPM_B_LEFT) { + /* check Xwindow: if Xwindow not active - xclip freeze for 6 sec :( */ + if (stat("/tmp/.X11-unix/X0", &X0) != -1) { + if (!(xclip=popen("/usr/X11R6/bin/xclip -d :0 -i", "w"))) + gpm_report(GPM_PR_OOPS,"open pipe"); + /* send currect selection to Xwindow clipboard */ + fwrite(sel_buffer, sizeof(char), sel_buffer_lth, xclip); + if (!WIFEXITED(pclose(xclip))) + gpm_report(GPM_PR_OOPS,"close pipe"); + } + /*resize sel_buffer back to "normal" size*/ + if(sel_buffer_lth>SCR_SIZE) { + free(sel_buffer); + sel_buffer=malloc(SCR_SIZE); + sel_buffer_lth=SCR_SIZE; + } + } + /* XCaP end */ + case GPM_MOVE: if (x2<1) x2++; else if (x2>maxx) x2--; if (y2<1) y2++; else if (y2>maxy) y2--; @@ -951,6 +1130,11 @@ maxfd=max(fd, maxfd); } + /* XCaP start */ + sel_buffer=malloc(SCR_SIZE); + sel_buffer_lth=SCR_SIZE; + /* XCaP end */ + /*....................................... catch interesting signals */ signal(SIGTERM, gpm_killed); diff -uNr gpm-1.20.0-orig/src/gpn.c gpm-1.20.0/src/gpn.c --- gpm-1.20.0-orig/src/gpn.c 2002-02-23 17:42:23.000000000 +0200 +++ gpm-1.20.0/src/gpn.c 2002-11-20 05:26:07.000000000 +0200 @@ -24,6 +24,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ********/ +/* + * Xwindow Copy&Paste patch + * (c) 2002 Alex Efros + */ + #include #include #include /* strerror(); ?!? memcpy() */ @@ -56,6 +61,8 @@ #include "headers/gpmInt.h" #include "headers/gpm.h" +#include "headers/xcap.h" + #define mkfifo(path, mode) (mknod ((path), (mode) | S_IFIFO, 0)) extern int errno; @@ -106,9 +113,6 @@ 0x00000000 /* Latin-1 lowercase */ }; - -#define inwordLut (long_array+1) - for (i=0; charset[i]; ) { i += getsym(charset+i, &this); if (charset[i] == '-' && charset[i + 1] != '\0') @@ -116,9 +120,15 @@ else next = this; for (c = this; c <= next; c++) - inwordLut[c>>5] |= 1 << (c&0x1F); + (long_array+1)[c>>5] |= 1 << (c&0x1F); } - + + /* XCaP */ + /* used in mode=1 (word-by-word selection) */ + for (i=0; i<8; i++) + inwordLut[i] = long_array[i+1]; + /* XCaP */ + if ((fd=open(consolename, O_WRONLY)) < 0) { /* try /dev/console, if /dev/tty0 failed -- is that really senseful ??? */ free(consolename); /* allocated by main */ diff -uNr gpm-1.20.0-orig/src/headers/xcap.h gpm-1.20.0/src/headers/xcap.h --- gpm-1.20.0-orig/src/headers/xcap.h 1970-01-01 03:00:00.000000000 +0300 +++ gpm-1.20.0/src/headers/xcap.h 2002-11-20 05:26:07.000000000 +0200 @@ -0,0 +1,13 @@ +/* + * Xwindow Copy&Paste patch + * (c) 2002 Alex Efros + */ + +#define SCR_SIZE 10240 /* current console image, for 80x25 needed only 2000 */ + +#include /* __u32 */ +__u32 inwordLut[8]; /* used in gpn.c and gpm.c */ + +char *sel_buffer; /* buffer with current selection */ +int sel_buffer_lth; /* size of buffer with current selection */ +