⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 saa7113h_api.c

📁 2440mmc-and-camera-linux-driver 2440mmc-and-camera-linux-driver
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	created by antiscle <hzh12@tom.com> 2005/07/04*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#include <errno.h>#include <unistd.h>#include <termios.h>#include <linux/fb.h>#include <sys/mman.h>#include <sys/ioctl.h>#include <jpeglib.h>#define	__user#include "videodev.h"#include "saa7113h_api.h"/****************************************************///#include "pxa_camera.h"#define WCAM_VIDIOCSCAMREG  	_IOW('v', 211, int)#define WCAM_VIDIOCGCAMREG   	_IOR('v', 212, int)#define WCAM_VIDIOCSCIREG    	_IOW('v', 213, int)#define WCAM_VIDIOCGCIREG    	_IOR('v', 214, int)#define WCAM_VIDIOCSINFOR		_IOW('v', 215, int)#define WCAM_VIDIOCGINFOR		_IOR('v', 216, int)#define CAMERA_IMAGE_FORMAT_YCBCR422_PACKED    15#define CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR    16#define STILL_IMAGE				CAMERA_STILL//(1)#define VIDEO_START				CAMERA_VIDEO//(0)#define VIDEO_STOP				(-1)/****************************************************/#define	MAIN_TEST#define USER_I2C_INIT	//use i2c initialize#define	FIXED_SOURCE_WIDTH	720#define	FIXED_SOURCE_HEIGHT	625/****************************************************/struct reg_set_s {	int val1;	int val2;};#if defined(USER_I2C_INIT)#include <sys/time.h>static void delay_ms(long ms){/*	struct timeval tvs, tve;	struct timezone tzs, tze;	if(!ms)		return;	gettimeofday(&tvs, &tzs);	while(1) {		long ds, dus;		gettimeofday(&tve, &tze);		dus = tve.tv_usec - tvs.tv_usec;		if(dus<0) {			dus += 1000000;			tve.tv_sec--;		}		ds = tve.tv_sec - tvs.tv_sec;		if((ds*1000000+dus)/1000>=ms)			break;	}*/	fd_set rfds;	struct timeval tv;	FD_ZERO(&rfds);	FD_SET(0, &rfds);	tv.tv_sec = 0;	tv.tv_usec = ms*1000;	select(1, &rfds, NULL,  NULL, &tv);}#define	CAMERA_I2C_ADDR	0x24#define CHIP_DELAY		0xFFstruct i2c_reg_t {	int subaddr;	int value;};static struct i2c_reg_t camera_regs[] = {{0x00, 0x00},		//ADR 0x00h		PH7113_CHIP_VERSION 00 - ID byte{0x01, 0x08},		//ADR 0x01h		PH7113_INCREMENT_DELAY - (1) (1) (1) (1) IDEL3 IDEL2 IDELL1 IDEL0{0x02, 0xc0},		//ADR 0x02h		PH7113_ANALOG_INPUT_CONTR_1 - FUSE1 FUSE0 GUDL1 GUDL0 MODE3 MODE2 MODE1 MODE0{0x03, 0x23},		//ADR 0x03h		PH7113_ANALOG_INPUT_CONTR_2 - (1) HLNRS VBSL WPOFF HOLDG GAFIX GAI28 GAI18{0x04, 0x00},		//ADR 0x04h		PH7113_ANALOG_INPUT_CONTR_3 - GAI17 GAI16 GAI15 GAI14 GAI13 GAI12 GAI11 GAI10{0x05, 0x00},		//ADR 0x05h		PH7113_ANALOG_INPUT_CONTR_4 - GAI27 GAI26 GAI25 GAI24 GAI23 GAI22 GAI21 GAI20{0x06, 0xe9},		//ADR 0x06h		PH7113_HORIZONTAL_SYNC_START - HSB7 HSB6 HSB5 HSB4 HSB3 HSB2 HSB1 HSB0{0x07, 0x0d},		//ADR 0x07h		PH7113_HORIZONTAL_SYNC_STOP - HSS7 HSS6 HSS5 HSS4 HSS3 HSS2 HSS1 HSS0{0x08, 0x98},		//ADR 0x08h		PH7113_SYNC_CONTROL - AUFD FSEL FOET HTC1 HTC0 HPLL VNOI1 VNOI0{0x09, 0x01},		//ADR 0x09h		PH7113_LUMINANCE_CONTROL - BYPS PREF BPSS1 BPSS0 VBLB UPTCV APER1 APER0{0x0a, 0x80},		//ADR 0x0ah		PH7113_LUMINANCE_BRIGHTNESS - BRIG7 BRIG6 BRIG5 BRIG4 BRIG3 BRIG2 BRIG1 BRIG0{0x0b, 0x47},		//ADR 0x0bh		PH7113_LUMINANCE_CONTRAST - CONT7 CONT6 CONT5 CONT4 CONT3 CONT2 CONT1 CONT0{0x0c, 0x40},		//ADR 0x0ch		PH7113_CHROMA_SATURATION - SATN7 SATN6 SATN5 SATN4 SATN3 SATN2 SATN1 SATN0{0x0d, 0x00},		//ADR 0x0dh		PH7113_CHROMA_HUE_CONTROL - HUEC7 HUEC6 HUEC5 HUEC4 HUEC3 HUEC2 HUEC1 HUEC0{0x0e, 0x05},	 	//ADR 0x0eh		PH7113_CHROMA_CONTROL - CDTO CSTD2 CSTD1 CSTD0 DCCF FCTC CHBW1 CHBW0{0x0f, 0x24},		//ADR 0x0fh		PH7113_CHROMA_GAIN_CONTROL - ACGC CGAIN6 CGAIN5 CGAIN4 CGAIN3 CGAIN2 CGAIN1 CGAIN0{0x10, 0x00},		//ADR 0x10h		PH7113_FORMAT_DELAY_CONTROL - OFTS1 OFTS0 HDEL1 HDEL0 VRLN YDEL2 YDEL1 YDEL0{0x11, 0x1d},//0x1c//ADR 0x11h 	PH7113_OUTPUT_CONTROL_1 - GPSW1 CM99 GPSW0 HLSEL OEYC OERT VIPB COLO{0x12, 0xa7},//0xc7 ,		//ADR 0x12h		PH7113_OUTPUT_CONTROL_2 - RTSE13 RTSE12 RTSE11 RTSE10 RTSE03 RTSE02 RTSE01 RTSE00			//RTS0 is VLINE,RTS1 is VFRAME{0x13, 0x81},//0x01//ADR 0x13h		PH7113_OUTPUT_CONTROL_3 - ADLSB (1) (1) OLDSB FIDP (1) AOSL1 AOSL0{0x14, 0x00},		//ADR 0x14h		RESERVED 14 - (1) (1) (1) (1) (1) (1) (1) (1){0x15, 0x38},		//ADR 0x15h		PH7113_V_GATE1_START - VSTA7 VSTA6 VSTA5 VSTA4 VSTA3 VSTA2 VSTA1 VSTA0{0x16, 0x00},		//ADR 0x16h		PH7113_V_GATE1_STOP - VSTO7 VSTO6 VSTO5 VSTO4 VSTO3 VSTO2 VSTO1 VSTO0{0x17, 0x01},		//ADR 0x17h		PH7113_V_GATE1_MSB - (1) (1) (1) (1) (1) (1) VSTO8 VSTA8{0x18, 0x00},		//ADR 0x18h{0x19, 0x00},		//ADR 0x19h{0x1a, 0x00},		//ADR 0x1ah{0x1b, 0x00},		//ADR 0x1bh{0x1c, 0x00},		//ADR 0x1ch{0x1d, 0x00},		//ADR 0x1dh{0x1e, 0x00},		//ADR 0x1eh{0x1f, 0x00},		//ADR 0x1fh{0x20, 0x00},		//ADR 0x20h{0x21, 0x00},		//ADR 0x21h{0x22, 0x00},		//ADR 0x22h{0x23, 0x00},		//ADR 0x23h{0x24, 0x00},		//ADR 0x24h{0x25, 0x00},		//ADR 0x25h{0x26, 0x00},		//ADR 0x26h{0x27, 0x00},		//ADR 0x27h{0x28, 0x00},		//ADR 0x28h{0x29, 0x00},		//ADR 0x29h{0x2a, 0x00},		//ADR 0x2ah{0x2b, 0x00},		//ADR 0x2bh{0x2c, 0x00},		//ADR 0x2ch{0x2d, 0x00},		//ADR 0x2dh{0x2e, 0x00},		//ADR 0x2eh{0x2f, 0x00},		//ADR 0x2fh{0x30, 0x00},		//ADR 0x30h{0x31, 0x00},		//ADR 0x31h{0x32, 0x00},		//ADR 0x32h{0x33, 0x00},		//ADR 0x33h{0x34, 0x00},		//ADR 0x34h{0x35, 0x00},		//ADR 0x35h{0x36, 0x00},		//ADR 0x36h{0x37, 0x00},		//ADR 0x37h{0x38, 0x00},		//ADR 0x38h{0x39, 0x00},		//ADR 0x39h{0x3a, 0x00},		//ADR 0x3ah{0x3b, 0x00},		//ADR 0x3bh{0x3c, 0x00},		//ADR 0x3ch{0x3d, 0x00},		//ADR 0x3dh{0x3e, 0x00},		//ADR 0x3eh{0x3f, 0x00},		//ADR 0x3fh{0x40, 0x02},		//ADR 0x40h{0x41, 0xff},		//ADR 0x41h{0x42, 0xff},		//ADR 0x42h{0x43, 0xff},		//ADR 0x43h{0x44, 0xff},		//ADR 0x44h{0x45, 0xff},		//ADR 0x45h{0x46, 0xff},		//ADR 0x46h{0x47, 0xff},		//ADR 0x47h{0x48, 0xff},		//ADR 0x48h{0x49, 0xff},		//ADR 0x49h{0x4a, 0xff},		//ADR 0x4ah{0x4b, 0xff},		//ADR 0x4bh{0x4c, 0xff},		//ADR 0x4ch{0x4d, 0xff},		//ADR 0x4dh{0x4e, 0xff},		//ADR 0x4eh{0x4f, 0xff},		//ADR 0x4fh{0x50, 0xff},		//ADR 0x50h{0x51, 0xff},		//ADR 0x51h{0x52, 0xff},		//ADR 0x52h{0x53, 0xff},		//ADR 0x53h{0x54, 0xff},		//ADR 0x54h{0x55, 0xff},		//ADR 0x55h{0x56, 0xff},		//ADR 0x56h{0x57, 0xff},		//ADR 0x57h{0x58, 0x00},		//ADR 0x58h{0x59, 0x54},		//ADR 0x59h{0x5a, 0x07},		//ADR 0x5ah{0x5b, 0x83},		//ADR 0x5bh{0x5c, 0x00},		//ADR 0x5ch{0x5d, 0x00},		//ADR 0x5dh{0x5e, 0x00},		//ADR 0x5eh{0x5f, 0x00},		//ADR 0x5fh{0x60, 0x00},		//ADR 0x60h{0x61, 0x00},		//ADR 0x61h{0x62, 0x00} 		//ADR 0x62h};#define CAMERA_REGS (sizeof(camera_regs)/sizeof(camera_regs[0]))#endif#ifdef USER_I2C_INITstatic int i2c_write(int fd, __u8 reg, __u8 val){	int retries;	__u8 data[2];	data[0] = reg;	data[1] = val;	for(retries=8; retries; retries--) {		if(write(fd, data, 2)==2)			return 0;		delay_ms(2);	}	//printf("write fail %x %x\n", data[0], data[1]);	return -1;}static int i2c_read(int fd, __u8 reg, __u8 *val){	int retries;	for(retries=8; retries; retries--) {		if(write(fd, &reg, 1)==1)			if(read(fd, val, 1)==1)				return 0;		delay_ms(2);	}	//printf("read fail\n");	return -1;}#define I2C_SLAVE	0x0703	/* Change slave address			*/static int camera_i2c_init(void){	int i, fd;	__u8 id[4];	//delay_ms(100);	printf("open i2c device...\n");	fd = open("/dev/i2c/0", O_RDWR);	if(fd<0) {		fd = open("/dev/misc/i2c", O_RDWR);		if(fd<0) {			printf("fail to open i2c adapter device!\n");			return -1;		}	}	if(ioctl(fd, I2C_SLAVE, CAMERA_I2C_ADDR)<0) {		printf("fail to set i2c device slave address!\n");		close(fd);		return -1;	}	printf("set slave address to 0x%x success!\n", CAMERA_I2C_ADDR);	if(i2c_read(fd, 0, id)) {		printf("fail to get camera chip version!\n");		close(fd);		return -1;	}	printf("chip version is 0x%02x\n", id[0]);	i2c_read(fd, 0x1f, id+1);	printf("decoder status is 0x%02x\n", id[1]);	for(i=0; i<CAMERA_REGS; i++) {		if(camera_regs[i].subaddr==CHIP_DELAY)			delay_ms(camera_regs[i].value);		else if(i2c_write(fd, camera_regs[i].subaddr, camera_regs[i].value))			printf("write subaddr 0x%x fail!\n", camera_regs[i].subaddr);		//delay_ms(2);		//printf("%d\n", i);	}//	if(cpu_type==1)	{	//s3c2440a//		i2c_write(fd, 0x15, 0x00);	//always has PCLK//		i2c_write(fd, 0x3a, 0x01);	//YCbYCr order//	}		close(fd);	return 0;}#else#define	camera_i2c_init()	0#endif/*************************************************************/#define	CAMERA_DEVNAME	"/dev/v4l/video0"static int   cam_fd  = -1;static char *cam_buf = NULL;static char *cam_y_buf;static char *cam_cb_buf;static char *cam_cr_buf;static int   cam_buf_size;static __u16 line_idx[1024];static char *line_y[1024];static char *line_cb[1024];static char *line_cr[1024];static char *image_line[1024];static unsigned char *image_buffer = NULL;static unsigned short image_width;static unsigned short image_height;static unsigned short image_format;static unsigned short mmap_camera;static unsigned short capture_video;static unsigned short cpu_type;static cam_window_t *cam_win_p = NULL;static struct {	int palette;	char *name;} optional_image_format[] = {	{		VIDEO_PALETTE_YUV422P,		"YCbCr422 planar",	},	{		VIDEO_PALETTE_RGB565,		"RGB565",	},/*	{		VIDEO_PALETTE_RGB24,		"RGB24",	},*/};#define	MAX_IMAGE_FORMAT	(sizeof(optional_image_format)/sizeof(optional_image_format[0]))static cam_window_t sub_win_pos[] = {	{0,   0,   720, 624, 1, 1},	{0,   0,   720, 624, 2, 2},	{0,   0,   720, 624, 3, 3},	{0,   0,   720, 624, 4, 4},	{180, 156, 540, 468, 1, 1},	{0,   0,   360, 312, 1, 1},	{360, 0,   720, 312, 1, 1},	{0,   312, 360, 624, 1, 1},	{360, 312, 720, 624, 1, 1},	{0,   0,   240, 208, 1, 1},	{240, 0,   480, 208, 1, 1},	{480, 0,   720, 208, 1, 1},	{0,   208, 240, 416, 1, 1},	{240, 208, 480, 416, 1, 1},	{480, 208, 720, 416, 1, 1},	{0,   416, 240, 624, 1, 1},	{240, 416, 480, 624, 1, 1},	{480, 416, 720, 624, 1, 1},		{40,  72,  680, 552, 1, 1},	{40,  72,  680, 552, 2, 2},	{200, 192, 520, 432, 1, 1},	{168, 168, 552, 456, 1, 1},		{9,   24,  711, 600, 3, 3},};#define	SUB_WIN_NUMBER	(sizeof(sub_win_pos)/sizeof(cam_window_t))int camera_open(int cpu){	int i;	struct video_capability vc;	struct video_window     vw;	struct video_capture    vcp;	struct video_picture    vp;	struct video_mbuf       vm;	cam_fd = open(CAMERA_DEVNAME, O_RDONLY);	//rd&wr	if(cam_fd<0) {		fprintf(stderr, "Open camera fail!\n");		return -ENODEV;	} else		fprintf(stdout, "Open camera success.\n");	image_width  = FIXED_SOURCE_WIDTH;	image_height = FIXED_SOURCE_HEIGHT;	image_format = 0;	//YCbCr4:2:2		cpu_type      = cpu;	mmap_camera   = 1;	if(camera_i2c_init()) {		fprintf(stderr, "fail to initialize the I2C interface of camera!\n");		camera_close();		return -ENODEV;	}	if(ioctl(cam_fd, VIDIOCGCAP, &vc)<0)		fprintf(stderr, "VIDIOCGCAP fail!\n");	else		fprintf(stdout, "max width %d, height %d\nmin width %d, height %d\n",			vc.maxwidth, vc.maxheight, vc.minwidth, vc.minheight);	vw.width  = FIXED_SOURCE_WIDTH;		//fixed in this application	vw.height = FIXED_SOURCE_HEIGHT;	//fixed in this application	if(ioctl(cam_fd, VIDIOCSWIN, &vw)<0)		fprintf(stderr, "VIDIOCSWIN fail!\n");	if(ioctl(cam_fd, VIDIOCGWIN, &vw)<0)		fprintf(stderr, "VIDIOCGWIN fail!\n");	else		fprintf(stdout, "current width %d, height %d\n", vw.width, vw.height);	if(!image_width||!image_height) {		image_width  = vw.width;		image_height = vw.height;	}	//used in s3c2440a	vcp.width  = image_width;	vcp.height = image_height;	if(ioctl(cam_fd, VIDIOCSCAPTURE, &vcp)<0)		fprintf(stderr, "VIDIOCSCAPTURE fail!\n");	else {		if(ioctl(cam_fd, VIDIOCGCAPTURE, &vcp)<0)			fprintf(stderr, "VIDIOCGCAPTURE fail!\n");		else			fprintf(stdout, "capture width %d, height %d\n", vcp.width, vcp.height);	}	vp.palette = optional_image_format[image_format].palette;	if(ioctl(cam_fd, VIDIOCSPICT, &vp)<0)		fprintf(stderr, "VIDIOCSPICT fail!\n");	if(ioctl(cam_fd, VIDIOCGPICT, &vp)<0)		fprintf(stderr, "VIDIOCGPICT fail!\n");	else		fprintf(stdout, "current palette %d\n",	vp.palette);	if(cpu_type==1) {		if(ioctl(cam_fd, VIDIOCSYCbCr, 2)<0) {			fprintf(stderr, "fail to set YCbCr order!\n");		}	}	if(cpu_type==PXA27X) {		struct reg_set_s reg;		//extend ioctl, just in pxa270		reg.val1 = CAMERA_IMAGE_FORMAT_YCBCR422_PACKED;	//input format for pxa270		reg.val2 = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR;	//output format for pxa270		if(ioctl(cam_fd, WCAM_VIDIOCSINFOR, &reg)<0)			fprintf(stderr, "WCAM_VIDIOCSINFOR fail!\n");		if(ioctl(cam_fd, WCAM_VIDIOCGINFOR, &reg)<0)			fprintf(stderr, "WCAM_VIDIOCGINFOR fail!\n");		else			fprintf(stdout, "current input format %d, output format %d\n",				reg.val1, reg.val2);	}	if(mmap_camera) {		if(ioctl(cam_fd, VIDIOCGMBUF, &vm)<0) {			fprintf(stderr, "VIDIOCGMBUF fail!\n");			mmap_camera = 0;		} else {			fprintf(stdout, "current camera buffer size %d, total frames %d.\n",				vm.size, vm.frames);			cam_buf = (__u8 *)mmap(0, vm.size, PROT_READ, MAP_SHARED, cam_fd, 0);			if((int)cam_buf==-1) {				fprintf(stderr, "mmap camera fail!\n");				cam_buf     = NULL;				mmap_camera = 0;							} else {				cam_buf_size = vm.size;				fprintf(stdout, "mmap camera ok.\n");			}		}	}	if(!mmap_camera) {		fprintf(stdout, "allocate memory for camera buffer.\n");		cam_buf_size = image_width*image_height*2;		cam_buf      = malloc(cam_buf_size);		if(cam_buf==NULL) {			fprintf(stderr, "fail to allocate memory for camera!\n");			camera_close();			return -ENOMEM;		}	}//	fprintf(stdout, "buffer at 0x%08x\n", (int)cam_buf);	cam_y_buf  = cam_buf;	cam_cb_buf = cam_y_buf  + image_height*image_width;	cam_cr_buf = cam_cb_buf + image_height*image_width/2;	for(i=0; i<625; i+=2) {		line_idx[i]   = i/2;		line_idx[i+1] = i/2 + 313;	}	for(i=0; i<625; i++) {		line_y[i]  = cam_y_buf  + line_idx[i]*image_width;		line_cb[i] = cam_cb_buf + line_idx[i]*image_width/2;		line_cr[i] = cam_cr_buf + line_idx[i]*image_width/2;	}	image_buffer = malloc(image_height*image_width*3);	//RGB24	if(image_buffer==NULL) {		fprintf(stderr, "allocate memory fail in saving picture!\n");		camera_close();		return -ENOMEM;	}	for(i=0; i<SUB_WIN_NUMBER; i++) {		sub_win_pos[i].width  = (sub_win_pos[i].x1 - sub_win_pos[i].x0) / sub_win_pos[i].x_ratio;		sub_win_pos[i].height = (sub_win_pos[i].y1 - sub_win_pos[i].y0) / sub_win_pos[i].y_ratio;	}	return cam_fd;}int camera_close(void){	if(cam_fd>=0) {		if(image_buffer!=NULL) {			free(image_buffer);			image_buffer = NULL;		}		if(cam_buf!=NULL) {			if(mmap_camera)				munmap(cam_buf, cam_buf_size);			else				free(cam_buf);			cam_buf = NULL;		}		close(cam_fd);		cam_fd = -1;	}	return 0;}int camera_start(int mode){	capture_video = (mode==CAMERA_VIDEO) ? 1 : 0;	if(capture_video) {		if(ioctl(cam_fd, VIDIOCCAPTURE, VIDEO_START)<0) {			fprintf(stderr, "VIDIOCCAPTURE fail!\n");			return -ENOSYS;		}	} else if(cpu_type==PXA27X) {		if(ioctl(cam_fd, VIDIOCCAPTURE, STILL_IMAGE)<0) {			fprintf(stderr, "VIDIOCCAPTURE fail!\n");			return -ENOSYS;		}	}	return 0;}int camera_stop(void){	if(capture_video) {//		if(ioctl(cam_fd, VIDIOCCAPTURE, VIDEO_STOP)<0) {//			fprintf(stderr, "VIDIOCCAPTURE fail!\n");//			return -ENOSYS;//		}	}		return 0;}int camera_capture(void){	//in pxa270, if capture still image, can do it just one time	if(!capture_video&&cpu_type!=PXA27X)		if(ioctl(cam_fd, VIDIOCCAPTURE, STILL_IMAGE)<0) {			fprintf(stderr, "VIDIOCCAPTURE fail!\n");			return -EIO;		}	return 0;}int camera_get_window(unsigned int idx, cam_window_t *win){	if(idx>=SUB_WIN_NUMBER)		return -EINVAL;		*win = sub_win_pos[idx];	return 0;}int camera_set_window(cam_window_t *win){	int w, h;	w = win->x1 - win->x0;	h = win->y1 - win->y0;	if(win->x0>=win->x1 || win->y0>=win->y1)		return -EINVAL;	if(win->x1>720 || win->y1>624)		return -EINVAL;	if(!win->x_ratio || !win->y_ratio)		return -EINVAL;	if(w&1)		return -EINVAL;	if((w%win->x_ratio) && (h%win->y_ratio))		return -EINVAL;		win->width  = w / win->x_ratio;	win->height = h / win->y_ratio;	sub_win_pos[SUBWIN_USER] = *win;	return 0;}static __inline void convert_rgb16_image(void *buf, int format, cam_window_t *win);static __inline void convert_rgb24_image(void *buf, int format, cam_window_t *win);int camera_output_lines(void *buf, int format, cam_window_t *win){	int ret, rgb24;	if(mmap_camera) {#if 1		//just for performance test in video capturing, int(rdy)->show->int->show		//use read to clear ready flag in driver		ret = read(cam_fd, cam_buf, 0);	//mmap camera for read, so read 0 byte to buf		if(ret<0) {			fprintf(stderr, "read camera fail!%d\n", ret);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -