74
80
khui_action_ref khui_menu_view[] = {
75
MENU_ACTION(KHUI_ACTION_CHOOSE_COLS),
76
MENU_ACTION(KHUI_MENU_LAYOUT),
77
MENU_ACTION(KHUI_MENU_TOOLBARS),
81
MENU_SUBMENU(KHUI_MENU_COLUMNS),
82
MENU_SUBMENU(KHUI_MENU_LAYOUT),
84
/* not implemented yet */
85
MENU_SUBMENU(KHUI_MENU_TOOLBARS),
89
/* not implemented yet */
79
90
MENU_ACTION(KHUI_ACTION_DEBUG_WINDOW),
81
93
MENU_ACTION(KHUI_ACTION_VIEW_REFRESH),
85
97
khui_action_ref khui_menu_options[] = {
86
98
MENU_ACTION(KHUI_ACTION_OPT_KHIM),
99
MENU_ACTION(KHUI_ACTION_OPT_APPEAR),
87
100
MENU_ACTION(KHUI_ACTION_OPT_IDENTS),
88
101
MENU_ACTION(KHUI_ACTION_OPT_NOTIF),
102
MENU_ACTION(KHUI_ACTION_OPT_PLUGINS),
171
196
/* all stock menus and toolbars */
172
197
khui_menu_def khui_all_menus[] = {
173
CONSTMENU(KHUI_MENU_MAIN, KHUI_MENUSTATE_CONSTANT, khui_main_menu),
174
CONSTMENU(KHUI_MENU_FILE, KHUI_MENUSTATE_CONSTANT, khui_menu_file),
175
CONSTMENU(KHUI_MENU_CRED, KHUI_MENUSTATE_CONSTANT, khui_menu_cred),
176
CONSTMENU(KHUI_MENU_VIEW, KHUI_MENUSTATE_CONSTANT, khui_menu_view),
177
CONSTMENU(KHUI_MENU_LAYOUT, KHUI_MENUSTATE_CONSTANT, khui_menu_layout),
178
CONSTMENU(KHUI_MENU_TOOLBARS, KHUI_MENUSTATE_CONSTANT, khui_menu_toolbars),
179
CONSTMENU(KHUI_MENU_OPTIONS, KHUI_MENUSTATE_CONSTANT, khui_menu_options),
180
CONSTMENU(KHUI_MENU_HELP, KHUI_MENUSTATE_CONSTANT, khui_menu_help),
198
CONSTMENU(KHUI_MENU_MAIN, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_main_menu),
199
CONSTMENU(KHUI_MENU_FILE, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_menu_file),
200
CONSTMENU(KHUI_MENU_CRED, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_menu_cred),
201
CONSTMENU(KHUI_MENU_VIEW, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_menu_view),
202
CONSTMENU(KHUI_MENU_LAYOUT, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_menu_layout),
203
CONSTMENU(KHUI_MENU_TOOLBARS, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_menu_toolbars),
204
CONSTMENU(KHUI_MENU_OPTIONS, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_menu_options),
205
CONSTMENU(KHUI_MENU_HELP, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_menu_help),
206
CONSTMENU(KHUI_MENU_COLUMNS, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_menu_columns),
183
CONSTMENU(KHUI_TOOLBAR_STANDARD, KHUI_MENUSTATE_CONSTANT, khui_toolbar_standard),
209
CONSTMENU(KHUI_TOOLBAR_STANDARD, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_toolbar_standard),
185
211
/* context menus */
186
212
CONSTMENU(KHUI_MENU_IDENT_CTX, KHUI_MENUSTATE_CONSTANT, khui_menu_ident_ctx),
187
213
CONSTMENU(KHUI_MENU_TOK_CTX, KHUI_MENUSTATE_CONSTANT, khui_menu_tok_ctx),
188
214
CONSTMENU(KHUI_MENU_ICO_CTX_MIN, KHUI_MENUSTATE_CONSTANT, khui_menu_ico_ctx_min),
189
215
CONSTMENU(KHUI_MENU_ICO_CTX_NORMAL, KHUI_MENUSTATE_CONSTANT, khui_menu_ico_ctx_normal),
216
CONSTMENU(KHUI_MENU_CWHEADER_CTX, KHUI_MENUSTATE_CONSTANT, khui_menu_cwheader_ctx),
191
218
/* pseudo menus */
192
219
CONSTMENU(KHUI_PMENU_TOK_SEL, KHUI_MENUSTATE_CONSTANT, khui_pmenu_tok_sel),
206
247
DeleteCriticalSection(&cs_actions);
250
KHMEXP khm_int32 KHMAPI
251
khui_action_create(const wchar_t * name,
252
const wchar_t * caption,
253
const wchar_t * tooltip,
258
khm_int32 action = 0;
263
FAILED(StringCchLength(caption, KHUI_MAXCCH_SHORT_DESC, &s)) ||
264
(tooltip && FAILED(StringCchLength(tooltip, KHUI_MAXCCH_SHORT_DESC, &s))) ||
265
(type != KHUI_ACTIONTYPE_TRIGGER && type != KHUI_ACTIONTYPE_TOGGLE)) {
269
EnterCriticalSection(&cs_actions);
270
if (name && (act = khui_find_named_action(name))) {
271
/* named action already exists */
276
for (i=0; i < khui_n_cust_actions; i++) {
277
if (khui_cust_actions[i] == NULL ||
278
(khui_cust_actions[i]->state & KHUI_ACTIONSTATE_DELETED))
282
if (i >= khui_n_cust_actions &&
283
(khui_cust_actions == NULL ||
284
khui_n_cust_actions + 1 > khui_nc_cust_actions)) {
286
khui_nc_cust_actions = UBOUNDSS(khui_n_cust_actions + 1,
290
assert(khui_nc_cust_actions > khui_n_cust_actions + 1);
292
khui_cust_actions = PREALLOC(khui_cust_actions,
293
sizeof(*khui_cust_actions) * khui_nc_cust_actions);
295
assert(khui_cust_actions);
299
if (i >= khui_n_cust_actions) {
300
i = khui_n_cust_actions ++;
301
act = PMALLOC(sizeof(khui_action));
303
act = khui_cust_actions[i];
305
act = PMALLOC(sizeof(khui_action));
312
khui_cust_actions[i] = act;
314
ZeroMemory(act, sizeof(*act));
316
act->cmd = KHUI_USERACTION_BASE + i;
318
act->name = (name? PWCSDUP(name) : 0);
319
act->caption = PWCSDUP(caption);
320
act->tooltip = (tooltip? PWCSDUP(tooltip) : 0);
321
act->listener = hsub;
322
act->data = userdata;
328
LeaveCriticalSection(&cs_actions);
331
kmq_post_message(KMSG_ACT, KMSG_ACT_NEW, action, NULL);
337
khui_action_get_data(khm_int32 action) {
340
act = khui_find_action(action);
349
khui_action_delete(khm_int32 action) {
352
act = khui_find_action(action);
357
/* for the moment, even when the action is deleted, we don't free
358
up the block of memory used by the khui_action structure. When
359
a new action is created, it will reuse deleted action
361
EnterCriticalSection(&cs_actions);
362
act->state |= KHUI_ACTIONSTATE_DELETED;
370
kmq_delete_subscription(act->listener);
374
act->listener = NULL;
375
LeaveCriticalSection(&cs_actions);
377
kmq_post_message(KMSG_ACT, KMSG_ACT_DELETE, action, NULL);
209
380
#define MENU_NC_ITEMS 8
211
382
KHMEXP khui_menu_def * KHMAPI
212
khui_menu_create(int cmd)
383
khui_menu_create(khm_int32 action)
214
385
khui_menu_def * d;
215
d = malloc(sizeof(*d));
387
d = PMALLOC(sizeof(*d));
216
388
ZeroMemory(d, sizeof(*d));
219
391
d->nc_items = MENU_NC_ITEMS;
220
d->items = malloc(sizeof(*(d->items)) * d->nc_items);
392
d->items = PMALLOC(sizeof(*(d->items)) * d->nc_items);
222
394
d->state = KHUI_MENUSTATE_ALLOCD;
398
EnterCriticalSection(&cs_actions);
400
for (i=0; i < khui_n_cust_menus; i++) {
401
if (khui_cust_menus[i] == NULL)
405
if (i >= khui_n_cust_menus) {
407
if (khui_n_cust_menus + 1 >= khui_nc_cust_menus) {
408
khui_nc_cust_menus = UBOUNDSS(khui_n_cust_menus + 1,
409
CACT_NC_ALLOC, CACT_NC_ALLOC);
411
PREALLOC(khui_cust_menus,
412
sizeof(khui_cust_menus[0]) * khui_nc_cust_menus);
415
i = khui_n_cust_menus ++;
418
khui_cust_menus[i] = d;
420
LeaveCriticalSection(&cs_actions);
427
khui_set_main_window(HWND hwnd) {
428
khui_hwnd_main = hwnd;
432
khui_action_trigger(khm_int32 action, khui_action_context * ctx) {
433
khui_action_context save;
439
khui_context_get(&save);
441
khui_context_set_indirect(ctx);
444
SendMessage(khui_hwnd_main, WM_COMMAND,
445
MAKEWPARAM(action, 0), (LPARAM) 0);
448
khui_context_set_indirect(&save);
227
452
KHMEXP khui_menu_def * KHMAPI
228
453
khui_menu_dup(khui_menu_def * src)
257
482
/* non-allocated menus are assumed to have no pointers to other
258
483
allocated blocks */
259
if(!(d->state & KHUI_MENUSTATE_ALLOCD))
484
if(!(d->state & KHUI_MENUSTATE_ALLOCD)) {
485
/* we shouldn't have tried to delete a constant menu */
492
EnterCriticalSection(&cs_actions);
493
for (i=0; i < khui_n_cust_menus; i++) {
494
if (khui_cust_menus[i] == d) {
495
khui_cust_menus[i] = NULL;
499
LeaveCriticalSection(&cs_actions);
262
501
for(i=0; i< (int) d->n_items; i++) {
263
502
if(d->items[i].flags & KHUI_ACTIONREF_FREE_PACTION)
264
free(d->items[i].p_action);
503
PFREE(d->items[i].p_action);
272
static void khui_menu_assert_size(khui_menu_def * d, size_t n)
512
menu_assert_size(khui_menu_def * d, size_t n)
515
assert(d->state & KHUI_MENUSTATE_ALLOCD);
274
517
if(n > (int) d->nc_items) {
275
518
khui_action_ref * ni;
277
520
d->nc_items = UBOUNDSS(n, MENU_NC_ITEMS, MENU_NC_ITEMS);
278
ni = malloc(sizeof(*(d->items)) * d->nc_items);
521
ni = PMALLOC(sizeof(*(d->items)) * d->nc_items);
279
522
memcpy(ni, d->items, sizeof(*(d->items)) * d->n_items);
285
KHMEXP void KHMAPI khui_menu_add_action(khui_menu_def * d, int id)
287
khui_menu_assert_size(d, d->n_items + 1);
288
d->items[d->n_items].flags = 0;
289
d->items[d->n_items ++].action = id;
292
KHMEXP void KHMAPI khui_menu_add_paction(khui_menu_def * d, khui_action * act, int flags)
294
khui_menu_assert_size(d, d->n_items + 1);
295
d->items[d->n_items].flags = flags | KHUI_ACTIONREF_PACTION;
296
d->items[d->n_items ++].p_action = act;
299
KHMEXP khui_menu_def * KHMAPI khui_find_menu(int id) {
529
menu_const_to_allocd(khui_menu_def * d)
531
khui_action_ref * olist;
532
khui_action_ref * nlist;
535
assert(!(d->state & KHUI_MENUSTATE_ALLOCD));
538
n = khui_action_list_length(d->items);
540
d->nc_items = UBOUNDSS(n, MENU_NC_ITEMS, MENU_NC_ITEMS);
541
nlist = PMALLOC(sizeof(d->items[0]) * d->nc_items);
542
memcpy(nlist, olist, sizeof(d->items[0]) * n);
546
d->state |= KHUI_MENUSTATE_ALLOCD;
550
khui_menu_insert_action(khui_menu_def * d, khm_size idx, khm_int32 action, khm_int32 flags)
552
if (!(d->state & KHUI_MENUSTATE_ALLOCD))
553
menu_const_to_allocd(d);
555
assert(d->state & KHUI_MENUSTATE_ALLOCD);
556
assert(action == KHUI_MENU_SEP || action > 0);
558
if (idx < 0 || idx > d->n_items)
561
menu_assert_size(d, d->n_items + 1);
563
if (idx < d->n_items) {
564
memmove(&d->items[idx + 1], &d->items[idx], (d->n_items - idx) * sizeof(d->items[0]));
567
d->items[idx].flags = flags;
568
d->items[idx].action = action;
569
if (action == KHUI_MENU_SEP)
570
d->items[idx].flags |= KHUI_ACTIONREF_SEP;
576
khui_menu_insert_paction(khui_menu_def * d, khm_size idx, khui_action * paction, int flags)
582
if (!(d->state & KHUI_MENUSTATE_ALLOCD))
583
menu_const_to_allocd(d);
585
assert(d->state & KHUI_MENUSTATE_ALLOCD);
587
if (idx < 0 || idx > d->n_items)
590
menu_assert_size(d, d->n_items + 1);
592
if (idx < d->n_items) {
593
memmove(&d->items[idx + 1], &d->items[idx], (d->n_items - idx) * sizeof(d->items[0]));
596
d->items[idx].flags = flags | KHUI_ACTIONREF_PACTION;
597
d->items[idx].p_action = paction;
603
khui_menu_remove_action(khui_menu_def * d, khm_size idx) {
605
assert(d->state & KHUI_MENUSTATE_ALLOCD);
607
if (idx < 0 || idx >= d->n_items)
610
if (idx < d->n_items - 1) {
611
memmove(&d->items[idx], &d->items[idx + 1],
612
((d->n_items - 1) - idx) * sizeof(d->items[0]));
618
KHMEXP khm_size KHMAPI
619
khui_menu_get_size(khui_menu_def * d) {
621
if (d->state & KHUI_MENUSTATE_ALLOCD)
624
return khui_action_list_length(d->items);
627
KHMEXP khui_action_ref *
628
khui_menu_get_action(khui_menu_def * d, khm_size idx) {
632
if (d->state & KHUI_MENUSTATE_ALLOCD)
635
n = khui_action_list_length(d->items);
637
if (idx < 0 || idx >= n)
640
return &d->items[idx];
643
KHMEXP khui_menu_def * KHMAPI
644
khui_find_menu(khm_int32 id) {
300
645
khui_menu_def * d;
304
for(i=0;i<khui_n_all_menus;i++) {
648
if (id < KHUI_USERACTION_BASE) {
650
for(i=0;i<khui_n_all_menus;i++) {
659
EnterCriticalSection(&cs_actions);
660
for (i=0; i < khui_n_cust_menus; i++) {
661
if (khui_cust_menus[i] &&
662
khui_cust_menus[i]->cmd == id) {
663
d = khui_cust_menus[i];
667
LeaveCriticalSection(&cs_actions);
312
KHMEXP khui_action * KHMAPI khui_find_action(int id) {
673
KHMEXP khui_action * KHMAPI
674
khui_find_action(khm_int32 id) {
313
675
khui_action * act;
718
pact = khui_cust_actions;
719
for(i=0;i<khui_n_cust_actions;i++) {
720
if(!pact[i] || !pact[i]->name)
723
if(!wcscmp(pact[i]->name, name)) {
724
if (pact[i]->state & KHUI_ACTIONSTATE_DELETED)
343
KHMEXP size_t KHMAPI khui_action_list_length(khui_action_ref * ref) {
735
khui_action_list_length(khui_action_ref * ref) {
345
while(ref && ref->action != KHUI_MENU_END) {
737
while(ref && ref->action != KHUI_MENU_END &&
738
!(ref->flags & KHUI_ACTIONREF_END)) {
352
KHMEXP void KHMAPI khui_check_radio_action(khui_menu_def * d, khm_int32 cmd)
746
khui_check_radio_action(khui_menu_def * d, khm_int32 cmd)
354
748
khui_action_ref * r;
355
749
khui_action * act;
358
while(r && r->action != KHUI_MENU_END) {
752
while(r && r->action != KHUI_MENU_END &&
753
(!(d->state & KHUI_MENUSTATE_ALLOCD) || (r - d->items) < (int) d->n_items)) {
359
754
if(r->flags & KHUI_ACTIONREF_PACTION) {
360
755
act = r->p_action;