4 提高窗口移动速度(4)(harib23d)
虽说窗口移动的速度已经快了很多,但还是无法完全跟上鼠标指针那矫健的身影(啊,在真机环境下当然还是跟得上的,这里是说在QEMU中运行的情形,大家别误会哦)。更进一步的提速我们现在还做不到,不过我们可以动点脑筋,在真正的速度不变的情况下,给用户带来好像变快了的错觉(笑)。
说起来,用“纸娃娃系统”之所以会感到速度慢,是因为移动窗口的时候,窗口移动的速度赶不上鼠标的速度,在放开鼠标键之后窗口还在那里挪动,因此我们只要针对这个现象想想办法就可以了。
为什么明明已经放开了鼠标键,窗口却还在挪动呢?这是因为伴随图层移动所进行的绘图操作非常消耗时间,导致系统来不及处理FIFO中的鼠标移动数据。那么我们可以在接收到鼠标移动数据后不立即进行绘图操作,但如果一直不绘图的话鼠标和窗口就静止不动了,那不就没意义了吗?我们可以等FIFO为空时再进行绘图操作嘛。
本次的bootpack.c节选
void HariMain(void)
{
(中略)
int mx, my, i, new_mx = -1, new_my = 0, new_wx = 0x7fffffff, new_wy = 0; /*这里!*/
(中略)
for (;;) {
(中略)
if (fifo32_status(&fifo) == 0) {
/* FIFO为空,当存在搁置的绘图操作时立即执行*/ /*从此开始*/
if (new_mx >= 0) {
io_sti();
sheet_slide(sht_mouse, new_mx, new_my);
new_mx = -1;
} else if (new_wx != 0x7fffffff) {
io_sti();
sheet_slide(sht, new_wx, new_wy);
new_wx = 0x7fffffff;
} else {
task_sleep(task_a);
io_sti();
} /*到此结束*/
} else {
(中略)
} else if (512 <= i && i <= 767) { /*到此结束*/
if (mouse_decode(&mdec, i - 512) != 0) {
(中略)
new_mx = mx; /*这里!*/
new_my = my; /*这里!*/
if ((mdec.btn & 0x01) != 0) {
/*按下鼠标左键*/
if (mmx < 0) {
(中略)
for (j = shtctl->top - 1; j > 0; j--) {
(中略)
if (0 <= x && x < sht->bxsize && 0 <= y && y < sht->bysize) {
if (sht->buf[y * sht->bxsize + x] != sht->col_inv) {
(中略)
if (3 <= x && x < sht->bxsize - 3 && 3 <= y && y < 21) {
mmx = mx; /*切换到窗口移动模式*/
mmy = my;
mmx2 = sht->vx0;
new_wy = sht->vy0; /*这里!*/
}
(中略)
}
}
}
} else {
/*如果处于窗口移动模式*/
x = mx - mmx; /*计算鼠标指针移动量*/
y = my - mmy;
new_wx = (mmx2 + x + 2) & ~3; /*这里!*/
new_wy = new_wy + y; /*这里!*/
mmy = my; /*更新到移动后的坐标*/
}
} else {
/*没有按下鼠标左键*/
mmx = -1; /*切换到一般模式*/
if (new_wx != 0x7fffffff) { /*从此开始*/
sheet_slide(sht, new_wx, new_wy); /*固定图层位置*/
new_wx = 0x7fffffff;
} /*到此结束*/
}
}
}
}
}
}
这次我们增加了new_mx和new_wy两个变量,并将原来的sheet_slide(sht_mouse, mx, my);改成了new_mx = mx; new_my = my;,也就是说,我们并不真的移动鼠标图层的位置,而是将移动后的坐标暂且保存起来,当FIFO为空时,再执行sheet_slide(sht_mouse, new_mx, new_my);。
窗口移动我们也采用相同的方法,只不过有一点小小的区别,代表FIFO为空时不需要执行sheet_slide的值从-1变成了0x7fffffff,这是因为鼠标的坐标不可能为负数,但窗口的坐标却有可能为负数,因此用-1会造成歧义,我们只好改用另外一个不可能会出现的值,即0x7fffffff。
当放开鼠标左键退出窗口移动模式时,即便FIFO不为空也需要立即更新窗口的位置,这是因为用户可能马上会去移动别的窗口,那样的话sht变量的值就会发生变化,因此我们必须在sht变量的值改变之前将当前窗口移动到指定的位置。
■■■■■
好了,我们来“make run”……哇!即便在CPU很慢的电脑上用QEMU运行我们的系统,窗口也能跟鼠标同步快速移动,太好了!
截图上看不出来,不过跟鼠标完全同步