source: abuse/branches/pd/imlib/port/x11/jwindow.c @ 528

Last change on this file since 528 was 49, checked in by Sam Hocevar, 15 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
File size: 9.8 KB
Line 
1#include "video.hpp"
2#include "image.hpp"
3#include "event.hpp"
4#include "filter.hpp"
5#include "event.hpp"
6#include "jwindow.hpp"
7#include <X11/Xlib.h>
8#include <X11/Xutil.h>
9#include <X11/keysym.h>
10#include <X11/X.h>
11
12int jw_left=5,jw_right=5,jw_top=15,jw_bottom=5;
13
14int frame_top() { return 0; }
15int frame_bottom() { return 0; }
16int frame_left() { return 0; }
17int frame_right() { return 0; }
18
19extern void update_dirty_window(Window win, image *im, int xoff, int yoff);
20extern Window root,mainwin;
21extern Display *display;
22extern int screen_num;
23
24struct jxwin
25{
26  Window win; 
27} ;
28
29void set_frame_size(int x)
30
31  return ;
32}
33
34void window_manager::close_window(jwindow *j)
35{
36  if (j==first)
37    first=first->next;
38  else
39  {
40    for (jwindow *k=first;k->next!=j;k=k->next);
41    k->next=j->next;
42  }
43  XFlush(display);
44  delete j;
45}
46
47void window_manager::hide_windows()
48{
49  for (jwindow *p=first;p;p=p->next)
50    p->hidden=1;
51}
52
53void window_manager::show_windows()
54{
55  for (jwindow *p=first;p;p=p->next)
56    p->hidden=0;
57
58}
59
60void window_manager::hide_window(jwindow *j)
61{
62  j->hidden=1;
63}
64
65void window_manager::show_window(jwindow *j)
66{
67  j->hidden=0;
68}
69
70void window_manager::get_event(event &ev)
71{
72  jwindow *j;
73  eh->get_event(ev);
74  if (ev.type==EV_KEY)
75    key_state[ev.key]=1;
76  else if (ev.type==EV_KEYRELEASE)
77    key_state[ev.key]=0;
78
79  if (state==inputing)
80  {
81    int f=0;
82    for (j=first;j;j=j->next)
83      if (!j->hidden && ((Window)ev.window)==((jxwin *)j->local_info)->win)
84      { f=1;
85        ev.window=j;
86      }
87    if (!f) ev.window=NULL;
88   
89    if (ev.window)
90    {
91      int closew=0,movew=0;
92      if (ev.type==EV_KEY && ev.key==JK_ESC)
93        closew=1;
94   
95      if (closew)
96        ev.type=EV_CLOSE_WINDOW;
97      else if (ev.window)
98        ev.window->inm->handle_event(ev,0,0);
99    }
100  }
101
102  if (ev.type==EV_REDRAW)
103  {
104    if (ev.window)
105      ev.window->screen->add_dirty(ev.redraw.x1,ev.redraw.y1,ev.redraw.x2,ev.redraw.y2);
106    else
107      screen->add_dirty(ev.redraw.x1,ev.redraw.y1,ev.redraw.x2,ev.redraw.y2);
108    flush_screen();
109    ev.type=EV_SPURIOUS;   // we took care of this one by ourselves.
110  }
111}
112
113void jwindow::resize(int L, int H)
114{
115  XWindowChanges v;
116  v.width=L;
117  v.height=H;
118  XFlush(display);
119  XConfigureWindow(display,((jxwin *)local_info)->win,CWWidth|CWHeight,&v);
120  l=L; h=H;
121}
122
123void window_manager::resize_window(jwindow *j, int l, int h)
124{
125  jwindow *p;
126  j->resize(l,h);
127  j->redraw(hi,med,low,font());
128}
129
130void window_manager::move_window(jwindow *j, int x, int y)
131{
132  return ;
133}
134
135window_manager::window_manager(image *Screen, palette *Pal, int Hi,
136                               int Med, int Low, JCFont *Font)
137{
138  screen=Screen; hi=Hi; low=Low; med=Med; first=NULL; pal=Pal;
139  bk=pal->find_closest(0,0,0);
140  state=inputing; fnt=Font; wframe_fnt=Font;
141  memset(key_state,0,sizeof(key_state));
142  eh=new event_handler(screen,pal);
143}
144
145jwindow *window_manager::new_window(int x, int y, int l, int h, ifield *fields, char *Name)
146{
147  if (x>screen->width()-4) x=screen->width()-4;
148  if (y>screen->height()-4) y=screen->height()-4;
149 
150  jwindow *j=new jwindow(x,y,l,h,this,fields,Name),*k;
151  j->hidden=0;
152  if (!first)
153    first=j;
154  else
155  {
156    k=first;
157    while (k->next) k=k->next;
158    k->next=j;
159    j->next=NULL;
160  }
161  j->redraw(hi,med,low,font());
162  return j;
163}
164
165void window_manager::flush_screen()
166{
167  jwindow *p,*q;
168
169  int mx,my,but;
170  image *mouse_pic,*mouse_save;
171 
172  update_dirty(screen);
173
174  for (p=first;p;p=p->next)
175  {
176    if (!p->hidden)
177      update_dirty_window(((jxwin *)p->local_info)->win,p->screen,0,0);
178  }
179}
180
181
182jwindow::jwindow(int X, int Y, int L, int H, window_manager *wm, ifield *fields, char *Name)
183{
184  ifield *i;
185  int x1,y1,x2,y2;
186  l=0; h=0;
187  if (fields)
188    for (i=fields;i;i=i->next)
189    {
190      i->area(x1,y1,x2,y2,wm);
191      if ((int)y2+1>(int)h)
192        h=y2+1;
193      if ((int)x2+1>(int)l)
194        l=x2+1;
195    }
196  else { l=2; h=2; }
197
198  if (L<=0) { l=l-L; } else l=L;
199  if (H<=0) { h=h-H; } else h=H;
200
201 if (Y<0) y=yres-h+Y-WINDOW_FRAME_TOP-WINDOW_FRAME_BOTTOM-1; else y=Y;
202 if (X<0) x=xres-l+X-WINDOW_FRAME_LEFT-WINDOW_FRAME_RIGHT-1; else x=X;
203
204  backg=wm->medium_color();
205  l+=WINDOW_FRAME_RIGHT; h+=WINDOW_FRAME_BOTTOM;
206  if (!fields) { l+=WINDOW_FRAME_LEFT; h+=WINDOW_FRAME_TOP; }
207
208  if (l<18) l=18;
209  if (h<12) h=12;
210  screen=new image(l,h,NULL,2);
211  l=screen->width();
212  h=screen->height();
213  screen->clear(backg);
214
215  next=NULL;
216  inm=new input_manager(screen,wm,fields);
217  if (Name==NULL)
218    name=strcpy((char *)jmalloc(strlen(" ")+1,"jwindow::window name")," "); 
219  else
220    name=strcpy((char *)jmalloc(strlen(Name)+1,"jwindow::window name"),Name);
221  local_info=(void *)jmalloc(sizeof(jxwin),"Xwindow struct");
222
223  XWindowAttributes wa;
224  XGetWindowAttributes(display,mainwin,&wa);
225  Window w=XCreateSimpleWindow(display,
226                              root,
227                              wa.x+x,wa.y+y,
228                              l,h,
229                              5,
230                              BlackPixel(display,screen_num),
231                              WhitePixel(display,screen_num));
232  ((jxwin *)local_info)->win=w;
233
234  XSelectInput(display,w,
235    KeyPressMask | VisibilityChangeMask | ButtonPressMask | ButtonReleaseMask |
236    ButtonMotionMask | PointerMotionMask | KeyReleaseMask |
237    ExposureMask | StructureNotifyMask);
238
239  XSetTransientForHint(display,w,mainwin);
240  XSetWindowColormap(display,w,wa.colormap);
241
242
243  XTextProperty xtext;
244  ERROR(XStringListToTextProperty(&Name,1,&xtext),"X alloc failed");
245
246
247  XSizeHints *xsize;
248  ERROR((xsize=XAllocSizeHints()),"X alloc failed");
249  xsize->flags=PPosition | PSize | PMinSize | PMaxSize;
250  xsize->min_width=l;
251  xsize->min_height=h;
252  xsize->max_width=l;
253  xsize->max_height=h;
254
255
256  XWMHints *wm_hints;
257  ERROR((wm_hints=XAllocWMHints()),"X alloc failed");
258  wm_hints->initial_state=NormalState;  // not iconified at first
259  wm_hints->input=1;                  // needs keyboard input
260  wm_hints->flags=StateHint | InputHint;
261
262 
263  XSetWMProperties(display,w,&xtext,&xtext,&Name,0,xsize,wm_hints,NULL);
264  XFree(xtext.value);
265  XFree(xsize);
266  XFree(wm_hints);
267
268
269
270  XEvent report;
271  XMapWindow(display,((jxwin *)local_info)->win);
272  do
273  { XNextEvent(display, &report);
274  } while (report.type!= Expose);     // wait for our window to pop up
275  x=y=0;
276}
277
278void jwindow::local_close()
279{
280  XDestroyWindow(display,((jxwin *)local_info)->win);
281  jfree(local_info);
282}
283
284void jwindow::redraw(int hi, int med, int low, JCFont *fnt)
285{
286  if (jw_right>=3)
287    screen->rectangle(0,0,l-3,h-3,low);
288  if (jw_right>=2)
289    screen->rectangle(1,1,l-2,h-2,med);
290  if (jw_right>=1)
291    screen->rectangle(2,2,l-1,h-1,hi);
292
293
294 
295  screen->wiget_bar(0,0,l-1,8,hi,med,low);
296  screen->line(1,1,l-2,1,low);
297  screen->line(1,3,l-2,3,low);
298  screen->line(1,5,l-2,5,low);
299  screen->line(1,7,l-2,7,low);
300
301  screen->wiget_bar(4,3,10,5,hi,med,low);
302  screen->rectangle(3,2,11,6,0); 
303
304  screen->line(0,8,l-1,8,0);
305  if (jw_right>=1)
306    screen->wiget_bar(0,9,l-1,h-1,hi,med,low); 
307    screen->wiget_bar(0,9,l-1,h-1,hi,med,low);
308  if (jw_right>=2)
309    screen->wiget_bar(4,13,l-jw_right,h-jw_right,low,med,hi);
310
311
312  if (name && name[0])
313  {
314    short cx1,cy1,cx2,cy2;
315    screen->get_clip(cx1,cy1,cx2,cy2);
316    screen->set_clip(14,1,l-2,WINDOW_FRAME_TOP-8);
317    screen->bar(14,1,14+fnt->width()*strlen(name),WINDOW_FRAME_TOP-8,med);
318    fnt->put_string(screen,14,1,name,low); 
319    screen->set_clip(cx1,cy1,cx2,cy2);
320  }
321 
322  screen->bar(x1(),y1(),x2(),y2(),backg);
323  inm->redraw();
324}
325
326
327ifield *input_manager::unlink(int id)     // unlinks ID from fields list and return the pointer to it
328{
329  for (ifield *i=first,*last;i;i=i->next)
330  {
331    if (i->id==id)
332    {
333      if (i==first)
334        first=first->next;
335      else
336        last->next=i->next;
337      if (active==i)
338        active=first;
339      return i;
340    }
341    last=i;
342  }
343  return NULL;   // no such id
344}
345
346input_manager::~input_manager()
347{ ifield *i;
348  while (first)
349  { i=first;
350    first=first->next;
351    delete i;
352  }
353}
354
355void input_manager::handle_event(event &ev, int xoff, int yoff)
356{
357  ifield *i,*in_area=NULL;
358  int x1,y1,x2,y2;
359  ev.mouse_move.x-=xoff;
360  ev.mouse_move.y-=yoff;
361
362  if (ev.type==EV_MOUSE_BUTTON && ev.mouse_button==1)
363  {
364    for (i=first;i;i=i->next)
365    {
366      i->area(x1,y1,x2,y2,wm);
367      if (ev.mouse_move.x>=x1 && ev.mouse_move.y>=y1 &&
368          ev.mouse_move.x<=x2 && ev.mouse_move.y<=y2)
369        in_area=i;
370    }
371    if (in_area!=active && in_area  && in_area->selectable())
372    {
373      if (active)
374        active->draw(0,screen,wm);
375      active=in_area;
376      active->draw(1,screen,wm);
377    }
378  }
379  if (ev.type==EV_KEY && ev.key==JK_TAB && active)
380  {
381    active->draw(0,screen,wm);
382    do
383    {
384      active=active->next;
385      if (!active) active=first;
386    } while (active && !active->selectable());
387    active->draw(1,screen,wm);
388  }
389  if (active)
390  {
391    if (ev.type!=EV_MOUSE_MOVE && ev.type!=EV_MOUSE_BUTTON)
392      active->handle_event(ev,screen,wm);
393    else
394    {
395      active->area(x1,y1,x2,y2,wm);
396      if (ev.mouse_move.x>=x1 && ev.mouse_move.y>=y1 &&
397          ev.mouse_move.x<=x2 && ev.mouse_move.y<=y2)
398      active->handle_event(ev,screen,wm);
399    }
400  }
401 
402  ev.mouse_move.x+=xoff;
403  ev.mouse_move.y+=yoff;
404}
405
406void input_manager::redraw()
407{
408  ifield *i;
409  for (i=first;i;i=i->next)
410    i->draw_first(screen,wm);
411  if (active)
412    active->draw(1,screen,wm);
413}
414
415input_manager::input_manager(image *Screen, window_manager *WM, ifield *First)
416{
417  screen=Screen;
418  wm=WM;
419  active=first=First;
420  while (active && !active->selectable()) active=active->next;
421  redraw();
422}
423
424void input_manager::remap(filter *f)
425{
426  for (ifield *i=first;i;i=i->next)
427   i->remap(f);
428  redraw();
429}
430
431void input_manager::add(ifield *i)
432{ ifield *f=first;
433  if (i->selectable())
434  {
435    if (!f)
436      first=i;
437    else
438    {
439      while (f->next) f=f->next;
440      f->next=i;
441    }
442  }
443}
444
445ifield *input_manager::get(int id)
446{
447  ifield *f;
448  for (f=first;f;f=f->next)
449  {
450    ifield *ret=f->find(id);
451    if (ret) return ret;
452  }
453  return NULL;
454}
455
456
457
458
459
460
461
462
463
Note: See TracBrowser for help on using the repository browser.