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

📄 server.c

📁 超强的嵌入式GUI系统
💻 C
字号:
/***************************************************************************    begin                : Wed Oct 8 2003    copyright            : (C) 2003 - 2007 by Alper Akcan    email                : distchx@yahoo.com ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU Lesser General Public License as        * *   published by the Free Software Foundation; either version 2.1 of the  * *   License, or (at your option) any later version.                       * *                                                                         * ***************************************************************************/#if defined(VIDEO_VESA)#include "../../../lib/xynth_.h"#include "server.h"#include "vesa.h"#include "../helper/helper.h"#include "lrmi-0.10/lrmi.h"#include "lrmi-0.10/vbe.h"#include <sys/shm.h>#include <sys/mman.h>#include <fcntl.h>#include <sys/io.h>#include <stdint.h>s_video_input_t s_video_vesa_input_keybd = {	VIDEO_INPUT_KEYBD,	s_video_vesa_kbd_init,	s_video_helper_kbd_update,	s_video_helper_kbd_uninit,};s_video_input_t s_video_vesa_input_mouse = {	VIDEO_INPUT_MOUSE,	s_video_helper_mouse_init,	s_video_helper_mouse_update,	s_video_helper_mouse_uninit,};s_video_input_t *s_video_vesa_input[] = {	&s_video_vesa_input_keybd,	&s_video_vesa_input_mouse,	NULL,};s_video_driver_t s_video_vesa = {	"vesa",	"/dev/mem",	s_video_vesa_input,	s_video_vesa_server_init,	s_video_vesa_server_uninit,	s_video_vesa_server_goto_back,	s_video_vesa_server_comefrom_back,	s_video_vesa_server_restore,	NULL,	NULL,	NULL};static int s_video_vesa_text_mode (void){	struct LRMI_regs r;	memset(&r, 0, sizeof(r));	r.eax = 3;	if (!LRMI_int(0x10, &r)) {		debugf(DSER, "Can't set text mode (vm86 failure)\n");		return -1;	}	return 0;}static int s_video_vesa_restore_state (void *buffer){	int ret = 0;	struct LRMI_regs r;	memset(&r, 0, sizeof(r));	r.eax = 0x4f04;	r.ecx = 0xf; 	/* all states */	r.edx = 2; 	/* restore state */	r.es = (unsigned int) buffer >> 4;	r.ebx = (unsigned int) buffer & 0xf;	if (!LRMI_int(0x10, &r)) {		debugf(DSER, "Can't restore video state (vm86 failure)\n");		ret = -1;	} else if ((r.eax & 0xffff) != 0x4f) {		debugf(DSER, "Restore video state failed\n");		ret = -1;	}	LRMI_free_real(buffer);	return ret;}static void * s_video_vesa_save_state (void){	void *buffer;	struct LRMI_regs r;	memset(&r, 0, sizeof(r));	r.eax = 0x4f04;	r.ecx = 0xf; 	/* all states */	r.edx = 0; 	/* get buffer size */	if (!LRMI_int(0x10, &r)) {		debugf(DSER, "Can't get video state buffer size (vm86 failure)\n");		goto err0;	}	if ((r.eax & 0xffff) != 0x4f) {		debugf(DSER, "Get video state buffer size failed\n");		goto err0;	}	buffer = LRMI_alloc_real((r.ebx & 0xffff) * 64);	if (buffer == NULL) {		debugf(DSER, "Can't allocate video state buffer\n");		goto err0;	}	memset(&r, 0, sizeof(r));	r.eax = 0x4f04;	r.ecx = 0xf; 	/* all states */	r.edx = 1; 	/* save state */	r.es = (unsigned int)buffer >> 4;	r.ebx = (unsigned int)buffer & 0xf;	if (!LRMI_int(0x10, &r)) {		debugf(DSER, "Can't save video state (vm86 failure)\n");		goto err1;	}	if ((r.eax & 0xffff) != 0x4f) {		debugf(DSER, "Save video state failed\n");		goto err1;	}	return buffer;err1:	LRMI_free_real(buffer);err0:	return NULL;}static int s_video_vesa_set_mode (int n){	int fd;	unsigned int lmembase;	struct LRMI_regs r;	s_video_vesa_data_t *priv = (s_video_vesa_data_t *) server->driver->driver_data;	priv->vbe.state = s_video_vesa_save_state();	if (priv->vbe.state == NULL) {		goto err0;	}	priv->vbe.mode_n = n;	memset(&r, 0, sizeof(r));	r.eax = 0x4f02;	r.ebx = n;	if (!LRMI_int(0x10, &r)) {		debugf(DSER, "Can't set video mode (vm86 failure)\n");		goto err0;	} else if ((r.eax & 0xffff) != 0x4f) {		debugf(DSER, "Set video mode failed\n");		goto err0;	}	memset(&r, 0, sizeof(r));	r.eax = 0x4f02;	r.ebx = n | 0x4000; /* linear mode */	if (!LRMI_int(0x10, &r)) {		debugf(DSER, "Can't set video mode (vm86 failure)\n");		goto err0;	} else if ((r.eax & 0xffff) != 0x4f) {		debugf(DSER, "Set video mode failed\n");		goto err0;	}	memset(&r, 0, sizeof(r));	r.eax = 0x4f01;	r.ecx = n;	r.es = (unsigned int) priv->vbe.mode >> 4;	r.edi = (unsigned int) priv->vbe.mode & 0xf;	if (!LRMI_int(0x10, &r)) {		debugf(DSER, "Can't get mode info (vm86 failure)\n");		goto err0;	}	if ((r.eax & 0xffff) != 0x4f) {		debugf(DSER, "Get mode info failed\n");		goto err0;	}	server->window->surface->linear_mem_base = (unsigned int) priv->vbe.mode->phys_base_ptr;	server->window->surface->linear_mem_size = (unsigned int) (priv->vbe.info->total_memory);	/* is this ok? haha this is really ugly.	 */	server->window->surface->linear_mem_size += (1024 - (priv->vbe.info->total_memory % 1024));	server->window->surface->linear_mem_size *= (64 * 1024);	fd = open("/dev/mem", O_RDWR);	if (fd < 0) {		debugf(DSER, "open failed");		goto err1;	}	if (server->window->surface->linear_mem_size) {		lmembase = (unsigned int) mmap((caddr_t) 0, server->window->surface->linear_mem_size,		                                            PROT_WRITE | PROT_READ, MAP_SHARED, fd,		                                            (off_t) server->window->surface->linear_mem_base);		if (lmembase == (unsigned int) MAP_FAILED) {			debugf(DSER, "mmap failed");			goto err1;		}	} else {		debugf(DSER, "mmap failed");			goto err1;	}	priv->vbe.addr = (char *) lmembase;	close(fd);	return 0;err1:	close(fd);err0:	return -1;}void s_video_vesa_server_restore (void){	s_video_vesa_data_t *priv = (s_video_vesa_data_t *) server->driver->driver_data;	if (server->driver->driver_data == NULL) {		return;	}	if (priv->vbe.mode_n < 0) {		return;	}	s_video_vesa_text_mode();	s_video_vesa_restore_state(priv->vbe.state);}void s_video_vesa_server_goto_back (void){	s_video_vesa_data_t *priv = (s_video_vesa_data_t *) server->driver->driver_data;	s_video_vesa_text_mode();	s_video_vesa_restore_state(priv->vbe.state);	s_server_surface_lock_real();}void s_video_vesa_server_comefrom_back (void){	s_video_vesa_data_t *priv = (s_video_vesa_data_t *) server->driver->driver_data;	s_video_vesa_set_mode(priv->vbe.mode_n);	s_server_surface_refresh();	s_video_helper_kbd_set_attr();}void s_video_vesa_surface_uninit (void){	s_video_vesa_data_t *priv = (s_video_vesa_data_t *) server->driver->driver_data;	s_video_vesa_text_mode();	s_video_vesa_restore_state(priv->vbe.state);	munmap((void *) server->window->surface->linear_mem_base, server->window->surface->linear_mem_size);	s_free(priv);	server->driver->driver_data = NULL;}void s_video_vesa_server_uninit (void){        s_video_vesa_surface_uninit();}void s_video_vesa_server_surface_setrgbpalette (void){}static void s_video_vesa_surface_init (s_video_helper_mode_info_t *gmode){	s_video_vesa_data_t *priv = (s_video_vesa_data_t *) server->driver->driver_data;        server->window->surface->width = gmode->xdim;        server->window->surface->height = gmode->ydim;        server->window->surface->bytesperpixel = gmode->bytesperpixel;        server->window->surface->bitsperpixel = priv->vbe.mode->bits_per_pixel;	server->window->surface->blueoffset = priv->vbe.mode->blue_field_position;	server->window->surface->greenoffset = priv->vbe.mode->green_field_position;	server->window->surface->redoffset = priv->vbe.mode->red_field_position;	server->window->surface->bluelength = priv->vbe.mode->blue_mask_size;	server->window->surface->greenlength = priv->vbe.mode->green_mask_size;	server->window->surface->redlength = priv->vbe.mode->red_mask_size;	server->window->surface->colors = gmode->colors;        switch (gmode->colors) {		default:		case 256:			server->window->surface->bitsperpixel = 8;			server->window->surface->blueoffset = 0;			server->window->surface->greenoffset = 3;			server->window->surface->redoffset = 6;			server->window->surface->bluelength = 3;			server->window->surface->greenlength = 3;			server->window->surface->redlength = 2;			break;		case 32768:			server->window->surface->bitsperpixel = 15;			server->window->surface->blueoffset = 0;			server->window->surface->greenoffset = 5;			server->window->surface->redoffset = 10;			server->window->surface->bluelength = 5;			server->window->surface->greenlength = 5;			server->window->surface->redlength = 5;			break;		case 65536:			server->window->surface->bitsperpixel = 16;			server->window->surface->blueoffset = 0;			server->window->surface->greenoffset = 5;			server->window->surface->redoffset = 11;			server->window->surface->bluelength = 5;			server->window->surface->greenlength = 6;			server->window->surface->redlength = 5;			break;		case 256 * 65536:			server->window->surface->bitsperpixel = server->window->surface->bytesperpixel * 8;			server->window->surface->blueoffset = 0;			server->window->surface->greenoffset = 8;			server->window->surface->redoffset = 16;			server->window->surface->bluelength = 8;			server->window->surface->greenlength = 8;			server->window->surface->redlength = 8;			break;	}	server->window->surface->vbuf = priv->vbe.addr;	server->window->surface->linear_buf = priv->vbe.addr;        server->window->surface->linear_mem_base = server->window->surface->linear_mem_base;	server->window->surface->linear_mem_size = server->window->surface->linear_mem_size;	s_video_helper_mtrr_add(server->window->surface->linear_mem_base, server->window->surface->linear_mem_size);	s_video_vesa_server_surface_setrgbpalette();}int s_video_vesa_server_init (s_server_conf_t *cfg){	struct LRMI_regs r;	short int *mode_list;	s_video_vesa_data_t *priv;	s_video_helper_mode_info_t *gmode;	priv = (s_video_vesa_data_t *) s_malloc(sizeof(s_video_vesa_data_t));	server->driver->driver_data = (void *) priv;	priv->vbe.mode_n = -1;	priv->console_fd = -1;		priv->console_fd = s_video_helper_console_init();	if (priv->console_fd < 0) {		debugf(DSER, "Unable to get console");		goto err0;	}	if (s_video_helper_mode_find(cfg, &gmode)) {		debugf(DSER, "Couldn't find mode: %s", cfg->general.mode);		goto err0;	}	if (!LRMI_init()) {		debugf(DSER, "LRMI_init() failed");		goto err0;	}	priv->vbe.info = LRMI_alloc_real(sizeof(struct vbe_info_block) +	                                 sizeof(struct vbe_mode_info_block));	if (priv->vbe.info == NULL) {		debugf(DSER, "Not enough memory!");		goto err1;	}	priv->vbe.mode = (struct vbe_mode_info_block *) (priv->vbe.info + 1);	ioperm(0, 1024, 1);	iopl(3);	memset(&r, 0, sizeof(r));	r.eax = 0x4f00;	r.es = (unsigned int) priv->vbe.info >> 4;	r.edi = 0;	memcpy(priv->vbe.info->vbe_signature, "VBE2", 4);	if (!LRMI_int(0x10, &r)) {		debugf(DSER, "Can't get VESA info (vm86 failure)");		goto err1;	}	if ((r.eax & 0xffff) != 0x4f || strncmp(priv->vbe.info->vbe_signature, "VESA", 4) != 0) {		debugf(DSER, "No VESA bios");		goto err1;	}	debugf(DSER, "VBE Version %x.%x", (int) (priv->vbe.info->vbe_version >> 8) & 0xff,	                                       (int) (priv->vbe.info->vbe_version) & 0xff);	debugf(DSER, "%s", (char *) (priv->vbe.info->oem_string_seg * 16 + priv->vbe.info->oem_string_off));	mode_list = (short int *) (priv->vbe.info->video_mode_list_seg * 16 + priv->vbe.info->video_mode_list_off);	while (*mode_list != -1) {		memset(&r, 0, sizeof(r));		r.eax = 0x4f01;		r.ecx = *mode_list;		r.es = (unsigned int) priv->vbe.mode >> 4;		r.edi = (unsigned int) priv->vbe.mode & 0xf;		if (!LRMI_int(0x10, &r)) {			debugf(DSER, "Can't get mode info (vm86 failure)");			goto err1;		}/*		if (priv->vbe.mode->memory_model == VBE_MODEL_RGB) {			debugf(DSER, "[%3d] %dx%d (%d:%d:%d)", *mode_list,			                                            priv->vbe.mode->x_resolution,			                                            priv->vbe.mode->y_resolution,			                                            priv->vbe.mode->red_mask_size,			                                            priv->vbe.mode->green_mask_size,			                                            priv->vbe.mode->blue_mask_size);		} else if (priv->vbe.mode->memory_model == VBE_MODEL_256) {			debugf(DSER, "[%3d] %dx%d (256 color palette)", *mode_list,			                                                     priv->vbe.mode->x_resolution,			                                                     priv->vbe.mode->y_resolution);		} else if (priv->vbe.mode->memory_model == VBE_MODEL_PACKED) {			debugf(DSER, "[%3d] %dx%d (%d color palette)", *mode_list,			                                                    priv->vbe.mode->x_resolution,			                                                    priv->vbe.mode->y_resolution,			                                                    1 << priv->vbe.mode->bits_per_pixel);                }*/                if ((priv->vbe.mode->x_resolution == gmode->xdim) &&                    (priv->vbe.mode->y_resolution == gmode->ydim) &&                    ((1 << ((priv->vbe.mode->bits_per_pixel == 32) ? 24 : priv->vbe.mode->bits_per_pixel)) == gmode->colors)) {			s_video_vesa_set_mode(*mode_list);			s_video_vesa_surface_init(gmode);			return gmode->number;		}		mode_list++;	}err1:	LRMI_free_real(priv->vbe.info);	debugf(DSER, "Mode %s cannot be found", cfg->general.mode);err0:	s_free(priv);	server->driver->driver_data = NULL;	return -1;}#endif /* VIDEO_VESA */

⌨️ 快捷键说明

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