2 * swindow.c - simple window handling functions
4 * Copyright © 2008 Julien Danjou <julien@danjou.info>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include "common/xutil.h"
31 extern awesome_t globalconf
;
34 simplewindow_draw_context_update(simple_window_t
*sw
, xcb_screen_t
*s
)
36 xcolor_t fg
= sw
->ctx
.fg
, bg
= sw
->ctx
.bg
;
37 int phys_screen
= sw
->ctx
.phys_screen
;
39 draw_context_wipe(&sw
->ctx
);
41 /* update draw context */
42 switch(sw
->orientation
)
46 /* we need a new pixmap this way [ ] to render */
47 sw
->ctx
.pixmap
= xcb_generate_id(globalconf
.connection
);
48 xcb_create_pixmap(globalconf
.connection
,
50 sw
->ctx
.pixmap
, s
->root
,
51 sw
->geometry
.height
, sw
->geometry
.width
);
52 draw_context_init(&sw
->ctx
, phys_screen
,
53 sw
->geometry
.height
, sw
->geometry
.width
,
54 sw
->ctx
.pixmap
, &fg
, &bg
);
57 draw_context_init(&sw
->ctx
, phys_screen
,
58 sw
->geometry
.width
, sw
->geometry
.height
,
59 sw
->pixmap
, &fg
, &bg
);
64 /** Initialize a simple window.
65 * \param sw The simple window to initialize.
66 * \param phys_screen Physical screen number.
67 * \param geometry Window geometry.
68 * \param border_width Window border width.
69 * \param orientation The rendering orientation.
70 * \param bg Default foreground color.
71 * \param bg Default background color.
74 simplewindow_init(simple_window_t
*sw
,
77 uint16_t border_width
,
78 orientation_t orientation
,
79 const xcolor_t
*fg
, const xcolor_t
*bg
)
81 xcb_screen_t
*s
= xutil_screen_get(globalconf
.connection
, phys_screen
);
82 uint32_t create_win_val
[3];
83 const uint32_t gc_mask
= XCB_GC_FOREGROUND
| XCB_GC_BACKGROUND
;
84 const uint32_t gc_values
[2] = { s
->black_pixel
, s
->white_pixel
};
86 sw
->geometry
.x
= geometry
.x
;
87 sw
->geometry
.y
= geometry
.y
;
88 sw
->geometry
.width
= geometry
.width
;
89 sw
->geometry
.height
= geometry
.height
;
90 sw
->border
.width
= border_width
;
91 sw
->orientation
= orientation
;
95 create_win_val
[0] = XCB_BACK_PIXMAP_PARENT_RELATIVE
;
96 create_win_val
[1] = 1;
97 create_win_val
[2] = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
98 | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY
| XCB_EVENT_MASK_ENTER_WINDOW
99 | XCB_EVENT_MASK_LEAVE_WINDOW
| XCB_EVENT_MASK_STRUCTURE_NOTIFY
100 | XCB_EVENT_MASK_BUTTON_PRESS
| XCB_EVENT_MASK_BUTTON_RELEASE
101 | XCB_EVENT_MASK_POINTER_MOTION
| XCB_EVENT_MASK_EXPOSURE
;
103 sw
->window
= xcb_generate_id(globalconf
.connection
);
104 xcb_create_window(globalconf
.connection
, s
->root_depth
, sw
->window
, s
->root
,
105 geometry
.x
, geometry
.y
, geometry
.width
, geometry
.height
,
106 border_width
, XCB_COPY_FROM_PARENT
, s
->root_visual
,
107 XCB_CW_BACK_PIXMAP
| XCB_CW_OVERRIDE_REDIRECT
| XCB_CW_EVENT_MASK
,
110 sw
->pixmap
= xcb_generate_id(globalconf
.connection
);
111 xcb_create_pixmap(globalconf
.connection
, s
->root_depth
, sw
->pixmap
, s
->root
,
112 geometry
.width
, geometry
.height
);
114 simplewindow_draw_context_update(sw
, s
);
116 /* The default GC is just a newly created associated to the root window */
117 sw
->gc
= xcb_generate_id(globalconf
.connection
);
118 xcb_create_gc(globalconf
.connection
, sw
->gc
, s
->root
, gc_mask
, gc_values
);
121 /** Destroy all resources of a simple window.
122 * \param sw The simple_window_t to wipe.
125 simplewindow_wipe(simple_window_t
*sw
)
129 xcb_destroy_window(globalconf
.connection
, sw
->window
);
130 sw
->window
= XCB_NONE
;
134 xcb_free_pixmap(globalconf
.connection
, sw
->pixmap
);
135 sw
->pixmap
= XCB_NONE
;
139 xcb_free_gc(globalconf
.connection
, sw
->gc
);
142 draw_context_wipe(&sw
->ctx
);
145 /** Move a simple window.
146 * \param sw The simple window to move.
147 * \param x New x coordinate.
148 * \param y New y coordinate.
151 simplewindow_move(simple_window_t
*sw
, int x
, int y
)
153 const uint32_t move_win_vals
[] = { x
, y
};
155 if(x
!= sw
->geometry
.x
|| y
!= sw
->geometry
.y
)
159 xcb_configure_window(globalconf
.connection
, sw
->window
,
160 XCB_CONFIG_WINDOW_X
| XCB_CONFIG_WINDOW_Y
,
165 /** Resize a simple window.
166 * \param sw The simple_window_t to resize.
167 * \param w New width.
168 * \param h New height.
171 simplewindow_resize(simple_window_t
*sw
, int w
, int h
)
173 if(w
> 0 && h
> 0 && (sw
->geometry
.width
!= w
|| sw
->geometry
.height
!= h
))
175 xcb_screen_t
*s
= xutil_screen_get(globalconf
.connection
, sw
->ctx
.phys_screen
);
176 uint32_t resize_win_vals
[2];
178 sw
->geometry
.width
= resize_win_vals
[0] = w
;
179 sw
->geometry
.height
= resize_win_vals
[1] = h
;
180 xcb_free_pixmap(globalconf
.connection
, sw
->pixmap
);
181 /* orientation != East */
182 if(sw
->pixmap
!= sw
->ctx
.pixmap
)
183 xcb_free_pixmap(globalconf
.connection
, sw
->ctx
.pixmap
);
184 sw
->pixmap
= xcb_generate_id(globalconf
.connection
);
185 xcb_create_pixmap(globalconf
.connection
, s
->root_depth
, sw
->pixmap
, s
->root
, w
, h
);
186 xcb_configure_window(globalconf
.connection
, sw
->window
,
187 XCB_CONFIG_WINDOW_WIDTH
| XCB_CONFIG_WINDOW_HEIGHT
,
189 simplewindow_draw_context_update(sw
, s
);
193 /** Move and resize a window in one call.
194 * \param sw The simple window to move and resize.
195 * \param geom The new gometry.
198 simplewindow_moveresize(simple_window_t
*sw
, area_t geom
)
200 uint32_t moveresize_win_vals
[4], mask_vals
= 0;
201 xcb_screen_t
*s
= xutil_screen_get(globalconf
.connection
, sw
->ctx
.phys_screen
);
203 if(sw
->geometry
.x
!= geom
.x
|| sw
->geometry
.y
!= geom
.y
)
205 sw
->geometry
.x
= moveresize_win_vals
[0] = geom
.x
;
206 sw
->geometry
.y
= moveresize_win_vals
[1] = geom
.y
;
207 mask_vals
|= XCB_CONFIG_WINDOW_X
| XCB_CONFIG_WINDOW_Y
;
210 if(sw
->geometry
.width
!= geom
.width
|| sw
->geometry
.height
!= geom
.height
)
214 sw
->geometry
.width
= moveresize_win_vals
[2] = geom
.width
;
215 sw
->geometry
.height
= moveresize_win_vals
[3] = geom
.height
;
219 sw
->geometry
.width
= moveresize_win_vals
[0] = geom
.width
;
220 sw
->geometry
.height
= moveresize_win_vals
[1] = geom
.height
;
222 mask_vals
|= XCB_CONFIG_WINDOW_WIDTH
| XCB_CONFIG_WINDOW_HEIGHT
;
223 xcb_free_pixmap(globalconf
.connection
, sw
->pixmap
);
224 /* orientation != East */
225 if(sw
->pixmap
!= sw
->ctx
.pixmap
)
226 xcb_free_pixmap(globalconf
.connection
, sw
->ctx
.pixmap
);
227 sw
->pixmap
= xcb_generate_id(globalconf
.connection
);
228 xcb_create_pixmap(globalconf
.connection
, s
->root_depth
, sw
->pixmap
, s
->root
, geom
.width
, geom
.height
);
229 simplewindow_draw_context_update(sw
, s
);
232 xcb_configure_window(globalconf
.connection
, sw
->window
, mask_vals
, moveresize_win_vals
);
235 /** Refresh the window content by copying its pixmap data to its window.
236 * \param sw The simple window to refresh.
239 simplewindow_refresh_pixmap_partial(simple_window_t
*sw
,
240 int16_t x
, int16_t y
,
241 uint16_t w
, uint16_t h
)
243 xcb_copy_area(globalconf
.connection
, sw
->pixmap
,
244 sw
->window
, sw
->gc
, x
, y
, x
, y
,
248 /** Set a simple window border width.
249 * \param sw The simple window to change border width.
250 * \param border_width The border width in pixel.
253 simplewindow_border_width_set(simple_window_t
*sw
, uint32_t border_width
)
255 xcb_configure_window(globalconf
.connection
, sw
->window
, XCB_CONFIG_WINDOW_BORDER_WIDTH
,
257 sw
->border
.width
= border_width
;
260 /** Set a simple window border color.
261 * \param sw The simple window to change border width.
262 * \param color The border color.
265 simplewindow_border_color_set(simple_window_t
*sw
, const xcolor_t
*color
)
267 xcb_change_window_attributes(globalconf
.connection
, sw
->window
,
268 XCB_CW_BORDER_PIXEL
, &color
->pixel
);
269 sw
->border
.color
= *color
;
272 /** Set simple window orientation.
273 * \param sw The simple window.
274 * \param o The new orientation
277 simplewindow_orientation_set(simple_window_t
*sw
, orientation_t o
)
279 if(o
!= sw
->orientation
)
281 xcb_screen_t
*s
= xutil_screen_get(globalconf
.connection
, sw
->ctx
.phys_screen
);
283 /* orientation != East */
284 if(sw
->pixmap
!= sw
->ctx
.pixmap
)
285 xcb_free_pixmap(globalconf
.connection
, sw
->ctx
.pixmap
);
286 simplewindow_draw_context_update(sw
, s
);
290 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80