⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cursor.c

📁 在ADS环境下MiniGUI的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
** $Id: cursor.c,v 1.55 2004/04/16 08:39:36 weiym Exp $
**
** cursor.c: the Cursor Support module of MiniGUI.
**
** Copyright (C) 2003 Feynman Software.
** Copyright (C) 1999 ~ 2002 Wei Yongming.
**
** Current maintainer: Wei Yongming.
**
** Create date: 1999.01.06
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/


#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include "common.h"
#include "minigui.h"
#include "gdi.h"
#include "window.h"
#include "cliprect.h"
#include "internals.h"
#include "ctrlclass.h"
#include "gal.h"
#include "dc.h"
#include "memops.h"
#include "inline.h"
#include "gal.h"
#include "cursor.h"
#include "ial.h"
#include "readbmp.h"
#include "misc.h"
#include "cursor.h"
#include "sysres.h"

// mutex ensuring exclusive access to mouse.
pthread_mutex_t __mg_mouselock;

static int curx, cury;
static int oldx = -1, oldy;

static RECT cliprc = { 0, 0, 0, 0};

#ifdef _CURSOR_SUPPORT
 
static PCURSOR SysCursor [MAX_SYSCURSORINDEX + 1];
static HCURSOR def_cursor;
static BYTE* savedbits = NULL;
static BYTE* cursorbits = NULL;
static int csrimgsize;
static int csrimgpitch;
 
static int oldboxleft = -100, oldboxtop = -100;
static int nShowCount = 0;
static PCURSOR pCurCsr = NULL;

#ifdef _USE_NEWGAL
Uint8* GetPixelUnderCursor (int x, int y, gal_pixel* pixel)
{
    Uint8* dst = NULL;
    
    pthread_mutex_lock (&__mg_mouselock);
    if (nShowCount >= 0 && pCurCsr
            && x >= oldboxleft && y >= oldboxtop
            && (x < oldboxleft + CURSORWIDTH)
            && (y < oldboxtop + CURSORHEIGHT)) {
        int _x = x - oldboxleft;
        int _y = y - oldboxtop;

        dst = savedbits + _y * csrimgpitch
                + _x * __gal_screen->format->BytesPerPixel;
        *pixel = _mem_get_pixel (dst, __gal_screen->format->BytesPerPixel);
    }
    pthread_mutex_unlock (&__mg_mouselock);

    return dst;
}
#endif

// Cursor creating and destroying.
// Only called from InitCursor and client code.
HCURSOR GUIAPI LoadCursorFromFile(const char* filename)
{
    FILE* fp;
    WORD wTemp;
    int  w, h, xhot, yhot, colornum;
    DWORD size, offset;
    DWORD imagesize, imagew, imageh;
    BYTE* image;
    HCURSOR csr = 0;
    
    if( !(fp = fopen(filename, "rb")) ) return 0;

    fseek(fp, sizeof(WORD), SEEK_SET);

    // the cbType of struct CURSORDIR.
    wTemp = MGUI_ReadLE16FP (fp);
    if(wTemp != 2) goto error;

    // skip the cdCount of struct CURSORDIR, we always use the first cursor.
    fseek(fp, sizeof(WORD), SEEK_CUR);
    
    // cursor info, read the members of struct CURSORDIRENTRY.
    w = fgetc (fp);  // the width of first cursor.
    h = fgetc (fp);  // the height of first cursor.
    if(w != CURSORWIDTH || h != CURSORHEIGHT) goto error;
    fseek(fp, sizeof(BYTE)*2, SEEK_CUR); // skip the bColorCount and bReserved.
    wTemp = MGUI_ReadLE16FP (fp);
    xhot = wTemp;
    wTemp = MGUI_ReadLE16FP (fp);
    yhot = wTemp;
    size = MGUI_ReadLE32FP (fp);
    offset = MGUI_ReadLE32FP (fp);

    // read the cursor image info.
    fseek(fp, offset, SEEK_SET);
    fseek(fp, sizeof(DWORD), SEEK_CUR); // skip the biSize member.
    imagew = MGUI_ReadLE32FP (fp);
    imageh = MGUI_ReadLE32FP (fp);
    // check the biPlanes member;
    wTemp = MGUI_ReadLE16FP (fp);
    if(wTemp != 1) goto error;
    // check the biBitCount member;
    wTemp = MGUI_ReadLE16FP (fp);
    if(wTemp > 4) goto error;
    colornum = (int)wTemp;
    fseek(fp, sizeof(DWORD), SEEK_CUR); // skip the biCompression members.
    imagesize = MGUI_ReadLE32FP (fp);

    // skip the rest members and the color table.
    fseek(fp, sizeof(DWORD)*4 + sizeof(BYTE)*(4<<colornum), SEEK_CUR);
    
    // allocate memory for image.
    if ((image = (BYTE*)ALLOCATE_LOCAL (imagesize)) == NULL)
        goto error;

    // read image
    fread (image, imagesize, 1, fp);
    
    csr = CreateCursor(xhot, yhot, w, h, 
                        image + (imagesize - MONOSIZE), image, colornum);

    DEALLOCATE_LOCAL (image);

error:
    fclose (fp);
    return csr;
}

