LCUI 0.12.4 开发日志

发表于2012年05月18日

2012-5-18

初次测试时,每行矩形绘制完后都有个问题,绘制了一个坐标有问题的矩形,经过调试分析后,发现代码中的变量名用错,导致用了错误的数据生成了错误的结果。

有个想法:
- 使用libxml库,用于实现xml文件的数据读写,懒得再为配置文件的读写功能另写代码来实现了,直接用libxml提供的API来完成。
- 脏矩形矩阵机制正在编写,目前的脏矩形矩阵创建功能在多次调试后已经完成,主要是根据屏幕尺寸,生成一个由64×64个脏矩形组成的矩阵。

接下来就是脏矩形矩阵的裁剪、尺寸调整、复制以及采样点的坐标生成、采样、对比。还需要写个函数,用于将各个矩形区域数据处理成互不重叠的,之后再进行相应屏幕区域内容更新。

修改了configure.ac,使configure脚本支持–enable-debug选项,这样,gcc编译器在编译源码时,加了-g参数,方便以后用gdb来调试代码。具体,参考了这篇文章

经过一番调试分析后,脏矩形矩阵的尺寸已经可以调整了,中途出现的问题,发现是自己在realloc时,由于给realloc的第一个参数写错(本来是用一维指针,却写成了二维指针),第二个参数中,sizeof()里的类型名写错(Dirty_Rect写成了Dirty_Rect*)。在测试过程中,发现有的问题会造成操作系统卡住,响应巨慢!用free命令查看后,发现每次调试卡住后,可用内存越来越多,已使用的内存变少了,这应该是由于测试程序申请了过多的内存空间导致的。

2012-5-19

脏矩形矩阵的采样点的生成已经完成。

2012-5-21

需要一个定时器,用于每隔一段时间去执行某个函数。

添加了移动对象处理机制,这个移动对象指的是需要改变位置的部件,部件移动前,将部件指针添加至队列,等待函数来处理并更新部件位置。

2012-6-3

完善了部件嵌套的图形处理功能,处理多级部件嵌套的图形显示时,不会出现图形显示错乱的问题。

2012-6-4

准备做一个锁屏程序,这是初始的形态:

screen_lock_1

2012-6-5

修改了锁屏程序,添加了背景图,调整了文本的位置:

screen_lock_2

滑块用picturebox部件代替,考虑到要有固定的滑动轨迹,widget部件要添加max_pos和min_pos属性,用于限制部件的最大位置和最小位置,也就是限制了它的可移动范围。

又修改了一下:

screen_lock_3

剩下的就是添加鼠标事件处理了。

2012-6-14

提供一个函数,在更新部件时,将部件指针、更新的数据(void*)和更新类型(char*)作为该函数的参数,并调用。该函数会将这些数据添加至队列,当然,会在添加时按照部件的层叠数据排序,排第一的是显示在最底层的部件,最后面的是最顶层的;对于未显示的部件,默认排最后;部件显示排列顺序越是靠底,它的处理优先级越是高,因为底层图形决定上层图形,上层图形可能会有透明效果,假设底层部件需要更新,并且该部件的区域范围包含了上层部件区域,如果先更新上层,那么,在这层的部件的矩形区域的图形是最新的,而它周围的图形还是未更新之前的。再比如,多个会自动移动的部件以一个部件作为容器,当快速移动容器部件的位置时,由于容器位置还未及时更新,会有几个区域显示的内容是该容器的背景内容,也就是排列在该容器底下的图层内容。

处理部件时,按照顺序,从底至顶更新部件数据。

要更新的数据主要有:
位置/布局,尺寸,图形数据。
更新尺寸时,图形数据需要更新,因为容器改变了,里面填充的内容也要改变;如果布局不为NONE,那么在更新后,连同位置也改变。
更新完这些数据后,再处理每个部件中已经记录的区域,先与该部件当前容器下的其它部件的区域进行检测,是否有重叠,有则将重叠部分裁剪掉,只留下不重叠的部分。之后,再与已记录在当前队列中的矩形进行检测。最后递归调用,直到容器为NULL为止。根据已经处理过的区域,将屏幕上相应区域的图形内容更新。

统一队列处理功能,每个队列成员是一个void指针,可指向任意类型变量的地址,这样就不必为不同类型的变量来写重复的队列处理函数了,也更方便维护。

2012-6-16

应该要指定LCUI_Graph类型的图形数据的使用方式,要么只读,要么读写。

| 状态 | 说明 |
| RO(只读) | 其它线程只有是进行只读操作才能共同对LCUI_Graph数据进行读取操作。 |
| RW(读写) | 与其它线程互斥,必须等待该状态被撤销才能进行其它操作。 |

这样,多个线程对同一图形数据的读取,这些线程就不必等待状态被撤销后才进行读取,提升了图形数据的读取速度。

但是,需要一个变量,记录有多少个线程对该数据进行访问,每次状态撤销,自减,当它为0时,恢复LCUI_Graph数据的状态为“未访问”。

该方案也可以应用到其它地方,例如:队列。

?2012-6-19

已经基本完成队列处理的函数,其它队列处理将改用此套函数来处理,例如:储存程序信息的队列、存储矩形数据的队列、事件队列等等。

部件处理功能也正进行进行修改。

2012-6-20

关于部件的更新,在LCUI_Widget结构体中添加一个队列,用于保存更新数据;对部件进行更新时,先按照显示顺序,从底到顶,处理部件的更新。

2012-6-22

图像数据应该可以被引用,图A引用图B中的区域(x, y, w, h)里的图形数据,比如:载入一张图片,这张图包含了各种所需的图形,使用它们时,只需要指定该图形在这个图形中的位置和范围,在处理时,就会直接使用该区域的图形,这样,就不需要从图形中裁剪出一块图形保存起来,减少了内存占用。

2012-6-23

部件只使用一个队列来储存,之前是分显示顺序队列和部件数据队列这两个队列,现在已经合并,部件数据在队列中的位置,代表它的显示位置。

Widget_Show和Widget_Hide这两个函数需要进行修改。

?2012-6-26

使用Show_Widget函数显示部件时,将部件由原来的位置移动到队列最前段,当然,要检查最前端的部件的位置是否为固定的,是固定的就检查后面的部件,直到部件为”非固定位置”或者当前位置为止,可用一个变量来保存该属性。这也是为了实现”始终前端显示”,比如:windows系统的迅雷7的浮动窗口,以及任务管理器的“保持前端显示”功能。

2012-6-27

部分源码已经修改完成,好像忘记了什么。

2012-6-28

完成了Show_Widget函数的修改,其它需要修改的地方,目前还在构思中,需整理一些相关的想法。

2012-7-1

合并了几个c文件的源代码,大部分源码修改已经基本完成,剩下的就是通过调试来接正细节问题。

2012-7-2

发现一个问题,生成的随机数居然是一样的。添加部件类型时,会用rand()函数生成一个ID,在调试过程中,发现添加多个不同的部件类型,得到的类型ID居然是一样的。原因是每次生成类型ID时,都调用了srand(time(NULL)), 把srand(time(NULL))放到LCUI初始化时调用,rand()函数生成的随机数就正常了。

由于内核的线程 使用pthread_create函数直接创建,没有被LCUI记录,因此,该线程中调用Get_Self_AppPointer () 函数时会返回NULL,无法得到程序信息,这回造成一些错误。LCUI_System结构体中加了个变量:self_id,保存LCUI主程序的线程ID,获取指向程序信息数据的指针时,判断一下线程是否与已保存的内核线程ID相等,是则返回指向LCUI主程序信息数据的指针。

该问题解决后,又一个问题出现了:屏幕无内容显示。

先看看相关函数代码,哪里有BUG,没有致命错误的不正常的运行结果,有点难解决。

2012-7-3

LCUI初始化时出现的一些错误已经解决,出现错误的原因,大多数都是因为有些变量没被初始化就直接使用了,比如队列。现在已经显示出鼠标指针了,可无法移动它,调试还在继续。。。

