📄 mousecur.c
字号:
/* Zgv v3.1 - GIF, JPEG and PBM/PGM/PPM viewer, for VGA PCs running Linux. * Copyright (C) 1993-1998 Russell Marks. See README for license details. * * mousecur.c - mouse cursor routines. * * These all check has_mouse and return if zero, so there's no need * to check that before calling them. */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <vga.h>#include <vgagl.h>#include <vgamouse.h>#include "rc_config.h"#include "rcfile.h"#include "zgv.h"/* Zgv has more problems with drawing a mouse cursor than most * svgalib programs would. For example, since we need to support 640x480 * 16-colour mode, we can't use any vgagl stuff, or at least not * exclusively. And for 320x400/360x480 modes, we have a specially * squished pointer. :-) */static int usegl=-1,usenarrow=-1;/* for area-under-cursor save buffer. * width/height may be less than sizes below if near edge of screen. */static int savex,savey,savew,saveh;static int screen_width,screen_height,screen_bytepp;#define MOUSECUR_XSIZE 16#define MOUSECUR_YSIZE 16#define MOUSECUR_PIXMAP_SIZE (MOUSECUR_XSIZE*MOUSECUR_YSIZE)/* next two pixmaps are *3 as must be able to handle up to 24-bit modes */static unsigned char mouseptr_save[MOUSECUR_PIXMAP_SIZE*3];static unsigned char mouseptr_pixmap[MOUSECUR_PIXMAP_SIZE*3];static unsigned char mouseptr_pixmap_orig[MOUSECUR_PIXMAP_SIZE]= { /* 1 is black, 2 is white, 0 is transparent */ 0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,1,1,2,2,0,0,0,0,0,0,0,0,0,0,0, 2,1,1,1,1,2,2,0,0,0,0,0,0,0,0,0, 0,2,1,1,1,1,1,2,2,0,0,0,0,0,0,0, 0,2,1,1,1,1,1,1,1,2,2,0,0,0,0,0, 0,0,2,1,1,1,1,1,1,1,1,2,2,0,0,0, 0,0,2,1,1,1,1,1,1,1,1,1,1,2,0,0, 0,0,0,2,1,1,1,1,1,2,2,2,2,0,0,0, 0,0,0,2,1,1,1,1,1,2,0,0,0,0,0,0, 0,0,0,0,2,1,1,2,2,1,2,0,0,0,0,0, 0,0,0,0,2,1,1,2,0,2,1,2,0,0,0,0, 0,0,0,0,0,2,1,2,0,0,2,1,2,0,0,0, 0,0,0,0,0,2,1,2,0,0,0,2,1,2,0,0, 0,0,0,0,0,0,2,0,0,0,0,0,2,1,2,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };static unsigned char mouseptr_pixmap_narrow_orig[MOUSECUR_PIXMAP_SIZE/2]= { /* 1 is black, 2 is white, 0 is transparent */ 0,2,0,0,0,0,0,0, 2,1,2,0,0,0,0,0, 2,1,1,2,0,0,0,0, 2,1,1,1,2,0,0,0, 2,1,1,1,1,2,0,0, 0,2,1,1,1,1,2,0, 0,2,1,1,1,1,1,2, 0,2,1,1,1,2,2,0, 0,2,1,1,1,2,0,0, 0,0,2,1,2,1,2,0, 0,0,2,1,2,1,2,0, 0,0,2,1,2,2,1,2, 0,0,2,1,2,2,1,2, 0,0,0,2,0,0,2,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0 };void mousecur_init(int blackcol,int whitecol){int f,val;int cols=vga_getcolors();int mode=vga_getcurrentmode();if(!has_mouse) return;switch(cols) { case 16777216: screen_bytepp=3; break; case 65536: case 32768: screen_bytepp=2; break; default: screen_bytepp=1; }screen_width =vga_getxdim();screen_height=vga_getydim();mouse_setxrange(0,screen_width-1);mouse_setyrange(0,screen_height-1);switch(mode) { case G640x480x16: case G320x200x256: case G320x240x256: case G320x400x256: case G360x480x256: usegl=0; break; default: usegl=1; }usenarrow=(mode==G320x400x256 || mode==G360x480x256);if(usegl) gl_setcontextvga(vga_getcurrentmode());for(f=0;f<(usenarrow?MOUSECUR_PIXMAP_SIZE/2:MOUSECUR_PIXMAP_SIZE);f++) { switch(usenarrow?mouseptr_pixmap_narrow_orig[f]:mouseptr_pixmap_orig[f]) { case 1: /* black */ val=blackcol; break; case 2: /* white (ish :-)) */ val=whitecol; break; default: /* assume zero - transparent */ val=0; break; } switch(screen_bytepp) { case 3: mouseptr_pixmap[f*3 ]=(val&255); mouseptr_pixmap[f*3+1]=(val>>8); mouseptr_pixmap[f*3+2]=(val>>16); break; case 2: mouseptr_pixmap[f*2 ]=(val&255); mouseptr_pixmap[f*2+1]=(val>>8); break; default: mouseptr_pixmap[f]=val; } }}void mousecur_on(){int small=0,y;if(!has_mouse) return;savex=mouse_getx();savey=mouse_gety();savew=MOUSECUR_XSIZE;saveh=MOUSECUR_YSIZE;if(usenarrow) savew/=2;/* deal with being near edge of screen */if(savex>screen_width-savew) savew=screen_width-savex,small=1;if(savey>screen_height-saveh) saveh=screen_height-savey,small=1;/* we need to save existing data, then draw the mouse. */if(usegl) { /* gl-using 8/15/16/24-bit version */ gl_getbox(savex,savey,savew,saveh,mouseptr_save); /* since there's no gl_putboxpartmask, and clipping doesn't work for * gl_putboxmask, we have to do either masking or clipping ourselves. * Hmm. I'll pick clipping, I think... */ if(small) /* do it a line at a time */ for(y=0;y<saveh;y++) gl_putboxmask(savex,savey+y,savew,1, mouseptr_pixmap+MOUSECUR_XSIZE*y*screen_bytepp); else /* full size, no problem */ gl_putboxmask(savex,savey,savew,saveh,mouseptr_pixmap); }else { static unsigned char scantmp[80]; unsigned char *saveptr,*inptr,*outptr; int x; /* 16-col and low-res-8-bit version */ /* save area */ saveptr=mouseptr_save; for(y=0;y<saveh;y++,saveptr+=savew) vga_getscansegment(saveptr,savex,savey+y,savew); saveptr=mouseptr_save; for(y=0;y<saveh;y++) { inptr=mouseptr_pixmap+y*(usenarrow?MOUSECUR_XSIZE/2:MOUSECUR_XSIZE); outptr=scantmp; for(x=0;x<savew;x++,inptr++,saveptr++) *outptr++=((*inptr)?(*inptr):(*saveptr)); vga_drawscansegment(scantmp,savex,savey+y,savew); } }}void mousecur_off(){if(!has_mouse) return;/* redraw saved data */if(usegl) gl_putbox(savex,savey,savew,saveh,mouseptr_save);else { unsigned char *saveptr=mouseptr_save; int y; for(y=0;y<saveh;y++,saveptr+=savew) vga_drawscansegment(saveptr,savex,savey+y,savew); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -