Ejemplo n.º 1
0
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__
}
Ejemplo n.º 2
0
// 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();
}
Ejemplo n.º 3
0
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);
    }
}
Ejemplo n.º 4
0
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__
}
Ejemplo n.º 5
0
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) );
}
Ejemplo n.º 6
0
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() );
}
Ejemplo n.º 7
0
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());
}
Ejemplo n.º 8
0
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;
    }
}
Ejemplo n.º 9
0
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)));
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
/* 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;
Ejemplo n.º 12
0
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 );
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
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__
}
Ejemplo n.º 16
0
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__
}
Ejemplo n.º 17
0
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++;
                            }
                        }
                    }
Ejemplo n.º 18
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
    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)&params) )
                {
                    // 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;
}
Ejemplo n.º 19
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)&params) )
                {
                    // 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;
}