鼠标已经可以移动,纠正了鼠标在移动或点击时出现的段错误,因为没传事件指针,函数获取到的是NULL,对NULL进行操作,就出错了。但是部件的图形无法显示,目测是图形绘制相关函数的问题。等部件能正常显示后,还要测试LCUI在退出时进行资源释放,是否会出问题。

纠正了部件局部区域刷新的问题,现在能显示部件了,但只显示了一个部件,其它部件没显示,估计是图形合成的问题。

2012-7-4

图形显示处理出了点问题,又是一个难题。

呃,原来是计算部件全局坐标的函数出了问题,用了Pos_Add(a, b)得位置a和b之和,但return的时候,直接返回a,并返回a与b之和,改成a = Pos_Add(a, b);就正常了,这个a和b,代表已累计的位置和当前部件的位置,位置的累计,是使用函数递归调用得来的。

还有一个问题:本应该刷新的区域,并未刷新。可能是记录和处理局部刷新区域的函数出了点问题,需要对数据进行跟踪。

对于还未显示的部件,将不转移它里面记录的区域数据,这也是避免部件未显示的问题,因为部件在显示前,就已经将它所在的区域的图形刷新了,顺序倒置了。
容器部件改变了尺寸,其子部件的位置也需要更新。

测试helloworld程序,居中显示的label部件看起来并不居中,怀疑窗口客户区的尺寸不正常,经过调试后发现,是由于标题栏尺寸更新不及时,导致获取的标题栏尺寸为0,进而使客户区尺寸和整个窗口几乎一样大。 把调整标题栏尺寸用到的Resize_Widget函数改用Exec_Resize_Widget函数即可,前者的部件尺寸更新不及时,后者是调用它后部件尺寸就被更新。

剩下的就是鼠标事件处理的问题,目前鼠标的点击无事件响应。

鼠标事件处理的问题已经纠正,整个架构的修改工作已经基本完成,剩下的就是处理残余的BUG,还要完成矩形裁剪功能。

2012-7-5

部件改变容器后,位置也需要更新。

2012-7-6

昨天只花了点事件设计了照片查看器的界面,剩下的时间什么都没做。。。

测试矩形裁剪算法时,由于BUG的存在,申请内存时用到的大小异常,导致系统内存瞬间不足,为了预防此问题,申请内存的函数加了个限制,申请内存空间过大,会自动终止程序并报错。

Show_Widget()函数使用的顺序决定部件的排列顺序,但是,发现一个问题,由于部件数据更新是按照部件显示顺序处理的,而“显示部件”这个操作也是按照之前的顺序处理的,这样导致Show_Widget()函数的部件顺序排列无效,当然,使用Exec_Show_Widget()函数即可解决此问题。

矩形分割功能已经调试完成,在调试过程中,发现一个问题:频繁删除/新增队列中的元素,一段时间后会引起段错误,引擎错误位置是在销毁队列成员的函数里,调用free函数释放了不正常的指针。

开始完善队列处理功能。

啊咧,完善后,矩形分割功能的测试效果出问题了,前三个区域居然没显示,队列处理问题?

经过一翻调试后,分析了结果,发现是WidgetQueue_Move()函数的问题,代码有逻辑错误,在调用Show_Widget()函数时,会调用它将部件排列至队列前端,调用几次Show_Widget()函数后,队列中记录的部件指针异常,部分记录的部件指针已不存在。问题现已纠正。

2012-7-7

矩形分割功能已经基本完成,测试程序的效果图如下:

队列处理上还是有小BUG存在,运行久了就会终止。

测试程序出现错误,label部件的private指针无故被置NULL。LCUI 库源代码调试无果,只好调试测试程序,根据打印的调试信息发现,在调用Window_Client_Area_Add函数后,private指针保存的地址被改变为NULL,使用gdb的watch命令,跟踪了该部件的private指针的变化,变为NULL的时候,显示的是 ?? ( ) 函数出错,使用back查看变化前都干了什么,最终得知是用于移除队列成员的函数有问题,

部件从源队列转移至新队列,部件地址不变,还是那个内存空间,只不过所属的队列改变了。未纠正错误前,用于删除队列成员的函数是默认将移走的成员的内存地址保存至队列末尾,之后再调用memset函数置0该内存空间,所以,在新队列中的部件,它的内存空间中的数据就被修改了,prvate指针也被赋为NULL。

该问题已经被纠正,详细处理方法,可等新版本的LCUI发布后,参考它的源代码。

2012-7-8

开始修改矩形区域记录机制,加入矩形分割功能,避免不必要的重复屏幕刷新。

矩形区域处理,不能有一丁点的误差,否则,添加矩形区域时,判断为重叠,分割出有问题的矩形,又添加至队列,这就循环错误下去。

2012-7-9

经调试分析,发现是检测两矩形是否有包含关系的函数出了点问题,本来是矩形A包含矩形B,而函数判断结果为不包含,所以,不包含那就判断为叠加,分割,添加,就这样循环下去。问题原因,也就是多算进去了1个像素。

开始完善图形合成功能。

在转移完所有子部件记录的局部区域数据至父部件后,需要判断该区域是否与其它子部件的区域重叠,重叠则分割,

区域图形更新,先遍历所有部件,把与该区域重叠的部件按显示排列顺序记录下来,之后再找到最前端的不透明的部件,最后,从这个部件开始,到最前端的部件为止,合成图形。

代码修改已经大致完成,等待调试纠正细节问题。

目前的现象是:只显示鼠标指针 + 段错误。

2012-7-10

能看到显示的图形了,完善了区域分割处理,可是随后的就是出现的段错误,错误出在Free_Graph()函数函数里,错误原因是很久没遇见过的double free or corruption (out),double free是不可能,只有是corruption (out)。

为了调试,我注释掉了其它图形处理函数,只留下Malloc_Graph()和Free_Graph()函数,调试结果发现没问题,看样子也不是Free_Graph()函数的问题,之前修改过了图形混合的函数,怀疑问题出在这,因为只有这函数修改了指针指向的内存空间里的数据,如果有访问越界,就会导致corruption (out)。

2012-7-11

原来记录部件时是以追加方式添加至队列的,导致最底层的部件变成了最顶层部件,改为从尾到头遍历即可。

用了之前的图形混合函数后,测试时发现没有出错了,仔细看了原来的函数的源代码,发现修改后的代码少了个处理:获取需裁剪的区域后,没有调整前景图形的粘贴位置,导致处理时,出现越界现象。

队列处理又出毛病了,total的值异常了!居然变成了1600多万!哪有这么多?仔细分析发现,记录的部件指针,在使用时部件数据异常,经过多次调试后,怀疑是队列销毁函数出了问题,由于这个队列只保存部件的指针,销毁时不应该释放部件指针,而这个函数恰好是释放了它,导致了部件数据异常。

没问题了,测试效果表明,图形刷新速度有所提升,以前用鼠标拖动窗口时,窗口还有延迟,现在,几乎和鼠标同步移动。

呃,递归转移部件记录的区域,还存在漏洞,如果直接添加至主记录中,那么,就不会进行分割,导致图形合成出现问题。

解决方法:先转移全部部件中记录的区域数据到主队列中,然后,遍历主队列,将里面记录的区域与每一个部件对比,如果重叠就分割。

2012-7-12

鼠标移动时,添加的区域有时没有被分割,这会使图形合成不全,影响效果;

这是由于LCUI分割完矩形后,遍历队列中的数据进行图形合成时,两个操作之间有一定的时间间隔,鼠标移动时,添加刷新区域,有时刚好赶上这个空隙,添加了进去。

还有一个问题,程序有时会莫名的卡住。

开个线程,如果卡住时间过长,直接终止程序。

这些问题放后面再解决,先把新部件都弄好。

2012-7-13

修改了部件事件功能,只提供部件拖动、点击事件响应。因为要新增几个部件,有个部件涉及到鼠标的拖动事件响应,如果重新为部件写个回调函数,用于处理鼠标事件,感觉是在写多余的代码,窗口部件实现了窗口拖动功能,而按钮,根据鼠标事件,会改变成相应的图形样式;因此,写几个函数,用于统一处理鼠标事件。

单选框、复选框和选项卡部件的开发被延迟了,还有那个菜单栏部件,我也想改一下,时间流逝得太快,上床打个盹,纠结一下BUG,想一下新功能的实现流程,一天的时间就过得差不多了,悲催啊!

2012-7-14

继续完善部件事件处理功能。

已经完成,等待添加新部件。

添加了复选框部件,正进行调试。

复选框部件中嵌套了PictureBox部件,用它显示图形,我用了一个变量来储存图形,设定图形后,由于局部变量的生存周期问题,导致该变量在声明它的函数退出后会无效,因此,复选框部件无图形显示。

2012-7-15

复选框应该能自动调整其大小,以适应嵌套在它里面的部件。

在调整部件尺寸时,就会检测它的父部件是否启用 自动调整尺寸的功能。如果启用了,计算适合的吃尺寸,并修改父部件的尺寸。

经过一番调试,部分代码做了修改,复选框部件也完成了,具体如下图所示:


勾选几个选项,点击按钮后,与按钮的点击事件关联的回调函数会被调用,从而根据勾选的复选框显示相应的结果。

剩下的就是单选框,选项卡,菜单栏这两个。

单选框可直接复制复选框的代码,稍加修改,再添加几个函数,要能 设定与其它复选框的互斥关系,只能有一个复选框被选中。

选项卡也不难,一个选项卡对应一个按钮,一个容器。在多个选项卡中切换,也就是让对应容器显示,其它选项卡对应的容器就隐藏掉,容器都隐藏了,里面的其它部件也会隐藏。

2012-7-16

开始写单选框。

单选框的互斥关系的建立功能,需要纠结,暂时不做,跳过,开始做选项卡。

选项卡不想纠结了,还是做照片查看器。

PictureBox部件中若没图,就默认使用error图,error图没有,就算了。

2012-7-17

部件隐藏后,其它部件无法点击。

参考了mgaview 0.1.4 的源代码,使LCUI能够在8位,16位,24位,32位显示器下正常输出图形,虽然没测试。。。

Set_Label_Text()函数中,如果控制符和参数列表数量不一致,会导致段错误,gdb调试会提示错误出在vfprinff()函数,看来,需要考虑让Set_Label_Text()函数能和printf()函数那样,在编译时能够检测语法错误。

照片查看器的初始效果图:

2012-7-18

照片查看器支持拖动浏览,具体如下所示:

鼠标拖动时浏览区域的移动距离有问题,缩放比例为100%倒是正常,但是,其它比例,浏览区域的移动和鼠标拖动不同步,移动的距离要根据缩放比例来算。

2012-7-19

各种纠结,虽然直接用缩放后的图形,移动浏览区域是没问题,可是考虑到内存状况,还是暂时不用这方法,

为了减少内存占用,PictureBox部件在缩放图形时,只截取浏览区域内的图形并进行缩放,也就是说,每次移动浏览区域时,都会对在浏览区域内的图形进行缩放,而不是预先将整张图像进行缩放,之后再直接从缩放后的图中截取出浏览区域内的图形。

2012-7-20

纠结了一段时间,还是让PictureBox部件在缩放图像时保存缩放后的图形,这个实现起来容易,可不省内存。如果按照之前的方法,并要确保移动浏览区域能够与鼠标拖动同步,虽然很省内存,但很有难度,因为,大于100%比例时,浏览区域上的1像素相当于实际图中的零点几像素,像素个数没有小数,只有使用临时区域,暂时先存放比实际浏览区域大的图形,尺寸刚好能容纳整数个原图的像素,还要记录这两个区域的相对距离,移动浏览区域时,就从临时区域内截取图形。

