📄 mouse.c
字号:
/* GPM/xterm mouse functions Copyright (C) 1999 Jesse McGrewThis file is part of JOE (Joe's Own Editor)JOE is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. JOE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with JOE; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "types.h"#ifdef HAVE_SYS_TIME_H#include <sys/time.h>#endifint auto_scroll = 0; /* Set for autoscroll */int auto_rate; /* Rate */int auto_trig_time; /* Time of next scroll */int rtbutton=0; /* use button 3 instead of 1 */int floatmouse=0; /* don't fix xcol after tomouse */int joexterm=0; /* set if we're using Joe's modified xterm */static int selecting = 0; /* Set if we did any selecting */static int Cb, Cx, Cy;static int last_msec=0; /* time in ms when event occurred */static int clicks;static void fake_key(int c){ MACRO *m=dokey(maint->curwin->kbd,c); int x=maint->curwin->kbd->x; maint->curwin->main->kbd->x=x; if(x) maint->curwin->main->kbd->seq[x-1]=maint->curwin->kbd->seq[x-1]; if(m) exemac(m);}/* Translate mouse coordinates */int mcoord(int x){ if (x>=33 && x<=240) return x - 33 + 1; else if (x==32) return -1 + 1; else if (x>240) return x - 257 + 1; else return 0; /* This should not happen */}int uxtmouse(BW *bw){ Cb = ttgetc()-32; if (Cb < 0) return -1; Cx = ttgetc(); if (Cx < 32) return -1; Cy = ttgetc(); if (Cy < 32) return -1; Cx = mcoord(Cx); Cy = mcoord(Cy); if ((Cb & 0x41) == 0x40) { fake_key(KEY_MWUP); return 0; } if ((Cb & 0x41) == 0x41) { fake_key(KEY_MWDOWN); return 0; } if ((Cb & 3) == 3) /* button released */ mouseup(Cx,Cy); else if ((Cb & 3) == (rtbutton ? 2 : 0)) /* preferred button */ if ((Cb & 32) == 0) /* button pressed */ mousedn(Cx,Cy); else /* drag */ mousedrag(Cx,Cy); else if ((maint->curwin->watom->what & TYPETW || maint->curwin->watom->what & TYPEPW) && joexterm && (Cb & 3) == 1) /* Paste */ ttputs(USTR "\33]52;;?\33\\"); return 0;}int mnow(){ struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec * 1000 + tv.tv_usec / 1000;}void mousedn(int x,int y){ Cx = x, Cy = y; if (last_msec == 0 || mnow() - last_msec > MOUSE_MULTI_THRESH) { /* not a multiple click */ clicks=1; fake_key(KEY_MDOWN); } else if(clicks==1) { /* double click */ clicks=2; fake_key(KEY_M2DOWN); } else if(clicks==2) { /* triple click */ clicks=3; fake_key(KEY_M3DOWN); } else { /* start over */ clicks=1; fake_key(KEY_MDOWN); }}/* Return base64 code character given 6-bit number */char base64_code[]="\ABCDEFGHIJKLMNOPQRSTUVWXYZ\abcdefghijklmnopqrstuvwxyz\0123456789+/";int base64_accu = 0;int base64_count = 0;int base64_pad = 0;static void ttputs64(unsigned char *p, unsigned length){ unsigned char buf[65]; unsigned x = 0; while (length--) { switch (base64_count) { case 0: buf[x++] = base64_code[*p >> 2]; base64_accu = (*p & 0x3); base64_count = 2; ++p; break; case 2: buf[x++] = base64_code[(base64_accu << 4) + (*p >> 4)]; base64_accu = (*p & 0xF); base64_count = 4; ++p; break; case 4: buf[x++] = base64_code[(base64_accu << 2) + (*p >> 6)]; buf[x++] = base64_code[*p & 0x3F]; base64_accu = 0; base64_count = 0; ++p; break; } if (x >= 63) { /* Write 63 or 64 characters */ base64_pad += x; buf[x] = 0; ttputs(buf); x = 0; } } if (x != 0) { base64_pad += x; buf[x] = 0; ttputs(buf); }}static void ttputs64_flush(){ unsigned char x; switch (base64_count) { case 0: break; case 2: x = base64_code[base64_accu << 4]; ttputc(x); break; case 4: x = base64_code[base64_accu << 2]; ttputc(x); break; } if (base64_pad & 3) { x = 4 - (base64_pad & 3); while (x--) ttputc('='); } base64_count = 0; base64_accu = 0; base64_pad = 0;}void select_done(struct charmap *map){ /* Feed text to xterm */ if (joexterm && markv(1)) { long left = markb->xcol; long right = markk->xcol; P *q = pdup(markb, USTR "select_done"); int c; /* ttputs(USTR "\33[?2P"); JOE's xterm */ ttputs(USTR "\33]52;;"); /* New xterm */ while (q->byte < markk->byte) { unsigned char buf[16]; int len; /* Skip until we're within columns */ while (q->byte < markk->byte && square && (piscol(q) < left || piscol(q) >= right)) pgetc(q); /* Copy text into buffer */ while (q->byte < markk->byte && (!square || (piscol(q) >= left && piscol(q) < right))) { c = pgetc(q); if (map->type) if (locale_map->type) { /* UTF-8 char to UTF-8 terminal */ len = utf8_encode(buf,c); ttputs64(buf, len); } else { /* UTF-8 char to non-UTF-8 terminal */ c = from_uni(locale_map,c); if (c == -1) c = '?'; buf[0] = c; ttputs64(buf, 1); } else if (locale_map->type) { /* Non-UTF-8 to UTF-8 terminal */ c = to_uni(map, c); if (c == -1) c = '?'; len = utf8_encode(buf,c); ttputs64(buf, len); } else { /* Non-UTF-8 to non-UTF-8 terminal */ buf[0] = c; ttputs64(buf, 1); } } /* Add a new line if we went past right edge of column */ if (square && q->byte<markk->byte && piscol(q) >= right) { buf[0] = 10; ttputs64(buf, 1); } } ttputs64_flush(); ttputs(USTR "\33\\"); prm(q); }}void mouseup(int x,int y){ auto_scroll = 0; Cx = x, Cy = y; if (selecting) { select_done(((BW *)maint->curwin->object)->b->o.charmap); selecting = 0; } switch(clicks) { case 1: fake_key(KEY_MUP); break; case 2: fake_key(KEY_M2UP); break; case 3: fake_key(KEY_M3UP); break; } last_msec = mnow();}void mousedrag(int x,int y){ Cx = x, Cy = y; switch(clicks) { case 1: fake_key(KEY_MDRAG); break; case 2: fake_key(KEY_M2DRAG); break; case 3: fake_key(KEY_M3DRAG); break; }}int drag_size; /* Set if we are resizing a window */int utomouse(BW *xx){ BW *bw; int x = Cx - 1, y = Cy - 1; W *w = watpos(maint,x,y); if (!w) return -1; maint->curwin = w; bw = w->object; drag_size = 0; if (w->watom->what == TYPETW) { if (bw->o.hex) { int goal_col = x - w->x + bw->offset - 60; int goal_line; long goal_byte; if (goal_col < 0) goal_col = 0; if (goal_col >15) goal_col = 15; /* window has a status line? */ if (((TW *)bw->object)->staon) /* clicked on it? */ if (y == w->y) { if (y != maint->wind) drag_size = y; return -1; } else goal_line = y - w->y + bw->top->byte/16 - 1; else goal_line = y - w->y + bw->top->byte/16; goal_byte = goal_line*16L + goal_col; if (goal_byte > bw->b->eof->byte) goal_byte = bw->b->eof->byte; pgoto(bw->cursor, goal_byte); return 0; } else { int goal_col = x - w->x + bw->offset - (bw->o.linums ? LINCOLS : 0); int goal_line;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -