videodev.c
来自「omap3 linux 2.6 用nocc去除了冗余代码」· C语言 代码 · 共 2,112 行 · 第 1/4 页
C
2,112 行
/* * Video capture interface for Linux version 2 * * A generic video device interface for the LINUX operating system * using a set of device structures/vectors for low level operations. * * This program 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 * 2 of the License, or (at your option) any later version. * * Authors: Alan Cox, <alan@redhat.com> (version 1) * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2) * * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com> * - Added procfs support */#define dbgarg(cmd, fmt, arg...) \ if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \ printk (KERN_DEBUG "%s: ", vfd->name); \ v4l_printk_ioctl(cmd); \ printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); \ }#define dbgarg2(fmt, arg...) \ if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg);#include <linux/module.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/mm.h>#include <linux/string.h>#include <linux/errno.h>#include <linux/init.h>#include <linux/kmod.h>#include <linux/slab.h>#include <asm/uaccess.h>#include <asm/system.h>#define __OLD_VIDIOC_ /* To allow fixing old calls*/#include <linux/videodev2.h>#include <media/v4l2-common.h>#include <linux/video_decoder.h>#define VIDEO_NUM_DEVICES 256#define VIDEO_NAME "video4linux"/* video4linux standard ID conversion to standard name */char *v4l2_norm_to_name(v4l2_std_id id){ char *name; u32 myid = id; /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle 64 bit comparations. So, on that architecture, with some gcc variants, compilation fails. Currently, the max value is 30bit wide. */ BUG_ON(myid != id); switch (myid) { case V4L2_STD_PAL: name = "PAL"; break; case V4L2_STD_PAL_BG: name = "PAL-BG"; break; case V4L2_STD_PAL_DK: name = "PAL-DK"; break; case V4L2_STD_PAL_B: name = "PAL-B"; break; case V4L2_STD_PAL_B1: name = "PAL-B1"; break; case V4L2_STD_PAL_G: name = "PAL-G"; break; case V4L2_STD_PAL_H: name = "PAL-H"; break; case V4L2_STD_PAL_I: name = "PAL-I"; break; case V4L2_STD_PAL_D: name = "PAL-D"; break; case V4L2_STD_PAL_D1: name = "PAL-D1"; break; case V4L2_STD_PAL_K: name = "PAL-K"; break; case V4L2_STD_PAL_M: name = "PAL-M"; break; case V4L2_STD_PAL_N: name = "PAL-N"; break; case V4L2_STD_PAL_Nc: name = "PAL-Nc"; break; case V4L2_STD_PAL_60: name = "PAL-60"; break; case V4L2_STD_NTSC: name = "NTSC"; break; case V4L2_STD_NTSC_M: name = "NTSC-M"; break; case V4L2_STD_NTSC_M_JP: name = "NTSC-M-JP"; break; case V4L2_STD_NTSC_443: name = "NTSC-443"; break; case V4L2_STD_NTSC_M_KR: name = "NTSC-M-KR"; break; case V4L2_STD_SECAM: name = "SECAM"; break; case V4L2_STD_SECAM_DK: name = "SECAM-DK"; break; case V4L2_STD_SECAM_B: name = "SECAM-B"; break; case V4L2_STD_SECAM_D: name = "SECAM-D"; break; case V4L2_STD_SECAM_G: name = "SECAM-G"; break; case V4L2_STD_SECAM_H: name = "SECAM-H"; break; case V4L2_STD_SECAM_K: name = "SECAM-K"; break; case V4L2_STD_SECAM_K1: name = "SECAM-K1"; break; case V4L2_STD_SECAM_L: name = "SECAM-L"; break; case V4L2_STD_SECAM_LC: name = "SECAM-LC"; break; default: name = "Unknown"; break; } return name;}EXPORT_SYMBOL(v4l2_norm_to_name);/* Fill in the fields of a v4l2_standard structure according to the 'id' and 'transmission' parameters. Returns negative on error. */int v4l2_video_std_construct(struct v4l2_standard *vs, int id, char *name){ u32 index = vs->index; memset(vs, 0, sizeof(struct v4l2_standard)); vs->index = index; vs->id = id; if (id & V4L2_STD_525_60) { vs->frameperiod.numerator = 1001; vs->frameperiod.denominator = 30000; vs->framelines = 525; } else { vs->frameperiod.numerator = 1; vs->frameperiod.denominator = 25; vs->framelines = 625; } strlcpy(vs->name, name, sizeof(vs->name)); return 0;}EXPORT_SYMBOL(v4l2_video_std_construct);/* ----------------------------------------------------------------- *//* some arrays for pretty-printing debug messages of enum types */char *v4l2_field_names[] = { [V4L2_FIELD_ANY] = "any", [V4L2_FIELD_NONE] = "none", [V4L2_FIELD_TOP] = "top", [V4L2_FIELD_BOTTOM] = "bottom", [V4L2_FIELD_INTERLACED] = "interlaced", [V4L2_FIELD_SEQ_TB] = "seq-tb", [V4L2_FIELD_SEQ_BT] = "seq-bt", [V4L2_FIELD_ALTERNATE] = "alternate", [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb", [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",};EXPORT_SYMBOL(v4l2_field_names);char *v4l2_type_names[] = { [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap", [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over", [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out", [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap", [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",};EXPORT_SYMBOL(v4l2_type_names);static char *v4l2_memory_names[] = { [V4L2_MEMORY_MMAP] = "mmap", [V4L2_MEMORY_USERPTR] = "userptr", [V4L2_MEMORY_OVERLAY] = "overlay",};#define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \ arr[a] : "unknown")/* ------------------------------------------------------------------ *//* debug help functions */static const char *v4l1_ioctls[] = { [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP", [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN", [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN", [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER", [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER", [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT", [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT", [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE", [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN", [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN", [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF", [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF", [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY", [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ", [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ", [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO", [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO", [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC", [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE", [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF", [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT", [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE", [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE", [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE", [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE", [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO", [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE", [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT", [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT"};#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)static const char *v4l2_ioctls[] = { [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED", [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT", [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT", [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT", [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS", [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF", [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF", [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF", [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY", [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF", [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF", [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON", [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF", [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM", [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM", [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD", [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD", [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD", [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT", [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL", [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL", [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER", [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER", [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO", [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO", [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL", [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU", [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT", [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT", [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT", [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT", [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT", [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT", [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT", [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR", [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR", [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY", [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY", [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP", [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP", [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP", [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP", [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP", [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD", [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT", [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO", [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT", [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY", [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY", [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP", [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS", [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS", [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS", [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS", [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES", [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS", [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX", [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD", [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD", [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER", [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT",};#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)static const char *v4l2_int_ioctls[] = { [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES", [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS", [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM", [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT", [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT", [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT", [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE", [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO", [_IOC_NR(DECODER_INIT)] = "DECODER_INIT", [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS", [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP", [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO", [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR", [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY", [_IOC_NR(TUNER_SET_CONFIG)] = "TUNER_SET_CONFIG", [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE", [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET", [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ", [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE", [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA", [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA", [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ", [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY", [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING", [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING", [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING", [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING", [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ", [_IOC_NR(VIDIOC_INT_INIT)] = "VIDIOC_INT_INIT", [_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)] = "VIDIOC_INT_G_STD_OUTPUT", [_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)] = "VIDIOC_INT_S_STD_OUTPUT",};#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)/* Common ioctl debug function. This function can be used by external ioctl messages as well as internal V4L ioctl */void v4l_printk_ioctl(unsigned int cmd){ char *dir; switch (_IOC_DIR(cmd)) { case _IOC_NONE: dir = "--"; break; case _IOC_READ: dir = "r-"; break; case _IOC_WRITE: dir = "-w"; break; case _IOC_READ | _IOC_WRITE: dir = "rw"; break; default: dir = "*ERR*"; break; } switch (_IOC_TYPE(cmd)) { case 'd': printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n", (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ? v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); break; case 'v': printk("v4l1 ioctl %s, dir=%s (0x%08x)\n", (_IOC_NR(cmd) < V4L1_IOCTLS) ? v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); break; case 'V': printk("v4l2 ioctl %s, dir=%s (0x%08x)\n", (_IOC_NR(cmd) < V4L2_IOCTLS) ? v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); break; default: printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n", _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); }}EXPORT_SYMBOL(v4l_printk_ioctl);/* * sysfs stuff */static ssize_t show_name(struct device *cd, struct device_attribute *attr, char *buf){ struct video_device *vfd = container_of(cd, struct video_device, class_dev); return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name);}struct video_device *video_device_alloc(void){ struct video_device *vfd; vfd = kzalloc(sizeof(*vfd),GFP_KERNEL); return vfd;}EXPORT_SYMBOL(video_device_alloc);void video_device_release(struct video_device *vfd){ kfree(vfd);}EXPORT_SYMBOL(video_device_release);static void video_release(struct device *cd){ struct video_device *vfd = container_of(cd, struct video_device, class_dev); /* needed until all drivers are fixed */ if (!vfd->release) return; vfd->release(vfd);}static struct device_attribute video_device_attrs[] = { __ATTR(name, S_IRUGO, show_name, NULL), __ATTR_NULL};static struct class video_class = { .name = VIDEO_NAME, .dev_attrs = video_device_attrs, .dev_release = video_release,};/* * Active devices */static struct video_device *video_device[VIDEO_NUM_DEVICES];static DEFINE_MUTEX(videodev_lock);struct video_device* video_devdata(struct file *file){ return video_device[iminor(file->f_path.dentry->d_inode)];}EXPORT_SYMBOL(video_devdata);/* * Open a video device - FIXME: Obsoleted */static int video_open(struct inode *inode, struct file *file){ unsigned int minor = iminor(inode); int err = 0; struct video_device *vfl; const struct file_operations *old_fops; if(minor>=VIDEO_NUM_DEVICES) return -ENODEV; mutex_lock(&videodev_lock); vfl=video_device[minor]; if(vfl==NULL) { mutex_unlock(&videodev_lock); request_module("char-major-%d-%d", VIDEO_MAJOR, minor); mutex_lock(&videodev_lock); vfl=video_device[minor]; if (vfl==NULL) { mutex_unlock(&videodev_lock); return -ENODEV; } } old_fops = file->f_op; file->f_op = fops_get(vfl->fops); if(file->f_op->open) err = file->f_op->open(inode,file); if (err) { fops_put(file->f_op); file->f_op = fops_get(old_fops); } fops_put(old_fops); mutex_unlock(&videodev_lock); return err;}/* * helper function -- handles userspace copying for ioctl arguments */static unsigned intvideo_fix_command(unsigned int cmd){ switch (cmd) { case VIDIOC_OVERLAY_OLD: cmd = VIDIOC_OVERLAY; break; case VIDIOC_S_PARM_OLD: cmd = VIDIOC_S_PARM; break; case VIDIOC_S_CTRL_OLD: cmd = VIDIOC_S_CTRL; break; case VIDIOC_G_AUDIO_OLD: cmd = VIDIOC_G_AUDIO; break; case VIDIOC_G_AUDOUT_OLD: cmd = VIDIOC_G_AUDOUT; break; case VIDIOC_CROPCAP_OLD: cmd = VIDIOC_CROPCAP;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?