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 sw
->ctx
.phys_screen
= phys_screen
;
115 simplewindow_draw_context_update(sw
, s
);
117 /* The default GC is just a newly created associated to the root window */
118 sw
->gc
= xcb_generate_id(globalconf
.connection
);
119 xcb_create_gc(globalconf
.connection
, sw
->gc
, s
->root
, gc_mask
, gc_values
);
122 /** Destroy all resources of a simple window.
123 * \param sw The simple_window_t to wipe.
126 simplewindow_wipe(simple_window_t
*sw
)
130 xcb_destroy_window(globalconf
.connection
, sw
->window
);
131 sw
->window
= XCB_NONE
;
135 xcb_free_pixmap(globalconf
.connection
, sw
->pixmap
);
136 sw
->pixmap
= XCB_NONE
;
140 xcb_free_gc(globalconf
.connection
, sw
->gc
);
143 draw_context_wipe(&sw
->ctx
);
146 /** Move a simple window.
147 * \param sw The simple window to move.
148 * \param x New x coordinate.
149 * \param y New y coordinate.
152 simplewindow_move(simple_window_t
*sw
, int x
, int y
)
154 const uint32_t move_win_vals
[] = { x
, y
};
156 if(x
!= sw
->geometry
.x
|| y
!= sw
->geometry
.y
)
160 xcb_configure_window(globalconf
.connection
, sw
->window
,
161 XCB_CONFIG_WINDOW_X
| XCB_CONFIG_WINDOW_Y
,
166 /** Resize a simple window.
167 * \param sw The simple_window_t to resize.
168 * \param w New width.
169 * \param h New height.
172 simplewindow_resize(simple_window_t
*sw
, int w
, int h
)
174 if(w
> 0 && h
> 0 && (sw
->geometry
.width
!= w
|| sw
->geometry
.height
!= h
))
176 xcb_screen_t
*s
= xutil_screen_get(globalconf
.connection
, sw
->ctx
.phys_screen
);
177 uint32_t resize_win_vals
[2];
179 sw
->geometry
.width
= resize_win_vals
[0] = w
;
180 sw
->geometry
.height
= resize_win_vals
[1] = h
;
181 xcb_free_pixmap(globalconf
.connection
, sw
->pixmap
);
182 /* orientation != East */
183 if(sw
->pixmap
!= sw
->ctx
.pixmap
)
184 xcb_free_pixmap(globalconf
.connection
, sw
->ctx
.pixmap
);
185 sw
->pixmap
= xcb_generate_id(globalconf
.connection
);
186 xcb_create_pixmap(globalconf
.connection
, s
->root_depth
, sw
->pixmap
, s
->root
, w
, h
);
187 xcb_configure_window(globalconf
.connection
, sw
->window
,
188 XCB_CONFIG_WINDOW_WIDTH
| XCB_CONFIG_WINDOW_HEIGHT
,
190 simplewindow_draw_context_update(sw
, s
);
194 /** Move and resize a window in one call.
195 * \param sw The simple window to move and resize.
196 * \param geom The new gometry.
199 simplewindow_moveresize(simple_window_t
*sw
, area_t geom
)
201 uint32_t moveresize_win_vals
[4], mask_vals
= 0;
202 xcb_screen_t
*s
= xutil_screen_get(globalconf
.connection
, sw
->ctx
.phys_screen
);
204 if(sw
->geometry
.x
!= geom
.x
|| sw
->geometry
.y
!= geom
.y
)
206 sw
->geometry
.x
= moveresize_win_vals
[0] = geom
.x
;
207 sw
->geometry
.y
= moveresize_win_vals
[1] = geom
.y
;
208 mask_vals
|= XCB_CONFIG_WINDOW_X
| XCB_CONFIG_WINDOW_Y
;
211 if(sw
->geometry
.width
!= geom
.width
|| sw
->geometry
.height
!= geom
.height
)
215 sw
->geometry
.width
= moveresize_win_vals
[2] = geom
.width
;
216 sw
->geometry
.height
= moveresize_win_vals
[3] = geom
.height
;
220 sw
->geometry
.width
= moveresize_win_vals
[0] = geom
.width
;
221 sw
->geometry
.height
= moveresize_win_vals
[1] = geom
.height
;
223 mask_vals
|= XCB_CONFIG_WINDOW_WIDTH
| XCB_CONFIG_WINDOW_HEIGHT
;
224 xcb_free_pixmap(globalconf
.connection
, sw
->pixmap
);
225 /* orientation != East */
226 if(sw
->pixmap
!= sw
->ctx
.pixmap
)
227 xcb_free_pixmap(globalconf
.connection
, sw
->ctx
.pixmap
);
228 sw
->pixmap
= xcb_generate_id(globalconf
.connection
);
229 xcb_create_pixmap(globalconf
.connection
, s
->root_depth
, sw
->pixmap
, s
->root
, geom
.width
, geom
.height
);
230 simplewindow_draw_context_update(sw
, s
);
233 xcb_configure_window(globalconf
.connection
, sw
->window
, mask_vals
, moveresize_win_vals
);
236 /** Refresh the window content by copying its pixmap data to its window.
237 * \param sw The simple window to refresh.
240 simplewindow_refresh_pixmap_partial(simple_window_t
*sw
,
241 int16_t x
, int16_t y
,
242 uint16_t w
, uint16_t h
)
244 xcb_copy_area(globalconf
.connection
, sw
->pixmap
,
245 sw
->window
, sw
->gc
, x
, y
, x
, y
,
249 /** Set a simple window border width.
250 * \param sw The simple window to change border width.
251 * \param border_width The border width in pixel.
254 simplewindow_border_width_set(simple_window_t
*sw
, uint32_t border_width
)
256 xcb_configure_window(globalconf
.connection
, sw
->window
, XCB_CONFIG_WINDOW_BORDER_WIDTH
,
258 sw
->border
.width
= border_width
;
261 /** Set a simple window border color.
262 * \param sw The simple window to change border width.
263 * \param color The border color.
266 simplewindow_border_color_set(simple_window_t
*sw
, const xcolor_t
*color
)
268 xcb_change_window_attributes(globalconf
.connection
, sw
->window
,
269 XCB_CW_BORDER_PIXEL
, &color
->pixel
);
270 sw
->border
.color
= *color
;
273 /** Set simple window orientation.
274 * \param sw The simple window.
275 * \param o The new orientation
278 simplewindow_orientation_set(simple_window_t
*sw
, orientation_t o
)
280 if(o
!= sw
->orientation
)
282 xcb_screen_t
*s
= xutil_screen_get(globalconf
.connection
, sw
->ctx
.phys_screen
);
284 /* orientation != East */
285 if(sw
->pixmap
!= sw
->ctx
.pixmap
)
286 xcb_free_pixmap(globalconf
.connection
, sw
->ctx
.pixmap
);
287 simplewindow_draw_context_update(sw
, s
);
291 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80