wxDragResult wxDropSource::DoDragDrop(int WXUNUSED(flags)) { wxASSERT_MSG( m_data, wxT("Drop source: no data") ); if (!m_data) return (wxDragResult) wxDragNone; if (m_data->GetFormatCount() == 0) return (wxDragResult) wxDragNone; OSErr result; DragReference theDrag; RgnHandle dragRegion; if ((result = NewDrag(&theDrag))) { return wxDragNone ; } // add data to drag size_t formatCount = m_data->GetFormatCount() ; wxDataFormat *formats = new wxDataFormat[formatCount] ; m_data->GetAllFormats( formats ) ; ItemReference theItem = 1 ; for ( size_t i = 0 ; i < formatCount ; ++i ) { size_t dataSize = m_data->GetDataSize( formats[i] ) ; Ptr dataPtr = new char[dataSize] ; m_data->GetDataHere( formats[i] , dataPtr ) ; OSType type = formats[i].GetFormatId() ; if ( type == 'TEXT' ) { dataSize-- ; dataPtr[ dataSize ] = 0 ; wxString st( (wxChar*) dataPtr ) ; wxCharBuffer buf = st.mb_str( wxConvLocal) ; AddDragItemFlavor(theDrag, theItem, type , buf.data(), strlen(buf), 0); } else if (type == kDragFlavorTypeHFS ) { HFSFlavor theFlavor ; OSErr err = noErr; CInfoPBRec cat; wxMacFilename2FSSpec( dataPtr , &theFlavor.fileSpec ) ; cat.hFileInfo.ioNamePtr = theFlavor.fileSpec.name; cat.hFileInfo.ioVRefNum = theFlavor.fileSpec.vRefNum; cat.hFileInfo.ioDirID = theFlavor.fileSpec.parID; cat.hFileInfo.ioFDirIndex = 0; err = PBGetCatInfoSync(&cat); if (err == noErr ) { theFlavor.fdFlags = cat.hFileInfo.ioFlFndrInfo.fdFlags; if (theFlavor.fileSpec.parID == fsRtParID) { theFlavor.fileCreator = 'MACS'; theFlavor.fileType = 'disk'; } else if ((cat.hFileInfo.ioFlAttrib & ioDirMask) != 0) { theFlavor.fileCreator = 'MACS'; theFlavor.fileType = 'fold'; } else { theFlavor.fileCreator = cat.hFileInfo.ioFlFndrInfo.fdCreator; theFlavor.fileType = cat.hFileInfo.ioFlFndrInfo.fdType; } AddDragItemFlavor(theDrag, theItem, type , &theFlavor, sizeof(theFlavor), 0); } } else { AddDragItemFlavor(theDrag, theItem, type , dataPtr, dataSize, 0); } delete[] dataPtr ; } delete[] formats ; dragRegion = NewRgn(); RgnHandle tempRgn = NewRgn() ; EventRecord* ev = NULL ; #if !TARGET_CARBON // TODO ev = (EventRecord*) wxTheApp->MacGetCurrentEvent() ; #else EventRecord rec ; ev = &rec ; wxMacConvertEventToRecord( (EventRef) wxTheApp->MacGetCurrentEvent() , &rec ) ; #endif const short dragRegionOuterBoundary = 10 ; const short dragRegionInnerBoundary = 9 ; SetRectRgn( dragRegion , ev->where.h - dragRegionOuterBoundary , ev->where.v - dragRegionOuterBoundary , ev->where.h + dragRegionOuterBoundary , ev->where.v + dragRegionOuterBoundary ) ; SetRectRgn( tempRgn , ev->where.h - dragRegionInnerBoundary , ev->where.v - dragRegionInnerBoundary , ev->where.h + dragRegionInnerBoundary , ev->where.v + dragRegionInnerBoundary ) ; DiffRgn( dragRegion , tempRgn , dragRegion ) ; DisposeRgn( tempRgn ) ; // TODO:work with promises in order to return data only when drag // was successfully completed gTrackingGlobals.m_currentSource = this ; result = TrackDrag(theDrag, ev , dragRegion); DisposeRgn(dragRegion); DisposeDrag(theDrag); gTrackingGlobals.m_currentSource = NULL ; KeyMap keymap; GetKeys(keymap); bool optionDown = keymap[1] & 4; wxDragResult dndresult = optionDown ? wxDragCopy : wxDragMove; return dndresult; }
// ---------------------------------------------------------------------------- void clKeyboardManager::Initialize(bool isRefreshRequest) // ---------------------------------------------------------------------------- { wxUnusedVar(isRefreshRequest); m_menuTable.clear(); // First, try to load accelerators from %appdata% keybindings.conf // containing merged default + user defined accerators // Second, try loading from default accerators in %appdata% + accerators.conf clKeyboardBindingConfig config; if( not config.Exists()) //does keybindings.conf exist? { #if defined(LOGGING) LOGIT( _T("[%s]"), _("Keyboard manager: No configuration found - importing old settings")); #endif //CL_DEBUG("Keyboard manager: No configuration found - importing old settings"); // Decide which file we want to load, take the user settings file first // GetUserDataDir() == "c:\Users\<username>\AppData\Roaming\<appname>\config\keybindings.conf" // GetDataDir() == executable directory // Old accererator setting are in %appdata% wxFileName fnOldSettings(wxStandardPaths::Get().GetTempDir(), _T("keyMnuAccels.conf")); wxString personality = Manager::Get()->GetPersonalityManager()->GetPersonality(); fnOldSettings.SetName(personality + _T(".") + fnOldSettings.GetName()); wxFileName fnFileToLoad; bool canDeleteOldSettings(false); // If %appdata% accerators.conf exist, use it if(fnOldSettings.FileExists()) { fnFileToLoad = fnOldSettings; //-canDeleteOldSettings = true; } else // else use executable dir accerators.conf.default accerators { //-fnFileToLoad = fnDefaultOldSettings; wxASSERT_MSG(0, _("clKeyboardManager::Initialize() missing accerators.conf file")); } if(fnFileToLoad.FileExists()) { #if defined(LOGGING) LOGIT( _T("KeyboardManager:Importing settings from:\n\t[%s]"), fnFileToLoad.GetFullPath().wx_str()); #endif // Apply the old settings to the menus wxString content; if(not ReadFileContent(fnFileToLoad, content)) return; wxArrayString lines = ::wxStringTokenize(content, _T("\r\n"), wxTOKEN_STRTOK); for(size_t i = 0; i < lines.GetCount(); ++i) { #if defined(LOGGING) #if wxVERSION_NUMBER > 3000 LOGIT( _T("AccelFile[%u:%s]"), (unsigned)i, lines.Item(i).wx_str() ); #else LOGIT( _T("AccelFile[%u:%s]"), i, lines.Item(i).wx_str() ); #endif #endif wxArrayString parts = ::wxStringTokenize(lines.Item(i), _T("|"), wxTOKEN_RET_EMPTY); if(parts.GetCount() < 3) continue; MenuItemData binding; binding.resourceID = parts.Item(0); binding.parentMenu = parts.Item(1); binding.action = parts.Item(2); if(parts.GetCount() == 4) { binding.accel = parts.Item(3); } m_menuTable.insert(std::make_pair(binding.resourceID, binding)); } if(canDeleteOldSettings) { if (fnFileToLoad.FileExists()) ::wxRemoveFile(fnFileToLoad.GetFullPath()); } } } else //config exists: "keybindings.conf" { config.Load(); m_menuTable = config.GetBindings(); } // Load the default settings and add any new entries from accerators.conf MenuItemDataMap_t defaultEntries = DoLoadDefaultAccelerators(); // Remove any map items nolonger matching the menu structure for (MenuItemDataMap_t::iterator mapIter = m_menuTable.begin(); mapIter != m_menuTable.end(); ++mapIter) { mnuContinue: if (mapIter == m_menuTable.end()) break; //search menu structure map for map menuId if ( defaultEntries.count(mapIter->first) == 0) { // menuID nolonger exists #if defined(LOGGING) wxString mapAccel = mapIter->second.accel; wxString mapParent = mapIter->second.parentMenu; wxString mapMnuID = mapIter->first; LOGIT( _T("Removing ID mismatch[%s][%s][%s]"), mapMnuID.wx_str(), mapParent.wx_str(), mapAccel.wx_str()); #endif mapIter = m_menuTable.erase(mapIter); goto mnuContinue; } else //remove the found map item if its label doesn't match menu structure label//(pecan 2019/05/18) { // Have matching map resoureID and menu structure resourceID (ie., menuItemID) MenuItemDataMap_t::iterator mnuIter = defaultEntries.find(mapIter->first); if (mnuIter == defaultEntries.end()) continue; wxString mapParent = mapIter->second.parentMenu; if (mapParent.empty()) continue; //skip global accelerators wxString mnuParent = mnuIter->second.parentMenu; if (mnuParent.empty()) continue; //skip global accelerators if (mapParent.Lower() != mnuParent.Lower()) { #if defined(LOGGING) wxString mapMnuID = mapIter->first; wxString mapAccel = mapIter->second.accel; LOGIT( _T("Removing LabelMismatch[%s][%s][%s]"), mapMnuID.wx_str(), mapParent.wx_str(), mapAccel.wx_str()); #endif mapIter = m_menuTable.erase(mapIter); goto mnuContinue; }//endif label compare }//endif else have matching resourceID }//endfor mapIter // Add any new entries from accerators.conf (the menu structure) std::for_each(defaultEntries.begin(), defaultEntries.end(), [&](const MenuItemDataMap_t::value_type& vdflt) { //-wxString vtValue = vdflt.first; //The menu id number if(m_menuTable.count(vdflt.first) == 0) { //searches map for like shortcut string m_menuTable.insert(vdflt); } // ---------------------------------------------------------------------------- // NO!no! don't overwrite past user changes; m_menuTable already has user keybinder.conf changes. // while defaultEntries have original CodeBlocks menu accelerators // User must make (or made) m_menuTable changes via KeyBinder configuration dialog. // ---------------------------------------------------------------------------- //-else //verify keyboard shortcut //-{ //- MenuItemDataMap_t::iterator mapIter = m_menuTable.find(vdflt.first); //- if (mapIter != m_menuTable.end()) //should never be true! //- if (mapIter->second.accel != vdflt.second.accel) //- { //- #if defined(LOGGING) //- wxString mapMenuItem = mapIter->second.parentMenu + mapIter->second.accel; //- wxString vdfltMenuItem = vdflt.second.parentMenu +vdflt.second.accel; //- LOGIT( _T("Initialize changing accel[%s]to[%s]"), mapMenuItem.wx_str(), vdfltMenuItem.wx_str()); //- #endif //- mapIter->second.accel = vdflt.second.accel; //- } //-} }); // Warn about duplicate shortcut entries (eg., (Print/PrevCallTip Ctrl-P) and (CC Search/Ctrl-Shift-.) have duplicates) //(2019/04/23) CheckForDuplicateAccels(m_menuTable); // Store the correct configuration; globalTable is inserted into menuTable config.SetBindings(m_menuTable, m_globalTable).Save(); // And apply the changes Update(); }
void wxPopupWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags ) { wxASSERT_MSG( (m_widget != NULL), wxT("invalid dialog") ); wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid dialog") ); if (m_resizing) return; /* I don't like recursions */ m_resizing = true; int old_x = m_x; int old_y = m_y; int old_width = m_width; int old_height = m_height; if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0) { if (x != -1) m_x = x; if (y != -1) m_y = y; if (width != -1) m_width = width; if (height != -1) m_height = height; } else { m_x = x; m_y = y; m_width = width; m_height = height; } /* if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH) { if (width == -1) m_width = 80; } if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT) { if (height == -1) m_height = 26; } */ int minWidth = GetMinWidth(), minHeight = GetMinHeight(), maxWidth = GetMaxWidth(), maxHeight = GetMaxHeight(); if ((minWidth != -1) && (m_width < minWidth)) m_width = minWidth; if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight; if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth; if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight; if ((m_x != -1) || (m_y != -1)) { if ((m_x != old_x) || (m_y != old_y)) { /* we set the position here and when showing the dialog for the first time in idle time */ gtk_widget_set_uposition( m_widget, m_x, m_y ); } } if ((m_width != old_width) || (m_height != old_height)) { gtk_widget_set_usize( m_widget, m_width, m_height ); /* actual resizing is deferred to GtkOnSize in idle time and when showing the dialog */ m_sizeSet = false; } m_resizing = false; }
void wxTaskBarJumpListImpl::LoadKnownCategory(const wxString& title) { IApplicationDocumentLists *docList = 0; HRESULT hr = CoCreateInstance ( wxCLSID_ApplicationDocumentLists, NULL, CLSCTX_INPROC_SERVER, wxIID_IApplicationDocumentLists, reinterpret_cast<void **>(&docList) ); if ( FAILED(hr) ) { wxLogApiError("CoCreateInstance(wxCLSID_ApplicationDocumentLists)", hr); return; } if ( !m_appID.empty() ) docList->SetAppID(m_appID.wc_str()); IObjectArray *array = NULL; wxASSERT_MSG( title == "Recent" || title == "Frequent", "Invalid title." ); hr = docList->GetList ( title == "Recent" ? ADLT_RECENT : ADLT_FREQUENT, 0, wxIID_IObjectArray, reinterpret_cast<void **>(&array) ); if ( FAILED(hr) ) { wxLogApiError("IApplicationDocumentLists::GetList", hr); return; } UINT count = 0; array->GetCount(&count); for (UINT i = 0; i < count; ++i) { IUnknown *collectionItem = NULL; hr = array->GetAt(i, wxIID_IUnknown, reinterpret_cast<void **>(&collectionItem)); if ( FAILED(hr) ) { wxLogApiError("IObjectArray::GetAt", hr); continue; } IShellLink *shellLink = NULL; IShellItem *shellItem = NULL; wxTaskBarJumpListItem* item = NULL; if ( SUCCEEDED(collectionItem->QueryInterface( wxIID_IShellLink, reinterpret_cast<void**>(&shellLink))) ) { item = GetItemFromIShellLink(shellLink); shellLink->Release(); } else if ( SUCCEEDED(collectionItem->QueryInterface( wxIID_IShellItem, reinterpret_cast<void**>(&shellItem))) ) { item = GetItemFromIShellItem(shellItem); shellItem->Release(); } else { wxLogError("Can not query interfaces: IShellLink or IShellItem."); } if ( item ) { if ( title == wxT("Frequent") ) m_frequent->Append(item); else m_recent->Append(item); } collectionItem->Release(); } array->Release(); docList->Release(); }
void Envelope::GetValues(double *buffer, int bufferLen, double t0, double tstep) const { t0 -= mOffset; int len = mEnv.Count(); double t = t0; double tprev, vprev, tnext = 0, vnext, vstep = 0; // in debug builds, do a spot of argument checking if(t0 > mTrackLen) { wxString msg; msg = wxString::Format(wxT("t0 %.20f mTrackLen %.20f diff %.20f"), t0, mTrackLen, t0-mTrackLen); wxASSERT_MSG(t0 <= mTrackLen, msg); } if(t0 < 0) { wxString msg; msg = wxString::Format(wxT("t0 %.20f"), t0); wxASSERT_MSG(t0 >= 0, msg); } for (int b = 0; b < bufferLen; b++) { if (len <= 0) { buffer[b] = mDefaultValue; t += tstep; continue; } if (t <= mEnv[0]->t) { buffer[b] = mEnv[0]->val; t += tstep; continue; } if (t >= mEnv[len - 1]->t) { buffer[b] = mEnv[len - 1]->val; t += tstep; continue; } if (b == 0 || t > tnext) { // binary search int lo = 0; int hi = len - 1; while (hi > (lo + 1)) { int mid = (lo + hi) / 2; if (t < mEnv[mid]->t) hi = mid; else lo = mid; } tprev = mEnv[lo]->t; tnext = mEnv[hi]->t; if (mDB) { vprev = log10(mEnv[lo]->val); vnext = log10(mEnv[hi]->val); // Special case for the log of zero if (mEnv[lo]->val <= 0.0) vprev = -7; // This corresponds to -140 dB if (mEnv[hi]->val <= 0.0) vnext = -7; } else { vprev = mEnv[lo]->val; vnext = mEnv[hi]->val; } // Interpolate double dt = (tnext - tprev); double to = t - tprev; double v; if (dt > 0.0) v = (vprev * (dt - to) + vnext * to) / dt; else v = vnext; if (mDB) { buffer[b] = pow(10.0, v); if (dt > 0.0) vstep = pow(10.0, (vnext - vprev) * tstep / dt); else vstep = 1.0; } else { buffer[b] = v; if (dt > 0.0) vstep = (vnext - vprev) * tstep / dt; else vstep = 0.0; } } else { if (mDB) { buffer[b] = buffer[b - 1] * vstep; } else { buffer[b] = buffer[b - 1] + vstep; } } t += tstep; } }
// Begin drag bool wxDragImage::BeginDrag(const wxPoint& hotspot, wxWindow* window, bool fullScreen, wxRect* rect) { wxASSERT_MSG( (m_hImageList != 0), wxT("Image list must not be null in BeginDrag.")); wxASSERT_MSG( (window != 0), wxT("Window must not be null in BeginDrag.")); m_fullScreen = fullScreen; if (rect) m_boundingRect = * rect; bool ret = (ImageList_BeginDrag(GetHimageList(), 0, hotspot.x, hotspot.y) != 0); if (!ret) { wxFAIL_MSG( wxT("BeginDrag failed.") ); return false; } if (m_cursor.IsOk()) { #if wxUSE_SIMPLER_DRAGIMAGE m_oldCursor = window->GetCursor(); window->SetCursor(m_cursor); #else if (!m_hCursorImageList) { #ifndef SM_CXCURSOR // Smartphone may not have these metric symbol int cxCursor = 16; int cyCursor = 16; #else int cxCursor = ::GetSystemMetrics(SM_CXCURSOR); int cyCursor = ::GetSystemMetrics(SM_CYCURSOR); #endif m_hCursorImageList = (WXHIMAGELIST) ImageList_Create(cxCursor, cyCursor, ILC_MASK, 1, 1); } // See if we can find the cursor hotspot wxPoint curHotSpot(hotspot); // Although it seems to produce the right position, when the hotspot goeos // negative it has strange effects on the image. // How do we stop the cursor jumping right and below of where it should be? #if 0 ICONINFO iconInfo; if (::GetIconInfo((HICON) (HCURSOR) m_cursor.GetHCURSOR(), & iconInfo) != 0) { curHotSpot.x -= iconInfo.xHotspot; curHotSpot.y -= iconInfo.yHotspot; } #endif //wxString msg; //msg.Printf("Hotspot = %d, %d", curHotSpot.x, curHotSpot.y); //wxLogDebug(msg); // First add the cursor to the image list HCURSOR hCursor = (HCURSOR) m_cursor.GetHCURSOR(); int cursorIndex = ImageList_AddIcon((HIMAGELIST) m_hCursorImageList, (HICON) hCursor); wxASSERT_MSG( (cursorIndex != -1), wxT("ImageList_AddIcon failed in BeginDrag.")); if (cursorIndex != -1) { ImageList_SetDragCursorImage((HIMAGELIST) m_hCursorImageList, cursorIndex, curHotSpot.x, curHotSpot.y); } #endif } #if !wxUSE_SIMPLER_DRAGIMAGE if (m_cursor.IsOk()) ::ShowCursor(FALSE); #endif m_window = window; ::SetCapture(GetHwndOf(window)); return true; }
wxTaskBarJumpListItem* wxTaskBarJumpListCategory::FindItemByPosition(size_t pos) const { wxASSERT_MSG( pos < m_items.size(), "invalid pos." ); return m_items[pos]; }
bool wxGLCanvasX11::ConvertWXAttrsToGL(const int *wxattrs, int *glattrs, size_t n) { wxCHECK_MSG( n >= 16, false, _T("GL attributes buffer too small") ); /* Different versions of GLX API use rather different attributes lists, see the following URLs: - <= 1.2: http://www.opengl.org/sdk/docs/man/xhtml/glXChooseVisual.xml - >= 1.3: http://www.opengl.org/sdk/docs/man/xhtml/glXChooseFBConfig.xml Notice in particular that - GLX_RGBA is boolean attribute in the old version of the API but a value of GLX_RENDER_TYPE in the new one - Boolean attributes such as GLX_DOUBLEBUFFER don't take values in the old version but must be followed by True or False in the new one. */ if ( !wxattrs ) { size_t i = 0; // use double-buffered true colour by default glattrs[i++] = GLX_DOUBLEBUFFER; if ( GetGLXVersion() < 13 ) { // default settings if attriblist = 0 glattrs[i++] = GLX_RGBA; glattrs[i++] = GLX_DEPTH_SIZE; glattrs[i++] = 1; glattrs[i++] = GLX_RED_SIZE; glattrs[i++] = 1; glattrs[i++] = GLX_GREEN_SIZE; glattrs[i++] = 1; glattrs[i++] = GLX_BLUE_SIZE; glattrs[i++] = 1; glattrs[i++] = GLX_ALPHA_SIZE; glattrs[i++] = 0; } else // recent GLX can choose the defaults on its own just fine { // we just need to have a value after GLX_DOUBLEBUFFER glattrs[i++] = True; } glattrs[i] = None; wxASSERT_MSG( i < n, _T("GL attributes buffer too small") ); } else // have non-default attributes { size_t p = 0; for ( int arg = 0; wxattrs[arg] != 0; ) { // check if we have any space left, knowing that we may insert 2 // more elements during this loop iteration and we always need to // terminate the list with None (hence -3) if ( p > n - 3 ) return false; // indicates whether we have a boolean attribute bool isBoolAttr = false; switch ( wxattrs[arg++] ) { case WX_GL_BUFFER_SIZE: glattrs[p++] = GLX_BUFFER_SIZE; break; case WX_GL_LEVEL: glattrs[p++] = GLX_LEVEL; break; case WX_GL_RGBA: if ( GetGLXVersion() >= 13 ) { // this is the default GLX_RENDER_TYPE anyhow continue; } glattrs[p++] = GLX_RGBA; isBoolAttr = true; break; case WX_GL_DOUBLEBUFFER: glattrs[p++] = GLX_DOUBLEBUFFER; isBoolAttr = true; break; case WX_GL_STEREO: glattrs[p++] = GLX_STEREO; isBoolAttr = true; break; case WX_GL_AUX_BUFFERS: glattrs[p++] = GLX_AUX_BUFFERS; break; case WX_GL_MIN_RED: glattrs[p++] = GLX_RED_SIZE; break; case WX_GL_MIN_GREEN: glattrs[p++] = GLX_GREEN_SIZE; break; case WX_GL_MIN_BLUE: glattrs[p++] = GLX_BLUE_SIZE; break; case WX_GL_MIN_ALPHA: glattrs[p++] = GLX_ALPHA_SIZE; break; case WX_GL_DEPTH_SIZE: glattrs[p++] = GLX_DEPTH_SIZE; break; case WX_GL_STENCIL_SIZE: glattrs[p++] = GLX_STENCIL_SIZE; break; case WX_GL_MIN_ACCUM_RED: glattrs[p++] = GLX_ACCUM_RED_SIZE; break; case WX_GL_MIN_ACCUM_GREEN: glattrs[p++] = GLX_ACCUM_GREEN_SIZE; break; case WX_GL_MIN_ACCUM_BLUE: glattrs[p++] = GLX_ACCUM_BLUE_SIZE; break; case WX_GL_MIN_ACCUM_ALPHA: glattrs[p++] = GLX_ACCUM_ALPHA_SIZE; break; case WX_GL_SAMPLE_BUFFERS: if ( !IsGLXMultiSampleAvailable() ) { // if it was specified just to disable it, no problem if ( !wxattrs[arg++] ) continue; // otherwise indicate that it's not supported return false; } glattrs[p++] = GLX_SAMPLE_BUFFERS_ARB; break; case WX_GL_SAMPLES: if ( !IsGLXMultiSampleAvailable() ) { if ( !wxattrs[arg++] ) continue; return false; } glattrs[p++] = GLX_SAMPLES_ARB; break; default: wxLogDebug(_T("Unsupported OpenGL attribute %d"), wxattrs[arg - 1]); continue; } if ( isBoolAttr ) { // as explained above, for pre 1.3 API the attribute just needs // to be present so we only add its value when using the new API if ( GetGLXVersion() >= 13 ) glattrs[p++] = True; } else // attribute with real (non-boolean) value { // copy attribute value as is glattrs[p++] = wxattrs[arg++]; } } glattrs[p] = None; } return true; }
PrefsDialog::PrefsDialog(wxWindow * parent) : wxDialog(parent, wxID_ANY, wxString(_("Audacity Preferences")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { ShuttleGui S(this, eIsCreating); S.StartVerticalLay(true); { S.StartHorizontalLay(wxALIGN_LEFT | wxEXPAND, true); { mCategories = new wxTreebook(this, wxID_ANY); S.Prop(1); S.AddWindow(mCategories, wxEXPAND); wxWindow *w; // Parameters are: AppPage( page, name, IsSelected, imageId) w = new DevicePrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); w = new PlaybackPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); w = new RecordingPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); #ifdef EXPERIMENTAL_MIDI_OUT w = new MidiIOPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); #endif w = new QualityPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); w = new GUIPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); w = new TracksPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); w = new ImportExportPrefs(mCategories);mCategories->AddPage(w, w->GetName(), false, 0); w = new ProjectsPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); w = new LibraryPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); w = new SpectrumPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); w = new DirectoriesPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); w = new WarningsPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); w = new EffectsPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); #ifdef EXPERIMENTAL_THEME_PREFS w = new ThemePrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); #endif // w = new BatchPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); w = new KeyConfigPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); w = new MousePrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); } S.EndHorizontalLay(); } S.EndVerticalLay(); S.AddStandardButtons(eOkButton | eCancelButton); size_t selected = gPrefs->Read(wxT("/Prefs/PrefsCategory"), 0L); if (selected < 0 || selected >= mCategories->GetPageCount()) { selected = 0; } mCategories->SetSelection(selected); #if defined(__WXGTK__) mCategories->GetTreeCtrl()->EnsureVisible(mCategories->GetTreeCtrl()->GetRootItem()); #endif // mCategories->SetSizeHints(-1, -1, 790, 600); // 790 = 800 - (border * 2) Layout(); Fit(); wxSize sz = GetSize(); wxASSERT_MSG(sz.x <= 800 && sz.y <= 600, wxT("Preferences dialog exceeds max size")); if (sz.x > 800) { sz.x = 800; } if (sz.y > 600) { sz.y = 600; } SetSizeHints(sz.x, sz.y, 800, 600); // Center after all that resizing, but make sure it doesn't end up // off-screen CentreOnParent(); }
void ClangWorkerThread::ProcessRequest(ThreadRequest* request) { // Send start event PostEvent(wxEVT_CLANG_PCH_CACHE_STARTED, ""); ClangThreadRequest* task = dynamic_cast<ClangThreadRequest*>(request); wxASSERT_MSG(task, "ClangWorkerThread: NULL task"); { // A bit of optimization wxCriticalSectionLocker locker(m_criticalSection); if(task->GetContext() == CTX_CachePCH && m_cache.Contains(task->GetFileName())) { // Nothing to be done here PostEvent(wxEVT_CLANG_PCH_CACHE_ENDED, task->GetFileName()); return; } } CL_DEBUG(wxT("==========> [ ClangPchMakerThread ] ProcessRequest started: %s"), task->GetFileName().c_str()); CL_DEBUG(wxT("ClangWorkerThread:: processing request %d"), (int)task->GetContext()); ClangCacheEntry cacheEntry = findEntry(task->GetFileName()); CXTranslationUnit TU = cacheEntry.TU; CL_DEBUG(wxT("ClangWorkerThread:: found cached TU: %p"), (void*)TU); bool reparseRequired = true; if(!TU) { // First time creating the TU TU = DoCreateTU(task->GetIndex(), task, true); reparseRequired = false; cacheEntry.lastReparse = time(NULL); cacheEntry.TU = TU; cacheEntry.sourceFile = task->GetFileName(); } if(!TU) { CL_DEBUG(wxT("Failed to parse Translation UNIT...")); PostEvent(wxEVT_CLANG_TU_CREATE_ERROR, task->GetFileName()); return; } if(reparseRequired && task->GetContext() == ::CTX_ReparseTU) { DoSetStatusMsg(wxString::Format(wxT("clang: re-parsing file %s..."), task->GetFileName().c_str())); // We need to reparse the TU CL_DEBUG(wxT("Calling clang_reparseTranslationUnit... [CTX_ReparseTU]")); if(clang_reparseTranslationUnit(TU, 0, NULL, clang_defaultReparseOptions(TU)) == 0) { CL_DEBUG(wxT("Calling clang_reparseTranslationUnit... done [CTX_ReparseTU]")); cacheEntry.lastReparse = time(NULL); } else { CL_DEBUG(wxT("An error occurred during reparsing of the TU for file %s. TU: %p"), task->GetFileName().c_str(), (void*)TU); // The only thing that left to be done here, is to dispose the TU clang_disposeTranslationUnit(TU); PostEvent(wxEVT_CLANG_TU_CREATE_ERROR, task->GetFileName()); return; } } // Construct a cache-returner class // which makes sure that the TU is cached // when we leave the current scope CacheReturner cr(this, cacheEntry); // Prepare the 'End' event wxCommandEvent eEnd(wxEVT_CLANG_PCH_CACHE_ENDED); ClangThreadReply* reply = new ClangThreadReply; reply->context = task->GetContext(); reply->filterWord = task->GetFilterWord(); reply->filename = task->GetFileName().c_str(); reply->results = NULL; wxFileName realFileName(reply->filename); if(realFileName.GetFullName().StartsWith(CODELITE_CLANG_FILE_PREFIX)) { realFileName.SetFullName(realFileName.GetFullName().Mid(strlen(CODELITE_CLANG_FILE_PREFIX))); } reply->filename = realFileName.GetFullPath(); if(task->GetContext() == CTX_CodeCompletion || task->GetContext() == CTX_WordCompletion || task->GetContext() == CTX_Calltip) { CL_DEBUG(wxT("Calling clang_codeCompleteAt...")); ClangThreadRequest::List_t usList = task->GetModifiedBuffers(); usList.push_back(std::make_pair(task->GetFileName(), task->GetDirtyBuffer())); ClangUnsavedFiles usf(usList); CL_DEBUG(wxT("Location: %s:%u:%u"), task->GetFileName().c_str(), task->GetLine(), task->GetColumn()); reply->results = clang_codeCompleteAt(TU, cstr(task->GetFileName()), task->GetLine(), task->GetColumn(), usf.GetUnsavedFiles(), usf.GetCount(), clang_defaultCodeCompleteOptions() #if HAS_LIBCLANG_BRIEFCOMMENTS | CXCodeComplete_IncludeBriefComments #endif ); cacheEntry.lastReparse = time(NULL); CL_DEBUG(wxT("Calling clang_codeCompleteAt... done")); wxString displayTip; bool hasErrors(false); if(reply->results) { unsigned maxErrorToDisplay = 10; std::set<wxString> errorMessages; unsigned errorCount = clang_codeCompleteGetNumDiagnostics(reply->results); // Collect all errors / fatal errors and report them back to user for(unsigned i = 0; i < errorCount; i++) { CXDiagnostic diag = clang_codeCompleteGetDiagnostic(reply->results, i); CXDiagnosticSeverity severity = clang_getDiagnosticSeverity(diag); if(!hasErrors) { hasErrors = (severity == CXDiagnostic_Error || severity == CXDiagnostic_Fatal); } if(severity == CXDiagnostic_Error || severity == CXDiagnostic_Fatal || severity == CXDiagnostic_Note) { CXString diagStr = clang_getDiagnosticSpelling(diag); wxString wxDiagString = wxString(clang_getCString(diagStr), wxConvUTF8); // Collect up to 10 error messages // and dont collect the same error twice if(errorMessages.find(wxDiagString) == errorMessages.end() && errorMessages.size() <= maxErrorToDisplay) { errorMessages.insert(wxDiagString); displayTip << wxDiagString.c_str() << wxT("\n"); } clang_disposeString(diagStr); } clang_disposeDiagnostic(diag); } CL_DEBUG(wxT("Found %u matches"), reply->results->NumResults); ClangUtils::printCompletionDiagnostics(reply->results); } if(!displayTip.IsEmpty() && hasErrors) { // Send back the error messages reply->errorMessage << "clang: " << displayTip; reply->errorMessage.RemoveLast(); // Free the results clang_disposeCodeCompleteResults(reply->results); reply->results = NULL; } // Send the event eEnd.SetClientData(reply); EventNotifier::Get()->AddPendingEvent(eEnd); } else if(task->GetContext() == CTX_GotoDecl || task->GetContext() == CTX_GotoImpl) { // Check to see if the file was modified since it was last reparsed // If it does, we need to re-parse it again wxFileName fnSource(cacheEntry.sourceFile); time_t fileModificationTime = fnSource.GetModificationTime().GetTicks(); time_t lastReparseTime = cacheEntry.lastReparse; if(fileModificationTime > lastReparseTime) { // The file needs to be re-parsed DoSetStatusMsg(wxString::Format(wxT("clang: re-parsing file %s...\n"), cacheEntry.sourceFile)); // Try reparsing the TU ClangThreadRequest::List_t usList = task->GetModifiedBuffers(); usList.push_back(std::make_pair(task->GetFileName(), task->GetDirtyBuffer())); ClangUnsavedFiles usf(usList); if(clang_reparseTranslationUnit(TU, usf.GetCount(), usf.GetUnsavedFiles(), clang_defaultReparseOptions(TU)) != 0) { // Failed to reparse cr.SetCancelled(true); // cancel the re-caching of the TU DoSetStatusMsg( wxString::Format("clang: clang_reparseTranslationUnit '%s' failed\n", cacheEntry.sourceFile)); clang_disposeTranslationUnit(TU); wxDELETE(reply); PostEvent(wxEVT_CLANG_TU_CREATE_ERROR, task->GetFileName()); return; } DoSetStatusMsg( wxString::Format("clang: clang_reparseTranslationUnit '%s' - done\n", cacheEntry.sourceFile)); // Update the 'lastReparse' field cacheEntry.lastReparse = time(NULL); } bool success = DoGotoDefinition(TU, task, reply); if(success) { eEnd.SetClientData(reply); EventNotifier::Get()->AddPendingEvent(eEnd); } else { DoSetStatusMsg(wxT("clang: no matches were found")); CL_DEBUG(wxT("Clang Goto Decl/Impl: could not find a cursor matching for position %s:%d:%d"), task->GetFileName().c_str(), (int)task->GetLine(), (int)task->GetColumn()); // Failed, delete the 'reply' allocatd earlier wxDELETE(reply); PostEvent(wxEVT_CLANG_TU_CREATE_ERROR, task->GetFileName()); } } else { wxDELETE(reply); PostEvent(wxEVT_CLANG_PCH_CACHE_ENDED, task->GetFileName()); } }
void wxOverlayImpl::Clear(wxDC* WXUNUSED(dc)) { wxASSERT_MSG( IsOk() , _("You cannot Clear an overlay that is not inited") ); CGRect box = CGRectMake( m_x - 1, m_y - 1 , m_width + 2 , m_height + 2 ); CGContextClearRect( m_overlayContext, box ); }
void MakeUserDataRec(OpenUserDataRec *myData , const wxString& filter ) { myData->menuitems = NULL ; myData->currentfilter = 0 ; myData->saveMode = false ; if ( filter && filter[0] ) { wxString filter2(filter) ; int filterIndex = 0; bool isName = true ; wxString current ; for( unsigned int i = 0; i < filter2.Len() ; i++ ) { if( filter2.GetChar(i) == wxT('|') ) { if( isName ) { myData->name.Add( current ) ; } else { myData->extensions.Add( current.MakeUpper() ) ; ++filterIndex ; } isName = !isName ; current = wxEmptyString ; } else { current += filter2.GetChar(i) ; } } // we allow for compatibility reason to have a single filter expression (like *.*) without // an explanatory text, in that case the first part is name and extension at the same time wxASSERT_MSG( filterIndex == 0 || !isName , wxT("incorrect format of format string") ) ; if ( current.IsEmpty() ) myData->extensions.Add( myData->name[filterIndex] ) ; else myData->extensions.Add( current.MakeUpper() ) ; if ( filterIndex == 0 || isName ) myData->name.Add( current.MakeUpper() ) ; ++filterIndex ; const size_t extCount = myData->extensions.GetCount(); for ( size_t i = 0 ; i < extCount; i++ ) { wxUint32 fileType; wxUint32 creator; wxString extension = myData->extensions[i]; if (extension.GetChar(0) == '*') extension = extension.Mid(1); // Remove leading * if (extension.GetChar(0) == '.') { extension = extension.Mid(1); // Remove leading . } if (wxFileName::MacFindDefaultTypeAndCreator( extension, &fileType, &creator )) { myData->filtermactypes.Add( (OSType)fileType ); } else { myData->filtermactypes.Add( '****' ) ; // We'll fail safe if it's not recognized } } } }
bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl ) { // This is for python: if( aFileSet.size() != 1 ) { UTF8 msg = StrPrintf( "Pcbnew:%s() takes only a single filename", __func__ ); DisplayError( this, msg ); return false; } wxString fullFileName( aFileSet[0] ); // We insist on caller sending us an absolute path, if it does not, we say it's a bug. wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(), wxT( "bug in single_top.cpp or project manager." ) ); if( !LockFile( fullFileName ) ) { wxString msg = wxString::Format( _( "PCB file '%s' is already open." ), GetChars( fullFileName ) ); DisplayError( this, msg ); return false; } if( GetScreen()->IsModify() ) { int response = YesNoCancelDialog( this, _( "The current board has been modified. Do you wish to save the changes?" ), wxEmptyString, _( "Save and Load" ), _( "Load Without Saving" ) ); if( response == wxID_CANCEL ) return false; else if( response == wxID_YES ) SavePcbFile( GetBoard()->GetFileName(), CREATE_BACKUP_FILE ); else { // response == wxID_NO, fall thru } } wxFileName pro = fullFileName; pro.SetExt( ProjectFileExtension ); bool is_new = !wxFileName::IsFileReadable( fullFileName ); // If its a non-existent schematic and caller thinks it exists if( is_new && !( aCtl & KICTL_CREATE ) ) { // notify user that fullFileName does not exist, ask if user wants to create it. wxString ask = wxString::Format( _( "Board '%s' does not exist. Do you wish to create it?" ), GetChars( fullFileName ) ); if( !IsOK( this, ask ) ) return false; } Clear_Pcb( false ); // pass false since we prompted above for a modified board IO_MGR::PCB_FILE_T pluginType = plugin_type( fullFileName, aCtl ); bool converted = pluginType != IO_MGR::LEGACY && pluginType != IO_MGR::KICAD; if( !converted ) { // PROJECT::SetProjectFullName() is an impactful function. It should only be // called under carefully considered circumstances. // The calling code should know not to ask me here to change projects unless // it knows what consequences that will have on other KIFACEs running and using // this same PROJECT. It can be very harmful if that calling code is stupid. Prj().SetProjectFullName( pro.GetFullPath() ); // load project settings before BOARD LoadProjectSettings(); } if( is_new ) { OnModify(); } else { BOARD* loadedBoard = 0; // it will be set to non-NULL if loaded OK PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) ); try { PROPERTIES props; char xbuf[30]; char ybuf[30]; // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet. sprintf( xbuf, "%d", GetPageSizeIU().x ); sprintf( ybuf, "%d", GetPageSizeIU().y ); props["page_width"] = xbuf; props["page_height"] = ybuf; #if USE_INSTRUMENTATION // measure the time to load a BOARD. unsigned startTime = GetRunningMicroSecs(); #endif loadedBoard = pi->Load( fullFileName, NULL, &props ); #if USE_INSTRUMENTATION unsigned stopTime = GetRunningMicroSecs(); printf( "PLUGIN::Load(): %u usecs\n", stopTime - startTime ); #endif } catch( const IO_ERROR& ioe ) { wxString msg = wxString::Format( _( "Error loading board.\n%s" ), GetChars( ioe.errorText ) ); DisplayError( this, msg ); return false; } SetBoard( loadedBoard ); // we should not ask PLUGINs to do these items: loadedBoard->BuildListOfNets(); loadedBoard->SynchronizeNetsAndNetClasses(); SetStatusText( wxEmptyString ); BestZoom(); // update the layer names in the listbox ReCreateLayerBox( false ); GetScreen()->ClrModify(); { wxFileName fn = fullFileName; CheckForAutoSaveFile( fullFileName, fn.GetExt() ); } if( pluginType == IO_MGR::LEGACY && loadedBoard->GetFileFormatVersionAtLoad() < LEGACY_BOARD_FILE_VERSION ) { DisplayInfoMessage( this, _( "This file was created by an older version of Pcbnew.\n" "It will be stored in the new file format when you save this file again." ) ); } } { wxFileName fn = fullFileName; if( converted ) fn.SetExt( PcbFileExtension ); wxString fname = fn.GetFullPath(); fname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP ); GetBoard()->SetFileName( fname ); } UpdateTitle(); if( !converted ) UpdateFileHistory( GetBoard()->GetFileName() ); // Rebuild the new pad list (for drc and ratsnet control ...) GetBoard()->m_Status_Pcb = 0; // Update info shown by the horizontal toolbars SetCurrentNetClass( NETCLASS::Default ); ReFillLayerWidget(); ReCreateLayerBox(); // upate the layer widget to match board visibility states, both layers and render columns. syncLayerVisibilities(); syncLayerWidgetLayer(); syncRenderStates(); // Update the tracks / vias available sizes list: ReCreateAuxiliaryToolbar(); // Update the RATSNEST items, which were not loaded at the time // BOARD::SetVisibleElements() was called from within any PLUGIN. // See case RATSNEST_VISIBLE: in BOARD::SetElementVisibility() GetBoard()->SetVisibleElements( GetBoard()->GetVisibleElements() ); // Display the loaded board: Zoom_Automatique( false ); // Compile ratsnest and displays net info { wxBusyCursor dummy; // Displays an Hourglass while building connectivity Compile_Ratsnest( NULL, true ); GetBoard()->GetRatsnest()->ProcessBoard(); } SetMsgPanel( GetBoard() ); // Refresh the 3D view, if any EDA_3D_FRAME* draw3DFrame = Get3DViewerFrame(); if( draw3DFrame ) draw3DFrame->NewDisplay(); #if 0 && defined(DEBUG) // Output the board object tree to stdout, but please run from command prompt: GetBoard()->Show( 0, std::cout ); #endif // from EDA_APPL which was first loaded BOARD only: { /* For an obscure reason the focus is lost after loading a board file * when starting up the process. * (seems due to the recreation of the layer manager after loading the file) * Give focus to main window and Drawpanel * must be done for these 2 windows (for an obscure reason ...) * Linux specific * This is more a workaround than a fix. */ SetFocus(); GetCanvas()->SetFocus(); } return true; }
wxUnixTimerImpl::~wxUnixTimerImpl() { wxASSERT_MSG( !m_isRunning, wxT("must have been stopped before") ); }
void wxMenuItem::SetItemLabel( const wxString& string ) { wxString str = string; if ( str.empty() && !IsSeparator() ) { wxASSERT_MSG(wxIsStockID(GetId()), wxT("A non-stock menu item with an empty label?")); str = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR | wxSTOCK_WITH_MNEMONIC); } // Some optimization to avoid flicker wxString oldLabel = m_text; oldLabel = wxStripMenuCodes(oldLabel); oldLabel.Replace(wxT("_"), wxEmptyString); wxString label1 = wxStripMenuCodes(str); wxString oldhotkey = GetHotKey(); // Store the old hotkey in Ctrl-foo format wxCharBuffer oldbuf = wxGTK_CONV( GetGtkHotKey(*this) ); // and as <control>foo DoSetText(str); if (oldLabel == label1 && oldhotkey == GetHotKey()) // Make sure we can change a hotkey even if the label is unaltered return; if (m_menuItem) { GtkLabel *label; if (m_labelWidget) label = (GtkLabel*) m_labelWidget; else label = GTK_LABEL( GTK_BIN(m_menuItem)->child ); // set new text gtk_label_set( label, wxGTK_CONV( m_text ) ); // reparse key accel (void)gtk_label_parse_uline (GTK_LABEL(label), wxGTK_CONV(m_text) ); gtk_accel_label_refetch( GTK_ACCEL_LABEL(label) ); } guint accel_key; GdkModifierType accel_mods; gtk_accelerator_parse( (const char*) oldbuf, &accel_key, &accel_mods); if (accel_key != 0) { gtk_widget_remove_accelerator( GTK_WIDGET(m_menuItem), m_parentMenu->m_accel, accel_key, accel_mods ); } wxCharBuffer buf = wxGTK_CONV( GetGtkHotKey(*this) ); gtk_accelerator_parse( (const char*) buf, &accel_key, &accel_mods); if (accel_key != 0) { gtk_widget_add_accelerator( GTK_WIDGET(m_menuItem), "activate", m_parentMenu->m_accel, accel_key, accel_mods, GTK_ACCEL_VISIBLE); } }
void GVGalaxyNGReport::TagStart (wxString & el, wxArrayString & attr) { enum XMLState t = Top(); wxString logMessage = wxString("t:") + lookupStateName(t); wxLogMessage(logMessage); //cerr << "t: " << lookupStateName(t) << endl; if (t == ReportNullState) { if(el=="galaxy") { Push(ReportGalaxyState); } else { Push(ReportUnknownState); } } else if(t==ReportGalaxyState) { if(el=="variant") { Push(ReportVariantState); } else if(el=="version") { Push(ReportVersionState); } else if(el=="game") { // Save Gamename m_gamename = attr[1]; Push(ReportGameState); } else { Push(ReportUnknownState); } } else if(t==ReportGameState) { if(el=="features") { Push(ReportFeaturesState); } else if(el=="turn") { m_turn = atoi(attr[1].c_str()); //Set Status for all Objects m_status.SetTurn(m_turn); m_bulletins.SetTurn(m_turn); m_options.SetTurn(m_turn); m_aliens.SetTurn(m_turn); m_planets.SetTurn(m_turn); Push(ReportTurnState); } else { Push(ReportUnknownState); } } else if(t==ReportFeaturesState) { if(el=="size") { Push(ReportFeaturesSizeState); } else if(el=="numWorlds") { Push(ReportFeaturesWorldsState); } else if(el=="numRaces") { Push(ReportFeaturesNumRacesState); } else if(el=="fullBombing") { m_fullBombing = (attr[1]=="ON")?true:false; Push(ReportUnknownState); } else if(el=="keepProduction") { m_keepProduction = (attr[1]=="ON")?true:false; Push(ReportUnknownState); } else if(el=="dontDropDead") { m_dontDropDead = (attr[1]=="ON")?true:false; Push(ReportUnknownState); } else if(el=="sphericalGalaxy") { m_sphericalGalaxy = (attr[1]=="ON")?true:false; Push(ReportUnknownState); } else { m_returnValue = false; m_error += "Features Element had unknown element " + el + "\n"; } } else if(t==ReportTurnState) { if(el=="race") { m_race = attr[1]; m_race_id = atoi(attr[3].c_str()); m_password = attr[5]; m_status.m_name = m_race; m_status.m_id = m_race_id; m_status.m_password = m_password; Push(ReportRaceState); } } else if(t==ReportRaceState) { if(el=="options") { Push(ReportPlayerOptionsState); } else if(el=="report") { Push(ReportReportState); } } else if(t==ReportPlayerOptionsState) { m_options.Add(el, attr[1]); Push(ReportUnknownState); } else if(t==ReportReportState) { if(el=="status") { Push(ReportStatusState); } else if(el=="alienRaces") { Push(ReportAlienRacesState); } else if (el == "map") { Push(ReportMapState); } else if(el=="identifiedWorlds") { int id; if (attr[1] == m_race) id = m_race_id; else { id = m_aliens.GetId(attr[1]); } m_planets.SetOwner(attr[1], id); Push(ReportIdentifiedWorldsState); } else if(el=="unidentifiedWorlds") { Push(ReportUnidentifiedWorldsState); } else if(el=="uninhabitedWorlds") { Push(ReportUninhabitedWorldsState); } else { Push(ReportUnknownState); } } else if (t == ReportMapState) { if (el == "ulx") { Push(ReportMapULXState); } if (el == "lrx") { Push(ReportMapLRXState); } if (el == "uly") { Push(ReportMapULYState); } if (el == "lry") { Push(ReportMapLRYState); } } else if(t==ReportStatusState) { if(el=="tech") { Push(ReportStatusTechState); } else if(el=="numPlanets") { Push(ReportStatusNumPlanetsState); } else if(el=="population") { Push(ReportStatusPopulationState); } else if(el=="industry") { Push(ReportStatusIndustryState); } else if(el=="stockpiles") { Push(ReportStatusStockpilesState); } else { wxASSERT_MSG(false, "This should never happen."); } } else if(t==ReportStatusTechState) { if(el=="drive") { Push(ReportStatusDriveState); } else if(el=="weapons") { Push(ReportStatusWeaponsState); } else if(el=="shields") { Push(ReportStatusShieldsState); } else if(el=="cargo") { Push(ReportStatusCargoState); } else { wxASSERT_MSG(false, "This should never happen."); } } else if(t==ReportStatusStockpilesState) { if(el=="capital") { Push(ReportStatusCapitalState); } else if(el=="material") { Push(ReportStatusMaterialState); } else if(el=="colonists") { Push(ReportStatusColonistsState); } else { wxASSERT_MSG(false, "This should never happen."); } } else if(t==ReportAlienRacesState) { if(el=="alienRace") { m_aliens.AddNew(attr[1], attr[3]); Push(ReportAlienRaceState); } else { wxASSERT_MSG(false, "This should never happen."); } } else if(t==ReportAlienRaceState) { if(el=="tech") { Push(ReportAlienTechState); } else if(el=="state") { //TODO: Changed to posture perhaps? Push(ReportAlienStateState); } else { wxASSERT_MSG(false, "This should never happen."); } } else if(t==ReportAlienTechState) { if(el=="drive") { Push(ReportAlienDriveState); } else if(el=="weapons") { Push(ReportAlienWeaponsState); } else if(el=="shields") { Push(ReportAlienShieldsState); } else if(el=="cargo") { Push(ReportAlienCargoState); } else { wxASSERT_MSG(false, "This should never happen."); } } else if(t==ReportIdentifiedWorldsState) { if(el=="world") { Push(ReportIWorldState); m_planets.Add(true, attr[1]); m_planets.SetStatus("Identified"); } else { wxASSERT_MSG(false, "This should never happen."); } } else if(t==ReportUnidentifiedWorldsState) { if(el=="world") { Push(ReportUWorldState); m_planets.Add(false, ""); m_planets.SetStatus("Unidentified"); } else { wxASSERT_MSG(false, "This should never happen."); } } else if(t==ReportUninhabitedWorldsState) { if(el=="world") { Push(ReportHWorldState); m_planets.Add(false, ""); m_planets.SetStatus("Uninhabited"); } else { wxASSERT_MSG(false, "This should never happen."); } } else if(t==ReportIWorldState) { if(el=="position") { Push(ReportIWorldPositionState); } else if(el=="resources") { Push(ReportIWorldResourcesState); } else if(el=="size") { Push(ReportIWorldSizeState); } else if(el=="population") { Push(ReportIWorldPopulationState); } else if(el=="industry") { Push(ReportIWorldIndustryState); } else if(el=="stockpiles") { Push(ReportIWorldStockpilesState); } else if(el=="production") { Push(ReportIWorldProductionState); } else { wxASSERT_MSG(false, "This should never happen."); } } else if(t==ReportIWorldPositionState) { if(el=="x") { Push(ReportIWorldXState); } else if(el=="y") { Push(ReportIWorldYState); } else { wxASSERT_MSG(false, "This should never happen."); } } else if(t==ReportIWorldStockpilesState) { if(el=="capital") { Push(ReportIWorldStockCapitalState); } else if(el=="material") { Push(ReportIWorldStockMaterialState); } else if(el=="colonists") { Push(ReportIWorldStockColonistsState); } else { wxASSERT_MSG(false, "This should never happen."); } } else if(t==ReportUWorldState) { if(el=="position") { Push(ReportUWorldPositionState); } else { wxASSERT(false); } } else if(t==ReportUWorldPositionState) { if(el=="x") { Push(ReportUWorldXState); } else if(el=="y") { Push(ReportUWorldYState); } else { wxASSERT_MSG(false, "This should never happen."); } } else if(t==ReportHWorldState) { if(el=="position") { Push(ReportHWorldPositionState); } else { wxASSERT(false); } } else if(t==ReportHWorldPositionState) { if(el=="x") { Push(ReportHWorldXState); } else if(el=="y") { Push(ReportHWorldYState); } else { wxASSERT_MSG(false, "This should never happen."); } } else { Push(ReportUnknownState); } m_depth++; } /* End of start handler */
bool wxMenu::GtkAppend(wxMenuItem *mitem, int pos) { GtkWidget *menuItem; wxString text; GtkLabel* label = NULL; if ( mitem->IsSeparator() ) { // TODO menuItem = gtk_menu_item_new(); } else if (mitem->GetBitmap().Ok()) { text = mitem->wxMenuItemBase::GetItemLabel(); const wxBitmap *bitmap = &mitem->GetBitmap(); // TODO wxUnusedVar(bitmap); menuItem = gtk_menu_item_new_with_label( wxGTK_CONV( text ) ); label = GTK_LABEL( GTK_BIN(menuItem)->child ); m_prevRadio = NULL; } else // a normal item { // text has "_" instead of "&" after mitem->SetItemLabel() so don't use it text = mitem->wxMenuItemBase::GetItemLabel() ; switch ( mitem->GetKind() ) { case wxITEM_CHECK: { menuItem = gtk_check_menu_item_new_with_label( wxGTK_CONV( text ) ); label = GTK_LABEL( GTK_BIN(menuItem)->child ); // set new text gtk_label_set_text( label, wxGTK_CONV( text ) ); m_prevRadio = NULL; break; } case wxITEM_RADIO: { GSList *group = NULL; if ( m_prevRadio == NULL ) { // start of a new radio group m_prevRadio = menuItem = gtk_radio_menu_item_new_with_label( group, wxGTK_CONV( text ) ); label = GTK_LABEL( GTK_BIN(menuItem)->child ); // set new text gtk_label_set_text( label, wxGTK_CONV( text ) ); } else // continue the radio group { group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (m_prevRadio)); m_prevRadio = menuItem = gtk_radio_menu_item_new_with_label( group, wxGTK_CONV( text ) ); label = GTK_LABEL( GTK_BIN(menuItem)->child ); } break; } default: wxFAIL_MSG( wxT("unexpected menu item kind") ); // fall through case wxITEM_NORMAL: { menuItem = gtk_menu_item_new_with_label( wxGTK_CONV( text ) ); label = GTK_LABEL( GTK_BIN(menuItem)->child ); m_prevRadio = NULL; break; } } } guint accel_key; GdkModifierType accel_mods; wxCharBuffer buf = wxGTK_CONV( GetGtkHotKey(*mitem) ); // wxPrintf( wxT("item: %s hotkey %s\n"), mitem->GetItemLabel().c_str(), GetGtkHotKey(*mitem).c_str() ); gtk_accelerator_parse( (const char*) buf, &accel_key, &accel_mods); if (accel_key != 0) { gtk_widget_add_accelerator (GTK_WIDGET(menuItem), "activate", m_accel, accel_key, accel_mods, GTK_ACCEL_VISIBLE); } if (pos == -1) gtk_menu_shell_append(GTK_MENU_SHELL(m_menu), menuItem); else gtk_menu_shell_insert(GTK_MENU_SHELL(m_menu), menuItem, pos); gtk_widget_show( menuItem ); if ( !mitem->IsSeparator() ) { wxASSERT_MSG( menuItem, wxT("invalid menuitem") ); gtk_signal_connect( GTK_OBJECT(menuItem), "select", GTK_SIGNAL_FUNC(gtk_menu_hilight_callback), (gpointer)this ); gtk_signal_connect( GTK_OBJECT(menuItem), "deselect", GTK_SIGNAL_FUNC(gtk_menu_nolight_callback), (gpointer)this ); if ( mitem->IsSubMenu() && mitem->GetKind() != wxITEM_RADIO && mitem->GetKind() != wxITEM_CHECK ) { gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem), mitem->GetSubMenu()->m_menu ); gtk_widget_show( mitem->GetSubMenu()->m_menu ); } else { gtk_signal_connect( GTK_OBJECT(menuItem), "activate", GTK_SIGNAL_FUNC(gtk_menu_clicked_callback), (gpointer)this ); } guint accel_key = gtk_label_parse_uline (GTK_LABEL(label), wxGTK_CONV( text ) ); if (accel_key != GDK_VoidSymbol) { gtk_widget_add_accelerator (menuItem, "activate_item", gtk_menu_ensure_uline_accel_group(GTK_MENU(m_menu)), accel_key, GDK_MOD1_MASK, GTK_ACCEL_LOCKED); } } mitem->SetMenuItem(menuItem); if (ms_locked) { // This doesn't even exist! // gtk_widget_lock_accelerators(mitem->GetMenuItem()); } return true; }
int wxSystemSettingsNative::GetMetric( wxSystemMetric index, wxWindow* win ) { guchar *data = NULL; Atom type; int format; gulong nitems; GdkWindow *window = NULL; if(win && GTK_WIDGET_REALIZED(win->GetHandle())) window = win->GetHandle()->window; switch (index) { case wxSYS_BORDER_X: case wxSYS_BORDER_Y: case wxSYS_EDGE_X: case wxSYS_EDGE_Y: case wxSYS_FRAMESIZE_X: case wxSYS_FRAMESIZE_Y: // If a window is specified/realized, and it is a toplevel window, we can query from wm. // The returned border thickness is outside the client area in that case. if (window) { wxTopLevelWindow *tlw = wxDynamicCast(win, wxTopLevelWindow); if (!tlw) return -1; // not a tlw, not sure how to approach else { // Check if wm supports frame extents - we can't know // the border widths if it does not. #if GTK_CHECK_VERSION(2,2,0) if (!gtk_check_version(2,2,0)) { if (!gdk_x11_screen_supports_net_wm_hint( gdk_drawable_get_screen(window), gdk_atom_intern("_NET_FRAME_EXTENTS", false) ) ) return -1; } else #endif { if (!gdk_net_wm_supports(gdk_atom_intern("_NET_FRAME_EXTENTS", false))) return -1; } // Get the frame extents from the windowmanager. // In most cases the top extent is the titlebar, so we use the bottom extent // for the heights. if (wxXGetWindowProperty(window, type, format, nitems, data)) { int border_return = -1; if ((type == XA_CARDINAL) && (format == 32) && (nitems >= 4) && (data)) { switch(index) { case wxSYS_BORDER_X: case wxSYS_EDGE_X: case wxSYS_FRAMESIZE_X: border_return = ((long*)data)[1]; // width of right extent break; default: border_return = ((long*)data)[3]; // height of bottom extent break; } } if (data) XFree(data); return border_return; } } } return -1; // no window specified case wxSYS_CURSOR_X: case wxSYS_CURSOR_Y: #ifdef __WXGTK24__ if (!gtk_check_version(2,4,0)) { if (window) return gdk_display_get_default_cursor_size(gdk_drawable_get_display(window)); else return gdk_display_get_default_cursor_size(gdk_display_get_default()); } else #endif return 16; case wxSYS_DCLICK_X: case wxSYS_DCLICK_Y: gint dclick_distance; #if GTK_CHECK_VERSION(2,2,0) if (window && !gtk_check_version(2,2,0)) g_object_get(gtk_settings_get_for_screen(gdk_drawable_get_screen(window)), "gtk-double-click-distance", &dclick_distance, NULL); else #endif g_object_get(gtk_settings_get_default(), "gtk-double-click-distance", &dclick_distance, NULL); return dclick_distance * 2; case wxSYS_DRAG_X: case wxSYS_DRAG_Y: gint drag_threshold; #if GTK_CHECK_VERSION(2,2,0) if (window && !gtk_check_version(2,2,0)) { g_object_get( gtk_settings_get_for_screen(gdk_drawable_get_screen(window)), "gtk-dnd-drag-threshold", &drag_threshold, NULL); } else #endif { g_object_get(gtk_settings_get_default(), "gtk-dnd-drag-threshold", &drag_threshold, NULL); } // The correct thing here would be to double the value // since that is what the API wants. But the values // are much bigger under GNOME than under Windows and // just seem to much in many cases to be useful. // drag_threshold *= 2; return drag_threshold; // MBN: ditto for icons case wxSYS_ICON_X: return 32; case wxSYS_ICON_Y: return 32; case wxSYS_SCREEN_X: #if GTK_CHECK_VERSION(2,2,0) if (window && !gtk_check_version(2,2,0)) return gdk_screen_get_width(gdk_drawable_get_screen(window)); else #endif return gdk_screen_width(); case wxSYS_SCREEN_Y: #if GTK_CHECK_VERSION(2,2,0) if (window && !gtk_check_version(2,2,0)) return gdk_screen_get_height(gdk_drawable_get_screen(window)); else #endif return gdk_screen_height(); case wxSYS_HSCROLL_Y: return 15; case wxSYS_VSCROLL_X: return 15; case wxSYS_CAPTION_Y: if (!window) // No realized window specified, and no implementation for that case yet. return -1; // Check if wm supports frame extents - we can't know the caption height if it does not. #if GTK_CHECK_VERSION(2,2,0) if (!gtk_check_version(2,2,0)) { if (!gdk_x11_screen_supports_net_wm_hint( gdk_drawable_get_screen(window), gdk_atom_intern("_NET_FRAME_EXTENTS", false) ) ) return -1; } else #endif { if (!gdk_net_wm_supports(gdk_atom_intern("_NET_FRAME_EXTENTS", false))) return -1; } wxASSERT_MSG( wxDynamicCast(win, wxTopLevelWindow), wxT("Asking for caption height of a non toplevel window") ); // Get the height of the top windowmanager border. // This is the titlebar in most cases. The titlebar might be elsewhere, and // we could check which is the thickest wm border to decide on which side the // titlebar is, but this might lead to interesting behaviours in used code. // Reconsider when we have a way to report to the user on which side it is. if (wxXGetWindowProperty(window, type, format, nitems, data)) { int caption_height = -1; if ((type == XA_CARDINAL) && (format == 32) && (nitems >= 3) && (data)) { caption_height = ((long*)data)[2]; // top frame extent } if (data) XFree(data); return caption_height; } // Try a default approach without a window pointer, if possible // ... return -1; case wxSYS_PENWINDOWS_PRESENT: // No MS Windows for Pen computing extension available in X11 based gtk+. return 0; default: return -1; // metric is unknown } }
bool wxDisplay::ChangeMode(const wxVideoMode& mode) { unsigned long dwDMVer; Gestalt(gestaltDisplayMgrVers, (long*)&dwDMVer); if (GetCount() == 1 || dwDMVer >= 0x020000) { if (mode == wxDefaultVideoMode) { //#ifndef __DARWIN__ // Handle hDisplayState; // if (DMBeginConfigureDisplays(&hDisplayState) != noErr) // { // wxLogSysError(wxT("Could not lock display for display mode changing!")); // return false; // } // wxASSERT( DMUseScreenPrefs(true, hDisplayState) == noErr); // DMEndConfigureDisplays(hDisplayState); // return true; //#else //hmmmmm.... return true; //#endif } //0 & NULL for params 2 & 3 of DMSetVideoMode signal it to use defaults (current mode) //DM 2.0+ doesn't use params 2 & 3 of DMSetDisplayMode //so we have to use this icky structure VDSwitchInfoRec sMode; memset(&sMode, 0, sizeof(VDSwitchInfoRec) ); DMListIndexType nNumModes; DMListType pModes; DMDisplayModeListIteratorUPP uppMLI; DisplayIDType nDisplayID; wxASSERT(DMGetDisplayIDByGDevice(m_priv->m_hndl, &nDisplayID, false) == noErr); //Create a new list... wxASSERT_MSG(DMNewDisplayModeList(nDisplayID, NULL, NULL, &nNumModes, &pModes) == noErr, wxT("Could not create a new display mode list") ); uppMLI = NewDMDisplayModeListIteratorUPP(DMModeInfoProc); wxASSERT(uppMLI); DMModeInfoRec sModeInfo; sModeInfo.bMatched = false; sModeInfo.pMode = &mode; unsigned int i; for(i = 0; i < nNumModes; ++i) { wxASSERT(DMGetIndexedDisplayModeFromList(pModes, i, NULL, uppMLI, &sModeInfo) == noErr); if (sModeInfo.bMatched == true) { sMode = sModeInfo.sMode; break; } } if(i == nNumModes) return false; DisposeDMDisplayModeListIteratorUPP(uppMLI); wxASSERT(DMDisposeList(pModes) == noErr); // For the really paranoid - // unsigned long flags; // Boolean bok; // wxASSERT(noErr == DMCheckDisplayMode(m_priv->m_hndl, sMode.csData, // sMode.csMode, &flags, NULL, &bok)); // wxASSERT(bok); Handle hDisplayState; if (DMBeginConfigureDisplays(&hDisplayState) != noErr) { wxLogSysError(wxT("Could not lock display for display mode changing!")); return false; } unsigned long dwBPP = (unsigned long) mode.bpp; if (DMSetDisplayMode(m_priv->m_hndl, sMode.csData, (unsigned long*) &(dwBPP), NULL //(unsigned long) &sMode , hDisplayState ) != noErr) { DMEndConfigureDisplays(hDisplayState); wxMessageBox(wxString::Format(wxT("Could not set the display mode"))); return false; } DMEndConfigureDisplays(hDisplayState); } else //DM 1.0, 1.2, 1.x { wxLogSysError(wxString::Format(wxT("Monitor gravitation not supported yet. dwDMVer:%u"), (unsigned int) dwDMVer)); return false; } return true; }
void wxCursor::CreateFromImage(const wxImage & image) { m_refData = new wxCursorRefData; int w = 16; int h = 16; int hotSpotX = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X); int hotSpotY = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y); int image_w = image.GetWidth(); int image_h = image.GetHeight(); wxASSERT_MSG( hotSpotX >= 0 && hotSpotX < image_w && hotSpotY >= 0 && hotSpotY < image_h, _T("invalid cursor hot spot coordinates") ); wxImage image16(image); // final image of correct size // if image is too small then place it in the center, resize it if too big if ((w > image_w) && (h > image_h)) { wxPoint offset((w - image_w)/2, (h - image_h)/2); hotSpotX = hotSpotX + offset.x; hotSpotY = hotSpotY + offset.y; image16 = image.Size(wxSize(w, h), offset); } else if ((w != image_w) || (h != image_h)) { hotSpotX = int(hotSpotX * double(w) / double(image_w)); hotSpotY = int(hotSpotY * double(h) / double(image_h)); image16 = image.Scale(w, h); } unsigned char * rgbBits = image16.GetData(); bool bHasMask = image16.HasMask() ; #if 0 // monochrome implementation M_CURSORDATA->m_hCursor = NewHandle( sizeof( Cursor ) ) ; M_CURSORDATA->m_disposeHandle = true ; HLock( (Handle) M_CURSORDATA->m_hCursor ) ; CursPtr cp = *(CursHandle)M_CURSORDATA->m_hCursor ; memset( cp->data , 0 , sizeof( Bits16 ) ) ; memset( cp->mask , 0 , sizeof( Bits16 ) ) ; unsigned char mr = image16.GetMaskRed() ; unsigned char mg = image16.GetMaskGreen() ; unsigned char mb = image16.GetMaskBlue() ; for ( int y = 0 ; y < h ; ++y ) { short rowbits = 0 ; short maskbits = 0 ; for ( int x = 0 ; x < w ; ++x ) { long pos = (y * w + x) * 3; unsigned char r = rgbBits[pos] ; unsigned char g = rgbBits[pos+1] ; unsigned char b = rgbBits[pos+2] ; if ( bHasMask && r==mr && g==mg && b==mb ) { // masked area, does not appear anywhere } else { if ( (int)r + (int)g + (int)b < 0x0200 ) { rowbits |= ( 1 << (15-x) ) ; } maskbits |= ( 1 << (15-x) ) ; } } cp->data[y] = rowbits ; cp->mask[y] = maskbits ; } if ( !bHasMask ) { memcpy( cp->mask , cp->data , sizeof( Bits16) ) ; } cp->hotSpot.h = hotSpotX ; cp->hotSpot.v = hotSpotY ; HUnlock( (Handle) M_CURSORDATA->m_hCursor ) ; #else PixMapHandle pm = (PixMapHandle) NewHandleClear( sizeof (PixMap)) ; short extent = 16 ; short bytesPerPixel = 1 ; short depth = 8 ; Rect bounds = { 0 , 0 , extent , extent } ; CCrsrHandle ch = (CCrsrHandle) NewHandleClear ( sizeof( CCrsr ) ) ; CTabHandle newColors = GetCTable( 8 ) ; HandToHand((Handle *) &newColors); // set the values to the indices for ( int i = 0 ; i < (**newColors).ctSize ; ++i ) { (**newColors).ctTable[i].value = i ; } HLock( (Handle) ch) ; (**ch).crsrType = 0x8001 ; // color cursors (**ch).crsrMap = pm ; short bytesPerRow = bytesPerPixel * extent ; (**pm).baseAddr = 0; (**pm).rowBytes = bytesPerRow | 0x8000; (**pm).bounds = bounds; (**pm).pmVersion = 0; (**pm).packType = 0; (**pm).packSize = 0; (**pm).hRes = 0x00480000; /* 72 DPI default res */ (**pm).vRes = 0x00480000; /* 72 DPI default res */ (**pm).pixelSize = depth; (**pm).pixelType = 0; (**pm).cmpCount = 1; (**pm).cmpSize = depth; (**pm).pmTable = newColors; (**ch).crsrData = NewHandleClear( extent * bytesPerRow ) ; (**ch).crsrXData = NULL ; (**ch).crsrXValid = 0; (**ch).crsrXHandle = NULL; (**ch).crsrHotSpot.h = hotSpotX ; (**ch).crsrHotSpot.v = hotSpotY ; (**ch).crsrXTable = NULL ; (**ch).crsrID = GetCTSeed() ; memset( (**ch).crsr1Data , 0 , sizeof( Bits16 ) ) ; memset( (**ch).crsrMask , 0 , sizeof( Bits16 ) ) ; unsigned char mr = image16.GetMaskRed() ; unsigned char mg = image16.GetMaskGreen() ; unsigned char mb = image16.GetMaskBlue() ; for ( int y = 0 ; y < h ; ++y ) { short rowbits = 0 ; short maskbits = 0 ; for ( int x = 0 ; x < w ; ++x ) { long pos = (y * w + x) * 3; unsigned char r = rgbBits[pos] ; unsigned char g = rgbBits[pos+1] ; unsigned char b = rgbBits[pos+2] ; RGBColor col = { 0xFFFF ,0xFFFF, 0xFFFF } ; if ( bHasMask && r==mr && g==mg && b==mb ) { // masked area, does not appear anywhere } else { if ( (int)r + (int)g + (int)b < 0x0200 ) { rowbits |= ( 1 << (15-x) ) ; } maskbits |= ( 1 << (15-x) ) ; col = *((RGBColor*) wxColor( r , g , b ).GetPixel()) ; } *((*(**ch).crsrData) + y * bytesPerRow + x) = GetCTabIndex( newColors , &col) ; } (**ch).crsr1Data[y] = rowbits ; (**ch).crsrMask[y] = maskbits ; } if ( !bHasMask ) { memcpy( (**ch).crsrMask , (**ch).crsr1Data , sizeof( Bits16) ) ; } HUnlock((Handle) ch) ; M_CURSORDATA->m_hCursor = ch ; M_CURSORDATA->m_isColorCursor = true ; #endif }
void wxTaskBarJumpListImpl::AddCustomCategory(wxTaskBarJumpListCategory *category) { wxASSERT_MSG( category != NULL, "Invalid category." ); m_customCategories.push_back(category); }
bool wxHIDDevice::Create (int nClass, int nType, int nDev) { //Create the mach port wxIOCHECK(IOMasterPort(bootstrap_port, &m_pPort), "Could not create mach port"); //Dictionary that will hold first //the matching dictionary for determining which kind of devices we want, //then later some registry properties from an iterator (see below) // //The call to IOServiceMatching filters down the //the services we want to hid services (and also eats the //dictionary up for us (consumes one reference)) CFMutableDictionaryRef pDictionary = IOServiceMatching(kIOHIDDeviceKey); wxCHECK_MSG( pDictionary, false, _T("IOServiceMatching(kIOHIDDeviceKey) failed") ); wxASSERT( pDictionary ); //Here we'll filter down the services to what we want if (nType != -1) { CFNumberRef pType = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &nType); CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsageKey), pType); CFRelease(pType); } if (nClass != -1) { CFNumberRef pClass = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &nClass); CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsagePageKey), pClass); CFRelease(pClass); } //Now get the maching services io_iterator_t pIterator; wxIOCHECK(IOServiceGetMatchingServices(m_pPort, pDictionary, &pIterator), "No Matching HID Services"); wxASSERT_MSG(pIterator != 0, wxT("No devices found!")); //Now we iterate through them io_object_t pObject; while ( (pObject = IOIteratorNext(pIterator)) != 0) { if(--nDev != 0) continue; if ( IORegistryEntryCreateCFProperties ( pObject, &pDictionary, kCFAllocatorDefault, kNilOptions ) != KERN_SUCCESS ) { wxLogDebug(_T("IORegistryEntryCreateCFProperties failed")); } //Just for sanity :) wxASSERT(CFGetTypeID(CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey))) == CFStringGetTypeID()); /* kIOHIDTransportKey; kIOHIDVendorIDKey; kIOHIDProductIDKey; kIOHIDVersionNumberKey; kIOHIDManufacturerKey; kIOHIDSerialNumberKey; if !kIOHIDLocationIDKey kUSBDevicePropertyLocationID kIOHIDPrimaryUsageKey kIOHIDPrimaryUsagePageKey idProduct idVendor USB Product Name */ //Get [product] name m_szProductName = wxMacCFStringHolder( (CFStringRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey)), false ).AsString(); CFNumberRef nref = (CFNumberRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductIDKey)); if (nref) CFNumberGetValue( nref, kCFNumberIntType, &m_nProductId ); nref = (CFNumberRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDVendorIDKey)); if (nref) CFNumberGetValue( nref, kCFNumberIntType, &m_nManufacturerId ); //Create the interface (good grief - long function names!) SInt32 nScore; IOCFPlugInInterface** ppPlugin; wxIOCHECK(IOCreatePlugInInterfaceForService(pObject, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &ppPlugin, &nScore), ""); //Now, the final thing we can check before we fall back to asserts //(because the dtor only checks if the device is ok, so if anything //fails from now on the dtor will delete the device anyway, so we can't break from this). //Get the HID interface from the plugin to the mach port wxSCHECK((*ppPlugin)->QueryInterface(ppPlugin, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (void**) &m_ppDevice), ""); //release the plugin (*ppPlugin)->Release(ppPlugin); //open the HID interface... if ( (*m_ppDevice)->open(m_ppDevice, 0) != S_OK ) wxLogDebug(_T("HID device: open failed")); // //Now the hard part - in order to scan things we need "cookies" - // wxCFArray CookieArray = CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDElementKey)); BuildCookies(CookieArray); //cleanup CFRelease(pDictionary); IOObjectRelease(pObject); break; } //iterator cleanup IOObjectRelease(pIterator); return true; }//end Create()
/* static */ bool wxAcceleratorEntry::ParseAccel(const wxString& text, int *flagsOut, int *keyOut) { // the parser won't like trailing spaces wxString label = text; label.Trim(true); // For compatibility with the old wx versions which accepted (and actually // even required) a TAB character in the string passed to this function we // ignore anything up to the first TAB. Notice however that the correct // input consists of just the accelerator itself and nothing else, this is // done for compatibility and compatibility only. int posTab = label.Find(wxT('\t')); if ( posTab == wxNOT_FOUND ) posTab = 0; else posTab++; // parse the accelerator string int accelFlags = wxACCEL_NORMAL; wxString current; for ( size_t n = (size_t)posTab; n < label.length(); n++ ) { if ( (label[n] == '+') || (label[n] == '-') ) { if ( CompareAccelString(current, wxTRANSLATE("ctrl")) ) accelFlags |= wxACCEL_CTRL; else if ( CompareAccelString(current, wxTRANSLATE("alt")) ) accelFlags |= wxACCEL_ALT; else if ( CompareAccelString(current, wxTRANSLATE("shift")) ) accelFlags |= wxACCEL_SHIFT; else if ( CompareAccelString(current, wxTRANSLATE("rawctrl")) ) accelFlags |= wxACCEL_RAW_CTRL; else // not a recognized modifier name { // we may have "Ctrl-+", for example, but we still want to // catch typos like "Crtl-A" so only give the warning if we // have something before the current '+' or '-', else take // it as a literal symbol if ( current.empty() ) { current += label[n]; // skip clearing it below continue; } else { wxLogDebug(wxT("Unknown accel modifier: '%s'"), current.c_str()); } } current.clear(); } else // not special character { current += (wxChar) wxTolower(label[n]); } } int keyCode; const size_t len = current.length(); switch ( len ) { case 0: wxLogDebug(wxT("No accel key found, accel string ignored.")); return false; case 1: // it's just a letter keyCode = current[0U]; // if the key is used with any modifiers, make it an uppercase one // because Ctrl-A and Ctrl-a are the same; but keep it as is if it's // used alone as 'a' and 'A' are different if ( accelFlags != wxACCEL_NORMAL ) keyCode = wxToupper(keyCode); break; default: keyCode = IsNumberedAccelKey(current, wxTRANSLATE("F"), WXK_F1, 1, 12); if ( !keyCode ) { for ( size_t n = 0; n < WXSIZEOF(wxKeyNames); n++ ) { const wxKeyName& kn = wxKeyNames[n]; if ( CompareAccelString(current, kn.name) ) { keyCode = kn.code; break; } } } if ( !keyCode ) keyCode = IsNumberedAccelKey(current, wxTRANSLATE("KP_"), WXK_NUMPAD0, 0, 9); if ( !keyCode ) keyCode = IsNumberedAccelKey(current, wxTRANSLATE("SPECIAL"), WXK_SPECIAL1, 1, 20); if ( !keyCode ) { wxLogDebug(wxT("Unrecognized accel key '%s', accel string ignored."), current.c_str()); return false; } } wxASSERT_MSG( keyCode, wxT("logic error: should have key code here") ); if ( flagsOut ) *flagsOut = accelFlags; if ( keyOut ) *keyOut = keyCode; return true; }
int FileDialog::ShowModal() { HWND hWnd = 0; if (m_parent) hWnd = (HWND) m_parent->GetHWND(); if (!hWnd && wxTheApp->GetTopWindow()) hWnd = (HWND) wxTheApp->GetTopWindow()->GetHWND(); static wxChar fileNameBuffer [ wxMAXPATH ]; // the file-name wxChar titleBuffer [ wxMAXFILE+1+wxMAXEXT ]; // the file-name, without path *fileNameBuffer = wxT('\0'); *titleBuffer = wxT('\0'); #if WXWIN_COMPATIBILITY_2_4 long msw_flags = 0; if ( (m_dialogStyle & wxHIDE_READONLY) || (m_dialogStyle & wxSAVE) ) msw_flags |= OFN_HIDEREADONLY; #else long msw_flags = OFN_HIDEREADONLY; #endif if ( m_dialogStyle & wxFILE_MUST_EXIST ) msw_flags |= OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; /* If the window has been moved the programmer is probably trying to center or position it. Thus we set the callback or hook function so that we can actually adjust the position. Without moving or centering the dlg, it will just stay in the upper left of the frame, it does not center automatically.. One additional note, when the hook is enabled, the PLACES BAR in the dlg (shown on later versions of windows (2000 and XP) will automatically be turned off according to the MSDN docs. This is normal. If the programmer needs the PLACES BAR (left side of dlg) they just shouldn't move or center the dlg. */ if (m_bMovedWindow) // we need these flags. { msw_flags |= OFN_EXPLORER|OFN_ENABLEHOOK; #ifndef __WXWINCE__ msw_flags |= OFN_ENABLESIZING; #endif } if (m_dialogStyle & wxMULTIPLE ) { // OFN_EXPLORER must always be specified with OFN_ALLOWMULTISELECT msw_flags |= OFN_EXPLORER | OFN_ALLOWMULTISELECT; } // if wxCHANGE_DIR flag is not given we shouldn't change the CWD which the // standard dialog does by default (notice that under NT it does it anyhow, // OFN_NOCHANGEDIR or not, see below) if ( !(m_dialogStyle & wxCHANGE_DIR) ) { msw_flags |= OFN_NOCHANGEDIR; } if ( m_dialogStyle & wxOVERWRITE_PROMPT ) { msw_flags |= OFN_OVERWRITEPROMPT; } if ( m_dialogStyle & wxRESIZE_BORDER ) { msw_flags |= OFN_ENABLESIZING; } if ( m_callback != NULL ) { msw_flags |= OFN_SHOWHELP | OFN_EXPLORER | OFN_ENABLEHOOK; } // We always need EXPLORER and ENABLEHOOK to use our filtering code msw_flags |= OFN_EXPLORER | OFN_ENABLEHOOK; OPENFILENAME of; wxZeroMemory(of); // Allow Places bar to show on supported platforms if ( wxGetOsVersion() == wxWINDOWS_NT ) { of.lStructSize = sizeof(OPENFILENAME); } else { of.lStructSize = OPENFILENAME_SIZE_VERSION_400; } of.hwndOwner = hWnd; of.lpstrTitle = WXSTRINGCAST m_message; of.lpstrFileTitle = titleBuffer; of.nMaxFileTitle = wxMAXFILE + 1 + wxMAXEXT; // Windows 3.0 and 3.1 of.lCustData = (LPARAM) this; // Convert forward slashes to backslashes (file selector doesn't like // forward slashes) and also squeeze multiple consecutive slashes into one // as it doesn't like two backslashes in a row neither wxString dir; size_t i, len = m_dir.length(); dir.reserve(len); for ( i = 0; i < len; i++ ) { wxChar ch = m_dir[i]; switch ( ch ) { case _T('/'): // convert to backslash ch = _T('\\'); // fall through case _T('\\'): while ( i < len - 1 ) { wxChar chNext = m_dir[i + 1]; if ( chNext != _T('\\') && chNext != _T('/') ) break; // ignore the next one, unless it is at the start of a UNC path if (i > 0) i++; else break; } // fall through default: // normal char dir += ch; } } of.lpstrInitialDir = dir.c_str(); of.Flags = msw_flags; of.lpfnHook = FileDialogHookFunction; wxArrayString wildDescriptions; size_t items = wxParseCommonDialogsFilter(m_wildCard, wildDescriptions, m_FilterGroups); wxASSERT_MSG( items > 0 , _T("empty wildcard list") ); wxString filterBuffer; for (i = 0; i < items ; i++) { filterBuffer += wildDescriptions[i]; filterBuffer += wxT("|"); filterBuffer += wxT("*.*"); filterBuffer += wxT("|"); } // Replace | with \0 for (i = 0; i < filterBuffer.Len(); i++ ) { if ( filterBuffer.GetChar(i) == wxT('|') ) { filterBuffer[i] = wxT('\0'); } } of.lpstrFilter = (LPTSTR)filterBuffer.c_str(); of.nFilterIndex = m_filterIndex + 1; ParseFilter(of.nFilterIndex); //=== Setting defaultFileName >>========================================= wxStrncpy( fileNameBuffer, (const wxChar *)m_fileName, wxMAXPATH-1 ); fileNameBuffer[ wxMAXPATH-1 ] = wxT('\0'); of.lpstrFile = fileNameBuffer; // holds returned filename of.nMaxFile = wxMAXPATH; // we must set the default extension because otherwise Windows would check // for the existing of a wrong file with wxOVERWRITE_PROMPT (i.e. if the // user types "foo" and the default extension is ".bar" we should force it // to check for "foo.bar" existence and not "foo") wxString defextBuffer; // we need it to be alive until GetSaveFileName()! if (m_dialogStyle & wxSAVE && m_dialogStyle & wxOVERWRITE_PROMPT) { const wxChar* extension = filterBuffer; int maxFilter = (int)(of.nFilterIndex*2L) - 1; for( int i = 0; i < maxFilter; i++ ) // get extension extension = extension + wxStrlen( extension ) + 1; // use dummy name a to avoid assert in AppendExtension defextBuffer = AppendExtension(wxT("a"), extension); if (defextBuffer.StartsWith(wxT("a."))) { defextBuffer.Mid(2); of.lpstrDefExt = defextBuffer.c_str(); } } // store off before the standard windows dialog can possibly change it const wxString cwdOrig = wxGetCwd(); //== Execute FileDialog >>================================================= bool success = (m_dialogStyle & wxSAVE ? GetSaveFileName(&of) : GetOpenFileName(&of)) != 0; #ifdef __WXWINCE__ DWORD errCode = GetLastError(); #else DWORD errCode = CommDlgExtendedError(); // GetOpenFileName will always change the current working directory on // (according to MSDN) "Windows NT 4.0/2000/XP" because the flag // OFN_NOCHANGEDIR has no effect. If the user did not specify wxCHANGE_DIR // let's restore the current working directory to what it was before the // dialog was shown (assuming this behavior extends to Windows Server 2003 // seems safe). if ( success && (msw_flags & OFN_NOCHANGEDIR) && wxGetOsVersion() == wxWINDOWS_NT ) { wxSetWorkingDirectory(cwdOrig); } #ifdef __WIN32__ if (!success && (errCode == CDERR_STRUCTSIZE)) { // The struct size has changed so try a smaller or bigger size int oldStructSize = of.lStructSize; of.lStructSize = oldStructSize - (sizeof(void *) + 2*sizeof(DWORD)); success = (m_dialogStyle & wxSAVE) ? (GetSaveFileName(&of) != 0) : (GetOpenFileName(&of) != 0); errCode = CommDlgExtendedError(); if (!success && (errCode == CDERR_STRUCTSIZE)) { of.lStructSize = oldStructSize + (sizeof(void *) + 2*sizeof(DWORD)); success = (m_dialogStyle & wxSAVE) ? (GetSaveFileName(&of) != 0) : (GetOpenFileName(&of) != 0); } } #endif // __WIN32__ #endif // __WXWINCE__ if ( success ) { m_fileNames.Empty(); if ( ( m_dialogStyle & wxMULTIPLE ) && #if defined(OFN_EXPLORER) ( fileNameBuffer[of.nFileOffset-1] == wxT('\0') ) #else ( fileNameBuffer[of.nFileOffset-1] == wxT(' ') ) #endif // OFN_EXPLORER ) { #if defined(OFN_EXPLORER) m_dir = fileNameBuffer; i = of.nFileOffset; m_fileName = &fileNameBuffer[i]; m_fileNames.Add(m_fileName); i += m_fileName.Len() + 1; while (fileNameBuffer[i] != wxT('\0')) { m_fileNames.Add(&fileNameBuffer[i]); i += wxStrlen(&fileNameBuffer[i]) + 1; } #else wxStringTokenizer toke(fileNameBuffer, _T(" \t\r\n")); m_dir = toke.GetNextToken(); m_fileName = toke.GetNextToken(); m_fileNames.Add(m_fileName); while (toke.HasMoreTokens()) m_fileNames.Add(toke.GetNextToken()); #endif // OFN_EXPLORER wxString dir(m_dir); if ( m_dir.Last() != _T('\\') ) dir += _T('\\'); m_path = dir + m_fileName; m_filterIndex = (int)of.nFilterIndex - 1; } else { //=== Adding the correct extension >>================================= m_filterIndex = (int)of.nFilterIndex - 1; #if 0 // LLL: Removed to prevent adding extension during Export // processing. if ( !of.nFileExtension || (of.nFileExtension && fileNameBuffer[of.nFileExtension] == wxT('\0')) ) { // User has typed a filename without an extension: const wxChar* extension = filterBuffer; int maxFilter = (int)(of.nFilterIndex*2L) - 1; for( int i = 0; i < maxFilter; i++ ) // get extension extension = extension + wxStrlen( extension ) + 1; m_fileName = AppendExtension(fileNameBuffer, extension); wxStrncpy(fileNameBuffer, m_fileName.c_str(), wxMin(m_fileName.Len(), wxMAXPATH-1)); fileNameBuffer[wxMin(m_fileName.Len(), wxMAXPATH-1)] = wxT('\0'); } #endif m_path = fileNameBuffer; m_fileName = wxFileNameFromPath(fileNameBuffer); m_fileNames.Add(m_fileName); m_dir = wxPathOnly(fileNameBuffer); } } else { // common dialog failed - why? #ifdef __WXDEBUG__ #ifdef __WXWINCE__ if (errCode == 0) { // OK, user cancelled the dialog } else if (errCode == ERROR_INVALID_PARAMETER) { wxLogError(wxT("Invalid parameter passed to file dialog function.")); } else if (errCode == ERROR_OUTOFMEMORY) { wxLogError(wxT("Out of memory when calling file dialog function.")); } else if (errCode == ERROR_CALL_NOT_IMPLEMENTED) { wxLogError(wxT("Call not implemented when calling file dialog function.")); } else { wxLogError(wxT("Unknown error %d when calling file dialog function."), errCode); } #else DWORD dwErr = CommDlgExtendedError(); if ( dwErr != 0 ) { // this msg is only for developers wxLogError(wxT("Common dialog failed with error code %0lx."), dwErr); } //else: it was just cancelled #endif #endif } return success ? wxID_OK : wxID_CANCEL; }
size_t wxDir::Traverse(wxDirTraverser& sink, const wxString& filespec, int flags) const { wxCHECK_MSG( IsOpened(), (size_t)-1, wxT("dir must be opened before traversing it") ); // the total number of files found size_t nFiles = 0; // the name of this dir with path delimiter at the end const wxString prefix = GetNameWithSep(); // first, recurse into subdirs if ( flags & wxDIR_DIRS ) { wxString dirname; for ( bool cont = GetFirst(&dirname, wxEmptyString, (flags & ~(wxDIR_FILES | wxDIR_DOTDOT)) | wxDIR_DIRS); cont; cont = cont && GetNext(&dirname) ) { const wxString fulldirname = prefix + dirname; switch ( sink.OnDir(fulldirname) ) { default: wxFAIL_MSG(wxT("unexpected OnDir() return value") ); wxFALLTHROUGH; case wxDIR_STOP: cont = false; break; case wxDIR_CONTINUE: { wxDir subdir; // don't give the error messages for the directories // which we can't open: there can be all sorts of good // reason for this (e.g. insufficient privileges) and // this shouldn't be treated as an error -- instead // let the user code decide what to do bool ok; do { wxLogNull noLog; ok = subdir.Open(fulldirname); if ( !ok ) { // ask the user code what to do bool tryagain; switch ( sink.OnOpenError(fulldirname) ) { default: wxFAIL_MSG(wxT("unexpected OnOpenError() return value") ); wxFALLTHROUGH; case wxDIR_STOP: cont = false; wxFALLTHROUGH; case wxDIR_IGNORE: tryagain = false; break; case wxDIR_CONTINUE: tryagain = true; } if ( !tryagain ) break; } } while ( !ok ); if ( ok ) { nFiles += subdir.Traverse(sink, filespec, flags); } } break; case wxDIR_IGNORE: // nothing to do ; } } } // now enum our own files if ( flags & wxDIR_FILES ) { flags &= ~wxDIR_DIRS; wxString filename; bool cont = GetFirst(&filename, filespec, flags); while ( cont ) { wxDirTraverseResult res = sink.OnFile(prefix + filename); if ( res == wxDIR_STOP ) break; wxASSERT_MSG( res == wxDIR_CONTINUE, wxT("unexpected OnFile() return value") ); nFiles++; cont = GetNext(&filename); } } return nFiles; }
bool wxGetKeyState (wxKeyCode key) { wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key != WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons")); if (wxHIDModule::sm_keyboards.GetCount() == 0) { int nKeyboards = wxHIDKeyboard::GetCount(); for(int i = 1; i <= nKeyboards; ++i) { wxHIDKeyboard* keyboard = new wxHIDKeyboard(); if(keyboard->Create(i)) { wxHIDModule::sm_keyboards.Add(keyboard); } else { delete keyboard; break; } } wxASSERT_MSG(wxHIDModule::sm_keyboards.GetCount() != 0, wxT("No keyboards found!")); } for(size_t i = 0; i < wxHIDModule::sm_keyboards.GetCount(); ++i) { wxHIDKeyboard* keyboard = (wxHIDKeyboard*) wxHIDModule::sm_keyboards[i]; switch(key) { case WXK_SHIFT: if( keyboard->IsActive(WXK_SHIFT) || keyboard->IsActive(WXK_RSHIFT) ) { return true; } break; case WXK_ALT: if( keyboard->IsActive(WXK_ALT) || keyboard->IsActive(WXK_RALT) ) { return true; } break; case WXK_CONTROL: if( keyboard->IsActive(WXK_CONTROL) || keyboard->IsActive(WXK_RCONTROL) ) { return true; } break; case WXK_MENU: if( keyboard->IsActive(WXK_MENU) || keyboard->IsActive(WXK_RMENU) ) { return true; } break; default: if( keyboard->IsActive(key) ) { return true; } break; } } return false; //not down/error }
// wxExecute: the real worker function long wxExecute(char **argv, int flags, wxProcess *process, const wxExecuteEnv *env) { // for the sync execution, we return -1 to indicate failure, but for async // case we return 0 which is never a valid PID // // we define this as a macro, not a variable, to avoid compiler warnings // about "ERROR_RETURN_CODE value may be clobbered by fork()" #define ERROR_RETURN_CODE ((flags & wxEXEC_SYNC) ? -1 : 0) wxCHECK_MSG( *argv, ERROR_RETURN_CODE, wxT("can't exec empty command") ); #if wxUSE_THREADS // fork() doesn't mix well with POSIX threads: on many systems the program // deadlocks or crashes for some reason. Probably our code is buggy and // doesn't do something which must be done to allow this to work, but I // don't know what yet, so for now just warn the user (this is the least we // can do) about it wxASSERT_MSG( wxThread::IsMain(), wxT("wxExecute() can be called only from the main thread") ); #endif // wxUSE_THREADS #if defined(__WXCOCOA__) || ( defined(__WXOSX_MAC__) && wxOSX_USE_COCOA_OR_CARBON ) // wxMacLaunch() only executes app bundles and only does it asynchronously. // It returns false if the target is not an app bundle, thus falling // through to the regular code for non app bundles. if ( !(flags & wxEXEC_SYNC) && wxMacLaunch(argv) ) { // we don't have any PID to return so just make up something non null return -1; } #endif // __DARWIN__ // this struct contains all information which we use for housekeeping wxExecuteData execData; execData.flags = flags; execData.process = process; // create pipes if ( !execData.pipeEndProcDetect.Create() ) { wxLogError( _("Failed to execute '%s'\n"), *argv ); return ERROR_RETURN_CODE; } // pipes for inter process communication wxPipe pipeIn, // stdin pipeOut, // stdout pipeErr; // stderr if ( process && process->IsRedirected() ) { if ( !pipeIn.Create() || !pipeOut.Create() || !pipeErr.Create() ) { wxLogError( _("Failed to execute '%s'\n"), *argv ); return ERROR_RETURN_CODE; } } // fork the process // // NB: do *not* use vfork() here, it completely breaks this code for some // reason under Solaris (and maybe others, although not under Linux) // But on OpenVMS we do not have fork so we have to use vfork and // cross our fingers that it works. #ifdef __VMS pid_t pid = vfork(); #else pid_t pid = fork(); #endif if ( pid == -1 ) // error? { wxLogSysError( _("Fork failed") ); return ERROR_RETURN_CODE; } else if ( pid == 0 ) // we're in child { // NB: we used to close all the unused descriptors of the child here // but this broke some programs which relied on e.g. FD 1 being // always opened so don't do it any more, after all there doesn't // seem to be any real problem with keeping them opened #if !defined(__VMS) && !defined(__EMX__) if ( flags & wxEXEC_MAKE_GROUP_LEADER ) { // Set process group to child process' pid. Then killing -pid // of the parent will kill the process and all of its children. setsid(); } #endif // !__VMS // redirect stdin, stdout and stderr if ( pipeIn.IsOk() ) { if ( dup2(pipeIn[wxPipe::Read], STDIN_FILENO) == -1 || dup2(pipeOut[wxPipe::Write], STDOUT_FILENO) == -1 || dup2(pipeErr[wxPipe::Write], STDERR_FILENO) == -1 ) { wxLogSysError(_("Failed to redirect child process input/output")); } pipeIn.Close(); pipeOut.Close(); pipeErr.Close(); } // Close all (presumably accidentally) inherited file descriptors to // avoid descriptor leaks. This means that we don't allow inheriting // them purposefully but this seems like a lesser evil in wx code. // Ideally we'd provide some flag to indicate that none (or some?) of // the descriptors do not need to be closed but for now this is better // than never closing them at all as wx code never used FD_CLOEXEC. // Note that while the reading side of the end process detection pipe // can be safely closed, we should keep the write one opened, it will // be only closed when the process terminates resulting in a read // notification to the parent const int fdEndProc = execData.pipeEndProcDetect.Detach(wxPipe::Write); execData.pipeEndProcDetect.Close(); // TODO: Iterating up to FD_SETSIZE is both inefficient (because it may // be quite big) and incorrect (because in principle we could // have more opened descriptions than this number). Unfortunately // there is no good portable solution for closing all descriptors // above a certain threshold but non-portable solutions exist for // most platforms, see [http://stackoverflow.com/questions/899038/ // getting-the-highest-allocated-file-descriptor] for ( int fd = 0; fd < (int)FD_SETSIZE; ++fd ) { if ( fd != STDIN_FILENO && fd != STDOUT_FILENO && fd != STDERR_FILENO && fd != fdEndProc ) { close(fd); } } // Process additional options if we have any if ( env ) { // Change working directory if it is specified if ( !env->cwd.empty() ) wxSetWorkingDirectory(env->cwd); // Change environment if needed. // // NB: We can't use execve() currently because we allow using // non full paths to wxExecute(), i.e. we want to search for // the program in PATH. However it just might be simpler/better // to do the search manually and use execve() envp parameter to // set up the environment of the child process explicitly // instead of doing what we do below. if ( !env->env.empty() ) { wxEnvVariableHashMap oldenv; wxGetEnvMap(&oldenv); // Remove unwanted variables wxEnvVariableHashMap::const_iterator it; for ( it = oldenv.begin(); it != oldenv.end(); ++it ) { if ( env->env.find(it->first) == env->env.end() ) wxUnsetEnv(it->first); } // And add the new ones (possibly replacing the old values) for ( it = env->env.begin(); it != env->env.end(); ++it ) wxSetEnv(it->first, it->second); } } execvp(*argv, argv); fprintf(stderr, "execvp("); for ( char **a = argv; *a; a++ ) fprintf(stderr, "%s%s", a == argv ? "" : ", ", *a); fprintf(stderr, ") failed with error %d!\n", errno); // there is no return after successful exec() _exit(-1); // some compilers complain about missing return - of course, they // should know that exit() doesn't return but what else can we do if // they don't? // // and, sure enough, other compilers complain about unreachable code // after exit() call, so we can just always have return here... #if defined(__VMS) || defined(__INTEL_COMPILER) return 0; #endif } else // we're in parent { // save it for WaitForChild() use execData.pid = pid; if (execData.process) execData.process->SetPid(pid); // and also in the wxProcess // prepare for IO redirection #if HAS_PIPE_STREAMS // the input buffer bufOut is connected to stdout, this is why it is // called bufOut and not bufIn wxStreamTempInputBuffer bufOut, bufErr; if ( process && process->IsRedirected() ) { // Avoid deadlocks which could result from trying to write to the // child input pipe end while the child itself is writing to its // output end and waiting for us to read from it. if ( !pipeIn.MakeNonBlocking(wxPipe::Write) ) { // This message is not terrible useful for the user but what // else can we do? Also, should we fail here or take the risk // to continue and deadlock? Currently we choose the latter but // it might not be the best idea. wxLogSysError(_("Failed to set up non-blocking pipe, " "the program might hang.")); #if wxUSE_LOG wxLog::FlushActive(); #endif } wxOutputStream *inStream = new wxPipeOutputStream(pipeIn.Detach(wxPipe::Write)); const int fdOut = pipeOut.Detach(wxPipe::Read); wxPipeInputStream *outStream = new wxPipeInputStream(fdOut); const int fdErr = pipeErr.Detach(wxPipe::Read); wxPipeInputStream *errStream = new wxPipeInputStream(fdErr); process->SetPipeStreams(outStream, inStream, errStream); bufOut.Init(outStream); bufErr.Init(errStream); execData.bufOut = &bufOut; execData.bufErr = &bufErr; execData.fdOut = fdOut; execData.fdErr = fdErr; } #endif // HAS_PIPE_STREAMS if ( pipeIn.IsOk() ) { pipeIn.Close(); pipeOut.Close(); pipeErr.Close(); } // we want this function to work even if there is no wxApp so ensure // that we have a valid traits pointer wxConsoleAppTraits traitsConsole; wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL; if ( !traits ) traits = &traitsConsole; return traits->WaitForChild(execData); } #if !defined(__VMS) && !defined(__INTEL_COMPILER) return ERROR_RETURN_CODE; #endif }
static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu ) { if (g_isIdle) wxapp_install_idle_handler(); int id = menu->FindMenuIdByMenuItem(widget); /* should find it for normal (not popup) menu */ wxASSERT_MSG( (id != -1) || (menu->GetWindow() != NULL), wxT("menu item not found in gtk_menu_clicked_callback") ); if (!menu->IsEnabled(id)) return; wxMenuItem* item = menu->FindChildItem( id ); wxCHECK_RET( item, wxT("error in menu item callback") ); if ( item->GetId() == wxGTK_TITLE_ID ) { // ignore events from the menu title return; } if (item->IsCheckable()) { bool isReallyChecked = item->IsChecked(), isInternallyChecked = item->wxMenuItemBase::IsChecked(); // ensure that the internal state is always consistent with what is // shown on the screen item->wxMenuItemBase::Check(isReallyChecked); // we must not report the events for the radio button going up nor the // events resulting from the calls to wxMenuItem::Check() if ( (item->GetKind() == wxITEM_RADIO && !isReallyChecked) || (isInternallyChecked == isReallyChecked) ) { return; } } // Is this menu on a menubar? (possibly nested) wxFrame* frame = NULL; if(menu->IsAttached()) frame = menu->GetMenuBar()->GetFrame(); // FIXME: why do we have to call wxFrame::GetEventHandler() directly here? // normally wxMenu::SendEvent() should be enough, if it doesn't work // in wxGTK then we have a bug in wxMenu::GetWindow() which // should be fixed instead of working around it here... if (frame) { // If it is attached then let the frame send the event. // Don't call frame->ProcessCommand(id) because it toggles // checkable items and we've already done that above. wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id); commandEvent.SetEventObject(frame); if (item->IsCheckable()) commandEvent.SetInt(item->IsChecked()); commandEvent.SetEventObject(menu); frame->HandleWindowEvent(commandEvent); } else { // otherwise let the menu have it menu->SendEvent(id, item->IsCheckable() ? item->IsChecked() : -1); } }
bool wxTopLevelWindowGTK::Show( bool show ) { wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") ); #ifdef GDK_WINDOWING_X11 bool deferShow = show && !m_isShown && m_deferShow; if (deferShow) { deferShow = m_deferShowAllowed && gs_requestFrameExtentsStatus != RFE_STATUS_BROKEN && !gtk_widget_get_realized(m_widget) && g_signal_handler_find(m_widget, GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA), g_signal_lookup("property_notify_event", GTK_TYPE_WIDGET), 0, NULL, NULL, this); if (deferShow) { GdkScreen* screen = gtk_widget_get_screen(m_widget); GdkAtom atom = gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false); deferShow = gdk_x11_screen_supports_net_wm_hint(screen, atom) != 0; // If _NET_REQUEST_FRAME_EXTENTS not supported, don't allow changes // to m_decorSize, it breaks saving/restoring window size with // GetSize()/SetSize() because it makes window bigger between each // restore and save. m_updateDecorSize = deferShow; } m_deferShow = deferShow; } if (deferShow) { // Initial show. If WM supports _NET_REQUEST_FRAME_EXTENTS, defer // calling gtk_widget_show() until _NET_FRAME_EXTENTS property // notification is received, so correct frame extents are known. // This allows resizing m_widget to keep the overall size in sync with // what wxWidgets expects it to be without an obvious change in the // window size immediately after it becomes visible. // Realize m_widget, so m_widget->window can be used. Realizing normally // causes the widget tree to be size_allocated, which generates size // events in the wrong order. However, the size_allocates will not be // done if the allocation is not the default (1,1). GtkAllocation alloc; gtk_widget_get_allocation(m_widget, &alloc); const int alloc_width = alloc.width; if (alloc_width == 1) { alloc.width = 2; gtk_widget_set_allocation(m_widget, &alloc); } gtk_widget_realize(m_widget); if (alloc_width == 1) { alloc.width = 1; gtk_widget_set_allocation(m_widget, &alloc); } // send _NET_REQUEST_FRAME_EXTENTS XClientMessageEvent xevent; memset(&xevent, 0, sizeof(xevent)); xevent.type = ClientMessage; GdkWindow* window = gtk_widget_get_window(m_widget); xevent.window = GDK_WINDOW_XID(window); xevent.message_type = gdk_x11_atom_to_xatom_for_display( gdk_window_get_display(window), gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false)); xevent.format = 32; Display* display = GDK_DISPLAY_XDISPLAY(gdk_window_get_display(window)); XSendEvent(display, DefaultRootWindow(display), false, SubstructureNotifyMask | SubstructureRedirectMask, (XEvent*)&xevent); if (gs_requestFrameExtentsStatus == RFE_STATUS_UNKNOWN) { // if WM does not respond to request within 1 second, // we assume support for _NET_REQUEST_FRAME_EXTENTS is not working m_netFrameExtentsTimerId = g_timeout_add(1000, request_frame_extents_timeout, this); } // defer calling gtk_widget_show() m_isShown = true; return true; } #endif // GDK_WINDOWING_X11 if (show && !gtk_widget_get_realized(m_widget)) { // size_allocate signals occur in reverse order (bottom to top). // Things work better if the initial wxSizeEvents are sent (from the // top down), before the initial size_allocate signals occur. wxSizeEvent event(GetSize(), GetId()); event.SetEventObject(this); HandleWindowEvent(event); } bool change = base_type::Show(show); if (change && !show) { // make sure window has a non-default position, so when it is shown // again, it won't be repositioned by WM as if it were a new window // Note that this must be done _after_ the window is hidden. gtk_window_move((GtkWindow*)m_widget, m_x, m_y); } return change; }
void SCH_EDIT_FRAME::LoadSettings( wxConfigBase* aCfg ) { EDA_DRAW_FRAME::LoadSettings( aCfg ); long tmp; ReadHotkeyConfig( SCH_EDIT_FRAME_NAME, g_Schematic_Hotkeys_Descr ); wxConfigLoadSetups( aCfg, GetConfigurationSettings() ); SetDefaultBusThickness( (int) aCfg->Read( DefaultBusWidthEntry, DEFAULTBUSTHICKNESS ) ); SetDefaultLineThickness( (int) aCfg->Read( DefaultDrawLineWidthEntry, DEFAULTDRAWLINETHICKNESS ) ); SCH_JUNCTION::SetSymbolSize( (int) aCfg->Read( DefaultJctSizeEntry, SCH_JUNCTION::GetSymbolSize() ) ); aCfg->Read( ShowHiddenPinsEntry, &m_showAllPins, false ); aCfg->Read( HorzVertLinesOnlyEntry, &m_forceHVLines, true ); aCfg->Read( AutoplaceFieldsEntry, &m_autoplaceFields, true ); aCfg->Read( AutoplaceJustifyEntry, &m_autoplaceJustify, true ); aCfg->Read( AutoplaceAlignEntry, &m_autoplaceAlign, false ); aCfg->Read( FootprintPreviewEntry, &m_footprintPreview, false ); // Load netlists options: aCfg->Read( SimulatorCommandEntry, &m_simulatorCommand ); wxASSERT_MSG( m_findReplaceData, wxT( "Find dialog data settings object not created. Bad programmer!" ) ); aCfg->Read( FindReplaceFlagsEntry, &tmp, (long) wxFR_DOWN ); m_findReplaceData->SetFlags( (wxUint32) tmp & ~FR_REPLACE_ITEM_FOUND ); m_findReplaceData->SetFindString( aCfg->Read( FindStringEntry, wxEmptyString ) ); m_findReplaceData->SetReplaceString( aCfg->Read( ReplaceStringEntry, wxEmptyString ) ); // Load the find and replace string history list. for( int i = 0; i < FR_HISTORY_LIST_CNT; ++i ) { wxString tmpHistory; wxString entry; entry.Printf( FindStringHistoryEntry, i ); tmpHistory = aCfg->Read( entry, wxEmptyString ); if( !tmpHistory.IsEmpty() ) m_findStringHistoryList.Add( tmpHistory ); entry.Printf( ReplaceStringHistoryEntry, i ); tmpHistory = aCfg->Read( entry, wxEmptyString ); if( !tmpHistory.IsEmpty() ) m_replaceStringHistoryList.Add( tmpHistory ); } wxString templateFieldNames = aCfg->Read( FieldNamesEntry, wxEmptyString ); if( !templateFieldNames.IsEmpty() ) { TEMPLATE_FIELDNAMES_LEXER lexer( TO_UTF8( templateFieldNames ) ); try { m_templateFieldNames.Parse( &lexer ); } catch( const IO_ERROR& DBG( e ) ) { // @todo show error msg DBG( printf( "templatefieldnames parsing error: '%s'\n", TO_UTF8( e.What() ) ); ) } }