4 * Part of gwm, the Gratuitous Window Manager,
5 * by Gary Wong, <gtw@gnu.org>.
7 * Copyright (C) 2009 Gary Wong
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of version 3 of the GNU General Public License as
11 * published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
33 #include "window-table.h"
35 static void root_key_press( struct gwm_window
*window
,
36 xcb_key_press_event_t
*ev
) {
40 for( i
= 0; i
< NUM_KEY_ACTIONS
; i
++ )
41 if( keyboard_map
[ ev
->detail
][ 0 ] == key_actions
[ i
].keysym
&&
42 ( ev
->state
& 0xFF & key_actions
[ i
].modifiers
) ==
43 key_actions
[ i
].modifiers
) {
44 key_actions
[ i
].handler( window
, (xcb_generic_event_t
*) ev
);
50 static const struct button_action
{
52 xcb_mod_mask_t modifiers
;
53 void ( *handler
)( struct gwm_window
*window
, xcb_generic_event_t
*ev
);
54 } button_actions
[] = {
55 /* FIXME This table should be configurable, of course. */
56 { 1, 0, action_map_all_icons
},
57 { 3, 0, action_start_xterm
}
60 #define NUM_BUTTON_ACTIONS ( sizeof button_actions / sizeof *button_actions )
62 static void root_button_press( struct gwm_window
*window
,
63 xcb_button_press_event_t
*ev
) {
70 for( i
= 0; i
< NUM_BUTTON_ACTIONS
; i
++ )
71 if( ev
->detail
== button_actions
[ i
].button
&&
72 ( ev
->state
& 0xFF & button_actions
[ i
].modifiers
) ==
73 button_actions
[ i
].modifiers
) {
74 button_actions
[ i
].handler( window
, (xcb_generic_event_t
*) ev
);
80 static void root_enter_notify( struct gwm_window
*window
,
81 xcb_enter_notify_event_t
*ev
) {
83 if( focus_frame
&& ( ev
->detail
== XCB_NOTIFY_DETAIL_INFERIOR
||
84 ev
->detail
== XCB_NOTIFY_DETAIL_NONLINEAR
) ) {
85 deactivate_focus_frame();
87 xcb_set_input_focus( c
, XCB_INPUT_FOCUS_NONE
,
88 XCB_INPUT_FOCUS_POINTER_ROOT
, ev
->time
);
93 install_window_colormap( window
->screen
, NULL
, ev
->time
);
96 static void root_map_request( struct gwm_window
*window
,
97 xcb_map_request_event_t
*ev
) {
99 manage_window( ev
->window
, TRUE
);
102 static void root_configure_request( struct gwm_window
*window
,
103 xcb_configure_request_event_t
*ev
) {
105 uint32_t values
[ 7 ];
107 /* Configuring an unmanaged window -- just honour the request as is. */
108 if( ev
->value_mask
& XCB_CONFIG_WINDOW_X
)
109 values
[ i
++ ] = ev
->x
;
110 if( ev
->value_mask
& XCB_CONFIG_WINDOW_Y
)
111 values
[ i
++ ] = ev
->y
;
112 if( ev
->value_mask
& XCB_CONFIG_WINDOW_WIDTH
)
113 values
[ i
++ ] = ev
->width
;
114 if( ev
->value_mask
& XCB_CONFIG_WINDOW_HEIGHT
)
115 values
[ i
++ ] = ev
->height
;
116 if( ev
->value_mask
& XCB_CONFIG_WINDOW_BORDER_WIDTH
)
117 values
[ i
++ ] = ev
->border_width
;
118 if( ev
->value_mask
& XCB_CONFIG_WINDOW_SIBLING
)
119 values
[ i
++ ] = ev
->sibling
;
120 if( ev
->value_mask
& XCB_CONFIG_WINDOW_STACK_MODE
)
121 values
[ i
++ ] = ev
->stack_mode
;
123 xcb_configure_window( c
, ev
->window
, ev
->value_mask
, values
);
126 static void root_circulate_request( struct gwm_window
*window
,
127 xcb_circulate_request_event_t
*ev
) {
129 uint32_t value
= ev
->place
== XCB_PLACE_ON_TOP
? XCB_STACK_MODE_ABOVE
:
130 XCB_STACK_MODE_BELOW
;
132 /* Circulating children of the root -- honour the request as is. */
133 xcb_configure_window( c
, ev
->window
, XCB_CONFIG_WINDOW_STACK_MODE
,
137 static void root_synthetic( struct gwm_window
*root
,
138 xcb_generic_event_t
*ev
) {
140 xcb_unmap_notify_event_t
*unmap
= (xcb_unmap_notify_event_t
*) ev
;
141 xcb_configure_request_event_t
*config
=
142 (xcb_configure_request_event_t
*) ev
;
143 struct gwm_window
*window
;
145 switch( ev
->response_type
& ~SEND_EVENT_MASK
) {
146 case XCB_UNMAP_NOTIFY
:
147 /* Handle a synthetic UnmapNotify request to move a window to
148 the Withdrawn state (see ICCCM 2.0, section 4.1.4). */
149 if( ( window
= lookup_window( unmap
->window
) ) &&
150 window
->type
== WINDOW_MANAGED
)
151 unmanage_window( window
);
155 case XCB_CONFIGURE_REQUEST
:
156 /* Handle a synthetic ConfigureRequest, which should be used
157 only to restack managed windows relative to windows which
158 were originally siblings (see ICCCM 4.1.5). */
159 if( ( config
->value_mask
& XCB_CONFIG_WINDOW_STACK_MODE
) &&
160 ( window
= lookup_window( config
->window
) ) &&
161 window
->type
== WINDOW_MANAGED
) {
162 struct gwm_window
*sibling
;
163 uint32_t values
[ 2 ];
165 if( ( sibling
= lookup_window( config
->sibling
) ) &&
166 sibling
->type
== WINDOW_MANAGED
)
167 sibling
= sibling
->u
.managed
.frame
;
169 values
[ 0 ] = sibling
? sibling
->w
: config
->sibling
;
170 values
[ 1 ] = config
->stack_mode
;
172 handle_error_reply( xcb_configure_window(
173 c
, window
->u
.managed
.frame
->w
,
174 XCB_CONFIG_WINDOW_SIBLING
|
175 XCB_CONFIG_WINDOW_STACK_MODE
,
177 ERR_MASK_VALUE
| ERR_MASK_WINDOW
|
185 event_handler root_handlers
[] = {
188 (event_handler
) root_key_press
,
189 NULL
, /* KeyRelease */
190 (event_handler
) root_button_press
,
191 NULL
, /* ButtonRelease */
192 NULL
, /* MotionNotify */
193 (event_handler
) root_enter_notify
,
194 NULL
, /* LeaveNotify */
197 NULL
, /* KeymapNotify */
199 NULL
, /* GraphicsExpose */
200 NULL
, /* NoExposure */
201 NULL
, /* VisibilityNotify */
202 NULL
, /* CreateNotify */
203 NULL
, /* DestroyNotify */
204 NULL
, /* UnmapNotify */
205 NULL
, /* MapNotify */
206 (event_handler
) root_map_request
,
207 NULL
, /* ReparentNotify */
208 NULL
, /* ConfigureNotify */
209 (event_handler
) root_configure_request
,
210 NULL
, /* GravityNotify */
211 NULL
, /* ResizeRequest */
212 NULL
, /* CirculateNotify */
213 (event_handler
) root_circulate_request
,
214 NULL
, /* PropertyNotify */
215 NULL
, /* SelectionClear */
216 NULL
, /* SelectionRequest */
217 NULL
, /* SelectionNotify */
218 NULL
, /* ColormapNotify */
219 NULL
, /* ClientMessage */
220 NULL
, /* MappingNotify */
221 (event_handler
) root_synthetic
,
222 NULL
/* ShapeNotify */