libxputty  0.1
A damn tiny abstraction Layer to create X11 window/widgets with cairo surfaces
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
xmenu.c
Go to the documentation of this file.
1 /*
2  * 0BSD
3  *
4  * BSD Zero Clause License
5  *
6  * Copyright (c) 2019 Hermann Meyer
7  *
8  * Permission to use, copy, modify, and/or distribute this software for any
9  * purpose with or without fee is hereby granted.
10 
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13  * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  *
19  */
20 
21 
22 #include "xmenu.h"
23 #include "xmenu_private.h"
24 
25 
26 void pop_menu_show(Widget_t *parent, Widget_t *menu, int elem, bool above) {
27  if (!childlist_has_child(menu->childlist)) return;
28  Widget_t* view_port = menu->childlist->childs[0];
29  if (!view_port->childlist->elem) return;
30  _configure_menu(parent, menu, elem, above);
31  pop_widget_show_all(menu);
32  int err = XGrabPointer(menu->app->dpy, DefaultRootWindow(parent->app->dpy), True,
33  ButtonPressMask|ButtonReleaseMask|PointerMotionMask,
34  GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
35  menu->app->hold_grab = menu;
36 
37  if (err) debug_print("Error grap pointer\n");
38 }
39 
40 Widget_t* create_viewport(Widget_t *parent, int width, int height) {
41  Widget_t *wid = create_widget(parent->app, parent, 0, 0, width, height);
42  wid->scale.gravity = NONE;
43  wid->flags &= ~USE_TRANSPARENCY;
44  wid->adj_y = add_adjustment(wid,0.0, 0.0, 0.0, -1.0,1.0, CL_VIEWPORT);
45  wid->adj = wid->adj_y;
48  return wid;
49 }
50 
51 void set_active_radio_entry(void *w_, void* user_data) {
52  Widget_t *w = (Widget_t*)w_;
53  int v = (int)adj_get_value(w->adj);
54  Widget_t *menu = w->childlist->childs[0];
55  Widget_t *view_port = menu->childlist->childs[0];
56  if (!childlist_has_child(view_port->childlist)) return;
57  int i = view_port->childlist->elem-1;
58  if (v > i || v < 0) return;
59  Widget_t *wi = view_port->childlist->childs[v];
60  for(;i>-1;i--) {
61  Widget_t *wid = view_port->childlist->childs[i];
62  if (wid->adj && wid->flags & IS_RADIO) {
63  if (wid == wi) adj_set_value(wid->adj_y, 1.0);
64  else adj_set_value(wid->adj_y, 0.0);
65  }
66  }
67 }
68 
69 Widget_t* add_menu(Widget_t *parent, const char * label,
70  int x, int y, int width, int height) {
71  Widget_t *wid = create_widget(parent->app, parent, x, y, width, height);
72  wid->label = label;
73  wid->adj_y = add_adjustment(wid,0.0, 0.0, 0.0, -1.0,1.0, CL_NONE);
74  wid->adj = wid->adj_y;
75  wid->scale.gravity = NONE;
76  wid->state = 0;
82 
83  Widget_t* menu = create_menu(wid, 25);
85 
86  return wid;
87 }
88 
89 Widget_t *menu_add_entry(Widget_t *wid, const char * label) {
90  Widget_t *menu = wid->childlist->childs[0];
91  Widget_t *item = menu_add_accel_item(menu,label);
92  float max_value = wid->adj->max_value+1.0;
93  set_adjustment(wid->adj,0.0, max_value, 0.0, max_value,1.0, CL_NONE);
94 
95  return item;
96 }
97 
98 Widget_t *menu_add_radio_entry(Widget_t *wid, const char * label) {
99  Widget_t *menu = wid->childlist->childs[0];
100  Widget_t *item = menu_add_radio_item(menu,label);
101  float max_value = wid->adj->max_value+1.0;
102  set_adjustment(wid->adj,0.0, max_value, 0.0, max_value,1.0, CL_NONE);
103 
104  return item;
105 }
106 
107 Widget_t* create_menu(Widget_t *parent, int height) {
108 
109  int x1, y1;
110  Window child;
111  XTranslateCoordinates( parent->app->dpy, parent->widget, DefaultRootWindow(parent->app->dpy), 0, 0, &x1, &y1, &child );
112  Widget_t *wid = create_window(parent->app, DefaultRootWindow(parent->app->dpy), x1, y1, 10, height);
113  create_viewport(wid, 10, 5*height);
114 
115  XSetWindowAttributes attributes;
116  attributes.override_redirect = True;
117  XChangeWindowAttributes(parent->app->dpy, wid->widget, CWOverrideRedirect, &attributes);
118 
119  Atom window_type = XInternAtom(wid->app->dpy, "_NET_WM_WINDOW_TYPE", False);
120  Atom window_type_popup = XInternAtom(wid->app->dpy, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", False);
121  XChangeProperty(wid->app->dpy, wid->widget, window_type,
122  XA_ATOM, 32, PropModeReplace, (unsigned char *) &window_type_popup,1 );
123 
124  Atom window_state = XInternAtom(wid->app->dpy, "_NET_WM_STATE", False);
125  Atom window_state_modal = XInternAtom(wid->app->dpy, "_NET_WM_STATE_MODAL", False);
126  XChangeProperty(wid->app->dpy, wid->widget, window_state,
127  XA_ATOM, 32, PropModeReplace, (unsigned char *) &window_state_modal, 1);
128 
129  XSetTransientForHint(parent->app->dpy,wid->widget,parent->widget);
131  wid->flags |= IS_POPUP;
132  wid->scale.gravity = NONE;
133  childlist_add_child(parent->childlist, wid);
134  return wid;
135 }
136 
137 Widget_t* menu_add_item(Widget_t *menu,const char * label) {
138  Widget_t* view_port = menu->childlist->childs[0];
139  XWindowAttributes attrs;
140  XGetWindowAttributes(menu->app->dpy, (Window)menu->widget, &attrs);
141  int width = attrs.width;
142  int height = attrs.height;
143  int si = childlist_has_child(view_port->childlist);
144  Widget_t *wid = create_widget(menu->app, view_port, 0, height*si, width, height);
145  float max_value = view_port->adj->max_value+1.0;
146  set_adjustment(view_port->adj,0.0, 0.0, 0.0, max_value,1.0, CL_VIEWPORT);
147  wid->scale.gravity = MENUITEM;
148  wid->flags &= ~USE_TRANSPARENCY;
149  wid->label = label;
153  return wid;
154 }
155 
156 Widget_t* menu_add_accel_item(Widget_t *menu,const char * label) {
157  Widget_t *wid = menu_add_item(menu, label);
159  return wid;
160 }
161 
162 Widget_t* menu_add_check_item(Widget_t *menu, const char * label) {
163  Widget_t *wid = menu_add_item(menu, label);
164  wid->adj_y = add_adjustment(wid,0.0, 0.0, 0.0, 1.0,1.0, CL_TOGGLE);
165  wid->adj = wid->adj_y;
168  return wid;
169 }
170 
172  Widget_t * p = (Widget_t*) w->parent;
173  int i = p->childlist->elem-1;
174  for(;i>-1;i--) {
175  Widget_t *wid = p->childlist->childs[i];
176  if (wid->adj && wid->flags & IS_RADIO) {
177  if (wid == w) adj_set_value(wid->adj_y, 1.0);
178  else adj_set_value(wid->adj_y, 0.0);
179  }
180  }
181 }
182 
183 Widget_t* menu_add_radio_item(Widget_t *menu, const char * label) {
184  Widget_t *wid = menu_add_check_item(menu, label);
185  wid->flags |= IS_RADIO;
189  return wid;
190 }
191 
192 
193 void menu_add_numeric_items(Widget_t *menu, int *imin, int *imax) {
194  Widget_t* view_port = menu->childlist->childs[0];
195  XWindowAttributes attrs;
196  XGetWindowAttributes(menu->app->dpy, (Window)menu->widget, &attrs);
197  int width = attrs.width;
198  int height = attrs.height;
199  int si = childlist_has_child(view_port->childlist);
200  float max_value = view_port->adj->max_value;
201  Widget_t *wid;
202  int i = (*imin);
203  int o = (*imax)+1;
204  for (;i<o;i++) {
205  si = childlist_has_child(view_port->childlist);
206  wid = create_widget(menu->app, view_port, 0, height*si, width, height);
207  max_value += 1.0;
208  set_adjustment(view_port->adj,0.0, 0.0, 0.0, max_value,1.0, CL_VIEWPORT);
209  wid->scale.gravity = MENUITEM;
210  wid->flags &= ~USE_TRANSPARENCY;
211  snprintf(wid->input_label, 31, "%i",i);
212  wid->label = wid->input_label;
216  }
217 }
Func_t::leave_callback
xevfunc leave_callback
Definition: xwidget.h:83
menu_add_numeric_items
void menu_add_numeric_items(Widget_t *menu, int *imin, int *imax)
menu_add_numeric_items - add numeric items from imin to imax to menu
Definition: xmenu.c:193
Func_t::enter_callback
xevfunc enter_callback
Definition: xwidget.h:82
CL_TOGGLE
@ CL_TOGGLE
Definition: xadjustment.h:51
Resize_t::gravity
Gravity gravity
Definition: xwidget.h:192
pop_widget_show_all
void pop_widget_show_all(Widget_t *w)
pop_widget_show_all - map/show popup widget with all it's childs
Definition: xwidget.c:418
MENUITEM
@ MENUITEM
Definition: xwidget.h:171
_draw_check_item
void _draw_check_item(void *w_, void *user_data)
_draw_check_item - draw item on expose call
Definition: xmenu_private.c:210
_radio_item_button_pressed
void _radio_item_button_pressed(void *w_, void *button_, void *user_data)
_radio_item_button_pressed - redraw item on button press
Definition: xmenu_private.c:274
_draw_viewslider
void _draw_viewslider(void *w_, void *user_data)
_draw_viewslider - draw a slider on the viewport to indicate the view point
Definition: xmenu_private.c:234
menu_add_check_item
Widget_t * menu_add_check_item(Widget_t *menu, const char *label)
menu_add_check_item - add a item to menu
Definition: xmenu.c:162
_draw_menu_label
void _draw_menu_label(void *w_, void *user_data)
_draw_menu_label - draw the menu label on expose call
Definition: xmenu_private.c:44
NONE
@ NONE
Definition: xwidget.h:173
Childlist_t::childs
Widget_t ** childs
Definition: xchildlist.h:51
childlist_add_child
void childlist_add_child(Childlist_t *childlist, Widget_t *child)
childlist_add_child - internal use to add a child to the Childlist_t You usually didn't need to cal...
Definition: xchildlist.c:42
create_widget
Widget_t * create_widget(Xputty *app, Widget_t *win, int x, int y, int width, int height)
*create_widget - create a widget A Widget_t could only be created as child of a other Widget_t To...
Definition: xwidget.c:268
transparent_draw
void transparent_draw(void *wid, void *user_data)
transparent_draw - copy parent surface to child surface you usaualy didn't need to call this,...
Definition: xwidget.c:469
Func_t::expose_callback
xevfunc expose_callback
Definition: xwidget.h:80
adj_get_value
float adj_get_value(Adjustment_t *adj)
adj_get_value - get the current value of the Adjustment_t
Definition: xadjustment.c:154
_set_viewpoint
void _set_viewpoint(void *w_, void *user_data)
_set_viewpoint - move the view_port to position
Definition: xmenu_private.c:257
xmenu_private.h
radio_item_set_active
void radio_item_set_active(Widget_t *w)
radio_item_set_active - activate selected radio item
Definition: xmenu.c:171
Widget_t::flags
long long flags
Definition: xwidget.h:324
adj_set_value
void adj_set_value(Adjustment_t *adj, float value)
adj_set_value - set the current value to the Adjustment_t
Definition: xadjustment.c:163
Widget_t::adj
Adjustment_t * adj
Definition: xwidget.h:334
menu_add_entry
Widget_t * menu_add_entry(Widget_t *wid, const char *label)
menu_add_entry - add a entry to menu
Definition: xmenu.c:89
Widget_t::scale
Resize_t scale
Definition: xwidget.h:356
CL_VIEWPORT
@ CL_VIEWPORT
Definition: xadjustment.h:57
Xputty::hold_grab
Widget_t * hold_grab
Definition: xputty.h:185
menu_add_item
Widget_t * menu_add_item(Widget_t *menu, const char *label)
menu_add_item - add a item to menu
Definition: xmenu.c:137
Widget_t::app
Xputty * app
Definition: xwidget.h:300
create_menu
Widget_t * create_menu(Widget_t *parent, int height)
create_menu - create a menu to a Widget_t
Definition: xmenu.c:107
_draw_menu
void _draw_menu(void *w_, void *user_data)
_draw_menu - draw menu on expose call
Definition: xmenu_private.c:122
Func_t::button_press_callback
evfunc button_press_callback
Definition: xwidget.h:93
Xputty::dpy
Display * dpy
Definition: xputty.h:181
USE_TRANSPARENCY
@ USE_TRANSPARENCY
Definition: xwidget.h:243
pop_menu_show
void pop_menu_show(Widget_t *parent, Widget_t *menu, int elem, bool above)
pop_menu_show - pop up a menu to a Widget_t
Definition: xmenu.c:26
_check_item_button_pressed
void _check_item_button_pressed(void *w_, void *button_, void *user_data)
_check_item_button_pressed - redraw item on button press
Definition: xmenu_private.c:266
menu_add_radio_item
Widget_t * menu_add_radio_item(Widget_t *menu, const char *label)
menu_add_radio_item - add a radio item to menu
Definition: xmenu.c:183
IS_RADIO
@ IS_RADIO
Definition: xwidget.h:239
_draw_item
void _draw_item(void *w_, void *user_data)
_draw_item - draw item on expose call
Definition: xmenu_private.c:129
_configure_menu
void _configure_menu(Widget_t *parent, Widget_t *menu, int elem, bool above)
_configure_menu - set final size and position of menu to a Widget_t
Definition: xmenu_private.c:281
Widget_t::state
int state
Definition: xwidget.h:342
xmenu.h
Widget_t::widget
Window widget
Definition: xwidget.h:302
debug_print
#define debug_print(...)
debug_print - print out state messages when compiled with the -DDEBUG flag
Definition: xputty.h:64
_draw_accel_item
void _draw_accel_item(void *w_, void *user_data)
_draw_accel_item - draw accel item on expose call
Definition: xmenu_private.c:162
Widget_t
Widget_t - struct to hold the basic Widget_t info.
Definition: xwidget.h:298
set_active_radio_entry
void set_active_radio_entry(void *w_, void *user_data)
Definition: xmenu.c:51
menu_add_radio_entry
Widget_t * menu_add_radio_entry(Widget_t *wid, const char *label)
menu_add_radio_entry- add a radio entry to menu
Definition: xmenu.c:98
IS_POPUP
@ IS_POPUP
Definition: xwidget.h:237
Func_t::button_release_callback
evfunc button_release_callback
Definition: xwidget.h:94
Widget_t::childlist
Childlist_t * childlist
Definition: xwidget.h:336
create_window
Widget_t * create_window(Xputty *app, Window win, int x, int y, int width, int height)
*create_window - create a Window You need to create as least minimun one Window to get started....
Definition: xwidget.c:145
Adjustment_t::max_value
float max_value
Definition: xadjustment.h:90
create_viewport
Widget_t * create_viewport(Widget_t *parent, int width, int height)
create_viewport - create a viewport on a menu to a Widget_t
Definition: xmenu.c:40
set_adjustment
void set_adjustment(Adjustment_t *adj, float std_value, float value, float min_value, float max_value, float step, CL_type type)
*set_adjustment - set a new range to a existing Adjustment_t it will be created if it not exsits yet
Definition: xadjustment.c:80
Func_t::adj_callback
xevfunc adj_callback
Definition: xwidget.h:84
Childlist_t::elem
int elem
Definition: xchildlist.h:57
Widget_t::input_label
char input_label[32]
Definition: xwidget.h:328
Widget_t::adj_y
Adjustment_t * adj_y
Definition: xwidget.h:332
Widget_t::func
Func_t func
Definition: xwidget.h:310
CL_NONE
@ CL_NONE
Definition: xadjustment.h:47
menu_add_accel_item
Widget_t * menu_add_accel_item(Widget_t *menu, const char *label)
menu_add_accel_item - add a accel item to menu
Definition: xmenu.c:156
add_adjustment
Adjustment_t * add_adjustment(Widget_t *w, float std_value, float value, float min_value, float max_value, float step, CL_type type)
*add_adjustment - adding a adjustment to a Widget_t
Definition: xadjustment.c:25
childlist_has_child
int childlist_has_child(Childlist_t *childlist)
childlist_has_child - check if a Widget_t Childlist_t contain a child
Definition: xchildlist.c:91
Widget_t::parent
void * parent
Definition: xwidget.h:304
Widget_t::label
const char * label
Definition: xwidget.h:326
_menu_entry_released
void _menu_entry_released(void *w_, void *item_, void *user_data)
_menu_entry_released - the menu release func
Definition: xmenu_private.c:105
_menu_released
void _menu_released(void *w_, void *button_, void *user_data)
_menu_released - popup the menu on click
Definition: xmenu_private.c:97
add_menu
Widget_t * add_menu(Widget_t *parent, const char *label, int x, int y, int width, int height)
add_menu - add a menu to a Widget_t
Definition: xmenu.c:69
_check_menu_state
void _check_menu_state(void *w_, void *user_data)
_check_menu_state - follow the mouse pointer when a menu is active
Definition: xmenu_private.c:78