Better error message
[notion/jeffpc.git] / ioncore / infowin.c
blob1f28a0a5108348772e31ace2403e57b95f4dcb92
1 /*
2 * ion/ioncore/infowin.h
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
7 */
9 #include <string.h>
11 #include <libtu/objp.h>
12 #include "common.h"
13 #include "global.h"
14 #include "window.h"
15 #include "infowin.h"
16 #include "resize.h"
17 #include "gr.h"
18 #include "event.h"
19 #include "strings.h"
22 /*{{{ Init/deinit */
25 bool infowin_init(WInfoWin *p, WWindow *parent, const WFitParams *fp,
26 const char *style)
28 XSetWindowAttributes attr;
30 if(!window_init(&(p->wwin), parent, fp, "WInfoWin"))
31 return FALSE;
33 p->buffer=ALLOC_N(char, INFOWIN_BUFFER_LEN);
34 if(p->buffer==NULL)
35 goto fail;
36 p->buffer[0]='\0';
38 if(style==NULL)
39 p->style=scopy("*");
40 else
41 p->style=scopy(style);
42 if(p->style==NULL)
43 goto fail2;
45 p->brush=NULL;
47 gr_stylespec_init(&p->attr);
49 infowin_updategr(p);
51 if(p->brush==NULL)
52 goto fail3;
54 /* Enable save unders */
55 attr.save_under=True;
56 XChangeWindowAttributes(ioncore_g.dpy, p->wwin.win, CWSaveUnder, &attr);
58 window_select_input(&(p->wwin), IONCORE_EVENTMASK_NORMAL);
60 return TRUE;
62 fail3:
63 gr_stylespec_unalloc(&p->attr);
64 free(p->style);
65 fail2:
66 free(p->buffer);
67 fail:
68 window_deinit(&(p->wwin));
69 return FALSE;
73 WInfoWin *create_infowin(WWindow *parent, const WFitParams *fp,
74 const char *style)
76 CREATEOBJ_IMPL(WInfoWin, infowin, (p, parent, fp, style));
80 void infowin_deinit(WInfoWin *p)
82 if(p->buffer!=NULL){
83 free(p->buffer);
84 p->buffer=NULL;
87 if(p->style!=NULL){
88 free(p->style);
89 p->style=NULL;
92 if(p->brush!=NULL){
93 grbrush_release(p->brush);
94 p->brush=NULL;
97 gr_stylespec_unalloc(&p->attr);
99 window_deinit(&(p->wwin));
103 /*}}}*/
106 /*{{{ Drawing and geometry */
109 void infowin_draw(WInfoWin *p, bool complete)
111 WRectangle g;
113 if(p->brush==NULL)
114 return;
116 g.x=0;
117 g.y=0;
118 g.w=REGION_GEOM(p).w;
119 g.h=REGION_GEOM(p).h;
121 grbrush_begin(p->brush, &g, GRBRUSH_NO_CLEAR_OK);
122 grbrush_init_attr(p->brush, &p->attr);
123 grbrush_draw_textbox(p->brush, &g, p->buffer, TRUE);
124 grbrush_end(p->brush);
128 void infowin_updategr(WInfoWin *p)
130 GrBrush *nbrush;
132 assert(p->style!=NULL);
134 nbrush=gr_get_brush(p->wwin.win,
135 region_rootwin_of((WRegion*)p),
136 p->style);
137 if(nbrush==NULL)
138 return;
140 if(p->brush!=NULL)
141 grbrush_release(p->brush);
143 p->brush=nbrush;
145 window_draw(&(p->wwin), TRUE);
150 /*}}}*/
153 /*{{{ Content-setting */
156 GrStyleSpec *infowin_stylespec(WInfoWin *p)
158 return &p->attr;
162 static void infowin_do_set_text(WInfoWin *p, const char *str)
164 strncpy(INFOWIN_BUFFER(p), str, INFOWIN_BUFFER_LEN);
165 INFOWIN_BUFFER(p)[INFOWIN_BUFFER_LEN-1]='\0';
169 static void infowin_resize(WInfoWin *p)
171 WRQGeomParams rq=RQGEOMPARAMS_INIT;
172 const char *str=INFOWIN_BUFFER(p);
173 GrBorderWidths bdw;
174 GrFontExtents fnte;
176 rq.flags=REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y;
178 rq.geom.x=REGION_GEOM(p).x;
179 rq.geom.y=REGION_GEOM(p).y;
181 grbrush_get_border_widths(p->brush, &bdw);
182 grbrush_get_font_extents(p->brush, &fnte);
184 rq.geom.w=bdw.left+bdw.right;
185 rq.geom.w+=grbrush_get_text_width(p->brush, str, strlen(str));
186 rq.geom.h=fnte.max_height+bdw.top+bdw.bottom;
188 if(rectangle_compare(&rq.geom, &REGION_GEOM(p))!=RECTANGLE_SAME)
189 region_rqgeom((WRegion*)p, &rq, NULL);
193 /*EXTL_DOC
194 * Set contents of the info window.
196 EXTL_EXPORT_MEMBER
197 void infowin_set_text(WInfoWin *p, const char *str, int maxw)
199 bool set=FALSE;
201 if(str==NULL){
202 INFOWIN_BUFFER(p)[0]='\0';
203 }else{
204 if(maxw>0 && p->brush!=NULL){
205 char *tmp=grbrush_make_label(p->brush, str, maxw);
206 if(tmp!=NULL){
207 infowin_do_set_text(p, tmp);
208 free(tmp);
209 set=TRUE;
213 if(!set)
214 infowin_do_set_text(p, str);
217 infowin_resize(p);
219 /* sometimes unnecessary */
220 window_draw((WWindow*)p, TRUE);
224 /*}}}*/
227 /*{{{ Load */
230 WRegion *infowin_load(WWindow *par, const WFitParams *fp, ExtlTab tab)
232 char *style=NULL, *text=NULL;
233 WInfoWin *p;
235 extl_table_gets_s(tab, "style", &style);
237 p=create_infowin(par, fp, style);
239 free(style);
241 if(p==NULL)
242 return NULL;
244 if(extl_table_gets_s(tab, "text", &text)){
245 infowin_do_set_text(p, text);
246 free(text);
249 return (WRegion*)p;
253 /*}}}*/
256 /*{{{ Dynamic function table and class implementation */
259 static DynFunTab infowin_dynfuntab[]={
260 {window_draw, infowin_draw},
261 {region_updategr, infowin_updategr},
262 END_DYNFUNTAB
266 EXTL_EXPORT
267 IMPLCLASS(WInfoWin, WWindow, infowin_deinit, infowin_dynfuntab);
270 /*}}}*/