Пример #1
0
/****************************************************************************
PARAMETERS:
dcache  - local cache for one directory
cache   - pointer to variable that holds list of found families

REMARKS:
Extracts information from dcache and translates it to cache.

This involves finding fonts with same family name and merging them into
one entry in cache.

Called exclusively by enumFontsInDir.
{secret}
****************************************************************************/
static void buildFontEnumCache(
    dirCache *dcache,
    fontEnumCache **cache)
{
    fontEnumCache  *ecache, *tail;
    size_t         i;
    fileCache      *f;

    if (dcache->filesCnt == 0)
        return;
    qsort(dcache->files, dcache->filesCnt, sizeof(fileCache),
          comparFileCacheByFamily);

    tail = ecache = NULL;
    for (i = 0, f = dcache->files; i < dcache->filesCnt; i++, f++) {
        /* new family: */
        if (tail == NULL ||
                    strcmp(tail->info.familyName, f->familyName) != 0) {
            if (tail == NULL) {
                if ((tail = ecache = PM_malloc(sizeof(fontEnumCache))) == NULL)
                    FATALERROR(grNoMem);
                }
            else {
                if ((tail->next = PM_malloc(sizeof(fontEnumCache))) == NULL)
                    FATALERROR(grNoMem);
                tail = tail->next;
                }
            tail->next = NULL;
            strcpy(tail->info.familyName, f->familyName);
            tail->info.fontLibType = f->fontLibType;
            tail->info.isFixed = f->isFixed;
            tail->info.regularFace[0] = '\0';
            tail->info.boldFace[0] = '\0';
            tail->info.italicFace[0] = '\0';
            tail->info.boldItalicFace[0] = '\0';
            }
        /* faces lookup: */
        if (!f->isBold && !f->isItalic)
            strcpy(tail->info.regularFace, f->fileName);
        else if (f->isBold && !f->isItalic)
            strcpy(tail->info.boldFace, f->fileName);
        else if (!f->isBold && f->isItalic)
            strcpy(tail->info.italicFace, f->fileName);
        else if (f->isBold && f->isItalic)
            strcpy(tail->info.boldItalicFace, f->fileName);
        }

    tail->next = *cache;
    *cache = ecache;
}
Пример #2
0
int main(void)
{
    PM_HWND hwndConsole;
    ulong   stateSize;
    void    *stateBuf;
    FILE    *f;

    /* Allocate a buffer to save console state and save the state */
    hwndConsole = PM_openConsole(0,0,0,0,0,true);
    stateSize = PM_getConsoleStateSize();
    if ((stateBuf = PM_malloc(stateSize)) == NULL) {
        PM_closeConsole(hwndConsole);
        printf("Unable to allocate console state buffer!\n");
        return -1;
        }
    PM_saveConsoleState(stateBuf,0);

    /* Restore the console state on exit */
    PM_restoreConsoleState(stateBuf,0);
    PM_closeConsole(hwndConsole);

    /* Write the saved console state buffer to disk */
    if ((f = fopen("/etc/pmsave.dat","wb")) == NULL)
        printf("Unable to open /etc/pmsave.dat for writing!\n");
    else {
        fwrite(&stateSize,1,sizeof(stateSize),f);
        fwrite(stateBuf,1,stateSize,f);
        fclose(f);
        printf("Console state successfully saved to /etc/pmsave.dat\n");
        }
    PM_free(stateBuf);
    return 0;
}
Пример #3
0
void * PMAPI PM_allocLockedMem(
    uint size,
    ulong *physAddr,
    ibool contiguous,
    ibool below16M)
{
    void*   linear;

    /* Allocate a physically contiguous buffer */
#ifdef  __QNXNTO__
    if ((linear = mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_PHYS|MAP_ANON,NOFD,0)) == MAP_FAILED) {
#else
    if ((linear = mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_ANON,NOFD,0)) == -1) {
#endif
        perror("PM_allocLockedMem mmap");
        return NULL;
        }
    *physAddr = PM_getPhysicalAddr(linear);
    return linear;
}

void PMAPI PM_freeLockedMem(
    void *p,
    uint size,
    ibool contiguous)
{
    if (munmap(p,size) == -1)
        perror("PM_freeLockedMem munmap");
}

/****************************************************************************
REMARKS:
Allocates a new block of pages for the page block manager.
****************************************************************************/
static pageblock *PM_addNewPageBlock(void)
{
    int         i,size;
    pageblock   *newBlock;
    char        *p,*next;

    /* Allocate memory for the new page block, and add to head of list */
    size = PAGES_PER_BLOCK * PM_PAGE_SIZE + (PM_PAGE_SIZE-1) + sizeof(pageblock);
    if ((newBlock = PM_malloc(size)) == NULL)
        return NULL;
    newBlock->prev = NULL;
    newBlock->next = pageBlocks;
    if (pageBlocks)
        pageBlocks->prev = newBlock;
    pageBlocks = newBlock;

    /* Initialise the page aligned free list for the page block */
    newBlock->freeCount = PAGES_PER_BLOCK;
    newBlock->freeList = p = (char*)(((ulong)(newBlock + 1) + (PM_PAGE_SIZE-1)) & ~(PM_PAGE_SIZE-1));
    newBlock->freeListStart = newBlock->freeList;
    newBlock->freeListEnd = p + (PAGES_PER_BLOCK-1) * PM_PAGE_SIZE;
    for (i = 0; i < PAGES_PER_BLOCK; i++,p = next)
        FREELIST_NEXT(p) = next = p + PM_PAGE_SIZE;
    FREELIST_NEXT(p - PM_PAGE_SIZE) = NULL;
    return newBlock;
}
Пример #4
0
int main(void)
{
    int     i;
    ulong   allocs;
    char    *p,*pa[MAXALLOC];
    PM_HWND hwndConsole;

    hwndConsole = PM_openConsole(0,0,0,0,0,true);
    for (allocs = i = 0; i < MAXALLOC; i++) {
        if ((pa[i] = PM_malloc(10*1024)) != 0) {    /* in 10k blocks    */
            p = pa[allocs];
            memset(p, 0, 10*1024); /* touch every byte              */
            *p = 'x';           /* do something, anything with      */
            p[1023] = 'y';      /* the allocated memory             */
            allocs++;
            printf("Allocated %lu bytes\r", 10*(allocs << 10));
            }
        else break;
        if (PM_kbhit() && (PM_getch() == 0x1B))
            break;
        }
    PM_closeConsole(hwndConsole);

    printf("\n\nAllocated total of %lu bytes\n", 10 * (allocs << 10));

    for (i = allocs-1; i >= 0; i--)
        PM_free(pa[i]);

    return 0;
}
Пример #5
0
     void * PMAPI PM_mallocShared(long size)
     {
     // TODO: This is used to allocate memory that is shared between process
     //       that all access the common SNAP drivers via a common display
     //       driver DLL. If your OS does not support shared memory (or if
     //       the display driver does not need to allocate shared memory
     //       for each process address space), this should just call PM_malloc.
     return PM_malloc(size);
 }
Пример #6
0
/****************************************************************************
REMARKS:
Allocate a block of (unnamed) shared memory.
****************************************************************************/
void * PMAPI PM_mallocShared(
    long size)
{
    /* TODO: This is used to allocate memory that is shared between process */
    /*       that all access the common Nucleus drivers via a common display */
    /*       driver DLL. If your OS does not support shared memory (or if */
    /*       the display driver does not need to allocate shared memory */
    /*       for each process address space), this should just call PM_malloc. */
    return PM_malloc(size);
}
Пример #7
0
/****************************************************************************
DESCRIPTION:
Copy a portion of a device context as a lightweight memory bitmap.

HEADER:
mgraph.h

PARAMETERS:
dc          - Device context to save from
left        - Left coordinate of bitmap to save
top         - Top coordinate of bitmap to save
right       - Right coordinate of bitmap to save
bottom      - Bottom coordinate of bitmap to save
savePalette - Save palette with bitmap.

RETURNS:
Pointer to allocated bitmap, NULL on error.

REMARKS:
This function copies a portion of a device context as a lightweight memory bitmap.
If this function fails (for instance if out of memory), it will return NULL and you
can get the error code from the MGL_result function. Otherwise this function will
return a pointer to a new lightweight bitmap containing the bitmap data.

Note that the source rectangle for the bitmap to be saved is not clipped to the
current clipping rectangle for the device context, but it is mapped to the current
viewport. If you specify dimensions that are larger than the current device context,
you will get garbage in the bitmap file as a result.

SEE ALSO:
MGL_loadBitmap, MGL_saveBitmapFromDC
****************************************************************************/
bitmap_t * MGLAPI MGL_getBitmapFromDC(
    MGLDC *dc,
    int left,
    int top,
    int right,
    int bottom,
    ibool savePalette)
{
    bitmap_t    *bitmap,bmh;
    long        size;
    int         palSize;

    /* Build the bitmap header and allocate memory for it */
    createBitmapHeader(dc,&left,&top,&right,&bottom,&bmh,&palSize);
    if (!savePalette && (dc->mi.modeFlags & MGL_IS_COLOR_INDEX))
        palSize = 0;
    size = sizeof(bitmap_t) + (long)bmh.bytesPerLine * bmh.height + palSize;
    if (dc->mi.bitsPerPixel >= 15)
        size += sizeof(pixel_format_t);
    if ((bitmap = PM_malloc(size)) == NULL) {
        __MGL_result = grNoMem;
        return NULL;
        }
    *bitmap = bmh;
    size = sizeof(bitmap_t);
    if (dc->mi.modeFlags & MGL_IS_COLOR_INDEX) {
        bitmap->pf = NULL;
        if (dc->mi.bitsPerPixel == 16) {
            bitmap->pf = (pixel_format_t*)((uchar*)bitmap + size);
            size += sizeof(pixel_format_t);
            *bitmap->pf = dc->pf;
            }
        if (savePalette) {
            bitmap->pal = (palette_t*)((uchar*)bitmap + size);
            size += palSize;
            memcpy(bitmap->pal,dc->colorTab,palSize);
            }
        else
            bitmap->pal = NULL;
        }
    else {
        bitmap->pf = (pixel_format_t*)((uchar*)bitmap + size);
        size += sizeof(pixel_format_t);
        *bitmap->pf = dc->pf;
        bitmap->pal = NULL;
        }
    bitmap->surface = (uchar*)bitmap + size;

    /* Now copy the bits from the device context into the bitmap */
    MAKE_HARDWARE_CURRENT(dc,true);
    dc->r.GetBitmapSys(bitmap->surface,bitmap->bytesPerLine,
        left,top,right-left,bottom-top,0,0,GA_REPLACE_MIX);
    RESTORE_HARDWARE(dc,true);
    return bitmap;
}
Пример #8
0
/****************************************************************************
DESCRIPTION:
Locates an open bitmap and loads it into memory from an open file.

HEADER:
mgraph.h

PARAMETERS:
f           - Open binary file to read data from
dwOffset    - Offset to start of bitmap in file
dwSize      - Size of the file
loadPalette - Should we load the palette values as well?

RETURNS:
Pointer to the loaded bitmap file

REMARKS:
This function is the same as MGL_loadBitmap, however it loads the file from a
previously open file. This allows you to create your own large files with
multiple files embedded in them.

SEE ALSO:
MGL_loadBitmap, MGL_loadBitmapIntoDC
****************************************************************************/
bitmap_t * MGLAPI MGL_loadBitmapExt(
    FILE *f,
    ulong dwOffset,
    ulong dwSize,
    ibool loadPalette)
{
    bitmap_t            bmh,*bitmap;
    palette_t           pal[256];       /* Temporary space for palette  */
    pixel_format_t      pf;
    long                size;
    int                 i,palSize;
    uchar               *p;
    ibool               isRLE;

    /* Open the bitmap header */
    if (!readBitmapHeaderExt(&bmh,pal,&palSize,&pf,f,dwOffset,loadPalette,&isRLE))
        return NULL;

    /* Allocate memory for the bitmap */
    if (!loadPalette && bmh.bitsPerPixel <= 8)
        palSize = 0;
    size = (long)bmh.bytesPerLine * bmh.height + palSize;
    if ((bitmap = PM_malloc(sizeof(bitmap_t)+size)) == NULL) {
        FATALERROR(grNoMem);
        return NULL;
        }
    *bitmap = bmh;

    size = sizeof(bitmap_t);
    if (bitmap->bitsPerPixel <= 8) {
        if (loadPalette) {
            bitmap->pal = (palette_t*)((uchar*)bitmap + size);
            memcpy(bitmap->pal,pal,palSize);
            }
        else
            bitmap->pal = NULL;
        bitmap->pf = NULL;
        }
    else {
        bitmap->pf = (pixel_format_t*)((uchar*)bitmap + size);
        *bitmap->pf = pf;
        bitmap->pal = NULL;
        }
    size += palSize;
    bitmap->surface = (uchar*)bitmap + size;

    /* Now read in the bits in the bitmap. We need to handle both cases
     * of bottom up and top down DIB's. We can also decode RLE bitmaps
     * (which are always bottom up DIB format) via MGL scratch buffer.
     */
    if (isRLE) {
        bufStart = (uchar*)_MGL_buf;
        bufSize = _MGL_bufSize;
        readChunk(f);
        gcount = gdata = 0;
        p = (uchar *)bitmap->surface + (long)bitmap->bytesPerLine * (bitmap->height-1);
        for (i = 0; i < bitmap->height; i++, p -= bitmap->bytesPerLine) {
            decodeScan(f,(uchar*)p,bitmap->bytesPerLine);
            }
        }
    else if (bitmap->height < 0) {
        bitmap->height = -bitmap->height;
        p = bitmap->surface;
        for (i = 0; i < bitmap->height; i++, p += bitmap->bytesPerLine) {
            __MGL_fread(p,1,bitmap->bytesPerLine,f);
            }
        }
    else {
        p = (uchar *)bitmap->surface + (long)bitmap->bytesPerLine * (bitmap->height-1);
        for (i = 0; i < bitmap->height; i++, p -= bitmap->bytesPerLine) {
            __MGL_fread(p,1,bitmap->bytesPerLine,f);
            }
        }
    (void)dwSize;
    return bitmap;
}
Пример #9
0
/****************************************************************************
DESCRIPTION:
Create a monochrome bitmap mask given a transparent color.

HEADER:
mgraph.h

PARAMETERS:
bitmap      - bitmap to build monochrome mask from
transparent - transparent color to mask out

RETURNS:
Pointer to allocated bitmap mask, or NULL on error.

REMARKS:
Attempts to build a monochrome bitmap mask that can be used to rasterize
transparent bitmaps. This is useful for devices that have hardware BitBlt
capabilities but lack hardware transparent BitBlt support. Everywhere the
transparent color is found, the mask will be 0, and everywhere else it will be 1.
Once you have created a monochrome bitmap mask, you can rasterize a transparent
bitmap by replacing all the transparent pixels in the original bitmap with 0's, and
then doing the following:

1. Set the foreground color to black and drawing the bitmap mask with
MGL_putBitmapMask. Everywhere that the bitmap has data a black
pixel will be used to 'punch' a hole in the display.

2. Use the MGL_bitBlt function to draw the
original bitmap on the display using the MGL_OR_MODE  write
mode. Everywhere that a pixel is transparent in the original source
bitmap, the destination will remain the same. Everywhere that a pixel is
non-transparent the pixel on the destination will be replaced with the
pixel in the source bitmap.

Note that only 8+ bits per pixel bitmaps are supported, and this function will fail on
lower color depths.

SEE ALSO:
MGL_transBltLin, MGL_putBitmapMask, MGL_bitBlt
****************************************************************************/
bitmap_t * MGLAPI MGL_buildMonoMask(
    bitmap_t *bitmap,
    color_t transparent)
{
    bitmap_t    *mask;
    int         i,bytes,last;
    long        bytesPerLine,size;
    uchar       *ps,*ms,*m,b;

    __MGL_result = grOK;
    if (bitmap->bitsPerPixel < 8) {
        __MGL_result = grInvalidBitmap;
        return NULL;
        }

    /* Allocate memory and build bitmap header information */
    bytesPerLine = (bitmap->width+7)/8;
    size = bytesPerLine * bitmap->height;
    if ((mask = PM_malloc(sizeof(bitmap_t)+size)) == NULL) {
        __MGL_result = grNoMem;
        return NULL;
        }
    mask->width = bitmap->width;
    mask->height = bitmap->height;
    mask->bitsPerPixel = 1;
    mask->bytesPerLine = bytesPerLine;
    mask->pf = NULL;
    mask->pal = NULL;
    mask->surface = (uchar*)mask + sizeof(bitmap_t);

    /* Now read the bits from the bitmap and build the mask */
    ps = bitmap->surface;
    ms = mask->surface;
    for (i = 0; i < bitmap->height; i++, ps += bitmap->bytesPerLine, ms += bytesPerLine) {
        bytes = bitmap->width / 8;
        last = bitmap->width - (bytes * 8);
        m = (uchar*)ms;
        if (bitmap->bitsPerPixel == 8) {
            uchar *p = (uchar*)ps;
            while (bytes--) {
                b = 0;
                if (p[0] != (uchar)transparent) b |= 0x80;
                if (p[1] != (uchar)transparent) b |= 0x40;
                if (p[2] != (uchar)transparent) b |= 0x20;
                if (p[3] != (uchar)transparent) b |= 0x10;
                if (p[4] != (uchar)transparent) b |= 0x08;
                if (p[5] != (uchar)transparent) b |= 0x04;
                if (p[6] != (uchar)transparent) b |= 0x02;
                if (p[7] != (uchar)transparent) b |= 0x01;
                *m++ = b;
                p += 8;
                }
            if (last) {
                b = 0;
                if (last >= 1 && p[0] != (uchar)transparent) b |= 0x80;
                if (last >= 2 && p[1] != (uchar)transparent) b |= 0x40;
                if (last >= 3 && p[2] != (uchar)transparent) b |= 0x20;
                if (last >= 4 && p[3] != (uchar)transparent) b |= 0x10;
                if (last >= 5 && p[4] != (uchar)transparent) b |= 0x08;
                if (last >= 6 && p[5] != (uchar)transparent) b |= 0x04;
                if (last >= 7 && p[6] != (uchar)transparent) b |= 0x02;
                *m = b;
                }
            }
        else if (bitmap->bitsPerPixel == 15 || bitmap->bitsPerPixel == 16) {
            ushort *p = (ushort*)ps;
            while (bytes--) {
                b = 0;
                if (p[0] != (ushort)transparent) b |= 0x80;
                if (p[1] != (ushort)transparent) b |= 0x40;
                if (p[2] != (ushort)transparent) b |= 0x20;
                if (p[3] != (ushort)transparent) b |= 0x10;
                if (p[4] != (ushort)transparent) b |= 0x08;
                if (p[5] != (ushort)transparent) b |= 0x04;
                if (p[6] != (ushort)transparent) b |= 0x02;
                if (p[7] != (ushort)transparent) b |= 0x01;
                *m++ = b;
                p += 8;
                }
            if (last) {
                b = 0;
                if (last >= 1 && p[0] != (ushort)transparent) b |= 0x80;
                if (last >= 2 && p[1] != (ushort)transparent) b |= 0x40;
                if (last >= 3 && p[2] != (ushort)transparent) b |= 0x20;
                if (last >= 4 && p[3] != (ushort)transparent) b |= 0x10;
                if (last >= 5 && p[4] != (ushort)transparent) b |= 0x08;
                if (last >= 6 && p[5] != (ushort)transparent) b |= 0x04;
                if (last >= 7 && p[6] != (ushort)transparent) b |= 0x02;
                *m = b;
                }
            }
        else if (bitmap->bitsPerPixel == 24) {
            uchar *p = (uchar*)ps;
            uchar t0 = (uchar)transparent;
            uchar t1 = (uchar)(transparent >> 8);
            uchar t2 = (uchar)(transparent >> 16);
            while (bytes--) {
                b = 0;
#define CHECK24(i) (p[(i*3)+0] != t0 || p[(i*3)+1] != t1 || p[(i*3)+2] != t2)
                if (CHECK24(0)) b |= 0x80;
                if (CHECK24(1)) b |= 0x40;
                if (CHECK24(2)) b |= 0x20;
                if (CHECK24(3)) b |= 0x10;
                if (CHECK24(4)) b |= 0x08;
                if (CHECK24(5)) b |= 0x04;
                if (CHECK24(6)) b |= 0x02;
                if (CHECK24(7)) b |= 0x01;
                *m++ = b;
                p += 24;
                }
            if (last) {
                b = 0;
                if (last >= 1 && CHECK24(0)) b |= 0x80;
                if (last >= 2 && CHECK24(1)) b |= 0x40;
                if (last >= 3 && CHECK24(2)) b |= 0x20;
                if (last >= 4 && CHECK24(3)) b |= 0x10;
                if (last >= 5 && CHECK24(4)) b |= 0x08;
                if (last >= 6 && CHECK24(5)) b |= 0x04;
                if (last >= 7 && CHECK24(6)) b |= 0x02;
                *m = b;
                }
#undef  CHECK24
            }
        else {
Пример #10
0
/****************************************************************************
DESCRIPTION:
Creates a new offscreen display device context.

HEADER:
mgraph.h

PARAMETERS:
dc      - MGL display or windowed device context to create offscreen DC from
width   - Width of the offscreen device context to create
height  - Height of the offscreen device context to create

RETURNS:
Pointer to the newly created offscreen device context, NULL if not valid.

REMARKS:
Creates a new offscreen display device context for rendering to offscreen
video memory when running in hardware accelerated video modes. You must
have already created a valid display device context before this function is
called, otherwise this function will return NULL. Also if the display device
does not support hardware accelerated offscreen display memory, this
function will also return NULL. Finally if there is no more available
offscreen display memory to fullfill the request, this function will fail.
See the MGL_result error code for more information if the function failed.

An offscreen device context can be used just like any other MGL device
context, so you can copy data around with MGL_bitBlt, or draw on the
device context using any of the MGL rendering functions. If you simply
want to store bitmaps in offscreen memory for fast blitting, you should
instead create the bitmaps as MGL buffers with the MGL_createBuffer function.
MGL buffers are similar to offscreen device contexts, except they can only
be used for blitting and cannot be used as a rendering target. MGL buffers
also use a lot less system memory resources than a full offscreen DC.

SEE ALSO:
MGL_createMemoryDC, MGL_createScrollingDisplayDC, MGL_createStereoDisplayDC,
MGL_createDisplayDC, MGL_destroyDC, MGL_createBuffer
****************************************************************************/
MGLDC * MGLAPI MGL_createOffscreenDC(
    MGLDC *dc,
    int width,
    int height)
{
    MGLDC   *offDC;
    MGLBUF  *buf;
    MGLDC   *oldDC = _MGL_dcPtr;

    /* Create an offscreen buffer for the DC */
    __MGL_result = grOK;
    if ((buf = MGL_createBuffer(dc,width,height,MGL_BUF_NOSYSMEM)) == NULL) {
        __MGL_result = grNoOffscreenMem;
        return NULL;
        }

    /* Now allocate memory for the device context */
    if ((offDC = _LST_newNode(sizeof(MGLDC))) == NULL) {
        FATALERROR(grNoMem);
        return NULL;
        }
    if (DEV.offDCList == NULL) {
        if ((DEV.offDCList = _LST_create()) == NULL) {
            FATALERROR(grNoMem);
            goto Error;
            }
        }

    /* Clone the original DC, but allocate a new color table and reset
     * many of the internal variables.
     */
    *offDC = *dc;
    memset(&offDC->wm,0,sizeof(offDC->wm));
    offDC->v->d.refCount++;
    offDC->deviceType = MGL_OFFSCREEN_DEVICE;
    offDC->mi.xRes = buf->width-1;
    offDC->mi.yRes = buf->height-1;
    offDC->bounds.left = 0;
    offDC->bounds.top = 0;
    offDC->bounds.right = buf->width;
    offDC->bounds.bottom = buf->height;
    offDC->visRectWin = offDC->visRectWM = offDC->size = offDC->bounds;
    offDC->mi.maxPage = 0;
    offDC->mi.bytesPerLine = buf->bytesPerLine;
    offDC->surface = buf->surface;
    offDC->offBuf = buf;
    offDC->clipRegionUser = NULL;
    offDC->visRegionWM = NULL;
    offDC->visRegionWin = NULL;
    offDC->clipRegionScreen = NULL;
    offDC->activeBuf = TO_BUF(buf);
    if ((offDC->colorTab = PM_malloc(sizeof(color_t) * 256)) == NULL) {
        FATALERROR(grNoMem);
        goto Error;
        }

    /* Set the default attributes for the device context and clear it */
    MGL_makeCurrentDC(offDC);
    MGL_defaultAttributes(offDC);
    MGL_setDefaultPalette(offDC);
    MGL_clearDevice();
    MGL_makeCurrentDC(oldDC);

    /* Add the new DC to the start of the DC chain */
    _LST_addToHead(DEV.offDCList,offDC);
    return offDC;

Error:
    if (buf)
        MGL_destroyBuffer(buf);
    if (DEV.offDCList && DEV.offDCList->count == 0) {
        _LST_destroy(DEV.offDCList,_LST_freeNode);
        DEV.offDCList = NULL;
        }
    _LST_freeNode(offDC);
    return NULL;
}
Пример #11
0
/****************************************************************************
REMARKS:
Does the hard work to create the actual display device context.
****************************************************************************/
static MGLDC * _MGL_createDisplayDC(
    int mode,
    int virtualX,
    int virtualY,
    int numBuffers,
    ibool stereo,
    int refreshRate)
{
    MGLDC       *dc;
    driverent   *entry;
    modeent     *me = &DEV.availableModes[mode];
    PM_HWND     hwndConsole = (PM_HWND)NULL;

    /* Check if the mode is currently available */
    __MGL_result = grOK;
    if (mode >= DEV.numModes || DEV.availableModes[mode].driver == 0xFF) {
        SETERROR(grInvalidMode);
        return NULL;
        }
    _MGL_destroyCurrentMode();

    /* Allocate memory for the new DC */
    if ((dc = _LST_newNode(sizeof(MGLDC))) == NULL) {
        FATALERROR(grNoMem);
        return NULL;
        }

    /* The display device list is currently empty, so create the new
     * list and start the specified graphics mode
     */
    if ((DEV.dispDCList = _LST_create()) == NULL) {
        FATALERROR(grNoMem);
        goto Error;
        }

    /* Open a new fullscreen console for the mode, and save it's state */
    DEV.stateBuf = NULL;
    if (_MGL_consoleSupport && (GET_CURRENT_DEVICE() == 0)) {
        hwndConsole = PM_openConsole((PM_HWND)_MGL_hwndFullScreen,GET_CURRENT_DEVICE(),me->xRes,me->yRes,me->bits,true);
        if ((DEV.stateBuf = PM_malloc(PM_getConsoleStateSize())) == NULL) {
            FATALERROR(grNoMem);
            goto Error;
            }
        PM_saveConsoleState(DEV.stateBuf,hwndConsole);
        }

    /* Now intialise the driver */
    entry = &DEV.driverTable[me->driver];
    if (!_MGL_initDC(dc,entry,me,(MGL_HWND)hwndConsole,virtualX,virtualY,numBuffers,stereo,refreshRate))
        goto Error;

    /* Set the suspend application callback for the console */
    PM_setSuspendAppCallback(_MGL_suspendAppProc);

    /* Set up the mouse cursor */
    if (_MGL_consoleSupport) {
        _MS_setDisplayDC(dc);
        MS_setCursor(MGL_DEF_CURSOR);
        MS_moveTo(dc->mi.xRes/2,dc->mi.yRes/2);
        }

    /* Now clear the device page */
    MGL_makeCurrentDC(dc);
    MGL_clearDevice();

    /* And clear the event queue of any extraneous events */
    if (_MGL_consoleSupport) {
        EVT_flush(EVT_EVERYEVT);
    }

    /* Add the new DC to the start of the DC chain */
    RESET_DEFAULT_CW();
    _LST_addToHead(DEV.dispDCList,dc);
    return dc;

Error:
    if (hwndConsole) {
        if (DEV.stateBuf) {
            PM_restoreConsoleState(DEV.stateBuf,hwndConsole);
            PM_free(DEV.stateBuf);
            DEV.stateBuf = NULL;
            }
        PM_closeConsole(hwndConsole);
        }
    DEV.fullScreen = false;
    if (DEV.dispDCList && DEV.dispDCList->count == 0) {
        _LST_destroy(DEV.dispDCList,_LST_freeNode);
        DEV.dispDCList = NULL;
        }
    _LST_freeNode(dc);
    return NULL;
}
Пример #12
0
/****************************************************************************
PARAMETERS:
path        - directory with font file
filename    - filename of the font file
cache       - local cache for one directory

REMARKS:
Updates cache entry for given font file. If such file is not in the
cache, loads it with MGL_openFontLib and extracts information about font
library type, family and face from it.

A font is marked as bold if its name ends with " Bold", as italic if it ends
with " Italic". Suffixes are cumulative. Family name is face name with
recognized suffixes stripped off. For example, cache entry for font
"Arial Bold Italic" will read "family is Arial, face is bold and italic".
{secret}
****************************************************************************/
static void enumFontFile(
    const char *path,
    const char *filename,
    dirCache *cache)
{
    char          fullname[PM_MAX_PATH];
    font_lib_t    *fontLib;
    fileCache     *entry;
    ibool         isNewer;
    ibool         foundSuffix;
#if 0 // TODO: missing PM_getFileTime under Unix and DOS
    PM_time       time;
    long          ytimef, ytimec;
#endif
    char          *buf;
    size_t        buflen;

    strcpy(fullname, path);
    PM_backslash(fullname);
    strcat(fullname, filename);

    /* Try to find entry in cache: */
    entry = (fileCache*) bsearch(filename, cache->files, cache->filesCnt,
                                    sizeof(fileCache), searchFileCache);

    isNewer = (entry == NULL);

#if 0 // TODO: missing PM_getFileTime under Unix and DOS
    if (!isNewer && PM_getFileTime(fullname, true, &time)) {
        ytimef = time.sec + 60 * (time.min + 60 * (time.hour + 24 * (time.day +
                    31 * time.mon)));
        ytimec = cache->timestamp.sec + 60 * (cache->timestamp.min + 60 * (
                    cache->timestamp.hour + 24 * (cache->timestamp.day +
                    31 * cache->timestamp.mon)));
        isNewer = time.year > cache->timestamp.year ||
                    (time.year == cache->timestamp.year && ytimef > ytimec);
        }
#endif

    if (!isNewer) {
        cache->validCnt++;
        entry->exists = true;
        return;
        }

    /* Nothing in cache, we have to open the font: */
    fontLib = MGL_openFontLib(fullname);
    if (fontLib == NULL)
        return;

    if (entry == NULL) {
        if (cache->filesCnt % CACHE_BLOCK_SIZE == 0) {
            cache->filesBlocks++;
            cache->files = PM_realloc(cache->files,
                    sizeof(fileCache) * cache->filesBlocks * CACHE_BLOCK_SIZE);
            }
        entry = cache->files + cache->filesCnt;
        cache->filesCnt++;
        }
    else {
        PM_free(entry->fileName);
        PM_free(entry->familyName);
        }

    /* Try to determine family name and face type from facename: */
    if ((entry->fileName = PM_malloc(strlen(filename) + 1)) == NULL)
        FATALERROR(grNoMem);
    strcpy(entry->fileName, filename);
    entry->fontLibType = fontLib->fontLibType;
    buflen = strlen(fontLib->name);
    if ((buf = PM_malloc(buflen + 1)) == NULL)
        FATALERROR(grNoMem);
    strcpy(buf, fontLib->name);
    entry->isBold = entry->isItalic = false;
    do {
        foundSuffix = false;
        if (buflen >= 5 && strcmp(buf + buflen - 5, " Bold") == 0) {
            foundSuffix = true;
            entry->isBold = true;
            buf[buflen - 5] = '\0';
            buflen -= 5;
            }
        if (buflen >= 7 && strcmp(buf + buflen - 7, " Italic") == 0) {
            foundSuffix = true;
            entry->isItalic = true;
            buf[buflen - 7] = '\0';
            buflen -= 7;
            }
        } while (buflen > 0 && foundSuffix);
    if (buflen == 0) {
        if ((entry->familyName = PM_malloc(strlen(filename) + 1)) == NULL)
            FATALERROR(grNoMem);
        strcpy(entry->familyName, filename);
        }
    else {
        if ((entry->familyName = PM_malloc(strlen(buf) + 1)) == NULL)
            FATALERROR(grNoMem);
        strcpy(entry->familyName, buf);
        }
    PM_free(buf);

    /* Check if the font is fixed width or proportional. In absence of better
       method, we do it by comparing average and maximum character width: */
    entry->isFixed = fontIsFixed(fontLib);

    MGL_closeFontLib(fontLib);

    cache->validCnt++;
    entry->exists = true;
}
Пример #13
0
/****************************************************************************
REMARKS:
VDD implementation of the ANSI C fopen function.
****************************************************************************/
FILE * fopen(
    const char *filename,
    const char *mode)
{
    FILE    *f = PM_malloc(sizeof(FILE));
    long    oldpos;
    ULONG   rc, ulAction;
    ULONG   omode, oflags;

    if (f != NULL) {
	f->offset = 0;
	f->text = (mode[1] == 't' || mode[2] == 't');
	f->writemode = (mode[0] == 'w') || (mode[0] == 'a');
	f->unputc = EOF;
	f->endp = f->buf + sizeof(f->buf);
	f->curp = f->startp = f->buf;

	if (mode[0] == 'r') {
	    #ifdef __OS2_VDD__
	    omode  = VDHOPEN_ACCESS_READONLY | VDHOPEN_SHARE_DENYNONE;
	    oflags = VDHOPEN_ACTION_OPEN_IF_EXISTS | VDHOPEN_ACTION_FAIL_IF_NEW;
	    #else
	    omode  = OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE;
	    oflags = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
	    #endif
	    }
	else if (mode[0] == 'w') {
	    #ifdef __OS2_VDD__
	    omode  = VDHOPEN_ACCESS_WRITEONLY | VDHOPEN_SHARE_DENYWRITE;
	    oflags = VDHOPEN_ACTION_REPLACE_IF_EXISTS | VDHOPEN_ACTION_CREATE_IF_NEW;
	    #else
	    omode  = OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYWRITE;
	    oflags = OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
	    #endif
	    }
	else {
	    #ifdef __OS2_VDD__
	    omode  = VDHOPEN_ACCESS_READWRITE | VDHOPEN_SHARE_DENYWRITE;
	    oflags = VDHOPEN_ACTION_OPEN_IF_EXISTS | VDHOPEN_ACTION_CREATE_IF_NEW;
	    #else
	    omode  = OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYWRITE;
	    oflags = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
	    #endif
	    }
	rc = _OS2Open((PSZ)filename, (PHFILE)&f->handle, &ulAction, 0, VDHOPEN_FILE_NORMAL, oflags, omode, NULL);
	if (rc != 0) {
	    PM_free(f);
	    return NULL;
	    }

	#ifdef __OS2_VDD__
	f->filesize = VDHSeek((HFILE)f->handle, 0, VDHSK_END_OF_FILE);
	#else
	rc = DosSetFilePtr((HFILE)f->handle, 0, FILE_END, &f->filesize);
	#endif

	if (mode[0] == 'a')
	    fseek(f,0,2);
    }
    return f;
}
Пример #14
0
void * PMAPI PM_mallocShared(long size)
{
    return PM_malloc(size);
}
Пример #15
0
static void InitPMCode(void)
/****************************************************************************
*
* Function:     InitPMCode  - 32 bit protected mode version
*
* Description:  Finds the address of and relocates the protected mode
*               code block from the VBE 2.0 into a local memory block. The
*               memory block is allocated with malloc() and must be freed
*               with VBE_freePMCode() after graphics processing is complete.
*
*               Note that this buffer _must_ be recopied after each mode set,
*               as the routines will change depending on the underlying
*               video mode.
*
****************************************************************************/
{
    RMREGS      regs;
    RMSREGS     sregs;
    uchar       *code;
    int         pmLen;

    if (!state->pmInfo && state->VBEVersion >= 0x200) {
	regs.x.ax = 0x4F0A;
	regs.x.bx = 0;
	PM_int86x(0x10,&regs,&regs,&sregs);
	if (regs.x.ax != VBE_SUCCESS)
	    return;
	if (VBE_shared)
	    state->pmInfo = PM_mallocShared(regs.x.cx);
	else
	    state->pmInfo = PM_malloc(regs.x.cx);
	if (state->pmInfo == NULL)
	    return;
	state->pmInfo32 = state->pmInfo;
	pmLen = regs.x.cx;

	/* Relocate the block into our local data segment */
	code = PM_mapRealPointer(sregs.es,regs.x.di);
	memcpy(state->pmInfo,code,pmLen);

	/* Now do a sanity check on the information we recieve to ensure
	 * that is is correct. Some BIOS return totally bogus information
	 * in here (Matrox is one)! Under DOS this works OK, but under OS/2
	 * we are screwed.
	 */
	if (state->pmInfo->setWindow >= pmLen ||
	    state->pmInfo->setDisplayStart >= pmLen ||
	    state->pmInfo->setPalette >= pmLen ||
	    state->pmInfo->IOPrivInfo >= pmLen) {
	    if (VBE_shared)
		PM_freeShared(state->pmInfo);
	    else
		PM_free(state->pmInfo);
	    state->pmInfo32 = state->pmInfo = NULL;
	    return;
	    }

	/* Read the IO priveledge info and determine if we need to
	 * pass a selector to MMIO registers to the bank switch code.
	 * Since we no longer support selector allocation, we no longer
	 * support this mechanism so we disable the protected mode
	 * interface in this case.
	 */
	if (state->pmInfo->IOPrivInfo && !state->MMIOSel) {
	    ushort *p = (ushort*)((uchar*)state->pmInfo + state->pmInfo->IOPrivInfo);
	    while (*p != 0xFFFF)
		p++;
	    p++;
	    if (*p != 0xFFFF)
		VBE_freePMCode();
	    }
	}
}
Пример #16
0
/****************************************************************************
REMARKS:
VxD implementation of the ANSI C fopen function.
****************************************************************************/
FILE * fopen(
    const char *filename,
    const char *mode)
{
    FILE    *f = PM_malloc(sizeof(FILE));
    long    oldpos;

    if (f) {
	f->offset = 0;
	f->text = (mode[1] == 't' || mode[2] == 't');
	f->writemode = (mode[0] == 'w') || (mode[0] == 'a');
	if (initComplete) {
	    WORD    omode,error;
	    BYTE    action;

	    if (mode[0] == 'r') {
		omode = OPEN_ACCESS_READONLY | OPEN_SHARE_COMPATIBLE;
		action = ACTION_IFEXISTS_OPEN | ACTION_IFNOTEXISTS_FAIL;
		}
	    else if (mode[0] == 'w') {
		omode = OPEN_ACCESS_WRITEONLY | OPEN_SHARE_COMPATIBLE;
		action = ACTION_IFEXISTS_TRUNCATE | ACTION_IFNOTEXISTS_CREATE;
		}
	    else {
		omode = OPEN_ACCESS_READWRITE | OPEN_SHARE_COMPATIBLE;
		action = ACTION_IFEXISTS_OPEN | ACTION_IFNOTEXISTS_CREATE;
		}
	    f->handle = (int)R0_OpenCreateFile(false,(char*)filename,omode,ATTR_NORMAL,action,0,&error,&action);
	    if (f->handle == 0) {
		PM_free(f);
		return NULL;
		}
	    f->filesize = R0_GetFileSize((HANDLE)f->handle,&error);
	    if (mode[0] == 'a')
		fseek(f,0,2);
	    }
	else {
	    int oflag,pmode;

	    if (mode[0] == 'r') {
		pmode = _S_IREAD;
		oflag = _O_RDONLY;
		}
	    else if (mode[0] == 'w') {
		pmode = _S_IWRITE;
		oflag = _O_WRONLY | _O_CREAT | _O_TRUNC;
		}
	    else {
		pmode = _S_IWRITE;
		oflag = _O_RDWR | _O_CREAT | _O_APPEND;
		}
	    if (f->text)
		oflag |= _O_TEXT;
	    else
		oflag |= _O_BINARY;
	    if ((f->handle = i_open(filename,oflag,pmode)) == -1) {
		PM_free(f);
		return NULL;
		}
	    oldpos = i_lseek(f->handle,0,1);
	    f->filesize = i_lseek(f->handle,0,2);
	    i_lseek(f->handle,oldpos,0);
	    }
	}
    return f;
}
Пример #17
0
/****************************************************************************
DESCRIPTION:
Returns the mask indicating what joystick axes are attached.

HEADER:
event.h

REMARKS:
This function is used to detect the attached joysticks, and determine
what axes are present and functioning. This function will re-detect any
attached joysticks when it is called, so if the user forgot to attach
the joystick when the application started, you can call this function to
re-detect any newly attached joysticks.

SEE ALSO:
EVT_joySetLowerRight, EVT_joySetCenter, EVT_joyIsPresent
****************************************************************************/
int EVTAPI EVT_joyIsPresent(void)
{
    static int      mask = 0;
    int             i;
    char            *tmp, name0[128], name1[128];
    static ibool    inited = false;

    if (inited)
        return mask;
    memset(EVT.joyMin,0,sizeof(EVT.joyMin));
    memset(EVT.joyCenter,0,sizeof(EVT.joyCenter));
    memset(EVT.joyMax,0,sizeof(EVT.joyMax));
    memset(EVT.joyPrev,0,sizeof(EVT.joyPrev));
    EVT.joyButState = 0;
    if ((tmp = getenv(ENV_JOYDEV0)) != NULL)
        strcpy(joystick0_dev,tmp);
    if ((tmp = getenv(ENV_JOYDEV1)) != NULL)
        strcpy(joystick1_dev,tmp);
    if ((joystick0_fd = open(joystick0_dev, O_RDONLY)) < 0)
        joystick0_fd = 0;
    if ((joystick1_fd = open(joystick1_dev, O_RDONLY)) < 0)
        joystick1_fd = 0;
    if (!joystick0_fd && !joystick1_fd) // No joysticks detected
        return 0;
    inited = true;
    if (ioctl(joystick0_fd ? joystick0_fd : joystick1_fd, JSIOCGVERSION, &js_version) < 0)
        return 0;

    /* Initialise joystick 0 */
    if (joystick0_fd) {
        ioctl(joystick0_fd, JSIOCGNAME(sizeof(name0)), name0);
        if (js_version & ~0xffff) {
            struct js_event js;

            ioctl(joystick0_fd, JSIOCGAXES, &js0_axes);
            ioctl(joystick0_fd, JSIOCGBUTTONS, &js0_buttons);
            axis0 = PM_calloc((int)js0_axes, sizeof(short));
            buts0 = PM_malloc((int)js0_buttons);
            /* Read the initial events */
            while(dataReady(joystick0_fd)
                  && read(joystick0_fd, &js, sizeof(struct js_event)) == sizeof(struct js_event)
                  && (js.type & JS_EVENT_INIT)
                  ) {
                if (js.type & JS_EVENT_BUTTON)
                    buts0[js.number] = js.value;
                else if (js.type & JS_EVENT_AXIS)
                    axis0[js.number] = scaleJoyAxis(js.value,js.number);
                }
            }
        else {
            js0_axes = 2;
            js0_buttons = 2;
            axis0 = PM_calloc((int)js0_axes, sizeof(short));
            buts0 = PM_malloc((int)js0_buttons);
            }
        }

    /* Initialise joystick 1 */
    if (joystick1_fd) {
        ioctl(joystick1_fd, JSIOCGNAME(sizeof(name1)), name1);
        if (js_version & ~0xffff) {
            struct js_event js;

            ioctl(joystick1_fd, JSIOCGAXES, &js1_axes);
            ioctl(joystick1_fd, JSIOCGBUTTONS, &js1_buttons);
            axis1 = PM_calloc((int)js1_axes, sizeof(short));
            buts1 = PM_malloc((int)js1_buttons);
            /* Read the initial events */
            while(dataReady(joystick1_fd)
                  && read(joystick1_fd, &js, sizeof(struct js_event))==sizeof(struct js_event)
                  && (js.type & JS_EVENT_INIT)
                  ) {
                if (js.type & JS_EVENT_BUTTON)
                    buts1[js.number] = js.value;
                else if (js.type & JS_EVENT_AXIS)
                    axis1[js.number] = scaleJoyAxis(js.value,js.number<<2);
                }
            }
        else {
            js1_axes = 2;
            js1_buttons = 2;
            axis1 = PM_calloc((int)js1_axes, sizeof(short));
            buts1 = PM_malloc((int)js1_buttons);
            }
        }

#ifdef  CHECKED
    fprintf(stderr,"Using joystick driver version %d.%d.%d\n",
            js_version >> 16, (js_version >> 8) & 0xff, js_version & 0xff);
    if (joystick0_fd)
        fprintf(stderr,"Joystick 1 (%s): %s\n", joystick0_dev, name0);
    if (joystick1_fd)
        fprintf(stderr,"Joystick 2 (%s): %s\n", joystick1_dev, name1);
#endif
    mask = _EVT_readJoyAxis(EVT_JOY_AXIS_ALL,EVT.joyCenter);
    if (mask) {
        for (i = 0; i < JOY_NUM_AXES; i++)
            EVT.joyMax[i] = EVT.joyCenter[i]*2;
        }
    return mask;
}
Пример #18
0
/****************************************************************************
DESCRIPTION:
Locates the specified bitmap file and loads it into a device context.

HEADER:
mgraph.h

PARAMETERS:
dc          - Device context to load bitmap into
f           - Pointer to opened bitmap file
dwSize      - Size of the bitmap file
dwOffset    - Offset into the file
dstLeft     - Left coordinate to place bitmap at
dstTop      - Top coordinate to place bitmap at
loadPalette - Should we load the palette values as well?

RETURNS:
True if the bitmap was successfully loaded.

REMARKS:
This function is the same as MGL_loadBitmapIntoDC, however it works with a
previously opened file. This allows you to create your own large files with
multiple files embedded in them.

SEE ALSO:
MGL_loadBitmapIntoDC
****************************************************************************/
ibool MGLAPI MGL_loadBitmapIntoDCExt(
    MGLDC *dc,
    FILE *f,
    ulong dwOffset,
    ulong dwSize,
    int dstLeft,
    int dstTop,
    ibool loadPalette)
{
    bitmap_t            bmh;
    palette_t           pal[256];         /* Temporary space for palette    */
    pixel_format_t      pf;
    int                 i,palSize,height;
    ibool               oldCheckId,isRLE;

    /* Read bitmap header */
    if (!readBitmapHeaderExt(&bmh,pal,&palSize,&pf,f,dwOffset,loadPalette,&isRLE))
        return false;

    /* Allocate a temporary bitmap to convert the scanlines */
    bmh.pal = pal;
    bmh.pf = &pf;
    if ((bmh.surface = PM_malloc(bmh.bytesPerLine)) == NULL) {
        FATALERROR(grNoMem);
        return false;
        }
    oldCheckId = MGL_checkIdentityPalette(false);

    /* Store the palette in the destination DC */
    if (loadPalette && (bmh.bitsPerPixel == 4 || bmh.bitsPerPixel == 8)) {
        MGL_setPalette(dc,pal,palSize / sizeof(palette_t),0);
        if (MGL_getVisualPage(dc) == MGL_getActivePage(dc))
            MGL_realizePalette(dc,palSize / sizeof(palette_t),0,false);
        }
    else if (loadPalette && ((dc->mi.modeFlags & MGL_IS_COLOR_INDEX) && bmh.bitsPerPixel > 8)) {
        MGL_getHalfTonePalette(pal);
        MGL_setPalette(dc,pal,MGL_getPaletteSize(dc),0);
        if (MGL_getVisualPage(dc) == MGL_getActivePage(dc))
            MGL_realizePalette(dc,MGL_getPaletteSize(dc),0,false);
        }

    /* Now read in the bits in the bitmap, by reading the data a scanline
     * at a time into our temporary memory DC, and then blting this to
     * the destination DC. We need to handle both cases of bottom up and
     * top down DIB's, plus RLE decoding.
     */
    height = bmh.height;
    if (isRLE) {
        /* Decode RLE bottom up DIB via MGL scratch buffer */
        bufStart = (uchar*)_MGL_buf;
        bufSize = _MGL_bufSize;
        readChunk(f);
        gcount = gdata = 0;
        bmh.height = 1;
        for (i = height-1; i >= 0; i--) {
            decodeScan(f,bmh.surface,bmh.bytesPerLine);
            MGL_putBitmap(dc,dstLeft,dstTop+i,&bmh,MGL_REPLACE_MODE);
            }
        }
    else if (height < 0) {
        /* Top down DIB */
        height = -bmh.height;
        bmh.height = 1;
        for (i = 0; i < height; i++) {
            __MGL_fread(bmh.surface,1,bmh.bytesPerLine,f);
            MGL_putBitmap(dc,dstLeft,dstTop+i,&bmh,MGL_REPLACE_MODE);
            }
        }
    else {
        /* Bottom up DIB */
        bmh.height = 1;
        for (i = height-1; i >= 0; i--) {
            __MGL_fread(bmh.surface,1,bmh.bytesPerLine,f);
            MGL_putBitmap(dc,dstLeft,dstTop+i,&bmh,MGL_REPLACE_MODE);
            }
        }
    PM_free(bmh.surface);
    MGL_checkIdentityPalette(oldCheckId);
    (void)dwSize;
    return true;
}
Пример #19
0
void * MGLAPI  XWINDC_createInstance(void)
{
    return PM_malloc(sizeof(XWINDC_data));
}
Пример #20
0
/****************************************************************************
PARAMETERS:
dir   - path to look for fntcache.inf in
cache - cache structure to save loaded data to

REMARKS:
Initializes dirCache structure and tries to load fntcache.inf file from
given directory. Silently fails if such file does not exist.

fntcache.inf is text file in the following format: first line contains
number of entries in decimal format, which indicates the number of file lines
to follow. Each file line contains three column delimined by '\t'. Font file
name is in the first column. Second column has fixed "T-F-B-I" format where
T is '0', '1' or '2' (as numerical values of MGL_fontLibType are), F is
'f' for fixed size fonts and 'p' for proportional, B is
'b' for bold face and 'n' otherwise and I is 'i' for italic face and 'n'
otherwise. Third column contains family name.

The cache is sorted alphabetically by file name.

Example file:
9
1979rg__.ttf    1-p-n-n 1979
1stgrade.ttf    1-p-n-n FirstGrader-Normal
39smooth.ttf    1-p-n-n 39 Smooth
7hours.ttf      1-p-n-n 7 hours
Scot000.ttf     1-p-n-n Scott
verdana.ttf     1-p-n-n Verdana
verdanab.ttf    1-p-b-n Verdana
verdanai.ttf    1-p-n-i Verdana
verdanaz.ttf    1-p-b-i Verdana
{secret}
****************************************************************************/
static void loadFontCache(
    const char *dir,
    dirCache *cache)
{
    char       filename[PM_MAX_PATH];
    char       buf[CACHE_LINE_SIZE];
    char       *c1, *c2;
    char       bufType, bufFixed, bufBold, bufItalic;
    fileCache  *file;
    FILE       *f;
    size_t     i;

    /* empty cache: */
    cache->filesCnt = 0;
    cache->validCnt = 0;
    cache->filesBlocks = 0;
    cache->files = NULL;

    /* try to load fonts cache file from directory, silently fail
       if it doesn't exist: */
    strcpy(filename, dir);
    PM_backslash(filename);
    strcat(filename, CACHE_FILE);
    f = __MGL_fopen(filename, "rt");
    if (f == NULL)
        return;
#if 0 // TODO: missing PM_getFileTime under Unix and DOS
    PM_getFileTime(filename, true, &cache->timestamp);
#endif
    if (fgets(buf, CACHE_LINE_SIZE, f) == NULL) {
        __MGL_fclose(f);
        return;
        }

    /* get number of items in the cache:  */
    if (sscanf(buf, "%li", &cache->filesCnt) != 1 ||
        cache->filesCnt == 0) {
        __MGL_fclose(f);
        return;
        }

    cache->filesBlocks = ((cache->filesCnt - 1) / CACHE_BLOCK_SIZE) + 1;
    cache->files =
        PM_malloc(sizeof(fileCache) * cache->filesBlocks * CACHE_BLOCK_SIZE);
    if (cache->files == NULL)
        FATALERROR(grNoMem);

    /* read entries. Each font file has one entry, there's one entry per
       line. The cache is sorted alphabetically by filename. */
    for (i = 0; i < cache->filesCnt; i++) {
        file = cache->files + i;
        file->exists = false;
        if (fgets(buf, CACHE_LINE_SIZE, f) == NULL) {
            cache->filesCnt = i;
            __MGL_fclose(f);
            return;
            }

        c1 = buf;
        for (c2 = c1; *c2 != '\0' && *c2 != '\t'; c2++) {}
        *c2 = '\0';
        if ((file->fileName = PM_malloc(strlen(c1) + 1)) == NULL)
            FATALERROR(grNoMem);
        strcpy(file->fileName, c1);

        c1 = c2 + 1;
        for (c2 = c1; *c2 != '\0' && *c2 != '\t'; c2++) {}
        *c2 = '\0';
        if (sscanf(c1, "%c-%c-%c-%c",
                   &bufType, &bufFixed, &bufBold, &bufItalic) != 4)
            continue;
        file->isBold = (bufBold == 'b');
        file->isItalic = (bufItalic == 'i');
        file->isFixed = (bufFixed == 'f');
        file->fontLibType = bufType - '0';

        c1 = c2 + 1;
        for (c2 = c1; *c2 != '\0'; c2++)
            if (*c2 == '\n' || *c2 == '\r') *c2 = '\0';
        if ((file->familyName = PM_malloc(strlen(c1) + 1)) == NULL)
            FATALERROR(grNoMem);
        strcpy(file->familyName, c1);
        }
    __MGL_fclose(f);
}