OSDN Git Service

implement NG res display.
[bbk/bchan.git] / src / main.c
1 /*
2  * main.c
3  *
4  * Copyright (c) 2009-2010 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        <tstring.h>
33 #include        <keycode.h>
34 #include        <tcode.h>
35 #include        <tctype.h>
36 #include        <btron/btron.h>
37 #include        <btron/dp.h>
38 #include        <btron/hmi.h>
39 #include        <btron/vobj.h>
40 #include        <btron/libapp.h>
41 #include        <btron/bsocket.h>
42
43 #include        "postres.h"
44 #include        "poptray.h"
45 #include        "confirm.h"
46 #include        "window.h"
47 #include        "cache.h"
48 #include        "parser.h"
49 #include        "layoutarray.h"
50 #include        "layout.h"
51 #include        "retriever.h"
52 #include        "submit.h"
53 #include        "tadurl.h"
54 #include        "sjisstring.h"
55 #include        "bchan_vobj.h"
56 #include        "bchan_panels.h"
57 #include        "bchan_menus.h"
58
59 #ifdef BCHAN_CONFIG_DEBUG
60 # define DP(arg) printf arg
61 # define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err)
62 #else
63 # define DP(arg) /**/
64 # define DP_ER(msg, err) /**/
65 #endif
66
67 #define BCHAN_DBX_MENU_TEST 20
68 #define BCHAN_DBX_TEXT_MLIST0   21
69 #define BCHAN_DBX_TEXT_MLIST1   22
70 #define BCHAN_DBX_TEXT_MLIST2   23
71 #define BCHAN_DBX_MSGTEXT_RETRIEVING 24
72 #define BCHAN_DBX_MSGTEXT_NOTMODIFIED 25
73 #define BCHAN_DBX_MSGTEXT_POSTSUCCEED 26
74 #define BCHAN_DBX_MSGTEXT_POSTDENIED 27
75 #define BCHAN_DBX_MSGTEXT_POSTERROR     28
76 #define BCHAN_DBX_MS_CONFIRM_POST 29
77 #define BCHAN_DBX_MS_CONFIRM_CANCEL     30
78 #define BCHAN_DBX_TEXT_CONFIRM_TITLE 31
79 #define BCHAN_DBX_MSGTEXT_NONAUTHORITATIVE 32
80 #define BCHAN_DBX_MSGTEXT_NETWORKERROR  33
81 #define BCHAN_DBX_FFUSEN_BBB 34
82 #define BCHAN_DBX_FFUSEN_TEXEDIT 35
83 #define BCHAN_DBX_FFUSEN_VIEWER 36
84 #define BCHAN_DBX_MSGTEXT_NOTFOUND      37
85 #define BCHAN_DBX_MSGTEXT_CANTRETRIEVE 44
86 #define BCHAN_DBX_GMENU_RESNUMBER 45
87 #define BCHAN_DBX_GMENU_RESID 47
88
89 #define BCHAN_MENU_WINDOW 4
90
91 typedef struct bchan_hmistate_t_ bchan_hmistate_t;
92 struct bchan_hmistate_t_ {
93         PTRSTL ptr;
94
95         TC *msg_retrieving;
96         TC *msg_notmodified;
97         TC *msg_nonauthoritative;
98         TC *msg_postsucceed;
99         TC *msg_postdenied;
100         TC *msg_posterror;
101         TC *msg_networkerror;
102         TC *msg_notfound;
103         TC *msg_cantretrieve;
104 };
105
106 LOCAL VOID bchan_hmistate_updateptrstyle(bchan_hmistate_t *hmistate, PTRSTL ptr)
107 {
108         if (hmistate->ptr == ptr) {
109                 return;
110         }
111         hmistate->ptr = ptr;
112         gset_ptr(hmistate->ptr, NULL, -1, -1);
113 }
114
115 LOCAL VOID bchan_hmistate_display_postdenied(bchan_hmistate_t *hmistate, TC *str, W len)
116 {
117         W size, msg_len;
118         TC *msg;
119
120         size = tc_strlen(hmistate->msg_postdenied);
121         msg_len = size + len + 2;
122         msg = malloc((msg_len + 1)*sizeof(TC));
123         if (msg == NULL) {
124                 pdsp_msg(hmistate->msg_postdenied);
125         }
126
127         tc_strcpy(msg, hmistate->msg_postdenied);
128         msg[size] = TK_LPAR;
129         memcpy((UB*)(msg + size + 1), str, len * sizeof(TC));
130         msg[msg_len - 1] = TK_RPAR;
131         msg[msg_len] = TNULL;
132
133         pdsp_msg(msg);
134
135         free(msg);
136 }
137
138 typedef struct bchan_t_ bchan_t;
139 struct bchan_t_ {
140         W wid;
141         W gid;
142         W taskid;
143         W mbfid;
144         VID vid;
145         W exectype;
146
147         Bool request_confirm_open; /* TODO: should be other implememt? */
148
149         MENUITEM *mnitem;
150         MNID mnid;
151
152         bchan_hmistate_t hmistate;
153         bchan_resnumbermenu_t resnumbermenu;
154         bchan_residmenu_t residmenu;
155
156         datretriever_t *retriever;
157         datcache_t *cache;
158         datparser_t *parser;
159         datlayoutarray_t *layoutarray;
160         datlayoutstyle_t style;
161         datlayout_t *layout;
162         datdraw_t *draw;
163         datwindow_t *window;
164         ressubmit_t *submit;
165         cfrmwindow_t *confirm;
166
167         postresdata_t *resdata;
168 };
169
170 #define BCHAN_MESSAGE_RETRIEVER_UPDATE   1
171 #define BCHAN_MESSAGE_RETRIEVER_RELAYOUT 2
172 #define BCHAN_MESSAGE_RETRIEVER_NOTMODIFIED 3
173 #define BCHAN_MESSAGE_RETRIEVER_NONAUTHORITATIVE 4
174 #define BCHAN_MESSAGE_RETRIEVER_NOTFOUND 5
175 #define BCHAN_MESSAGE_RETRIEVER_ERROR -1
176
177 static  WEVENT  wev0;
178
179 void    killme(bchan_t *bchan)
180 {
181         gset_ptr(PS_BUSY, NULL, -1, -1);
182         pdsp_msg(NULL);
183         bchan_residmenu_finalize(&bchan->residmenu);
184         bchan_resnumbermenu_finalize(&bchan->resnumbermenu);
185         if (bchan->exectype == EXECREQ) {
186                 oend_prc(bchan->vid, NULL, 0);
187         }
188         if (bchan->wid > 0) {
189                 wcls_wnd(bchan->wid, CLR);
190         }
191         ext_prc(0);
192 }
193
194 LOCAL VOID bchan_scroll(VP arg, W dh, W dv)
195 {
196         bchan_t *bchan = (bchan_t*)arg;
197         datdraw_scrollviewrect(bchan->draw, dh, dv);
198         wscr_wnd(bchan->wid, NULL, -dh, -dv, W_MOVE|W_RDSET);
199 }
200
201 LOCAL VOID bchan_draw(VP arg, RECT *r)
202 {
203         bchan_t *bchan = (bchan_t*)arg;
204         datdraw_draw(bchan->draw, r);
205 }
206
207 LOCAL VOID bchan_resize(VP arg)
208 {
209         bchan_t *bchan = (bchan_t*)arg;
210         W l,t,r,b;
211         RECT work;
212         Bool workchange = False;
213
214         wget_wrk(bchan->wid, &work);
215         if (work.c.left != 0) {
216                 work.c.left = 0;
217                 workchange = True;
218         }
219         if (work.c.top != 0) {
220                 work.c.top = 0;
221                 workchange = True;
222         }
223         wset_wrk(bchan->wid, &work);
224         gset_vis(bchan->gid, work);
225
226         datdraw_getviewrect(bchan->draw, &l, &t, &r, &b);
227
228         r = l + work.c.right - work.c.left;
229         b = t + work.c.bottom - work.c.top;
230
231         datdraw_setviewrect(bchan->draw, l, t, r, b);
232         datwindow_setworkrect(bchan->window, l, t, r, b);
233
234         if (workchange == True) {
235                 wera_wnd(bchan->wid, NULL);
236                 wreq_dsp(bchan->wid);
237         }
238 }
239
240 LOCAL VOID bchan_close(VP arg)
241 {
242         bchan_t *bchan = (bchan_t*)arg;
243         /* TODO: guard request event W_DELETE and W_FINISH. */
244         datcache_writefile(bchan->cache);
245         killme(bchan);
246 }
247
248 LOCAL VOID bchan_pushstringtotray(TC *str, W len)
249 {
250         W err;
251         TRAYREC trayrec[2];
252         UB bin[4+24];
253         TADSEG *base = (TADSEG*)bin;
254         TEXTSEG *textseg = (TEXTSEG*)(bin + 4);
255
256         base->id = 0xFFE1;
257         base->len = 24;
258         textseg->view = (RECT){{0, 0, 0, 0}};
259         textseg->draw = (RECT){{0, 0, 0, 0}};
260         textseg->h_unit = -120;
261         textseg->v_unit = -120;
262         textseg->lang = 0x21;
263         textseg->bgpat = 0;
264
265         trayrec[0].id = 0xE1;
266         trayrec[0].len = 28;
267         trayrec[0].dt = bin;
268         trayrec[1].id = TR_TEXT;
269         trayrec[1].len = len * sizeof(TC);
270         trayrec[1].dt = (B*)str;
271
272         err = tpsh_dat(trayrec, 2, NULL);
273         if (err < 0) {
274                 DP_ER("tpsh_dat", err);
275         }
276 }
277
278 LOCAL VOID bchan_pushthreadtitle(bchan_t *bchan)
279 {
280         W len;
281         TC *str;
282
283         str = datlayout_gettitle(bchan->layout);
284         len = datlayout_gettitlelen(bchan->layout);
285         bchan_pushstringtotray(str, len);
286 }
287
288 LOCAL VOID bchan_pushthreadurl(bchan_t *bchan)
289 {
290         W host_len, board_len, thread_len, len, i, ret;
291         UB *host, *board, *thread;
292         TC *str;
293
294         datcache_gethost(bchan->cache, &host, &host_len);
295         datcache_getborad(bchan->cache, &board, &board_len);
296         datcache_getthread(bchan->cache, &thread, &thread_len);
297
298         len = 7 + host_len + 15 + board_len + 1 + thread_len + 1;
299         str = malloc(sizeof(TC)*len);
300
301         str[0] = TK_h;
302         str[1] = TK_t;
303         str[2] = TK_t;
304         str[3] = TK_p;
305         str[4] = TK_COLN;
306         str[5] = TK_SLSH;
307         str[6] = TK_SLSH;
308         for (i = 0; i < host_len; i++) {
309                 ret = sjtotc(str + 7 + i, host + i);
310                 if (ret != 1) {
311                         DP(("invalid charactor\n"));
312                         free(str);
313                         return;
314                 }
315         }
316         str[7 + host_len] = TK_SLSH;
317         str[7 + host_len + 1] = TK_t;
318         str[7 + host_len + 2] = TK_e;
319         str[7 + host_len + 3] = TK_s;
320         str[7 + host_len + 4] = TK_t;
321         str[7 + host_len + 5] = TK_SLSH;
322         str[7 + host_len + 6] = TK_r;
323         str[7 + host_len + 7] = TK_e;
324         str[7 + host_len + 8] = TK_a;
325         str[7 + host_len + 9] = TK_d;
326         str[7 + host_len + 10] = TK_PROD;
327         str[7 + host_len + 11] = TK_c;
328         str[7 + host_len + 12] = TK_g;
329         str[7 + host_len + 13] = TK_i;
330         str[7 + host_len + 14] = TK_SLSH;
331         for (i = 0; i < board_len; i++) {
332                 ret = sjtotc(str + 7 + host_len + 15 + i, board + i);
333                 if (ret != 1) {
334                         DP(("invalid charactor\n"));
335                         free(str);
336                         return;
337                 }
338         }
339         str[7 + host_len + 15 + board_len] = TK_SLSH;
340         for (i = 0; i < thread_len; i++) {
341                 ret = sjtotc(str + 7 + host_len + 15 + board_len + 1 + i, thread + i);
342                 if (ret != 1) {
343                         DP(("invalid charactor\n"));
344                         free(str);
345                         return;
346                 }
347         }
348         str[7 + host_len + 15 + board_len + 1 + thread_len] = TK_SLSH;
349
350         bchan_pushstringtotray(str, len);
351
352         free(str);
353 }
354
355 LOCAL Bool bchan_is_bbs_url(UB *data, W data_len)
356 {
357         TC *str;
358         W str_len, cmp, i, n_slsh = 0;
359
360         if ((tadurl_cmpscheme(data, data_len, "http", 4) != 0)
361                 &&(tadurl_cmpscheme(data, data_len, "ttp", 3) != 0)) {
362                 return False;
363         }
364
365         cmp = tadurl_cmppath(data, data_len, "test/read.cgi/", 14);
366         if (cmp != 0) {
367                 return False;
368         }
369
370         str = (TC*)data;
371         str_len = data_len/2;
372
373         for (i=0;; i++) {
374                 if (i >= str_len) {
375                         return False;
376                 }
377                 if (n_slsh == 6) {
378                         break;
379                 }
380                 if (str[i] == TK_SLSH) {
381                         n_slsh++;
382                 }
383         }
384
385         for (;; i++) {
386                 if (i >= str_len) {
387                         return False;
388                 }
389                 if (str[i] == TK_SLSH) {
390                         break;
391                 }
392                 if (tc_isdigit(str[i]) == 0) {
393                         return False;
394                 }
395         }
396
397         return True;
398 }
399
400 LOCAL W bchan_createvobj_allocate_url(UB *data, W data_len, TC **url, W *url_len)
401 {
402         TC *str;
403         W len;
404
405         if (tadurl_cmpscheme(data, data_len, "http", 4) == 0) {
406                 len = data_len;
407                 str = malloc(len);
408                 if (str == NULL) {
409                         return -1; /* TODO */
410                 }
411                 memcpy(str, data, data_len);
412         } else if (tadurl_cmpscheme(data, data_len, "ttp", 3) == 0) {
413                 len = data_len + sizeof(TC)*1;
414                 str = malloc(len);
415                 if (str == NULL) {
416                         return -1; /* TODO */
417                 }
418                 memcpy(str + 1, data, data_len);
419                 str[0] = TK_h;
420         } else if (tadurl_cmpscheme(data, data_len, "sssp", 4) == 0) {
421                 len = data_len;
422                 str = malloc(len);
423                 if (str == NULL) {
424                         return -1; /* TODO */
425                 }
426                 memcpy(str + 4, data + 8, data_len - 8);
427                 str[0] = TK_h;
428                 str[1] = TK_t;
429                 str[2] = TK_t;
430                 str[3] = TK_p;
431         } else {
432                 return -1; /* TODO */
433         }
434
435         *url = str;
436         *url_len = len/sizeof(TC);
437
438         return 0;
439 }
440
441 LOCAL VOID bchan_separete_bbs_url(UB *url, W url_len, UB **host, W *host_len, UB **board, W *board_len, UB **thread, W *thread_len)
442 {
443         W i,n_slsh = 0;
444
445         for (i=0; i < url_len; i++) {
446                 if (n_slsh == 2) {
447                         break;
448                 }
449                 if (url[i] == '/') {
450                         n_slsh++;
451                 }
452         }
453         *host = url + i;
454         *host_len = 0;
455         for (; i < url_len; i++) {
456                 if (n_slsh == 3) {
457                         break;
458                 }
459                 if (url[i] == '/') {
460                         n_slsh++;
461                 } else {
462                         (*host_len)++;
463                 }
464         }
465         for (; i < url_len; i++) {
466                 if (n_slsh == 5) {
467                         break;
468                 }
469                 if (url[i] == '/') {
470                         n_slsh++;
471                 }
472         }
473         *board = url + i;
474         *board_len = 0;
475         for (; i < url_len; i++) {
476                 if (n_slsh == 6) {
477                         break;
478                 }
479                 if (url[i] == '/') {
480                         n_slsh++;
481                 } else {
482                         (*board_len)++;
483                 }
484         }
485         *thread = url + i;
486         *thread_len = 0;
487         for (; i < url_len; i++) {
488                 if (n_slsh == 7) {
489                         break;
490                 }
491                 if (url[i] == '/') {
492                         n_slsh++;
493                 } else {
494                         (*thread_len)++;
495                 }
496         }
497 }
498
499 #define BCHAN_CREATEVOBJ_CANCELED 0
500 #define BCHAN_CREATEVOBJ_CREATED 1
501
502 LOCAL W bchan_createvobj(bchan_t *bchan, UB *data, W data_len, VOBJSEG *vseg, LINK *lnk)
503 {
504         W err, fsn_bbb_len, fsn_texedit_len, fsn_viewer_len, url_len, ascii_url_len;
505         TC *url;
506         void *fsn_bbb, *fsn_texedit, *fsn_viewer;
507         UB *ascii_url;
508         UB *host, *board, *thread;
509         W host_len, board_len, thread_len;
510         LTADSEG *lseg;
511         Bool is_bbs;
512         TC title[] = {TK_T, TK_h, TK_r, TK_e, TK_a, TK_d, TNULL}; /* tmp */
513
514         err = dget_dtp(64, BCHAN_DBX_FFUSEN_BBB, (void**)&fsn_bbb);
515         if (err < 0) {
516                 DP_ER("dget_dtp: BCHAN_DBX_FFUSEN_BBB", err);
517                 return err;
518         }
519         fsn_bbb_len = dget_siz((B*)fsn_bbb);
520         err = dget_dtp(64, BCHAN_DBX_FFUSEN_TEXEDIT, (void**)&fsn_texedit);
521         if (err < 0) {
522                 DP_ER("dget_dtp: BCHAN_DBX_FFUSEN_TEXEDIT", err);
523                 return err;
524         }
525         fsn_texedit_len = dget_siz((B*)fsn_texedit);
526         err = dget_dtp(64, BCHAN_DBX_FFUSEN_VIEWER, (void**)&fsn_viewer);
527         if (err < 0) {
528                 DP_ER("dget_dtp: BCHAN_DBX_FFUSEN_VIEWER", err);
529                 return err;
530         }
531         fsn_viewer_len = dget_siz((B*)fsn_viewer);
532
533         for (;;) {
534                 if(((*(UH*)data) & 0xFF80) == 0xFF80) {
535                         lseg = (LTADSEG*)(data);
536                         if (lseg->len == 0xffff) {
537                                 data += lseg->llen + 8;
538                                 data_len -= lseg->llen + 8;
539                         } else {
540                                 data += lseg->len + 4;
541                                 data_len -= lseg->len + 4;
542                         }
543                 } else {
544                         break;
545                 }
546         }
547
548         is_bbs = bchan_is_bbs_url(data, data_len);
549         if (is_bbs == True) {
550                 ascii_url = NULL;
551                 ascii_url_len = 0;
552                 err = sjstring_appendconvartingTCstring(&ascii_url, &ascii_url_len, (TC*)data, data_len/2);
553                 if (err < 0) {
554                         return 0;
555                 }
556
557                 bchan_separete_bbs_url(ascii_url, ascii_url_len, &host, &host_len, &board, &board_len, &thread, &thread_len);
558                 err = bchan_createviewervobj(title, fsn_viewer, fsn_viewer_len, host, host_len, board, board_len, thread, thread_len, vseg, lnk);
559                 if (err < 0) {
560                         return 0;
561                 }
562
563                 free(ascii_url);
564         } else {
565                 err = bchan_createvobj_allocate_url(data, data_len, &url, &url_len);
566                 if (err < 0) {
567                         DP_ER("bchan_createvobj_allocate_url", err);
568                         return err;
569                 }
570
571                 err = bchan_createbbbvobj(fsn_bbb, fsn_bbb_len, fsn_texedit, fsn_texedit_len, (UB*)url, url_len*2, vseg, lnk);
572                 if (err < 0) {
573                         DP_ER("bchan_createbbbvobj", err);
574                         return err;
575                 }
576
577                 free(url);
578         }
579
580         return BCHAN_CREATEVOBJ_CREATED;
581 }
582
583 LOCAL VOID bchan_scrollbyahcnor(bchan_t *bchan, UB *data, W data_len)
584 {
585         LTADSEG *lseg;
586         W num, len;
587         TC *str;
588         W fnd;
589         W cl, ct, cr, cb, tl, tt, tr, tb;
590
591         for (;;) {
592                 if(((*(UH*)data) & 0xFF80) == 0xFF80) {
593                         lseg = (LTADSEG*)(data);
594                         if (lseg->len == 0xffff) {
595                                 data += lseg->llen + 8;
596                                 data_len -= lseg->llen + 8;
597                         } else {
598                                 data += lseg->len + 4;
599                                 data_len -= lseg->len + 4;
600                         }
601                 } else {
602                         break;
603                 }
604         }
605
606         str = (TC*)data;
607         len = data_len;
608
609         num = tc_atoi(str + 2);
610         DP(("num = %d\n", num));
611
612         fnd = datlayout_getthreadviewrectbyindex(bchan->layout, num - 1, &tl, &tt, &tr, &tb);
613         if (fnd == 0) {
614                 return;
615         }
616         datdraw_getviewrect(bchan->draw, &cl, &ct, &cr, &cb);
617         datwindow_scrollbyvalue(bchan->window, 0 - cl, tt - ct);
618 }
619
620 LOCAL VOID bchan_layout_res_updateattrbyindex(datlayout_res_t *layout_res, UW attr, COLOR color)
621 {
622         if ((attr & DATCACHE_RESINDEXDATA_FLAG_NG) != 0) {
623                 datlayout_res_enableindexNG(layout_res);
624         } else {
625                 datlayout_res_disableindexNG(layout_res);
626         }
627         if ((attr & DATCACHE_RESINDEXDATA_FLAG_COLOR) != 0) {
628                 datlayout_res_enableindexcolor(layout_res);
629         } else {
630                 datlayout_res_disableindexcolor(layout_res);
631         }
632         datlayout_res_setindexcolor(layout_res, color);
633 }
634
635 LOCAL VOID bchan_layout_res_updateattrbyid(datlayout_res_t *layout_res, UW attr, COLOR color)
636 {
637         if ((attr & DATCACHE_RESIDDATA_FLAG_NG) != 0) {
638                 datlayout_res_enableidNG(layout_res);
639         } else {
640                 datlayout_res_disableidNG(layout_res);
641         }
642         if ((attr & DATCACHE_RESIDDATA_FLAG_COLOR) != 0) {
643                 datlayout_res_enableidcolor(layout_res);
644         } else {
645                 datlayout_res_disableidcolor(layout_res);
646         }
647         datlayout_res_setidcolor(layout_res, color);
648 }
649
650 LOCAL VOID bchan_butdn_updatedisplayinfobyindex(bchan_t *bchan, W resindex, UW attr, COLOR color)
651 {
652         datlayout_res_t *layout_res;
653         Bool found;
654
655         found = datlayoutarray_getresbyindex(bchan->layoutarray, resindex, &layout_res);
656         if (found == False) {
657                 return;
658         }
659
660         bchan_layout_res_updateattrbyindex(layout_res, attr, color);
661
662         wreq_dsp(bchan->wid);
663 }
664
665 LOCAL VOID bchan_butdn_updatedisplayinfobyid(bchan_t *bchan, TC *id, W id_len, UW attr, COLOR color)
666 {
667         datlayout_res_t *layout_res;
668         W i, len;
669         Bool found, issame;
670
671         len = datlayoutarray_length(bchan->layoutarray);
672         for (i = 0; i < len; i++) {
673                 found = datlayoutarray_getresbyindex(bchan->layoutarray, i, &layout_res);
674                 if (found == False) {
675                         break;
676                 }
677
678                 issame = datlayout_res_issameid(layout_res, id, id_len);
679                 if (issame != True) {
680                         continue;
681                 }
682
683                 bchan_layout_res_updateattrbyid(layout_res, attr, color);
684         }
685
686         wreq_dsp(bchan->wid);
687 }
688
689 LOCAL VOID bchan_butdn_pressnumber(bchan_t *bchan, WEVENT *wev, W resindex)
690 {
691         W size, err;
692         PNT pos;
693         B *data;
694         COLOR color;
695         UW attr = 0;
696
697         DP(("press DATDRAW_FINDACTION_TYPE_NUMBER: %d\n", resindex + 1));
698         err = datcache_searchresindexdata(bchan->cache, resindex, &attr, &color);
699         if (err == DATCACHE_SEARCHRESINDEXDATA_FOUND) {
700                 if ((attr & DATCACHE_RESINDEXDATA_FLAG_NG) != 0) {
701                         err = bchan_resnumbermenu_setngselected(&bchan->resnumbermenu, True);
702                 } else {
703                         err = bchan_resnumbermenu_setngselected(&bchan->resnumbermenu, False);
704                 }
705         } else {
706                 attr = 0;
707                 err = bchan_resnumbermenu_setngselected(&bchan->resnumbermenu, False);
708         }
709
710         pos.x = wev->s.pos.x;
711         pos.y = wev->s.pos.y;
712         gcnv_abs(bchan->gid, &pos);
713         err = bchan_resnumbermenu_select(&bchan->resnumbermenu, pos);
714         if (err == BCHAN_RESNUMBERMENU_SELECT_PUSHTRAY) {
715                 size = datlayout_resindextotraytextdata(bchan->layout, resindex, NULL, 0);
716                 data = malloc(size);
717                 if (data == NULL) {
718                         return;
719                 }
720                 datlayout_resindextotraytextdata(bchan->layout, resindex, data, size);
721                 bchan_pushstringtotray((TC*)data, size/2);
722                 free(data);
723         } if (err == BCHAN_RESNUMBERMENU_SELECT_NG) {
724                 if ((attr & DATCACHE_RESINDEXDATA_FLAG_NG) != 0) {
725                         datcache_removeresindexdata(bchan->cache, resindex);
726                         attr = 0;
727                 } else {
728                         err = datcache_addresindexdata(bchan->cache, resindex, DATCACHE_RESINDEXDATA_FLAG_NG, 0x10000000);
729                         attr = DATCACHE_RESINDEXDATA_FLAG_NG;
730                 }
731                 bchan_butdn_updatedisplayinfobyindex(bchan, resindex, attr, color);
732         }
733 }
734
735 LOCAL VOID bchan_butdn_pressresheaderid(bchan_t *bchan, WEVENT *wev, W resindex)
736 {
737         W id_len, size, err;
738         TC *id;
739         PNT pos;
740         B *data;
741         COLOR color;
742         UW attr = 0;
743
744         DP(("press DATDRAW_FINDACTION_TYPE_ID\n"));
745
746         datlayout_getidfromindex(bchan->layout, resindex, &id, &id_len);
747         if (id == NULL) {
748                 DP(("      id is not exist\n"));
749                 return;
750         }
751
752         err = datcache_searchresiddata(bchan->cache, id, id_len, &attr, &color);
753         if (err == DATCACHE_SEARCHRESIDDATA_FOUND) {
754                 if ((attr & DATCACHE_RESIDDATA_FLAG_NG) != 0) {
755                         err = bchan_residmenu_setngselected(&bchan->residmenu, True);
756                 } else {
757                         err = bchan_residmenu_setngselected(&bchan->residmenu, False);
758                 }
759         } else {
760                 attr = 0;
761                 err = bchan_residmenu_setngselected(&bchan->residmenu, False);
762         }
763
764         pos.x = wev->s.pos.x;
765         pos.y = wev->s.pos.y;
766         gcnv_abs(bchan->gid, &pos);
767         err = bchan_residmenu_select(&bchan->residmenu, pos);
768         if (err == BCHAN_RESIDMENU_SELECT_PUSHTRAY) {
769                 size = datlayout_idtotraytextdata(bchan->layout, id, id_len, NULL, 0);
770                 data = malloc(size);
771                 if (data == NULL) {
772                         return;
773                 }
774                 datlayout_idtotraytextdata(bchan->layout, id, id_len, data, size);
775                 bchan_pushstringtotray((TC*)data, size/2);
776                 free(data);
777         } if (err == BCHAN_RESIDMENU_SELECT_NG) {
778                 if ((attr & DATCACHE_RESIDDATA_FLAG_NG) != 0) {
779                         datcache_removeresiddata(bchan->cache, id, id_len);
780                         attr = 0;
781                 } else {
782                         err = datcache_addresiddata(bchan->cache, id, id_len, DATCACHE_RESIDDATA_FLAG_NG, 0x10000000);
783                         attr = DATCACHE_RESIDDATA_FLAG_NG;
784                 }
785                 bchan_butdn_updatedisplayinfobyid(bchan, id, id_len, attr, color);
786         }
787 }
788
789 LOCAL VOID bchan_butdn(VP arg, WEVENT *wev)
790 {
791         bchan_t *bchan = (bchan_t*)arg;
792         W fnd, event_type, type, len, dx, dy, err, size, resindex;
793         WID wid_butup;
794         GID gid;
795         RECT r, r0;
796         UB *start;
797         PNT p1, pos;
798         TR_VOBJREC vrec;
799         TRAYREC tr_rec;
800         WEVENT paste_ev;
801         SEL_RGN sel;
802
803         /* TODO: change to same as bchanl's commonwindow */
804         switch (wchk_dck(wev->s.time)) {
805         case    W_CLICK:
806                 fnd = datdraw_findaction(bchan->draw, wev->s.pos, &r, &type, &start, &len, &resindex);
807                 if (fnd == 0) {
808                         return;
809                 }
810                 if (type != DATDRAW_FINDACTION_TYPE_ANCHOR) {
811                         return;
812                 }
813                 bchan_scrollbyahcnor(bchan, start, len);
814                 return;
815         case    W_DCLICK:
816         case    W_QPRESS:
817         default:
818                 return;
819         case    W_PRESS:
820         }
821
822         fnd = datdraw_findaction(bchan->draw, wev->s.pos, &r, &type, &start, &len, &resindex);
823         if (fnd == 0) {
824                 return;
825         }
826         if (type == DATDRAW_FINDACTION_TYPE_NUMBER) {
827                 bchan_butdn_pressnumber(bchan, wev, resindex);
828                 return;
829         }
830         if (type == DATDRAW_FINDACTION_TYPE_RESID) {
831                 bchan_butdn_pressresheaderid(bchan, wev, resindex);
832                 return;
833         }
834         if (type != DATDRAW_FINDACTION_TYPE_URL) {
835                 return;
836         }
837
838         gid = wsta_drg(bchan->wid, 0);
839         if (gid < 0) {
840                 DP_ER("wsta_drg error:", gid);
841                 return;
842         }
843
844         gget_fra(gid, &r0);
845         gset_vis(gid, r0);
846
847         dx = r.c.left - wev->s.pos.x;
848         dy = r.c.top - wev->s.pos.y;
849
850         p1 = wev->s.pos;
851         sel.sts = 0;
852         sel.rgn.r.c.left = r.c.left;
853         sel.rgn.r.c.top = r.c.top;
854         sel.rgn.r.c.right = r.c.right;
855         sel.rgn.r.c.bottom = r.c.bottom;
856         adsp_sel(gid, &sel, 1);
857
858         gset_ptr(PS_GRIP, NULL, -1, -1);
859         for (;;) {
860                 event_type = wget_drg(&pos, wev);
861                 if (event_type == EV_BUTUP) {
862                         wid_butup = wev->s.wid;
863                         break;
864                 }
865                 if (event_type != EV_NULL) {
866                         continue;
867                 }
868                 if ((pos.x == p1.x)&&(pos.y == p1.y)) {
869                         continue;
870                 }
871                 adsp_sel(gid, &sel, 0);
872                 sel.rgn.r.c.left += pos.x - p1.x;
873                 sel.rgn.r.c.top += pos.y - p1.y;
874                 sel.rgn.r.c.right += pos.x - p1.x;
875                 sel.rgn.r.c.bottom += pos.y - p1.y;
876                 adsp_sel(gid, &sel, 1);
877                 p1 = pos;
878         }
879         gset_ptr(PS_SELECT, NULL, -1, -1);
880         adsp_sel(gid, &sel, 0);
881         wend_drg();
882
883         /* BUTUP on self window or no window or system message panel */
884         if ((wid_butup == bchan->wid)||(wid_butup == 0)||(wid_butup == -1)) {
885                 return;
886         }
887
888         err = oget_vob(-wid_butup, &vrec.vlnk, NULL, 0, &size);
889         if (err < 0) {
890                 return;
891         }
892
893         err = bchan_createvobj(bchan, start, len, &vrec.vseg, (LINK*)&vrec.vlnk);
894         if (err < 0) {
895                 DP_ER("bchan_createvobj error", err);
896                 return;
897         }
898         if (err == BCHAN_CREATEVOBJ_CANCELED) {
899                 DP(("canceled\n"));
900                 return;
901         }
902
903         tr_rec.id = TR_VOBJ;
904         tr_rec.len = sizeof(TR_VOBJREC);
905         tr_rec.dt = (B*)&vrec;
906         err = tset_dat(&tr_rec, 1);
907         if (err < 0) {
908                 err = del_fil(NULL, (LINK*)&vrec.vlnk, 0);
909                 if (err < 0) {
910                         DP_ER("error del_fil:", err);
911                 }
912                 return;
913         }
914
915         paste_ev.r.type = EV_REQUEST;
916         paste_ev.r.r.p.rightbot.x = wev->s.pos.x + dx;
917         paste_ev.r.r.p.rightbot.y = wev->s.pos.y + dy;
918         paste_ev.r.cmd = W_PASTE;
919         paste_ev.r.wid = wid_butup;
920         err = wsnd_evt(&paste_ev);
921         if (err < 0) {
922                 tset_dat(NULL, 0);
923                 err = del_fil(NULL, (LINK*)&vrec.vlnk, 0);
924                 if (err < 0) {
925                         DP_ER("error del_fil:", err);
926                 }
927                 return;
928         }
929         err = wwai_rsp(NULL, W_PASTE, 60000);
930         if (err != W_ACK) {
931                 tset_dat(NULL, 0);
932                 err = del_fil(NULL, (LINK*)&vrec.vlnk, 0);
933                 if (err < 0) {
934                         DP_ER("error del_fil:", err);
935                 }
936         }
937
938         wswi_wnd(wid_butup, NULL);
939
940         /* temporary fix. to fix canceling layout. */
941         req_tmg(0, BCHAN_MESSAGE_RETRIEVER_UPDATE);
942 }
943
944 LOCAL W bchan_paste(VP arg, WEVENT *wev)
945 {
946         bchan_t *bchan = (bchan_t*)arg;
947         W err;
948         postresdata_t *post = NULL;
949
950         err = poptray_gettraydata(&post);
951         if (err < 0) {
952                 return 1; /* NACK */
953         }
954
955         wev->r.r.p.rightbot.x = 0x8000;
956         wev->r.r.p.rightbot.y = 0x8000;
957
958         if (post != NULL) {
959                 if (bchan->resdata != NULL) {
960                         postresdata_delete(bchan->resdata);
961                 }
962                 bchan->resdata = post;
963                 cfrmwindow_setpostresdata(bchan->confirm, post);
964                 bchan->request_confirm_open = True;
965         }
966
967         return 0; /* ACK */
968 }
969
970 LOCAL VOID bchan_recieveclose(VP arg, W send)
971 {
972         bchan_t *bchan = (bchan_t*)arg;
973         TC *dmsg = NULL;
974         W dmsg_len, err;
975
976         DP(("bchan_recieveclose = %d\n", send));
977         if (send == 1) {
978                 bchan_hmistate_updateptrstyle(&bchan->hmistate, PS_BUSY);
979                 err = ressubmit_respost(bchan->submit, bchan->resdata, &dmsg, &dmsg_len);
980                 bchan_hmistate_updateptrstyle(&bchan->hmistate, PS_SELECT);
981                 switch (err) {
982                 case RESSUBMIT_RESPOST_SUCCEED:
983                         pdsp_msg(bchan->hmistate.msg_postsucceed);
984                         break;
985                 case RESSUBMIT_RESPOST_DENIED:
986                         bchan_hmistate_display_postdenied(&bchan->hmistate, dmsg, dmsg_len);
987                         break;
988                 case RESSUBMIT_RESPOST_ERROR_CLIENT:
989                 case RESSUBMIT_RESPOST_ERROR_STATUS:
990                 case RESSUBMIT_RESPOST_ERROR_CONTENT:
991                 default:
992                         pdsp_msg(bchan->hmistate.msg_posterror);
993                         break;
994                 }
995                 if (dmsg != NULL) {
996                         free(dmsg);
997                 }
998         }
999 }
1000
1001 LOCAL VOID bchan_hmistate_initialize(bchan_hmistate_t *hmistate)
1002 {
1003         W err;
1004
1005         hmistate->ptr = PS_SELECT;
1006
1007         err = dget_dtp(TEXT_DATA, BCHAN_DBX_MSGTEXT_RETRIEVING, (void**)&hmistate->msg_retrieving);
1008         if (err < 0) {
1009                 DP_ER("dget_dtp: message retrieving error", err);
1010                 hmistate->msg_retrieving = NULL;
1011         }
1012         err = dget_dtp(TEXT_DATA, BCHAN_DBX_MSGTEXT_NOTMODIFIED, (void**)&hmistate->msg_notmodified);
1013         if (err < 0) {
1014                 DP_ER("dget_dtp: message not modified error", err);
1015                 hmistate->msg_notmodified = NULL;
1016         }
1017         err = dget_dtp(TEXT_DATA, BCHAN_DBX_MSGTEXT_NONAUTHORITATIVE, (void**)&hmistate->msg_nonauthoritative);
1018         if (err < 0) {
1019                 DP_ER("dget_dtp: message non-authoritative error", err);
1020                 hmistate->msg_nonauthoritative = NULL;
1021         }
1022         err = dget_dtp(TEXT_DATA, BCHAN_DBX_MSGTEXT_POSTSUCCEED, (void**)&hmistate->msg_postsucceed);
1023         if (err < 0) {
1024                 DP_ER("dget_dtp: message post succeed error", err);
1025                 hmistate->msg_postsucceed = NULL;
1026         }
1027         err = dget_dtp(TEXT_DATA, BCHAN_DBX_MSGTEXT_POSTDENIED, (void**)&hmistate->msg_postdenied);
1028         if (err < 0) {
1029                 DP_ER("dget_dtp: message post denied error", err);
1030                 hmistate->msg_postdenied = NULL;
1031         }
1032         err = dget_dtp(TEXT_DATA, BCHAN_DBX_MSGTEXT_POSTERROR, (void**)&hmistate->msg_posterror);
1033         if (err < 0) {
1034                 DP_ER("dget_dtp: message post error error", err);
1035                 hmistate->msg_posterror = NULL;
1036         }
1037         err = dget_dtp(TEXT_DATA, BCHAN_DBX_MSGTEXT_NETWORKERROR, (void**)&hmistate->msg_networkerror);
1038         if (err < 0) {
1039                 DP_ER("dget_dtp: message network error error", err);
1040                 hmistate->msg_networkerror = NULL;
1041         }
1042         err = dget_dtp(TEXT_DATA, BCHAN_DBX_MSGTEXT_NOTFOUND, (void**)&hmistate->msg_notfound);
1043         if (err < 0) {
1044                 DP_ER("dget_dtp: message notfound error", err);
1045                 hmistate->msg_notfound = NULL;
1046         }
1047         err = dget_dtp(TEXT_DATA, BCHAN_DBX_MSGTEXT_CANTRETRIEVE, (void**)&hmistate->msg_cantretrieve);
1048         if (err < 0) {
1049                 DP_ER("dget_dtp: message cantretrieve error", err);
1050                 hmistate->msg_cantretrieve = NULL;
1051         }
1052 }
1053
1054 LOCAL W bchan_initialize(bchan_t *bchan, VID vid, WID wid, W exectype)
1055 {
1056         GID gid;
1057         datcache_t *cache;
1058         datparser_t *parser;
1059         datlayoutarray_t *layoutarray;
1060         datlayout_t *layout;
1061         datdraw_t *draw;
1062         datwindow_t *window;
1063         datretriever_t *retriever;
1064         ressubmit_t *submit;
1065         cfrmwindow_t *confirm;
1066         MENUITEM *mnitem_dbx, *mnitem;
1067         MNID mnid;
1068         static  RECT    r0 = {{200, 80, 500+7, 230+30}};
1069         RECT w_work;
1070         W len, err;
1071
1072         gid = wget_gid(wid);
1073
1074         cache = datcache_new(vid);
1075         if (cache == NULL) {
1076                 DP_ER("datcache_new error", 0);
1077                 goto error_cache;
1078         }
1079         parser = datparser_new(cache);
1080         if (parser == NULL) {
1081                 DP_ER("datparser_new error", 0);
1082                 goto error_parser;
1083         }
1084         layoutarray = datlayoutarray_new();
1085         if (layoutarray == NULL) {
1086                 DP_ER("datlayoutarray_new error", 0);
1087                 goto error_layoutarray;
1088         }
1089         /* TODO: style initialize. */
1090         layout = datlayout_new(gid, &bchan->style, layoutarray);
1091         if (layout == NULL) {
1092                 DP_ER("datlayout_new error", 0);
1093                 goto error_layout;
1094         }
1095         draw = datdraw_new(gid, &bchan->style, layoutarray);
1096         if (draw == NULL) {
1097                 DP_ER("datdraw_new error", 0);
1098                 goto error_draw;
1099         }
1100         window = datwindow_new(wid, bchan_scroll, bchan_draw, bchan_resize, bchan_close, bchan_butdn, bchan_paste, bchan);
1101         if (window == NULL) {
1102                 DP_ER("datwindow_new error", 0);
1103                 goto error_window;
1104         }
1105         retriever = datretriever_new(cache);
1106         if (retriever == NULL) {
1107                 DP_ER("datretriever_new error", 0);
1108                 goto error_retriever;
1109         }
1110         submit = ressubmit_new(cache);
1111         if (submit == NULL) {
1112                 DP_ER("ressubmit_new error", 0);
1113                 goto error_submit;
1114         }
1115         confirm = cfrmwindow_new(&r0, wid, bchan_recieveclose, bchan, BCHAN_DBX_TEXT_CONFIRM_TITLE, BCHAN_DBX_MS_CONFIRM_POST, BCHAN_DBX_MS_CONFIRM_CANCEL);
1116         if (confirm == NULL) {
1117                 DP_ER("dfrmwindow_new error", 0);
1118                 goto error_confirm;
1119         }
1120         err = dget_dtp(8, BCHAN_DBX_MENU_TEST, (void**)&mnitem_dbx);
1121         if (err < 0) {
1122                 DP_ER("dget_dtp error:", err);
1123                 goto error_dget_dtp;
1124         }
1125         len = dget_siz((B*)mnitem_dbx);
1126         mnitem = malloc(len);
1127         if (mnitem == NULL) {
1128                 DP_ER("mallod error", err);
1129                 goto error_mnitem;
1130         }
1131         memcpy(mnitem, mnitem_dbx, len);
1132         mnid = mcre_men(BCHAN_MENU_WINDOW+2, mnitem, NULL);
1133         if (mnid < 0) {
1134                 DP_ER("mcre_men error", mnid);
1135                 goto error_mcre_men;
1136         }
1137         err = bchan_resnumbermenu_initialize(&bchan->resnumbermenu, BCHAN_DBX_GMENU_RESNUMBER);
1138         if (err < 0) {
1139                 DP_ER("bchan_resnumbermenu_initialize", err);
1140                 goto error_resnumbermenu_initialize;
1141         }
1142         err = bchan_residmenu_initialize(&bchan->residmenu, BCHAN_DBX_GMENU_RESID);
1143         if (err < 0) {
1144                 DP_ER("bchan_residmenu_initialize", err);
1145                 goto error_residmenu_initialize;
1146         }
1147
1148         bchan_hmistate_initialize(&bchan->hmistate);
1149
1150         wget_wrk(wid, &w_work);
1151         datdraw_setviewrect(draw, 0, 0, w_work.c.right, w_work.c.bottom);
1152         datwindow_setworkrect(window, 0, 0, w_work.c.right, w_work.c.bottom);
1153
1154         if (exectype == EXECREQ) {
1155                 osta_prc(vid, wid);
1156         }
1157
1158         bchan->wid = wid;
1159         bchan->gid = gid;
1160         bchan->taskid = -1;
1161         bchan->mbfid = -1;
1162         bchan->vid = vid;
1163         bchan->exectype = exectype;
1164         bchan->request_confirm_open = False;
1165         bchan->cache = cache;
1166         bchan->parser = parser;
1167         bchan->layoutarray = layoutarray;
1168         bchan->layout = layout;
1169         bchan->draw = draw;
1170         bchan->window = window;
1171         bchan->retriever = retriever;
1172         bchan->submit = submit;
1173         bchan->confirm = confirm;
1174         bchan->resdata = NULL;
1175         bchan->mnitem = mnitem;
1176         bchan->mnid = mnid;
1177
1178         return 0;
1179
1180 error_residmenu_initialize:
1181         bchan_resnumbermenu_finalize(&bchan->resnumbermenu);
1182 error_resnumbermenu_initialize:
1183         mdel_men(mnid);
1184 error_mcre_men:
1185         free(mnitem);
1186 error_mnitem:
1187 error_dget_dtp:
1188         cfrmwindow_delete(confirm);
1189 error_confirm:
1190         ressubmit_delete(submit);
1191 error_submit:
1192         datretriever_delete(retriever);
1193 error_retriever:
1194         datwindow_delete(window);
1195 error_window:
1196         datdraw_delete(draw);
1197 error_draw:
1198         datlayout_delete(layout);
1199 error_layout:
1200         datlayoutarray_delete(layoutarray);
1201 error_layoutarray:
1202         datparser_delete(parser);
1203 error_parser:
1204         datcache_delete(cache);
1205 error_cache:
1206         return -1; /* TODO */
1207 }
1208
1209 #define BCHAN_LAYOUT_MAXBLOCKING 20
1210
1211 LOCAL W bchan_layout_appendres(bchan_t *bchan, datparser_res_t *res)
1212 {
1213         W err, ret, index, id_len;
1214         TC *id;
1215         UW attr;
1216         COLOR color;
1217         Bool found;
1218         datlayout_res_t *layout_res;
1219
1220         err = datlayout_appendres(bchan->layout, res);
1221         if (err < 0) {
1222                 return err;
1223         }
1224
1225         found = datlayoutarray_getreslast(bchan->layoutarray, &layout_res);
1226         if (found == False) {
1227                 return 0;
1228         }
1229         index = datlayoutarray_length(bchan->layoutarray) - 1;
1230
1231         datlayout_res_getid(layout_res, &id, &id_len);
1232         ret = datcache_searchresiddata(bchan->cache, id, id_len, &attr, &color);
1233         if (ret == DATCACHE_SEARCHRESIDDATA_FOUND) {
1234                 bchan_layout_res_updateattrbyid(layout_res, attr, color);
1235         }
1236         ret = datcache_searchresindexdata(bchan->cache, index, &attr, &color);
1237         if (ret == DATCACHE_SEARCHRESINDEXDATA_FOUND) {
1238                 bchan_layout_res_updateattrbyindex(layout_res, attr, color);
1239         }
1240
1241         return 0;
1242 }
1243
1244 LOCAL VOID bchan_relayout(bchan_t *bchan)
1245 {
1246         datparser_res_t *res = NULL;
1247         RECT w_work;
1248         W i, err, l, t, r, b;
1249         TC *title;
1250
1251         datlayout_clear(bchan->layout);
1252         datparser_clear(bchan->parser);
1253
1254         for (i=0;;i++) {
1255                 if (i >= BCHAN_LAYOUT_MAXBLOCKING) {
1256                         req_tmg(0, BCHAN_MESSAGE_RETRIEVER_UPDATE);
1257                         break;
1258                 }
1259
1260                 err = datparser_getnextres(bchan->parser, &res);
1261                 if (err != 1) {
1262                         break;
1263                 }
1264                 if (res == NULL) {
1265                         break;
1266                 }
1267                 bchan_layout_appendres(bchan, res);
1268         }
1269
1270         wget_wrk(bchan->wid, &w_work);
1271
1272         datlayout_getdrawrect(bchan->layout, &l, &t, &r, &b);
1273         datwindow_setdrawrect(bchan->window, l, t, r, b);
1274
1275         title = datlayout_gettitle(bchan->layout);
1276         wset_tit(bchan->wid, -1, title, 0);
1277
1278         wreq_dsp(bchan->wid);
1279 }
1280
1281 LOCAL VOID bchan_update(bchan_t *bchan)
1282 {
1283         datparser_res_t *res = NULL;
1284         RECT w_work;
1285         W i, err, l, t, r, b;
1286
1287         for (i=0;;i++) {
1288                 if (i >= BCHAN_LAYOUT_MAXBLOCKING) {
1289                         req_tmg(0, BCHAN_MESSAGE_RETRIEVER_UPDATE);
1290                         break;
1291                 }
1292
1293                 err = datparser_getnextres(bchan->parser, &res);
1294                 if (err != 1) {
1295                         break;
1296                 }
1297                 if (res == NULL) {
1298                         break;
1299                 }
1300                 bchan_layout_appendres(bchan, res);
1301         }
1302
1303         wget_wrk(bchan->wid, &w_work);
1304
1305         datlayout_getdrawrect(bchan->layout, &l, &t, &r, &b);
1306         datwindow_setdrawrect(bchan->window, l, t, r, b);
1307
1308         wreq_dsp(bchan->wid);
1309 }
1310
1311 LOCAL VOID bchan_retriever_task(W arg)
1312 {
1313         bchan_t *bchan;
1314         datretriever_t *retr;
1315         W msg,err;
1316
1317         bchan = (bchan_t*)arg;
1318         retr = bchan->retriever;
1319
1320         for (;;) {
1321                 DP(("before rcv_mbf %d\n", bchan->mbfid));
1322                 err = rcv_mbf(bchan->mbfid, (VP)&msg, T_FOREVER);
1323                 DP_ER("rcv_mbf", err);
1324                 if (err != 4) {
1325                         continue;
1326                 }
1327
1328                 err = datretriever_request(retr);
1329
1330                 switch (err) {
1331                 case DATRETRIEVER_REQUEST_ALLRELOAD:
1332                         req_tmg(0, BCHAN_MESSAGE_RETRIEVER_RELAYOUT);
1333                         break;
1334                 case DATRETRIEVER_REQUEST_PARTIAL_CONTENT:
1335                         req_tmg(0, BCHAN_MESSAGE_RETRIEVER_UPDATE);
1336                         break;
1337                 case DATRETRIEVER_REQUEST_NOT_MODIFIED:
1338                         req_tmg(0, BCHAN_MESSAGE_RETRIEVER_NOTMODIFIED);
1339                         break;
1340                 case DATRETRIEVER_REQUEST_NON_AUTHORITATIVE:
1341                         req_tmg(0, BCHAN_MESSAGE_RETRIEVER_NONAUTHORITATIVE);
1342                         break;
1343                 case DATRETRIEVER_REQUEST_NOT_FOUND:
1344                         req_tmg(0, BCHAN_MESSAGE_RETRIEVER_NOTFOUND);
1345                         break;
1346                 case DATRETRIEVER_REQUEST_UNEXPECTED:
1347                 default:
1348                         DP_ER("datretreiver_request error:",err);
1349                         DATRETRIEVER_DP(retr);
1350                         req_tmg(0, BCHAN_MESSAGE_RETRIEVER_ERROR);
1351                         break;
1352                 }
1353         }
1354
1355         ext_tsk();
1356 }
1357
1358 LOCAL W bchan_prepare_network(bchan_t *bchan)
1359 {
1360         if (bchan->retriever == NULL) {
1361                 return 0;
1362         }
1363         if (datretriever_isenablenetwork(bchan->retriever) == False) {
1364                 return 0;
1365         }
1366
1367         bchan->mbfid = cre_mbf(sizeof(W), sizeof(W), DELEXIT);
1368         if (bchan->mbfid < 0) {
1369                 DP_ER("cre_mbf error:", bchan->mbfid);
1370                 return -1;
1371         }
1372         bchan->taskid = cre_tsk(bchan_retriever_task, -1, (W)bchan);
1373         if (bchan->taskid < 0) {
1374                 del_mbf(bchan->mbfid);
1375                 bchan->mbfid = -1;
1376                 DP_ER("cre_tsk error:", bchan->taskid);
1377                 return -1;
1378         }
1379
1380         return 0;
1381 }
1382
1383 LOCAL W bchan_networkrequest(bchan_t *bchan)
1384 {
1385         W msg = 1, err;
1386         static UW lastrequest = 0;
1387         UW etime;
1388
1389         if (datretriever_isenablenetwork(bchan->retriever) == False) {
1390                 pdsp_msg(bchan->hmistate.msg_cantretrieve);
1391                 return 0;
1392         }
1393         if (bchan->mbfid < 0) {
1394                 return 0;
1395         }
1396
1397         err = get_etm(&etime);
1398         if (err < 0) {
1399                 DP_ER("get_etm error:", err);
1400                 return err;
1401         }
1402         if (lastrequest + 10000 > etime) {
1403                 return 0;
1404         }
1405         lastrequest = etime;
1406
1407         err = snd_mbf(bchan->mbfid, &msg, sizeof(W), T_FOREVER);
1408         if (err < 0) {
1409                 DP_ER("snd_mbf error:", err);
1410                 return err;
1411         }
1412
1413         bchan_hmistate_updateptrstyle(&bchan->hmistate, PS_BUSY);
1414         pdsp_msg(bchan->hmistate.msg_retrieving);
1415
1416         return 0;
1417 }
1418
1419 LOCAL VOID keydwn(bchan_t *bchan, UH keycode, TC ch)
1420 {
1421         W l,t,r,b,l1,t1,r1,b1,scr;
1422
1423         switch (ch) {
1424         case KC_CC_U:
1425                 datdraw_getviewrect(bchan->draw, &l, &t, &r, &b);
1426                 if (t < 16) {
1427                         scr = -t;
1428                 } else {
1429                         scr = -16;
1430                 }
1431                 datwindow_scrollbyvalue(bchan->window, 0, scr);
1432                 break;
1433         case KC_CC_D:
1434                 datdraw_getviewrect(bchan->draw, &l, &t, &r, &b);
1435                 datlayout_getdrawrect(bchan->layout, &l1, &t1, &r1, &b1);
1436                 if (b + 16 > b1) {
1437                         scr = b1 - b;
1438                 } else {
1439                         scr = 16;
1440                 }
1441                 if (scr > 0) {
1442                         datwindow_scrollbyvalue(bchan->window, 0, scr);
1443                 }
1444                 break;
1445         case KC_CC_R:
1446                 datdraw_getviewrect(bchan->draw, &l, &t, &r, &b);
1447                 datlayout_getdrawrect(bchan->layout, &l1, &t1, &r1, &b1);
1448                 if (r + 16 > r1) {
1449                         scr = r1 - r;
1450                 } else {
1451                         scr = 16;
1452                 }
1453                 if (scr > 0) {
1454                         datwindow_scrollbyvalue(bchan->window, scr, 0);
1455                 }
1456                 break;
1457         case KC_CC_L:
1458                 datdraw_getviewrect(bchan->draw, &l, &t, &r, &b);
1459                 if (l < 16) {
1460                         scr = -l;
1461                 } else {
1462                         scr = -16;
1463                 }
1464                 datwindow_scrollbyvalue(bchan->window, scr, 0);
1465                 break;
1466         case KC_PG_U:
1467                 datdraw_getviewrect(bchan->draw, &l, &t, &r, &b);
1468                 if (t < b - t) {
1469                         scr = -t;
1470                 } else {
1471                         scr = - (b - t);
1472                 }
1473                 datwindow_scrollbyvalue(bchan->window, 0, scr);
1474                 break;
1475         case KC_PG_D:
1476                 datdraw_getviewrect(bchan->draw, &l, &t, &r, &b);
1477                 datlayout_getdrawrect(bchan->layout, &l1, &t1, &r1, &b1);
1478                 if (b + (b - t) > b1) {
1479                         scr = b1 - b;
1480                 } else {
1481                         scr = (b - t);
1482                 }
1483                 if (scr > 0) {
1484                         datwindow_scrollbyvalue(bchan->window, 0, scr);
1485                 }
1486                 break;
1487         case KC_PG_R:
1488                 datdraw_getviewrect(bchan->draw, &l, &t, &r, &b);
1489                 datlayout_getdrawrect(bchan->layout, &l1, &t1, &r1, &b1);
1490                 if (r + (r - l) > r1) {
1491                         scr = r1 - r;
1492                 } else {
1493                         scr = (r - l);
1494                 }
1495                 if (scr > 0) {
1496                         datwindow_scrollbyvalue(bchan->window, scr, 0);
1497                 }
1498                 break;
1499         case KC_PG_L:
1500                 datdraw_getviewrect(bchan->draw, &l, &t, &r, &b);
1501                 if (l < r - l) {
1502                         scr = -l;
1503                 } else {
1504                         scr = - (r - l);
1505                 }
1506                 datwindow_scrollbyvalue(bchan->window, scr, 0);
1507                 break;
1508         case KC_PF5:
1509                 bchan_networkrequest(bchan);
1510                 break;
1511         }
1512 }
1513
1514 LOCAL VOID bchan_setupmenu(bchan_t *bchan)
1515 {
1516         TC *str;
1517
1518         /* [Áàºî] -> [¥¹¥ì¥¿¥¤¤ò¥È¥ì¡¼¤ËÊ£¼Ì] */
1519         str = datlayout_gettitle(bchan->layout);
1520         if (str == NULL) {
1521                 mchg_atr(bchan->mnid, (2 << 8)|1, M_INACT);
1522         } else {
1523                 mchg_atr(bchan->mnid, (2 << 8)|1, M_ACT);
1524         }
1525
1526         /* [ɽ¼¨] -> [¥¹¥ì¥Ã¥É¾ðÊó¤òɽ¼¨] */
1527         /* [ÊÔ½¸] -> [¥¹¥ì¥Ã¥É£Õ£Ò£Ì¤ò¥È¥ì¡¼¤ËÊ£¼Ì] */
1528         /* [Áàºî] -> [¥¹¥ì¥Ã¥É¼èÆÀ] */
1529         if (datretriever_isenablenetwork(bchan->retriever) == False) {
1530                 mchg_atr(bchan->mnid, (1 << 8)|2, M_INACT);
1531                 mchg_atr(bchan->mnid, (2 << 8)|2, M_INACT);
1532                 mchg_atr(bchan->mnid, (3 << 8)|1, M_INACT);
1533         } else {
1534                 mchg_atr(bchan->mnid, (1 << 8)|2, M_ACT);
1535                 mchg_atr(bchan->mnid, (2 << 8)|2, M_ACT);
1536                 mchg_atr(bchan->mnid, (3 << 8)|1, M_ACT);
1537         }
1538
1539         wget_dmn(&(bchan->mnitem[BCHAN_MENU_WINDOW].ptr));
1540         mset_itm(bchan->mnid, BCHAN_MENU_WINDOW, bchan->mnitem+BCHAN_MENU_WINDOW);
1541         oget_men(0, NULL, &(bchan->mnitem[BCHAN_MENU_WINDOW+1].ptr), NULL, NULL);
1542         mset_itm(bchan->mnid, BCHAN_MENU_WINDOW+1, bchan->mnitem+BCHAN_MENU_WINDOW+1);
1543 }
1544
1545 LOCAL VOID bchan_selectmenu(bchan_t *bchan, W i)
1546 {
1547         UB *host, *board, *thread;
1548         W host_len, board_len, thread_len;
1549
1550         switch(i >> 8) {
1551         case 0: /* [½ªÎ»] */
1552                 killme(bchan);
1553                 break;
1554         case 1: /* [ɽ¼¨] */
1555                 switch(i & 0xff) {
1556                 case 1: /* [ºÆɽ¼¨] */
1557                         wreq_dsp(bchan->wid);
1558                         break;
1559                 case 2: /* [¥¹¥ì¥Ã¥É¾ðÊó¤òɽ¼¨] */
1560                         datcache_gethost(bchan->cache, &host, &host_len);
1561                         datcache_getborad(bchan->cache, &board, &board_len);
1562                         datcache_getthread(bchan->cache, &thread, &thread_len);
1563                         bchan_panels_threadinfo(host, host_len, board, board_len, thread, thread_len);
1564                         break;
1565                 }
1566                 break;
1567         case 2: /* [Áàºî] */
1568                 switch(i & 0xff) {
1569                 case 1: /* [¥¹¥ì¥¿¥¤¤ò¥È¥ì¡¼¤ËÊ£¼Ì] */
1570                         bchan_pushthreadtitle(bchan);
1571                         break;
1572                 case 2: /* [¥¹¥ì¥Ã¥É£Õ£Ò£Ì¤ò¥È¥ì¡¼¤ËÊ£¼Ì] */
1573                         bchan_pushthreadurl(bchan);
1574                         break;
1575                 }
1576                 break;
1577         case 3: /* [Áàºî] */
1578                 switch(i & 0xff) {
1579                 case 1: /* [¥¹¥ì¥Ã¥É¼èÆÀ] */
1580                         bchan_networkrequest(bchan);
1581                         break;
1582                 }
1583                 break;
1584         case BCHAN_MENU_WINDOW: /* [¥¦¥£¥ó¥É¥¦] */
1585                 wexe_dmn(i);
1586                 break;
1587         case BCHAN_MENU_WINDOW+1: /* [¾®Êª] */
1588             oexe_apg(0, i);
1589                 break;
1590         }
1591         return;
1592 }
1593
1594 LOCAL VOID bchan_popupmenu(bchan_t *bchan, PNT pos)
1595 {
1596         W       i;
1597
1598         bchan_setupmenu(bchan);
1599         gset_ptr(PS_SELECT, NULL, -1, -1);
1600         i = msel_men(bchan->mnid, pos);
1601         if (i > 0) {
1602                 bchan_selectmenu(bchan, i);
1603         }
1604 }
1605
1606 LOCAL VOID receive_message(bchan_t *bchan)
1607 {
1608         MESSAGE msg;
1609         W code, err;
1610
1611     err = rcv_msg(MM_ALL, &msg, sizeof(MESSAGE), WAIT|NOCLR);
1612         if (err >= 0) {
1613                 if (msg.msg_type == MS_TMOUT) { /* should be use other type? */
1614                         code = msg.msg_body.TMOUT.code;
1615                         switch (code) {
1616                         case BCHAN_MESSAGE_RETRIEVER_UPDATE:
1617                                 bchan_update(bchan);
1618                                 bchan_hmistate_updateptrstyle(&bchan->hmistate, PS_SELECT);
1619                                 pdsp_msg(NULL);
1620                                 break;
1621                         case BCHAN_MESSAGE_RETRIEVER_RELAYOUT:
1622                                 bchan_relayout(bchan);
1623                                 bchan_hmistate_updateptrstyle(&bchan->hmistate, PS_SELECT);
1624                                 pdsp_msg(NULL);
1625                                 break;
1626                         case BCHAN_MESSAGE_RETRIEVER_NOTMODIFIED:
1627                                 bchan_hmistate_updateptrstyle(&bchan->hmistate, PS_SELECT);
1628                                 pdsp_msg(bchan->hmistate.msg_notmodified);
1629                                 break;
1630                         case BCHAN_MESSAGE_RETRIEVER_NONAUTHORITATIVE:
1631                                 bchan_hmistate_updateptrstyle(&bchan->hmistate, PS_SELECT);
1632                                 pdsp_msg(bchan->hmistate.msg_nonauthoritative);
1633                                 break;
1634                         case BCHAN_MESSAGE_RETRIEVER_NOTFOUND:
1635                                 bchan_hmistate_updateptrstyle(&bchan->hmistate, PS_SELECT);
1636                                 pdsp_msg(bchan->hmistate.msg_notfound);
1637                                 break;
1638                         case BCHAN_MESSAGE_RETRIEVER_ERROR:
1639                                 bchan_hmistate_updateptrstyle(&bchan->hmistate, PS_SELECT);
1640                                 pdsp_msg(bchan->hmistate.msg_networkerror);
1641                                 break;
1642                         }
1643                 }
1644         }
1645         clr_msg(MM_ALL, MM_ALL);
1646 }
1647
1648 typedef struct _arg {
1649         W ac;
1650         TC **argv;
1651 } CLI_arg;
1652
1653 LOCAL    CLI_arg   MESSAGEtoargv(const MESSAGE *src)
1654 {
1655         W len,i,ac;
1656         TC *str;
1657         TC **argv;
1658         CLI_arg ret;
1659
1660         len = src->msg_size / sizeof(TC);
1661         str = (TC*)(src->msg_body.ANYMSG.msg_str);
1662         ac = 0;
1663         for(i=0;i<len;i++){
1664                 if(str[i] == TK_KSP){
1665                         str[i] = TNULL;
1666                         continue;
1667                 }
1668                 ac++;
1669                 for(;i<len;i++){
1670                         if(str[i] == TK_KSP){
1671                                 i--;
1672                                 break;
1673                         }
1674                 }
1675         }
1676
1677         argv = (TC**)malloc(sizeof(TC*)*ac);
1678
1679         ac = 0;
1680         for(i=0;i<len;i++){
1681                 if(str[i] == TNULL){
1682                         str[i] = TNULL;
1683                         continue;
1684                 }
1685                 argv[ac++] = str+i;
1686                 for(;i<len;i++){
1687                         if(str[i] == TNULL){
1688                                 i--;
1689                                 break;
1690                         }
1691                 }
1692         }
1693
1694         ret.ac = ac;
1695         ret.argv = argv;
1696
1697         return ret;
1698 }
1699
1700 EXPORT  W       MAIN(MESSAGE *msg)
1701 {
1702         static  RECT    r0 = {{100, 100, 650+7, 400+30}};
1703         static  TC      tit0[21];
1704         static  PAT     pat0 = {{
1705                 0,
1706                 16, 16,
1707                 0x10efefef,
1708                 0x10efefef,
1709                 FILL100
1710         }};
1711         W       i, err, size;
1712         WID wid;
1713         VID vid;
1714         LINK lnk, dbx;
1715         CLI_arg arg;
1716         bchan_t bchan;
1717         datwindow_t *window;
1718         VOBJSEG vseg = {
1719                 {{0,0,100,20}},
1720                 16, 16,
1721                 0x10000000, 0x10000000, 0x10FFFFFF, 0x10FFFFFF,
1722                 0
1723         };
1724
1725         err = dopn_dat(NULL);
1726         if (err < 0) {
1727                 ext_prc(0);
1728         }
1729
1730         switch (msg->msg_type) {
1731         case 0: /* CLI */
1732                 arg = MESSAGEtoargv(msg);
1733                 if (arg.ac <= 1) {
1734                         ext_prc(0);
1735                 }
1736                 err = get_lnk(arg.argv[1], &lnk, F_NORM);
1737                 if (err < 0) {
1738                         DP_ER("get_lnk error", err);
1739                         ext_prc(0);
1740                 }
1741                 vid = oreg_vob((VLINK*)&lnk, (VP)&vseg, -1, V_NODISP);
1742                 if (vid < 0) {
1743                         DP_ER("error oreq_vob", vid);
1744                         ext_prc(0);
1745                 }
1746                 err = get_lnk((TC[]){TK_b, TK_c, TK_h, TK_a, TK_n, TK_PROD, TK_d, TK_b, TK_x,TNULL}, &dbx, F_NORM);
1747                 if (err < 0) {
1748                         DP_ER("get_lnk error", err);
1749                         ext_prc(0);
1750                 }
1751                 err = dopn_dat(&dbx);
1752                 if (err < 0) {
1753                         DP_ER("dopn_dat error", err);
1754                         ext_prc(0);
1755                 }
1756                 fil_sts(&lnk, tit0, NULL, NULL);
1757                 break;
1758         case DISPREQ:
1759                 oend_req(((M_DISPREQ*)msg)->vid, -1);
1760                 ext_prc(0);
1761                 break;
1762         case PASTEREQ:
1763                 oend_req(((M_PASTEREQ*)msg)->vid, -1);
1764                 ext_prc(0);
1765                 break;
1766         case EXECREQ:
1767                 if ((((M_EXECREQ*)msg)->mode & 2) != 0) {
1768                         ext_prc(0);
1769                 }
1770                 err = dopn_dat(&((M_EXECREQ*)msg)->self);
1771                 if (err < 0) {
1772                         ext_prc(0);
1773                 }
1774                 fil_sts(&((M_EXECREQ*)msg)->lnk, tit0, NULL, NULL);
1775                 vid = ((M_EXECREQ*)msg)->vid;
1776                 break;
1777         default:
1778                 ext_prc(0);
1779                 break;
1780         }
1781
1782         wid = wopn_wnd(WA_SIZE|WA_HHDL|WA_VHDL|WA_BBAR|WA_RBAR, 0, &r0, NULL, 1, tit0, &pat0, NULL);
1783         if (wid < 0) {
1784                 ext_prc(0);
1785         }
1786         
1787         err = bchan_initialize(&bchan, vid, wid, msg->msg_type);
1788         if (err < 0) {
1789                 DP_ER("bchan_initialize error", err);
1790                 ext_prc(0);
1791         }
1792         window = bchan.window;
1793
1794         err = bchan_prepare_network(&bchan);
1795         if (err < 0) {
1796                 DP_ER("bchan_prepare_network error:", err);
1797                 killme(&bchan);
1798         }
1799
1800         size = datcache_datasize(bchan.cache);
1801         if ((msg->msg_type == EXECREQ)&&(size == 0)) {
1802                 bchan_networkrequest(&bchan);
1803         } else {
1804                 req_tmg(0, BCHAN_MESSAGE_RETRIEVER_RELAYOUT);
1805         }
1806
1807         wreq_dsp(bchan.wid);
1808
1809         /*¥¤¥Ù¥ó¥È¥ë¡¼¥×*/
1810         for (;;) {
1811                 wget_evt(&wev0, WAIT);
1812                 switch (wev0.s.type) {
1813                         case    EV_NULL:
1814                                 if ((wev0.s.wid != wid)
1815                                         &&(cfrmwindow_compairwid(bchan.confirm, wev0.s.wid) == False)) {
1816                                         gset_ptr(bchan.hmistate.ptr, NULL, -1, -1);
1817                                         break;          /*¥¦¥£¥ó¥É¥¦³°*/
1818                                 }
1819                                 if (wev0.s.cmd != W_WORK)
1820                                         break;          /*ºî¶ÈÎΰ賰*/
1821                                 if (wev0.s.stat & ES_CMD)
1822                                         break;  /*Ì¿Îᥭ¡¼¤¬²¡¤µ¤ì¤Æ¤¤¤ë*/
1823                                 gset_ptr(bchan.hmistate.ptr, NULL, -1, -1);
1824                                 break;
1825                         case    EV_REQUEST:
1826                                 if (wev0.g.wid == wid) {
1827                                         datwindow_weventrequest(window, &wev0);
1828                                 }
1829                                 if (cfrmwindow_compairwid(bchan.confirm, wev0.s.wid)) {
1830                                         cfrmwindow_weventrequest(bchan.confirm, &wev0);
1831                                 }
1832                                 break;
1833                         case    EV_RSWITCH:
1834                                 if (wev0.s.wid == wid) {
1835                                         datwindow_weventreswitch(window, &wev0);
1836                                         if (bchan.request_confirm_open == True) {
1837                                                 cfrmwindow_open(bchan.confirm);
1838                                                 bchan.request_confirm_open = False;
1839                                         }
1840                                 }
1841                                 if (cfrmwindow_compairwid(bchan.confirm, wev0.s.wid)) {
1842                                         cfrmwindow_weventreswitch(bchan.confirm, &wev0);
1843                                 }
1844                                 break;
1845                         case    EV_SWITCH:
1846                                 if (wev0.s.wid == wid) {
1847                                         datwindow_weventswitch(window, &wev0);
1848                                         if (bchan.request_confirm_open == True) {
1849                                                 cfrmwindow_open(bchan.confirm);
1850                                                 bchan.request_confirm_open = False;
1851                                         }
1852                                 }
1853                                 if (cfrmwindow_compairwid(bchan.confirm, wev0.s.wid)) {
1854                                         cfrmwindow_weventswitch(bchan.confirm, &wev0);
1855                                 }
1856                                 break;
1857                         case    EV_BUTDWN:
1858                                 if (wev0.g.wid == wid) {
1859                                         datwindow_weventbutdn(window, &wev0);
1860                                 }
1861                                 if (cfrmwindow_compairwid(bchan.confirm, wev0.s.wid)) {
1862                                         cfrmwindow_weventbutdn(bchan.confirm, &wev0);
1863                                 }
1864                                 break;
1865                         case    EV_KEYDWN:
1866                                 if (wev0.s.stat & ES_CMD) {     /*Ì¿Îᥭ¡¼*/
1867                                         bchan_setupmenu(&bchan);
1868                                         i = mfnd_key(bchan.mnid, wev0.e.data.key.code);
1869                                         if (i >= 0) {
1870                                                 bchan_selectmenu(&bchan, i);
1871                                                 break;
1872                                         }
1873                                 }
1874                         case    EV_AUTKEY:
1875                                 keydwn(&bchan, wev0.e.data.key.keytop, wev0.e.data.key.code);
1876                                 break;
1877                         case    EV_INACT:
1878                                 pdsp_msg(NULL);
1879                                 break;
1880                         case    EV_DEVICE:
1881                                 oprc_dev(&wev0.e, NULL, 0);
1882                                 break;
1883                         case    EV_MSG:
1884                                 receive_message(&bchan);
1885                                 break;
1886                         case    EV_MENU:
1887                                 bchan_popupmenu(&bchan, wev0.s.pos);
1888                                 break;
1889                 }
1890         }
1891
1892         return 0;
1893 }