Example #1
0
//打开新的console的函数
LAYER *open_console(LAYER_MANAGE *layer_manage, unsigned int memory_total)
{
	MEMMANAGE *memmanage = (MEMMANAGE *)MEMMANAGE_ADDR;
	LAYER *layer_console = layer_alloc(layer_manage);
	unsigned char *buf_console = (unsigned char *)memmanage_alloc_4K(memmanage, 256 * 165);	
	TASK *task_console = task_alloc();
	int *console_fifo = (int *)memmanage_alloc_4K(memmanage, 128 * 4);
	layer_set(layer_console, buf_console, 256, 165, -1);
	create_window(buf_console, 256, 165, "console", INACTIVE);
	create_textbox(layer_console, 8, 28, 240, 128, COL8_000000);
	task_console->console_stack = memmanage_alloc_4K(memmanage, 64 * 1024) + 64 * 1024 - 12;			//由于这里要传入两个参数,所以减去了12
	task_console->tss.esp = task_console->console_stack;
	task_console->tss.eip = (int) &console_task;			//eip指向的是运行console的函数首地址
	task_console->tss.es = 1 * 8;
	task_console->tss.cs = 2 * 8;
	task_console->tss.ss = 1 * 8;
	task_console->tss.ds = 1 * 8;
	task_console->tss.fs = 1 * 8;
	task_console->tss.gs = 1 * 8;
	*((int *) (task_console->tss.esp + 4)) = (int) layer_console;
	*((int *) (task_console->tss.esp + 8)) = memory_total;	
	task_run(task_console, 2, 2); 			/* level=2, priority=2 */
	layer_console->task = task_console;
	layer_console->flags |= 0x20;			//flags的0x20代表当前窗口的光标ON
	init_fifo(&task_console->fifo, 128, console_fifo, task_console);
	return layer_console;
}
Example #2
0
//打开新的console的函数
LAYER *open_console(LAYER_MANAGE *layer_manage, unsigned int memory_total)
{
	MEMMANAGE *memmanage = (MEMMANAGE *)MEMMANAGE_ADDR;
	LAYER *layer_console = layer_alloc(layer_manage);
	unsigned char *buf_console = (unsigned char *)memmanage_alloc_4K(memmanage, 256 * 165);	
	layer_set(layer_console, buf_console, 256, 165, -1);
	create_window(buf_console, 256, 165, "console", INACTIVE);
	create_textbox(layer_console, 8, 28, 240, 128, COL8_000000);
	layer_console->task = open_console_task(layer_console, memory_total);
	layer_console->flags |= 0x20;			//flags的0x20代表当前窗口的光标ON
	return layer_console;
}
Example #3
0
Chatbox create_chatbox(SDL_Renderer *s, TTF_Font *font, unsigned x, unsigned y, int length)
{
    int i;

    Chatbox b = malloc(sizeof(struct chatbox));
    b->first = b->upper = b->last = -1;
    b->length = length;
    b->output = create_textbox(s, font, x, y);

    b->fontsize = FONT_PIXELSIZE * vstretch;

    for (i = 0; i < MAXLINES; i++)
        b->lines[i] = 0;

    return b;
}
Example #4
0
void Client::set_key(MappedKey::Device dev, int param) {
    set_key(dev, param, binding.left, PlayerKeyStateLeft);
    set_key(dev, param, binding.right, PlayerKeyStateRight);
    set_key(dev, param, binding.up, PlayerKeyStateUp);
    set_key(dev, param, binding.down, PlayerKeyStateDown);
    set_key(dev, param, binding.jump, PlayerKeyStateJump);
    set_key(dev, param, binding.fire, PlayerKeyStateFire);
    set_key(dev, param, binding.drop1, PlayerKeyStateDrop1);
    set_key(dev, param, binding.drop2, PlayerKeyStateDrop2);
    set_key(dev, param, binding.drop3, PlayerKeyStateDrop3);

    if (binding.chat.device == dev && binding.chat.param == param) {
        if (!get_stack_count()) {
            subsystem.clear_input_buffer();
            int vw = subsystem.get_view_width();
            int vh = subsystem.get_view_height();
            int ww = 350;
            int wh = 30;
            GuiWindow *window = push_window(1, 1, ww, wh, "Enter Message");
            window->set_on_keydown(static_window_keydown, this);
            window->set_on_joybuttondown(static_window_joybutton_down, this);
            ww = window->get_client_width();
            chat_textbox = create_textbox(window, Spc, Spc, ww - 2 * Spc, "");
            window->set_height(window->get_height() - window->get_client_height() + 2 * Spc + chat_textbox->get_height());
            window->set_x(vw / 2 - window->get_client_width() / 2);
            window->set_y(vh / 2 - window->get_client_height() / 2);
            chat_textbox->set_focus();
            if (me) {
                me->state.client_server_state.key_states = 0;
            }
        }
    }

    if (binding.stats.device == dev && binding.stats.param == param) {
        if (!get_stack_count()) {
            if (tournament) {
                tournament->show_stats(true);
            }
        }
    }

    if (binding.escape.device == dev && binding.escape.param == param) {
        show_options_menu();
    }
}
Example #5
0
int main(int argc, char **argv)
{
    int i, c, *w, down;
    gamestr g;
    player players[5];
    char names[5 * 9], *p;
    int belts[5];
    g.villain = players;

    SDL_Renderer *screen;
    SDL_Event event;
    Tbox t;
    Chatbox out;

    if (argc == 3)
        screen = init_sdl(atoi(argv[1]), atoi(argv[2]), 0, FONT);
    else if (argc == 2)
        screen = init_sdl(W, H, argv[1], FONT);
    else
        screen = init_sdl(W, H, 0, FONT);

    for (i = 0; i < 5; i++) {
        sprintf(&names[9 * i], "Player %1d", i + 1);
        g.villain[i].name = &names[9 * i];
        g.villain[i].water_level = i;
        g.villain[i].points = i;
        g.villain[i].lifebelts = i;
        g.villain[i].played = i + 1;
        g.villain[i].dead = i == 4 ? 1 : 0;
        belts[i] = 6;
    }

    belts[0] = 10;

    for (i = 0; i < 12; i++)
        g.player.weathercards[i] = i + 1;

    g.w_card[0] = 5;
    g.w_card[1] = 12;

    t = create_textbox(screen, getfont(), 36, 532);
    out = create_chatbox(screen, getfont(), 36, 410, 10);

    g.count = 5;

    render(screen, &g, 0, belts);
    textbox_set(t, strdup(""));
    chatbox_append(out, strdup("foobar"));
    chatbox_append(out, strdup("baaz"));
    chatbox_append(out, strdup("quux"));
    chatbox_render(out);
    SDL_RenderPresent(screen);

    down = 0;
    for (i = 9; i; i--) {
        do {
            SDL_WaitEvent(&event);
            c = SDL_GetModState();

            if (event.type == SDL_QUIT)
                exit(0);
            if (event.type == SDL_KEYUP || event.type == SDL_MOUSEBUTTONUP)
                belts[0] = 0;
            if (event.type == SDL_KEYDOWN)
                down = 1;
        } while (belts[0]);
        belts[0] = 10;

        if (down && event.type == SDL_KEYUP) {
            if ((p = handle_keypress(event.key.keysym.sym, c, t, out))) {
                chatbox_append(out, p);
            }
#if 0
            if ((c = getprintkey(event.key.keysym.sym, SDL_GetModState()))) {
                /* append to message */
                p = malloc(strlen(textbox_get(t)) + 2);
                sprintf(p, "%s%c", textbox_get(t), c);

                /* fprintf(stderr, "text is now %s\n", p); */

                free(textbox_get(t));
                textbox_set(t, p);
            }

            switch(event.key.keysym.sym) {
            case SDLK_q:
                exit(0);
            case SDLK_PAGEUP:
                chatbox_scrollup(out);
                break;
            case SDLK_PAGEDOWN:
                chatbox_scrolldown(out);
                break;
            case SDLK_RETURN:
                chatbox_append(out, textbox_get(t));
                textbox_set(t, strdup(""));
                break;
            default:
                break;
            }
#endif /* 0 */
        } else if (event.type == SDL_MOUSEBUTTONUP) {
            w = g.player.weathercards;

            c = card_select(event.button.x, event.button.y, w);

            if (c != -1) {
                g.villain[0].played = w[c];
                w[c] = 0;
            }
        }

    	g.villain[0].lifebelts = i;
        if (i == 1) i = 2;

        render(screen, &g, 0, belts);
        textbox_update(t);
        chatbox_render(out);
        game_over(screen, &g, 0, 0, 0);

        SDL_RenderPresent(screen);
    }

    return 0;
}
Example #6
0
void HariMain(void)
{
	/*
	**最初的这部分变量没有通过内存管理来分配,它们本身属于操作系统的一部分,存在于bootpack.hrb所在的那块儿内存空间中
	*/
	BOOTINFO *binfo = (BOOTINFO *) ADR_BOOTINFO;
	MOUSE_DECODE mouse_dec;
	MEMMANAGE *memmanage = (MEMMANAGE *)MEMMANAGE_ADDR;
	LAYER_MANAGE *layer_manage;
	LAYER *layer_bg, *layer_mouse, *layer_window;
	TIMER *timer1, *timer2, *timer3;
	FIFO fifo_mutual;									//缓冲区管理,所有中断公用的
	TSS tss_a, tss_b;									//用于切换的两个任务
	int fifobuf[128];									//缓冲区
	int cursor_x = 8, cursor_color = COL8_FFFFFF;		//分别代表输入字符后的那个闪烁光标的横坐标和颜色
	int mCursorX, mCursorY;				//鼠标光标显示位置的横纵坐标
	int task_b_esp;
	unsigned int memory_total, i;
	char buf_cursor[mCursorWidth * mCursorHeight];
	unsigned char *buf_bg, *buf_window;			//屏幕的大背景会在init_screen的时候画出来,这里只需要一个指向它的指针即可
	unsigned char strings[40];
	mCursorX = binfo->scrnx / 2;			
	mCursorY = (binfo->scrny - 28)/ 2;		//减去下方任务栏的高度
	
	
	/*内存检查*/
	i = memtest(0x00400000, 0xbfffffff) / (1024 * 1024);		//i的单位是MB
	
	/*内存管理*/
	memmanage_init(memmanage);
	memory_total = i * 1024 * 1024;
	memmanage_free_4K(memmanage, 0x00001000, 0x0009e000);
	memmanage_free_4K(memmanage, 0x00400000, memory_total - 0x00400000);
	
	/*初始化接收中断的缓冲区*/
	init_fifo(&fifo_mutual, 128, fifobuf);		//初始化mouseFIFO缓冲区
	/*初始化GDT和IDT表以及PIC板的数据*/
	init_GDTandIDT();				//初始化GDT和IDT表
	init_pic();						//初始化PIC主从板数据,除了IRQ2禁止了全部中断
	io_sti();						//开始接收中断
	/*初始化PIT中断控制*/
	init_PIT();
		/*若要接收鼠标中断需要两个步骤,首先必须使鼠标控制电路(就是键盘控制电路的一部分)有效,然后要使鼠标本身有效*/
	init_keyboard(&fifo_mutual, 256);						//初始化键盘控制器电路
	enable_mouse(&fifo_mutual, 512, &mouse_dec);				//激活鼠标
	/*开放各种中断*/
	io_out8(PIC0_IMR, 0xf8);				//PIC0开发IRQ(11111000),开放IRQ0、IRQ1和IRQ2,定时器、键盘中断和从PIC板
	io_out8(PIC1_IMR, 0xef); 				//PIC1开放IRQ(11101111), 开放鼠标中断
	/*初始化调色板,为图形界面做准备*/
	init_palette();					//初始化调色板
	/*初始化图层管理,并且初始化鼠标光标和背景的图层*/
	layer_manage = layer_man_init(memmanage, binfo->vram, binfo->scrnx, binfo->scrny);
	
	layer_bg = layer_alloc(layer_manage);			//为背景分配图层
	layer_mouse = layer_alloc(layer_manage);		//为鼠标分配图层
	layer_window = layer_alloc(layer_manage);		//为窗口分配图层
	
	buf_bg = (unsigned char *)memmanage_alloc_4K(memmanage, binfo->scrnx * binfo->scrny);		//为背景图形的内容分配内存
	buf_window = (unsigned char *)memmanage_alloc_4K(memmanage, 160 * 52);						//为窗口图形的内容分配内存
	/*为各个图形的图层内容进行设定*/
	layer_set(layer_bg, buf_bg, binfo->scrnx, binfo->scrny, -1);			
	layer_set(layer_mouse, buf_cursor, 16, 16 ,99);
	layer_set(layer_window, buf_window, 160, 52, -1);
	/*初始化整个桌面背景*/
	init_screen(buf_bg, binfo->scrnx, binfo->scrny);				//这个时候的init_screen不再是直接画出背景,而是在mBg内存地址中填写好背景内容
	layer_slide(layer_bg, 0, 0);					//把背景图层从(0,0)坐标开始画
	/*初始化鼠标图标*/
	init_mouse_cursor(buf_cursor, 99);								//初始化鼠标光标
	layer_slide(layer_mouse, mCursorX, mCursorY);	//现在显示图形不需要再用displayShape函数了,直接用这个图层管理的绘图函数就行
	/*初始化窗口*/
	create_window(buf_window, 160, 52, "window");					//制作窗口
	layer_slide(layer_window, 80, 72);								//在指定位置显示出窗口
	create_textbox(layer_window, 8, 28, 144, 16, COL8_FFFFFF);		//在这个窗口中创建一个输入框
	/*设置好各个图层的高度*/
	layer_switch(layer_bg, 0);						//把背景图层调为最底层,高度为0
	layer_switch(layer_window, 1);					//窗口图层调节为第二层,高度为1
	layer_switch(layer_mouse, 2);					//鼠标图层调为最高层,高度为2
	/*定时器的初始化及其设置*/
	timer1 = timer_alloc();
	timer_init(timer1, &fifo_mutual, 10);
	timer_set(timer1, 1000);
	
	timer2 = timer_alloc();
	timer_init(timer2, &fifo_mutual, 3);
	timer_set(timer2, 300);
	
	timer3 = timer_alloc();
	timer_init(timer3, &fifo_mutual, 1);
	timer_set(timer3, 50);
	/*在屏幕上显示一些内存、鼠标和键盘等信息*/
	sprintf(strings, "Memory has %dMB", i);
	displayStrings_CS(buf_bg, binfo->scrnx, 0, 48, COL8_FFFFFF,strings);
	layer_refresh(layer_bg, 0, 48, binfo->scrnx, 80);
	sprintf(strings, "free memory:%dKB",memmanage_total(memmanage) / 1024);
	displayStrings_CS(buf_bg, binfo->scrnx, 120, 48, COL8_FFFFFF,strings);			//用字体显示当前内存容量
	layer_refresh(layer_bg, 120, 48, binfo->scrnx, 80);
	
	/*任务切换*/
	SEGMENT_DESCRIPTOR *gdt = (SEGMENT_DESCRIPTOR *)ADR_GDT;
	tss_a.ldtr = 0;
	tss_a.iomap = 0x40000000;
	tss_b.ldtr = 0;
	tss_b.iomap = 0x40000000;
	
	set_segmdesc(gdt + 3, 103, (int) &tss_a, AR_TSS32);			//任务a在第三个段中运行,段限是103字节
	set_segmdesc(gdt + 4, 103, (int) &tss_b, AR_TSS32);
	
	load_tr(3 * 8);				//代表当前在运行第三个段中的程序
	task_b_esp = memmanage_alloc_4K(memmanage, 64 * 1024) + 64 * 1024;
	tss_b.eip = (int) &task_b_main;
	tss_b.eflags = 0x00000202; /* IF = 1; */
	tss_b.eax = 0;
	tss_b.ecx = 0;
	tss_b.edx = 0;
	tss_b.ebx = 0;
	tss_b.esp = task_b_esp;
	tss_b.ebp = 0;
	tss_b.esi = 0;
	tss_b.edi = 0;
	tss_b.es = 1 * 8;
	tss_b.cs = 2 * 8;
	tss_b.ss = 1 * 8;
	tss_b.ds = 1 * 8;
	tss_b.fs = 1 * 8;
	tss_b.gs = 1 * 8;
	
	for(;;)
	{
		/*只有在从中断返回的缓冲区中读取数据的时候才需要禁止中断,因为如果这个时候来了中断而没有禁止的话,
		**有可能读脏数据,即把还没有读出的数据的给抹掉或换成别的数据
		*/
		io_cli();		
		if(0 == fifo_status(&fifo_mutual))		//当前没有中断产生
		{
			io_stihlt();			//当CPU执行hlt指令之后只有外部中断等之情况才会再次唤醒CPU继续工作
		}
		else
		{
			i = fifo_get(&fifo_mutual);
			io_sti();
			if((keyboard_offset <= i) && (i <= keyboard_offset + 255))			//键盘数据
			{
				sprintf(strings, "%2X", i - keyboard_offset);
				displayStrings_atLayer(layer_bg, 0, 0, COL8_FFFFFF, COL8_008484, strings);					//由于向背景图层中添加了新东西,需要重绘各个图层
				if(i < keyboard_offset + 0x54)				//判断按下的字符是否可打印
				{
					if(0 != key_table[i - keyboard_offset] && cursor_x < 144)			//0对应的字符无法打印出来
					{
						strings[0] = key_table[i - keyboard_offset];
						strings[1] = 0;
						displayStrings_atLayer(layer_window, cursor_x, 28, COL8_000000, COL8_FFFFFF, strings);
						cursor_x += 8;			//光标的位置随着每一个字符的输入向后移动一个字符宽度的位置即8像素
					}
					if((keyboard_offset + 0x0e == i) && cursor_x > 8)				//按下了退格键的情况,退格键的号码是0x0e
					{
						cursor_x -= 8;
						/*本来退格键应该只填充一个空格就行的,但是这样的话没办法刷新光标所在的那块儿区域了,
						**会留下光标的黑色痕迹,所以直接填充两个空格,刷新之后就不会有痕迹了
						*/
						displayStrings_atLayer(layer_window, cursor_x, 28, COL8_000000, COL8_FFFFFF, "  ");
					}
					//由于光标坐标后退了,为了及时显示它,需要立即重绘光标
					drawRectangle(layer_window->buffer, layer_window->length, cursor_color, cursor_x, 28, 2, 15);
					layer_refresh(layer_window, cursor_x, 28, cursor_x + 8, 44);
				}
			}
			else if((mouse_offset <= i) && (i <= mouse_offset + 255))		//鼠标数据
			{
				if(0 != mouse_decode(&mouse_dec, i - mouse_offset))		//只有返回值为1的时候才说明成功接收完成一次鼠标的中断
				{
				/*显示鼠标的信息*/
					sprintf(strings,"[lcr %3d,%3d]",mouse_dec.x, mouse_dec.y);
					if(0 != (mouse_dec.btn & 0x01))		//按下了左键
					{
						strings[1] = 'L';
						//layer_slide(layer_window, mCursorX - 80, mCursorY -8);		//这行代码是移动窗口的
					}
					if(0 != (mouse_dec.btn & 0x02))		//按下了右键
					{
						strings[3] = 'R';
					}
					if(0 != (mouse_dec.btn & 0x04))		//按下了中键
					{
						strings[2] = 'C';
					}
					displayStrings_atLayer(layer_bg, 0, 16, COL8_FFFFFF, COL8_008484, strings);	
					/*鼠标的移动*/
					//根据mouse_dec里存储的鼠标信息画出新的鼠标图像
					mCursorX += mouse_dec.x;
					mCursorY += mouse_dec.y;
					//不能让鼠标移出画面
					if(mCursorX < 0)
					{
						mCursorX = 0;
					}
					if(mCursorY < 0)
					{
						mCursorY = 0;
					}
					if(mCursorX > binfo->scrnx - 1)
					{
						mCursorX = binfo->scrnx - 1;
					}
					if(mCursorY > binfo->scrny - 1)
					{
						mCursorY = binfo->scrny - 1;
					}
					sprintf(strings, "(%3d,%3d)", mCursorX, mCursorY);
					displayStrings_atLayer(layer_bg, 40, 32, COL8_FFFFFF, COL8_008484, strings);
					layer_slide(layer_mouse, mCursorX, mCursorY);
				}
			}
			else if(10 == i)						//10秒定时器
			{	
				displayStrings_atLayer(layer_bg, 0, 64, COL8_FFFFFF, COL8_008484, "10[sec]");
				taskswitch4();		//执行任务切换
			}
			else if(3 == i)							//3秒定时器
			{
				displayStrings_atLayer(layer_bg, 0, 80, COL8_FFFFFF, COL8_008484, "3[sec]");
			}
			else if(1 == i || 0 == i)				//光标闪烁定时器
			{
				if(0 != i)				//这个timer的数据为1的时候显示光标
				{
					timer_init(timer3, &fifo_mutual, 0);
					cursor_color = COL8_000000;
				}
				else					//这个timer的数据为0的时候不显示光标
				{
					timer_init(timer3, &fifo_mutual, 1);
					cursor_color = COL8_FFFFFF;
				}
				timer_set(timer3, 50);
				drawRectangle(layer_window->buffer, layer_window->length, cursor_color, cursor_x, 28, 2, 15);
				layer_refresh(layer_window, cursor_x, 28, cursor_x + 8, 44);
			}
		}
	}	
}
Example #7
0
void HariMain(void)
{
	/*
	**最初的这部分变量没有通过内存管理来分配,它们本身属于操作系统的一部分,存在于bootpack.hrb所在的那块儿内存空间中
	*/
	BOOTINFO *binfo = (BOOTINFO *) ADR_BOOTINFO;
	MOUSE_DECODE mouse_dec;
	MEMMANAGE *memmanage = (MEMMANAGE *)MEMMANAGE_ADDR;
	LAYER_MANAGE *layer_manage;
	LAYER *layer_bg, *layer_mouse, *layer_window, *layer_console;
	TIMER *timer;
	FIFO fifo_mutual;									//缓冲区管理,所有中断公用的
	FIFO keycmd_fifo;									
	TASK *task_a, *task_console;
	int fifobuf[128];									//缓冲区
	int keycmd_buf[32];
	int cursor_x = 8, cursor_color = COL8_FFFFFF;		//分别代表输入字符后的那个闪烁光标的横坐标和颜色
	int mCursorX, mCursorY;				//鼠标光标显示位置的横纵坐标
	int key_to = 0, key_shift = 0, key_leds = (binfo->leds >> 4) & 7, keycmd_wait = -1;			//标志键盘输入到哪个窗口中
	unsigned int memory_total, i;
	char buf_cursor[mCursorWidth * mCursorHeight];
	unsigned char *buf_bg, *buf_window, *buf_console;			//屏幕的大背景会在init_screen的时候画出来,这里只需要一个指向它的指针即可
	unsigned char strings[40];
	mCursorX = binfo->scrnx / 2;			
	mCursorY = (binfo->scrny - 28)/ 2;		//减去下方任务栏的高度
	
	
	/*内存检查*/
	i = memtest(0x00400000, 0xbfffffff) / (1024 * 1024);		//i的单位是MB
	
	/*内存管理*/
	memmanage_init(memmanage);
	memory_total = i * 1024 * 1024;
	memmanage_free_4K(memmanage, 0x00001000, 0x0009e000);
	memmanage_free_4K(memmanage, 0x00400000, memory_total - 0x00400000);
	
	init_fifo(&keycmd_fifo, 32, keycmd_buf, 0);
	/*初始化接收中断的缓冲区*/
	init_fifo(&fifo_mutual, 128, fifobuf, 0);		//初始化mouseFIFO缓冲区,现在还没任务,先指定为0
	/*初始化GDT和IDT表以及PIC板的数据*/
	init_GDTandIDT();				//初始化GDT和IDT表
	init_pic();						//初始化PIC主从板数据,除了IRQ2禁止了全部中断
	io_sti();						//开始接收中断
	/*初始化PIT中断控制*/
	init_PIT();
		/*若要接收鼠标中断需要两个步骤,首先必须使鼠标控制电路(就是键盘控制电路的一部分)有效,然后要使鼠标本身有效*/
	init_keyboard(&fifo_mutual, 256);						//初始化键盘控制器电路
	enable_mouse(&fifo_mutual, 512, &mouse_dec);				//激活鼠标
	/*开放各种中断*/
	io_out8(PIC0_IMR, 0xf8);				//PIC0开发IRQ(11111000),开放IRQ0、IRQ1和IRQ2,定时器、键盘中断和从PIC板
	io_out8(PIC1_IMR, 0xef); 				//PIC1开放IRQ(11101111), 开放鼠标中断
	/*初始化任务切换管理*/
	task_a = task_init(memmanage);		//这个task_a其实代表的就是这些鼠标键盘等的任务
	fifo_mutual.task = task_a;						//为鼠标键盘等的缓冲区指定唤醒任务为task_a
	task_run(task_a, 1, 2);
	/*初始化调色板,为图形界面做准备*/
	init_palette();					//初始化调色板
	/*初始化图层管理,并且初始化鼠标光标和背景的图层*/
	layer_manage = layer_man_init(memmanage, binfo->vram, binfo->scrnx, binfo->scrny);
	
	layer_bg = layer_alloc(layer_manage);			//为背景分配图层
	layer_mouse = layer_alloc(layer_manage);		//为鼠标分配图层
	layer_window = layer_alloc(layer_manage);		//为窗口分配图层
	
	buf_bg = (unsigned char *)memmanage_alloc_4K(memmanage, binfo->scrnx * binfo->scrny);		//为背景图形的内容分配内存
	buf_window = (unsigned char *)memmanage_alloc_4K(memmanage, 160 * 52);						//为窗口图形的内容分配内存
	/*为各个图形的图层内容进行设定*/
	layer_set(layer_bg, buf_bg, binfo->scrnx, binfo->scrny, -1);			
	layer_set(layer_mouse, buf_cursor, 16, 16 ,99);
	layer_set(layer_window, buf_window, 160, 52, -1);
	/*初始化整个桌面背景*/
	init_screen(buf_bg, binfo->scrnx, binfo->scrny);				//这个时候的init_screen不再是直接画出背景,而是在mBg内存地址中填写好背景内容
	layer_slide(layer_bg, 0, 0);					//把背景图层从(0,0)坐标开始画
	/*初始化鼠标图标*/
	init_mouse_cursor(buf_cursor, 99);								//初始化鼠标光标
	layer_slide(layer_mouse, mCursorX, mCursorY);	//现在显示图形不需要再用displayShape函数了,直接用这个图层管理的绘图函数就行
	/*初始化窗口*/
	create_window(buf_window, 160, 52, "task_a", ACTIVE);					//制作窗口
	layer_slide(layer_window, 80, 100);								//在指定位置显示出窗口
	create_textbox(layer_window, 8, 28, 144, 16, COL8_FFFFFF);		//在这个窗口中创建一个输入框
	/*执行一个命令行窗口任务*/
	layer_console = layer_alloc(layer_manage);
	buf_console = (unsigned char *)memmanage_alloc_4K(memmanage, 256 * 165);	
	layer_set(layer_console, buf_console, 256, 165, -1);
	create_window(buf_console, 256, 165, "console", INACTIVE);
	create_textbox(layer_console, 8, 28, 240, 128, COL8_000000);
	task_console = task_alloc();
	task_console->tss.esp = memmanage_alloc_4K(memmanage, 64 * 1024) + 64 * 1024 - 8;
	task_console->tss.eip = (int) &console_task;
	task_console->tss.es = 1 * 8;
	task_console->tss.cs = 2 * 8;
	task_console->tss.ss = 1 * 8;
	task_console->tss.ds = 1 * 8;
	task_console->tss.fs = 1 * 8;
	task_console->tss.gs = 1 * 8;
	*((int *) (task_console->tss.esp + 4)) = (int) layer_console;
	task_run(task_console, 2, 2); /* level=2, priority=2 */
	
	
	layer_slide(layer_console, 32, 60);
	/*设置好各个图层的高度*/
	layer_switch(layer_bg, 0);						//把背景图层调为最底层,高度为0
	layer_switch(layer_console, 1);					//命令行窗口图层调节为第三层,高度为2
	layer_switch(layer_window, 2);					//窗口图层调节为第二层,高度为1
	layer_switch(layer_mouse, 3);					//鼠标图层调为最高层,高度为3
	/*定时器的初始化及其设置*/
	timer = timer_alloc();
	timer_init(timer, &fifo_mutual, 1);
	timer_set(timer, 50);
	/*在屏幕上显示一些内存、鼠标和键盘等信息*/
	sprintf(strings, "Memory has %dMB", i);
	displayStrings_CS(buf_bg, binfo->scrnx, 0, 48, COL8_FFFFFF,strings);
	layer_part_refresh(layer_bg, 0, 48, binfo->scrnx, 80);
	sprintf(strings, "free memory:%dKB",memmanage_total(memmanage) / 1024);
	displayStrings_CS(buf_bg, binfo->scrnx, 120, 48, COL8_FFFFFF,strings);			//用字体显示当前内存容量
	layer_part_refresh(layer_bg, 120, 48, binfo->scrnx, 80);
	
	
	//
	fifo_put(&keycmd_fifo, KEYCMD_LED);
	fifo_put(&keycmd_fifo, key_leds);
	
	for(;;)
	{ 
		if(fifo_status(&keycmd_fifo) > 0 && keycmd_wait < 0)
		{
			keycmd_wait = fifo_get(&keycmd_fifo);
			wait_KBC_sendready();
			io_out8(PORT_KEYDATA, keycmd_wait);
		}
		/*只有在从中断返回的缓冲区中读取数据的时候才需要禁止中断,因为如果这个时候来了中断而没有禁止的话,
		**有可能读脏数据,即把还没有读出的数据的给抹掉或换成别的数据
		*/
		io_cli();		
		if(0 == fifo_status(&fifo_mutual))		//当前没有中断产生
		{
			task_sleep(task_a);	//如果没有需要处理的数据,就自己让自己休眠
			/*上面的那个函数直接就跳转到另一个任务中去了,不过,因为每个人物的默认eflags都是开启中断的,
			**所以不用担心,这个任务还是能被唤醒的,耳环醒后的第一个动作就是为了以防万一先开启中断
			*/
			io_sti();		//万一只有自己在运行的话,则无法睡眠,那么就执行hlt指令好了,这样省电嘛	
		}
		else
		{
			i = fifo_get(&fifo_mutual);
			io_sti();
			//如果是键盘中断的话,需要处理键盘发送来的中断数据
			if((keyboard_offset <= i) && (i <= keyboard_offset + 255))			
			{
				sprintf(strings, "%2X", i - keyboard_offset);
				displayStrings_atLayer(layer_bg, 0, 0, COL8_FFFFFF, COL8_008484, strings);					//由于向背景图层中添加了新东西,需要重绘各个图层
				//判断shift键是否按下
				if(i < 0x80 + keyboard_offset)
				{
					if(0 == key_shift)
					{
						strings[0] = key_table[i - keyboard_offset];
					}
					else
					{
						strings[0] = key_table_shift[i - keyboard_offset];
					}
				}
				else
				{
					strings[0] = 0;
				}
				//判断Caps和Shift键的情况以确定输入大写还是小写字母
				if('A' <= strings[0] && strings[0] <= 'Z')
				{
					//小写字母的情况
					if((0 == (key_leds & 4) && 0 == key_shift) || (0 != (key_leds & 4) && 0 != key_shift))
					{
						strings[0] += 0x20;
					}
				}
				//判断按下的字符是否为一般字符,0对应的字符不处理
				if(strings[0] != 0)				
				{
					//发送给task_a任务的窗口
					if(0 == key_to)
					{
						//所有可打印的字符都需要打印出来
						if(cursor_x < 144)
						{
							strings[1] = 0;
							displayStrings_atLayer(layer_window, cursor_x, 28, COL8_000000, COL8_FFFFFF, strings);
							cursor_x += 8;			//光标的位置随着每一个字符的输入向后移动一个字符宽度的位置即8像素
						}
					}
					//发送给命令行窗口
					else
					{
						fifo_put(&task_console->fifo, strings[0] + 256);
					}
				}
				/*这些都是那些不能打印的特殊按键,它们对应的都是0*/
				//按下了退格键的情况,退格键的号码是0x0e
				if((keyboard_offset + 0x0e == i))				
				{
					if(0 == key_to)
					{
						//只有当前的输入位置上有字符了才能向前删除
						if(cursor_x > 8)
						{
							cursor_x -= 8;
							/*本来退格键应该只填充一个空格就行的,但是这样的话没办法刷新光标所在的那块儿区域了,
							**会留下光标的黑色痕迹,所以直接填充两个空格,刷新之后就不会有痕迹了
							*/
							displayStrings_atLayer(layer_window, cursor_x, 28, COL8_000000, COL8_FFFFFF, "  ");
						}
					}
					else
					{
						fifo_put(&task_console->fifo, 8 + keyboard_offset);
					}
				}
				//按下TAB键的处理情况,切换输入窗口
				if(keyboard_offset + 0x0f == i)					
				{
					if(0 == key_to)			//当前最前面窗口为task_a,则让console窗口成为最前端窗口
					{
						key_to = 1;
						create_titlebar(buf_window, layer_window->length, "task_a", INACTIVE);
						create_titlebar(buf_console, layer_console->length, "console", ACTIVE);
					}
					else					//task_a任务的窗口成为最前端窗口
					{
						key_to = 0;
						create_titlebar(buf_window, layer_window->length, "task_a", ACTIVE);
						create_titlebar(buf_console, layer_console->length, "console", INACTIVE);
					}
					layer_part_refresh(layer_window, 0, 0, layer_window->length, 21);
					layer_part_refresh(layer_console, 0, 0, layer_console->length, 21);
				}
				//左shift ON
				if(0x2a + keyboard_offset == i)
				{
					key_shift |= 1;
				}
				//右shift ON
				if(0x36 + keyboard_offset == i)
				{
					key_shift |= 2;
				}
				//左shift OFF
				if(0xaa + keyboard_offset == i)
				{
					key_shift &= ~1;
				}
				//左shift OFF
				if(0xb6 + keyboard_offset == i)
				{
					key_shift &= ~2;
				}
				//由于光标坐标后退了,为了及时显示它,需要立即重绘光标
				drawRectangle(layer_window->buffer, layer_window->length, cursor_color, cursor_x, 28, 2, 15);
				layer_part_refresh(layer_window, cursor_x, 28, cursor_x + 8, 44);
				/*对各种锁定键的处理*/
				//CapsLock键
				if(i == keyboard_offset + 0x3a)
				{
					key_leds ^= 4;
					fifo_put(&keycmd_fifo, KEYCMD_LED);
					fifo_put(&keycmd_fifo, key_leds);
				}
				//NumLock键
				if(i == keyboard_offset + 0x45)
				{
					key_leds ^= 2;
					fifo_put(&keycmd_fifo, KEYCMD_LED);
					fifo_put(&keycmd_fifo, key_leds);
				}
				//ScrollLock键
				if(i == keyboard_offset + 0x46)
				{
					key_leds ^= 1;
					fifo_put(&keycmd_fifo, KEYCMD_LED);
					fifo_put(&keycmd_fifo, key_leds);
				}
				//键盘成功接收到数据
				if(i == keyboard_offset + 0xfa)
				{
					keycmd_wait = -1;
				}
				//键盘没有成功接收到数据
				if(i == keyboard_offset + 0xfe)
				{
					wait_KBC_sendready();
					io_out8(PORT_KEYDATA, keycmd_wait);
				}
			}
			//如果是鼠标中断的话,需要处理鼠标发送来的中断数据
			else if((mouse_offset <= i) && (i <= mouse_offset + 255))		
			{
				if(0 != mouse_decode(&mouse_dec, i - mouse_offset))		//只有返回值为1的时候才说明成功接收完成一次鼠标的中断
				{
				/*显示鼠标的信息*/
					sprintf(strings,"[lcr %3d,%3d]",mouse_dec.x, mouse_dec.y);
					if(0 != (mouse_dec.btn & 0x01))		//按下了左键
					{
						strings[1] = 'L';
						layer_slide(layer_window, mCursorX - 80, mCursorY -8);		//这行代码是移动窗口的
					}
					if(0 != (mouse_dec.btn & 0x02))		//按下了右键
					{
						strings[3] = 'R';
					}
					if(0 != (mouse_dec.btn & 0x04))		//按下了中键
					{
						strings[2] = 'C';
					}
					displayStrings_atLayer(layer_bg, 0, 16, COL8_FFFFFF, COL8_008484, strings);	
					/*鼠标的移动*/
					//根据mouse_dec里存储的鼠标信息画出新的鼠标图像
					mCursorX += mouse_dec.x;
					mCursorY += mouse_dec.y;
					//不能让鼠标移出画面
					if(mCursorX < 0)
					{
						mCursorX = 0;
					}
					if(mCursorY < 0)
					{
						mCursorY = 0;
					}
					if(mCursorX > binfo->scrnx - 1)
					{
						mCursorX = binfo->scrnx - 1;
					}
					if(mCursorY > binfo->scrny - 1)
					{
						mCursorY = binfo->scrny - 1;
					}
					sprintf(strings, "(%3d,%3d)", mCursorX, mCursorY);
					displayStrings_atLayer(layer_bg, 40, 32, COL8_FFFFFF, COL8_008484, strings);
					layer_slide(layer_mouse, mCursorX, mCursorY);
				}
			}
			//如果是定时器中断的话,需要处理定时器对应的任务
			else if(1 == i || 0 == i)				
			{
				if(0 != i)				//这个timer的数据为1的时候显示光标
				{
					timer_init(timer, &fifo_mutual, 0);
					cursor_color = COL8_000000;
				}
				else					//这个timer的数据为0的时候不显示光标
				{
					timer_init(timer, &fifo_mutual, 1);
					cursor_color = COL8_FFFFFF;
				}
				timer_set(timer, 50);
				drawRectangle(layer_window->buffer, layer_window->length, cursor_color, cursor_x, 28, 2, 15);
				layer_part_refresh(layer_window, cursor_x, 28, cursor_x + 8, 44);
			}
		}
	}	
}
Example #8
0
void HariMain(void)
{
	/*
	**最初的这部分变量没有通过内存管理来分配,它们本身属于操作系统的一部分,存在于bootpack.hrb所在的那块儿内存空间中
	*/
	BOOTINFO *binfo = (BOOTINFO *) ADR_BOOTINFO;
	MOUSE_DECODE mouse_dec;
	MEMMANAGE *memmanage = (MEMMANAGE *)MEMMANAGE_ADDR;
	LAYER_MANAGE *layer_manage;
	LAYER *layer_bg, *layer_mouse, *layer_window, *layer_windowB[3];
	TIMER *timer;
	FIFO fifo_mutual;									//缓冲区管理,所有中断公用的
	TASK *task_a, *task_b[3];
	int fifobuf[128];									//缓冲区
	int cursor_x = 8, cursor_color = COL8_FFFFFF;		//分别代表输入字符后的那个闪烁光标的横坐标和颜色
	int mCursorX, mCursorY;				//鼠标光标显示位置的横纵坐标
	unsigned int memory_total, i;
	char buf_cursor[mCursorWidth * mCursorHeight];
	unsigned char *buf_bg, *buf_window, *buf_windowB;			//屏幕的大背景会在init_screen的时候画出来,这里只需要一个指向它的指针即可
	unsigned char strings[40];
	mCursorX = binfo->scrnx / 2;			
	mCursorY = (binfo->scrny - 28)/ 2;		//减去下方任务栏的高度
	
	
	/*内存检查*/
	i = memtest(0x00400000, 0xbfffffff) / (1024 * 1024);		//i的单位是MB
	
	/*内存管理*/
	memmanage_init(memmanage);
	memory_total = i * 1024 * 1024;
	memmanage_free_4K(memmanage, 0x00001000, 0x0009e000);
	memmanage_free_4K(memmanage, 0x00400000, memory_total - 0x00400000);
	
	/*初始化接收中断的缓冲区*/
	init_fifo(&fifo_mutual, 128, fifobuf, 0);		//初始化mouseFIFO缓冲区,现在还没任务,先指定为0
	/*初始化GDT和IDT表以及PIC板的数据*/
	init_GDTandIDT();				//初始化GDT和IDT表
	init_pic();						//初始化PIC主从板数据,除了IRQ2禁止了全部中断
	io_sti();						//开始接收中断
	/*初始化PIT中断控制*/
	init_PIT();
		/*若要接收鼠标中断需要两个步骤,首先必须使鼠标控制电路(就是键盘控制电路的一部分)有效,然后要使鼠标本身有效*/
	init_keyboard(&fifo_mutual, 256);						//初始化键盘控制器电路
	enable_mouse(&fifo_mutual, 512, &mouse_dec);				//激活鼠标
	/*开放各种中断*/
	io_out8(PIC0_IMR, 0xf8);				//PIC0开发IRQ(11111000),开放IRQ0、IRQ1和IRQ2,定时器、键盘中断和从PIC板
	io_out8(PIC1_IMR, 0xef); 				//PIC1开放IRQ(11101111), 开放鼠标中断
	/*初始化任务切换管理*/
	task_a = task_init(memmanage);		//这个task_a其实代表的就是这些鼠标键盘等的任务
	fifo_mutual.task = task_a;						//为鼠标键盘等的缓冲区指定唤醒任务为task_a
	task_run(task_a, 1, 2);
	/*初始化调色板,为图形界面做准备*/
	init_palette();					//初始化调色板
	/*初始化图层管理,并且初始化鼠标光标和背景的图层*/
	layer_manage = layer_man_init(memmanage, binfo->vram, binfo->scrnx, binfo->scrny);
	
	layer_bg = layer_alloc(layer_manage);			//为背景分配图层
	layer_mouse = layer_alloc(layer_manage);		//为鼠标分配图层
	layer_window = layer_alloc(layer_manage);		//为窗口分配图层
	
	buf_bg = (unsigned char *)memmanage_alloc_4K(memmanage, binfo->scrnx * binfo->scrny);		//为背景图形的内容分配内存
	buf_window = (unsigned char *)memmanage_alloc_4K(memmanage, 160 * 52);						//为窗口图形的内容分配内存
	/*为各个图形的图层内容进行设定*/
	layer_set(layer_bg, buf_bg, binfo->scrnx, binfo->scrny, -1);			
	layer_set(layer_mouse, buf_cursor, 16, 16 ,99);
	layer_set(layer_window, buf_window, 160, 52, -1);
	/*初始化整个桌面背景*/
	init_screen(buf_bg, binfo->scrnx, binfo->scrny);				//这个时候的init_screen不再是直接画出背景,而是在mBg内存地址中填写好背景内容
	layer_slide(layer_bg, 0, 0);					//把背景图层从(0,0)坐标开始画
	/*初始化鼠标图标*/
	init_mouse_cursor(buf_cursor, 99);								//初始化鼠标光标
	layer_slide(layer_mouse, mCursorX, mCursorY);	//现在显示图形不需要再用displayShape函数了,直接用这个图层管理的绘图函数就行
	/*初始化窗口*/
	create_window(buf_window, 160, 52, "task_a", ACTIVE);					//制作窗口
	layer_slide(layer_window, 80, 72);								//在指定位置显示出窗口
	create_textbox(layer_window, 8, 28, 144, 16, COL8_FFFFFF);		//在这个窗口中创建一个输入框
	/*再画出3个窗口*/
	for (i = 0; i < 3; i++) {
		layer_windowB[i] = layer_alloc(layer_manage);
		buf_windowB = (unsigned char *)memmanage_alloc_4K(memmanage, 144 * 52);
		layer_set(layer_windowB[i], buf_windowB, 144, 52, -1);		//无透明色
		sprintf(strings, "task_b%d", i);
		create_window(buf_windowB, 144, 52, strings, INACTIVE);
		
		task_b[i] = task_alloc();
		task_b[i]->tss.esp = memmanage_alloc_4K(memmanage, 64 * 1024) + 64 * 1024 - 8;
		task_b[i]->tss.eip = (int) &task_b_main;
		task_b[i]->tss.es = 1 * 8;
		task_b[i]->tss.cs = 2 * 8;
		task_b[i]->tss.ss = 1 * 8;
		task_b[i]->tss.ds = 1 * 8;
		task_b[i]->tss.fs = 1 * 8;
		task_b[i]->tss.gs = 1 * 8;
		*((int *) (task_b[i]->tss.esp + 4)) = (int) layer_windowB[i];
		task_run(task_b[i], 2, i + 1); 
	}
	task_run(task_a, 1, 0);
	layer_slide(layer_windowB[0], 240, 72);
	layer_slide(layer_windowB[1], 80, 132);
	layer_slide(layer_windowB[2], 240, 132);
	
	/*设置好各个图层的高度*/
	layer_switch(layer_bg, 0);						//把背景图层调为最底层,高度为0
	layer_switch(layer_windowB[0], 1);					//窗口图层调节为第二层,高度为1
	layer_switch(layer_windowB[1], 2);					//窗口图层调节为第二层,高度为1
	layer_switch(layer_windowB[2], 3);					//窗口图层调节为第二层,高度为1
	layer_switch(layer_window, 4);					//窗口图层调节为第二层,高度为1
	layer_switch(layer_mouse, 5);					//鼠标图层调为最高层,高度为2
	/*定时器的初始化及其设置*/
	timer = timer_alloc();
	timer_init(timer, &fifo_mutual, 1);
	timer_set(timer, 50);
	/*在屏幕上显示一些内存、鼠标和键盘等信息*/
	sprintf(strings, "Memory has %dMB", i);
	displayStrings_CS(buf_bg, binfo->scrnx, 0, 48, COL8_FFFFFF,strings);
	layer_refresh(layer_bg, 0, 48, binfo->scrnx, 80);
	sprintf(strings, "free memory:%dKB",memmanage_total(memmanage) / 1024);
	displayStrings_CS(buf_bg, binfo->scrnx, 120, 48, COL8_FFFFFF,strings);			//用字体显示当前内存容量
	layer_refresh(layer_bg, 120, 48, binfo->scrnx, 80);
	
	
	
	for(;;)
	{
		/*只有在从中断返回的缓冲区中读取数据的时候才需要禁止中断,因为如果这个时候来了中断而没有禁止的话,
		**有可能读脏数据,即把还没有读出的数据的给抹掉或换成别的数据
		*/
		io_cli();		
		if(0 == fifo_status(&fifo_mutual))		//当前没有中断产生
		{
			task_sleep(task_a);	//如果没有需要处理的数据,就自己让自己休眠
			/*上面的那个函数直接就跳转到另一个任务中去了,不过,因为每个人物的默认eflags都是开启中断的,
			**所以不用担心,这个任务还是能被唤醒的,耳环醒后的第一个动作就是为了以防万一先开启中断
			*/
			io_sti();		//万一只有自己在运行的话,则无法睡眠,那么就执行hlt指令好了,这样省电嘛	
		}
		else
		{
			i = fifo_get(&fifo_mutual);
			io_sti();
			if((keyboard_offset <= i) && (i <= keyboard_offset + 255))			//键盘数据
			{
				sprintf(strings, "%2X", i - keyboard_offset);
				displayStrings_atLayer(layer_bg, 0, 0, COL8_FFFFFF, COL8_008484, strings);					//由于向背景图层中添加了新东西,需要重绘各个图层
				if(i < keyboard_offset + 0x54)				//判断按下的字符是否可打印
				{
					if(0 != key_table[i - keyboard_offset] && cursor_x < 144)			//0对应的字符无法打印出来
					{
						strings[0] = key_table[i - keyboard_offset];
						strings[1] = 0;
						displayStrings_atLayer(layer_window, cursor_x, 28, COL8_000000, COL8_FFFFFF, strings);
						cursor_x += 8;			//光标的位置随着每一个字符的输入向后移动一个字符宽度的位置即8像素
					}
					if((keyboard_offset + 0x0e == i) && cursor_x > 8)				//按下了退格键的情况,退格键的号码是0x0e
					{
						cursor_x -= 8;
						/*本来退格键应该只填充一个空格就行的,但是这样的话没办法刷新光标所在的那块儿区域了,
						**会留下光标的黑色痕迹,所以直接填充两个空格,刷新之后就不会有痕迹了
						*/
						displayStrings_atLayer(layer_window, cursor_x, 28, COL8_000000, COL8_FFFFFF, "  ");
					}
					//由于光标坐标后退了,为了及时显示它,需要立即重绘光标
					drawRectangle(layer_window->buffer, layer_window->length, cursor_color, cursor_x, 28, 2, 15);
					layer_refresh(layer_window, cursor_x, 28, cursor_x + 8, 44);
				}
			}
			else if((mouse_offset <= i) && (i <= mouse_offset + 255))		//鼠标数据
			{
				if(0 != mouse_decode(&mouse_dec, i - mouse_offset))		//只有返回值为1的时候才说明成功接收完成一次鼠标的中断
				{
				/*显示鼠标的信息*/
					sprintf(strings,"[lcr %3d,%3d]",mouse_dec.x, mouse_dec.y);
					if(0 != (mouse_dec.btn & 0x01))		//按下了左键
					{
						strings[1] = 'L';
						layer_slide(layer_window, mCursorX - 80, mCursorY -8);		//这行代码是移动窗口的
					}
					if(0 != (mouse_dec.btn & 0x02))		//按下了右键
					{
						strings[3] = 'R';
					}
					if(0 != (mouse_dec.btn & 0x04))		//按下了中键
					{
						strings[2] = 'C';
					}
					displayStrings_atLayer(layer_bg, 0, 16, COL8_FFFFFF, COL8_008484, strings);	
					/*鼠标的移动*/
					//根据mouse_dec里存储的鼠标信息画出新的鼠标图像
					mCursorX += mouse_dec.x;
					mCursorY += mouse_dec.y;
					//不能让鼠标移出画面
					if(mCursorX < 0)
					{
						mCursorX = 0;
					}
					if(mCursorY < 0)
					{
						mCursorY = 0;
					}
					if(mCursorX > binfo->scrnx - 1)
					{
						mCursorX = binfo->scrnx - 1;
					}
					if(mCursorY > binfo->scrny - 1)
					{
						mCursorY = binfo->scrny - 1;
					}
					sprintf(strings, "(%3d,%3d)", mCursorX, mCursorY);
					displayStrings_atLayer(layer_bg, 40, 32, COL8_FFFFFF, COL8_008484, strings);
					layer_slide(layer_mouse, mCursorX, mCursorY);
				}
			}
			else if(1 == i || 0 == i)				//光标闪烁定时器
			{
				if(0 != i)				//这个timer的数据为1的时候显示光标
				{
					timer_init(timer, &fifo_mutual, 0);
					cursor_color = COL8_000000;
				}
				else					//这个timer的数据为0的时候不显示光标
				{
					timer_init(timer, &fifo_mutual, 1);
					cursor_color = COL8_FFFFFF;
				}
				timer_set(timer, 50);
				drawRectangle(layer_window->buffer, layer_window->length, cursor_color, cursor_x, 28, 2, 15);
				layer_refresh(layer_window, cursor_x, 28, cursor_x + 8, 44);
			}
		}
	}	
}