예제 #1
0
bitmapinit()
{
	fbbm_rop_reset(consfb);
	if (!consfb->Mono) {
		lock_bitmap();
		fbbm_init_palette(consfb);
		unlock_bitmap();
	}
}
예제 #2
0
/*
 * shrink_fork()
 *
 * Try to remove enough allocation blocks from 'fork'
 * so that it is 'ablocks' allocation blocks long.
 */
static void shrink_fork(struct hfs_fork *fork, int ablocks)
{
    struct hfs_mdb *mdb = fork->entry->mdb;
    struct hfs_extent *ext;
    int i, error, next, count;
    hfs_u32 ablksz = mdb->alloc_blksz;

    next =  (fork->psize / ablksz) - 1;
    ext = find_ext(fork, next);
    while (ext && ext->start && (ext->start >= ablocks)) {
        next = ext->start - 1;
        delete_extent(fork, ext);
        ext = find_ext(fork, next);
    }
    if (!ext) {
        fork->psize = (next + 1) * ablksz;
        return;
    }

    if ((count = next + 1 - ablocks) > 0) {
        for (i=2; (i>=0) && !ext->length[i]; --i) {};
        lock_bitmap(mdb);
        while (count && (ext->length[i] <= count)) {
            ext->end -= ext->length[i];
            count -= ext->length[i];
            error = hfs_clear_vbm_bits(mdb, ext->block[i],
                                       ext->length[i]);
            if (error) {
                hfs_warn("hfs_truncate: error %d freeing "
                         "blocks.\n", error);
            }
            ext->block[i] = ext->length[i] = 0;
            --i;
        }
        if (count) {
            ext->end -= count;
            ext->length[i] -= count;
            error = hfs_clear_vbm_bits(mdb, ext->block[i] +
                                       ext->length[i], count);
            if (error) {
                hfs_warn("hfs_truncate: error %d freeing "
                         "blocks.\n", error);
            }
        }
        unlock_bitmap(mdb);
        update_ext(fork, ext);
    }

    fork->psize = ablocks * ablksz;
}
예제 #3
0
/*
 * delete_extent()
 *
 * Description:
 *   Deletes an extent record from a fork, reducing its physical length.
 * Input Variable(s):
 *   struct hfs_fork *fork: the fork
 *   struct hfs_extent *ext: the current last extent for 'fork'
 * Output Variable(s):
 *   NONE
 * Returns:
 *   void
 * Preconditions:
 *   'fork' points to a valid (struct hfs_fork)
 *   'ext' point to a valid (struct hfs_extent) which is the last in 'fork'
 *    and which is not also the first extent in 'fork'.
 * Postconditions:
 *   The extent record has been removed if possible, and a warning has been
 *   printed otherwise.
 */