HCURSOR GUIAPI LoadCursorFromMem (const void* area)
{
    const Uint8* p = (Uint8*)area;
    WORD wTemp;

    int  w, h, xhot, yhot, colornum;
    DWORD size, offset;
    DWORD imagesize, imagew, imageh;
    
    p += sizeof (WORD);
    wTemp = MGUI_ReadLE16Mem (&p);
    if(wTemp != 2) goto error;

    // skip the cdCount of struct CURSORDIR, we always use the first cursor.
    p += sizeof (WORD);
    
    // cursor info, read the members of struct CURSORDIRENTRY.
    w = *p++;  // the width of first cursor.
    h = *p++;  // the height of first cursor.
    if (w != CURSORWIDTH || h != CURSORHEIGHT)
        goto error;

    // skip the bColorCount and bReserved.
    p += sizeof(BYTE)*2;
    xhot = MGUI_ReadLE16Mem (&p);
    yhot = MGUI_ReadLE16Mem (&p);
    size = MGUI_ReadLE32Mem (&p);
    offset = MGUI_ReadLE32Mem (&p);

    // read the cursor image info.
    p = (Uint8*)area + offset;

    // skip the biSize member.
    p += sizeof (DWORD);    
    imagew = MGUI_ReadLE32Mem (&p);
    imageh = MGUI_ReadLE32Mem (&p);

    // check the biPlanes member;
    wTemp = MGUI_ReadLE16Mem (&p);
    if (wTemp != 1) goto error;

    // check the biBitCount member;
    wTemp = MGUI_ReadLE16Mem (&p);
    if (wTemp > 4) goto error;
    colornum = wTemp;

    // skip the biCompression members.
    p += sizeof (DWORD);    
    imagesize = MGUI_ReadLE32Mem (&p);

    // skip the rest members and the color table.
    p += sizeof(DWORD)*4 + sizeof(BYTE)*(4<<colornum);
    
    return CreateCursor (xhot, yhot, w, h, 
                        p + (imagesize - MONOSIZE), p, colornum);

error:
    return 0;
}

#ifdef _USE_NEWGAL
static BITMAP csr_bmp = {BMP_TYPE_NORMAL, 0, 0, 0, 0, CURSORWIDTH, CURSORHEIGHT};
#endif

