]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/dope/server/common/background.c
Inital import
[l4.git] / l4 / pkg / dope / server / common / background.c
1 /*
2  * \brief   DOpE Background widget module
3  * \date    2002-11-13
4  * \author  Norman Feske <nf2@inf.tu-dresden.de>
5  */
6
7 /*
8  * Copyright (C) 2002-2004  Norman Feske  <nf2@os.inf.tu-dresden.de>
9  * Technische Universitaet Dresden, Operating Systems Research Group
10  *
11  * This file is part of the DOpE package, which is distributed under
12  * the  terms  of the  GNU General Public Licence 2.  Please see the
13  * COPYING file for details.
14  */
15
16 struct background;
17 #define WIDGET struct background
18
19 #include "dopestd.h"
20 #include "background.h"
21 #include "gfx.h"
22 #include "widget_data.h"
23 #include "widget_help.h"
24 #include "widman.h"
25 #include "userstate.h"
26 #include "script.h"
27
28 static struct gfx_services *gfx;
29 static struct widman_services *widman;
30 static struct script_services *script;
31 static struct userstate_services *userstate;
32
33 struct background_data {
34         long    style;
35         void  (*click) (void *);
36         WIDGET *content;
37 };
38
39 int init_background(struct dope_services *d);
40
41
42 /******************************
43  *** GENERAL WIDGET METHODS ***
44  ******************************/
45
46 static int bg_draw(BACKGROUND *b, struct gfx_ds *ds, long x, long y, WIDGET *origin) {
47         WIDGET *c;
48         int ret = 0;
49
50         if (origin == b) return 1;
51         
52         c = b->bd->content;
53
54         x += b->wd->x;
55         y += b->wd->y;
56
57         if (!origin) switch (b->bd->style) {
58                 case BG_STYLE_WIN:
59                         gfx->draw_box(ds, x, y, b->wd->w, b->wd->h, 0x708090ff);
60                         ret |= 1;
61                         break;
62                 case BG_STYLE_DESK:
63                         gfx->draw_box(ds, x, y, b->wd->w, b->wd->h, 0x506070ff);
64                         ret |= 1;
65                         break;
66         }
67         if (c) ret |= c->gen->draw(c, ds, x, y, origin);
68         return ret;
69 }
70
71
72 static WIDGET *bg_find(BACKGROUND *b, long x, long y) {
73         WIDGET *c, *result = b;
74         if (!b) return NULL;
75
76         /* return if position is outside the background area */
77         if ((x < b->wd->x) && (x >= b->wd->x + b->wd->w)
78          && (y < b->wd->y) && (y >= b->wd->y + b->wd->h))
79                 return NULL;
80
81         if ((c = b->bd->content))
82                 result = c->gen->find(c, x, y);
83                 
84         return result;
85 }
86
87
88 static void (*orig_handle_event) (BACKGROUND *b, EVENT *e, WIDGET *from);
89 static void bg_handle_event(BACKGROUND *b, EVENT *e, WIDGET *from) {
90         if ((e->type == L4RE_EV_KEY && e->value == 1) && (b->bd->click)) {
91                 b->bd->click(b);
92                 return;
93         }
94         if (orig_handle_event) orig_handle_event(b, e, from);
95 }
96
97
98 static void bg_calc_minmax(BACKGROUND *b) {
99         WIDGET *c = b->bd->content;
100
101         if (c) {
102                 b->wd->min_w = c->wd->min_w;
103                 b->wd->min_h = c->wd->min_h;
104                 b->wd->max_w = c->wd->max_w;
105                 b->wd->max_h = c->wd->max_h;
106         } else {
107                 b->wd->min_w = b->wd->min_h = 0;
108                 b->wd->max_w = b->wd->max_h = 9999;
109         }
110 }
111
112
113 /*** UPDATE POSITION AND SIZE OF BACKGROUND ***
114  *
115  * Keep size of child in sync with background.
116  */
117 static void (*orig_updatepos)(WIDGET *w);
118 static void bg_updatepos(BACKGROUND *b) {
119         WIDGET *c = b->bd->content;
120         if (c) {
121                 c->gen->set_x(c, 0);
122                 c->gen->set_y(c, 0);
123                 c->gen->set_w(c, b->wd->w);
124                 c->gen->set_h(c, b->wd->h);
125                 c->gen->updatepos(c);
126         }
127         orig_updatepos(b);
128 }
129
130
131 /*** RETURN WIDGET TYPE IDENTIFIER ***/
132 static char *bg_get_type(BACKGROUND *bg) {
133     (void)bg;
134         return "Background";
135 }
136
137
138 /*** REMOVE CONTENT FROM THE BACKGROUND ***/
139 static void bg_remove_child(BACKGROUND *b, WIDGET *child) {
140         if (!child || (b->bd->content != child)) return;
141
142         b->bd->content = NULL;
143         child->gen->set_parent(child, NULL);
144         child->gen->dec_ref(child);
145
146         b->wd->update |= WID_UPDATE_MINMAX;
147         b->gen->update(b);
148 }
149
150
151 /*** FREE DATA ***/
152 static void bg_free_data(BACKGROUND *b) {
153
154         /* get rid of the content */
155         if (b->bd->content)
156                 b->bd->content->gen->release(b->bd->content);
157 }
158
159
160 /***********************************
161  *** BACKGROUND SPECIFIC METHODS ***
162  ***********************************/
163
164 static void bg_set_style(BACKGROUND *b, long new_style) {
165         b->bd->style = new_style;
166 }
167
168
169 static void bg_set_click(BACKGROUND *b, void (*click)(void *)) {
170         b->bd->click = click;
171 }
172
173
174 static void bg_set_content(BACKGROUND *b, WIDGET *new_content) {
175
176         /* avoid cyclic parent relationships */
177         if (new_content->gen->related_to(new_content, b)) return;
178
179         /* get rid of old content */
180         if (b->bd->content) {
181                 b->bd->content->gen->set_parent(b->bd->content, NULL);
182                 b->bd->content->gen->dec_ref(b->bd->content);
183         }
184
185         /* welcome new content */
186         b->bd->content = new_content;
187         if (new_content) {
188                 new_content->gen->inc_ref(new_content);
189                 new_content->gen->release(new_content);
190                 new_content->gen->set_parent(new_content, b);
191         }
192         
193         b->wd->update |= WID_UPDATE_MINMAX;
194 }
195
196
197 static struct widget_methods gen_methods;
198 static struct background_methods bg_methods = {
199         bg_set_style,
200         bg_set_click,
201 };
202
203
204
205 /*************************
206  *** SERVICE FUNCTIONS ***
207  *************************/
208
209 static BACKGROUND *create(void) {
210
211         BACKGROUND *new = ALLOC_WIDGET(struct background);
212         SET_WIDGET_DEFAULTS(new, struct background, &bg_methods);
213
214         /* set background specific default attributes */
215         new->bd->style  =  BG_STYLE_WIN;
216         new->wd->flags |=  WID_FLAGS_CONCEALING;
217
218         return new;
219 }
220
221
222
223 /****************************************
224  *** SERVICE STRUCTURE OF THIS MODULE ***
225  ****************************************/
226
227 static struct background_services services = {
228         create
229 };
230
231
232 /**************************
233  *** MODULE ENTRY POINT ***
234  **************************/
235
236 static void build_script_lang(void) {
237         void *widtype;
238
239         widtype = script->reg_widget_type("Background", (void *(*)(void))create);
240         script->reg_widget_attrib(widtype, "Widget content", NULL, bg_set_content, gen_methods.update);
241         widman->build_script_lang(widtype, &gen_methods);
242 }
243
244
245 int init_background(struct dope_services *d) {
246
247         gfx       = d->get_module("Gfx 1.0");
248         widman    = d->get_module("WidgetManager 1.0");
249         userstate = d->get_module("UserState 1.0");
250         script    = d->get_module("Script 1.0");
251
252         /* define general widget functions */
253         widman->default_widget_methods(&gen_methods);
254         orig_handle_event        = gen_methods.handle_event;
255         orig_updatepos           = gen_methods.updatepos;
256         
257         gen_methods.get_type     = bg_get_type;
258         gen_methods.draw         = bg_draw;
259         gen_methods.find         = bg_find;
260         gen_methods.handle_event = bg_handle_event;
261         gen_methods.updatepos    = bg_updatepos;
262         gen_methods.calc_minmax  = bg_calc_minmax;
263         gen_methods.remove_child = bg_remove_child;
264         gen_methods.free_data    = bg_free_data;
265
266         build_script_lang();
267
268         d->register_module("Background 1.0", &services);
269         return 1;
270 }
271
272
273
274
275
276