X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2b5f62a0b2db198609b45dec622a018dae37008e..4dd2530846d0fcf214e3b288b04ce3aa932af048:/src/x11/utils.cpp diff --git a/src/x11/utils.cpp b/src/x11/utils.cpp index d0360712e4..80e3fcacda 100644 --- a/src/x11/utils.cpp +++ b/src/x11/utils.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: utils.cpp +// Name: src/x11/utils.cpp // Purpose: Various utilities // Author: Julian Smart // Modified by: @@ -9,6 +9,13 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// for compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#if defined(__BORLANDC__) + #pragma hdrstop +#endif + // ============================================================================ // declarations // ============================================================================ @@ -17,12 +24,16 @@ // headers // ---------------------------------------------------------------------------- -#include "wx/setup.h" #include "wx/utils.h" -#include "wx/app.h" -#include "wx/msgdlg.h" -#include "wx/cursor.h" -#include "wx/window.h" // for wxTopLevelWindows + +#ifndef WX_PRECOMP + #include "wx/app.h" + #include "wx/window.h" // for wxTopLevelWindows + #include "wx/cursor.h" + #include "wx/msgdlg.h" +#endif + +#include "wx/apptrait.h" #include #include @@ -66,77 +77,67 @@ void wxFlushEvents() XSync (display, FALSE); -#ifdef __WXMOTIF__ - // XtAppPending returns availability of events AND timers/inputs, which - // are processed via callbacks, so XtAppNextEvent will not return if - // there are no events. So added '& XtIMXEvent' - Sergey. - while (XtAppPending ((XtAppContext) wxTheApp->GetAppContext()) & XtIMXEvent) - { - XFlush (XtDisplay ((Widget) wxTheApp->GetTopLevelWidget())); - // Jan Lessner: works better when events are non-X events - XtAppProcessEvent((XtAppContext) wxTheApp->GetAppContext(), XtIMXEvent); - } -#endif -#ifdef __WXX11__ // TODO for X11 // ?? -#endif } bool wxCheckForInterrupt(wxWindow *wnd) { -#ifdef __WXMOTIF__ - wxCHECK_MSG( wnd, FALSE, "NULL window in wxCheckForInterrupt" ); - - Display *dpy=(Display*) wnd->GetXDisplay(); - Window win=(Window) wnd->GetXWindow(); - XEvent event; - XFlush(dpy); - if (wnd->GetMainWidget()) - { - XmUpdateDisplay((Widget)(wnd->GetMainWidget())); - } - - bool hadEvents = FALSE; - while( XCheckMaskEvent(dpy, - ButtonPressMask|ButtonReleaseMask|ButtonMotionMask| - PointerMotionMask|KeyPressMask|KeyReleaseMask, - &event) ) - { - if ( event.xany.window == win ) - { - hadEvents = TRUE; - - XtDispatchEvent(&event); - } - } - - return hadEvents; -#else - wxASSERT_MSG(FALSE, "wxCheckForInterrupt not yet implemented."); - return FALSE; -#endif + wxFAIL_MSG(wxT("wxCheckForInterrupt not yet implemented.")); + return false; } // ---------------------------------------------------------------------------- // wxExecute stuff // ---------------------------------------------------------------------------- +WX_DECLARE_HASH_MAP( int, wxEndProcessData*, wxIntegerHash, wxIntegerEqual, wxProcMap ); + +static wxProcMap *gs_procmap; + int wxAddProcessCallback(wxEndProcessData *proc_data, int fd) { -#ifdef __WXMOTIF__ - XtInputId id = XtAppAddInput((XtAppContext) wxTheApp->GetAppContext(), - fd, - (XtPointer *) XtInputReadMask, - (XtInputCallbackProc) xt_notify_end_process, - (XtPointer) proc_data); - - return (int)id; -#endif -#ifdef __WXX11__ - // TODO - return 0; -#endif + if (!gs_procmap) gs_procmap = new wxProcMap(); + (*gs_procmap)[fd] = proc_data; + return 1; +} + +void wxCheckForFinishedChildren() +{ + wxProcMap::iterator it; + if (!gs_procmap) return; + if (gs_procmap->size() == 0) { + // Map empty, delete it. + delete gs_procmap; + gs_procmap = NULL; + return; + } + for (it = gs_procmap->begin();it != gs_procmap->end(); ++it) + { + wxEndProcessData *proc_data = it->second; + int pid = (proc_data->pid > 0) ? proc_data->pid : -(proc_data->pid); + int status = 0; + // has the process really terminated? + int rc = waitpid(pid, &status, WNOHANG); + if (rc == 0) + continue; // no, it didn't exit yet, continue waiting + + // set exit code to -1 if something bad happened + proc_data->exitcode = rc != -1 && WIFEXITED(status) ? + WEXITSTATUS(status) : -1; + + // child exited, end waiting + close(it->first); + + // don't call us again! + gs_procmap->erase(it->first); + + wxHandleProcessTermination(proc_data); + + // Iterator is invalid. Handle any further children in subsequent + // calls. + break; + } } // ---------------------------------------------------------------------------- @@ -144,25 +145,31 @@ int wxAddProcessCallback(wxEndProcessData *proc_data, int fd) // ---------------------------------------------------------------------------- // Emit a beeeeeep +#ifndef __EMX__ +// on OS/2, we use the wxBell from wxBase library (src/os2/utils.cpp) void wxBell() { // Use current setting for the bell XBell ((Display*) wxGetDisplay(), 0); } +#endif -int wxGetOsVersion(int *majorVsn, int *minorVsn) +wxPortId wxGUIAppTraits::GetToolkitVersion(int *verMaj, int *verMin) const { -#ifdef __WXX11__ - if (majorVsn) - *majorVsn = 0; - - if (minorVsn) - *minorVsn = 0; - - return wxX11; -#endif + // get X protocol version + Display *display = wxGlobalDisplay(); + if (display) + { + if ( verMaj ) + *verMaj = ProtocolVersion (display); + if ( verMin ) + *verMin = ProtocolRevision (display); + } + + return wxPORT_X11; } + // ---------------------------------------------------------------------------- // display info // ---------------------------------------------------------------------------- @@ -187,7 +194,7 @@ void wxGetMousePosition( int* x, int* y ) #endif }; -// Return TRUE if we have a colour display +// Return true if we have a colour display bool wxColourDisplay() { return wxDisplayDepth() > 1; @@ -233,303 +240,78 @@ void wxClientDisplayRect(int *x, int *y, int *width, int *height) wxDisplaySize(width, height); } +wxWindow* wxFindWindowAtPoint(const wxPoint& pt) +{ + return wxGenericFindWindowAtPoint(pt); +} + // Configurable display in wxX11 and wxMotif -static WXDisplay *gs_currentDisplay = NULL; +static Display *gs_currentDisplay = NULL; static wxString gs_displayName; WXDisplay *wxGetDisplay() { - if (gs_currentDisplay) - return gs_currentDisplay; -#ifdef __WXMOTIF__ - if (wxTheApp && wxTheApp->GetTopLevelWidget()) - return XtDisplay ((Widget) wxTheApp->GetTopLevelWidget()); - else if (wxTheApp) - return wxTheApp->GetInitialDisplay(); - return NULL; -#endif -#ifdef __WXX11__ - return wxApp::GetDisplay(); -#endif + return (WXDisplay *)gs_currentDisplay; } -bool wxSetDisplay(const wxString& display_name) +// close the current display +void wxCloseDisplay() { - gs_displayName = display_name; - - if ( display_name.IsEmpty() ) + if ( gs_currentDisplay ) { - gs_currentDisplay = NULL; - - return TRUE; - } - else - { - Display* display = XOpenDisplay((char*) display_name.c_str()); - - if (display) + if ( XCloseDisplay(gs_currentDisplay) != 0 ) { - gs_currentDisplay = (WXDisplay*) display; - return TRUE; + wxLogWarning(_("Failed to close the display \"%s\""), + gs_displayName.c_str()); } - else - return FALSE; + + gs_currentDisplay = NULL; + gs_displayName.clear(); } } -wxString wxGetDisplayName() +bool wxSetDisplay(const wxString& displayName) { - return gs_displayName; -} + Display *dpy = XOpenDisplay + ( + displayName.empty() ? NULL + : (const char *)displayName.mb_str() + ); -wxWindow* wxFindWindowAtPoint(const wxPoint& pt) -{ - return wxGenericFindWindowAtPoint(pt); -} + if ( !dpy ) + { + wxLogError(_("Failed to open display \"%s\"."), displayName.c_str()); + return false; + } -// ---------------------------------------------------------------------------- -// keycode translations -// ---------------------------------------------------------------------------- + wxCloseDisplay(); -#include + gs_currentDisplay = dpy; + gs_displayName = displayName; -// FIXME what about tables?? + return true; +} -int wxCharCodeXToWX(KeySym keySym) +wxString wxGetDisplayName() { - int id; - switch (keySym) - { - case XK_Shift_L: - case XK_Shift_R: - id = WXK_SHIFT; break; - case XK_Control_L: - case XK_Control_R: - id = WXK_CONTROL; break; - case XK_BackSpace: - id = WXK_BACK; break; - case XK_Delete: - id = WXK_DELETE; break; - case XK_Clear: - id = WXK_CLEAR; break; - case XK_Tab: - id = WXK_TAB; break; - case XK_numbersign: - id = '#'; break; - case XK_Return: - id = WXK_RETURN; break; - case XK_Escape: - id = WXK_ESCAPE; break; - case XK_Pause: - case XK_Break: - id = WXK_PAUSE; break; - case XK_Num_Lock: - id = WXK_NUMLOCK; break; - case XK_Scroll_Lock: - id = WXK_SCROLL; break; - - case XK_Home: - id = WXK_HOME; break; - case XK_End: - id = WXK_END; break; - case XK_Left: - id = WXK_LEFT; break; - case XK_Right: - id = WXK_RIGHT; break; - case XK_Up: - id = WXK_UP; break; - case XK_Down: - id = WXK_DOWN; break; - case XK_Next: - id = WXK_NEXT; break; - case XK_Prior: - id = WXK_PRIOR; break; - case XK_Menu: - id = WXK_MENU; break; - case XK_Select: - id = WXK_SELECT; break; - case XK_Cancel: - id = WXK_CANCEL; break; - case XK_Print: - id = WXK_PRINT; break; - case XK_Execute: - id = WXK_EXECUTE; break; - case XK_Insert: - id = WXK_INSERT; break; - case XK_Help: - id = WXK_HELP; break; - - case XK_KP_Multiply: - id = WXK_MULTIPLY; break; - case XK_KP_Add: - id = WXK_ADD; break; - case XK_KP_Subtract: - id = WXK_SUBTRACT; break; - case XK_KP_Divide: - id = WXK_DIVIDE; break; - case XK_KP_Decimal: - id = WXK_DECIMAL; break; - case XK_KP_Equal: - id = '='; break; - case XK_KP_Space: - id = ' '; break; - case XK_KP_Tab: - id = WXK_TAB; break; - case XK_KP_Enter: - id = WXK_RETURN; break; - case XK_KP_0: - id = WXK_NUMPAD0; break; - case XK_KP_1: - id = WXK_NUMPAD1; break; - case XK_KP_2: - id = WXK_NUMPAD2; break; - case XK_KP_3: - id = WXK_NUMPAD3; break; - case XK_KP_4: - id = WXK_NUMPAD4; break; - case XK_KP_5: - id = WXK_NUMPAD5; break; - case XK_KP_6: - id = WXK_NUMPAD6; break; - case XK_KP_7: - id = WXK_NUMPAD7; break; - case XK_KP_8: - id = WXK_NUMPAD8; break; - case XK_KP_9: - id = WXK_NUMPAD9; break; - case XK_F1: - id = WXK_F1; break; - case XK_F2: - id = WXK_F2; break; - case XK_F3: - id = WXK_F3; break; - case XK_F4: - id = WXK_F4; break; - case XK_F5: - id = WXK_F5; break; - case XK_F6: - id = WXK_F6; break; - case XK_F7: - id = WXK_F7; break; - case XK_F8: - id = WXK_F8; break; - case XK_F9: - id = WXK_F9; break; - case XK_F10: - id = WXK_F10; break; - case XK_F11: - id = WXK_F11; break; - case XK_F12: - id = WXK_F12; break; - case XK_F13: - id = WXK_F13; break; - case XK_F14: - id = WXK_F14; break; - case XK_F15: - id = WXK_F15; break; - case XK_F16: - id = WXK_F16; break; - case XK_F17: - id = WXK_F17; break; - case XK_F18: - id = WXK_F18; break; - case XK_F19: - id = WXK_F19; break; - case XK_F20: - id = WXK_F20; break; - case XK_F21: - id = WXK_F21; break; - case XK_F22: - id = WXK_F22; break; - case XK_F23: - id = WXK_F23; break; - case XK_F24: - id = WXK_F24; break; - default: - id = (keySym <= 255) ? (int)keySym : -1; - } - - return id; + return gs_displayName; } -KeySym wxCharCodeWXToX(int id) +#include "wx/module.h" + +// the module responsible for closing the X11 display at the program end +class wxX11DisplayModule : public wxModule { - KeySym keySym; +public: + virtual bool OnInit() { return true; } + virtual void OnExit() { wxCloseDisplay(); } - switch (id) - { - case WXK_CANCEL: keySym = XK_Cancel; break; - case WXK_BACK: keySym = XK_BackSpace; break; - case WXK_TAB: keySym = XK_Tab; break; - case WXK_CLEAR: keySym = XK_Clear; break; - case WXK_RETURN: keySym = XK_Return; break; - case WXK_SHIFT: keySym = XK_Shift_L; break; - case WXK_CONTROL: keySym = XK_Control_L; break; - case WXK_MENU : keySym = XK_Menu; break; - case WXK_PAUSE: keySym = XK_Pause; break; - case WXK_ESCAPE: keySym = XK_Escape; break; - case WXK_SPACE: keySym = ' '; break; - case WXK_PRIOR: keySym = XK_Prior; break; - case WXK_NEXT : keySym = XK_Next; break; - case WXK_END: keySym = XK_End; break; - case WXK_HOME : keySym = XK_Home; break; - case WXK_LEFT : keySym = XK_Left; break; - case WXK_UP: keySym = XK_Up; break; - case WXK_RIGHT: keySym = XK_Right; break; - case WXK_DOWN : keySym = XK_Down; break; - case WXK_SELECT: keySym = XK_Select; break; - case WXK_PRINT: keySym = XK_Print; break; - case WXK_EXECUTE: keySym = XK_Execute; break; - case WXK_INSERT: keySym = XK_Insert; break; - case WXK_DELETE: keySym = XK_Delete; break; - case WXK_HELP : keySym = XK_Help; break; - case WXK_NUMPAD0: keySym = XK_KP_0; break; - case WXK_NUMPAD1: keySym = XK_KP_1; break; - case WXK_NUMPAD2: keySym = XK_KP_2; break; - case WXK_NUMPAD3: keySym = XK_KP_3; break; - case WXK_NUMPAD4: keySym = XK_KP_4; break; - case WXK_NUMPAD5: keySym = XK_KP_5; break; - case WXK_NUMPAD6: keySym = XK_KP_6; break; - case WXK_NUMPAD7: keySym = XK_KP_7; break; - case WXK_NUMPAD8: keySym = XK_KP_8; break; - case WXK_NUMPAD9: keySym = XK_KP_9; break; - case WXK_MULTIPLY: keySym = XK_KP_Multiply; break; - case WXK_ADD: keySym = XK_KP_Add; break; - case WXK_SUBTRACT: keySym = XK_KP_Subtract; break; - case WXK_DECIMAL: keySym = XK_KP_Decimal; break; - case WXK_DIVIDE: keySym = XK_KP_Divide; break; - case WXK_F1: keySym = XK_F1; break; - case WXK_F2: keySym = XK_F2; break; - case WXK_F3: keySym = XK_F3; break; - case WXK_F4: keySym = XK_F4; break; - case WXK_F5: keySym = XK_F5; break; - case WXK_F6: keySym = XK_F6; break; - case WXK_F7: keySym = XK_F7; break; - case WXK_F8: keySym = XK_F8; break; - case WXK_F9: keySym = XK_F9; break; - case WXK_F10: keySym = XK_F10; break; - case WXK_F11: keySym = XK_F11; break; - case WXK_F12: keySym = XK_F12; break; - case WXK_F13: keySym = XK_F13; break; - case WXK_F14: keySym = XK_F14; break; - case WXK_F15: keySym = XK_F15; break; - case WXK_F16: keySym = XK_F16; break; - case WXK_F17: keySym = XK_F17; break; - case WXK_F18: keySym = XK_F18; break; - case WXK_F19: keySym = XK_F19; break; - case WXK_F20: keySym = XK_F20; break; - case WXK_F21: keySym = XK_F21; break; - case WXK_F22: keySym = XK_F22; break; - case WXK_F23: keySym = XK_F23; break; - case WXK_F24: keySym = XK_F24; break; - case WXK_NUMLOCK: keySym = XK_Num_Lock; break; - case WXK_SCROLL: keySym = XK_Scroll_Lock; break; - default: keySym = id <= 255 ? (KeySym)id : 0; - } +private: + DECLARE_DYNAMIC_CLASS(wxX11DisplayModule) +}; - return keySym; -} +IMPLEMENT_DYNAMIC_CLASS(wxX11DisplayModule, wxModule) // ---------------------------------------------------------------------------- // Some colour manipulation routines @@ -654,22 +436,21 @@ wxString wxGetXEventName(XEvent& event) return str; #else int type = event.xany.type; - static char* event_name[] = { - "", "unknown(-)", // 0-1 - "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease", // 2-5 - "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", // 6-9 - "FocusOut", "KeymapNotify", "Expose", "GraphicsExpose", // 10-13 - "NoExpose", "VisibilityNotify", "CreateNotify", // 14-16 - "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest",// 17-20 - "ReparentNotify", "ConfigureNotify", "ConfigureRequest", // 21-23 - "GravityNotify", "ResizeRequest", "CirculateNotify", // 24-26 - "CirculateRequest", "PropertyNotify", "SelectionClear", // 27-29 - "SelectionRequest", "SelectionNotify", "ColormapNotify", // 30-32 - "ClientMessage", "MappingNotify", // 33-34 - "unknown(+)"}; // 35 - type = wxMin(35, type); type = wxMax(1, type); - wxString str(event_name[type]); - return str; + static char* event_name[] = { + "", "unknown(-)", // 0-1 + "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease", // 2-5 + "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", // 6-9 + "FocusOut", "KeymapNotify", "Expose", "GraphicsExpose", // 10-13 + "NoExpose", "VisibilityNotify", "CreateNotify", // 14-16 + "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest",// 17-20 + "ReparentNotify", "ConfigureNotify", "ConfigureRequest", // 21-23 + "GravityNotify", "ResizeRequest", "CirculateNotify", // 24-26 + "CirculateRequest", "PropertyNotify", "SelectionClear", // 27-29 + "SelectionRequest", "SelectionNotify", "ColormapNotify", // 30-32 + "ClientMessage", "MappingNotify", // 33-34 + "unknown(+)"}; // 35 + type = wxMin(35, type); type = wxMax(1, type); + return wxString::FromAscii(event_name[type]); #endif } #endif