root/foundation-apps/grosview-maxx/xwin.cc

Revision 2, 15.4 KB (checked in by emasson, 3 years ago)

initial import for the community edition

Line 
1//
2// $Id: xwin.cc,v 1.1.1.1 2008/05/04 15:53:48 emasson Exp $
3//
4
5#include <X11/Xatom.h>
6#include <stdlib.h>
7#include <unistd.h>
8#include "general.h"
9#include "xwin.h"
10#include "Xrm.h"
11
12CVSID("$Id: xwin.cc,v 1.1.1.1 2008/05/04 15:53:48 emasson Exp $");
13CVSID_DOT_H(XWIN_H_CVSID);
14
15//-----------------------------------------------------------------------------
16
17//  argc is a reference, so that the changes to argc by XrmParseCommand are
18//  noticed by the caller (XOSView, in this case).  BCG
19XWin::XWin(){
20}
21//-----------------------------------------------------------------------------
22
23XWin::XWin( int argc, char *argv[], int x, int y, int width, int height ){
24  std::cerr << "This constructor call is not supported! (" << __FILE__
25       << ":" << __LINE__ << ")" << std::endl;
26  exit (-1);
27  //  FIXME BCG  This constructor needs to do much of the work of the above
28  //  one.  Or, we need to drop this as a constructor.  As it is, it is
29  //  VERY MUCH out of date.
30  x_ = x;
31  y_ = y;
32  width_ = width;
33  height_ = height;
34  (void) argc;
35  (void) argv;
36}
37//-----------------------------------------------------------------------------
38
39void XWin::XWinInit (int argc, char** argv, char* geometry, Xrm* xrm) {
40  (void) argc;
41  (void) argv;  //  Avoid gcc warnings about unused variables.
42  //  Eventually, we may want to have XWin handle some arguments other
43  //  than resources, so argc and argv are left as parameters.  BCG
44
45  geometry_ = geometry;  //  Save for later use.
46  width_ = height_ = x_ = y_ = 0;
47  xrmptr_ = xrm;
48
49  name_ = "";
50  font_ = NULL;
51  done_ = 0; 
52 
53  // Set up the default Events
54  events_ = NULL;
55  addEvent( new Event( this, ConfigureNotify, &XWin::configureEvent ) );
56  addEvent( new Event( this, ClientMessage, &XWin::deleteEvent ) );
57  addEvent( new Event( this, MappingNotify, &XWin::mappingNotify ) );
58
59  //openDisplay();  //  Done explicitly in xosview.cc.
60}
61
62XWin::~XWin( void ){
63
64  // delete the events
65  Event *event = events_;
66  while ( event != NULL ){
67    Event *save = event->next_;
68    delete event;
69    event = save;
70  }
71 
72  XFree( title_.value );
73  XFree( iconname_.value );
74  XFree( sizehints_ );
75  XFree( wmhints_ );
76  XFree( classhints_ );
77  XFreeGC( display_, gc_ );
78  XFreeFont( display_, font_ );
79  XDestroyWindow( display_, window_ );
80  // close the connection to the display
81  XCloseDisplay( display_ );
82}
83//-----------------------------------------------------------------------------
84
85void XWin::init( int argc, char **argv ){
86  XGCValues            gcv;
87  XSetWindowAttributes xswa;
88  Pixmap               background_pixmap;
89  int                  doPixmap = 0;
90
91  setFont();
92  setColors();
93  getGeometry();
94#ifdef HAVE_XPM
95  doPixmap=getPixmap(&background_pixmap);
96#endif
97 
98  window_ = XCreateSimpleWindow(display_, DefaultRootWindow(display_),
99                                sizehints_->x, sizehints_->y,
100                                sizehints_->width, sizehints_->height,
101                                1,
102                                fgcolor_, bgcolor_);
103
104
105  setHints( argc, argv );
106
107  // Finally, create a graphics context for the main window
108  gcv.font = font_->fid;
109  gcv.foreground = fgcolor_;
110  gcv.background = bgcolor_;
111  gc_ = XCreateGC(display_, window_,
112                  (GCFont | GCForeground | GCBackground), &gcv);
113               
114  // Set main window's attributes (colormap, bit_gravity)
115  xswa.colormap = colormap_;
116  xswa.bit_gravity = NorthWestGravity;
117  XChangeWindowAttributes(display_, window_,
118                          (CWColormap | CWBitGravity), &xswa);
119
120  // If there is a pixmap file, set it as the background
121  if(doPixmap)
122  {
123        XSetWindowBackgroundPixmap(display_,window_,background_pixmap);
124  }
125
126  // Do transparency if requested
127  if(isResourceTrue("transparent"))
128  {
129        XSetWindowBackgroundPixmap(display_,window_,ParentRelative);
130  }         
131 
132  // add the events
133  Event *tmp = events_;
134  while ( tmp != NULL ){
135    selectEvents( tmp->mask_ );
136    tmp = tmp->next_;
137  }
138
139  // Map the main window
140  map();
141  flush();
142  if(XGetWindowAttributes(display_, window_, &attr_) == 0){
143    std::cerr <<"Error getting attributes of Main." <<std::endl;
144    exit(2);
145  }
146
147  //  Create stipple pixmaps.
148  stipples_[0] = createPixmap("\000\000", 2, 2);
149  stipples_[1] = createPixmap("\002\000\001\000", 2, 4);
150  stipples_[2] = createPixmap("\002\001", 2, 2);
151  stipples_[3] = createPixmap("\002\003\001\003", 2, 4);
152  doStippling_ = isResourceTrue("enableStipple");
153}
154//-----------------------------------------------------------------------------
155
156void XWin::setFont( void ){
157  // Set up the font
158  if ( font_ != NULL )
159    return;
160  const char* fontName = getResource("font");
161
162  if ((font_ = XLoadQueryFont(display_, fontName)) == NULL){
163    std::cerr <<name_ <<": display " <<DisplayString(display_)
164      <<" cannot load font " << fontName << std::endl;
165    exit(1);
166  }
167}
168//-----------------------------------------------------------------------------
169
170void XWin::setHints( int argc, char *argv[] ){
171  // Set up class hint
172  if((classhints_ = XAllocClassHint()) == NULL){
173    std::cerr <<"Error allocating class hint!" <<std::endl;
174    exit(1);
175  }
176  //  We have to cast away the const's.
177  classhints_->res_name = (char*) xrmptr_->instanceName();
178  classhints_->res_class = (char*) xrmptr_->className();
179
180  // Set up the window manager hints
181  if((wmhints_ = XAllocWMHints()) == NULL){
182    std::cerr <<"Error allocating Window Manager hints!" <<std::endl;
183    exit(1);
184  }
185  wmhints_->flags = (InputHint|StateHint);
186  wmhints_->input = True;
187  wmhints_->initial_state = NormalState;
188
189  // Set up XTextProperty for window name and icon name
190  if(XStringListToTextProperty(&name_, 1, &title_) == 0){
191    std::cerr <<"Error creating XTextProperty!" <<std::endl;
192    exit(1);
193  }
194  if(XStringListToTextProperty(&name_, 1, &iconname_) == 0){
195    std::cerr <<"Error creating XTextProperty!" <<std::endl;
196    exit(1);
197  }
198
199  XSetWMProperties(display_, window_, &title_, &iconname_, argv, argc,
200                   sizehints_, wmhints_, classhints_);
201
202  // Set up the Atoms for delete messages
203  wm_ = XInternAtom( display(), "WM_PROTOCOLS", False );
204  wmdelete_ = XInternAtom( display(), "WM_DELETE_WINDOW", False );
205  XChangeProperty( display(), window(), wm_, XA_ATOM, 32,
206                   PropModeReplace, (unsigned char *)(&wmdelete_), 1 );
207}
208//-----------------------------------------------------------------------------
209
210void XWin::openDisplay( void ){
211  // Open connection to display selected by user
212  if ((display_ = XOpenDisplay (display_name_)) == NULL) {
213    std::cerr <<"Can't open display named " << display_name_ <<std::endl;
214    exit(1);
215  }
216
217  colormap_ = DefaultColormap( display_, screen() ); 
218}
219//-----------------------------------------------------------------------------
220
221void XWin::setColors( void ){
222  XColor               color; 
223 
224  // Main window's background color
225  if (XParseColor(display_, colormap_, getResource("background"),
226                  &color) == 0 ||
227      XAllocColor(display_, colormap_, &color) == 0)
228    bgcolor_ = WhitePixel(display_, DefaultScreen(display_));
229  else
230    bgcolor_ = color.pixel;
231
232  // Main window's foreground color */
233  if (XParseColor(display_, colormap_, getResource("foreground"),
234                  &color) == 0 ||
235      XAllocColor(display_, colormap_, &color) == 0)
236    fgcolor_ = BlackPixel(display_, DefaultScreen(display_));
237  else
238    fgcolor_ = color.pixel;
239}
240//-----------------------------------------------------------------------------
241
242int XWin::getPixmap(Pixmap *pixmap)
243{
244#ifdef HAVE_XPM
245        char    *pixmap_file;
246        XWindowAttributes    root_att;
247        XpmAttributes        pixmap_att;
248
249//      if (isResourceTrue("transparent"))
250//      {
251//              Atom act_type;
252//              int act_format;
253//              unsigned long nitems, bytes_after;
254//              unsigned char *prop = NULL;
255//
256//              if (XGetWindowProperty(display_, window_,
257//                                     XInternAtom (display_, "_XROOTPMAP_ID", True),
258//                                     0, 1, False, XA_PIXMAP, &act_type, &act_format,
259//                                     &nitems, &bytes_after, &prop) != Success)
260//              {
261//                      cerr << "Unable to get root window pixmap" << endl;
262//                      cerr << "Defaulting to blank" << endl;
263//                      pixmap=NULL;
264//                      return 0; // OOps
265//              }
266//
267//              pixmap = (Pixmap *) prop;
268//              XFree (prop);
269//              return 1;  // Good, got the pixmap of the root window
270//      }
271
272        pixmap_file = (char*) getResourceOrUseDefault("pixmapName",NULL);
273
274        if (pixmap_file)
275        {
276                XGetWindowAttributes(display_, DefaultRootWindow(display_),&root_att);
277                pixmap_att.closeness=30000;
278                pixmap_att.colormap=root_att.colormap;
279                pixmap_att.valuemask=XpmSize|XpmReturnPixels|XpmColormap|XpmCloseness;
280                if(XpmReadFileToPixmap(display_,DefaultRootWindow(display_),pixmap_file, pixmap, NULL, &pixmap_att))
281                {
282                        std::cerr << "Pixmap " << pixmap_file  << " not found" << std::endl;
283                        std::cerr << "Defaulting to blank" << std::endl;
284                        pixmap=NULL;
285                        return 0; // OOps
286                }
287                return 1;  // Good, found the pixmap
288        }
289        return 0; // No file specified, none used
290#else
291        (void) pixmap;
292        std::cerr << "Error:  getPixmap called, when Xpm is not enabled!\n" ;
293        return 0;
294#endif
295}
296
297void XWin::getGeometry( void ){
298  char                 default_geometry[80];
299  int                  bitmask;
300
301  // Fill out a XsizeHints structure to inform the window manager
302  // of desired size and location of main window.
303  if((sizehints_ = XAllocSizeHints()) == NULL){
304    std::cerr <<"Error allocating size hints!" <<std::endl;
305    exit(1);
306  }
307  sizehints_->flags = PSize;
308  sizehints_->height = height_;
309  sizehints_->min_height = sizehints_->height;
310  sizehints_->width = width_;
311  sizehints_->min_width = sizehints_->width;
312  sizehints_->x = x_;
313  sizehints_->y = y_;
314
315  // Construct a default geometry string
316  snprintf(default_geometry, 80, "%dx%d+%d+%d", sizehints_->width,
317          sizehints_->height, sizehints_->x, sizehints_->y);
318
319  // Process the geometry specification
320  bitmask =  XGeometry(display_, DefaultScreen(display_),
321                       getResourceOrUseDefault("geometry", geometry_),
322                       default_geometry,
323                       0,
324                       1, 1, 0, 0, &(sizehints_->x), &(sizehints_->y),
325                       &(sizehints_->width), &(sizehints_->height));
326
327  // Check bitmask and set flags in XSizeHints structure
328  if (bitmask & (WidthValue | HeightValue)){
329    sizehints_->flags |= PPosition;
330    width_ = sizehints_->width;
331    height_ = sizehints_->height;
332  }
333
334  if (bitmask & (XValue | YValue)){
335    sizehints_->flags |= USPosition;
336    x_ = sizehints_->x;
337    y_ = sizehints_->y;
338  }
339}
340//-----------------------------------------------------------------------------
341
342void XWin::selectEvents( long mask ){
343  XWindowAttributes    xAttr;
344  XSetWindowAttributes xSwAttr;
345
346  if ( XGetWindowAttributes( display_, window_, &xAttr ) != 0 ){
347    xSwAttr.event_mask = xAttr.your_event_mask | mask;
348    XChangeWindowAttributes( display_, window_, CWEventMask, &xSwAttr );
349  }
350}
351
352void XWin::ignoreEvents( long mask ){
353  XWindowAttributes    xAttr;
354  XSetWindowAttributes xSwAttr;
355
356  if ( XGetWindowAttributes( display_, window_, &xAttr ) != 0 ){
357    xSwAttr.event_mask = xAttr.your_event_mask & mask;
358    XChangeWindowAttributes( display_, window_, CWEventMask, &xSwAttr );
359  }
360}
361//-----------------------------------------------------------------------------
362
363void XWin::checkevent( void ){
364  XEvent event;
365 
366  while ( XEventsQueued( display_, QueuedAfterReading ) ){
367    XNextEvent( display_, &event );
368
369    // call all of the Event's call back functions to process this event
370    Event *tmp = events_;
371    while ( tmp != NULL ){
372      tmp->callBack( event );
373      tmp = tmp->next_;
374    }
375  }
376}
377//-----------------------------------------------------------------------------
378#if 0
379void XWin::usage( void ){
380  //  FIXME  We need to update this.  BCG
381  std::cerr <<name_ <<" [-display name] [-geometry geom]" <<std::endl;
382//    exit (1);
383}
384#endif
385//-----------------------------------------------------------------------------
386
387void XWin::addEvent( Event *event ){
388  Event *tmp = events_;
389
390  if ( events_ == NULL )
391    events_ = event;
392  else {
393    while ( tmp->next_ != NULL )
394      tmp = tmp->next_;
395    tmp->next_ = event;
396  }
397}
398//-----------------------------------------------------------------------------
399
400const char *XWin::getResourceOrUseDefault( const char *name, const char* defaultVal ){
401
402  const char* retval = xrmptr_->getResource (name);
403  if (retval)
404    return retval;
405  else
406    return defaultVal;
407}
408
409//-----------------------------------------------------------------------------
410
411const char *XWin::getResource( const char *name ){
412  const char* retval = xrmptr_->getResource (name);
413  if (retval)
414    return retval;
415  else
416  {
417    std::cerr << "Error:  Couldn't find '" << name << "' resource in the resource database!\n";
418    exit (-1);
419      /*  Some compilers aren't smart enough to know that exit() exits.  */
420    return '\0';
421  }
422}
423
424//-----------------------------------------------------------------------------
425
426void XWin::dumpResources( std::ostream &os ){
427std::cerr << "Function not implemented!\n"//  BCG  FIXME  Need to make this.
428(void) os;  //  Keep gcc happy.
429}
430//-----------------------------------------------------------------------------
431
432unsigned long XWin::allocColor( const char *name ){
433  XColor exact, closest;
434 
435  if ( XAllocNamedColor( display_, colormap(), name, &closest, &exact ) == 0 )
436    std::cerr <<"XWin::allocColor() : failed to alloc : " <<name <<std::endl;
437
438  return exact.pixel;
439}
440//-----------------------------------------------------------------------------
441
442void XWin::configureEvent( XEvent &event ){
443  x( event.xconfigure.x );
444  y( event.xconfigure.y );
445  width( event.xconfigure.width );
446  height( event.xconfigure.height );
447}
448//-----------------------------------------------------------------------------
449
450void XWin::deleteEvent( XEvent &event ){
451  if ( (event.xclient.message_type == wm_ ) &&
452       ((unsigned)event.xclient.data.l[0] == wmdelete_) )
453    done( 1 );
454}
455//-----------------------------------------------------------------------------
456
457XWin::Event::Event( XWin *parent, int event, EventCallBack callBack ){
458  next_ = NULL;
459  parent_ = parent;
460  event_ = event;
461  callBack_ = callBack;
462
463  switch ( event_ ){
464  case ButtonPress:
465    mask_ = ButtonPressMask;
466    break;
467  case ButtonRelease:
468    mask_ = ButtonReleaseMask;
469    break;
470  case EnterNotify:
471    mask_ = EnterWindowMask;
472    break;
473  case LeaveNotify:
474    mask_ = LeaveWindowMask;
475    break;
476  case MotionNotify:
477    mask_ = PointerMotionMask;
478    break;
479  case FocusIn:
480  case FocusOut:
481    mask_ = FocusChangeMask;
482    break;
483  case KeymapNotify:
484    mask_ = KeymapStateMask;
485    break;
486  case KeyPress:
487    mask_ = KeyPressMask;
488    break;
489  case KeyRelease:
490    mask_ = KeyReleaseMask;
491    break;
492  case MapNotify:
493  case SelectionClear:
494  case SelectionNotify:
495  case SelectionRequest:
496  case ClientMessage:
497  case MappingNotify:
498    mask_ = NoEventMask;
499    break;
500  case Expose:
501  case GraphicsExpose:
502  case NoExpose:
503    mask_ = ExposureMask;
504    break;
505  case ColormapNotify:
506    mask_ = ColormapChangeMask;
507    break;
508  case PropertyNotify:
509    mask_ = PropertyChangeMask;
510    break;
511  case UnmapNotify:
512  case ReparentNotify:
513  case GravityNotify:
514  case DestroyNotify:
515  case CirculateNotify:
516  case ConfigureNotify:
517    mask_ = StructureNotifyMask | SubstructureNotifyMask;
518    break;
519  case CreateNotify:
520    mask_ = SubstructureNotifyMask;
521    break;
522  case VisibilityNotify:
523    mask_ = VisibilityChangeMask;
524    break;
525  // The following are used by window managers
526  case CirculateRequest:
527  case ConfigureRequest:
528  case MapRequest:
529    mask_ = SubstructureRedirectMask;
530    break;
531  case ResizeRequest:
532    mask_ = ResizeRedirectMask;
533    break;
534  default:
535    std::cerr <<"XWin::Event::Event() : unknown event type : " <<event_ <<std::endl;
536    mask_ = NoEventMask;
537    break;
538  }
539}
540
Note: See TracBrowser for help on using the browser.