File: mkmenu.c

package info (click to toggle)
notion 4.0.2%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 4,676 kB
  • sloc: ansic: 47,508; sh: 2,096; makefile: 603; perl: 270
file content (126 lines) | stat: -rw-r--r-- 3,566 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
 * ion/mod_menu/mkmenu.c
 *
 * Copyright (c) Tuomo Valkonen 1999-2007.
 *
 * See the included file LICENSE for details.
 */

#include <limits.h>
#include <ioncore/common.h>
#include <ioncore/pointer.h>
#include <ioncore/stacking.h>
#include <ioncore/grab.h>
#include <libextl/extl.h>
#include "menu.h"
#include "mkmenu.h"


/*--lowlevel routine not to be called by the user--EXTL_DOC
 * Display a menu inside multiplexer. The \var{handler} parameter
 * is a function that gets the selected menu entry as argument and
 * should call it with proper parameters. The table \var{tab} is a
 * list of menu entries of the form \code{\{name = ???, [ submenu_fn = ??? ]\}}.
 * The function \var{submenu_fn} return a similar submenu definition
 * when called.
 *
 * Do not use this function directly. Use  \fnref{mod_menu.menu} and
 * \fnref{mod_menu.bigmenu}.
 */
EXTL_EXPORT
WMenu *mod_menu_do_menu(WMPlex *mplex, ExtlFn handler, ExtlTab tab,
                        ExtlTab param)
{
    WMenuCreateParams fnp;
    WMPlexAttachParams par=MPLEXATTACHPARAMS_INIT;

    fnp.handler=handler;
    fnp.tab=tab;
    fnp.pmenu_mode=FALSE;
    fnp.submenu_mode=FALSE;
    fnp.big_mode=extl_table_is_bool_set(param, "big");
    fnp.initial=0;
    extl_table_gets_i(param, "initial", &(fnp.initial));
    fnp.refg.x=0;
    fnp.refg.y=0;
    fnp.refg.w=0;
    fnp.refg.h=0;

    par.flags=(MPLEX_ATTACH_SWITCHTO|
               MPLEX_ATTACH_LEVEL|
               MPLEX_ATTACH_UNNUMBERED|
               MPLEX_ATTACH_SIZEPOLICY);
    par.szplcy=SIZEPOLICY_FULL_BOUNDS;
    par.level=STACKING_LEVEL_MODAL1+1;

    return (WMenu*)mplex_do_attach_new(mplex, &par,
                                       (WRegionCreateFn*)create_menu,
                                       (void*)&fnp);
}


/*--lowlevel routine not to be called by the user--EXTL_DOC
 * Display a pop-up menu inside window \var{where}. This function
 * can only be called from a mouse/pointing device button press handler
 * and the menu will be placed below the point where the press occured.
 * The \var{handler} and \var{tab} parameters are similar to those of
 * \fnref{menu_menu}.
 *
 * Do not use this function directly. Use \fnref{mod_menu.pmenu}.
 */
EXTL_EXPORT
WMenu *mod_menu_do_pmenu(WWindow *where, ExtlFn handler, ExtlTab tab)
{
    WScreen *scr;
    WMenuCreateParams fnp;
    XEvent *ev=ioncore_current_pointer_event();
    WMenu *menu;
    WFitParams fp;

    if(ev==NULL || ev->type!=ButtonPress)
        return NULL;

    scr=region_screen_of((WRegion*)where);

    if(scr==NULL)
        return NULL;

    fnp.handler=handler;
    fnp.tab=tab;
    fnp.pmenu_mode=TRUE;
    fnp.big_mode=FALSE;
    fnp.submenu_mode=FALSE;
    fnp.initial=0;
    fnp.refg.x=ev->xbutton.x_root-REGION_GEOM(scr).x;
    fnp.refg.y=ev->xbutton.y_root-REGION_GEOM(scr).y;
    fnp.refg.w=0;
    fnp.refg.h=0;

    fp.mode=REGION_FIT_BOUNDS;
    fp.g.x=REGION_GEOM(where).x;
    fp.g.y=REGION_GEOM(where).y;
    fp.g.w=REGION_GEOM(where).w;
    fp.g.h=REGION_GEOM(where).h;

    menu=create_menu((WWindow*)scr, &fp, &fnp);

    if(menu==NULL)
        return NULL;

    region_restack((WRegion*)menu, None, Above);

    if(!ioncore_set_drag_handlers((WRegion*)menu,
                            NULL,
                            (WMotionHandler*)menu_motion,
                            (WButtonHandler*)menu_release,
                            NULL,
                            (GrabKilledHandler*)menu_cancel)){
        destroy_obj((Obj*)menu);
        return NULL;
    }

    region_map((WRegion*)menu);

    return menu;
}