luaa: add support for meta __ipairs
[awesome.git] / swindow.c
blob10d284e6a837bf125e4a6f89eb4bb2e6e2c1a3d2
1 /*
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.
22 #include <math.h>
24 #include <xcb/xcb.h>
26 #include "structs.h"
27 #include "swindow.h"
28 #include "draw.h"
29 #include "common/xutil.h"
31 extern awesome_t globalconf;
33 static void
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)
44 case South:
45 case North:
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,
49 s->root_depth,
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);
55 break;
56 case East:
57 draw_context_init(&sw->ctx, phys_screen,
58 sw->geometry.width, sw->geometry.height,
59 sw->pixmap, &fg, &bg);
60 break;
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.
73 void
74 simplewindow_init(simple_window_t *sw,
75 int phys_screen,
76 area_t geometry,
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;
92 sw->ctx.fg = *fg;
93 sw->ctx.bg = *bg;
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,
108 create_win_val);
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.
125 void
126 simplewindow_wipe(simple_window_t *sw)
128 if(sw->window)
130 xcb_destroy_window(globalconf.connection, sw->window);
131 sw->window = XCB_NONE;
133 if(sw->pixmap)
135 xcb_free_pixmap(globalconf.connection, sw->pixmap);
136 sw->pixmap = XCB_NONE;
138 if(sw->gc)
140 xcb_free_gc(globalconf.connection, sw->gc);
141 sw->gc = XCB_NONE;
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.
151 void
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)
158 sw->geometry.x = x;
159 sw->geometry.y = y;
160 xcb_configure_window(globalconf.connection, sw->window,
161 XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
162 move_win_vals);
166 /** Resize a simple window.
167 * \param sw The simple_window_t to resize.
168 * \param w New width.
169 * \param h New height.
171 void
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,
189 resize_win_vals);
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.
198 void
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)
213 if(mask_vals)
215 sw->geometry.width = moveresize_win_vals[2] = geom.width;
216 sw->geometry.height = moveresize_win_vals[3] = geom.height;
218 else
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.
239 void
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,
246 w, h);
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.
253 void
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,
257 &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.
265 void
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
277 void
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);
283 sw->orientation = o;
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