📄 mousecur.c
字号:
/* zgv 5.9 - GIF, JPEG and PBM/PGM/PPM viewer, for VGA PCs running Linux. * Copyright (C) 1993-2005 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. * * SDL mouse support by Dimitar Zhekov. */#ifdef BACKEND_SDL#include <stdlib.h>#include <SDL/SDL.h>#include "zgv.h"static int usenarrow=0;#define MOUSECUR_XSIZE 16#define MOUSECUR_YSIZE 16#define MOUSECUR_PIXMAP_SIZE (((MOUSECUR_XSIZE+7)/8)*MOUSECUR_YSIZE)/* data for zgv's mouse cursor, see non-SDL version */static Uint8 mouse_data[MOUSECUR_PIXMAP_SIZE] = { 0x00, 0x00, 0x60, 0x00, 0x78, 0x00, 0x3e, 0x00, 0x3f, 0x80, 0x1f, 0xe0, 0x1f, 0xf8, 0x0f, 0x80, 0x0f, 0x80, 0x06, 0x40, 0x06, 0x20, 0x02, 0x10, 0x02, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00 };static Uint8 mouse_mask[MOUSECUR_PIXMAP_SIZE] = { 0x60, 0x00, 0xf8, 0x00, 0xfe, 0x00, 0x7f, 0x80, 0x7f, 0xe0, 0x3f, 0xf8, 0x3f, 0xfc, 0x1f, 0xf8, 0x1f, 0xc0, 0x0f, 0xe0, 0x0f, 0x70, 0x07, 0x38, 0x07, 0x1c, 0x02, 0x0e, 0x00, 0x04, 0x00, 0x00 };static Uint8 mouse_data_narrow[MOUSECUR_PIXMAP_SIZE/2] = { 0x00, 0x40, 0x60, 0x70, 0x78, 0x3c, 0x3e, 0x38, 0x38, 0x14, 0x14, 0x12, 0x12, 0x00, 0x00, 0x00 };static Uint8 mouse_mask_narrow[MOUSECUR_PIXMAP_SIZE/2] = { 0x40, 0xe0, 0xf0, 0xf8, 0xfc, 0x7e, 0x7f, 0x7e, 0x7c, 0x3e, 0x3e, 0x3f, 0x3f, 0x12, 0x00, 0x00 };static Uint8 mouse_data_hidden[1] = { 0 }, mouse_mask_hidden[1] = { 0 };static SDL_Cursor *mouse_cursor=NULL, *mouse_cursor_narrow, *mouse_cursor_hidden;void mousecur_init(int blackcol,int whitecol){SDL_Surface *surface=SDL_GetVideoSurface();if(!has_mouse || !surface) return;if(!mouse_cursor) { mouse_cursor=SDL_CreateCursor(mouse_data, mouse_mask, MOUSECUR_XSIZE, MOUSECUR_YSIZE, 0, 0); mouse_cursor_narrow=SDL_CreateCursor(mouse_data_narrow, mouse_mask_narrow, MOUSECUR_XSIZE/2, MOUSECUR_YSIZE, 0, 0); mouse_cursor_hidden=SDL_CreateCursor(mouse_data_hidden, mouse_mask_hidden, 1, 1, 0, 0); if(!mouse_cursor || !mouse_cursor_narrow || !mouse_cursor_hidden) { fprintf(stderr, "zgv: SDL create cursor failed - %s\n" " mouse support disabled...\n", SDL_GetError()); has_mouse=0; return; } SDL_ShowCursor(SDL_ENABLE); }usenarrow=((surface->w==320 && surface->h==400) || (surface->w==360 && surface->h==480));}void mousecur_on(void){if(has_mouse) SDL_SetCursor(usenarrow ? mouse_cursor_narrow : mouse_cursor);}void mousecur_off(void){if(has_mouse) SDL_SetCursor(mouse_cursor_hidden);}#else /* !BACKEND_SDL */#include <stdio.h>#include <string.h>#include <stdlib.h>#include "zgv_io.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 *4 as must be able to handle up to 32-bpp modes */static unsigned char mouseptr_save[MOUSECUR_PIXMAP_SIZE*4];static unsigned char mouseptr_pixmap[MOUSECUR_PIXMAP_SIZE*4];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 mode=vga_getcurrentmode();if(!has_mouse) return;screen_bytepp=vga_getmodeinfo(mode)->bytesperpixel;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 4: mouseptr_pixmap[f*4 ]=(val&255); mouseptr_pixmap[f*4+1]=(val>>8); mouseptr_pixmap[f*4+2]=(val>>16); mouseptr_pixmap[f*4+3]=0; break; 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/32-bpp 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); }}#endif /* !BACKEND_SDL */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -