OSDN Git Service

implement display attribute setter and getter interface.
[bbk/bchanl.git] / src / bchanl_subject.c
1 /*
2  * bchanl_subject.c
3  *
4  * Copyright (c) 2009-2011 project bchan
5  *
6  * This software is provided 'as-is', without any express or implied
7  * warranty. In no event will the authors be held liable for any damages
8  * arising from the use of this software.
9  *
10  * Permission is granted to anyone to use this software for any purpose,
11  * including commercial applications, and to alter it and redistribute it
12  * freely, subject to the following restrictions:
13  *
14  * 1. The origin of this software must not be misrepresented; you must not
15  *    claim that you wrote the original software. If you use this software
16  *    in a product, an acknowledgment in the product documentation would be
17  *    appreciated but is not required.
18  *
19  * 2. Altered source versions must be plainly marked as such, and must not be
20  *    misrepresented as being the original software.
21  *
22  * 3. This notice may not be removed or altered from any source
23  *    distribution.
24  *
25  */
26
27 #include        <basic.h>
28 #include        <bstdlib.h>
29 #include        <bstdio.h>
30 #include        <bstring.h>
31 #include        <errcode.h>
32 #include        <tcode.h>
33 #include        <tstring.h>
34 #include        <bsys/queue.h>
35 #include        <btron/btron.h>
36 #include        <btron/hmi.h>
37 #include        <btron/vobj.h>
38
39 #include    "bchanl_subject.h"
40
41 #include        "subjectcache.h"
42 #include        "subjectparser.h"
43 #include        "subjectlayout.h"
44
45 #ifdef BCHANL_CONFIG_DEBUG
46 # define DP(arg) printf arg
47 # define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err)
48 #else
49 # define DP(arg) /**/
50 # define DP_ER(msg, err) /**/
51 #endif
52
53 /* copy from bchan/src/cache.h */
54 #define DATCACHE_RECORDTYPE_MAIN 31
55 #define DATCACHE_RECORDTYPE_INFO 30
56 #define DATCACHE_RECORDSUBTYPE_RETRIEVE 0x0001
57 #define DATCACHE_RECORDSUBTYPE_HEADER 0x0002
58
59 struct bchanl_subject_t_ {
60         GID gid;
61         sbjtcache_t *cache;
62         sbjtparser_t *parser;
63         sbjtlist_t *list;
64         sbjtlayout_t *layout;
65         sbjtdraw_t *draw;
66         TC *title;
67         W title_len;
68 };
69
70 typedef struct bchanl_subjecthashnode_t_ {
71         QUEUE queue;
72         bchanl_subject_t subject;
73 } bchanl_subjecthashnode_t;
74
75 struct bchanl_subjecthash_t_ {
76         W base;
77         GID gid;
78         FSSPEC fspec;
79         COLOR vobjbgcol;
80         bchanl_subjecthashnode_t tbl[1];
81 };
82
83 EXPORT VOID bchanl_subject_gettitle(bchanl_subject_t *subject, TC **title, W *title_len)
84 {
85         *title = subject->title;
86         *title_len = subject->title_len;
87 }
88
89 EXPORT sbjtcache_t* bchanl_subject_getcache(bchanl_subject_t *subject)
90 {
91         return subject->cache;
92 }
93
94 EXPORT sbjtlayout_t* bchanl_subject_getlayout(bchanl_subject_t *subject)
95 {
96         return subject->layout;
97 }
98
99 EXPORT sbjtdraw_t* bchanl_subject_getdraw(bchanl_subject_t *subject)
100 {
101         return subject->draw;
102 }
103
104 EXPORT W bchanl_subject_relayout(bchanl_subject_t *subject)
105 {
106         sbjtparser_t *parser;
107         sbjtlist_t *list;
108         sbjtlayout_t *layout;
109         sbjtparser_thread_t *thread = NULL;
110         sbjtlist_iterator_t *list_iter;
111         sbjtlist_tuple_t *tuple;
112         W err;
113         Bool next;
114         STIME current;
115
116         parser = subject->parser;
117         list = subject->list;
118         layout = subject->layout;
119
120         sbjtlayout_clear(layout);
121         sbjtlist_clear(list);
122         sbjtparser_clear(parser);
123
124         get_tim(&current, NULL);
125
126         for (;;) {
127                 err = sbjtparser_getnextthread(parser, &thread);
128                 if (err != 1) {
129                         break;
130                 }
131                 if (thread != NULL) {
132                         sbjtlist_appendthread(list, thread, current);
133                 } else {
134                         break;
135                 }
136         }
137
138         sbjtlist_sort(list, SBJTLIST_SORTBY_NUMBER, NULL, 0);
139
140         list_iter = sbjtlist_startread(list, False);
141         for (;;) {
142                 next = sbjtlist_iterator_next(list_iter, &tuple);
143                 if (next == False) {
144                         break;
145                 }
146                 sbjtlayout_appendthread(layout, tuple);
147         }
148         sbjtlist_endread(list, list_iter);
149
150         return 0;
151 }
152
153 EXPORT W bchanl_subject_reorder(bchanl_subject_t *subject, TC *filterword, W filterword_len, W sortby, Bool descending)
154 {
155         sbjtlist_t *list;
156         sbjtlayout_t *layout;
157         sbjtlist_iterator_t *list_iter;
158         sbjtlist_tuple_t *tuple;
159         Bool next;
160
161         list = subject->list;
162         layout = subject->layout;
163
164         sbjtlayout_clear(layout);
165
166         sbjtlist_sort(list, sortby, filterword, filterword_len);
167
168         list_iter = sbjtlist_startread(list, descending);
169         for (;;) {
170                 next = sbjtlist_iterator_next(list_iter, &tuple);
171                 if (next == False) {
172                         break;
173                 }
174                 sbjtlayout_appendthread(layout, tuple);
175         }
176         sbjtlist_endread(list, list_iter);
177
178         return 0;
179 }
180
181 EXPORT W bchanl_subject_createviewervobj(bchanl_subject_t *subject, sbjtlist_tuple_t *tuple, UB *fsnrec, W fsnrec_len, VOBJSEG *seg, LINK *lnk)
182 {
183         W fd, len, err;
184         UB *bin;
185         TC *str, title[21];
186         VID vid;
187         RECT newr;
188
189         seg->view = (RECT){{0,0,300,20}};
190         seg->height = 100;
191         seg->chsz = 16;
192         seg->frcol = 0x10000000;
193         seg->chcol = 0x10000000;
194         seg->tbcol = sbjtlayout_getvobjbgcol(subject->layout);
195         seg->bgcol = 0x10ffffff;
196         seg->dlen = 0;
197
198         sbjtlist_tuple_gettitle(tuple, &str, &len);
199         if (len > 20) {
200                 len = 20;
201         }
202         tc_strncpy(title, str, len);
203         title[len] = TNULL;
204
205         fd = cre_fil(lnk, title, NULL, 1, F_FLOAT);
206         if (fd < 0) {
207                 DP_ER("cre_fil error", fd);
208                 return fd;
209         }
210
211         err = apd_rec(fd, fsnrec, fsnrec_len, 8, 0, 0);
212         if (err < 0) {
213                 DP_ER("apd_rec:fusen rec error", err);
214                 cls_fil(fd);
215                 del_fil(NULL, lnk, 0);
216                 return fd;
217         }
218
219         err = apd_rec(fd, NULL, NULL, DATCACHE_RECORDTYPE_INFO, DATCACHE_RECORDSUBTYPE_RETRIEVE, 0);
220         if (err < 0) {
221                 DP_ER("apd_rec:retrieve info error", err);
222                 cls_fil(fd);
223                 del_fil(NULL, lnk, 0);
224                 return fd;
225         }
226         err = see_rec(fd, -1, -1, NULL);
227         if (err < 0) {
228                 DP_ER("see_rec error", err);
229                 cls_fil(fd);
230                 del_fil(NULL, lnk, 0);
231                 return fd;
232         }
233
234         sbjtcache_gethost(subject->cache, &bin, &len);
235         err = wri_rec(fd, -1, bin, len, NULL, NULL, 0);
236         if (err < 0) {
237                 DP_ER("wri_rec:host error", err);
238                 cls_fil(fd);
239                 del_fil(NULL, lnk, 0);
240                 return fd;
241         }
242         err = wri_rec(fd, -1, "\n", 1, NULL, NULL, 0);
243         if (err < 0) {
244                 DP_ER("wri_rec:host error", err);
245                 cls_fil(fd);
246                 del_fil(NULL, lnk, 0);
247                 return fd;
248         }
249         sbjtcache_getboard(subject->cache, &bin, &len);
250         err = wri_rec(fd, -1, bin, len, NULL, NULL, 0);
251         if (err < 0) {
252                 DP_ER("wri_rec:board error", err);
253                 cls_fil(fd);
254                 del_fil(NULL, lnk, 0);
255                 return fd;
256         }
257         err = wri_rec(fd, -1, "\n", 1, NULL, NULL, 0);
258         if (err < 0) {
259                 DP_ER("wri_rec:board error", err);
260                 cls_fil(fd);
261                 del_fil(NULL, lnk, 0);
262                 return fd;
263         }
264         sbjtlist_tuple_getthreadnumberstr(tuple, &bin, &len);
265         err = wri_rec(fd, -1, bin, len, NULL, NULL, 0);
266         if (err < 0) {
267                 DP_ER("wri_rec:thread error", err);
268                 cls_fil(fd);
269                 del_fil(NULL, lnk, 0);
270                 return fd;
271         }
272         err = wri_rec(fd, -1, "\n", 1, NULL, NULL, 0);
273         if (err < 0) {
274                 DP_ER("wri_rec:thread error", err);
275                 cls_fil(fd);
276                 del_fil(NULL, lnk, 0);
277                 return fd;
278         }
279
280         cls_fil(fd);
281
282         vid = oreg_vob((VLINK*)lnk, seg, -1, V_NODISP);
283         if (vid < 0) {
284                 DP_ER("oreg_vob", vid);
285                 del_fil(NULL, lnk, 0);
286                 return vid;
287         }
288 #if 0
289         err = ochg_nam(vid, NULL); /* should use original panel */
290         if (err < 0) {
291                 DP_ER("ochg_nam", err);
292                 odel_vob(vid, 0);
293                 del_fil(NULL, lnk, 0);
294                 return err;
295         }
296         if (err == 0) {
297                 odel_vob(vid, 0);
298                 del_fil(NULL, lnk, 0);
299                 return BCHANL_SUBJECT_CREATEVIEWERVOBJ_CANCELED;
300         }
301 #endif
302         err = orsz_vob(vid, &newr, V_ADJUST1|V_NODISP);
303         if (err < 0) {
304                 DP_ER("orsz_vob", vid);
305                 odel_vob(vid, 0);
306                 del_fil(NULL, lnk, 0);
307                 return err;
308         }
309         seg->view = newr;
310         err = odel_vob(vid, 0);
311         if (err < 0) {
312                 DP_ER("odel_vob", err);
313                 del_fil(NULL, lnk, 0);
314                 return err;
315         }
316
317
318         return BCHANL_SUBJECT_CREATEVIEWERVOBJ_CREATED;
319 }
320
321 EXPORT VOID bchanl_subject_setresnumberdisplay(bchanl_subject_t *subject, Bool display)
322 {
323         sbjtlayout_setresnumberdisplay(subject->layout, display);
324 }
325
326 EXPORT VOID bchanl_subject_setsincedisplay(bchanl_subject_t *subject, Bool display)
327 {
328         sbjtlayout_setsincedisplay(subject->layout, display);
329 }
330
331 EXPORT VOID bchanl_subject_setvigordisplay(bchanl_subject_t *subject, Bool display)
332 {
333         sbjtlayout_setvigordisplay(subject->layout, display);
334 }
335
336 EXPORT Bool bchanl_subject_getresnumberdisplay(bchanl_subject_t *subject)
337 {
338         return sbjtlayout_getresnumberdisplay(subject->layout);
339 }
340
341 EXPORT Bool bchanl_subject_getsincedisplay(bchanl_subject_t *subject)
342 {
343         return sbjtlayout_getsincedisplay(subject->layout);
344 }
345
346 EXPORT Bool bchanl_subject_getvigordisplay(bchanl_subject_t *subject)
347 {
348         return sbjtlayout_getvigordisplay(subject->layout);
349 }
350
351 LOCAL W bchanl_subject_initialize(bchanl_subject_t *subject, GID gid, UB *host, W host_len, UB *board, W board_len, TC *title, W title_len, FSSPEC *fspec, COLOR vobjbgcol)
352 {
353         sbjtcache_t *cache;
354         sbjtparser_t *parser;
355         sbjtlist_t *list;
356         sbjtlayout_t *layout;
357         sbjtdraw_t *draw;
358         TC *title_buf;
359         W err;
360
361         cache = sbjtcache_new();
362         if (cache == NULL) {
363                 goto error_cache;
364         }
365         parser = sbjtparser_new(cache);
366         if (parser == NULL) {
367                 goto error_parser;
368         }
369         list = sbjtlist_new();
370         if (list == NULL) {
371                 goto error_list;
372         }
373         layout = sbjtlayout_new(gid);
374         if (layout == NULL) {
375                 goto error_layout;
376         }
377         draw = sbjtdraw_new(layout);
378         if (draw == NULL) {
379                 goto error_draw;
380         }
381         title_buf = malloc(sizeof(TC)*(title_len+1));
382         if (title_buf == NULL) {
383                 goto error_title;
384         }
385         tc_strncpy(title_buf, title, title_len);
386         title_buf[title_len] = TNULL;
387         err = sbjtcache_updatehost(cache, host, host_len);
388         if (err < 0) {
389                 goto error_info;
390         }
391         err = sbjtcache_updateboard(cache, board, board_len);
392         if (err < 0) {
393                 goto error_info;
394         }
395         sbjtlayout_setfsspec(layout, fspec);
396         sbjtlayout_setvobjbgcol(layout, vobjbgcol);
397
398         subject->gid = gid;
399         subject->cache = cache;
400         subject->parser = parser;
401         subject->list = list;
402         subject->layout = layout;
403         subject->draw = draw;
404         subject->title = title_buf;
405
406         return 0;
407
408 error_info:
409         free(title_buf);
410 error_title:
411         sbjtdraw_delete(draw);
412 error_draw:
413         sbjtlayout_delete(layout);
414 error_layout:
415         sbjtlist_delete(list);
416 error_list:
417         sbjtparser_delete(parser);
418 error_parser:
419         sbjtcache_delete(cache);
420 error_cache:
421         return -1; /* TODO */
422 }
423
424 LOCAL VOID bchanl_subject_finalize(bchanl_subject_t *subject)
425 {
426         free(subject->title);
427         sbjtdraw_delete(subject->draw);
428         sbjtlayout_delete(subject->layout);
429         sbjtlist_delete(subject->list);
430         sbjtparser_delete(subject->parser);
431         sbjtcache_delete(subject->cache);
432 }
433
434 LOCAL bchanl_subjecthashnode_t* bchanl_subjecthashnode_new(GID gid, UB *host, W host_len, UB *board, W board_len, TC *title, W title_len, FSSPEC *fspec, COLOR vobjbgcol)
435 {
436         bchanl_subjecthashnode_t *node;
437         W err;
438
439         node = (bchanl_subjecthashnode_t*)malloc(sizeof(bchanl_subjecthashnode_t));
440         if (node == NULL) {
441                 return NULL;
442         }
443
444         QueInit(&(node->queue));
445         err = bchanl_subject_initialize(&(node->subject), gid, host, host_len, board, board_len, title, title_len, fspec, vobjbgcol);
446         if (err < 0) {
447                 free(node);
448                 return NULL;
449         }
450
451         return node;
452 }
453
454 LOCAL VOID bchanl_subjecthashnode_delete(bchanl_subjecthashnode_t *hashnode)
455 {
456         bchanl_subject_finalize(&(hashnode->subject));
457         QueRemove(&(hashnode->queue));
458         return;
459 }
460
461 LOCAL Bool bchanl_subjecthashnode_issameboard(bchanl_subjecthashnode_t *node, UB *host, W host_len, UB *board, W board_len)
462 {
463         sbjtcache_t *cache;
464         UB *host0, *board0;
465         W host_len0, board_len0, cmp;
466
467         cache = node->subject.cache;
468
469         sbjtcache_gethost(cache, &host0, &host_len0);
470         if (host_len != host_len0) {
471                 return False;
472         }
473         cmp = strncmp(host, host0, host_len);
474         if (cmp != 0) {
475                 return False;
476         }
477
478         sbjtcache_getboard(cache, &board0, &board_len0);
479         if (board_len != board_len0) {
480                 return False;
481         }
482
483         cmp = strncmp(board, board0, board_len);
484         if (cmp != 0) {
485                 return False;
486         }
487
488         return True;
489 }
490
491 LOCAL W bchanl_subjecthash_calchashvalue(bchanl_subjecthash_t *subjecthash, UB *host, W host_len, UB *board, W board_len)
492 {
493         W i,num = 0;
494
495         for (i = 0; i < host_len; i++) {
496                 num += host[i];
497         }
498         for (i = 0; i < board_len; i++) {
499                 num += board[i];
500         }
501
502         return num % subjecthash->base;
503 }
504
505 EXPORT bchanl_subject_t* bchanl_subjecthash_search(bchanl_subjecthash_t *subjecthash, UB *host, W host_len, UB *board, W board_len)
506 {
507         bchanl_subjecthashnode_t *node, *buf;
508         W hashval;
509         Bool same;
510
511         hashval = bchanl_subjecthash_calchashvalue(subjecthash, host, host_len, board, board_len);
512         buf = subjecthash->tbl + hashval;
513
514         for (node = (bchanl_subjecthashnode_t *)buf->queue.next; node != buf; node = (bchanl_subjecthashnode_t *)node->queue.next) {
515                 same = bchanl_subjecthashnode_issameboard(node, host, host_len, board, board_len);
516                 if (same == True) {
517                         return &(node->subject);
518                 }
519         }
520
521         return NULL;
522 }
523
524 EXPORT W bchanl_subjecthash_append(bchanl_subjecthash_t *subjecthash, UB *host, W host_len, UB *board, W board_len, TC *title, W title_len)
525 {
526         bchanl_subjecthashnode_t *hashnode, *buf;
527         bchanl_subject_t *subject;
528         W hashval;
529
530         subject = bchanl_subjecthash_search(subjecthash, host, host_len, board, board_len);
531         if (subject != NULL) {
532                 return 0;
533         }
534
535         hashval = bchanl_subjecthash_calchashvalue(subjecthash, host, host_len, board, board_len);
536         buf = subjecthash->tbl + hashval;
537
538         hashnode = bchanl_subjecthashnode_new(subjecthash->gid, host, host_len, board, board_len, title, title_len, &subjecthash->fspec, subjecthash->vobjbgcol);
539         if (hashnode == NULL) {
540                 return -1; /* TODO*/
541         }
542
543         QueInsert(&(hashnode->queue), &(buf->queue));
544
545         return 0;
546 }
547
548 EXPORT bchanl_subjecthash_t* bchanl_subjecthash_new(GID gid, W base)
549 {
550         W i, err;
551         bchanl_subjecthash_t *ret;
552
553         if (base <= 0) {
554                 return NULL;
555         }
556
557         ret = (bchanl_subjecthash_t*)malloc(sizeof(W)+sizeof(GID)+sizeof(FSSPEC)+sizeof(COLOR)+sizeof(bchanl_subjecthashnode_t)*base);
558         if (ret == NULL) {
559                 return NULL;
560         }
561
562         ret->gid = gid;
563         ret->base = base;
564         for (i=0;i<base;i++) {
565                 QueInit(&(ret->tbl[i].queue));
566         }
567
568         err = wget_inf(WI_FSVOBJ, &ret->fspec, sizeof(FSSPEC));
569         if (err < 0) {
570                 ret->fspec.name[0] = TNULL;
571                 ret->fspec.attr = FT_PROP|FT_GRAYSCALE;
572                 ret->fspec.fclass = FTC_DEFAULT;
573                 ret->fspec.size.h = 16;
574                 ret->fspec.size.v = 16;
575         }
576         err = wget_inf(WI_VOBJBGCOL, &ret->vobjbgcol, sizeof(COLOR));
577         if (err < 0) {
578                 ret->vobjbgcol = 0x10000000;
579         }
580
581         return ret;
582 }
583
584 EXPORT VOID bchanl_subjecthash_delete(bchanl_subjecthash_t *subjecthash)
585 {
586         W i;
587         bchanl_subjecthashnode_t *buf,*buf_next;
588         Bool empty;
589
590         for(i = 0;i < subjecthash->base; i++){
591                 buf = subjecthash->tbl + i;
592                 for(;;){
593                         empty = isQueEmpty(&(buf->queue));
594                         if (empty == True) {
595                                 break;
596                         }
597                         buf_next = (bchanl_subjecthashnode_t*)buf->queue.next;
598                         QueRemove(&buf_next->queue);
599                         bchanl_subjecthashnode_delete(buf_next);
600                 }
601         }
602
603         free(subjecthash);
604 }