📄 framebuffer.c
字号:
int l1, l2, l3; /* Draw mouse, background */ mouse_length=mouse_right>fb_xsize?fb_xsize-mouse_left:arrow_width; background_length=background_right-mouse_right; if (background_length+mouse_right>fb_xsize) background_length=fb_xsize-mouse_right; l1=mouse_length*fb_pixelsize; l2=(mouse_right-background_left)*fb_pixelsize; l3=background_length*fb_pixelsize; for (;mouse_top<yend;mouse_top++){ mouse_drawscansegment(mouse_ptr,mouse_left,mouse_top,l1); if (background_length>0) mouse_drawscansegment( background_ptr +l2, mouse_right,mouse_top ,l3); mouse_ptr+=skip; background_ptr+=skip; } } if (background_bottom<mouse_bottom){ /* Count over bottoms! tops will be invalid! */ /* Draw mouse */ mouse_length=mouse_right>fb_xsize?fb_xsize-mouse_left :arrow_width; for (;background_bottom<mouse_bottom;background_bottom++){ mouse_drawscansegment(mouse_ptr,mouse_left,background_bottom ,mouse_length*fb_pixelsize); mouse_ptr+=skip; } }else{ /* Draw background */ background_length=background_right>fb_xsize?fb_xsize-background_left :arrow_width; for (;mouse_bottom<background_bottom;mouse_bottom++){ mouse_drawscansegment(background_ptr,background_left,mouse_bottom ,background_length*fb_pixelsize); background_ptr+=skip; } }}/* This moves the mouse a sophisticated way when the old and new position of the * cursor overlap. */static inline void redraw_mouse_sophisticated(void){ int new_background_x, new_background_y; get_mouse_background(mouse_buffer); put_and_clip_background_buffer_over_mouse_buffer(); memcpy(new_background_buffer,mouse_buffer,fb_pixelsize*arrow_area); new_background_x=mouse_x; new_background_y=mouse_y; render_mouse_arrow(); place_mouse_composite(); memcpy(background_buffer,new_background_buffer,fb_pixelsize*arrow_area); background_x=new_background_x; background_y=new_background_y;}static void redraw_mouse(void){ if (!fb_active) return; /* We are not drawing */ if (mouse_x!=background_x||mouse_y!=background_y){ if (RECTANGLES_INTERSECT( background_x, background_x+arrow_width, mouse_x, mouse_x+arrow_width, background_y, background_y+arrow_height, mouse_y, mouse_y+arrow_height)){ redraw_mouse_sophisticated(); }else{ /* Do a normal hide/show */ get_mouse_background(mouse_buffer); memcpy(new_background_buffer, mouse_buffer,arrow_area*fb_pixelsize); render_mouse_arrow(); hide_mouse(); place_mouse(); memcpy(background_buffer,new_background_buffer ,arrow_area*fb_pixelsize); background_x=mouse_x; background_y=mouse_y; } }}/* This is an empiric magic that ensures * Good white purity * Correct rounding and dithering prediction * And this is the cabbala: * 063 021 063 * 009 009 021 * 255 085 255 * 036 036 084 */static void generate_palette(struct palette *palette){ int a; switch (fb_colors) { case 16: for (a=0;a<fb_palette_colors;a++) { palette->red[a]=(a&8)?65535:0; palette->green[a]=((a>>1)&3)*(65535/3); palette->blue[a]=(a&1)?65535:0; } break; case 256: for (a=0;a<fb_palette_colors;a++){ palette->red[a]=((a>>5)&7)*(65535/7); palette->green[a]=((a>>2)&7)*(65535/7); palette->blue[a]=(a&3)*(65535/3); } break; case 32768: for (a=0;a<fb_palette_colors;a++){ /* palette->red[a]=((a>>10)&31)*(65535/31); palette->green[a]=((a>>5)&31)*(65535/31); palette->blue[a]=(a&31)*(65535/31); */ palette->red[a]= palette->green[a]= palette->blue[a]=(((a&31)*255)/31)*257; } break; case 65536: for (a=0;a<fb_palette_colors;a++){ /* palette->red[a]=((a>>11)&31)*(65535/31); palette->green[a]=((a>>5)&63)*(65535/63); palette->blue[a]=(a&31)*(65535/31); */ palette->green[a]=(((a&63)*255)/64)*257; palette->red[a]= palette->blue[a]=(((a&31)*255)/32)*257; } break; default: for (a=0;a<fb_palette_colors;a++){ palette->red[a]= palette->green[a]= palette->blue[a]=a*257; /* stuff it in both high and low byte */ } }}static void alloc_palette(struct palette *pal){ pal->red=mem_calloc(sizeof(unsigned short)*fb_palette_colors); pal->green=mem_calloc(sizeof(unsigned short)*fb_palette_colors); pal->blue=mem_calloc(sizeof(unsigned short)*fb_palette_colors); if (!pal->red||!pal->green||!pal->blue) { /*internal("Cannot create palette.\n")*/; }}static void free_palette(struct palette *pal){ mem_free(pal->red); mem_free(pal->green); mem_free(pal->blue);}static void set_palette(struct palette *pal){ struct fb_cmap cmap; int i; unsigned short *red=pal->red; unsigned short *green=pal->green; unsigned short *blue=pal->blue; __u16 *r, *g, *b, *t; r=mem_alloc(fb_palette_colors*sizeof(__u16)); g=mem_alloc(fb_palette_colors*sizeof(__u16)); b=mem_alloc(fb_palette_colors*sizeof(__u16)); t=mem_calloc(fb_palette_colors*sizeof(__u16)); if (!r||!g||!b||!t) { /*internal("Cannot allocate memory.\n")*/; } for (i = 0; i < fb_palette_colors; i++) { r[i] = red[i]; g[i] = green[i]; b[i] = blue[i]; /*fprintf(stderr, "%d %d %d\n", r[i], g[i], b[i]);*/ /*fprintf(stderr, "%5x: %5x\t%5x\t%5x\t%5x\n",i,r[i],g[i],b[i],t[i]);*/ } cmap.start = 0; cmap.len = fb_palette_colors; cmap.red = r; cmap.green = g; cmap.blue = b; cmap.transp = t; if ((ioctl(fb_handler, FBIOPUTCMAP, &cmap))==-1) { /*internal("Cannot set palette\n")*/; } mem_free(r);mem_free(g);mem_free(b);mem_free(t);}static void get_palette(struct palette *pal){ struct fb_cmap cmap; int i; __u16 *r, *g, *b, *t; r=mem_alloc(fb_palette_colors*sizeof(__u16)); g=mem_alloc(fb_palette_colors*sizeof(__u16)); b=mem_alloc(fb_palette_colors*sizeof(__u16)); t=mem_alloc(fb_palette_colors*sizeof(__u16)); if (!r||!g||!b||!t) { /*internal("Cannot allocate memory.\n")*/; } cmap.start = 0; cmap.len = fb_palette_colors; cmap.red = r; cmap.green = g; cmap.blue = b; cmap.transp = t; if (ioctl(fb_handler, FBIOGETCMAP, &cmap)) { /*internal("Cannot get palette\n")*/; } for (i = 0; i < fb_palette_colors; i++) { /*printf("%d %d %d\n",r[i],g[i],b[i]);*/ pal->red[i] = r[i]; pal->green[i] = g[i]; pal->blue[i] = b[i]; } mem_free(r);mem_free(g);mem_free(b);mem_free(t);}static void fb_switch_signal(void *data){ struct vt_stat st; struct rect r; int signal=(int)(unsigned long)data; switch(signal) { case SIG_REL: /* release */ fb_active=0; if (!in_gr_operation)ioctl(TTY,VT_RELDISP,1); break; case SIG_ACQ: /* acq */ if (ioctl(TTY,VT_GETSTATE,&st)) return; if (st.v_active != fb_console) return; fb_active=1; ioctl(TTY,VT_RELDISP,VT_ACKACQ); if (have_cmap && current_virtual_device) set_palette(&global_pal); r.x1=0; r.y1=0; r.x2=fb_xsize; r.y2=fb_ysize; if (border_left | border_top | border_right | border_bottom) memset(fb_mem,0,fb_mem_size); if (current_virtual_device) current_virtual_device->redraw_handler(current_virtual_device,&r); break; }}static unsigned char *fb_switch_init(void){ ioctl(TTY, VT_WAITACTIVE, fb_console); install_signal_handler(SIG_REL, fb_switch_signal, (void*)SIG_REL, 1); install_signal_handler(SIG_ACQ, fb_switch_signal, (void*)SIG_ACQ, 0); if (-1 == ioctl(TTY,VT_GETMODE, &vt_omode)) { return stracpy("Could not get VT mode.\n"); } memcpy(&vt_mode, &vt_omode, sizeof(vt_mode)); vt_mode.mode = VT_PROCESS; vt_mode.waitv = 0; vt_mode.relsig = SIG_REL; vt_mode.acqsig = SIG_ACQ; if (-1 == ioctl(TTY,VT_SETMODE, &vt_mode)) { return stracpy("Could not set VT mode.\n"); } return NULL;}static void fb_switch_shutdown(void){ ioctl(TTY,VT_SETMODE, &vt_omode);}static void fb_shutdown_palette(void){ if (have_cmap) { set_palette(&old_palette); free_palette(&old_palette); free_palette(&global_pal); }}static void fb_ctrl_c(struct itrm *i){ kbd_ctrl_c();}#ifndef USE_GPM_DXvoid fb_mouse_setsize(){ struct vt_stat vs; if (!ioctl(0, VT_GETSTATE, &vs)) { fd_set zero; struct timeval tv; FD_ZERO(&zero); memset(&tv, 0, sizeof tv); ioctl(0, VT_ACTIVATE, vs.v_active > 1 ? 1 : 2); tv.tv_sec = 0; tv.tv_usec = 100000; select(0, &zero, &zero, &zero, &tv); tv.tv_sec = 0; tv.tv_usec = 100000; select(0, &zero, &zero, &zero, &tv); tv.tv_sec = 0; tv.tv_usec = 100000; select(0, &zero, &zero, &zero, &tv); ioctl(0, VT_ACTIVATE, vs.v_active); }}#endifvoid unhandle_fb_mouse(void);static void fb_gpm_in(void *nic){#ifndef USE_GPM_DX static int lx = -1, ly = -1;#endif struct event ev; Gpm_Event gev; again: if (Gpm_GetEvent(&gev) <= 0) { unhandle_fb_mouse(); return; } /*fprintf(stderr, "%d %d\n", gev.x, gev.y);*/#ifndef USE_GPM_DX if (gev.x != lx || gev.y != ly) { mouse_x = (gev.x - 1) * fb_xsize / fb_txt_xsize + fb_xsize / fb_txt_xsize / 2 - 1; mouse_y = (gev.y - 1) * fb_ysize / fb_txt_ysize + fb_ysize / fb_txt_ysize / 2 - 1; lx = gev.x, ly = gev.y; }#else if (gev.dx || gev.dy) { if (!(gev.type & gpm_smooth)) { mouse_x += gev.dx * 8; mouse_y += gev.dy * 8; } else { mouse_x += gev.dx; mouse_y += gev.dy; } }#endif ev.ev = EV_MOUSE; if (mouse_x >= fb_xsize) mouse_x = fb_xsize - 1; if (mouse_y >= fb_ysize) mouse_y = fb_ysize - 1; if (mouse_x < 0) mouse_x = 0; if (mouse_y < 0) mouse_y = 0; if (!(gev.type & gpm_smooth) && (gev.dx || gev.dy)) { mouse_x = (mouse_x + 8) / 8 * 8 - 4; mouse_y = (mouse_y + 8) / 8 * 8 - 4; if (mouse_x >= fb_xsize) mouse_x = fb_xsize - 1; if (mouse_y >= fb_ysize) mouse_y = fb_ysize - 1; if (mouse_x < 0) mouse_x = 0; if (mouse_y < 0) mouse_y = 0; } ev.x = mouse_x; ev.y = mouse_y; if (gev.buttons & GPM_B_LEFT) ev.b = B_LEFT; else if (gev.buttons & GPM_B_MIDDLE) ev.b = B_MIDDLE; else if (gev.buttons & GPM_B_RIGHT) ev.b = B_RIGHT; else ev.b = 0; if (gev.type & GPM_DOWN) ev.b |= B_DOWN; else if (gev.type & GPM_UP) ev.b |= B_UP; else if (gev.type & GPM_DRAG) ev.b |= B_DRAG; else ev.b |= B_MOVE;#ifndef USE_GPM_DX if (fb_msetsize < 0) { } else if (fb_msetsize < 10) { fb_msetsize++; } else if ((ev.b & BM_ACT) == B_MOVE && !(ev.b & BM_BUTT)) { fb_mouse_setsize(); fb_msetsize = -1; }#endif if (((ev.b & BM_ACT) == B_MOVE && !(ev.b & BM_BUTT)) || (ev.b & BM_ACT) == B_DRAG) { if (can_read(fb_hgpm)) goto again; } if (!current_virtual_device) return; if (current_virtual_device->mouse_handler) current_virtual_device->mouse_handler(current_virtual_device, ev.x, ev.y, ev.b); redraw_mouse();}static int handle_fb_mouse(void){ Gpm_Connect conn;#ifndef USE_GPM_DX int gpm_ver = 0; struct winsize ws; fb_old_ws_v = 0;#endif fb_hgpm = -1;#ifndef USE_GPM_DX Gpm_GetLibVersion(&gpm_ver); if (gpm_ver >= 11900 && ioctl(1, TIOCGWINSZ, &ws) != -1) { memcpy(&fb_old_ws, &ws, sizeof(struct winsize)); fb_old_ws_v = 1; ws.ws_row *= 2; ioctl(1, TIOCSWINSZ, &ws); fb_msetsize = 0; memcpy(&fb_new_ws, &ws, sizeof ws); } else fb_msetsize = -1; get_terminal_size(1, &fb_txt_xsize, &fb_txt_ysize);#endif conn.eventMask = ~0; conn.defaultMask = gpm_smooth; conn.minMod = 0; conn.maxMod = -1; if ((fb_hgpm = Gpm_Open(&conn, 0)) < 0) { unhandle_fb_mouse(); return -1; } set_handlers(fb_hgpm, fb_gpm_in, NULL, NULL, NULL);#ifdef SIGTSTP install_signal_handler(SIGTSTP, (void (*)(void *))sig_tstp, NULL, 0);#endif#ifdef SIGCONT install_signal_handler(SIGCONT, (void (*)(void *))sig_cont, NULL, 0);#endif#ifdef SIGTTIN install_signal_handler(SIGTTIN, (void (*)(void *))sig_tstp, NULL, 0);#endif return 0;}void unhandle_fb_mouse(void){ if (fb_hgpm >= 0) set_handlers(fb_hgpm, NULL, NULL, NULL, NULL);#ifndef USE_GPM_DX fb_hgpm = -1; if (fb_old_ws_v) { ioctl(1, TIOCSWINSZ, &fb_old_ws); fb_old_ws_v = 0; }#endif Gpm_Close();#ifdef SIGTSTP install_signal_handler(SIGTSTP, (void (*)(void *))sig_tstp, NULL, 0);#endif#ifdef SIGCONT install_signal_handler(SIGCONT, (void (*)(void *))sig_cont, NULL, 0);#endif#ifdef SIGTTIN install_signal_handler(SIGTTIN, (void (*)(void *))sig_tstp, NULL, 0);#endif}#ifndef USE_GPM_DXstatic void block_fb_mouse(void){ if (fb_hgpm >= 0) set_handlers(fb_hgpm, NULL, NULL, NULL, NULL);#ifndef USE_GPM_DX if (fb_old_ws_v) { ioctl(1, TIOCSWINSZ, &fb_old_ws); }#endif}static void unblock_fb_mouse(void){ if (fb_hgpm >= 0) set_handlers(fb_hgpm, fb_gpm_in, NULL, NULL, NULL);#ifndef USE_GPM_DX if (fb_old_ws_v) { ioctl(1, TIOCSWINSZ, &fb_new_ws); fb_msetsize = 0; }#endif}#endifstatic void fb_hide_cursor(void){ printf("\033[10000B\033[10000C\033[?25l"); fflush(stdout);}static void fb_show_cursor(void){ printf("\033[10000D\033[?25h"); fflush(stdout);}static unsigned char *fb_init_driver(unsigned char *param, unsigned char *ignore){ unsigned char *e; struct stat st; kbd_set_raw = 1; fb_old_vd = NULL; ignore=ignore; fb_driver_param=NULL; if(param != NULL) fb_driver_param=stracpy(param); border_left = border_right = border_top = border_bottom = 0; if (!param) param=""; if (*param) { if (*param < '0' || *param > '9') { bad_p: if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; } return stracpy("-mode syntax is left_border[,top_border[,right_border[,bottom_border]]]\n"); } border_left = strtoul(param, (char **)(void *)¶m, 10); if (*param == ',') param++; } else { border_left = 0; } if (*param) { if (*param < '0' || *param > '9') goto bad_p; border_top = strtoul(param, (char **)(void *)¶m, 10); if (*param == ',') param++; } else { border_top = border_left; } if (*param) { if (*param < '0' || *param > '9') goto bad_p; border_right = strtoul(param, (char **)(void *)¶m, 10); if (*param == ',') param++; } else { border_right = border_left; } if (*param) { if (*param < '0' || *param > '9') goto bad_p; border_bottom = strtoul(param, (char **)(void *)¶m, 10); if (*param == ',') param++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -