]> git.saurik.com Git - wxWidgets.git/blame - src/motif/app.cpp
image handlers moved to separate headers (imagbmp.h etc.) This change is backward...
[wxWidgets.git] / src / motif / app.cpp
CommitLineData
4bb6408c
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: app.cpp
3// Purpose: wxApp
4// Author: Julian Smart
5// Modified by:
6// Created: 17/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
afb74891 9// Licence: wxWindows licence
4bb6408c
JS
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
ee31c392 13 #pragma implementation "app.h"
4bb6408c
JS
14#endif
15
16#include "wx/frame.h"
17#include "wx/app.h"
18#include "wx/utils.h"
19#include "wx/gdicmn.h"
20#include "wx/pen.h"
21#include "wx/brush.h"
22#include "wx/cursor.h"
23#include "wx/icon.h"
24#include "wx/palette.h"
25#include "wx/dc.h"
26#include "wx/dialog.h"
27#include "wx/msgdlg.h"
28#include "wx/log.h"
29#include "wx/module.h"
30#include "wx/memory.h"
8bedcdce
RR
31#include "wx/log.h"
32#include "wx/intl.h"
b412f9be 33
7bcb11d3 34#if wxUSE_THREADS
dfe1eee3 35 #include "wx/thread.h"
7bcb11d3 36#endif
4bb6408c 37
47d67540 38#if wxUSE_WX_RESOURCES
9c6e1335 39 #include "wx/resource.h"
4bb6408c
JS
40#endif
41
338dd992
JJ
42#ifdef __VMS__
43#pragma message disable nosimpint
44#endif
4bb6408c
JS
45#include <Xm/Xm.h>
46#include <X11/Xlib.h>
47#include <X11/Xutil.h>
48#include <X11/Xresource.h>
49#include <X11/Xatom.h>
338dd992
JJ
50#ifdef __VMS__
51#pragma message enable nosimpint
52#endif
4bb6408c
JS
53
54#include "wx/motif/private.h"
55
56#include <string.h>
57
58extern char *wxBuffer;
59extern wxList wxPendingDelete;
7491d644 60
4bb6408c
JS
61wxApp *wxTheApp = NULL;
62
63wxHashTable *wxWidgetHashTable = NULL;
64
4bb6408c 65IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
9c6e1335 66
4bb6408c 67BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
9c6e1335 68 EVT_IDLE(wxApp::OnIdle)
4bb6408c 69END_EVENT_TABLE()
4bb6408c
JS
70
71long wxApp::sm_lastMessageTime = 0;
72
73bool wxApp::Initialize()
74{
4bb6408c 75 wxBuffer = new char[BUFSIZ + 512];
afb74891 76
4bb6408c 77 wxClassInfo::InitializeClasses();
afb74891 78
ee31c392 79 // GL: I'm annoyed ... I don't know where to put this and I don't want to
4d3a259a
GL
80 // create a module for that as it's part of the core.
81#if wxUSE_THREADS
4d3a259a
GL
82 wxPendingEventsLocker = new wxCriticalSection();
83#endif
84
4bb6408c
JS
85 wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
86 wxTheColourDatabase->Initialize();
afb74891 87
4b5f3fe6 88 wxInitializeStockLists();
4bb6408c 89 wxInitializeStockObjects();
afb74891 90
47d67540 91#if wxUSE_WX_RESOURCES
4bb6408c
JS
92 wxInitializeResourceSystem();
93#endif
afb74891 94
2d120f83 95 // For PostScript printing
47d67540 96#if wxUSE_POSTSCRIPT
2d120f83 97 /* Done using wxModule now
4bb6408c
JS
98 wxInitializePrintSetupData();
99 wxThePrintPaperDatabase = new wxPrintPaperDatabase;
100 wxThePrintPaperDatabase->CreateDatabase();
2d120f83 101 */
4bb6408c 102#endif
afb74891 103
4bb6408c 104 wxBitmap::InitStandardHandlers();
afb74891 105
4bb6408c 106 wxWidgetHashTable = new wxHashTable(wxKEY_INTEGER);
afb74891 107
4bb6408c 108 wxModule::RegisterModules();
aaa38880 109 if (!wxModule::InitializeModules()) return FALSE;
afb74891 110
4bb6408c
JS
111 return TRUE;
112}
113
114void wxApp::CleanUp()
115{
116 delete wxWidgetHashTable;
117 wxWidgetHashTable = NULL;
afb74891 118
4bb6408c 119 wxModule::CleanUpModules();
afb74891 120
47d67540 121#if wxUSE_WX_RESOURCES
4bb6408c
JS
122 wxCleanUpResourceSystem();
123#endif
afb74891 124
4bb6408c 125 wxDeleteStockObjects() ;
afb74891 126
4bb6408c 127 // Destroy all GDI lists, etc.
afb74891 128
4bb6408c
JS
129 delete wxTheBrushList;
130 wxTheBrushList = NULL;
afb74891 131
4bb6408c
JS
132 delete wxThePenList;
133 wxThePenList = NULL;
afb74891 134
4bb6408c
JS
135 delete wxTheFontList;
136 wxTheFontList = NULL;
afb74891 137
4bb6408c
JS
138 delete wxTheBitmapList;
139 wxTheBitmapList = NULL;
afb74891 140
4bb6408c
JS
141 delete wxTheColourDatabase;
142 wxTheColourDatabase = NULL;
afb74891 143
47d67540 144#if wxUSE_POSTSCRIPT
2d120f83 145 /* Done using wxModule now
4bb6408c
JS
146 wxInitializePrintSetupData(FALSE);
147 delete wxThePrintPaperDatabase;
148 wxThePrintPaperDatabase = NULL;
2d120f83 149 */
4bb6408c 150#endif
afb74891 151
4bb6408c 152 wxBitmap::CleanUpHandlers();
afb74891 153
4bb6408c
JS
154 delete[] wxBuffer;
155 wxBuffer = NULL;
afb74891 156
4bb6408c 157 wxClassInfo::CleanUpClasses();
afb74891 158
184b5d99
JS
159 delete wxTheApp;
160 wxTheApp = NULL;
afb74891 161
4d3a259a
GL
162 // GL: I'm annoyed ... I don't know where to put this and I don't want to
163 // create a module for that as it's part of the core.
164#if wxUSE_THREADS
165 delete wxPendingEvents;
166 delete wxPendingEventsLocker;
167#endif
168
184b5d99
JS
169#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
170 // At this point we want to check if there are any memory
171 // blocks that aren't part of the wxDebugContext itself,
172 // as a special case. Then when dumping we need to ignore
173 // wxDebugContext, too.
4fabb575 174 if (wxDebugContext::CountObjectsLeft(TRUE) > 0)
184b5d99 175 {
2d120f83
JS
176 wxLogDebug("There were memory leaks.\n");
177 wxDebugContext::Dump();
178 wxDebugContext::PrintStatistics();
184b5d99 179 }
184b5d99 180#endif
afb74891 181
4bb6408c
JS
182 // do it as the very last thing because everything else can log messages
183 wxLog::DontCreateOnDemand();
184 // do it as the very last thing because everything else can log messages
185 delete wxLog::SetActiveTarget(NULL);
186}
187
188int wxEntry( int argc, char *argv[] )
189{
4fabb575
JS
190#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
191 // This seems to be necessary since there are 'rogue'
192 // objects present at this point (perhaps global objects?)
193 // Setting a checkpoint will ignore them as far as the
194 // memory checking facility is concerned.
195 // Of course you may argue that memory allocated in globals should be
196 // checked, but this is a reasonable compromise.
197 wxDebugContext::SetCheckpoint();
198#endif
afb74891 199
4bb6408c 200 if (!wxApp::Initialize())
2d120f83 201 return FALSE;
afb74891 202
4bb6408c
JS
203 if (!wxTheApp)
204 {
2d120f83
JS
205 if (!wxApp::GetInitializerFunction())
206 {
207 printf( "wxWindows error: No initializer - use IMPLEMENT_APP macro.\n" );
208 return 0;
209 };
afb74891 210
2d120f83 211 wxTheApp = (wxApp*) (* wxApp::GetInitializerFunction()) ();
4bb6408c 212 };
afb74891 213
4bb6408c
JS
214 if (!wxTheApp)
215 {
2d120f83
JS
216 printf( "wxWindows error: wxTheApp == NULL\n" );
217 return 0;
4bb6408c 218 };
afb74891 219
4bb6408c
JS
220 wxTheApp->SetClassName(wxFileNameFromPath(argv[0]));
221 wxTheApp->SetAppName(wxFileNameFromPath(argv[0]));
afb74891 222
4bb6408c
JS
223 wxTheApp->argc = argc;
224 wxTheApp->argv = argv;
afb74891 225
4bb6408c
JS
226 // GUI-specific initialization, such as creating an app context.
227 wxTheApp->OnInitGui();
afb74891 228
e146b8c8
VZ
229 // Here frames insert themselves automatically into wxTopLevelWindows by
230 // getting created in OnInit().
afb74891 231
4bb6408c 232 int retValue = 0;
4fabb575
JS
233 if (wxTheApp->OnInit())
234 {
2d120f83 235 if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun();
4fabb575 236 }
afb74891 237
f57fe24c
JS
238 // flush the logged messages if any
239 wxLog *pLog = wxLog::GetActiveTarget();
240 if ( pLog != NULL && pLog->HasPendingMessages() )
2d120f83 241 pLog->Flush();
afb74891 242
f57fe24c 243 delete wxLog::SetActiveTarget(new wxLogStderr); // So dialog boxes aren't used
2d120f83 244 // for further messages
afb74891 245
4bb6408c
JS
246 if (wxTheApp->GetTopWindow())
247 {
2d120f83
JS
248 delete wxTheApp->GetTopWindow();
249 wxTheApp->SetTopWindow(NULL);
4bb6408c 250 }
afb74891 251
4bb6408c 252 wxTheApp->DeletePendingObjects();
afb74891 253
4bb6408c 254 wxTheApp->OnExit();
afb74891 255
4bb6408c 256 wxApp::CleanUp();
afb74891 257
4bb6408c
JS
258 return retValue;
259};
260
261// Static member initialization
ee31c392 262wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
4bb6408c
JS
263
264wxApp::wxApp()
265{
266 m_topWindow = NULL;
267 wxTheApp = this;
268 m_className = "";
269 m_wantDebugOutput = TRUE ;
270 m_appName = "";
271 argc = 0;
272 argv = NULL;
4bb6408c 273 m_exitOnFrameDelete = TRUE;
afb74891 274
4bb6408c
JS
275 m_mainColormap = (WXColormap) NULL;
276 m_appContext = (WXAppContext) NULL;
277 m_topLevelWidget = (WXWidget) NULL;
278 m_maxRequestSize = 0;
47bc1060 279 m_initialDisplay = (WXDisplay*) 0;
4bb6408c
JS
280}
281
282bool wxApp::Initialized()
283{
284 if (GetTopWindow())
2d120f83 285 return TRUE;
4bb6408c 286 else
2d120f83 287 return FALSE;
4bb6408c
JS
288}
289
290int wxApp::MainLoop()
291{
292 m_keepGoing = TRUE;
afb74891 293
2d120f83 294 /*
4bb6408c
JS
295 * Sit around forever waiting to process X-events. Property Change
296 * event are handled special, because they have to refer to
297 * the root window rather than to a widget. therefore we can't
298 * use an Xt-eventhandler.
299 */
afb74891 300
4bb6408c 301 XSelectInput(XtDisplay((Widget) wxTheApp->GetTopLevelWidget()),
2d120f83
JS
302 XDefaultRootWindow(XtDisplay((Widget) wxTheApp->GetTopLevelWidget())),
303 PropertyChangeMask);
afb74891 304
4bb6408c 305 XEvent event;
afb74891 306
4bb6408c
JS
307 // Use this flag to allow breaking the loop via wxApp::ExitMainLoop()
308 while (m_keepGoing)
309 {
2d120f83 310 XtAppNextEvent( (XtAppContext) wxTheApp->GetAppContext(), &event);
afb74891 311
2d120f83 312 ProcessXEvent((WXEvent*) & event);
afb74891 313
2d120f83
JS
314 if (XtAppPending( (XtAppContext) wxTheApp->GetAppContext() ) == 0)
315 {
316 if (!ProcessIdle())
afb74891 317 {
7bcb11d3 318#if wxUSE_THREADS
afb74891
VZ
319 // leave the main loop to give other threads a chance to
320 // perform their GUI work
2d120f83 321 wxMutexGuiLeave();
afb74891 322 wxUsleep(20);
2d120f83 323 wxMutexGuiEnter();
7bcb11d3 324#endif
2d120f83
JS
325 }
326 }
afb74891 327
8aa04e8b 328 }
afb74891 329
8aa04e8b
JS
330 return 0;
331}
332
333// Processes an X event.
334void wxApp::ProcessXEvent(WXEvent* _event)
335{
336 XEvent* event = (XEvent*) _event;
afb74891 337
ee31c392 338 if (event->type == KeyPress)
8aa04e8b 339 {
31528cd3
VZ
340#ifdef __WXDEBUG__
341 Widget widget = XtWindowToWidget(event->xany.display, event->xany.window);
342 wxLogDebug("Got key press event for 0x%08x (parent = 0x%08x)",
343 widget, XtParent(widget));
344#endif // DEBUG
345
3d9431bf
MB
346 if (CheckForAccelerator(_event))
347 {
348 // Do nothing! We intercepted and processed the event as an
349 // accelerator.
350 return;
351 }
a3736ef4 352#if 1
9779893b 353 // It seemed before that this hack was redundant and
a3736ef4
MB
354 // key down events were being generated by wxCanvasInputEvent.
355 // But no longer - why ???
356 //
3d9431bf
MB
357 else if (CheckForKeyDown(_event))
358 {
359 // We intercepted and processed the key down event
360 return;
361 }
9779893b 362#endif
3d9431bf
MB
363 else
364 {
365 XtDispatchEvent(event);
366 return;
367 }
368 }
369 else if (event->type == KeyRelease)
370 {
364c7f3c
MB
371 // TODO: work out why we still need this ! -michael
372 //
3d9431bf
MB
373 if (CheckForKeyUp(_event))
374 {
375 // We intercepted and processed the key up event
376 return;
377 }
378 else
379 {
380 XtDispatchEvent(event);
381 return;
382 }
8aa04e8b
JS
383 }
384 else if (event->type == PropertyNotify)
385 {
386 HandlePropertyChange(_event);
387 return;
388 }
389 else if (event->type == ResizeRequest)
390 {
ee31c392
VZ
391 /* Terry Gitnick <terryg@scientech.com> - 1/21/98
392 * If resize event, don't resize until the last resize event for this
393 * window is recieved. Prevents flicker as windows are resized.
394 */
afb74891 395
8aa04e8b
JS
396 Display *disp = XtDisplay((Widget) wxTheApp->GetTopLevelWidget());
397 Window win = event->xany.window;
398 XEvent report;
afb74891 399
8aa04e8b
JS
400 // to avoid flicker
401 report = * event;
402 while( XCheckTypedWindowEvent (disp, win, ResizeRequest, &report));
afb74891 403
f97c9854
JS
404 // TODO: when implementing refresh optimization, we can use
405 // XtAddExposureToRegion to expand the window's paint region.
afb74891 406
8aa04e8b
JS
407 XtDispatchEvent(event);
408 }
409 else
410 {
411 XtDispatchEvent(event);
4bb6408c 412 }
4bb6408c
JS
413}
414
415// Returns TRUE if more time is needed.
416bool wxApp::ProcessIdle()
417{
418 wxIdleEvent event;
419 event.SetEventObject(this);
420 ProcessEvent(event);
afb74891 421
4bb6408c
JS
422 return event.MoreRequested();
423}
424
425void wxApp::ExitMainLoop()
426{
427 m_keepGoing = FALSE;
428}
429
430// Is a message/event pending?
431bool wxApp::Pending()
432{
433 XFlush(XtDisplay( (Widget) wxTheApp->GetTopLevelWidget() ));
afb74891 434
8aa04e8b
JS
435 // Fix by Doug from STI, to prevent a stall if non-X event
436 // is found.
437 return ((XtAppPending( (XtAppContext) GetAppContext() ) & XtIMXEvent) != 0) ;
4bb6408c
JS
438}
439
440// Dispatch a message.
441void wxApp::Dispatch()
442{
2d120f83 443 // XtAppProcessEvent( (XtAppContext) wxTheApp->GetAppContext(), XtIMAll);
afb74891 444
8aa04e8b
JS
445 XEvent event;
446 XtAppNextEvent((XtAppContext) GetAppContext(), &event);
447 ProcessXEvent((WXEvent*) & event);
4bb6408c
JS
448}
449
450// This should be redefined in a derived class for
451// handling property change events for XAtom IPC.
452void wxApp::HandlePropertyChange(WXEvent *event)
453{
454 // by default do nothing special
455 XtDispatchEvent((XEvent*) event); /* let Motif do the work */
456}
457
458void wxApp::OnIdle(wxIdleEvent& event)
459{
460 static bool inOnIdle = FALSE;
afb74891 461
4bb6408c
JS
462 // Avoid recursion (via ProcessEvent default case)
463 if (inOnIdle)
2d120f83 464 return;
afb74891 465
4bb6408c 466 inOnIdle = TRUE;
afb74891 467
4bb6408c
JS
468 // 'Garbage' collection of windows deleted with Close().
469 DeletePendingObjects();
afb74891 470
7214297d
GL
471#if wxUSE_THREADS
472 // Flush pending events.
473 ProcessPendingEvents();
474#endif
475
4bb6408c
JS
476 // flush the logged messages if any
477 wxLog *pLog = wxLog::GetActiveTarget();
478 if ( pLog != NULL && pLog->HasPendingMessages() )
2d120f83 479 pLog->Flush();
afb74891 480
4bb6408c
JS
481 // Send OnIdle events to all windows
482 bool needMore = SendIdleEvents();
afb74891 483
4bb6408c 484 if (needMore)
2d120f83 485 event.RequestMore(TRUE);
afb74891 486
4bb6408c
JS
487 inOnIdle = FALSE;
488}
489
9779893b
RD
490void wxWakeUpIdle()
491{
492 // **** please implement me! ****
493 // Wake up the idle handler processor, even if it is in another thread...
494}
495
496
4bb6408c
JS
497// Send idle event to all top-level windows
498bool wxApp::SendIdleEvents()
499{
500 bool needMore = FALSE;
e146b8c8
VZ
501
502 wxWindowList::Node* node = wxTopLevelWindows.GetFirst();
2d120f83
JS
503 while (node)
504 {
e146b8c8 505 wxWindow* win = node->GetData();
2d120f83 506 if (SendIdleEvents(win))
4bb6408c 507 needMore = TRUE;
e146b8c8 508 node = node->GetNext();
2d120f83 509 }
e146b8c8 510
4bb6408c
JS
511 return needMore;
512}
513
514// Send idle event to window and all subwindows
515bool wxApp::SendIdleEvents(wxWindow* win)
516{
517 bool needMore = FALSE;
afb74891 518
2d120f83
JS
519 wxIdleEvent event;
520 event.SetEventObject(win);
521 win->ProcessEvent(event);
afb74891 522
4bb6408c
JS
523 if (event.MoreRequested())
524 needMore = TRUE;
afb74891 525
2d120f83
JS
526 wxNode* node = win->GetChildren().First();
527 while (node)
528 {
529 wxWindow* win = (wxWindow*) node->Data();
530 if (SendIdleEvents(win))
4bb6408c 531 needMore = TRUE;
afb74891 532
2d120f83
JS
533 node = node->Next();
534 }
4bb6408c
JS
535 return needMore ;
536}
537
538void wxApp::DeletePendingObjects()
539{
540 wxNode *node = wxPendingDelete.First();
541 while (node)
542 {
2d120f83 543 wxObject *obj = (wxObject *)node->Data();
afb74891 544
2d120f83 545 delete obj;
afb74891 546
2d120f83
JS
547 if (wxPendingDelete.Member(obj))
548 delete node;
afb74891 549
2d120f83
JS
550 // Deleting one object may have deleted other pending
551 // objects, so start from beginning of list again.
552 node = wxPendingDelete.First();
4bb6408c
JS
553 }
554}
555
4bb6408c
JS
556// Create an application context
557bool wxApp::OnInitGui()
558{
559 XtToolkitInitialize() ;
560 wxTheApp->m_appContext = (WXAppContext) XtCreateApplicationContext() ;
561 Display *dpy = XtOpenDisplay((XtAppContext) wxTheApp->m_appContext,(String)NULL,NULL,
9c6e1335 562 (const char*) wxTheApp->GetClassName(), NULL, 0,
4bb6408c 563# if XtSpecificationRelease < 5
9c6e1335 564 (Cardinal*) &argc,
4bb6408c 565# else
9c6e1335 566 &argc,
4bb6408c 567# endif
9c6e1335
VZ
568 argv);
569
4bb6408c 570 if (!dpy) {
7bcb11d3 571 wxString className(wxTheApp->GetClassName());
9c6e1335 572 wxLogError(_("wxWindows could not open display for '%s': exiting."),
7bcb11d3 573 (const char*) className);
2d120f83 574 exit(-1);
4bb6408c 575 }
47bc1060 576 m_initialDisplay = (WXDisplay*) dpy;
afb74891 577
4bb6408c 578 wxTheApp->m_topLevelWidget = (WXWidget) XtAppCreateShell((String)NULL, (const char*) wxTheApp->GetClassName(),
2d120f83
JS
579 applicationShellWidgetClass,dpy,
580 NULL,0) ;
afb74891 581
4bb6408c
JS
582 // Add general resize proc
583 XtActionsRec rec;
584 rec.string = "resize";
585 rec.proc = (XtActionProc)wxWidgetResizeProc;
586 XtAppAddActions((XtAppContext) wxTheApp->m_appContext, &rec, 1);
afb74891 587
4bb6408c
JS
588 GetMainColormap(dpy);
589 m_maxRequestSize = XMaxRequestSize((Display*) dpy);
afb74891 590
4bb6408c
JS
591 return TRUE;
592}
593
594WXColormap wxApp::GetMainColormap(WXDisplay* display)
595{
596 if (!display) /* Must be called first with non-NULL display */
2d120f83 597 return m_mainColormap;
a91b47e8
JS
598
599 int defaultScreen = DefaultScreen((Display*) display);
600 Screen* screen = XScreenOfDisplay((Display*) display, defaultScreen);
afb74891 601
a91b47e8 602 Colormap c = DefaultColormapOfScreen(screen);
afb74891 603
4bb6408c 604 if (!m_mainColormap)
2d120f83 605 m_mainColormap = (WXColormap) c;
afb74891 606
4bb6408c
JS
607 return (WXColormap) c;
608}
609
8aa04e8b
JS
610// Returns TRUE if an accelerator has been processed
611bool wxApp::CheckForAccelerator(WXEvent* event)
612{
613 XEvent* xEvent = (XEvent*) event;
614 if (xEvent->xany.type == KeyPress)
615 {
616 // Find a wxWindow for this window
617 // TODO: should get display for the window, not the current display
618 Widget widget = XtWindowToWidget((Display*) wxGetDisplay(), xEvent->xany.window);
619 wxWindow* win = NULL;
afb74891 620
8aa04e8b
JS
621 // Find the first wxWindow that corresponds to this event window
622 while (widget && !(win = wxGetWindowFromTable(widget)))
623 widget = XtParent(widget);
afb74891 624
8aa04e8b
JS
625 if (!widget || !win)
626 return FALSE;
afb74891 627
8aa04e8b
JS
628 wxKeyEvent keyEvent(wxEVT_CHAR);
629 wxTranslateKeyEvent(keyEvent, win, (Widget) 0, xEvent);
afb74891 630
8aa04e8b
JS
631 // Now we have a wxKeyEvent and we have a wxWindow.
632 // Go up the hierarchy until we find a matching accelerator,
633 // or we get to the top.
634 while (win)
635 {
636 if (win->ProcessAccelerator(keyEvent))
637 return TRUE;
638 win = win->GetParent();
639 }
640 return FALSE;
641 }
642 return FALSE;
643}
644
ee31c392
VZ
645bool wxApp::CheckForKeyDown(WXEvent* event)
646{
647 XEvent* xEvent = (XEvent*) event;
ee31c392
VZ
648 if (xEvent->xany.type == KeyPress)
649 {
3d9431bf
MB
650 Widget widget = XtWindowToWidget((Display*) wxGetDisplay(),
651 xEvent->xany.window);
652 wxWindow* win = NULL;
653
654 // Find the first wxWindow that corresponds to this event window
655 while (widget && !(win = wxGetWindowFromTable(widget)))
656 widget = XtParent(widget);
657
658 if (!widget || !win)
659 return FALSE;
660
661 wxKeyEvent keyEvent(wxEVT_KEY_DOWN);
662 wxTranslateKeyEvent(keyEvent, win, (Widget) 0, xEvent);
663
664 return win->ProcessEvent( keyEvent );
665 }
666
667 return FALSE;
668}
669
670bool wxApp::CheckForKeyUp(WXEvent* event)
671{
672 XEvent* xEvent = (XEvent*) event;
673 if (xEvent->xany.type == KeyRelease)
674 {
675 Widget widget = XtWindowToWidget((Display*) wxGetDisplay(),
676 xEvent->xany.window);
677 wxWindow* win = NULL;
ee31c392 678
3d9431bf
MB
679 // Find the first wxWindow that corresponds to this event window
680 while (widget && !(win = wxGetWindowFromTable(widget)))
681 widget = XtParent(widget);
ee31c392 682
3d9431bf
MB
683 if (!widget || !win)
684 return FALSE;
ee31c392 685
3d9431bf
MB
686 wxKeyEvent keyEvent(wxEVT_KEY_UP);
687 wxTranslateKeyEvent(keyEvent, win, (Widget) 0, xEvent);
ee31c392 688
3d9431bf 689 return win->ProcessEvent( keyEvent );
ee31c392 690 }
ee31c392
VZ
691
692 return FALSE;
693}
694
4bb6408c
JS
695void wxExit()
696{
697 int retValue = 0;
698 if (wxTheApp)
2d120f83 699 retValue = wxTheApp->OnExit();
afb74891 700
4bb6408c
JS
701 wxApp::CleanUp();
702 /*
2d120f83
JS
703 * Exit in some platform-specific way. Not recommended that the app calls this:
704 * only for emergencies.
705 */
4bb6408c
JS
706 exit(retValue);
707}
708
709// Yield to other processes
710bool wxYield()
711{
712 while (wxTheApp && wxTheApp->Pending())
2d120f83 713 wxTheApp->Dispatch();
518b5d2f
VZ
714
715 // VZ: is it the same as this (taken from old wxExecute)?
716#if 0
717 XtAppProcessEvent((XtAppContext) wxTheApp->GetAppContext(), XtIMAll);
718#endif
719
4bb6408c
JS
720 return TRUE;
721}
722
ee31c392
VZ
723// TODO use XmGetPixmap (?) to get the really standard icons!
724
725#include "wx/generic/info.xpm"
726#include "wx/generic/error.xpm"
727#include "wx/generic/question.xpm"
728#include "wx/generic/warning.xpm"
729
730wxIcon
731wxApp::GetStdIcon(int which) const
732{
733 switch(which)
734 {
735 case wxICON_INFORMATION:
736 return wxIcon(info_xpm);
737
738 case wxICON_QUESTION:
739 return wxIcon(question_xpm);
740
741 case wxICON_EXCLAMATION:
742 return wxIcon(warning_xpm);
743
744 default:
745 wxFAIL_MSG("requested non existent standard icon");
746 // still fall through
747
748 case wxICON_HAND:
749 return wxIcon(error_xpm);
750 }
751}
d391a345
VZ
752
753// ----------------------------------------------------------------------------
754// accessors for C modules
755// ----------------------------------------------------------------------------
756
757extern "C" XtAppContext wxGetAppContext()
758{
759 return (XtAppContext)wxTheApp->GetAppContext();
760}