可是,尺寸的确定就需要纠结了,如果起点小于0,需要修改相对距离,相对距离是浮点数,如果起点+尺寸超出原图范围,那就需要调整尺寸,尺寸改变了,临时浏览区域的尺寸也要改变。这还只是缩放比例大于100%,小于100%还没考虑进来。

有些问题无法用文字描述清楚,这个优化还是在以后完成吧,现在暂时先用着简单的方法。

粗略的算了一下,ubuntu下的照片查看器,打开一张 1941×2437的图片,缩放比例为2000%,占用内存20多MB,鼠标拖动浏览起来还有点卡。

2012-7-21

Fill_Background_Image()函数我居然用了GRAPH_MIX_FLAG_REPLACE标志,这个标志不是给它用的,现已改用?LAYOUT_STRETCH ,怪不得修改Zoom_Graph()函数后,标题栏的图形绘制出了问题。

PictureBox 部件代码的改写已完成。

RadioButton部件,用链表记录各个RadioButton部件的互斥关系,部件私有数据保存链表表头指针。添加互斥关系或移除互斥关系,也就是对链表的操作。
需要一个队列来保存这些链表表头指针。

2012-7-22

直接用队列来保存具备互斥关系的单选框的指针,有现成的就用,无需再重新写个。

单选框的互斥关系的建立与删除已经完成,测试无任何致命错误。

部分部件的析构函数都未完成,之前的调试都是直接ctrl+c终止程序,准备测试LCUI的退出是否正常。

想让configure如果未检测到依赖库就终止,而AC_CHECK_LIB这宏应该有结果处理,于是搜索了一番,发现了不错的地方:http://www.gnu.org/savannah-checkouts/gnu/,在上面可以找到所有gnu项目,而且还有项目主页,主页上有文档,可以在线查看。

AC_CHECK_LIB如果没有检测到库的存在,就调用AC_MSG_ERROR来打印错误信息并终止configure脚本。

部件全局透明度的设置问题已解决,原来是由于数据类型问题,计算后的结果是浮点数,却赋值给了整数变量,导致合成图形时,按照了不正常的透明度来混合了。

改变部件的全局透明度后,该部件范围内显示的图形不正常,经调试分析后,发现是处理屏幕图形更新时,判断图层是否不透明的地方,忽略了图层的全局透明度,即使全局透明度小于255,也判定为不透明,导致图层合成出问题。

2012-7-23

队列添加一个锁,当某线程锁住了该队列,其它线程无法访问该队列,只能等待那个线程解锁队列,才能访问。

队列锁还有点问题,一个线程锁住了后,再解锁,其它线程还是无法访问,一直在等待。

2012-7-24

之前截的图还没合成gif动画,现在已合成,效果如下:

鼠标在部件上,部件移动时,有不正常的图形显示,但是,移开鼠标后,部件移动就没问题了。

2012-7-25

相关清理功能已经大致完善,LCUI 退出时的相关处理也完善了一下,一开始,关闭窗口,还要等待鼠标移动一次才退出程序,因为有个线程在阻塞等待鼠标输入,调短了阻塞时长,就可以了。LCUI退出后,终端属性无法恢复正常,无回显,按删除键居然回显字符,程序输出的字符凌乱,只好找个正常属性的终端,用个printf()函数打印终端各个属性的值,恢复属性时就用这个值,没办法,网上搜索到的大多数是转的,转来转去,没几个人真正弄懂用法。

tcsetattr()函数设定终端属性,tcgetattr()函数获取终端属性,可是结构体termios中的各个成员该赋什么值,就不清楚了,虽然有相关说明,ICANON、ECHO什么的,之前我是在网上某个代码中修改来的,也就是tm.c_lflag &= ~(ICANON|ECHO);,又是按位与,又是按位取反,有时按位或,这好蛋疼。

2012-7-26

由于启用了队列锁,照片查看器的图片浏览功能出了点问题,浏览区域的移动与鼠标拖动不同步,估计是由于队列锁的原因,等待队列解锁耽误了一些时间,导致区域移动被延迟,正在修改部件的拖动事件关联函数,一个first_click表示是否第一次点击,一个end_click表示是否结束了点击,当两个都为“假”时,就可以确定部件正处于拖动状态,回调函数判断first_click为真,就记录好浏览区域与PictureBox部件的偏移位置,等回调函数再次被调用时,如果两个变量都为“假”,那就移动浏览区域至新的位置;如果end_click为“真”,结束拖动。

