1 // -*- mode: C++; indent-tabs-mode: nil; -*-
4 # include "../config.h"
7 #include "../version.h"
10 #include "otk/property.hh"
11 #include "otk/display.hh"
12 #include "otk/assassin.hh"
13 #include "otk/util.hh" // TEMPORARY
16 #include <X11/cursorfont.h>
20 #endif // HAVE_STDIO_H
24 #endif // HAVE_STDLIB_H
28 #endif // HAVE_SIGNAL_H
32 #endif // HAVE_FCNTL_H
35 # include <sys/types.h>
37 #endif // HAVE_UNISTD_H
39 #ifdef HAVE_SYS_SELECT_H
40 # include <sys/select.h>
41 #endif // HAVE_SYS_SELECT_H
44 #define _(str) gettext(str)
51 Openbox
*Openbox::instance
= (Openbox
*) 0;
54 void Openbox::signalHandler(int signal
)
58 // XXX: Do something with HUP? Really shouldn't, we get this when X shuts
59 // down and hangs-up on us.
64 printf("Caught signal %d. Exiting.\n", signal
);
70 printf("Caught signal %d. Aborting and dumping core.\n", signal
);
76 Openbox::Openbox(int argc
, char **argv
)
77 : otk::OtkEventDispatcher(),
78 otk::OtkEventHandler()
80 struct sigaction action
;
82 _state
= State_Starting
; // initializing everything
84 Openbox::instance
= this;
86 _displayreq
= (char*) 0;
89 _rcfilepath
= otk::expandTilde("~/.openbox/rc3");
91 parseCommandLine(argc
, argv
);
93 // TEMPORARY: using the xrdb rc3
94 _config
.setFile(_rcfilepath
);
95 if (!_config
.load()) {
96 printf("failed to load rc file %s\n", _config
.file().c_str());
100 _config
.getValue("session.styleFile", s
);
102 if (!_config
.load()) {
103 printf("failed to load style %s\n", _config
.file().c_str());
107 // open the X display (and gets some info about it, and its screens)
108 otk::OBDisplay::initialize(_displayreq
);
109 assert(otk::OBDisplay::display
);
111 // set up the signal handler
112 action
.sa_handler
= Openbox::signalHandler
;
113 action
.sa_mask
= sigset_t();
114 action
.sa_flags
= SA_NOCLDSTOP
| SA_NODEFER
;
115 sigaction(SIGPIPE
, &action
, (struct sigaction
*) 0);
116 sigaction(SIGSEGV
, &action
, (struct sigaction
*) 0);
117 sigaction(SIGFPE
, &action
, (struct sigaction
*) 0);
118 sigaction(SIGTERM
, &action
, (struct sigaction
*) 0);
119 sigaction(SIGINT
, &action
, (struct sigaction
*) 0);
120 sigaction(SIGHUP
, &action
, (struct sigaction
*) 0);
122 _property
= new otk::OBProperty();
124 // set this class as the fallback event handler (for map events)
125 setFallbackHandler(this);
127 // create the mouse cursors we'll use
128 _cursors
.session
= XCreateFontCursor(otk::OBDisplay::display
, XC_left_ptr
);
129 _cursors
.move
= XCreateFontCursor(otk::OBDisplay::display
, XC_fleur
);
130 _cursors
.ll_angle
= XCreateFontCursor(otk::OBDisplay::display
, XC_ll_angle
);
131 _cursors
.lr_angle
= XCreateFontCursor(otk::OBDisplay::display
, XC_lr_angle
);
132 _cursors
.ul_angle
= XCreateFontCursor(otk::OBDisplay::display
, XC_ul_angle
);
133 _cursors
.ur_angle
= XCreateFontCursor(otk::OBDisplay::display
, XC_ur_angle
);
135 // initialize all the screens
137 screen
= new OBScreen(0, _config
);
138 if (screen
->managed()) {
139 _screens
.push_back(screen
);
140 _screens
[0]->manageExisting();
141 // XXX: "change to" the first workspace on the screen to initialize stuff
145 if (_screens
.empty()) {
146 printf(_("No screens were found without a window manager. Exiting.\n"));
150 _state
= State_Normal
; // done starting
156 _state
= State_Exiting
; // time to kill everything
158 std::for_each(_screens
.begin(), _screens
.end(), otk::PointerAssassin());
160 // close the X display
161 otk::OBDisplay::destroy();
165 void Openbox::parseCommandLine(int argc
, char **argv
)
169 for (int i
= 1; i
< argc
; ++i
) {
170 std::string
arg(argv
[i
]);
172 if (arg
== "-display") {
176 _displayreq
= argv
[i
];
177 } else if (arg
== "-rc") {
181 _rcfilepath
= argv
[i
];
182 } else if (arg
== "-menu") {
186 _menufilepath
= argv
[i
];
187 } else if (arg
== "-version") {
190 } else if (arg
== "-help") {
204 void Openbox::showVersion()
206 printf(_("Openbox - version %s\n"), OPENBOX_VERSION
);
207 printf(" (c) 2002 - 2002 Ben Jansens\n\n");
211 void Openbox::showHelp()
213 showVersion(); // show the version string and copyright
215 // print program usage and command line options
216 printf(_("Usage: %s [OPTIONS...]\n\
218 -display <string> use display connection.\n\
219 -rc <string> use alternate resource file.\n\
220 -menu <string> use alternate menu file.\n\
221 -version display version and exit.\n\
222 -help display this help text and exit.\n\n"), _argv0
);
224 printf(_("Compile time options:\n\
249 void Openbox::eventLoop()
251 while (!_doshutdown
) {
252 dispatchEvents(); // from OtkEventDispatcher
253 _timermanager
.fire();
258 void Openbox::addClient(Window window
, OBClient
*client
)
260 _clients
[window
] = client
;
264 void Openbox::removeClient(Window window
)
266 ClientMap::iterator it
= _clients
.find(window
);
267 if (it
!= _clients
.end())
272 OBClient
*Openbox::findClient(Window window
)
275 NOTE: we dont use _clients[] to find the value because that will insert
276 a new null into the hash, which really sucks when we want to clean up the
279 ClientMap::iterator it
= _clients
.find(window
);
280 if (it
!= _clients
.end())
283 return (OBClient
*) 0;
287 void Openbox::mapRequestHandler(const XMapRequestEvent
&e
)
290 printf("MapRequest for 0x%lx\n", e
.window
);
293 otk::OtkEventHandler::mapRequestHandler(e
);
295 OBClient
*client
= findClient(e
.window
);
298 // XXX: uniconify and/or unshade the window
300 int screen
= INT_MAX
;
302 for (int i
= 0; i
< ScreenCount(otk::OBDisplay::display
); ++i
)
303 if (otk::OBDisplay::screenInfo(i
)->getRootWindow() == e
.parent
) {
308 if (screen
>= ScreenCount(otk::OBDisplay::display
)) {
310 we got a map request for a window who's parent isn't root. this
311 can happen in only one circumstance:
313 a client window unmapped a managed window, and then remapped it
314 somewhere between unmapping the client window and reparenting it
317 regardless of how it happens, we need to find the screen that
320 XWindowAttributes wattrib
;
321 if (! XGetWindowAttributes(otk::OBDisplay::display
, e
.window
,
323 // failed to get the window attributes, perhaps the window has
324 // now been destroyed?
328 for (int i
= 0; i
< ScreenCount(otk::OBDisplay::display
); ++i
)
329 if (otk::OBDisplay::screenInfo(i
)->getRootWindow() == wattrib
.root
) {
335 assert(screen
< static_cast<int>(_screens
.size()));
336 _screens
[screen
]->manageWindow(e
.window
);