当前位置: 首页 > news >正文

Day24 窗口操作

文章目录

      • 1. 定时器API(harib21g)
      • 2. 取消定时器(harib21h)

1. 定时器API(harib21g)

在这里插入图片描述

// console.c 文件
int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax)
{struct TASK *task = task_now();/* 省略 */if (edx == 16) {reg[7] = (int) timer_alloc();} else if (edx == 17) {timer_init((struct TIMER *) ebx, &task->fifo, eax + 256);} else if (edx == 18) {timer_settime((struct TIMER *) ebx, eax);} else if (edx == 19) {timer_free((struct TIMER *) ebx);}return 0;
}

应用程序:

# a_nask.nas 文件
_api_alloctimer:	# int api_alloctimer(void);MOV		EDX,16INT		0x40RET_api_inittimer:		; void api_inittimer(int timer, int data);PUSH	EBXMOV		EDX,17MOV		EBX,[ESP+ 8]		# timerMOV		EAX,[ESP+12]		# dataINT		0x40POP		EBXRET_api_settimer:		; void api_settimer(int timer, int time);PUSH	EBXMOV		EDX,18MOV		EBX,[ESP+ 8]		# timerMOV		EAX,[ESP+12]		# timeINT		0x40POP		EBXRET_api_freetimer:		# void api_freetimer(int timer);PUSH	EBXMOV		EDX,19MOV		EBX,[ESP+ 8]		# timerINT		0x40POP		EBXRET
// noodle.c 文件
#include <stdio.h>int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
void api_putstrwin(int win, int x, int y, int col, int len, char *str);
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
void api_initmalloc(void);
char *api_malloc(int size);
int api_getkey(int mode);
int api_alloctimer(void);
void api_inittimer(int timer, int data);
void api_settimer(int timer, int time);
void api_end(void);void HariMain(void)
{char *buf, s[12];int win, timer, sec = 0, min = 0, hou = 0;api_initmalloc();buf = api_malloc(150 * 50);win = api_openwin(buf, 150, 50, -1, "noodle");timer = api_alloctimer();api_inittimer(timer, 128);for (;;) {sprintf(s, "%5d:%02d:%02d", hou, min, sec);api_boxfilwin(win, 28, 27, 115, 41, 7 /* 白色 */);api_putstrwin(win, 28, 27, 0 /* 黑色 */, 11, s);api_settimer(timer, 100);	/* 1秒 */if (api_getkey(1) != 128) {break;}sec++;if (sec == 60) {sec = 0;min++;if (min == 60) {min = 0;hou++;}}}api_end();
}

api_getkey(1)是阻塞等待,就是当fifo为空时,本任务会先休眠等待直到fifo中有内容。当定时器超时时,会产生128这个值(键盘编码不会产生128)。

2. 取消定时器(harib21h)

当前存在的一个问题是,如果应用程序被取消了,那么定时器还在按照频率触发。

// timer.c 文件
int timer_cancel(struct TIMER *timer)
{int e;struct TIMER *t;e = io_load_eflags();io_cli();	/* 禁止中断,主要是禁止改变定时器状态 */if (timer->flags == TIMER_FLAGS_USING) {	/* 是否需要取消 */if (timer == timerctl.t0) {/* 第一个定时器的取消处理 */t = timer->next;timerctl.t0 = t;timerctl.next = t->timeout;} else {/* 非第一个定时器的取消 *//* 找到timer前的一个定时器 */t = timerctl.t0;for (;;) {if (t->next == timer) {break;}t = t->next;}t->next = timer->next; /* 指针后移 */}timer->flags = TIMER_FLAGS_ALLOC;io_store_eflags(e);return 1;	/* 取消处理成功 */}io_store_eflags(e);return 0; /* 不需要取消处理 */
}void timer_cancelall(struct FIFO32 *fifo)
{int e, i;struct TIMER *t;e = io_load_eflags();io_cli();	/* 禁止改变定时器状态 */for (i = 0; i < MAX_TIMER; i++) {t = &timerctl.timers0[i];if (t->flags != 0 && t->flags2 != 0 && t->fifo == fifo) {timer_cancel(t);timer_free(t);}}io_store_eflags(e);return;
}

还需要在定时器结构体中增加一个标记,标识该定时器是否需要在应用程序结束时结束自动取消。

// bootpack.h 文件
struct TIMER {struct TIMER *next;unsigned int timeout;char flags;char flags2;		// 通常情况下为0,为1标识应用程序结束时取消定时器struct FIFO32 *fifo;int data;
};
// timer.c 文件
struct TIMER *timer_alloc(void)
{int i;for (i = 0; i < MAX_TIMER; i++) {/* 省略 */timerctl.timers0[i].flags2 = 0;		// 初始值为0return &timerctl.timers0[i];}}return 0;
}
// console.c 文件
int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax)
{/* 省略 */if (edx == 16) {reg[7] = (int) timer_alloc();((struct TIMER *) reg[7])->flags2 = 1;	/* 标记为应用程序结束时自动取消 */}/* 省略 */
}
// console.c 文件
int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline)
{/* 省略 */if (finfo != 0) {/* 省略 */start_app(0x1b, 1003 * 8, esp, 1004 * 8, &(task->tss.esp0));		// 跳到用户态,执行应用程序,应用程序调用api_end()函数之后才会从本行往下执行shtctl = (struct SHTCTL *) *((int *) 0x0fe4);for (i = 0; i < MAX_SHEETS; i++) {sht = &(shtctl->sheets0[i]);if ((sht->flags & 0x11) == 0x11 && sht->task == task) {/* 找到应用程序残留的窗口 */sheet_free(sht);	/* 关闭 */}}timer_cancelall(&task->fifo);		// 清理定时器memman_free_4k(memman, (int) q, segsiz);}/* 省略 */
}
http://www.dtcms.com/a/391721.html

相关文章:

  • 5. Linux 文件系统基本管理
  • 【MySQL】GROUP BY详解与优化
  • 深度学习:DenseNet 稠密连接​ -- 缓解梯度消失
  • Linux DNS 子域授权实践
  • 团体程序设计天梯赛-练习集 L1-041 寻找250
  • mellanox网卡(ConnectX-7)开启SACK
  • 相机镜头靶面
  • 【语法进阶】gevent的使用与总结
  • Java优选算法——前缀和
  • ARM不同层次开发
  • 【Python】高质量解析 PDF 文件框架和工具
  • RSS-2025 | 无地图具身导航新范式!CREStE:基于互联网规模先验与反事实引导的可扩展无地图导航
  • RNA-seq分析之共识聚类分析
  • Linux开发——ARM介绍
  • Force Dimension Sigma力反馈设备远程遥操作机械臂外科手术应用
  • 泛函驻点方程与边界条件的推导:含四阶导数与给定边界
  • C#开发USB报警灯服务,提供MES或者其它系统通过WebAPI调用控制报警灯
  • Docker基础篇08:Docker常规安装简介
  • 【软考-系统架构设计师】软件架构分析方法(SAAM)
  • 广西保安员考试题库及答案
  • 【Vue】Vue 项目中常见的埋点方案
  • 投稿之前去重还是投稿之后去重?
  • 【包教包会】CocosCreator3.x全局单例最优解
  • 为什么要使用dynamic_cast
  • 随机过程笔记
  • OpenHarmony:NDK开发
  • Dify 从入门到精通(第 87/100 篇):Dify 的多模态模型可观测性(高级篇)
  • 5种获取JavaScript时间戳函数的方法
  • Redis 三种集群模式
  • 初识kotlin协程