测试照片查看器时,发现无法正常显示包含汉字的文件名,乱码,难道是由于获取文件列表时,将UTF-8编码的文件名当成GB2312编码的,又转换成unicode编码的缘故?

照片查看器的效果图:

2012-7-27

浪费了时间。

2012-7-28

关于那个问题,个人怀疑是鼠标事件处理的问题,因为也只有它才会根鼠标位置有关系。

还有图层合成也存在一定问题。

修改了处理部件移动的函数,居然没问题了,奇怪了,即使是使用之前的代码,也不应该会出现问题的,难道这暗示着LCUI还有某个BUG?

卸载tslib,测试了configure脚本,在检测tslib是否可用时,脚本退出,可是,打印的错误信息中有双引号,把configure.ac里的AC_MSG_ERROR里写的错误信息改了一下,去掉了双引号,保存后,就autoreconf,再次测试configure脚本,这次错误信息没双引号了,话说,传给AC_MSG_ERROR的字符串不加双引号也可以?

好了,完善照片查看器,再整理文件,移植到学习机上,测试效果,无大问题后,做好源码包发布前的准备。

函数的说明,我觉得写在头文件中应该好一些,这样省得保持头文件和源文件内的函数说明的一致了。

开始完善按键响应功能。

由于没有初始化按键事件队列,导致鼠标事件无法正常处理,使鼠标无法拖动窗口,无法点击按钮,按钮无反应。

处理按键事件时,由于按键处理线程未被LCUI记录,导致无法获取指向程序数据的指针,产生段错误。

猜拳和照片查看器已经完成。

2012-7-30

复选框和单选框有点毛病,移动窗口很卡。

出现段错误,原因是label部件的字体处理出了问题,应该不是字体处理问题,可能是因为复选框和单选框部件本身存在问题。

window部件的代码改了一次,标题栏上的图标用picturebox部件,文本用label部件,可能是之前生成标题栏文本位图的那个Get_Fonts_Bitmap()函数有问题,不用它了。

修改了鼠标事件处理。

不知道是哪个线程用完队列后,队列记录总线程数为1,mode非0,让其它线程就这样卡住。看来,需要研究一下线程同步了。

读写锁正是我需要的。

还是有点不满意,自己在读写锁的基础上改进一下。

2012-7-31

读写锁+互斥锁,如果线程自己之前已经设置为“读”,但现在又要“写”,那么,就会等待其它线程用完,用完后,就并将“读”状态入栈,并之前设置的“读”解锁,之后再设置“写”锁。用完数据后,进行解锁,解锁时,就会出栈,得到“读”状态,解锁但前的“写”锁,恢复成“读”锁。

测试读写锁中。。。

原来是由于设置读写锁为“读”时,忘记设置了,到设置读写锁为“写”时,解锁一次(本来没锁住),又一直在等待能设置“写”锁。

2012-8-1

读写+互斥锁已经搞定,在线程设定互斥锁时,等待其它读/写线程使用结束,如果只剩下一个线程在读/写,而且这个线程就是自己,那么,删除记录,结束等待,并记录设定互斥锁的线程ID,设定后,其它线程均不能访问,只能等待互斥锁解锁。

设定读锁或者写锁时,如果线程之前设定过,且没有解锁,那么就会记录之前使用的锁的状态,我使用了 栈 来存放,栈处理函数也就那么几十行而已,pop出栈,push入栈。又写了个测试程序测试这个栈处理函数是否有问题。

但是,为了存2种状态,就要用一个int型变量,假如要入栈几十个状态,那不就是占几十个sizeof(int)字节?如果用1位来保存这2种状态,那么,一个int型变量(32位)可以保存32个状态,占4个字节内存,而如果用1个int型变量保存1个状态,32个状态就要32*4个字节,这占用内存够多的。。。

