OSDN Git Service

fix parts ID mistake.
[bbk/bchanl.git] / src / bchanl_hmi.c
1 /*
2  * bchanl_hmi.c
3  *
4  * Copyright (c) 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    "bchanl_hmi.h"
28 #include    "hmi_wscr.h"
29
30 #include        <bstdio.h>
31 #include        <bstdlib.h>
32 #include        <tcode.h>
33 #include        <tstring.h>
34 #include        <btron/btron.h>
35 #include        <btron/hmi.h>
36 #include        <btron/vobj.h>
37
38 #ifdef BCHANL_CONFIG_DEBUG
39 # define DP(arg) printf arg
40 # define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err)
41 #else
42 # define DP(arg) /**/
43 # define DP_ER(msg, err) /**/
44 #endif
45
46 struct subjectwindow_t_ {
47         WID wid;
48         GID gid;
49         subjectwindow_scrollcalback scroll_callback;
50         windowscroll_t wscr;
51         VP arg;
52         WEVENT savedwev;
53 };
54
55 struct bbsmenuwindow_t_ {
56         WID wid;
57         GID gid;
58         bbsmenuwindow_scrollcalback scroll_callback;
59         windowscroll_t wscr;
60         VP arg;
61         WEVENT savedwev;
62 };
63
64 #define SUBJECTOPTIONWINDOW_STRBUF_LEN 512
65 struct subjectoptionwindow_t_ {
66         WID wid;
67         GID gid;
68         WID parent;
69         RECT r;
70         PAT bgpat;
71         W dnum_filter;
72         W dnum_order;
73         W dnum_orderby;
74         PAID tb_filter_id;
75         PAID ws_order_id;
76         PAID ws_orderby_id;
77         WEVENT savedwev;
78         W order;
79         W orderby;
80         TC strbuf[SUBJECTOPTIONWINDOW_STRBUF_LEN];
81         Bool tb_appended;
82 };
83
84 #define BCHANLHMI_FLAG_SWITCHBUTDN 0x00000001
85
86 struct bchanlhmi_t_ {
87         WEVENT wev;
88         bchanlhmievent_t evt;
89         UW flag;
90         subjectwindow_t *subjectwindow;
91         bbsmenuwindow_t *bbsmenuwindow;
92         subjectoptionwindow_t *subjectoptionwindow;
93 };
94
95 EXPORT W subjectwindow_startredisp(subjectwindow_t *window, RECT *r)
96 {
97         return wsta_dsp(window->wid, r, NULL);
98 }
99
100 EXPORT W subjectwindow_endredisp(subjectwindow_t *window)
101 {
102         return wend_dsp(window->wid);
103 }
104
105 EXPORT W subjectwindow_eraseworkarea(subjectwindow_t *window, RECT *r)
106 {
107         return wera_wnd(window->wid, r);
108 }
109
110 EXPORT W subjectwindow_scrollworkarea(subjectwindow_t *window, W dh, W dv)
111 {
112         return wscr_wnd(window->wid, NULL, dh, dv, W_MOVE|W_RDSET);
113 }
114
115 EXPORT VOID subjectwindow_scrollbyvalue(subjectwindow_t *window, W dh, W dv)
116 {
117         windowscroll_scrollbyvalue(&window->wscr, dh, dv);
118 }
119
120 EXPORT W subjectwindow_requestredisp(subjectwindow_t *window)
121 {
122         return wreq_dsp(window->wid);
123 }
124
125 EXPORT GID subjectwindow_startdrag(subjectwindow_t *window)
126 {
127         return wsta_drg(window->wid, 0);
128 }
129
130 EXPORT W subjectwindow_getdrag(subjectwindow_t *window, PNT *pos, WID *wid, PNT *pos_butup)
131 {
132         W etype;
133
134         etype = wget_drg(pos, &window->savedwev);
135         *wid = window->savedwev.s.wid;
136         if (etype == EV_BUTUP) {
137                 *pos_butup = window->savedwev.s.pos;
138         }
139
140         return etype;
141 }
142
143 EXPORT VOID subjectwindow_enddrag(subjectwindow_t *window)
144 {
145         wend_drg();
146 }
147
148 EXPORT VOID subjectwindow_responsepasterequest(subjectwindow_t *window, W nak, PNT *pos)
149 {
150         if (pos != NULL) {
151                 window->savedwev.r.r.p.rightbot.x = pos->x;
152                 window->savedwev.r.r.p.rightbot.y = pos->y;
153         }
154         wrsp_evt(&window->savedwev, nak);
155 }
156
157 EXPORT W subjectwindow_getworkrect(subjectwindow_t *window, RECT *r)
158 {
159         return wget_wrk(window->wid, r);
160 }
161
162 EXPORT GID subjectwindow_getGID(subjectwindow_t *window)
163 {
164         return wget_gid(window->wid);
165 }
166
167 EXPORT WID subjectwindow_getWID(subjectwindow_t *window)
168 {
169         return window->wid;
170 }
171
172 EXPORT W subjectwindow_settitle(subjectwindow_t *window, TC *title)
173 {
174         return wset_tit(window->wid, -1, title, 0);
175 }
176
177 EXPORT Bool subjectwindow_isactive(subjectwindow_t *window)
178 {
179         WID wid;
180         wid = wget_act(NULL);
181         if (window->wid == wid) {
182                 return True;
183         }
184         return False;
185 }
186
187 EXPORT W subjectwindow_setdrawrect(subjectwindow_t *window, W l, W t, W r, W b)
188 {
189         return windowscroll_setdrawrect(&window->wscr, l, t, r, b);
190 }
191
192 EXPORT W subjectwindow_setworkrect(subjectwindow_t *window, W l, W t, W r, W b)
193 {
194         return windowscroll_setworkrect(&window->wscr, l, t, r, b);
195 }
196
197 EXPORT W bbsmenuwindow_startredisp(bbsmenuwindow_t *window, RECT *r)
198 {
199         return wsta_dsp(window->wid, r, NULL);
200 }
201
202 EXPORT W bbsmenuwindow_endredisp(bbsmenuwindow_t *window)
203 {
204         return wend_dsp(window->wid);
205 }
206
207 EXPORT W bbsmenuwindow_eraseworkarea(bbsmenuwindow_t *window, RECT *r)
208 {
209         return wera_wnd(window->wid, r);
210 }
211
212 EXPORT W bbsmenuwindow_scrollworkarea(bbsmenuwindow_t *window, W dh, W dv)
213 {
214         return wscr_wnd(window->wid, NULL, dh, dv, W_MOVE|W_RDSET);
215 }
216
217 EXPORT VOID bbsmenuwindow_scrollbyvalue(bbsmenuwindow_t *window, W dh, W dv)
218 {
219         windowscroll_scrollbyvalue(&window->wscr, dh, dv);
220 }
221
222 EXPORT W bbsmenuwindow_requestredisp(bbsmenuwindow_t *window)
223 {
224         return wreq_dsp(window->wid);
225 }
226
227 EXPORT GID bbsmenuwindow_startdrag(bbsmenuwindow_t *window)
228 {
229         return wsta_drg(window->wid, 0);
230 }
231
232 EXPORT W bbsmenuwindow_getdrag(bbsmenuwindow_t *window, PNT *pos, WID *wid, PNT *pos_butup)
233 {
234         W etype;
235
236         etype = wget_drg(pos, &window->savedwev);
237         *wid = window->savedwev.s.wid;
238         if (etype == EV_BUTUP) {
239                 *pos_butup = window->savedwev.s.pos;
240         }
241
242         return etype;
243 }
244
245 EXPORT VOID bbsmenuwindow_enddrag(bbsmenuwindow_t *window)
246 {
247         wend_drg();
248 }
249
250 EXPORT VOID bbsmenuwindow_responsepasterequest(bbsmenuwindow_t *window, W nak, PNT *pos)
251 {
252         if (pos != NULL) {
253                 window->savedwev.r.r.p.rightbot.x = pos->x;
254                 window->savedwev.r.r.p.rightbot.y = pos->y;
255         }
256         wrsp_evt(&window->savedwev, nak);
257 }
258
259 EXPORT W bbsmenuwindow_getworkrect(bbsmenuwindow_t *window, RECT *r)
260 {
261         return wget_wrk(window->wid, r);
262 }
263
264 EXPORT GID bbsmenuwindow_getGID(bbsmenuwindow_t *window)
265 {
266         return wget_gid(window->wid);
267 }
268
269 EXPORT WID bbsmenuwindow_getWID(bbsmenuwindow_t *window)
270 {
271         return window->wid;
272 }
273
274 EXPORT W bbsmenuwindow_settitle(bbsmenuwindow_t *window, TC *title)
275 {
276         return wset_tit(window->wid, -1, title, 0);
277 }
278
279 EXPORT Bool bbsmenuwindow_isactive(bbsmenuwindow_t *window)
280 {
281         WID wid;
282         wid = wget_act(NULL);
283         if (window->wid == wid) {
284                 return True;
285         }
286         return False;
287 }
288
289 EXPORT W bbsmenuwindow_setdrawrect(bbsmenuwindow_t *window, W l, W t, W r, W b)
290 {
291         return windowscroll_setdrawrect(&window->wscr, l, t, r, b);
292 }
293
294 EXPORT W bbsmenuwindow_setworkrect(bbsmenuwindow_t *window, W l, W t, W r, W b)
295 {
296         return windowscroll_setworkrect(&window->wscr, l, t, r, b);
297 }
298
299 EXPORT W subjectoptionwindow_open(subjectoptionwindow_t *window)
300 {
301         WID wid;
302
303         if (window->wid > 0) {
304                 return 0;
305         }
306
307         wid = wopn_wnd(WA_SUBW|WA_TITL|WA_HHDL, window->parent, &(window->r), NULL, 2, NULL, &window->bgpat, NULL);
308         if (wid < 0) {
309                 DP_ER("wopn_wnd: subjectoption error", wid);
310                 return wid;
311         }
312         window->wid = wid;
313         window->gid = wget_gid(wid);
314
315         window->tb_filter_id = copn_par(wid, window->dnum_filter, NULL);
316         if (window->tb_filter_id < 0) {
317                 DP_ER("copn_par list error:", window->tb_filter_id);
318         }
319         window->ws_order_id = copn_par(wid, window->dnum_order, NULL);
320         if (window->ws_order_id < 0) {
321                 DP_ER("copn_par delete error:", window->ws_order_id);
322         }
323         window->ws_orderby_id = copn_par(wid, window->dnum_orderby, NULL);
324         if (window->ws_orderby_id < 0) {
325                 DP_ER("copn_par input error:", window->ws_orderby_id);
326         }
327
328         wreq_dsp(wid);
329
330         return 0;
331 }
332
333 EXPORT VOID subjectoptionwindow_close(subjectoptionwindow_t *window)
334 {
335         WDSTAT stat;
336         W err;
337
338         if (window->wid < 0) {
339                 return;
340         }
341
342         stat.attr = WA_STD;
343         err = wget_sts(window->wid, &stat, NULL);
344         if (err >= 0) {
345                 window->r = stat.r;
346         }
347         cdel_pwd(window->wid, NOCLR);
348         wcls_wnd(window->wid, CLR);
349         window->wid = -1;
350         window->gid = -1;
351 }
352
353 EXPORT Bool subjectoptionwindow_isopen(subjectoptionwindow_t *window)
354 {
355         if (window->wid < 0) {
356                 return False;
357         }
358         return True;
359 }
360
361 EXPORT W subjectoptionwindow_setorder(subjectoptionwindow_t *window, W order)
362 {
363         if ((order != SUBJECTOPTIONWINDOW_ORDER_ASCENDING)
364                 &&(order != SUBJECTOPTIONWINDOW_ORDER_DESCENDING)) {
365                 return -1; /* TODO */
366         }
367         window->order = order;
368         if (window->wid < 0) {
369                 return 0;
370         }
371         return cset_val(window->ws_order_id, 1, (W*)&order);
372 }
373
374 EXPORT W subjectoptionwindow_setorderby(subjectoptionwindow_t *window, W orderby)
375 {
376         if ((orderby != SUBJECTOPTIONWINDOW_ORDERBY_NUMBER)
377                 &&(orderby != SUBJECTOPTIONWINDOW_ORDERBY_RES)
378                 &&(orderby != SUBJECTOPTIONWINDOW_ORDERBY_SINCE)
379                 &&(orderby != SUBJECTOPTIONWINDOW_ORDERBY_VIGOR)) {
380                 return -1; /* TODO */
381         }
382         window->orderby = orderby;
383         if (window->wid < 0) {
384                 return 0;
385         }
386         return cset_val(window->ws_orderby_id, 1, (W*)&orderby);
387 }
388
389 EXPORT W subjectoptionwindow_settext(subjectoptionwindow_t *window, TC *str, W len)
390 {
391         W cp_len;
392
393         if (len < SUBJECTOPTIONWINDOW_STRBUF_LEN) {
394                 cp_len = len;
395         } else {
396                 cp_len = SUBJECTOPTIONWINDOW_STRBUF_LEN;
397         }
398         memcpy(window->strbuf, str, cp_len * sizeof(TC));
399         if (window->wid < 0) {
400                 return 0;
401         }
402
403         return cset_val(window->tb_filter_id, cp_len, (W*)window->strbuf);
404 }
405
406 EXPORT W subjectoptionwindow_getorder(subjectoptionwindow_t *window)
407 {
408         return window->order;
409 }
410
411 EXPORT W subjectoptionwindow_getorderby(subjectoptionwindow_t *window)
412 {
413         return window->orderby;
414 }
415
416 EXPORT W subjectoptionwindow_gettext(subjectoptionwindow_t *window, TC *str, W len)
417 {
418         W cp_len;
419
420         if (len < SUBJECTOPTIONWINDOW_STRBUF_LEN) {
421                 cp_len = len;
422         } else {
423                 cp_len = SUBJECTOPTIONWINDOW_STRBUF_LEN;
424         }
425         memcpy(str, window->strbuf, cp_len * sizeof(TC));
426
427         return cp_len;
428 }
429
430 EXPORT W subjectoptionwindow_starttextboxaction(subjectoptionwindow_t *window)
431 {
432         window->tb_appended = False;
433         return 0;
434 }
435
436 EXPORT W subjectoptionwindow_gettextboxaction(subjectoptionwindow_t *window, TC *key, TC **val, W *len)
437 {
438         W ret, len0;
439         WEVENT *wev;
440
441         if (window->tb_appended == True) {
442                 return SUBJECTOPTIONWINDOW_GETTEXTBOXACTION_FINISH;
443         }
444
445         wev = &window->savedwev;
446
447         for (;;) {
448                 ret = cact_par(window->tb_filter_id, wev);
449                 if (ret < 0) {
450                         DP_ER("cact_par tb_filter_id error:", ret);
451                         return ret;
452                 }
453                 switch (ret & 0xefff) {
454                 case P_EVENT:
455                         switch (wev->s.type) {
456                         case EV_INACT:
457                         case EV_REQUEST:
458                                 wugt_evt(wev);
459                                 return SUBJECTOPTIONWINDOW_GETTEXTBOXACTION_FINISH;
460                         case EV_DEVICE:
461                                 oprc_dev(&wev->e, NULL, 0);
462                                 break;
463                         }
464                         wev->s.type = EV_NULL;
465                         continue;
466                 case P_MENU:
467                         wev->s.type = EV_NULL;
468                         if ((wev->s.type == EV_KEYDWN)&&(wev->s.stat & ES_CMD)) {
469                                 *key = wev->e.data.key.code;
470                                 return SUBJECTOPTIONWINDOW_GETTEXTBOXACTION_KEYMENU;
471                         }
472                         return SUBJECTOPTIONWINDOW_GETTEXTBOXACTION_MENU;
473                 case (0x4000|P_MOVE):
474                         return SUBJECTOPTIONWINDOW_GETTEXTBOXACTION_MOVE;
475                 case (0x4000|P_COPY):
476                         return SUBJECTOPTIONWINDOW_GETTEXTBOXACTION_COPY;
477                 case (0x4000|P_NL):
478                         len0 = cget_val(window->tb_filter_id, 128, (W*)window->strbuf);
479                         if (len0 <= 0) {
480                                 return SUBJECTOPTIONWINDOW_GETTEXTBOXACTION_FINISH;
481                         }
482                         *val = window->strbuf;
483                         *len = len0;
484                         window->tb_appended = True;
485                         return SUBJECTOPTIONWINDOW_GETTEXTBOXACTION_APPEND;
486                 case (0x4000|P_TAB):
487                         return SUBJECTOPTIONWINDOW_GETTEXTBOXACTION_FINISH;
488                 case (0x4000|P_BUT):
489                         wugt_evt(wev);
490                         return SUBJECTOPTIONWINDOW_GETTEXTBOXACTION_FINISH;
491                 default:
492                         return SUBJECTOPTIONWINDOW_GETTEXTBOXACTION_FINISH;
493                 }
494         }
495
496         return SUBJECTOPTIONWINDOW_GETTEXTBOXACTION_FINISH;
497 }
498
499 EXPORT W subjectoptionwindow_endtextboxaction(subjectoptionwindow_t *window)
500 {
501         return 0;
502 }
503
504 LOCAL VOID subjectoptionwindow_draw(subjectoptionwindow_t *window, RECT *r)
505 {
506         cdsp_pwd(window->wid, r, P_RDISP);
507 }
508
509 LOCAL VOID subjectoptionwindow_redisp(subjectoptionwindow_t *window)
510 {
511         RECT r;
512         do {
513                 if (wsta_dsp(window->wid, &r, NULL) == 0) {
514                         break;
515                 }
516                 wera_wnd(window->wid, &r);
517                 subjectoptionwindow_draw(window, &r);
518         } while (wend_dsp(window->wid) > 0);
519 }
520
521 LOCAL VOID bchanlhmi_setswitchbutdnflag(bchanlhmi_t *hmi)
522 {
523         hmi->flag = hmi->flag | BCHANLHMI_FLAG_SWITCHBUTDN;
524 }
525
526 LOCAL VOID bchanlhmi_clearswitchbutdnflag(bchanlhmi_t *hmi)
527 {
528         hmi->flag = hmi->flag & ~BCHANLHMI_FLAG_SWITCHBUTDN;
529 }
530
531 LOCAL Bool bchanlhmi_issetswitchbutdnflag(bchanlhmi_t *hmi)
532 {
533         if ((hmi->flag & BCHANLHMI_FLAG_SWITCHBUTDN) == 0) {
534                 return False;
535         }
536         return True;
537 }
538
539 LOCAL WID bchanlhmi_getsubjectWID(bchanlhmi_t *hmi)
540 {
541         if (hmi->subjectwindow == NULL) {
542                 return -1;
543         }
544         return hmi->subjectwindow->wid;
545 }
546
547 LOCAL WID bchanlhmi_getbbsmenuWID(bchanlhmi_t *hmi)
548 {
549         if (hmi->bbsmenuwindow == NULL) {
550                 return -1;
551         }
552         return hmi->bbsmenuwindow->wid;
553 }
554
555 LOCAL WID bchanlhmi_getsubjectoptionWID(bchanlhmi_t *hmi)
556 {
557         if (hmi->subjectoptionwindow == NULL) {
558                 return -1;
559         }
560         return hmi->subjectoptionwindow->wid;
561 }
562
563 LOCAL VOID bchanlhmi_weventrequest(bchanlhmi_t *hmi, WEVENT *wev, bchanlhmievent_t *evt)
564 {
565         WID subject_wid, bbsmenu_wid, subjectoption_wid;
566
567         subject_wid = bchanlhmi_getsubjectWID(hmi);
568         bbsmenu_wid = bchanlhmi_getbbsmenuWID(hmi);
569         subjectoption_wid = bchanlhmi_getsubjectoptionWID(hmi);
570
571         switch (wev->g.cmd) {
572         case    W_REDISP:       /*ºÆɽ¼¨Í×µá*/
573                 if (wev->g.wid == subject_wid) {
574                         evt->type = BCHANLHMIEVENT_TYPE_SUBJECT_DRAW;
575                 } else if (wev->g.wid == bbsmenu_wid) {
576                         evt->type = BCHANLHMIEVENT_TYPE_BBSMENU_DRAW;
577                 } else if (wev->g.wid == subjectoption_wid) {
578                         subjectoptionwindow_redisp(hmi->subjectoptionwindow);
579                 }
580                 break;
581         case    W_PASTE:        /*Ž¹þ¤ßÍ×µá*/
582                 if (wev->g.wid == subject_wid) {
583                         evt->type = BCHANLHMIEVENT_TYPE_SUBJECT_PASTE;
584                         memcpy(&hmi->subjectwindow->savedwev, wev, sizeof(WEVENT));
585                 } else if (wev->g.wid == bbsmenu_wid) {
586                         evt->type = BCHANLHMIEVENT_TYPE_BBSMENU_PASTE;
587                         memcpy(&hmi->bbsmenuwindow->savedwev, wev, sizeof(WEVENT));
588                 } else {
589                         wrsp_evt(wev, 1); /*NACK*/
590                 }
591                 break;
592         case    W_DELETE:       /*Êݸ½ªÎ»*/
593                 wrsp_evt(wev, 0);       /*ACK*/
594                 if (wev->g.wid == subject_wid) {
595                         evt->type = BCHANLHMIEVENT_TYPE_SUBJECT_CLOSE;
596                         evt->data.subject_close.save = True;
597                 } else if (wev->g.wid == bbsmenu_wid) {
598                         evt->type = BCHANLHMIEVENT_TYPE_BBSMENU_CLOSE;
599                         evt->data.bbsmenu_close.save = True;
600                 } else if (wev->g.wid == subjectoption_wid) {
601                         subjectoptionwindow_close(hmi->subjectoptionwindow);
602                 }
603                 break;
604         case    W_FINISH:       /*ÇÑ´þ½ªÎ»*/
605                 wrsp_evt(wev, 0);       /*ACK*/
606                 if (wev->g.wid == subject_wid) {
607                         evt->type = BCHANLHMIEVENT_TYPE_SUBJECT_CLOSE;
608                         evt->data.subject_close.save = False;
609                 } else if (wev->g.wid == bbsmenu_wid) {
610                         evt->type = BCHANLHMIEVENT_TYPE_BBSMENU_CLOSE;
611                         evt->data.bbsmenu_close.save = False;
612                 } else if (wev->g.wid == subjectoption_wid) {
613                         subjectoptionwindow_close(hmi->subjectoptionwindow);
614                 }
615                 break;
616         }
617 }
618
619 LOCAL VOID subjectwindow_resize(subjectwindow_t *window, SIZE *sz)
620 {
621         RECT work;
622         Bool workchange = False;
623
624         wget_wrk(window->wid, &work);
625         if (work.c.left != 0) {
626                 work.c.left = 0;
627                 workchange = True;
628         }
629         if (work.c.top != 0) {
630                 work.c.top = 0;
631                 workchange = True;
632         }
633         wset_wrk(window->wid, &work);
634         gset_vis(window->gid, work);
635
636         if (workchange == True) {
637                 wera_wnd(window->wid, NULL);
638                 wreq_dsp(window->wid);
639         }
640
641         sz->v = work.c.bottom - work.c.top;
642         sz->h = work.c.right - work.c.left;
643 }
644
645 LOCAL VOID bbsmenuwindow_resize(bbsmenuwindow_t *window, SIZE *sz)
646 {
647         RECT work;
648         Bool workchange = False;
649
650         wget_wrk(window->wid, &work);
651         if (work.c.left != 0) {
652                 work.c.left = 0;
653                 workchange = True;
654         }
655         if (work.c.top != 0) {
656                 work.c.top = 0;
657                 workchange = True;
658         }
659         wset_wrk(window->wid, &work);
660         gset_vis(window->gid, work);
661
662         if (workchange == True) {
663                 wera_wnd(window->wid, NULL);
664                 wreq_dsp(window->wid);
665         }
666
667         sz->v = work.c.bottom - work.c.top;
668         sz->h = work.c.right - work.c.left;
669 }
670
671 LOCAL VOID subjectoptionwindow_butdnwork(subjectoptionwindow_t *window, WEVENT *wev, bchanlhmievent_t *evt)
672 {
673         PAID id;
674         W ret;
675
676         ret = cfnd_par(window->wid, wev->s.pos, &id);
677         if (ret <= 0) {
678                 return;
679         }
680         if (id == window->tb_filter_id) {
681                 memcpy(&window->savedwev, wev, sizeof(WEVENT));
682                 evt->type = BCHANLHMIEVENT_TYPE_SUBJECTOPTION_TEXTBOX;
683                 return;
684         }
685         if (id == window->ws_order_id) {
686                 ret = cact_par(window->ws_order_id, wev);
687                 if ((ret & 0x5000) != 0x5000) {
688                         return;
689                 }
690                 window->order = ret & 0xfff;
691                 evt->type = BCHANLHMIEVENT_TYPE_SUBJECTOPTION_CHANGEORDER;
692                 evt->data.subjectoption_changeorder.order = window->order;
693                 return;
694         }
695         if (id == window->ws_orderby_id) {
696                 ret = cact_par(window->ws_orderby_id, wev);
697                 if ((ret & 0x5000) != 0x5000) {
698                         return;
699                 }
700                 window->orderby = ret & 0xfff;
701                 evt->type = BCHANLHMIEVENT_TYPE_SUBJECTOPTION_CHANGEORDERBY;
702                 evt->data.subjectoption_changeorderby.orderby = window->orderby;
703                 return;
704         }
705 }
706
707 LOCAL VOID bchanlhmi_weventbutdn(bchanlhmi_t *hmi, WEVENT *wev, bchanlhmievent_t *evt)
708 {
709         W i;
710         WID subject_wid, bbsmenu_wid, subjectoption_wid;
711
712         subject_wid = bchanlhmi_getsubjectWID(hmi);
713         bbsmenu_wid = bchanlhmi_getbbsmenuWID(hmi);
714         subjectoption_wid = bchanlhmi_getsubjectoptionWID(hmi);
715
716         switch  (wev->s.cmd) {
717         case    W_PICT:
718                 switch (wchk_dck(wev->s.time)) {
719                 case    W_DCLICK:
720                         if (wev->s.wid == subject_wid) {
721                                 evt->type = BCHANLHMIEVENT_TYPE_SUBJECT_CLOSE;
722                                 evt->data.subject_close.save = True; /* TODO: tmp value. */
723                         } else if (wev->s.wid == bbsmenu_wid) {
724                                 evt->type = BCHANLHMIEVENT_TYPE_BBSMENU_CLOSE;
725                                 evt->data.bbsmenu_close.save = True; /* TODO: tmp value. */
726                         } else if (wev->s.wid == subjectoption_wid) {
727                                 subjectoptionwindow_close(hmi->subjectoptionwindow);
728                         }
729                         return;
730                 case    W_PRESS:
731                         break;
732                 default:
733                         return;
734                 }
735         case    W_FRAM:
736         case    W_TITL:
737                 if (wmov_drg(wev, NULL) > 0) {
738                         if (wev->s.wid == subject_wid) {
739                                 evt->type = BCHANLHMIEVENT_TYPE_SUBJECT_DRAW;
740                         } else if (wev->s.wid == bbsmenu_wid) {
741                                 evt->type = BCHANLHMIEVENT_TYPE_BBSMENU_DRAW;
742                         } else if (wev->s.wid == subjectoption_wid) {
743                                 subjectoptionwindow_redisp(hmi->subjectoptionwindow);
744                         }
745                 }
746                 return;
747         case    W_LTHD:
748         case    W_RTHD:
749         case    W_LBHD:
750         case    W_RBHD:
751                 switch (wchk_dck(wev->s.time)) {
752                 case    W_DCLICK:
753                         i = wchg_wnd(wev->s.wid, NULL, W_MOVE);
754                         break;
755                 case    W_PRESS:
756                         i = wrsz_drg(wev, NULL, NULL);
757                         break;
758                 default:
759                         return;
760                 }
761
762                 if (wev->s.wid == subject_wid) {
763                         evt->type = BCHANLHMIEVENT_TYPE_SUBJECT_RESIZE;
764                         subjectwindow_resize(hmi->subjectwindow, &evt->data.subject_resize.work_sz);
765                         windowscroll_updatebar(&hmi->subjectwindow->wscr);
766                         if (i > 0) {
767                                 //evt->type = BCHANLHMIEVENT_TYPE_SUBJECT_DRAW;
768                                 /* TODO: queueing */
769                                 evt->data.subject_resize.needdraw = True;
770                         } else {
771                                 evt->data.subject_resize.needdraw = False;
772                         }
773                 } else if (wev->s.wid == bbsmenu_wid) {
774                         evt->type = BCHANLHMIEVENT_TYPE_BBSMENU_RESIZE;
775                         bbsmenuwindow_resize(hmi->bbsmenuwindow, &evt->data.bbsmenu_resize.work_sz);
776                         windowscroll_updatebar(&hmi->bbsmenuwindow->wscr);
777                         if (i > 0) {
778                                 //evt->type = BCHANLHMIEVENT_TYPE_BBSMENU_DRAW;
779                                 /* TODO: queueing */
780                                 evt->data.bbsmenu_resize.needdraw = True;
781                         } else {
782                                 evt->data.bbsmenu_resize.needdraw = False;
783                         }
784                 }
785                 /* subject option window need not do nothing. */
786                 return;
787         case    W_RBAR:
788                 if (wev->s.wid == subject_wid) {
789                         windowscroll_weventrbar(&hmi->subjectwindow->wscr, wev);
790                 } else if (wev->s.wid == bbsmenu_wid) {
791                         windowscroll_weventrbar(&hmi->bbsmenuwindow->wscr, wev);
792                 }
793                 /* subject option window need not do nothing. */
794                 return;
795         case    W_BBAR:
796                 if (wev->s.wid == subject_wid) {
797                         windowscroll_weventbbar(&hmi->subjectwindow->wscr, wev);
798                 } else if (wev->s.wid == bbsmenu_wid) {
799                         windowscroll_weventbbar(&hmi->bbsmenuwindow->wscr, wev);
800                 }
801                 /* subject option window need not do nothing. */
802                 return;
803         case    W_WORK:
804                 if (wev->s.wid == subject_wid) {
805                         evt->type = BCHANLHMIEVENT_TYPE_SUBJECT_BUTDN;
806                         evt->data.subject_butdn.type = wchk_dck(wev->s.time);
807                         evt->data.subject_butdn.pos = wev->s.pos;
808                         memcpy(&hmi->subjectwindow->savedwev, wev, sizeof(WEVENT));
809                 } else if (wev->s.wid == bbsmenu_wid) {
810                         evt->type = BCHANLHMIEVENT_TYPE_BBSMENU_BUTDN;
811                         evt->data.bbsmenu_butdn.type = wchk_dck(wev->s.time);
812                         evt->data.bbsmenu_butdn.pos = wev->s.pos;
813                         memcpy(&hmi->bbsmenuwindow->savedwev, wev, sizeof(WEVENT));
814                 } else if (wev->s.wid == subjectoption_wid) {
815                         subjectoptionwindow_butdnwork(hmi->subjectoptionwindow, wev, evt);
816                 }
817                 return;
818         }
819
820         return;
821 }
822
823 LOCAL VOID bchanlhmi_weventswitch(bchanlhmi_t *hmi, WEVENT *wev, bchanlhmievent_t *evt)
824 {
825         WID subject_wid, bbsmenu_wid;
826
827         subject_wid = bchanlhmi_getsubjectWID(hmi);
828         bbsmenu_wid = bchanlhmi_getbbsmenuWID(hmi);
829
830         if (wev->s.wid == subject_wid) {
831                 evt->type = BCHANLHMIEVENT_TYPE_SUBJECT_SWITCH;
832                 evt->data.subject_switch.needdraw = False;
833         } else if (wev->s.wid == bbsmenu_wid) {
834                 evt->type = BCHANLHMIEVENT_TYPE_BBSMENU_SWITCH;
835                 evt->data.bbsmenu_switch.needdraw = False;
836         }
837         bchanlhmi_setswitchbutdnflag(hmi);
838 }
839
840 LOCAL VOID bchanlhmi_weventreswitch(bchanlhmi_t *hmi, WEVENT *wev, bchanlhmievent_t *evt)
841 {
842         WID subject_wid, bbsmenu_wid, subjectoption_wid;
843
844         subject_wid = bchanlhmi_getsubjectWID(hmi);
845         bbsmenu_wid = bchanlhmi_getbbsmenuWID(hmi);
846         subjectoption_wid = bchanlhmi_getsubjectoptionWID(hmi);
847
848         if (wev->s.wid == subject_wid) {
849                 evt->type = BCHANLHMIEVENT_TYPE_SUBJECT_SWITCH;
850                 evt->data.subject_switch.needdraw = True;
851         } else if (wev->s.wid == bbsmenu_wid) {
852                 evt->type = BCHANLHMIEVENT_TYPE_BBSMENU_SWITCH;
853                 evt->data.bbsmenu_switch.needdraw = True;
854         } else if (wev->s.wid == subjectoption_wid) {
855                 subjectoptionwindow_redisp(hmi->subjectoptionwindow);
856         }
857         bchanlhmi_setswitchbutdnflag(hmi);
858 }
859
860 LOCAL VOID bchanlhmi_receivemessage(bchanlhmi_t *hmi, bchanlhmievent_t *evt)
861 {
862         MESSAGE msg;
863         W err;
864
865     err = rcv_msg(MM_ALL, &msg, sizeof(MESSAGE), WAIT|NOCLR);
866         if (err >= 0) {
867                 if (msg.msg_type == MS_TMOUT) { /* should be use other type? */
868                         evt->type = BCHANLHMIEVENT_TYPE_COMMON_TIMEOUT;
869                         evt->data.common_timeout.code = msg.msg_body.TMOUT.code;
870                 }
871         }
872         clr_msg(MM_ALL, MM_ALL);
873 }
874
875 EXPORT W bchanlhmi_getevent(bchanlhmi_t *hmi, bchanlhmievent_t **evt)
876 {
877         WEVENT  *wev0;
878         WID subject_wid, bbsmenu_wid, subjectoption_wid;
879         Bool ok;
880
881         subject_wid = bchanlhmi_getsubjectWID(hmi);
882         bbsmenu_wid = bchanlhmi_getbbsmenuWID(hmi);
883         subjectoption_wid = bchanlhmi_getsubjectoptionWID(hmi);
884
885         hmi->evt.type = BCHANLHMIEVENT_TYPE_NONE;
886         wev0 = &hmi->wev;
887
888         ok = bchanlhmi_issetswitchbutdnflag(hmi);
889         if (ok == True) {
890                 bchanlhmi_weventbutdn(hmi, wev0, &hmi->evt);
891                 bchanlhmi_clearswitchbutdnflag(hmi);
892                 return 0;
893         }
894
895         wget_evt(wev0, WAIT);
896         switch (wev0->s.type) {
897         case    EV_NULL:
898                 cidl_par(wev0->s.wid, &wev0->s.pos);
899                 if ((wev0->s.wid != subject_wid)&&(wev0->s.wid != bbsmenu_wid)) {
900                         hmi->evt.type = BCHANLHMIEVENT_TYPE_COMMON_MOUSEMOVE;
901                         hmi->evt.data.common_mousemove.pos = wev0->s.pos;
902                         break;          /*¥¦¥£¥ó¥É¥¦³°*/
903                 }
904                 if (wev0->s.cmd != W_WORK)
905                         break;          /*ºî¶ÈÎΰ賰*/
906                 if (wev0->s.stat & ES_CMD)
907                         break;  /*Ì¿Îᥭ¡¼¤¬²¡¤µ¤ì¤Æ¤¤¤ë*/
908                 if (wev0->s.wid == subject_wid) {
909                         hmi->evt.type = BCHANLHMIEVENT_TYPE_SUBJECT_MOUSEMOVE;
910                         hmi->evt.data.subject_mousemove.pos = wev0->s.pos;
911                         hmi->evt.data.subject_mousemove.stat = wev0->s.stat;
912                         break;
913                 }
914                 if (wev0->s.wid == bbsmenu_wid) {
915                         hmi->evt.type = BCHANLHMIEVENT_TYPE_BBSMENU_MOUSEMOVE;
916                         hmi->evt.data.bbsmenu_mousemove.pos = wev0->s.pos;
917                         hmi->evt.data.bbsmenu_mousemove.stat = wev0->s.stat;
918                         break;
919                 }
920                 if (wev0->s.wid == subjectoption_wid) {
921                         cidl_par(wev0->s.wid, &wev0->s.pos);
922                         break;
923                 }
924                 break;
925         case    EV_REQUEST:
926                 bchanlhmi_weventrequest(hmi, wev0, &hmi->evt);
927                 break;
928         case    EV_RSWITCH:
929                 bchanlhmi_weventreswitch(hmi, wev0, &hmi->evt);
930                 break;
931         case    EV_SWITCH:
932                 bchanlhmi_weventswitch(hmi, wev0, &hmi->evt);
933                 break;
934         case    EV_BUTDWN:
935                 bchanlhmi_weventbutdn(hmi, wev0, &hmi->evt);
936                 break;
937         case    EV_KEYDWN:
938         case    EV_AUTKEY:
939                 hmi->evt.type = BCHANLHMIEVENT_TYPE_COMMON_KEYDOWN;
940                 hmi->evt.data.common_keydown.keycode = wev0->e.data.key.code;
941                 hmi->evt.data.common_keydown.keytop = wev0->e.data.key.keytop;
942                 hmi->evt.data.common_keydown.stat = wev0->e.stat;
943                 break;
944         case    EV_INACT:
945                 pdsp_msg(NULL);
946                 break;
947         case    EV_DEVICE:
948                 oprc_dev(&wev0->e, NULL, 0);
949                 break;
950         case    EV_MSG:
951                 bchanlhmi_receivemessage(hmi, &hmi->evt);
952                 break;
953         case    EV_MENU:
954                 hmi->evt.type = BCHANLHMIEVENT_TYPE_COMMON_MENU;
955                 hmi->evt.data.common_menu.pos = wev0->s.pos;
956                 break;
957         }
958
959         *evt = &hmi->evt;
960
961         return 0;
962 }
963
964 LOCAL VOID subjectwindow_scroll(VP arg, W dh, W dv)
965 {
966         subjectwindow_t *window = (subjectwindow_t*)arg;
967         (*window->scroll_callback)(window->arg, dh, dv);
968 }
969
970 LOCAL subjectwindow_t* subjectwindow_new(RECT *r, TC *title, PAT *bgpat, subjectwindow_scrollcalback scrollcallback, VP arg)
971 {
972         subjectwindow_t* window;
973         W err;
974
975         window = malloc(sizeof(subjectwindow_t));
976         if (window == NULL) {
977                 return NULL;
978         }
979
980         window->wid = wopn_wnd(WA_SIZE|WA_HHDL|WA_VHDL|WA_BBAR|WA_RBAR, 0, r, NULL, 1, title, bgpat, NULL);
981         if (window->wid < 0) {
982                 free(window);
983                 return NULL;
984         }
985         err = windowscroll_initialize(&window->wscr, window->wid, subjectwindow_scroll, (VP)window);
986         if (err < 0) {
987                 wcls_wnd(window->wid, CLR);
988                 free(window);
989                 return NULL;
990         }
991         window->gid = wget_gid(window->wid);
992         window->scroll_callback = scrollcallback;
993         window->arg = arg;
994
995         return window;
996 }
997
998 LOCAL VOID subjectwindow_delete(subjectwindow_t *window)
999 {
1000         wcls_wnd(window->wid, CLR);
1001         windowscroll_finalize(&window->wscr);
1002         free(window);
1003 }
1004
1005 EXPORT subjectwindow_t* bchanlhmi_newsubjectwindow(bchanlhmi_t *hmi, RECT *r, TC *title, PAT *bgpat, subjectwindow_scrollcalback scrollcallback, VP arg)
1006 {
1007         hmi->subjectwindow = subjectwindow_new(r, title, bgpat, scrollcallback, arg);
1008         return hmi->subjectwindow;
1009 }
1010
1011 EXPORT VOID bchanlhmi_deletesubjectwindow(bchanlhmi_t *hmi, subjectwindow_t *window)
1012 {
1013         subjectwindow_delete(window);
1014         hmi->subjectwindow = NULL;
1015 }
1016
1017 LOCAL VOID bbsmenuwindow_scroll(VP arg, W dh, W dv)
1018 {
1019         bbsmenuwindow_t *window = (bbsmenuwindow_t*)arg;
1020         (*window->scroll_callback)(window->arg, dh, dv);
1021 }
1022
1023 LOCAL bbsmenuwindow_t* bbsmenuwindow_new(RECT *r, TC *title, PAT *bgpat, bbsmenuwindow_scrollcalback scrollcallback, VP arg)
1024 {
1025         bbsmenuwindow_t* window;
1026         W err;
1027
1028         window = malloc(sizeof(bbsmenuwindow_t));
1029         if (window == NULL) {
1030                 return NULL;
1031         }
1032
1033         window->wid = wopn_wnd(WA_SIZE|WA_HHDL|WA_VHDL|WA_BBAR|WA_RBAR, 0, r, NULL, 1, title, bgpat, NULL);
1034         if (window->wid < 0) {
1035                 free(window);
1036                 return NULL;
1037         }
1038         err = windowscroll_initialize(&window->wscr, window->wid, bbsmenuwindow_scroll, (VP)window);
1039         if (err < 0) {
1040                 wcls_wnd(window->wid, CLR);
1041                 free(window);
1042                 return NULL;
1043         }
1044         window->gid = wget_gid(window->wid);
1045         window->scroll_callback = scrollcallback;
1046         window->arg = arg;
1047
1048         return window;
1049 }
1050
1051 LOCAL VOID bbsmenuwindow_delete(bbsmenuwindow_t *window)
1052 {
1053         wcls_wnd(window->wid, CLR);
1054         windowscroll_finalize(&window->wscr);
1055         free(window);
1056 }
1057
1058 EXPORT bbsmenuwindow_t* bchanlhmi_newbbsmenuwindow(bchanlhmi_t *hmi, RECT *r, TC *title, PAT *bgpat, bbsmenuwindow_scrollcalback scrollcallback, VP arg)
1059 {
1060         hmi->bbsmenuwindow = bbsmenuwindow_new(r, title, bgpat, scrollcallback, arg);
1061         return hmi->bbsmenuwindow;
1062 }
1063
1064 EXPORT VOID bchanlhmi_deletebbsmenuwindow(bchanlhmi_t *hmi, bbsmenuwindow_t *window)
1065 {
1066         bbsmenuwindow_delete(window);
1067         hmi->bbsmenuwindow = NULL;
1068 }
1069
1070 LOCAL subjectoptionwindow_t* subjectoptionwindow_new(PNT *p, WID parent, W dnum_filter, W dnum_order, W dnum_orderby)
1071 {
1072         subjectoptionwindow_t *window;
1073         W err;
1074
1075         window = (subjectoptionwindow_t*)malloc(sizeof(subjectoptionwindow_t));
1076         if (window == NULL) {
1077                 DP_ER("malloc error:", 0);
1078                 return NULL;
1079         }
1080         window->wid = -1;
1081         window->gid = -1;
1082         window->parent = parent;
1083         window->r.p.lefttop = *p;
1084         window->r.p.rightbot.x = p->x + 8+360+8+80+8 + 7;
1085         window->r.p.rightbot.y = p->y + 8+24+16+70+8 + 7;
1086         err = wget_inf(WI_PANELBACK, &window->bgpat, sizeof(PAT));
1087         if (err != sizeof(PAT)) {
1088                 DP_ER("wget_inf error:", err);
1089                 window->bgpat.spat.kind = 0;
1090                 window->bgpat.spat.hsize = 16;
1091                 window->bgpat.spat.vsize = 16;
1092                 window->bgpat.spat.fgcol = 0x10ffffff;
1093                 window->bgpat.spat.bgcol = 0;
1094                 window->bgpat.spat.mask = FILL100;
1095         }
1096         window->dnum_filter = dnum_filter;
1097         window->dnum_order = dnum_order;
1098         window->dnum_orderby = dnum_orderby;
1099         window->tb_filter_id = -1;
1100         window->ws_order_id = -1;
1101         window->ws_orderby_id = -1;
1102         window->order = SUBJECTOPTIONWINDOW_ORDER_ASCENDING;
1103         window->orderby = SUBJECTOPTIONWINDOW_ORDERBY_NUMBER;
1104         memset(window->strbuf, 0, sizeof(TC)*SUBJECTOPTIONWINDOW_STRBUF_LEN);
1105
1106         return window;
1107 }
1108
1109 LOCAL VOID subjectoptionwindow_delete(subjectoptionwindow_t *window)
1110 {
1111         if (window->wid > 0) {
1112                 cdel_pwd(window->wid, NOCLR);
1113                 wcls_wnd(window->wid, CLR);
1114         }
1115         free(window);
1116 }
1117
1118 EXPORT subjectoptionwindow_t *bchanlhmi_newsubjectoptionwindow(bchanlhmi_t *hmi, PNT *p, W dnum_filter, W dnum_order, W dnum_orderby)
1119 {
1120         W subject_wid;
1121         subject_wid = bchanlhmi_getsubjectWID(hmi);
1122         if (subject_wid < 0) {
1123                 DP_ER("subject window not exist", 0);
1124                 return NULL;
1125         }
1126         hmi->subjectoptionwindow = subjectoptionwindow_new(p, subject_wid, dnum_filter, dnum_order, dnum_orderby);
1127         return hmi->subjectoptionwindow;
1128 }
1129
1130 EXPORT VOID bchanlhmi_deletesubjectoptionwindow(bchanlhmi_t *hmi, subjectoptionwindow_t *window)
1131 {
1132         subjectoptionwindow_delete(window);
1133         hmi->subjectoptionwindow = NULL;
1134 }
1135
1136 EXPORT bchanlhmi_t* bchanlhmi_new()
1137 {
1138         bchanlhmi_t *hmi;
1139
1140         hmi = (bchanlhmi_t *)malloc(sizeof(bchanlhmi_t));
1141         if (hmi == NULL) {
1142                 return NULL;
1143         }
1144         hmi->subjectwindow = NULL;
1145         hmi->bbsmenuwindow = NULL;
1146         hmi->subjectoptionwindow = NULL;
1147
1148         return hmi;
1149 }
1150
1151 EXPORT VOID bchanlhmi_delete(bchanlhmi_t *hmi)
1152 {
1153         if (hmi->subjectoptionwindow != NULL) {
1154                 subjectoptionwindow_delete(hmi->subjectoptionwindow);
1155         }
1156         if (hmi->bbsmenuwindow != NULL) {
1157                 bbsmenuwindow_delete(hmi->bbsmenuwindow);
1158         }
1159         if (hmi->subjectwindow != NULL) {
1160                 subjectwindow_delete(hmi->subjectwindow);
1161         }
1162         free(hmi);
1163 }