static void delete_extent(struct hfs_fork *fork, struct hfs_extent *ext)
{
    struct hfs_mdb *mdb = fork->entry->mdb;
    struct hfs_ext_key key;
    int error;

    if (fork->cache == ext) {
        set_cache(fork, ext->prev);
    }
    ext->prev->next = NULL;
    if (ext->count != 1) {
        hfs_warn("hfs_truncate: extent has count %d.\n", ext->count);
    }

    lock_bitmap(mdb);
    error = hfs_clear_vbm_bits(mdb, ext->block[2], ext->length[2]);
    if (error) {
        hfs_warn("hfs_truncate: error %d freeing blocks.\n", error);
    }
    error = hfs_clear_vbm_bits(mdb, ext->block[1], ext->length[1]);
    if (error) {
        hfs_warn("hfs_truncate: error %d freeing blocks.\n", error);
    }
    error = hfs_clear_vbm_bits(mdb, ext->block[0], ext->length[0]);
    if (error) {
        hfs_warn("hfs_truncate: error %d freeing blocks.\n", error);
    }
    unlock_bitmap(mdb);

    build_key(&key, fork, ext->start);

    error = hfs_bdelete(mdb->ext_tree, HFS_BKEY(&key));
    if (error) {
        hfs_warn("hfs_truncate: error %d deleting an extent.\n", error);
    }

    HFS_DELETE(ext);
}
예제 #4
0
int main(int argc,char **argv) {
    WNDCLASS wnd;
    HRESULT hr;
    RECT rect;
    MSG msg;
    char *a;
    int i;

    for (i=1;i < argc;) {
        a = argv[i++];

        if (*a == '-') {
            do { a++; } while (*a == '-');

            if (!strcmp(a,"nodpiaware")) {
                gdi_no_dpiaware = true;
            }
            else if (!strcmp(a,"dpiaware")) {
                gdi_no_dpiaware = false;
            }
            else {
                fprintf(stderr,"Unhandled switch %s\n",a);
                return 1;
            }
        }
        else {
            fprintf(stderr,"Unhandled arg %s\n",a);
            return 1;
        }
    }

    if (sizeof(rgb24bpp_t) != 3)
        fprintf(stderr,"WARNING: uint24_t is not 3 bytes long, it is %u bytes\n",(unsigned int)sizeof(rgb24bpp_t));

    /* Please don't scale me in the name of "DPI awareness" */
    if (!gdi_no_dpiaware)
        win32_dpi_aware();

    /* Bring up DirectX */
    /* NTS: On multi-monitor setups, this will create an "emulated" object. Hardware accel won't be possible unless we enum monitors. */
    if ((hr=DirectDrawCreate(NULL,&ddraw1,NULL)) != DD_OK) {
        fprintf(stderr,"DirectDrawCreate failed, HRESULT=0x%08lx\n",hr);
        return 1;
    }
    if ((hr=ddraw1->QueryInterface(IID_IDirectDraw2,(void**)(&ddraw))) != S_OK) {
        fprintf(stderr,"Unable to query IDirectDraw2 from IDirectDraw, HR=0x%08lx\n",hr);
        return 1;
    }
    ddraw1->Release();
    ddraw1 = NULL;
    if ((hr=ddraw->SetCooperativeLevel(hwndMain,ddrawCooperativeLevel=DDSCL_NORMAL)) != DD_OK) {
        fprintf(stderr,"Unable to ask for Normal cooperative mode, HR=0x%08lx\n",hr);
        return 1;
    }

    myInstance = GetModuleHandle(NULL);

    memset(&wnd,0,sizeof(wnd));
    wnd.lpfnWndProc = WndProc;
    wnd.hInstance = myInstance;
    wnd.lpszClassName = hwndMainClass;
    wnd.hCursor = LoadCursor(NULL,IDC_ARROW);

    if (!RegisterClass(&wnd)) {
        fprintf(stderr,"RegisterClass() failed\n");
        return 1;
    }

    rect.top = 0;
    rect.left = 0;
    rect.right = 640;
    rect.bottom = 480;
    AdjustWindowRect(&rect,WS_OVERLAPPEDWINDOW,FALSE);

    hwndMain = CreateWindow(hwndMainClass,hwndMainTitle,
        hwndMainStyle=WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,CW_USEDEFAULT,
        rect.right - rect.left,rect.bottom - rect.top,
        NULL,NULL,
        myInstance,NULL);
    if (!hwndMain) {
        fprintf(stderr,"CreateWindow() failed\n");
        return 1;
    }

    if (!init_dx_primary_surface()) {
        fprintf(stderr,"Failed to init primary surface\n");
        return 1;
    }

    GetClientRect(hwndMain,&rect);
    if (!init_bitmap(rect.right,rect.bottom)) {
        fprintf(stderr,"nit_bitmap() failed for %ux%u\n",(unsigned int)rect.right,(unsigned int)rect.bottom);
        return 1;
    }
    if (lock_bitmap()) {
        render_pattern(dx_bitmap);
        unlock_bitmap();
    }

    ShowWindow(hwndMain,SW_SHOW);
    UpdateWindow(hwndMain);

    while (GetMessage(&msg,NULL,0,0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    free_dx_primary_surface();
    free_bitmap();
    if (ddraw != NULL) {
        ddraw->RestoreDisplayMode();
        ddraw->Release();
        ddraw = NULL;
    }

    if (menuDisplayModes != NULL) {
        DestroyMenu(menuDisplayModes);
        menuDisplayModes = NULL;
    }

    return 0;
}
예제 #5
0
static LRESULT CALLBACK WndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) {
    switch (uMsg) {
        case WM_CREATE:
            break;
        case WM_PAINT: {
            PAINTSTRUCT ps;
            BeginPaint(hwnd,&ps);
            EndPaint(hwnd,&ps);

            if (ddsurfacePrimary == NULL) {
                unlock_bitmap();
                free_bitmap();
                free_dx_primary_surface();
                init_dx_primary_surface();

                RECT rct;
                GetClientRect(hwndMain,&rct);

                if (!init_bitmap(rct.right,rct.bottom))
                    fprintf(stderr,"WARNING WM_RESIZE init_bitmap(%u,%u) failed\n",
                            (unsigned int)rct.right,(unsigned int)rct.bottom);

                if (lock_bitmap()) {
                    render_pattern(dx_bitmap);
                    unlock_bitmap();
                }
            }

            update_screen();
            } break;
        case WM_DISPLAYCHANGE: {
            announce_fmt = true;

            unlock_bitmap();
            free_bitmap();
            free_dx_primary_surface();
            init_dx_primary_surface();

            RECT rct;
            GetClientRect(hwndMain,&rct);

            if (!init_bitmap(rct.right,rct.bottom))
                fprintf(stderr,"WARNING WM_RESIZE init_bitmap(%u,%u) failed\n",
                        (unsigned int)rct.right,(unsigned int)rct.bottom);

            if (lock_bitmap()) {
                render_pattern(dx_bitmap);
                unlock_bitmap();
            }

            InvalidateRect(hwndMain,NULL,FALSE); // DWM compositor-based versions set WM_PAINT such that only the affected area will repaint
            } return DefWindowProc(hwnd,uMsg,wParam,lParam);
        case WM_SIZE:
            if (!init_bitmap(LOWORD(lParam),HIWORD(lParam)))
                fprintf(stderr,"WARNING WM_RESIZE init_bitmap(%u,%u) failed\n",
                    LOWORD(lParam),HIWORD(lParam));

            if (lock_bitmap()) {
                render_pattern(dx_bitmap);
                unlock_bitmap();
            }

            InvalidateRect(hwndMain,NULL,FALSE); // DWM compositor-based versions set WM_PAINT such that only the affected area will repaint
            break;
        case WM_RBUTTONUP:
            populateDisplayModes();
            if (menuDisplayModes != NULL) {
                POINT pt;

                GetCursorPos(&pt);
                TrackPopupMenu(menuDisplayModes,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RIGHTBUTTON,pt.x,pt.y,0,hwnd,NULL);
            }
            break;
        case WM_COMMAND:
            if (wParam >= 4000 && wParam < (WPARAM)(4000+displayModesCount)) {
                DDSURFACEDESC devmode = displayModes[wParam-4000];
                HRESULT hr;

                fprintf(stderr,"Setting display to %u x %u x %ubpp\n",
                    (unsigned int)devmode.dwWidth,
                    (unsigned int)devmode.dwHeight,
                    (unsigned int)devmode.ddpfPixelFormat.dwRGBBitCount);
                if ((hr=ddraw->SetDisplayMode(devmode.dwWidth,devmode.dwHeight,devmode.ddpfPixelFormat.dwRGBBitCount,devmode.dwRefreshRate,0)) != DD_OK)
                    fprintf(stderr,"Failed to set display mode HR=0x%08lx\n",hr);
                if (hr == DDERR_NOEXCLUSIVEMODE) {
                    // NTS: Windows 95/98/ME DirectX demands we enter Exclusive cooperative mode before it allows mode changes that change bit depth
                    fprintf(stderr,"Sorry, Windows demands we set the cooperative mode to Exclusive\n"); // Windows 9x/ME behavior for NORMAL cooperative mode DirectX apps
                    try_exclusive_mode();
                    if ((hr=ddraw->SetDisplayMode(devmode.dwWidth,devmode.dwHeight,devmode.ddpfPixelFormat.dwRGBBitCount,devmode.dwRefreshRate,0)) != DD_OK)
                        fprintf(stderr,"Failed to set display mode HR=0x%08lx\n",hr);
                }

                if (hr == DD_OK) {
                    if (is_exclusive_mode()) {
                        // NTS: When we're in Exclusive Fullscreen mode, Windows doesn't broadcast WM_DISPLAYCHANGE or WM_PAINT the way it normally does while we're active.
                        //      So for our display code to work we have to poke and prod the window manager and make our window fullscreen, with focus.
                        unlock_bitmap();
                        free_bitmap();
                        free_dx_primary_surface();
                        init_dx_primary_surface();

                        RECT rct;
                        GetClientRect(hwndMain,&rct);

                        if (!init_bitmap(rct.right,rct.bottom))
                            fprintf(stderr,"WARNING WM_RESIZE init_bitmap(%u,%u) failed\n",
                                    (unsigned int)rct.right,(unsigned int)rct.bottom);

                        if (lock_bitmap()) {
                            render_pattern(dx_bitmap);
                            unlock_bitmap();
                        }

                        InvalidateRect(hwndMain,NULL,FALSE); // DWM compositor-based versions set WM_PAINT such that only the affected area will repaint
                        try_exclusive_mode();
                    }
                    hasSetMode = true;
                }
            }
            else if (wParam == 5000) {
                try_exclusive_mode();
                update_screen();
            }
            else if (wParam == 5001) {
                leave_exclusive_mode();
            }
            else if (wParam == 5002) {
                leave_exclusive_mode();
                ddraw->RestoreDisplayMode();
            }
            else {
                return DefWindowProc(hwnd,uMsg,wParam,lParam);
            }
            break;
        case WM_KEYDOWN:
            switch (wParam) {
                case VK_ESCAPE:
                    PostMessage(hwnd,WM_CLOSE,0,0);
                    break;
                case VK_SPACE:
                    if ((++pattern) >= 2)
                        pattern = 0;

                    if (lock_bitmap()) {
                        render_pattern(dx_bitmap);
                        unlock_bitmap();
                    }

                    InvalidateRect(hwndMain,NULL,FALSE); // DWM compositor-based versions set WM_PAINT such that only the affected area will repaint
                    break;
            }
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hwnd,uMsg,wParam,lParam);
    }

    return 0;
}
예제 #6
0
void update_screen() {
    IDirectDrawSurface *dst;
    RECT dstRect;
    RECT srcRect;
    HRESULT hr;
    POINT pt;

    // NTS: dx_bitmap.is_valid() is not a valid test because base==canvas==NULL unless surface is locked
    if (ddsurfaceBMP == NULL) return;

    // NTS: We must provide a source rect, else Windows XP in 24bpp mode will conveniently choose to render the
    //      right half (where extra padding+junk exist) rather than from the left side. Provide a source rect
    //      to make it 100% clear which part of the surface we want blitted to screen.
    pt.x = pt.y = 0;
    ClientToScreen(hwndMain,&pt);
    GetClientRect(hwndMain,&dstRect);
    OffsetRect(&dstRect,pt.x,pt.y);
    srcRect.top = srcRect.left = 0;
    srcRect.right = dx_bitmap.width;
    srcRect.bottom = dx_bitmap.height;

    if (ddsurfaceGDI != NULL)
        dst = ddsurfaceGDI;
    else if (ddsurfacePrimary != NULL)
        dst = ddsurfacePrimary;
    else
        dst = NULL;

    if (dst != NULL)
        hr = dst->Blt(&dstRect,ddsurfaceBMP,&srcRect,0,NULL);
    else
        hr = DD_OK;

    if (hr == DDERR_SURFACELOST) {
        fprintf(stderr,"Whoops, the primary surface was lost.\n");
        if ((hr=dst->Restore()) != DD_OK) {
            fprintf(stderr,"Unable to restore surface hr=0x%08lx.\n",hr);
            unlock_bitmap();
            free_bitmap();
            free_dx_primary_surface();
            init_dx_primary_surface();

            RECT rct;
            GetClientRect(hwndMain,&rct);

            if (!init_bitmap(rct.right,rct.bottom))
                fprintf(stderr,"WARNING WM_RESIZE init_bitmap(%u,%u) failed\n",
                        (unsigned int)rct.right,(unsigned int)rct.bottom);

            if (lock_bitmap()) {
                render_pattern(dx_bitmap);
                unlock_bitmap();
            }

            InvalidateRect(hwndMain,NULL,FALSE); // DWM compositor-based versions set WM_PAINT such that only the affected area will repaint
        }
    }
    else if (hr != DD_OK) {
        fprintf(stderr,"DirectX blit failed, HR=0x%08lx\n",hr);
    }
}
예제 #7
0
/*
 * grow_fork()
 *
 * Try to add enough allocation blocks to 'fork'
 * so that it is 'ablock' allocation blocks long.
 */
static int grow_fork(struct hfs_fork *fork, int ablocks)
{
    struct hfs_cat_entry *entry = fork->entry;
    struct hfs_mdb *mdb = entry->mdb;
    struct hfs_extent *ext;
    int i, start, err;
    hfs_u16 need, len=0;
    hfs_u32 ablksz = mdb->alloc_blksz;
    hfs_u32 blocks, clumpablks;

    blocks = fork->psize;
    need = ablocks - blocks/ablksz;
    if (need < 1) { /* no need to grow the fork */
        return 0;
    }

    /* round up to clumpsize */
    if (entry->u.file.clumpablks) {
        clumpablks = entry->u.file.clumpablks;
    } else {
        clumpablks = mdb->clumpablks;
    }
    need = ((need + clumpablks - 1) / clumpablks) * clumpablks;

    /* find last extent record and try to extend it */
    if (!(ext = find_ext(fork, blocks/ablksz - 1))) {
        /* somehow we couldn't find the end of the file! */
        return -1;
    }

    /* determine which is the last used extent in the record */
    /* then try to allocate the blocks immediately following it */
    for (i=2; (i>=0) && !ext->length[i]; --i) {};
    if (i>=0) {
        /* try to extend the last extent */
        start = ext->block[i] + ext->length[i];

        err = 0;
        lock_bitmap(mdb);
        len = hfs_vbm_count_free(mdb, start);
        if (!len) {
            unlock_bitmap(mdb);
            goto more_extents;
        }
        if (need < len) {
            len = need;
        }
        err = hfs_set_vbm_bits(mdb, start, len);
        unlock_bitmap(mdb);
        if (err) {
            relse_ext(ext);
            return -1;
        }

        zero_blocks(mdb, start, len);

        ext->length[i] += len;
        ext->end += len;
        blocks = (fork->psize += len * ablksz);
        need -= len;
        update_ext(fork, ext);
    }

more_extents:
    /* add some more extents */
    while (need) {
        len = need;
        err = 0;
        lock_bitmap(mdb);
        start = hfs_vbm_search_free(mdb, &len);
        if (need < len) {
            len = need;
        }
        err = hfs_set_vbm_bits(mdb, start, len);
        unlock_bitmap(mdb);
        if (!len || err) {
            relse_ext(ext);
            return -1;
        }
        zero_blocks(mdb, start, len);

        /* determine which is the first free extent in the record */
        for (i=0; (i<3) && ext->length[i]; ++i) {};
        if (i < 3) {
            ext->block[i] = start;
            ext->length[i] = len;
            ext->end += len;
            update_ext(fork, ext);
        } else {
            if (!(ext = new_extent(fork, ext, blocks/ablksz,
                                   start, len, ablksz))) {
                lock_bitmap(mdb);
                hfs_clear_vbm_bits(mdb, start, len);
                unlock_bitmap(mdb);
                return -1;
            }
        }
        blocks = (fork->psize += len * ablksz);
        need -= len;
    }
    set_cache(fork, ext);
    relse_ext(ext);
    return 0;
}