这是具体使用示例:设定读锁–》设定读锁–》设定写锁–》设定读锁–》设定写锁–》解锁–》解锁–》解锁–》解锁–》解锁

一个线程可以往复设置读写锁,但设定锁的次数要和解锁次数一致,解锁后,会恢复上次锁的状态,也就是设定锁时保护现场,解锁时恢复现场。

设定写锁时,会等待其它线程使用完,有个记录,记录着当前使用锁的线程ID,如果记录中有自己,且还有几个线程正在使用锁,那么,该线程就会先移除自己的记录,解锁,等待其它线程用完后,再恢复记录,并设置写锁。

呃,经过LCUI 的程序的暴力测试,读写+互斥锁 的BUG就暴露出来了,单个小程序测试没出问题,往复运行十几次后出了BUG,线程被阻塞了,线程A在等,线程B也在等;线程A正在使用写锁,并且想设定互斥锁,但有线程B的记录,正等待的记录移除;而线程B已添加记录,并想设定“读”锁,正在等线程A解除“写”锁。

2012-8-2

貌似在绕弯子,浪费时间,删代码。

直接用互斥锁得了,队列处理函数不对队列使用互斥锁,由自己手动设置互斥锁。

记录读写次数,每次读写或解锁时都打印一次读写次数,最终测试发现,某处连续使用两次“读”锁,然后连续两次进行解锁,导致异常,使其它线程无法正常使用该锁。搜索了全部源码文件,原来是Record_WidgetUpdate()函数里出了问题。

开始完善源代码的注释。

2012-8-3

代码注释已经修改完毕,开始更新头文件。

头文件已更新完毕,准备完善测试程序的源代码。

测试程序源代码修改完毕,Makefile添加完毕。

等待相关文档的完善。

2012-8-4

LCUI 0.12.4 已发布。

2012-8-5

交叉编译,运行configure脚本时加了–build=mipsel-linux –target=mispel-linux 这两个参数,检测出来的编译器还是电脑端的gcc编译器,不是mipsel-linux-gcc编译器。

只好在make时,加了CC=mipsel-linux-gcc,自己指定编译器,可是生成动态库就出问题了:

/usr/bin/ld: .libs/LCUI_Main.o: Relocations in generic ELF (EM: 8)

/usr/bin/ld: .libs/LCUI_Main.o: Relocations in generic ELF (EM: 8)

.libs/LCUI_Main.o: could not read symbols: File in wrong format

链接器的问题,用的还是电脑端的ld链接器,不是mipsel-linux-ld链接器,即使make时指定LD=mipsel-linux-ld也没效果,修改Makefile还是一样,好吧,直接在嵌入式设备上编译。

不同版本的编译器,给出的警告也不同,用新版本编译无警告,在旧版本中就有,甚至会是错误。

比如:pthread_rwlock_t这个类型,电脑上可以正常编译,但嵌入式设备上就报错,没这个类型,看了pthread.h头文件的内容后,又参考了相关资料,定义_GNU_SOURCE宏即可,我把它加到LCUI.h中,居然没用,只好在configure.ac文件中添加编译器的参数:-D _GNU_SOURCE,这样生成makefile后,makefile里就默认使用这个参数。

电脑上没有libiconv库,也能使用iconv的函数,可能是某库内置这个libiconv库的函数,但在嵌入式设备上,链接时需要libiconv库,因此,改了configure.ac,让configure脚本检测是否有libiconv库,有则在链接时加上-liconv参数。

2012-8-6

嵌入式设备上测试,发现程序不能在设备上正常运行,是因为收到SIGTTOU信号的缘故,导致程序终止。
开启触屏后,程序出现段错误,终止运行。
在有16位色显示器的嵌入式设备上测试,发现显示的图形异常,但mgaview测试无问题,可能是代码抄错了。

2012-8-7

论坛和博客的迁移以及相关工作已完成,编辑了WordPress的主题CSS样式。

编辑了多说评论框的CSS样式。