4 * Copyright (c) Tuomo Valkonen 1999-2006.
6 * Ion is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
14 #include <libtu/objp.h>
15 #include <libextl/readconfig.h>
16 #include <libmainloop/hooks.h>
23 /*{{{ Lookup and registration */
30 GrEngine *next, *prev;
34 static GrEngine *engines=NULL, *current_engine=NULL;
37 bool gr_register_engine(const char *engine, GrGetBrushFn *fn)
41 if(engine==NULL || fn==NULL)
49 eng->name=scopy(engine);
58 LINK_ITEM(engines, eng, next, prev);
64 void gr_unregister_engine(const char *engine)
68 for(eng=engines; eng!=NULL; eng=eng->next){
69 if(strcmp(eng->name, engine)==0)
76 UNLINK_ITEM(engines, eng, next, prev);
78 if(current_engine==eng)
84 static bool gr_do_select_engine(const char *engine)
88 for(eng=engines; eng!=NULL; eng=eng->next){
89 if(strcmp(eng->name, engine)==0){
100 * Future requests for ''brushes'' are to be forwarded to the drawing engine
101 * \var{engine}. If no engine of such name is known, a module with that name
102 * is attempted to be loaded. This function is only intended to be called from
103 * colour scheme etc. configuration files and can not be used to change the
104 * look of existing objects; for that use \fnref{gr.read_config}.
106 EXTL_EXPORT_AS(gr, select_engine)
107 bool gr_select_engine(const char *engine)
112 if(gr_do_select_engine(engine))
115 if(!ioncore_load_module(engine))
118 if(!gr_do_select_engine(engine)){
119 warn(TR("Drawing engine %s is not registered!"), engine);
127 GrBrush *gr_get_brush(Window win, WRootWin *rootwin, const char *style)
129 GrEngine *eng=(current_engine!=NULL ? current_engine : engines);
132 if(eng==NULL || eng->fn==NULL)
135 ret=(eng->fn)(win, rootwin, style);
138 warn(TR("Unable to find brush for style '%s'."), style);
150 uint gr_stylespec_score2(const char *spec, const char *attrib,
151 const char *attrib_p2)
158 if(spec==NULL || strcmp(spec, "*")==0)
167 attrib=strchr(attrib, '-');
190 if(a==0 && attrib_p2!=NULL){
206 uint gr_stylespec_score(const char *spec, const char *attrib)
208 return gr_stylespec_score2(spec, attrib, NULL);
215 /*{{{ Init, deinit */
218 bool grbrush_init(GrBrush *brush)
224 void grbrush_deinit(GrBrush *brush)
229 void grbrush_release(GrBrush *brush)
231 CALL_DYN(grbrush_release, brush, (brush));
235 GrBrush *grbrush_get_slave(GrBrush *brush, WRootWin *rootwin,
239 CALL_DYN_RET(slave, GrBrush*, grbrush_get_slave, brush,
240 (brush, rootwin, style));
248 /*{{{ Dynfuns/begin/end/replay */
251 void grbrush_begin(GrBrush *brush, const WRectangle *geom, int flags)
253 CALL_DYN(grbrush_begin, brush, (brush, geom, flags));
257 void grbrush_end(GrBrush *brush)
259 CALL_DYN(grbrush_end, brush, (brush));
266 /*{{{ Dynfuns/values */
269 void grbrush_get_font_extents(GrBrush *brush, GrFontExtents *fnte)
271 CALL_DYN(grbrush_get_font_extents, brush, (brush, fnte));
275 void grbrush_get_border_widths(GrBrush *brush, GrBorderWidths *bdw)
277 CALL_DYN(grbrush_get_border_widths, brush, (brush, bdw));
281 DYNFUN bool grbrush_get_extra(GrBrush *brush, const char *key,
282 char type, void *data)
285 CALL_DYN_RET(ret, bool, grbrush_get_extra, brush,
286 (brush, key, type, data));
294 /*{{{ Dynfuns/Borders */
297 void grbrush_draw_border(GrBrush *brush, const WRectangle *geom,
300 CALL_DYN(grbrush_draw_border, brush, (brush, geom, attrib));
304 void grbrush_draw_borderline(GrBrush *brush, const WRectangle *geom,
305 const char *attrib, GrBorderLine line)
307 CALL_DYN(grbrush_draw_borderline, brush, (brush, geom, attrib, line));
314 /*{{{ Dynfuns/Strings */
317 void grbrush_draw_string(GrBrush *brush, int x, int y,
318 const char *str, int len, bool needfill,
321 CALL_DYN(grbrush_draw_string, brush,
322 (brush, x, y, str, len, needfill, attrib));
326 uint grbrush_get_text_width(GrBrush *brush, const char *text, uint len)
329 CALL_DYN_RET(ret, uint, grbrush_get_text_width, brush,
338 /*{{{ Dynfuns/Textboxes */
341 void grbrush_draw_textbox(GrBrush *brush, const WRectangle *geom,
342 const char *text, const char *attr,
345 CALL_DYN(grbrush_draw_textbox, brush,
346 (brush, geom, text, attr, needfill));
349 void grbrush_draw_textboxes(GrBrush *brush, const WRectangle *geom,
350 int n, const GrTextElem *elem,
351 bool needfill, const char *common_attrib)
353 CALL_DYN(grbrush_draw_textboxes, brush,
354 (brush, geom, n, elem, needfill, common_attrib));
361 /*{{{ Dynfuns/Misc */
364 void grbrush_set_window_shape(GrBrush *brush, bool rough,
365 int n, const WRectangle *rects)
367 CALL_DYN(grbrush_set_window_shape, brush, (brush, rough, n, rects));
371 void grbrush_enable_transparency(GrBrush *brush, GrTransparency tr)
373 CALL_DYN(grbrush_enable_transparency, brush, (brush, tr));
377 void grbrush_fill_area(GrBrush *brush, const WRectangle *geom,
380 CALL_DYN(grbrush_fill_area, brush, (brush, geom, attr));
384 void grbrush_clear_area(GrBrush *brush, const WRectangle *geom)
386 CALL_DYN(grbrush_clear_area, brush, (brush, geom));
393 /*{{{ ioncore_read_config/refresh */
397 * Read drawing engine configuration file \file{draw.lua}.
399 EXTL_EXPORT_AS(gr, read_config)
400 void gr_read_config()
402 extl_read_config("look", NULL, TRUE);
404 /* If nothing has been loaded, try the default engine with
408 warn(TR("No drawing engines loaded, trying \"de\"."));
409 gr_select_engine("de");
415 * Refresh objects' brushes to update them to use newly loaded style.
417 EXTL_EXPORT_AS(gr, refresh)
422 FOR_ALL_ROOTWINS(rootwin){
423 region_updategr((WRegion*)rootwin);
431 /*{{{ Class implementation */
434 static DynFunTab grbrush_dynfuntab[]={
439 IMPLCLASS(GrBrush, Obj, grbrush_deinit, grbrush_dynfuntab);