/*
|
/*
|
* Copyright (c) 2000 Greg Haerr <greg@censoft.com>
|
* Copyright (c) 2000 Greg Haerr <greg@censoft.com>
|
*
|
*
|
* Caret control for Microwindows win32 api.
|
* Caret control for Microwindows win32 api.
|
*
|
*
|
* TODO: add SetSysTimer for blinking
|
* TODO: add SetSysTimer for blinking
|
*/
|
*/
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <sys/time.h>
|
#include <sys/time.h>
|
#ifndef __ECOS
|
#ifndef __ECOS
|
#include <malloc.h>
|
#include <malloc.h>
|
#endif
|
#endif
|
#include "windows.h"
|
#include "windows.h"
|
#include "device.h"
|
#include "device.h"
|
|
|
#define DEF_BLINK_TIME 500 /* default blink time in ms*/
|
#define DEF_BLINK_TIME 500 /* default blink time in ms*/
|
|
|
typedef struct {
|
typedef struct {
|
HWND hwnd; /* != NULL if caret is created*/
|
HWND hwnd; /* != NULL if caret is created*/
|
int x;
|
int x;
|
int y;
|
int y;
|
int nWidth;
|
int nWidth;
|
int nHeight;
|
int nHeight;
|
BOOL fShown; /* caret is currently visible*/
|
BOOL fShown; /* caret is currently visible*/
|
int nShowCount; /* <= 0 for hidden caret*/
|
int nShowCount; /* <= 0 for hidden caret*/
|
UINT nBlinkTime;
|
UINT nBlinkTime;
|
} CARETINFO;
|
} CARETINFO;
|
|
|
/* local data*/
|
/* local data*/
|
static CARETINFO sysCaret; /* the system caret*/
|
static CARETINFO sysCaret; /* the system caret*/
|
|
|
/* local procs*/
|
/* local procs*/
|
static void MwShowCaret(void);
|
static void MwShowCaret(void);
|
static void MwHideCaret(void);
|
static void MwHideCaret(void);
|
static void MwUpdateCaret(void);
|
static void MwUpdateCaret(void);
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
CreateCaret(HWND hwnd, HBITMAP hBitmap, int nWidth, int nHeight)
|
CreateCaret(HWND hwnd, HBITMAP hBitmap, int nWidth, int nHeight)
|
{
|
{
|
|
|
DestroyCaret(); /* destroy old caret if any*/
|
DestroyCaret(); /* destroy old caret if any*/
|
|
|
if (nWidth <= 0)
|
if (nWidth <= 0)
|
nWidth = 1;
|
nWidth = 1;
|
if (nHeight <= 0)
|
if (nHeight <= 0)
|
nHeight = 1;
|
nHeight = 1;
|
|
|
sysCaret.hwnd = hwnd;
|
sysCaret.hwnd = hwnd;
|
sysCaret.x = 0;
|
sysCaret.x = 0;
|
sysCaret.y = 0;
|
sysCaret.y = 0;
|
sysCaret.nWidth = nWidth;
|
sysCaret.nWidth = nWidth;
|
sysCaret.nHeight = nHeight;
|
sysCaret.nHeight = nHeight;
|
sysCaret.fShown = FALSE;
|
sysCaret.fShown = FALSE;
|
sysCaret.nShowCount = 0;
|
sysCaret.nShowCount = 0;
|
sysCaret.nBlinkTime = DEF_BLINK_TIME;
|
sysCaret.nBlinkTime = DEF_BLINK_TIME;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
DestroyCaret(VOID)
|
DestroyCaret(VOID)
|
{
|
{
|
if (sysCaret.fShown)
|
if (sysCaret.fShown)
|
MwHideCaret();
|
MwHideCaret();
|
sysCaret.hwnd = NULL;
|
sysCaret.hwnd = NULL;
|
sysCaret.fShown = FALSE;
|
sysCaret.fShown = FALSE;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
HideCaret(HWND hwnd)
|
HideCaret(HWND hwnd)
|
{
|
{
|
if (hwnd == NULL)
|
if (hwnd == NULL)
|
hwnd = sysCaret.hwnd;
|
hwnd = sysCaret.hwnd;
|
if (hwnd == NULL || hwnd != sysCaret.hwnd)
|
if (hwnd == NULL || hwnd != sysCaret.hwnd)
|
return FALSE;
|
return FALSE;
|
|
|
/* hide caret if this call made it invisible*/
|
/* hide caret if this call made it invisible*/
|
if (--sysCaret.nShowCount == 0) {
|
if (--sysCaret.nShowCount == 0) {
|
MwHideCaret();
|
MwHideCaret();
|
return TRUE;
|
return TRUE;
|
}
|
}
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
ShowCaret(HWND hwnd)
|
ShowCaret(HWND hwnd)
|
{
|
{
|
if (hwnd == NULL)
|
if (hwnd == NULL)
|
hwnd = sysCaret.hwnd;
|
hwnd = sysCaret.hwnd;
|
if (hwnd == NULL || hwnd != sysCaret.hwnd || sysCaret.nShowCount < 0)
|
if (hwnd == NULL || hwnd != sysCaret.hwnd || sysCaret.nShowCount < 0)
|
return FALSE;
|
return FALSE;
|
|
|
if (++sysCaret.nShowCount > 1)
|
if (++sysCaret.nShowCount > 1)
|
return TRUE;
|
return TRUE;
|
|
|
/* show caret, this call made it visible*/
|
/* show caret, this call made it visible*/
|
MwShowCaret();
|
MwShowCaret();
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
SetCaretPos(int nX, int nY)
|
SetCaretPos(int nX, int nY)
|
{
|
{
|
if (sysCaret.fShown && (sysCaret.x != nX || sysCaret.y != nY)) {
|
if (sysCaret.fShown && (sysCaret.x != nX || sysCaret.y != nY)) {
|
MwUpdateCaret(); /* toggle off*/
|
MwUpdateCaret(); /* toggle off*/
|
sysCaret.x = nX;
|
sysCaret.x = nX;
|
sysCaret.y = nY;
|
sysCaret.y = nY;
|
MwUpdateCaret(); /* toggle on in new location*/
|
MwUpdateCaret(); /* toggle on in new location*/
|
return TRUE;
|
return TRUE;
|
}
|
}
|
sysCaret.x = nX;
|
sysCaret.x = nX;
|
sysCaret.y = nY;
|
sysCaret.y = nY;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
GetCaretPos(LPPOINT lpPoint)
|
GetCaretPos(LPPOINT lpPoint)
|
{
|
{
|
lpPoint->x = sysCaret.x;
|
lpPoint->x = sysCaret.x;
|
lpPoint->y = sysCaret.y;
|
lpPoint->y = sysCaret.y;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
UINT WINAPI
|
UINT WINAPI
|
GetCaretBlinkTime(VOID)
|
GetCaretBlinkTime(VOID)
|
{
|
{
|
return sysCaret.nBlinkTime;
|
return sysCaret.nBlinkTime;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
SetCaretBlinkTime(UINT uMSeconds)
|
SetCaretBlinkTime(UINT uMSeconds)
|
{
|
{
|
sysCaret.nBlinkTime = uMSeconds;
|
sysCaret.nBlinkTime = uMSeconds;
|
/* SetSysTimer */
|
/* SetSysTimer */
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
static void
|
static void
|
MwShowCaret(void)
|
MwShowCaret(void)
|
{
|
{
|
if (sysCaret.fShown)
|
if (sysCaret.fShown)
|
return;
|
return;
|
MwUpdateCaret();
|
MwUpdateCaret();
|
sysCaret.fShown = TRUE;
|
sysCaret.fShown = TRUE;
|
}
|
}
|
|
|
static void
|
static void
|
MwHideCaret(void)
|
MwHideCaret(void)
|
{
|
{
|
if (!sysCaret.fShown)
|
if (!sysCaret.fShown)
|
return;
|
return;
|
MwUpdateCaret();
|
MwUpdateCaret();
|
sysCaret.fShown = FALSE;
|
sysCaret.fShown = FALSE;
|
}
|
}
|
|
|
/* Draw the caret using XOR. Same routine is used to show and hide caret.*/
|
/* Draw the caret using XOR. Same routine is used to show and hide caret.*/
|
static void
|
static void
|
MwUpdateCaret(void)
|
MwUpdateCaret(void)
|
{
|
{
|
int oldmode;
|
int oldmode;
|
HDC hdc;
|
HDC hdc;
|
HPEN hpen;
|
HPEN hpen;
|
HBRUSH hbr;
|
HBRUSH hbr;
|
|
|
oldmode = GdSetMode(MWMODE_XOR);
|
oldmode = GdSetMode(MWMODE_XOR);
|
hdc = GetDC(sysCaret.hwnd);
|
hdc = GetDC(sysCaret.hwnd);
|
hpen = SelectObject(hdc, GetStockObject(WHITE_PEN));
|
hpen = SelectObject(hdc, GetStockObject(WHITE_PEN));
|
|
|
/* it seems there's some problems with Rectangle with nWidth == 1*/
|
/* it seems there's some problems with Rectangle with nWidth == 1*/
|
if (sysCaret.nWidth == 1) {
|
if (sysCaret.nWidth == 1) {
|
MoveToEx(hdc, sysCaret.x, sysCaret.y, NULL);
|
MoveToEx(hdc, sysCaret.x, sysCaret.y, NULL);
|
LineTo(hdc, sysCaret.x, sysCaret.y+sysCaret.nHeight);
|
LineTo(hdc, sysCaret.x, sysCaret.y+sysCaret.nHeight);
|
} else {
|
} else {
|
hbr = SelectObject(hdc, GetStockObject(WHITE_BRUSH));
|
hbr = SelectObject(hdc, GetStockObject(WHITE_BRUSH));
|
Rectangle(hdc, sysCaret.x, sysCaret.y,
|
Rectangle(hdc, sysCaret.x, sysCaret.y,
|
sysCaret.x+sysCaret.nWidth,
|
sysCaret.x+sysCaret.nWidth,
|
sysCaret.y+sysCaret.nHeight);
|
sysCaret.y+sysCaret.nHeight);
|
SelectObject(hdc, hbr);
|
SelectObject(hdc, hbr);
|
}
|
}
|
SelectObject(hdc, hpen);
|
SelectObject(hdc, hpen);
|
ReleaseDC(sysCaret.hwnd, hdc);
|
ReleaseDC(sysCaret.hwnd, hdc);
|
GdSetMode(oldmode);
|
GdSetMode(oldmode);
|
}
|
}
|
|
|