void FileNameTestCase::TestExists() { wxFileName fn(wxFileName::CreateTempFileName("filenametest")); CPPUNIT_ASSERT( fn.IsOk() ); wxON_BLOCK_EXIT1( wxRemoveFile, fn.GetFullPath() ); CPPUNIT_ASSERT( fn.FileExists() ); CPPUNIT_ASSERT( !wxFileName::DirExists(fn.GetFullPath()) ); CPPUNIT_ASSERT( fn.Exists(wxFILE_EXISTS_REGULAR) ); CPPUNIT_ASSERT( !fn.Exists(wxFILE_EXISTS_DIR) ); CPPUNIT_ASSERT( fn.Exists() ); const wxString& tempdir = wxFileName::GetTempDir(); wxFileName fileInTempDir(tempdir, "bloordyblop"); CPPUNIT_ASSERT( !fileInTempDir.Exists() ); CPPUNIT_ASSERT( fileInTempDir.DirExists() ); wxFileName dirTemp(wxFileName::DirName(tempdir)); CPPUNIT_ASSERT( !dirTemp.FileExists() ); CPPUNIT_ASSERT( dirTemp.DirExists() ); CPPUNIT_ASSERT( dirTemp.Exists(wxFILE_EXISTS_DIR) ); CPPUNIT_ASSERT( !dirTemp.Exists(wxFILE_EXISTS_REGULAR) ); CPPUNIT_ASSERT( dirTemp.Exists() ); #ifdef __UNIX__ CPPUNIT_ASSERT( !wxFileName::FileExists("/dev/null") ); CPPUNIT_ASSERT( !wxFileName::DirExists("/dev/null") ); CPPUNIT_ASSERT( wxFileName::Exists("/dev/null") ); CPPUNIT_ASSERT( wxFileName::Exists("/dev/null", wxFILE_EXISTS_DEVICE) ); #ifdef __LINUX__ // These files are only guaranteed to exist under Linux. // No need for wxFILE_EXISTS_NO_FOLLOW here; wxFILE_EXISTS_SYMLINK implies it CPPUNIT_ASSERT( wxFileName::Exists("/proc/self", wxFILE_EXISTS_SYMLINK) ); CPPUNIT_ASSERT( wxFileName::Exists("/dev/log", wxFILE_EXISTS_SOCKET) ); #endif // __LINUX__ #ifndef __VMS wxString fifo = dirTemp.GetPath() + "/fifo"; if (mkfifo(fifo.c_str(), 0600) == 0) { wxON_BLOCK_EXIT1(wxRemoveFile, fifo); CPPUNIT_ASSERT( wxFileName::Exists(fifo, wxFILE_EXISTS_FIFO) ); } #endif #endif // __UNIX__ }
// Helper of test_new_file_and_save() which tests creating a new file of // the type corresponding to the key argument, used to select this type in // the "New" popup menu. // // The last argument indicates whether a dialog is shown when creating a // new file of this type (e.g. true for illustrations, false for census). // It affects this function behaviour in two ways: first, it needs to be // ready for this dialog appearing and, second, "File|Save" menu command is // disabled for the files created in this way and "File|Save as" needs to // be used instead. void do_test_create_open (wx_base_test_case& test ,int key ,char const* basename ,bool uses_dialog) { test.skip_if_not_supported(basename); wxString const file = test.get_test_file_path_for(basename); LMI_ASSERT(!wxFileExists(file)); wxUIActionSimulator z; z.Char('n', wxMOD_CONTROL); // new file z.Char(key ); // choose document type if (uses_dialog) { wxTEST_DIALOG (wxYield() ,wxExpectDismissableModal<MvcController>(wxID_OK). Describe("new file properties") ); } wxYield(); z.Char(uses_dialog ? 'a' : 's', wxMOD_CONTROL); // save or save as wxTEST_DIALOG (wxYield() ,wxExpectModal<wxFileDialog>(file).Describe("save file dialog") ); wxYield(); LMI_ASSERT(wxFileExists(file)); wxON_BLOCK_EXIT1(wxRemoveFile, file); z.Char('l', wxMOD_CONTROL); // close document wxYield(); z.Char('o', wxMOD_CONTROL); // and open it again if (uses_dialog) { wxTEST_DIALOG (wxYield() ,wxExpectModal<wxFileDialog>(file).Describe("open file dialog") ,wxExpectDismissableModal<MvcController>(wxID_OK). Describe("existing file properties") ); } else { wxTEST_DIALOG (wxYield() ,wxExpectModal<wxFileDialog>(file).Describe("open file dialog") ); } wxYield(); z.Char('l', wxMOD_CONTROL); // close it finally wxYield(); }
void wxCmdLineParserData::SetArguments(int argc, char **argv) { m_arguments.clear(); // Command-line arguments are supposed to be in the user locale encoding // (what else?) but wxLocale probably wasn't initialized yet as we're // called early during the program startup and so our locale might not have // been set from the environment yet. To work around this problem we // temporarily change the locale here. The only drawback is that changing // the locale is thread-unsafe but precisely because we're called so early // it's hopefully safe to assume that no other threads had been created yet. char * const locOld = SetAllLocaleFacets(""); wxON_BLOCK_EXIT1( SetAllLocaleFacets, locOld ); for ( int n = 0; n < argc; n++ ) { // try to interpret the string as being in the current locale wxString arg(argv[n]); // but just in case we guessed wrongly and the conversion failed, do // try to salvage at least something if ( arg.empty() && argv[n][0] != '\0' ) arg = wxString(argv[n], wxConvISO8859_1); m_arguments.push_back(arg); } }
void FileNameTestCase::TestIsSame() { wxFileName fn1( wxFileName::CreateTempFileName( "filenametest1" ) ); CPPUNIT_ASSERT( fn1.IsOk() ); wxON_BLOCK_EXIT1( wxRemoveFile, fn1.GetFullPath() ); wxFileName fn2( wxFileName::CreateTempFileName( "filenametest2" ) ); CPPUNIT_ASSERT( fn2.IsOk() ); wxON_BLOCK_EXIT1( wxRemoveFile, fn2.GetFullPath() ); CPPUNIT_ASSERT( fn1.SameAs( fn1 ) ); CPPUNIT_ASSERT( !fn1.SameAs( fn2 ) ); #if defined(__UNIX__) // We need to create a temporary directory and a temporary link. // Unfortunately we can't use wxFileName::CreateTempFileName() for neither // as it creates plain files, so use tempnam() explicitly instead. char* tn = tempnam(NULL, "wxfn1"); const wxString tempdir1 = wxString::From8BitData(tn); free(tn); CPPUNIT_ASSERT( wxFileName::Mkdir(tempdir1) ); // Unfortunately the casts are needed to select the overload we need here. wxON_BLOCK_EXIT2( static_cast<bool (*)(const wxString&, int)>(wxFileName::Rmdir), tempdir1, static_cast<int>(wxPATH_RMDIR_RECURSIVE) ); tn = tempnam(NULL, "wxfn2"); const wxString tempdir2 = wxString::From8BitData(tn); free(tn); CPPUNIT_ASSERT_EQUAL( 0, symlink(tempdir1.c_str(), tempdir2.c_str()) ); wxON_BLOCK_EXIT1( wxRemoveFile, tempdir2 ); wxFileName fn3(tempdir1, "foo"); wxFileName fn4(tempdir2, "foo"); // These files have different paths, hence are different. CPPUNIT_ASSERT( !fn3.SameAs(fn4) ); // Create and close a file to trigger creating it. wxFile(fn3.GetFullPath(), wxFile::write); // Now that both files do exist we should be able to detect that they are // actually the same file. CPPUNIT_ASSERT( fn3.SameAs(fn4) ); #endif // __UNIX__ }
void LogTestCase::CompatLogger() { CompatTestLog log; wxLog * const logOld = wxLog::SetActiveTarget(&log); wxON_BLOCK_EXIT1( wxLog::SetActiveTarget, logOld ); wxLogError("Old error"); CPPUNIT_ASSERT_EQUAL( "Old error", log.GetLog(wxLOG_Error) ); }
void LogTestCase::CompatLogger2() { CompatTestLog2 log; wxLog * const logOld = wxLog::SetActiveTarget(&log); wxON_BLOCK_EXIT1( wxLog::SetActiveTarget, logOld ); wxLogWarning("Old warning"); CPPUNIT_ASSERT_EQUAL( "Old warning", log.Get() ); }
void FileNameTestCase::TestShortcuts() { wxFileName fn(wxFileName::CreateTempFileName("filenametest")); CPPUNIT_ASSERT( fn.IsOk() ); wxON_BLOCK_EXIT1( wxRemoveFile, fn.GetFullPath() ); wxFileName fnLink(fn.GetPath(), "sc_" + fn.GetName(), "lnk"); CPPUNIT_ASSERT( fnLink.IsOk() ); wxON_BLOCK_EXIT1( wxRemoveFile, fnLink.GetFullPath() ); CreateShortcut(fn.GetFullPath(), fnLink.GetFullPath()); // MakeRelativeTo() is supposed to change only the path of the file, not its // name. wxFileName fnLinkRel(fnLink); fnLink.MakeRelativeTo("."); CPPUNIT_ASSERT_EQUAL(fnLink.GetFullName(), fnLinkRel.GetFullName()); }
static void targets_selection_received( GtkWidget *WXUNUSED(widget), GtkSelectionData *selection_data, guint32 WXUNUSED(time), wxClipboard *clipboard ) { if ( !clipboard ) return; wxON_BLOCK_EXIT1(wxClipboardSync::OnDone, clipboard); if (!selection_data) return; const int selection_data_length = gtk_selection_data_get_length(selection_data); if (selection_data_length <= 0) return; // make sure we got the data in the correct form GdkAtom type = gtk_selection_data_get_data_type(selection_data); if ( type != GDK_SELECTION_TYPE_ATOM ) { if ( strcmp(wxGtkString(gdk_atom_name(type)), "TARGETS") != 0 ) { wxLogTrace( TRACE_CLIPBOARD, wxT("got unsupported clipboard target") ); return; } } // it's not really a format, of course, but we can reuse its GetId() method // to format this atom as string wxDataFormat clip(gtk_selection_data_get_selection(selection_data)); wxLogTrace( TRACE_CLIPBOARD, wxT("Received available formats for clipboard %s"), clip.GetId().c_str() ); // the atoms we received, holding a list of targets (= formats) const GdkAtom* const atoms = (GdkAtom*)gtk_selection_data_get_data(selection_data); for (size_t i = 0; i < selection_data_length / sizeof(GdkAtom); i++) { const wxDataFormat format(atoms[i]); wxLogTrace(TRACE_CLIPBOARD, wxT("\t%s"), format.GetId().c_str()); if ( clipboard->GTKOnTargetReceived(format) ) return; } }
void FileNameTestCase::TestGetTimes() { wxFileName fn(wxFileName::CreateTempFileName("filenametest")); CPPUNIT_ASSERT( fn.IsOk() ); wxON_BLOCK_EXIT1( wxRemoveFile, fn.GetFullPath() ); wxDateTime dtAccess, dtMod, dtCreate; CPPUNIT_ASSERT( fn.GetTimes(&dtAccess, &dtMod, &dtCreate) ); // make sure all retrieved dates are equal to the current date&time // with an accuracy up to 1 minute CPPUNIT_ASSERT(dtCreate.IsEqualUpTo(wxDateTime::Now(), wxTimeSpan(0,1))); CPPUNIT_ASSERT(dtMod.IsEqualUpTo(wxDateTime::Now(), wxTimeSpan(0,1))); CPPUNIT_ASSERT(dtAccess.IsEqualUpTo(wxDateTime::Now(), wxTimeSpan(0,1))); }
static void selection_received( GtkWidget *WXUNUSED(widget), GtkSelectionData *selection_data, guint32 WXUNUSED(time), wxClipboard *clipboard ) { if ( !clipboard ) return; wxON_BLOCK_EXIT1(wxClipboardSync::OnDone, clipboard); if (!selection_data || gtk_selection_data_get_length(selection_data) <= 0) return; clipboard->GTKOnSelectionReceived(*selection_data); }
/* static */ THREAD_RETVAL wxThreadInternal::DoThreadStart(wxThread *thread) { wxON_BLOCK_EXIT1(DoThreadOnExit, thread); THREAD_RETVAL rc = THREAD_ERROR_EXIT; wxTRY { // store the thread object in the TLS if ( !::TlsSetValue(gs_tlsThisThread, thread) ) { wxLogSysError(_("Cannot start thread: error writing TLS.")); return THREAD_ERROR_EXIT; } rc = wxPtrToUInt(thread->Entry()); } wxCATCH_ALL( wxTheApp->OnUnhandledException(); ) return rc;
void ScopeGuardTestCase::BlockExit() { int n = 1, m = 2; { gs_count = 1; wxON_BLOCK_EXIT0(IncGlobal); wxON_BLOCK_EXIT1(Inc, &n); wxON_BLOCK_EXIT2(IncBy, &m, 15); CPPUNIT_ASSERT_EQUAL( 1, gs_count ); CPPUNIT_ASSERT_EQUAL( 1, n ); CPPUNIT_ASSERT_EQUAL( 2, m ); } CPPUNIT_ASSERT_EQUAL( 2, gs_count ); CPPUNIT_ASSERT_EQUAL( 2, n ); CPPUNIT_ASSERT_EQUAL( 17, m ); }
int wxRendererMSW::GetHeaderButtonHeight(wxWindow * WXUNUSED(win)) { // some "reasonable" value returned in case of error, it doesn't really // correspond to anything but it's better than returning 0 static const int DEFAULT_HEIGHT = 20; // create a temporary header window just to get its geometry HWND hwndHeader = ::CreateWindow(WC_HEADER, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); if ( !hwndHeader ) return DEFAULT_HEIGHT; wxON_BLOCK_EXIT1( ::DestroyWindow, hwndHeader ); // initialize the struct filled with the values by Header_Layout() RECT parentRect = { 0, 0, 100, 100 }; WINDOWPOS wp = { 0, 0, 0, 0, 0, 0, 0 }; HDLAYOUT hdl = { &parentRect, &wp }; return Header_Layout(hwndHeader, &hdl) ? wp.cy : DEFAULT_HEIGHT; }
static gint selection_clear_clip( GtkWidget *WXUNUSED(widget), GdkEventSelection *event ) { wxClipboard * const clipboard = wxTheClipboard; if ( !clipboard ) return TRUE; // notice the use of OnDoneIfInProgress() here instead of just OnDone(): // it's perfectly possible that we're receiving this notification from GTK+ // even though we hadn't cleared the clipboard ourselves but because // another application (or even another window in the same program) // acquired it wxON_BLOCK_EXIT1(wxClipboardSync::OnDoneIfInProgress, clipboard); wxClipboard::Kind kind; if (event->selection == GDK_SELECTION_PRIMARY) { wxLogTrace(TRACE_CLIPBOARD, wxT("Lost primary selection" )); kind = wxClipboard::Primary; } else if (event->selection == g_clipboardAtom) { wxLogTrace(TRACE_CLIPBOARD, wxT("Lost clipboard" )); kind = wxClipboard::Clipboard; } else // some other selection, we're not concerned { return FALSE; } // the clipboard is no longer in our hands, we don't need data any more clipboard->GTKClearData(kind); return TRUE; }
void FileNameTestCase::TestSetTimes() { wxFileName fn(wxFileName::CreateTempFileName("filenametest")); CPPUNIT_ASSERT( fn.IsOk() ); wxON_BLOCK_EXIT1( wxRemoveFile, fn.GetFullPath() ); const wxDateTime dtAccess(1, wxDateTime::Jan, 2013); const wxDateTime dtModify(1, wxDateTime::Feb, 2013); const wxDateTime dtCreate(1, wxDateTime::Mar, 2013); CPPUNIT_ASSERT( fn.SetTimes(&dtAccess, &dtModify, &dtCreate) ); wxDateTime dtAccess2, dtModify2, dtCreate2; CPPUNIT_ASSERT( fn.GetTimes(&dtAccess2, &dtModify2, &dtCreate2) ); CPPUNIT_ASSERT_EQUAL( dtAccess, dtAccess2 ); CPPUNIT_ASSERT_EQUAL( dtModify, dtModify2 ); // Under Unix the creation time can't be set. #ifdef __WINDOWS__ CPPUNIT_ASSERT_EQUAL( dtCreate, dtCreate2 ); #endif // __WINDOWS__ }
void ExecTestCase::TestOverlappedSyncExecute() { // Windows Synchronous wxExecute implementation does not currently // support overlapped event loops. It is still using wxYield, which is // not nestable. Therefore, this test would fail in Windows. // If someday somebody changes that in Windows, they could use this // test to verify it. // // Because MSW is not yet ready for this test, it may make sense to // separate it out to its own test suite, so we could register it under // "fixme" for Windows, but a real test for Unix. But that is more work, // so just #ifndefing it here for now. // // Too bad you can't just register one test case of a test suite as a // "fixme". #ifndef __WINDOWS__ // Simple helper delaying the call to wxExecute(): instead of running it // immediately, it runs it when we re-enter the event loop. class DelayedExecuteTimer : public wxTimer { public: DelayedExecuteTimer(const wxString& command, wxArrayString& outputArray) : m_command(command), m_outputArray(outputArray) { // The exact delay doesn't matter, anything short enough will do. StartOnce(10); } virtual void Notify() { wxExecute(m_command, m_outputArray); } private: wxString m_command; wxArrayString& m_outputArray; }; // Create two scripts with one of them taking longer than the other one to // execute. const wxString shortSleepFile = CreateSleepFile("shortsleep", 1); wxON_BLOCK_EXIT1( wxRemoveFile, shortSleepFile ); const wxString longSleepFile = CreateSleepFile("longsleep", 2); wxON_BLOCK_EXIT1( wxRemoveFile, longSleepFile ); const wxString shortSleepCommand = MakeShellCommand(shortSleepFile); const wxString longSleepCommand = MakeShellCommand(longSleepFile); // Collect the child process output wxArrayString shortSleepOutput, longSleepOutput; // Test that launching a process taking a longer time to run while the // shorter process is running works, i.e. that our outer wxExecute() // doesn't return until both process terminate. DelayedExecuteTimer delayLongSleep(longSleepCommand, longSleepOutput); wxExecute(shortSleepCommand, shortSleepOutput); CPPUNIT_ASSERT( !shortSleepOutput.empty() ); CPPUNIT_ASSERT_EQUAL( SLEEP_END_STRING, shortSleepOutput.Last() ); CPPUNIT_ASSERT( !longSleepOutput.empty() ); CPPUNIT_ASSERT_EQUAL( SLEEP_END_STRING, longSleepOutput.Last() ); // And also that, vice versa, running a short-lived child process that both // starts and ends while a longer-lived parent process is still running // works too. DelayedExecuteTimer delayShortSleep(shortSleepCommand, shortSleepOutput); wxExecute(longSleepCommand, longSleepOutput); CPPUNIT_ASSERT( !shortSleepOutput.empty() ); CPPUNIT_ASSERT_EQUAL( SLEEP_END_STRING, shortSleepOutput.Last() ); CPPUNIT_ASSERT( !longSleepOutput.empty() ); CPPUNIT_ASSERT_EQUAL( SLEEP_END_STRING, longSleepOutput.Last() ); #endif // !__WINDOWS__ }
bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height, int bpp, int ncolors, int comp, wxFileOffset bmpOffset, wxInputStream& stream, bool verbose, bool IsBmp, bool hasPalette) { wxInt32 aDword, rmask = 0, gmask = 0, bmask = 0, amask = 0; int rshift = 0, gshift = 0, bshift = 0, ashift = 0; int rbits = 0, gbits = 0, bbits = 0; wxInt32 dbuf[4]; wxInt8 bbuf[4]; wxUint8 aByte; wxUint16 aWord; // allocate space for palette if needed: BMPPalette *cmap; if ( bpp < 16 ) { cmap = new BMPPalette[ncolors]; if ( !cmap ) { if (verbose) { wxLogError(_("BMP: Couldn't allocate memory.")); } return false; } } else // no palette { cmap = NULL; } wxON_BLOCK_EXIT1(&BMPPalette::Free, cmap); // destroy existing here instead of: image->Destroy(); image->Create(width, height); unsigned char *ptr = image->GetData(); if ( !ptr ) { if ( verbose ) { wxLogError( _("BMP: Couldn't allocate memory.") ); } return false; } unsigned char *alpha; if ( bpp == 32 ) { // tell the image to allocate an alpha buffer image->SetAlpha(); alpha = image->GetAlpha(); if ( !alpha ) { if ( verbose ) { wxLogError(_("BMP: Couldn't allocate memory.")); } return false; } } else // no alpha { alpha = NULL; } // Reading the palette, if it exists: if ( bpp < 16 && ncolors != 0 ) { unsigned char* r = new unsigned char[ncolors]; unsigned char* g = new unsigned char[ncolors]; unsigned char* b = new unsigned char[ncolors]; for (int j = 0; j < ncolors; j++) { if (hasPalette) { stream.Read(bbuf, 4); cmap[j].b = bbuf[0]; cmap[j].g = bbuf[1]; cmap[j].r = bbuf[2]; r[j] = cmap[j].r; g[j] = cmap[j].g; b[j] = cmap[j].b; } else { //used in reading .ico file mask r[j] = cmap[j].r = g[j] = cmap[j].g = b[j] = cmap[j].b = ( j ? 255 : 0 ); } } #if wxUSE_PALETTE // Set the palette for the wxImage image->SetPalette(wxPalette(ncolors, r, g, b)); #endif // wxUSE_PALETTE delete[] r; delete[] g; delete[] b; } else if ( bpp == 16 || bpp == 32 ) { if ( comp == BI_BITFIELDS ) { int bit; stream.Read(dbuf, 4 * 3); rmask = wxINT32_SWAP_ON_BE(dbuf[0]); gmask = wxINT32_SWAP_ON_BE(dbuf[1]); bmask = wxINT32_SWAP_ON_BE(dbuf[2]); // find shift amount (Least significant bit of mask) for (bit = bpp-1; bit>=0; bit--) { if (bmask & (1 << bit)) bshift = bit; if (gmask & (1 << bit)) gshift = bit; if (rmask & (1 << bit)) rshift = bit; } // Find number of bits in mask (MSB-LSB+1) for (bit = 0; bit < bpp; bit++) { if (bmask & (1 << bit)) bbits = bit-bshift+1; if (gmask & (1 << bit)) gbits = bit-gshift+1; if (rmask & (1 << bit)) rbits = bit-rshift+1; } } else if ( bpp == 16 ) { rmask = 0x7C00; gmask = 0x03E0; bmask = 0x001F; rshift = 10; gshift = 5; bshift = 0; rbits = 5; gbits = 5; bbits = 5; } else if ( bpp == 32 ) { rmask = 0x00FF0000; gmask = 0x0000FF00; bmask = 0x000000FF; amask = 0xFF000000; ashift = 24; rshift = 16; gshift = 8; bshift = 0; rbits = 8; gbits = 8; bbits = 8; } } /* * Reading the image data */ if ( IsBmp ) { // NOTE: seeking a positive amount in wxFromCurrent mode allows us to // load even non-seekable streams (see wxInputStream::SeekI docs)! const wxFileOffset pos = stream.TellI(); if (pos != wxInvalidOffset && bmpOffset > pos) if (stream.SeekI(bmpOffset - pos, wxFromCurrent) == wxInvalidOffset) return false; //else: icon, just carry on } unsigned char *data = ptr; /* set the whole image to the background color */ if ( bpp < 16 && (comp == BI_RLE4 || comp == BI_RLE8) ) { for (int i = 0; i < width * height; i++) { *ptr++ = cmap[0].r; *ptr++ = cmap[0].g; *ptr++ = cmap[0].b; } ptr = data; } int linesize = ((width * bpp + 31) / 32) * 4; /* BMPs are stored upside down */ for ( int line = (height - 1); line >= 0; line-- ) { int linepos = 0; for ( int column = 0; column < width ; ) { if ( bpp < 16 ) { linepos++; aByte = stream.GetC(); if ( bpp == 1 ) { for (int bit = 0; bit < 8 && column < width; bit++) { int index = ((aByte & (0x80 >> bit)) ? 1 : 0); ptr[poffset] = cmap[index].r; ptr[poffset + 1] = cmap[index].g; ptr[poffset + 2] = cmap[index].b; column++; } } else if ( bpp == 4 ) { if ( comp == BI_RLE4 ) { wxUint8 first; first = aByte; aByte = stream.GetC(); if ( first == 0 ) { if ( aByte == 0 ) { if ( column > 0 ) column = width; } else if ( aByte == 1 ) { column = width; line = -1; } else if ( aByte == 2 ) { aByte = stream.GetC(); column += aByte; linepos = column * bpp / 4; aByte = stream.GetC(); line -= aByte; // upside down } else { int absolute = aByte; wxUint8 nibble[2] ; int readBytes = 0 ; for (int k = 0; k < absolute; k++) { if ( !(k % 2 ) ) { ++readBytes ; aByte = stream.GetC(); nibble[0] = (wxUint8)( (aByte & 0xF0) >> 4 ) ; nibble[1] = (wxUint8)( aByte & 0x0F ) ; } ptr[poffset ] = cmap[nibble[k%2]].r; ptr[poffset + 1] = cmap[nibble[k%2]].g; ptr[poffset + 2] = cmap[nibble[k%2]].b; column++; if ( k % 2 ) linepos++; } if ( readBytes & 0x01 ) aByte = stream.GetC(); } } else { wxUint8 nibble[2] ; nibble[0] = (wxUint8)( (aByte & 0xF0) >> 4 ) ; nibble[1] = (wxUint8)( aByte & 0x0F ) ; for ( int l = 0; l < first && column < width; l++ ) { ptr[poffset ] = cmap[nibble[l%2]].r; ptr[poffset + 1] = cmap[nibble[l%2]].g; ptr[poffset + 2] = cmap[nibble[l%2]].b; column++; if ( l % 2 ) linepos++; } } }
int wxKill(long pid, wxSignal sig, wxKillError *krc, int flags) { if (flags & wxKILL_CHILDREN) wxKillAllChildren(pid, sig, krc); // get the process handle to operate on HANDLE hProcess = ::OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION, FALSE, // not inheritable (DWORD)pid); if ( hProcess == NULL ) { if ( krc ) { // recognize wxKILL_ACCESS_DENIED as special because this doesn't // mean that the process doesn't exist and this is important for // wxProcess::Exists() *krc = ::GetLastError() == ERROR_ACCESS_DENIED ? wxKILL_ACCESS_DENIED : wxKILL_NO_PROCESS; } return -1; } wxON_BLOCK_EXIT1(::CloseHandle, hProcess); bool ok = true; switch ( sig ) { case wxSIGKILL: // kill the process forcefully returning -1 as error code if ( !::TerminateProcess(hProcess, (UINT)-1) ) { wxLogSysError(_("Failed to kill process %d"), pid); if ( krc ) { // this is not supposed to happen if we could open the // process *krc = wxKILL_ERROR; } ok = false; } break; case wxSIGNONE: // do nothing, we just want to test for process existence if ( krc ) *krc = wxKILL_OK; return 0; default: // any other signal means "terminate" { wxFindByPidParams params; params.pid = (DWORD)pid; // EnumWindows() has nice semantics: it returns 0 if it found // something or if an error occurred and non zero if it // enumerated all the window if ( !::EnumWindows(wxEnumFindByPidProc, (LPARAM)¶ms) ) { // did we find any window? if ( params.hwnd ) { // tell the app to close // // NB: this is the harshest way, the app won't have an // opportunity to save any files, for example, but // this is probably what we want here. If not we // can also use SendMesageTimeout(WM_CLOSE) if ( !::PostMessage(params.hwnd, WM_QUIT, 0, 0) ) { wxLogLastError(_T("PostMessage(WM_QUIT)")); } } else // it was an error then { wxLogLastError(_T("EnumWindows")); ok = false; } } else // no windows for this PID { if ( krc ) *krc = wxKILL_ERROR; ok = false; } } } // the return code DWORD rc wxDUMMY_INITIALIZE(0); if ( ok ) { // as we wait for a short time, we can use just WaitForSingleObject() // and not MsgWaitForMultipleObjects() switch ( ::WaitForSingleObject(hProcess, 500 /* msec */) ) { case WAIT_OBJECT_0: // process terminated if ( !::GetExitCodeProcess(hProcess, &rc) ) { wxLogLastError(_T("GetExitCodeProcess")); } break; default: wxFAIL_MSG( _T("unexpected WaitForSingleObject() return") ); // fall through case WAIT_FAILED: wxLogLastError(_T("WaitForSingleObject")); // fall through case WAIT_TIMEOUT: if ( krc ) *krc = wxKILL_ERROR; rc = STILL_ACTIVE; break; } } // the return code is the same as from Unix kill(): 0 if killed // successfully or -1 on error if ( !ok || rc == STILL_ACTIVE ) return -1; if ( krc ) *krc = wxKILL_OK; return 0; }
int wxKill(long pid, wxSignal sig, wxKillError *krc, int flags) { if (flags & wxKILL_CHILDREN) wxKillAllChildren(pid, sig, krc); // get the process handle to operate on DWORD dwAccess = PROCESS_QUERY_INFORMATION | SYNCHRONIZE; if ( sig == wxSIGKILL ) dwAccess |= PROCESS_TERMINATE; HANDLE hProcess = ::OpenProcess(dwAccess, FALSE, (DWORD)pid); if ( hProcess == NULL ) { if ( krc ) { // recognize wxKILL_ACCESS_DENIED as special because this doesn't // mean that the process doesn't exist and this is important for // wxProcess::Exists() *krc = ::GetLastError() == ERROR_ACCESS_DENIED ? wxKILL_ACCESS_DENIED : wxKILL_NO_PROCESS; } return -1; } wxON_BLOCK_EXIT1(::CloseHandle, hProcess); // Default timeout for waiting for the process termination after killing // it. It should be long enough to allow the process to terminate even on a // busy system but short enough to avoid blocking the main thread for too // long. DWORD waitTimeout = 500; // ms bool ok = true; switch ( sig ) { case wxSIGKILL: // kill the process forcefully returning -1 as error code if ( !::TerminateProcess(hProcess, (UINT)-1) ) { wxLogSysError(_("Failed to kill process %d"), pid); if ( krc ) { // this is not supposed to happen if we could open the // process *krc = wxKILL_ERROR; } ok = false; } break; case wxSIGNONE: // Opening the process handle may succeed for a process even if it // doesn't run any more (typically because open handles to it still // exist elsewhere, possibly in this process itself if we're // killing a child process) so we still need check if it hasn't // terminated yet but, unlike when killing it, we don't need to // wait for any time at all. waitTimeout = 0; break; default: // any other signal means "terminate" { wxFindByPidParams params; params.pid = (DWORD)pid; // EnumWindows() has nice semantics: it returns 0 if it found // something or if an error occurred and non zero if it // enumerated all the window if ( !::EnumWindows(wxEnumFindByPidProc, (LPARAM)¶ms) ) { // did we find any window? if ( params.hwnd ) { // tell the app to close // // NB: this is the harshest way, the app won't have an // opportunity to save any files, for example, but // this is probably what we want here. If not we // can also use SendMesageTimeout(WM_CLOSE) if ( !::PostMessage(params.hwnd, WM_QUIT, 0, 0) ) { wxLogLastError(wxT("PostMessage(WM_QUIT)")); } } else // it was an error then { wxLogLastError(wxT("EnumWindows")); ok = false; } } else // no windows for this PID { if ( krc ) *krc = wxKILL_ERROR; ok = false; } } } // the return code if ( ok ) { // as we wait for a short time, we can use just WaitForSingleObject() // and not MsgWaitForMultipleObjects() switch ( ::WaitForSingleObject(hProcess, waitTimeout) ) { case WAIT_OBJECT_0: // Process terminated: normally this indicates that we // successfully killed it but when testing for the process // existence, this means failure. if ( sig == wxSIGNONE ) { if ( krc ) *krc = wxKILL_NO_PROCESS; ok = false; } break; default: wxFAIL_MSG( wxT("unexpected WaitForSingleObject() return") ); // fall through case WAIT_FAILED: wxLogLastError(wxT("WaitForSingleObject")); // fall through case WAIT_TIMEOUT: // Process didn't terminate: normally this is a failure but not // when we're just testing for its existence. if ( sig != wxSIGNONE ) { if ( krc ) *krc = wxKILL_ERROR; ok = false; } break; } } // the return code is the same as from Unix kill(): 0 if killed // successfully or -1 on error if ( !ok ) return -1; if ( krc ) *krc = wxKILL_OK; return 0; }