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

📄 cursor.c

📁 在ecos 下mingui 的移植开发
💻 C
字号:
// cursor.c: the Cursor Support module of MiniGUI.//// Copyright (C) 1999, Wei Yongming.//// Current maintainer: Wei Yongming./***  This library is free software; you can redistribute it and/or**  modify it under the terms of the GNU Library General Public**  License as published by the Free Software Foundation; either**  version 2 of the License, or (at your option) any later version.****  This library 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**  Library General Public License for more details.****  You should have received a copy of the GNU Library General Public**  License along with this library; if not, write to the Free**  Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,**  MA 02111-1307, USA*/// Create date: 1999.01.06// Last modified date: 1999.01.06//// Modify records:////  Who             When        Where       For What                Status//-----------------------------------------------------------------------------//  WEI Yongming    1999/10/27  Tsinghua    Fix SetCursorPos bug    Working//// TODO:// #include <stdio.h>#include <stddef.h>#include <stdlib.h>#ifndef __ECOS# include <malloc.h>#endif#include <string.h>#include <pthread.h>#include <errno.h>#include "common.h"#include "minigui.h"#include "gdi.h"#include "gal.h"#include "cursor.h"#include "ial.h"#define __NO_MOUSE      0#define CURSORWIDTH	    32#define CURSORHEIGHT	32#define MONOSIZE	    (CURSORWIDTH*CURSORHEIGHT/8)#define MONOPITCH       4#define CURSORSECTION   "cursorinfo"#ifndef lintstatic char fileid[] = "$Id: cursor.c,v 1.11 2000/11/10 05:53:52 ymwei Exp $";#endifextern pthread_mutex_t gdilock;// mutex ensuring exclusive access to mouse.pthread_mutex_t mouselock; static PCURSOR SysCursor [MAX_SYSCURSORINDEX + 1];static HCURSOR def_cursor;static BYTE* savedbits = NULL;static BYTE* cursorbits = NULL;static int csrimgsize; static int nShowCount = 0;static PCURSOR pCurCsr = NULL;// Cursor creating and destroying.// Only called from InitCursor and client code.HCURSOR GUIAPI LoadCursorFromFile(const char* filename){    FILE* fp;    WORD wTemp;    BYTE bTemp;    int  w, h, xhot, yhot, colornum;    DWORD size, offset;    DWORD imagesize, imagew, imageh;    BYTE* image;        if( !(fp = fopen(filename, "rb")) ) return 0;    fseek(fp, sizeof(WORD), SEEK_SET);    // the cbType of struct CURSORDIR.    fread(&wTemp, sizeof(WORD), 1, 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.    fread(&bTemp, sizeof(BYTE), 1, fp);    w = bTemp;  // the width of first cursor.    fread(&bTemp, sizeof(BYTE), 1, fp);    h = bTemp;  // the height of first cursor.    if(w != CURSORWIDTH || h != CURSORHEIGHT) goto error;    fseek(fp, sizeof(BYTE)*2, SEEK_CUR); // skip the bColorCount and bReserved.    fread(&wTemp, sizeof(WORD), 1, fp);    xhot = wTemp;    fread(&wTemp, sizeof(WORD), 1, fp);    yhot = wTemp;    fread(&size, sizeof(DWORD), 1, fp);    fread(&offset, sizeof(DWORD), 1, fp);    // read the cursor image info.    fseek(fp, offset, SEEK_SET);    fseek(fp, sizeof(DWORD), SEEK_CUR); // skip the biSize member.    fread(&imagew, sizeof(DWORD), 1, fp);    fread(&imageh, sizeof(DWORD), 1, fp);    // check the biPlanes member;    fread(&wTemp, sizeof(WORD), 1, fp);    if(wTemp != 1) goto error;    // check the biBitCount member;    fread(&wTemp, sizeof(WORD), 1, fp);    if(wTemp > 4) goto error;    colornum = (int)wTemp;    fseek(fp, sizeof(DWORD), SEEK_CUR); // skip the biCompression members.    fread(&imagesize, sizeof(DWORD), 1, fp);    // skip the rest members and the color table.    fseek(fp, sizeof(DWORD)*4 + sizeof(BYTE)*(4<<colornum), SEEK_CUR);        // allocate memory for image.    image = (BYTE*)alloca(imagesize);    // read image    fread(image, imagesize, 1, fp);        fclose(fp);        return CreateCursor(xhot, yhot, w, h,                         image + (imagesize - MONOSIZE), image, colornum);error:    fclose(fp);    return 0;}// 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;    if(colornum == 1) {        ExpandMonoBitmap (HDC_SCREEN, w, h, pANDBits, BMP_FLOW_UP, MONOPITCH,                          pcsr->AndBits, 0xFFFFFFFF, 0);        ExpandMonoBitmap (HDC_SCREEN, w, h, pXORBits, BMP_FLOW_UP, MONOPITCH,                         pcsr->XorBits, 0xFFFFFFFF, 0);    }    else if(colornum == 4) {        ExpandMonoBitmap (HDC_SCREEN, w, h, pANDBits, BMP_FLOW_UP, MONOPITCH,                          pcsr->AndBits, 0xFFFFFFFF, 0);        Expand16CBitmap (HDC_SCREEN, w, h, pXORBits, BMP_FLOW_UP, MONOPITCH*4,                        pcsr->XorBits, NULL);    }    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;}// Must be called at startup.BOOL InitCursor( void ){    char szPathName[MAX_PATH + 1];    char szFileName[MAX_PATH + 1];    char szKey[10];    char szValue[MAX_FILENAME + 1];    int number;    int i;    csrimgsize = CURSORWIDTH * CURSORHEIGHT * BYTESPERPHYPIXEL;    if( !(savedbits = malloc(csrimgsize)) )        return FALSE;    if( !(cursorbits = malloc(csrimgsize)) )    {        free(savedbits);        savedbits = NULL;        return FALSE;    }    if( GetValueFromEtcFile(ETCFILEPATH, CURSORSECTION, "cursorpath",                             szPathName, MAX_PATH) < 0 )         goto error;    if( GetValueFromEtcFile(ETCFILEPATH, CURSORSECTION, "cursornumber",                             szValue, 10) < 0 )        goto error;    number = atoi(szValue);    if(number <= 0)#if __NO_MOUSE        goto error;#else        return TRUE;#endif    number = number < (MAX_SYSCURSORINDEX + 1) ?              number : (MAX_SYSCURSORINDEX + 1);    for(i = 0; i < number; i++)    {        sprintf(szKey, "cursor%d", i);        if( GetValueFromEtcFile(ETCFILEPATH, CURSORSECTION,                                 szKey, szValue, MAX_FILENAME) < 0 )            goto error;        strcpy(szFileName, szPathName);        strcat(szFileName, szValue);        if( !(SysCursor[i] = (PCURSOR)LoadCursorFromFile(szFileName)) )             goto error;    }    pthread_mutex_init(&mouselock, NULL);    return TRUE;error:    TerminateCursor();    return FALSE;}// The following function must be called at last. BOOL TerminateCursor( void ){    int i;    if( !savedbits ) return FALSE;    free(savedbits);    free(cursorbits);    savedbits = NULL;    pCurCsr = NULL;    nShowCount = 0;     for(i = 0; i<= MAX_SYSCURSORINDEX; i++)    {        if( SysCursor[i] ) {            free(SysCursor[i]->AndBits);            free(SysCursor[i]->XorBits);            free(SysCursor[i]);            SysCursor[i] = NULL;       }    }    return TRUE;}HCURSOR GUIAPI GetCurrentCursor(void){    HCURSOR hcsr;    pthread_mutex_lock (&mouselock);        hcsr = (HCURSOR)pCurCsr;    pthread_mutex_unlock(&mouselock);    return hcsr;}static int curx, cury;static int oldx = -1, oldy;static int oldboxleft = -100, oldboxtop = -100;static RECT cliprc = { 0, 0, 0, 0};// Cursor pointer shape and hiding and showing.static inline int boxleft(void){    if(!pCurCsr) return -100;    return curx - pCurCsr->xhotspot;}static inline int boxtop(void){    if(!pCurCsr) return -100;    return cury - pCurCsr->yhotspot;}static inline void hidecursor(void){    GAL_SetGC(PHYSICALGC);    GAL_EnableClipping(PHYSICALGC);    GAL_PutBox(PHYSICALGC, oldboxleft, oldboxtop, CURSORWIDTH, CURSORHEIGHT, savedbits);}static inline void showcursor(void){    BYTE* andbits;    BYTE* xorbits;    int i;    int x, y;    GAL_SetGC(PHYSICALGC);    x = boxleft();    y = boxtop();    GAL_DisableClipping(PHYSICALGC);    GAL_GetBox(PHYSICALGC, x, y, CURSORWIDTH, CURSORHEIGHT, savedbits);    oldboxleft = x;    oldboxtop = y;    memcpy(cursorbits, savedbits, csrimgsize);    andbits = pCurCsr->AndBits;    xorbits = pCurCsr->XorBits;    for(i = 0; i < csrimgsize; i++) {        cursorbits[i] &= *andbits++;        cursorbits[i] ^= *xorbits++;    }    GAL_EnableClipping(PHYSICALGC);    GAL_PutBox(PHYSICALGC, x, y, CURSORWIDTH, CURSORHEIGHT, cursorbits);}// The return value indicates whether mouse has moved. // TRUE for moved.BOOL GUIAPI RefreshCursor(int* x, int* y, int* button){    pthread_mutex_lock (&gdilock);    pthread_mutex_lock (&mouselock);    IAL_UpdateMouse ();    *x = curx = IAL_GetMouseX ();    *y = cury = IAL_GetMouseY ();    *button = IAL_GetMouseButton ();    if(oldx != curx || oldy != cury)    {        if(nShowCount >= 0 && pCurCsr) {            hidecursor();            showcursor();        }        oldx = curx;        oldy = cury;        pthread_mutex_unlock(&mouselock);        pthread_mutex_unlock(&gdilock);        return TRUE;    }    pthread_mutex_unlock(&mouselock);    pthread_mutex_unlock(&gdilock);    return FALSE;}// Cursor clipping support.void GUIAPI ClipCursor(const RECT* prc){    RECT rc;    pthread_mutex_lock (&mouselock);    if( IsRectEmpty(&cliprc) )        SetRect(&cliprc, 0, 0, WIDTHOFPHYGC - 1, HEIGHTOFPHYGC - 1);    if(prc == NULL)    {        IAL_SetMouseRange (0,0,WIDTHOFPHYGC - 1,HEIGHTOFPHYGC - 1);        SetRect(&cliprc, 0, 0, WIDTHOFPHYGC - 1, HEIGHTOFPHYGC - 1);        pthread_mutex_unlock(&mouselock);        return;    }            memcpy(&rc, prc, sizeof(RECT));    NormalizeRect(&rc);    IntersectRect(&cliprc, &rc, &cliprc);    NormalizeRect(&cliprc);    IAL_SetMouseRange (cliprc.left,cliprc.top, cliprc.right,cliprc.bottom);    pthread_mutex_unlock(&mouselock);}void GUIAPI GetClipCursor(RECT* prc){    pthread_mutex_lock (&mouselock);    memcpy(prc, &cliprc, sizeof(RECT));    pthread_mutex_unlock(&mouselock);}HCURSOR GUIAPI SetCursorEx (HCURSOR hcsr, BOOL setdef){    PCURSOR old, pcsr;    pthread_mutex_lock (&mouselock);    if (setdef) {        old = (PCURSOR) def_cursor;        def_cursor = hcsr;    }    else        old = pCurCsr;    if ((PCURSOR)hcsr == pCurCsr) {        pthread_mutex_unlock(&mouselock);        return (HCURSOR) old;    }    pthread_mutex_unlock(&mouselock);    pthread_mutex_lock (&gdilock);    pthread_mutex_lock (&mouselock);    pcsr = (PCURSOR)hcsr;    if (pCurCsr)        hidecursor();    pCurCsr = pcsr;    if (nShowCount >= 0 && pCurCsr)        showcursor();    pthread_mutex_unlock(&mouselock);    pthread_mutex_unlock(&gdilock);    return (HCURSOR) old;}void ShowCursorForGDI(BOOL fShow, const RECT* prc){    int csrleft, csrright, csrtop, csrbottom;    int intleft, intright, inttop, intbottom;    if (!fShow)        pthread_mutex_lock (&mouselock);    csrleft = boxleft();    csrright = csrleft + CURSORWIDTH;    csrtop = boxtop();    csrbottom = csrtop + CURSORHEIGHT;    intleft = (csrleft > prc->left) ? csrleft : prc->left;    inttop  = (csrtop > prc->top) ? csrtop : prc->top;    intright = (csrright < prc->right) ? csrright : prc->right;    intbottom = (csrbottom < prc->bottom) ? csrbottom : prc->bottom;    if(intleft >= intright || inttop >= intbottom)    {        if (fShow)            pthread_mutex_unlock(&mouselock);        return;    }    if (fShow && nShowCount >= 0 && pCurCsr) {        showcursor();    }    if (!fShow && nShowCount >= 0 && pCurCsr) {        hidecursor();    }    if (fShow)        pthread_mutex_unlock(&mouselock);    return;}int GUIAPI ShowCursor(BOOL fShow){    int count;    pthread_mutex_lock (&gdilock);    pthread_mutex_lock (&mouselock);    if(fShow) {        nShowCount++;        if(nShowCount == 0 && pCurCsr)           showcursor();    }    else {        nShowCount--;        if(nShowCount == -1 && pCurCsr);           hidecursor();    }    count = nShowCount;    pthread_mutex_unlock(&mouselock);    pthread_mutex_unlock(&gdilock);    return count;}// Cursor position.void GUIAPI GetCursorPos(POINT* ppt){    pthread_mutex_lock (&mouselock);    ppt->x = curx;    ppt->y = cury;    pthread_mutex_unlock(&mouselock);}void GUIAPI SetCursorPos(int x, int y){    pthread_mutex_lock (&gdilock);    pthread_mutex_lock (&mouselock);    IAL_SetMouseXY (x, y);    curx = IAL_GetMouseX ();    cury = IAL_GetMouseY ();    if(oldx != curx || oldy != cury)    {        if(nShowCount >= 0 && pCurCsr) {            hidecursor();            showcursor();        }        oldx = curx;        oldy = cury;    }    pthread_mutex_unlock(&mouselock);    pthread_mutex_unlock(&gdilock);}

⌨️ 快捷键说明

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