]> git.saurik.com Git - wxWidgets.git/blame - src/x11/app.cpp
Add wxTranslations::GetTranslatedString().
[wxWidgets.git] / src / x11 / app.cpp
CommitLineData
83df96d6 1/////////////////////////////////////////////////////////////////////////////
4bcc3647 2// Name: src/x11/app.cpp
83df96d6
JS
3// Purpose: wxApp
4// Author: Julian Smart
5// Modified by:
6// Created: 17/09/98
83df96d6 7// Copyright: (c) Julian Smart
65571936 8// Licence: wxWindows licence
83df96d6
JS
9/////////////////////////////////////////////////////////////////////////////
10
4bcc3647
WS
11// for compilers that support precompilation, includes "wx.h".
12#include "wx/wxprec.h"
13
88a7a4e1
WS
14#include "wx/app.h"
15
32d4c30a
WS
16#ifndef WX_PRECOMP
17 #include "wx/hash.h"
88a7a4e1 18 #include "wx/intl.h"
e4db172a 19 #include "wx/log.h"
de6185e2 20 #include "wx/utils.h"
76b49cf4 21 #include "wx/frame.h"
923d28da 22 #include "wx/icon.h"
fdf565fe 23 #include "wx/dialog.h"
5b56bffb 24 #include "wx/memory.h"
dd05139a 25 #include "wx/gdicmn.h"
02761f6c 26 #include "wx/module.h"
11a0827d 27 #include "wx/crt.h"
32d4c30a
WS
28#endif
29
1b0fb34b 30#include "wx/evtloop.h"
2b5f62a0 31#include "wx/filename.h"
83df96d6 32
ef8c973b
VS
33#include "wx/univ/theme.h"
34#include "wx/univ/renderer.h"
c2ca375c 35#include "wx/generic/private/timer.h"
ef8c973b 36
83df96d6
JS
37#if wxUSE_THREADS
38 #include "wx/thread.h"
39#endif
40
7eaac9f5 41#include "wx/x11/private.h"
83df96d6
JS
42
43#include <string.h>
44
9d2cef1c
RR
45//------------------------------------------------------------------------
46// global data
47//------------------------------------------------------------------------
48
b8033a5d
VZ
49wxWindowHash *wxWidgetHashTable = NULL;
50wxWindowHash *wxClientWidgetHashTable = NULL;
9d2cef1c 51
4bcc3647 52static bool g_showIconic = false;
9d2cef1c 53static wxSize g_initialSize = wxDefaultSize;
83df96d6 54
9d2cef1c
RR
55// This is required for wxFocusEvent::SetWindow(). It will only
56// work for focus events which we provoke ourselves (by calling
57// SetFocus()). It will not work for those events, which X11
58// generates itself.
59static wxWindow *g_nextFocus = NULL;
60static wxWindow *g_prevFocus = NULL;
83df96d6 61
9d2cef1c
RR
62//------------------------------------------------------------------------
63// X11 error handling
64//------------------------------------------------------------------------
83df96d6 65
1b0fb34b 66typedef int (*XErrorHandlerFunc)(Display *, XErrorEvent *);
83df96d6 67
1b0fb34b 68XErrorHandlerFunc gs_pfnXErrorHandler = 0;
83df96d6 69
1b0fb34b
JS
70static int wxXErrorHandler(Display *dpy, XErrorEvent *xevent)
71{
72 // just forward to the default handler for now
c79a329d
JS
73 if (gs_pfnXErrorHandler)
74 return gs_pfnXErrorHandler(dpy, xevent);
75 else
76 return 0;
1b0fb34b 77}
83df96d6 78
9d2cef1c
RR
79//------------------------------------------------------------------------
80// wxApp
81//------------------------------------------------------------------------
82
83df96d6
JS
83long wxApp::sm_lastMessageTime = 0;
84
9d2cef1c
RR
85IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
86
3ee937aa 87bool wxApp::Initialize(int& argC, wxChar **argV)
83df96d6 88{
657a8a35 89#if !wxUSE_NANOX
a11672a4
RR
90 // install the X error handler
91 gs_pfnXErrorHandler = XSetErrorHandler( wxXErrorHandler );
657a8a35 92#endif
a11672a4 93
c6441a0d 94 wxString displayName;
4bcc3647 95 bool syncDisplay = false;
256d631a 96
3ee937aa
JS
97 int argCOrig = argC;
98 for ( int i = 0; i < argCOrig; i++ )
256d631a 99 {
9a83f860 100 if (wxStrcmp( argV[i], wxT("-display") ) == 0)
256d631a 101 {
995a9573 102 if (i < (argCOrig - 1))
256d631a 103 {
3ee937aa 104 argV[i++] = NULL;
05e2b077 105
3ee937aa 106 displayName = argV[i];
05e2b077 107
3ee937aa
JS
108 argV[i] = NULL;
109 argC -= 2;
256d631a
JS
110 }
111 }
9a83f860 112 else if (wxStrcmp( argV[i], wxT("-geometry") ) == 0)
256d631a 113 {
995a9573 114 if (i < (argCOrig - 1))
256d631a 115 {
3ee937aa 116 argV[i++] = NULL;
05e2b077 117
256d631a 118 int w, h;
9a83f860 119 if (wxSscanf(argV[i], wxT("%dx%d"), &w, &h) != 2)
256d631a 120 {
05e2b077 121 wxLogError( _("Invalid geometry specification '%s'"),
3ee937aa 122 wxString(argV[i]).c_str() );
256d631a
JS
123 }
124 else
125 {
126 g_initialSize = wxSize(w, h);
127 }
05e2b077 128
3ee937aa
JS
129 argV[i] = NULL;
130 argC -= 2;
256d631a
JS
131 }
132 }
9a83f860 133 else if (wxStrcmp( argV[i], wxT("-sync") ) == 0)
256d631a 134 {
4bcc3647 135 syncDisplay = true;
05e2b077 136
3ee937aa
JS
137 argV[i] = NULL;
138 argC--;
256d631a 139 }
9a83f860 140 else if (wxStrcmp( argV[i], wxT("-iconic") ) == 0)
256d631a 141 {
4bcc3647 142 g_showIconic = true;
45ff6421 143
3ee937aa
JS
144 argV[i] = NULL;
145 argC--;
256d631a 146 }
05e2b077 147 }
256d631a 148
3ee937aa 149 if ( argC != argCOrig )
05e2b077 150 {
995a9573 151 // remove the arguments we consumed
3ee937aa 152 for ( int i = 0; i < argC; i++ )
05e2b077 153 {
3ee937aa 154 while ( !argV[i] )
05e2b077 155 {
995a9573 156 memmove(argV + i, argV + i + 1, (argCOrig - i)*sizeof(wxChar *));
05e2b077
VZ
157 }
158 }
256d631a 159 }
a11672a4 160
b886fae6
VZ
161 // open and set up the X11 display
162 if ( !wxSetDisplay(displayName) )
a11672a4 163 {
b886fae6 164 wxLogError(_("wxWidgets could not open display. Exiting."));
05e2b077
VZ
165 return false;
166 }
167
b886fae6 168 Display *dpy = wxGlobalDisplay();
256d631a 169 if (syncDisplay)
b886fae6 170 XSynchronize(dpy, True);
7c9955d1 171
b886fae6 172 XSelectInput(dpy, XDefaultRootWindow(dpy), PropertyChangeMask);
e2386592 173
4bcc3647 174 wxSetDetectableAutoRepeat( true );
a11672a4 175
5b004007 176
b886fae6 177 if ( !wxAppBase::Initialize(argC, argV) )
5b004007 178 return false;
5b004007 179
2b5f62a0
VZ
180#if wxUSE_UNICODE
181 // Glib's type system required by Pango
182 g_type_init();
7c9955d1 183#endif
2b5f62a0 184
05e2b077
VZ
185#if wxUSE_INTL
186 wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
187#endif
a11672a4 188
b8033a5d
VZ
189 wxWidgetHashTable = new wxWindowHash;
190 wxClientWidgetHashTable = new wxWindowHash;
a11672a4 191
05e2b077 192 return true;
a11672a4
RR
193}
194
05e2b077 195void wxApp::CleanUp()
83df96d6 196{
5276b0a5
VZ
197 wxDELETE(wxWidgetHashTable);
198 wxDELETE(wxClientWidgetHashTable);
83df96d6 199
05e2b077
VZ
200 wxAppBase::CleanUp();
201}
83df96d6 202
83df96d6
JS
203wxApp::wxApp()
204{
b886fae6
VZ
205 m_mainColormap = NULL;
206 m_topLevelWidget = NULL;
83df96d6 207 m_maxRequestSize = 0;
4bcc3647 208 m_showIconic = false;
256d631a 209 m_initialSize = wxDefaultSize;
366e8ae6 210
8601b2e1 211#if !wxUSE_NANOX
9ce8d6a2 212 m_visualInfo = NULL;
8601b2e1 213#endif
dc4025af
RR
214}
215
216wxApp::~wxApp()
217{
8601b2e1 218#if !wxUSE_NANOX
9ce8d6a2 219 delete m_visualInfo;
8601b2e1 220#endif
83df96d6
JS
221}
222
70b8ab77 223#if !wxUSE_NANOX
aedeab23 224
f809133f
RR
225//-----------------------------------------------------------------------
226// X11 predicate function for exposure compression
227//-----------------------------------------------------------------------
228
229struct wxExposeInfo
230{
231 Window window;
232 Bool found_non_matching;
233};
234
aedeab23 235extern "C"
89954433 236Bool wxX11ExposePredicate (Display *WXUNUSED(display), XEvent *xevent, XPointer arg)
f809133f
RR
237{
238 wxExposeInfo *info = (wxExposeInfo*) arg;
e2386592 239
f809133f
RR
240 if (info->found_non_matching)
241 return FALSE;
e2386592 242
f809133f
RR
243 if (xevent->xany.type != Expose)
244 {
4bcc3647 245 info->found_non_matching = true;
f809133f
RR
246 return FALSE;
247 }
e2386592 248
f809133f
RR
249 if (xevent->xexpose.window != info->window)
250 {
4bcc3647 251 info->found_non_matching = true;
f809133f
RR
252 return FALSE;
253 }
e2386592 254
f809133f
RR
255 return TRUE;
256}
aedeab23
VZ
257
258#endif // wxUSE_NANOX
f809133f
RR
259
260//-----------------------------------------------------------------------
4bcc3647 261// Processes an X event, returning true if the event was processed.
f809133f
RR
262//-----------------------------------------------------------------------
263
086fd560 264bool wxApp::ProcessXEvent(WXEvent* _event)
1b0fb34b
JS
265{
266 XEvent* event = (XEvent*) _event;
83df96d6 267
1b0fb34b 268 wxWindow* win = NULL;
c79a329d 269 Window window = XEventGetWindow(event);
e2386592 270#if 0
1b0fb34b 271 Window actualWindow = window;
e2386592 272#endif
0b5c0e1a 273
1b0fb34b 274 // Find the first wxWindow that corresponds to this event window
774b90fb
JS
275 // Because we're receiving events after a window
276 // has been destroyed, assume a 1:1 match between
277 // Window and wxWindow, so if it's not in the table,
278 // it must have been destroyed.
e2386592 279
774b90fb
JS
280 win = wxGetWindowFromTable(window);
281 if (!win)
ab6b6b15
RR
282 {
283#if wxUSE_TWO_WINDOWS
284 win = wxGetClientWindowFromTable(window);
285 if (!win)
286#endif
4bcc3647 287 return false;
ab6b6b15 288 }
83df96d6 289
e2386592 290
1b0fb34b
JS
291 switch (event->type)
292 {
2f12683e
RR
293 case Expose:
294 {
8601b2e1 295#if wxUSE_TWO_WINDOWS && !wxUSE_NANOX
f41bc3e3 296 if (event->xexpose.window != (Window)win->GetClientAreaWindow())
ab6b6b15
RR
297 {
298 XEvent tmp_event;
299 wxExposeInfo info;
300 info.window = event->xexpose.window;
4bcc3647 301 info.found_non_matching = false;
aedeab23 302 while (XCheckIfEvent( wxGlobalDisplay(), &tmp_event, wxX11ExposePredicate, (XPointer) &info ))
ab6b6b15
RR
303 {
304 // Don't worry about optimizing redrawing the border etc.
305 }
306 win->NeedUpdateNcAreaInIdle();
307 }
308 else
309#endif
310 {
311 win->GetUpdateRegion().Union( XExposeEventGetX(event), XExposeEventGetY(event),
312 XExposeEventGetWidth(event), XExposeEventGetHeight(event));
ab6b6b15 313 win->GetClearRegion().Union( XExposeEventGetX(event), XExposeEventGetY(event),
2f12683e
RR
314 XExposeEventGetWidth(event), XExposeEventGetHeight(event));
315
316#if !wxUSE_NANOX
ab6b6b15
RR
317 XEvent tmp_event;
318 wxExposeInfo info;
319 info.window = event->xexpose.window;
4bcc3647 320 info.found_non_matching = false;
aedeab23 321 while (XCheckIfEvent( wxGlobalDisplay(), &tmp_event, wxX11ExposePredicate, (XPointer) &info ))
ab6b6b15
RR
322 {
323 win->GetUpdateRegion().Union( tmp_event.xexpose.x, tmp_event.xexpose.y,
324 tmp_event.xexpose.width, tmp_event.xexpose.height );
e2386592 325
ab6b6b15
RR
326 win->GetClearRegion().Union( tmp_event.xexpose.x, tmp_event.xexpose.y,
327 tmp_event.xexpose.width, tmp_event.xexpose.height );
328 }
2f12683e 329#endif
c2c0dabf
RR
330
331 // This simplifies the expose and clear areas to simple
332 // rectangles.
333 win->GetUpdateRegion() = win->GetUpdateRegion().GetBox();
334 win->GetClearRegion() = win->GetClearRegion().GetBox();
e2386592 335
c2c0dabf 336 // If we only have one X11 window, always indicate
e2386592 337 // that borders might have to be redrawn.
679918f9 338 if (win->X11GetMainWindow() == win->GetClientAreaWindow())
ab6b6b15 339 win->NeedUpdateNcAreaInIdle();
2f12683e 340
ab6b6b15
RR
341 // Only erase background, paint in idle time.
342 win->SendEraseEvents();
09a1dffa
JS
343
344 // EXPERIMENT
345 //win->Update();
ab6b6b15 346 }
2f12683e 347
4bcc3647 348 return true;
2f12683e 349 }
e2386592 350
2f12683e
RR
351#if !wxUSE_NANOX
352 case GraphicsExpose:
353 {
9a83f860 354 wxLogTrace( wxT("expose"), wxT("GraphicsExpose from %s"), win->GetName().c_str());
e2386592 355
2f12683e
RR
356 win->GetUpdateRegion().Union( event->xgraphicsexpose.x, event->xgraphicsexpose.y,
357 event->xgraphicsexpose.width, event->xgraphicsexpose.height);
e2386592 358
2f12683e
RR
359 win->GetClearRegion().Union( event->xgraphicsexpose.x, event->xgraphicsexpose.y,
360 event->xgraphicsexpose.width, event->xgraphicsexpose.height);
e2386592 361
2f12683e
RR
362 if (event->xgraphicsexpose.count == 0)
363 {
364 // Only erase background, paint in idle time.
365 win->SendEraseEvents();
c2c0dabf 366 // win->Update();
2f12683e
RR
367 }
368
4bcc3647 369 return true;
2f12683e
RR
370 }
371#endif
372
1b0fb34b 373 case KeyPress:
83df96d6 374 {
9d2cef1c 375 if (!win->IsEnabled())
4bcc3647 376 return false;
b513212d 377
9d2cef1c
RR
378 wxKeyEvent keyEvent(wxEVT_KEY_DOWN);
379 wxTranslateKeyEvent(keyEvent, win, window, event);
e2386592 380
9d2cef1c 381 // wxLogDebug( "OnKey from %s", win->GetName().c_str() );
e2386592 382
120b822d 383 // We didn't process wxEVT_KEY_DOWN, so send wxEVT_CHAR
937013e0 384 if (win->HandleWindowEvent( keyEvent ))
4bcc3647 385 return true;
e2386592 386
120b822d 387 keyEvent.SetEventType(wxEVT_CHAR);
2b5f62a0
VZ
388 // Do the translation again, retaining the ASCII
389 // code.
97f89762 390 if (wxTranslateKeyEvent(keyEvent, win, window, event, true) &&
937013e0 391 win->HandleWindowEvent( keyEvent ))
4bcc3647 392 return true;
e2386592 393
120b822d
RR
394 if ( (keyEvent.m_keyCode == WXK_TAB) &&
395 win->GetParent() && (win->GetParent()->HasFlag( wxTAB_TRAVERSAL)) )
9d2cef1c 396 {
120b822d
RR
397 wxNavigationKeyEvent new_event;
398 new_event.SetEventObject( win->GetParent() );
399 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
400 new_event.SetDirection( (keyEvent.m_keyCode == WXK_TAB) );
401 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
402 new_event.SetWindowChange( keyEvent.ControlDown() );
403 new_event.SetCurrentFocus( win );
937013e0 404 return win->GetParent()->HandleWindowEvent( new_event );
1b0fb34b 405 }
120b822d 406
4bcc3647 407 return false;
83df96d6 408 }
1b0fb34b 409 case KeyRelease:
7eaac9f5 410 {
9d2cef1c 411 if (!win->IsEnabled())
4bcc3647 412 return false;
b513212d 413
9d2cef1c
RR
414 wxKeyEvent keyEvent(wxEVT_KEY_UP);
415 wxTranslateKeyEvent(keyEvent, win, window, event);
e2386592 416
937013e0 417 return win->HandleWindowEvent( keyEvent );
7eaac9f5 418 }
256d631a
JS
419 case ConfigureNotify:
420 {
c79a329d 421#if wxUSE_NANOX
9d2cef1c 422 if (event->update.utype == GR_UPDATE_SIZE)
c79a329d 423#endif
256d631a 424 {
3cd2f0bd
VZ
425 wxTopLevelWindow *tlw = wxDynamicCast(win, wxTopLevelWindow);
426 if ( tlw )
c2c0dabf 427 {
c2c0dabf
RR
428 tlw->SetConfigureGeometry( XConfigureEventGetX(event), XConfigureEventGetY(event),
429 XConfigureEventGetWidth(event), XConfigureEventGetHeight(event) );
430 }
e2386592 431
3cd2f0bd 432 if ( tlw && tlw->IsShown() )
77df2fbc 433 {
77df2fbc
RR
434 tlw->SetNeedResizeInIdle();
435 }
436 else
437 {
438 wxSizeEvent sizeEvent( wxSize(XConfigureEventGetWidth(event), XConfigureEventGetHeight(event)), win->GetId() );
439 sizeEvent.SetEventObject( win );
e2386592 440
937013e0 441 return win->HandleWindowEvent( sizeEvent );
77df2fbc 442 }
256d631a 443 }
4bcc3647 444 return false;
256d631a
JS
445 }
446#if !wxUSE_NANOX
1b0fb34b 447 case PropertyNotify:
086fd560 448 return HandlePropertyChange(_event);
657a8a35 449
b513212d 450 case ClientMessage:
3a0b23eb 451 {
9d2cef1c 452 if (!win->IsEnabled())
4bcc3647 453 return false;
3a0b23eb 454
7e4501ee
RR
455 Atom wm_delete_window = XInternAtom(wxGlobalDisplay(), "WM_DELETE_WINDOW", True);
456 Atom wm_protocols = XInternAtom(wxGlobalDisplay(), "WM_PROTOCOLS", True);
b513212d
JS
457
458 if (event->xclient.message_type == wm_protocols)
459 {
6a44bffd 460 if ((Atom) (event->xclient.data.l[0]) == wm_delete_window)
b513212d 461 {
4bcc3647
WS
462 win->Close(false);
463 return true;
b513212d
JS
464 }
465 }
4bcc3647 466 return false;
b513212d 467 }
2f12683e
RR
468#if 0
469 case DestroyNotify:
470 {
471 printf( "destroy from %s\n", win->GetName().c_str() );
472 break;
473 }
474 case CreateNotify:
475 {
476 printf( "create from %s\n", win->GetName().c_str() );
477 break;
478 }
479 case MapRequest:
480 {
481 printf( "map request from %s\n", win->GetName().c_str() );
482 break;
483 }
1b0fb34b 484 case ResizeRequest:
7eaac9f5 485 {
2f12683e 486 printf( "resize request from %s\n", win->GetName().c_str() );
e2386592 487
7266b672 488 Display *disp = (Display*) wxGetDisplay();
1b0fb34b 489 XEvent report;
e2386592 490
1b0fb34b
JS
491 // to avoid flicker
492 report = * event;
493 while( XCheckTypedWindowEvent (disp, actualWindow, ResizeRequest, &report));
e2386592 494
b1633d20
RR
495 wxSize sz = win->GetSize();
496 wxSizeEvent sizeEvent(sz, win->GetId());
497 sizeEvent.SetEventObject(win);
1b0fb34b 498
937013e0 499 return win->HandleWindowEvent( sizeEvent );
7eaac9f5 500 }
256d631a 501#endif
b1633d20 502#endif
256d631a
JS
503#if wxUSE_NANOX
504 case GR_EVENT_TYPE_CLOSE_REQ:
505 {
506 if (win)
507 {
4bcc3647
WS
508 win->Close(false);
509 return true;
256d631a 510 }
4bcc3647 511 return false;
256d631a
JS
512 break;
513 }
c79a329d 514#endif
1b0fb34b
JS
515 case EnterNotify:
516 case LeaveNotify:
517 case ButtonPress:
518 case ButtonRelease:
519 case MotionNotify:
7eaac9f5 520 {
7e4501ee 521 if (!win->IsEnabled())
4bcc3647 522 return false;
366e8ae6 523
9691c806
RR
524 // Here we check if the top level window is
525 // disabled, which is one aspect of modality.
526 wxWindow *tlw = win;
527 while (tlw && !tlw->IsTopLevel())
528 tlw = tlw->GetParent();
529 if (tlw && !tlw->IsEnabled())
4bcc3647 530 return false;
e2386592 531
7e4501ee 532 if (event->type == ButtonPress)
1b0fb34b 533 {
ad02525d 534 if ((win != wxWindow::FindFocus()) && win->CanAcceptFocus())
9d2cef1c
RR
535 {
536 // This might actually be done in wxWindow::SetFocus()
ea1ad04b 537 // and not here. TODO.
9d2cef1c
RR
538 g_prevFocus = wxWindow::FindFocus();
539 g_nextFocus = win;
e2386592 540
9a83f860 541 wxLogTrace( wxT("focus"), wxT("About to call SetFocus on %s of type %s due to button press"), win->GetName().c_str(), win->GetClassInfo()->GetClassName() );
58ec2255
JS
542
543 // Record the fact that this window is
544 // getting the focus, because we'll need to
545 // check if its parent is getting a bogus
546 // focus and duly ignore it.
547 // TODO: may need to have this code in SetFocus, too.
548 extern wxWindow* g_GettingFocus;
549 g_GettingFocus = win;
9d2cef1c
RR
550 win->SetFocus();
551 }
1b0fb34b 552 }
e2386592 553
ea1ad04b
RR
554#if !wxUSE_NANOX
555 if (event->type == LeaveNotify || event->type == EnterNotify)
556 {
557 // Throw out NotifyGrab and NotifyUngrab
558 if (event->xcrossing.mode != NotifyNormal)
4bcc3647 559 return false;
ea1ad04b
RR
560 }
561#endif
7e4501ee
RR
562 wxMouseEvent wxevent;
563 wxTranslateMouseEvent(wxevent, win, window, event);
937013e0 564 return win->HandleWindowEvent( wxevent );
7eaac9f5 565 }
1b0fb34b 566 case FocusIn:
256d631a 567#if !wxUSE_NANOX
bcd3832a
VZ
568 if ((event->xfocus.detail != NotifyPointer) &&
569 (event->xfocus.mode == NotifyNormal))
256d631a 570#endif
bcd3832a 571 {
9a83f860 572 wxLogTrace( wxT("focus"), wxT("FocusIn from %s of type %s"), win->GetName().c_str(), win->GetClassInfo()->GetClassName() );
bcd3832a
VZ
573
574 extern wxWindow* g_GettingFocus;
575 if (g_GettingFocus && g_GettingFocus->GetParent() == win)
576 {
577 // Ignore this, this can be a spurious FocusIn
578 // caused by a child having its focus set.
579 g_GettingFocus = NULL;
9a83f860 580 wxLogTrace( wxT("focus"), wxT("FocusIn from %s of type %s being deliberately ignored"), win->GetName().c_str(), win->GetClassInfo()->GetClassName() );
4bcc3647 581 return true;
bcd3832a
VZ
582 }
583 else
1b0fb34b 584 {
bcd3832a
VZ
585 wxFocusEvent focusEvent(wxEVT_SET_FOCUS, win->GetId());
586 focusEvent.SetEventObject(win);
587 focusEvent.SetWindow( g_prevFocus );
588 g_prevFocus = NULL;
366e8ae6 589
937013e0 590 return win->HandleWindowEvent(focusEvent);
1b0fb34b 591 }
1b0fb34b 592 }
4bcc3647 593 return false;
bcd3832a 594
1b0fb34b 595 case FocusOut:
256d631a 596#if !wxUSE_NANOX
bcd3832a
VZ
597 if ((event->xfocus.detail != NotifyPointer) &&
598 (event->xfocus.mode == NotifyNormal))
256d631a 599#endif
bcd3832a 600 {
9a83f860 601 wxLogTrace( wxT("focus"), wxT("FocusOut from %s of type %s"), win->GetName().c_str(), win->GetClassInfo()->GetClassName() );
e2386592 602
bcd3832a
VZ
603 wxFocusEvent focusEvent(wxEVT_KILL_FOCUS, win->GetId());
604 focusEvent.SetEventObject(win);
605 focusEvent.SetWindow( g_nextFocus );
606 g_nextFocus = NULL;
937013e0 607 return win->HandleWindowEvent(focusEvent);
1b0fb34b 608 }
4bcc3647 609 return false;
83df96d6 610 }
83df96d6 611
4bcc3647 612 return false;
83df96d6
JS
613}
614
615// This should be redefined in a derived class for
616// handling property change events for XAtom IPC.
89954433 617bool wxApp::HandlePropertyChange(WXEvent *WXUNUSED(event))
83df96d6
JS
618{
619 // by default do nothing special
7eaac9f5 620 // TODO: what to do for X11
256d631a 621 // XtDispatchEvent((XEvent*) event);
4bcc3647 622 return false;
83df96d6
JS
623}
624
e2478fde 625void wxApp::WakeUpIdle()
83df96d6 626{
e2478fde
VZ
627 // TODO: use wxMotif implementation?
628
83df96d6
JS
629 // Wake up the idle handler processor, even if it is in another thread...
630}
631
632
256d631a 633// Create display, and other initialization
83df96d6
JS
634bool wxApp::OnInitGui()
635{
d8cebdca 636#if wxUSE_LOG
ca7497c2
JS
637 // Eventually this line will be removed, but for
638 // now we don't want to try popping up a dialog
639 // for error messages.
640 delete wxLog::SetActiveTarget(new wxLogStderr);
d8cebdca 641#endif
e2386592 642
ea596687 643 if (!wxAppBase::OnInitGui())
4bcc3647 644 return false;
e2386592 645
b886fae6
VZ
646 Display *dpy = wxGlobalDisplay();
647 GetMainColormap(dpy);
256d631a 648
b886fae6 649 m_maxRequestSize = XMaxRequestSize(dpy);
83df96d6 650
8601b2e1 651#if !wxUSE_NANOX
9ce8d6a2 652 m_visualInfo = new wxXVisualInfo;
b886fae6 653 wxFillXVisualInfo(m_visualInfo, dpy);
8601b2e1 654#endif
366e8ae6 655
4bcc3647 656 return true;
83df96d6
JS
657}
658
2b5f62a0
VZ
659#if wxUSE_UNICODE
660
661#include <pango/pango.h>
662#include <pango/pangox.h>
4ae1af05
MB
663#ifdef HAVE_PANGO_XFT
664 #include <pango/pangoxft.h>
665#endif
2b5f62a0
VZ
666
667PangoContext* wxApp::GetPangoContext()
668{
b886fae6
VZ
669 static PangoContext *s_pangoContext = NULL;
670 if ( !s_pangoContext )
671 {
672 Display *dpy = wxGlobalDisplay();
7c9955d1 673
4ae1af05 674#ifdef HAVE_PANGO_XFT
b886fae6
VZ
675 int xscreen = DefaultScreen(dpy);
676 static int use_xft = -1;
677 if (use_xft == -1)
678 {
679 wxString val = wxGetenv( L"GDK_USE_XFT" );
680 use_xft = val == L"1";
681 }
7c9955d1 682
b886fae6
VZ
683 if (use_xft)
684 s_pangoContext = pango_xft_get_context(dpy, xscreen);
685 else
686#endif // HAVE_PANGO_XFT
687 s_pangoContext = pango_x_get_context(dpy);
7c9955d1 688
b886fae6 689 if (!PANGO_IS_CONTEXT(s_pangoContext))
43b2d5e7 690 {
b886fae6 691 wxLogError( wxT("No pango context.") );
43b2d5e7 692 }
b886fae6 693 }
7c9955d1 694
b886fae6 695 return s_pangoContext;
2b5f62a0 696}
b886fae6
VZ
697
698#endif // wxUSE_UNICODE
2b5f62a0 699
83df96d6
JS
700WXColormap wxApp::GetMainColormap(WXDisplay* display)
701{
702 if (!display) /* Must be called first with non-NULL display */
703 return m_mainColormap;
704
705 int defaultScreen = DefaultScreen((Display*) display);
706 Screen* screen = XScreenOfDisplay((Display*) display, defaultScreen);
707
708 Colormap c = DefaultColormapOfScreen(screen);
709
710 if (!m_mainColormap)
711 m_mainColormap = (WXColormap) c;
712
713 return (WXColormap) c;
714}
715
8354aa92 716Window wxGetWindowParent(Window window)
7eaac9f5 717{
9a83f860 718 wxASSERT_MSG( window, wxT("invalid window") );
e2386592 719
86fd8bda
RR
720 return (Window) 0;
721
a371f703
JJ
722#ifndef __VMS
723 // VMS chokes on unreacheable code
724 Window parent, root = 0;
c79a329d
JS
725#if wxUSE_NANOX
726 int noChildren = 0;
727#else
7eaac9f5 728 unsigned int noChildren = 0;
c79a329d 729#endif
ea596687 730 Window* children = NULL;
c79a329d 731
ee351013 732 // #define XQueryTree(d,w,r,p,c,nc) GrQueryTree(w,p,c,nc)
c79a329d
JS
733 int res = 1;
734#if !wxUSE_NANOX
735 res =
736#endif
737 XQueryTree((Display*) wxGetDisplay(), window, & root, & parent,
ee351013 738 & children, & noChildren);
ea596687
JS
739 if (children)
740 XFree(children);
741 if (res)
7eaac9f5
JS
742 return parent;
743 else
744 return (Window) 0;
a371f703 745#endif
7eaac9f5
JS
746}
747
e2478fde 748void wxApp::Exit()
83df96d6 749{
83df96d6 750 wxApp::CleanUp();
e2478fde
VZ
751
752 wxAppConsole::Exit();
83df96d6
JS
753}
754