// Only called from InitCursor and client code.
HCURSOR GUIAPI CreateCursor(int xhotspot, int yhotspot, int w, int h,
                     const BYTE* pANDBits, const BYTE* pXORBits, int colornum)
{
    PCURSOR pcsr;
    
    if( w != CURSORWIDTH || h != CURSORHEIGHT ) return 0;

    // allocate memory.
    if( !(pcsr = (PCURSOR)malloc(sizeof(CURSOR))) ) return 0;
    if( !(pcsr->AndBits = malloc(csrimgsize)) ) {
        free(pcsr);
        return 0;
    }
    if( !(pcsr->XorBits = malloc(csrimgsize)) ) {
        free(pcsr->AndBits);
        free(pcsr);
        return 0;
    }

    pcsr->xhotspot = xhotspot;
    pcsr->yhotspot = yhotspot;
    pcsr->width = w;
    pcsr->height = h;

#ifdef _USE_NEWGAL
    if (colornum == 1) {
        ExpandMonoBitmap (HDC_SCREEN, pcsr->AndBits, csrimgpitch, pANDBits, MONOPITCH,
                        w, h, MYBMP_FLOW_UP, 0, 0xFFFFFFFF);
        ExpandMonoBitmap (HDC_SCREEN, pcsr->XorBits, csrimgpitch, pXORBits, MONOPITCH,
                        w, h, MYBMP_FLOW_UP, 0, 0xFFFFFFFF);
    }
    else if (colornum == 4) {
        ExpandMonoBitmap (HDC_SCREEN, pcsr->AndBits, csrimgpitch, pANDBits, MONOPITCH,
                        w, h, MYBMP_FLOW_UP, 0, 0xFFFFFFFF);
        Expand16CBitmap (HDC_SCREEN, pcsr->XorBits, csrimgpitch, pXORBits, MONOPITCH*4,
                        w, h, MYBMP_FLOW_UP, NULL);
    }
#else
    if(colornum == 1) {
        ExpandMonoBitmap (HDC_SCREEN, w, h, pANDBits, MONOPITCH, MYBMP_FLOW_UP,
                         pcsr->AndBits, csrimgpitch, 0, 0xFFFFFFFF);
        ExpandMonoBitmap (HDC_SCREEN, w, h, pXORBits, MONOPITCH, MYBMP_FLOW_UP,
                         pcsr->XorBits, csrimgpitch, 0, 0xFFFFFFFF);
    }
    else if(colornum == 4) {
        ExpandMonoBitmap (HDC_SCREEN, w, h, pANDBits, MONOPITCH, MYBMP_FLOW_UP,
                         pcsr->AndBits, csrimgpitch, 0, 0xFFFFFFFF);
        Expand16CBitmap (HDC_SCREEN, w, h, pXORBits, MONOPITCH*4, MYBMP_FLOW_UP,
                        pcsr->XorBits, csrimgpitch, NULL);
    }
#endif

    return (HCURSOR)pcsr;
}

// Only called from client code.
BOOL GUIAPI DestroyCursor(HCURSOR hcsr)
{
    int i;
    PCURSOR pcsr = (PCURSOR)hcsr;

    if (pcsr == NULL)
        return TRUE;

    for(i = 0; i <= MAX_SYSCURSORINDEX; i++)
    {
        if(pcsr == SysCursor[i])
            return FALSE;
    }

    free(pcsr->AndBits);
    free(pcsr->XorBits);
    free(pcsr);
    return TRUE;
}

// Only called from client code, and accessed items are not changable ones.
HCURSOR GUIAPI GetSystemCursor(int csrid)
{
    if(csrid > MAX_SYSCURSORINDEX || csrid < 0)
        return 0; 

    return (HCURSOR)(SysCursor[csrid]);
}

HCURSOR GUIAPI GetDefaultCursor (void)
{
    return def_cursor;
}

#define CURSORSECTION   "cursorinfo"

BOOL InitCursor(void)
{
    char szValue[MAX_NAME + 1];
    int number;
    int i;

#ifdef _USE_NEWGAL
    csrimgsize = GAL_GetBoxSize (__gal_screen, CURSORWIDTH, CURSORHEIGHT, &csrimgpitch);

    csr_bmp.bmBitsPerPixel = __gal_screen->format->BitsPerPixel;
    csr_bmp.bmBytesPerPixel = __gal_screen->format->BytesPerPixel;
    csr_bmp.bmPitch = csrimgpitch;
#else
    csrimgpitch = CURSORWIDTH * BYTESPERPHYPIXEL;
    csrimgsize = csrimgpitch * CURSORHEIGHT;
#endif

    if( !(savedbits = malloc(csrimgsize)) )
        return FALSE;

    if( !(cursorbits = malloc(csrimgsize)) )
    {
        free(savedbits);
        savedbits = NULL;
        return FALSE;
    }

    if( GetMgEtcValue (CURSORSECTION, "cursornumber", szValue, 10) < 0 )
        goto error;
    
    number = atoi(szValue);

    if(number <= 0)
        return TRUE;

    number = number < (MAX_SYSCURSORINDEX + 1) ? 
             number : (MAX_SYSCURSORINDEX + 1);

    for(i = 0; i < number; i++) {
        if ( !(SysCursor[i] = LoadSystemCursor(i)) )
             goto error;
    }
	
    pthread_mutex_init(&__mg_mouselock, NULL);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -