Merge pull request #23 from inmarket/master
Ginput and structure changes
This commit is contained in:
commit
b5d8cc2086
65 changed files with 3593 additions and 887 deletions
|
@ -33,12 +33,15 @@
|
|||
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
|
||||
|
||||
/* Include the emulation code for things we don't support */
|
||||
#include "gdisp_emulation.c"
|
||||
#include "lld/gdisp/emulation.c"
|
||||
|
||||
#if defined(BOARD_OLIMEX_STM32_LCD)
|
||||
#if defined(GDISP_USE_CUSTOM_BOARD) && GDISP_USE_CUSTOM_BOARD
|
||||
/* Include the user supplied board definitions */
|
||||
#include "gdisp_lld_board.h"
|
||||
#elif defined(BOARD_OLIMEX_STM32_LCD)
|
||||
#include "gdisp_lld_board_olimex_stm32_lcd.h"
|
||||
#else
|
||||
#include "gdisp_lld_board_example.h"
|
||||
#include "gdisp_lld_board.h"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
|
||||
|
||||
/* Include the emulation code for things we don't support */
|
||||
#include "gdisp_emulation.c"
|
||||
#include "lld/gdisp/emulation.c"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
|
@ -73,7 +73,10 @@
|
|||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if defined(BOARD_OLIMEX_SAM7_EX256)
|
||||
#if defined(GDISP_USE_CUSTOM_BOARD) && GDISP_USE_CUSTOM_BOARD
|
||||
/* Include the user supplied board definitions */
|
||||
#include "gdisp_lld_board.h"
|
||||
#elif defined(BOARD_OLIMEX_SAM7_EX256)
|
||||
#include "gdisp_lld_board_olimexsam7ex256.h"
|
||||
#else
|
||||
/* Include the user supplied board definitions */
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
|
||||
|
||||
/* Include the emulation code for things we don't support */
|
||||
#include "gdisp_emulation.c"
|
||||
#include "lld/gdisp/emulation.c"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
|
@ -56,7 +56,10 @@
|
|||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if defined(BOARD_OLIMEX_STM32_E407)
|
||||
#if defined(GDISP_USE_CUSTOM_BOARD) && GDISP_USE_CUSTOM_BOARD
|
||||
/* Include the user supplied board definitions */
|
||||
#include "gdisp_lld_board.h"
|
||||
#elif defined(BOARD_OLIMEX_STM32_E407)
|
||||
#include "gdisp_lld_board_olimex_e407.h"
|
||||
#else
|
||||
#include "gdisp_lld_board.h"
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
|
||||
|
||||
/* Include the emulation code for things we don't support */
|
||||
#include "gdisp_emulation.c"
|
||||
#include "lld/gdisp/emulation.c"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
|
@ -53,7 +53,10 @@
|
|||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if defined(BOARD_FIREBULL_STM32_F103)
|
||||
#if defined(GDISP_USE_CUSTOM_BOARD) && GDISP_USE_CUSTOM_BOARD
|
||||
/* Include the user supplied board definitions */
|
||||
#include "gdisp_lld_board.h"
|
||||
#elif defined(BOARD_FIREBULL_STM32_F103)
|
||||
#include "gdisp_lld_board_firebullstm32f103.h"
|
||||
#else
|
||||
/* Include the user supplied board definitions */
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
|
||||
|
||||
/* Include the emulation code for things we don't support */
|
||||
#include "gdisp_emulation.c"
|
||||
#include "lld/gdisp/emulation.c"
|
||||
|
||||
/* All the board specific code should go in these include file so the driver
|
||||
* can be ported to another board just by creating a suitable file.
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
|
||||
|
||||
/* Include the emulation code for things we don't support */
|
||||
#include "gdisp_emulation.c"
|
||||
#include "lld/gdisp/emulation.c"
|
||||
|
||||
/* ---- Required Routines ---- */
|
||||
/*
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define GDISP_LLD_NO_STRUCT
|
||||
|
||||
/* Include the emulation code for things we don't support */
|
||||
#include "gdisp_emulation.c"
|
||||
#include "lld/gdisp/emulation.c"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
# List the required driver.
|
||||
GFXSRC += $(GFXLIB)/drivers/gdisp/Win32/gdisp_lld.c
|
||||
|
||||
# Required include directories
|
||||
GFXINC += $(GFXLIB)/drivers/gdisp/Win32
|
5
drivers/ginput/toggle/Pal/ginput_lld.mk
Normal file
5
drivers/ginput/toggle/Pal/ginput_lld.mk
Normal file
|
@ -0,0 +1,5 @@
|
|||
# List the required driver.
|
||||
GFXSRC += $(GFXLIB)/drivers/ginput/toggle/Pal/ginput_lld_toggle.c
|
||||
|
||||
# Required include directories
|
||||
GFXINC += $(GFXLIB)/drivers/ginput/toggle/Pal
|
62
drivers/ginput/toggle/Pal/ginput_lld_toggle.c
Normal file
62
drivers/ginput/toggle/Pal/ginput_lld_toggle.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file drivers/ginput/togglePal/ginput_lld_toggle.c
|
||||
* @brief GINPUT Toggle low level driver source for the ChibiOS PAL hardware.
|
||||
*
|
||||
* @addtogroup GINPUT_TOGGLE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if (GFX_USE_GINPUT && GINPUT_NEED_TOGGLE) /*|| defined(__DOXYGEN__)*/
|
||||
|
||||
// Declare the static members in the following include file
|
||||
#define GINPUT_TOGGLE_DECLARE_CONFIG
|
||||
|
||||
#include "lld/ginput/toggle.h"
|
||||
|
||||
/**
|
||||
* @brief Initialise the port.
|
||||
*
|
||||
* @param[in] ptc A pointer to one of the entries in GInputToggleConfigTable
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ginput_lld_toggle_init(const GToggleConfig *ptc) {
|
||||
palSetGroupMode(((IOBus *)ptc->id)->portid, ptc->mask, 0, ptc->mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the bits from the port.
|
||||
*
|
||||
* @param[in] ptc A pointer to one of the entries in GInputToggleConfigTable
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
unsigned ginput_lld_toggle_getbits(const GToggleConfig *ptc) {
|
||||
return palReadBus((IOBus *)ptc->id);
|
||||
}
|
||||
|
||||
#endif /* GFX_USE_GINPUT && GINPUT_NEED_TOGGLE */
|
||||
/** @} */
|
65
drivers/ginput/toggle/Pal/ginput_lld_toggle_board_example.h
Normal file
65
drivers/ginput/toggle/Pal/ginput_lld_toggle_board_example.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file drivers/ginput/togglePal/ginput_lld_toggle_board_example.h
|
||||
* @brief GINPUT Toggle low level driver source for the ChibiOS PAL hardware on the example board.
|
||||
*
|
||||
* @addtogroup GINPUT_TOGGLE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _GDISP_LLD_TOGGLE_BOARD_H
|
||||
#define _GDISP_LLD_TOGGLE_BOARD_H
|
||||
|
||||
#ifndef _GINPUT_LLD_TOGGLE_CONFIG_H
|
||||
// Visible in ginput.h
|
||||
|
||||
#define GINPUT_TOGGLE_SW1 0 // Switch 1
|
||||
#define GINPUT_TOGGLE_SW2 1 // Switch 2
|
||||
#define GINPUT_TOGGLE_UP 2 // Joystick Up
|
||||
#define GINPUT_TOGGLE_DOWN 3 // Joystick Down
|
||||
#define GINPUT_TOGGLE_LEFT 4 // Joystick Left
|
||||
#define GINPUT_TOGGLE_RIGHT 5 // Joystick Right
|
||||
#define GINPUT_TOGGLE_CENTER 6 // Joystick Center
|
||||
|
||||
#elif !defined(GINPUT_TOGGLE_DECLARE_CONFIG)
|
||||
// Visible in ginput_lld.h
|
||||
|
||||
#define GINPUT_TOGGLE_NUM_PORTS 7 // The total number of toggle inputs
|
||||
|
||||
#else
|
||||
// Visible in ginput_lld_toggle.c
|
||||
|
||||
GToggleConfig GInputToggleConfigTable[] = {
|
||||
{AT91C_BASE_PIOB, // Switch 1 and Switch 2
|
||||
PIOB_SW1_MASK|PIOB_SW2_MASK,
|
||||
PIOB_SW1_MASK|PIOB_SW2_MASK,
|
||||
PAL_MODE_INPUT},
|
||||
{AT91C_BASE_PIOA, // B1..4 Joystick
|
||||
PIOA_B1_MASK|PIOA_B2_MASK|PIOA_B3_MASK|PIOA_B4_MASK|PIOA_B5_MASK,
|
||||
PIOA_B1_MASK|PIOA_B2_MASK|PIOA_B3_MASK|PIOA_B4_MASK|PIOA_B5_MASK,
|
||||
PAL_MODE_INPUT},
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _GDISP_LLD_TOGGLE_BOARD_H */
|
||||
/** @} */
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file drivers/ginput/togglePal/ginput_lld_toggle_board_olimexsam7ex256.h
|
||||
* @brief GINPUT Toggle low level driver source for the ChibiOS PAL hardware on the Olimex SAM7EX256 board.
|
||||
*
|
||||
* @addtogroup GINPUT_TOGGLE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _GDISP_LLD_TOGGLE_BOARD_H
|
||||
#define _GDISP_LLD_TOGGLE_BOARD_H
|
||||
|
||||
#define GINPUT_TOGGLE_NUM_PORTS 7 // The total number of toggle inputs
|
||||
#define GINPUT_TOGGLE_CONFIG_ENTRIES 2 // The total number of GToggleConfig entries
|
||||
|
||||
#define GINPUT_TOGGLE_SW1 0 // Switch 1
|
||||
#define GINPUT_TOGGLE_SW2 1 // Switch 2
|
||||
#define GINPUT_TOGGLE_UP 2 // Joystick Up
|
||||
#define GINPUT_TOGGLE_DOWN 3 // Joystick Down
|
||||
#define GINPUT_TOGGLE_LEFT 4 // Joystick Left
|
||||
#define GINPUT_TOGGLE_RIGHT 5 // Joystick Right
|
||||
#define GINPUT_TOGGLE_CENTER 6 // Joystick Center
|
||||
|
||||
#ifdef GINPUT_TOGGLE_DECLARE_CONFIG
|
||||
// Visible in ginput_lld_toggle.c
|
||||
|
||||
const GToggleConfig GInputToggleConfigTable[GINPUT_TOGGLE_CONFIG_ENTRIES] = {
|
||||
{AT91C_BASE_PIOB, // Switch 1 and Switch 2
|
||||
PIOB_SW1_MASK|PIOB_SW2_MASK,
|
||||
PIOB_SW1_MASK|PIOB_SW2_MASK,
|
||||
PAL_MODE_INPUT},
|
||||
{AT91C_BASE_PIOA, // B1..4 Joystick
|
||||
PIOA_B1_MASK|PIOA_B2_MASK|PIOA_B3_MASK|PIOA_B4_MASK|PIOA_B5_MASK,
|
||||
PIOA_B1_MASK|PIOA_B2_MASK|PIOA_B3_MASK|PIOA_B4_MASK|PIOA_B5_MASK,
|
||||
PAL_MODE_INPUT},
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _GDISP_LLD_TOGGLE_BOARD_H */
|
||||
/** @} */
|
44
drivers/ginput/toggle/Pal/ginput_lld_toggle_config.h
Normal file
44
drivers/ginput/toggle/Pal/ginput_lld_toggle_config.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file drivers/ginput/togglePal/ginput_lld_toggle_config.h
|
||||
* @brief GINPUT Toggle Driver configuration header.
|
||||
*
|
||||
* @addtogroup GDISP
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_TOGGLE_CONFIG_H
|
||||
#define _GINPUT_LLD_TOGGLE_CONFIG_H
|
||||
|
||||
#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
|
||||
|
||||
#if defined(BOARD_OLIMEX_SAM7_EX256)
|
||||
#include "ginput_lld_toggle_board_olimexsam7ex256.h"
|
||||
#else
|
||||
/* Include the user supplied board definitions */
|
||||
#include "ginput_lld_toggle_board.h"
|
||||
#endif
|
||||
|
||||
#endif /* GFX_USE_GDISP && GINPUT_NEED_TOGGLE */
|
||||
|
||||
#endif /* _GINPUT_LLD_TOGGLE_CONFIG_H */
|
||||
/** @} */
|
13
drivers/ginput/toggle/Pal/readme.txt
Normal file
13
drivers/ginput/toggle/Pal/readme.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
To use this driver:
|
||||
|
||||
1. Add in your halconf.h:
|
||||
a) #define GFX_USE_GINPUT TRUE
|
||||
#define GINPUT_NEED_TOGGLE TRUE
|
||||
d) If you are not using a known board then create a ginput_lld_toggle_board.h file
|
||||
and ensure it is on your include path.
|
||||
Use the ginput_lld_toggle_board_example.h file as a basis.
|
||||
Currently known boards are:
|
||||
Olimex SAM7-EX256
|
||||
|
||||
2. To your makefile add the following lines:
|
||||
include $(GFXLIB)/drivers/ginput/togglePal/ginput_lld.mk
|
5
drivers/ginput/touch/ADS7843/ginput_lld.mk
Normal file
5
drivers/ginput/touch/ADS7843/ginput_lld.mk
Normal file
|
@ -0,0 +1,5 @@
|
|||
# List the required driver.
|
||||
GFXSRC += $(GFXLIB)/drivers/ginput/touch/ADS7843/ginput_lld_mouse.c
|
||||
|
||||
# Required include directories
|
||||
GFXINC += $(GFXLIB)/drivers/ginput/touch/ADS7843
|
139
drivers/ginput/touch/ADS7843/ginput_lld_mouse.c
Normal file
139
drivers/ginput/touch/ADS7843/ginput_lld_mouse.c
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file drivers/ginput/touch/ADS7843/ginput_lld_mouse.c
|
||||
* @brief GINPUT Touch low level driver source for the ADS7843.
|
||||
*
|
||||
* @addtogroup GINPUT_MOUSE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if (GFX_USE_GINPUT && GINPUT_NEED_MOUSE) /*|| defined(__DOXYGEN__)*/
|
||||
|
||||
#include "lld/ginput/mouse.h"
|
||||
|
||||
#if defined(GINPUT_MOUSE_USE_CUSTOM_BOARD) && GINPUT_MOUSE_USE_CUSTOM_BOARD
|
||||
/* Include the user supplied board definitions */
|
||||
#include "ginput_lld_mouse_board.h"
|
||||
//#elif defined(BOARD_OLIMEX_SAM7_EX256)
|
||||
// #include "ginput_lld_mouse_board_olimexsam7ex256.h"
|
||||
#else
|
||||
#include "ginput_lld_mouse_board.h"
|
||||
#endif
|
||||
|
||||
static uint16_t sampleBuf[7];
|
||||
static coord_t lastx, lasty;
|
||||
|
||||
/**
|
||||
* @brief 7-point median filtering code for touch samples
|
||||
*
|
||||
* @note This is an internally used routine only.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void filter(void) {
|
||||
uint16_t temp;
|
||||
int i,j;
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
for(j = i; j < 7; j++) {
|
||||
if(sampleBuf[i] > sampleBuf[j]) {
|
||||
/* Swap the values */
|
||||
temp = sampleBuf[i];
|
||||
sampleBuf[i] = sampleBuf[j];
|
||||
sampleBuf[j] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialise the mouse/touch.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ginput_lld_mouse_init(void) {
|
||||
init_board();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the mouse/touch position.
|
||||
*
|
||||
* @param[in] pt A pointer to the structure to fill
|
||||
*
|
||||
* @note For drivers that don't support returning a position
|
||||
* when the touch is up (most touch devices), it should
|
||||
* return the previous position with the new Z value.
|
||||
* The z value is the pressure for those touch devices
|
||||
* that support it (-100 to 100 where > 0 is touched)
|
||||
* or, 0 or 100 for those drivers that don't.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ginput_lld_mouse_get_reading(MouseReading *pt) {
|
||||
// If touch-off return the previous results
|
||||
if (!getpin_pressed()) {
|
||||
pt->x = lastx;
|
||||
pt->y = lasty;
|
||||
pt->z = 0;
|
||||
pt->buttons = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the port to get the touch settings
|
||||
aquire_bus();
|
||||
|
||||
/* Get the X value
|
||||
* Discard the first conversion - very noisy and keep the ADC on hereafter
|
||||
* till we are done with the sampling. Note that PENIRQ is disabled while reading.
|
||||
* Finally switch on PENIRQ once again - perform a dummy read.
|
||||
* Once we have the readings, find the medium using our filter function
|
||||
*/
|
||||
read_value(0xD1);
|
||||
for(i = 0; i < 7; i++)
|
||||
sampleBuf[i] = read_value(0xD1);
|
||||
read_value(0xD0);
|
||||
filter();
|
||||
lastx = (coord_t)sampleBuf[3];
|
||||
|
||||
/* Get the Y value using the same process as above */
|
||||
read_value(0x91);
|
||||
for(i = 0; i < 7; i++)
|
||||
sampleBuf[i] = read_value(0x91);
|
||||
read_value(0x90);
|
||||
filter();
|
||||
lasty = (coord_t)sampleBuf[3];
|
||||
|
||||
// Release the bus
|
||||
release_bus();
|
||||
|
||||
// Return the results
|
||||
pt->x = lastx;
|
||||
pt->y = lasty;
|
||||
pt->z = 100;
|
||||
pt->buttons = GINPUT_TOUCH_PRESSED;
|
||||
}
|
||||
|
||||
#endif /* GFX_USE_GINPUT && GINPUT_NEED_MOUSE */
|
||||
/** @} */
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file drivers/ginput/touch/ADS7843/ginput_lld_mouse_board_example.h
|
||||
* @brief GINPUT Touch low level driver source for the ADS7843 on the example board.
|
||||
*
|
||||
* @addtogroup GINPUT_MOUSE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
/**
|
||||
* @brief Initialise the board for the touch.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline void init_board(void) {
|
||||
/* Code here */
|
||||
#error "ginputADS7843: You must supply a definition for init_board for your board"
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check whether the surface is currently touched
|
||||
* @return TRUE if the surface is currently touched
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline bool_t getpin_pressed(void) {
|
||||
/* Code here */
|
||||
#error "ginputADS7843: You must supply a definition for getpin_pressed for your board"
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Aquire the bus ready for readings
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline void aquire_bus(void) {
|
||||
/* Code here */
|
||||
#error "ginputADS7843: You must supply a definition for aquire_bus for your board"
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release the bus after readings
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline void release_bus(void) {
|
||||
/* Code here */
|
||||
#error "ginputADS7843: You must supply a definition for release_bus for your board"
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read a value from touch controller
|
||||
* @return The value read from the controller
|
||||
*
|
||||
* params[in] port The controller port to read.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline uint16_t read_value(uint16_t port) {
|
||||
/* Code here */
|
||||
#error "ginputADS7843: You must supply a definition for read_value for your board"
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
||||
/** @} */
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file drivers/ginput/touch/ADS7843/ginput_lld_mouse_board_unknown.h
|
||||
* @brief GINPUT Touch low level driver source for the ADS7843 on some unknown board.
|
||||
*
|
||||
* @addtogroup GINPUT_MOUSE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
/**
|
||||
* @brief Initialise the board for the touch.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline void init_board(void) {
|
||||
spiStart(TOUCH_SPIDriver, TOUCH_SPIConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check whether the surface is currently touched
|
||||
* @return TRUE if the surface is currently touched
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline bool_t getpin_pressed(void) {
|
||||
return !palReadPad(TOUCH_PressedPort, TOUCH_PressedPin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Aquire the bus ready for readings
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline void aquire_bus(void) {
|
||||
#if defined(SPI_USE_MUTUAL_EXCLUSION)
|
||||
spiAcquireBus(TOUCH_SPIDriver);
|
||||
#endif
|
||||
|
||||
GINPUT_TOUCH_SPI_PROLOGUE();
|
||||
palClearPad(TOUCH_SPIConfig->ssport, TOUCH_SPIConfig->sspad);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release the bus after readings
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline void release_bus(void) {
|
||||
palSetPad(TOUCH_SPIConfig->ssport, TOUCH_SPIConfig->sspad);
|
||||
GINPUT_TOUCH_SPI_EPILOGUE();
|
||||
|
||||
#if defined(SPI_USE_MUTUAL_EXCLUSION)
|
||||
spiReleaseBus(tsDriver->spip);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read a value from touch controller
|
||||
* @return The value read from the controller
|
||||
*
|
||||
* params[in] port The controller port to read.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline uint16_t read_value(uint16_t port) {
|
||||
static uint8_t txbuf[3] = {0};
|
||||
static uint8_t rxbuf[3] = {0};
|
||||
|
||||
txbuf[0] = cmd;
|
||||
spiExchange(TOUCH_SPIDriver, 3, txbuf, rxbuf);
|
||||
return (rxbuf[1] << 5) | (rxbuf[2] >> 3);
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
||||
/** @} */
|
41
drivers/ginput/touch/ADS7843/ginput_lld_mouse_config.h
Normal file
41
drivers/ginput/touch/ADS7843/ginput_lld_mouse_config.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
ChibiOS/GFX - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file drivers/ginput/touch/ADS7843/ginput_lld_mouse_config.h
|
||||
* @brief GINPUT LLD header file for mouse/touch driver.
|
||||
*
|
||||
* @addtogroup GINPUT_LLD_MOUSE
|
||||
* @{
|
||||
*/
|
||||
#ifndef _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
#define _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_TOUCH
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION TRUE
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR 2
|
||||
#define GINPUT_MOUSE_READ_CYCLES 4
|
||||
#define GINPUT_MOUSE_POLL_PERIOD 100
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 2
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 2
|
||||
#define GINPUT_MOUSE_CLICK_TIME 700
|
||||
|
||||
#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */
|
||||
/** @} */
|
9
drivers/ginput/touch/ADS7843/readme.txt
Normal file
9
drivers/ginput/touch/ADS7843/readme.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
To use this driver:
|
||||
|
||||
1. Add in your halconf.h:
|
||||
a) #define GFX_USE_GINPUT TRUE
|
||||
b) #define GINPUT_NEED_MOUSE TRUE
|
||||
|
||||
2. To your makefile add the following lines:
|
||||
include $(GFXLIB)/drivers/ginput/touch/ADS7843/ginput_lld.mk
|
||||
|
5
drivers/ginput/touch/MCU/ginput_lld.mk
Normal file
5
drivers/ginput/touch/MCU/ginput_lld.mk
Normal file
|
@ -0,0 +1,5 @@
|
|||
# List the required driver.
|
||||
GFXSRC += $(GFXLIB)/drivers/ginput/touch/MCU/ginput_lld_mouse.c
|
||||
|
||||
# Required include directories
|
||||
GFXINC += $(GFXLIB)/drivers/ginput/touch/MCU
|
136
drivers/ginput/touch/MCU/ginput_lld_mouse.c
Normal file
136
drivers/ginput/touch/MCU/ginput_lld_mouse.c
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file drivers/ginput/touch/MCU/ginput_lld_mouse.c
|
||||
* @brief GINPUT Touch low level driver source for the MCU.
|
||||
*
|
||||
* @addtogroup GINPUT_MOUSE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if (GFX_USE_GINPUT && GINPUT_NEED_MOUSE) /*|| defined(__DOXYGEN__)*/
|
||||
|
||||
#include "lld/ginput/touch.h"
|
||||
|
||||
#if defined(GINPUT_MOUSE_USE_CUSTOM_BOARD) && GINPUT_MOUSE_USE_CUSTOM_BOARD
|
||||
/* Include the user supplied board definitions */
|
||||
#include "ginput_lld_mouse_board.h"
|
||||
//#elif defined(BOARD_OLIMEX_SAM7_EX256)
|
||||
// #include "ginput_lld_mouse_board_olimexsam7ex256.h"
|
||||
#else
|
||||
#include "ginput_lld_mouse_board.h"
|
||||
#endif
|
||||
|
||||
static uint16_t sampleBuf[7];
|
||||
static coord_t lastx, lasty;
|
||||
|
||||
/**
|
||||
* @brief 7-point median filtering code for touchscreen samples
|
||||
*
|
||||
* @note This is an internally used routine only.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void filter(void) {
|
||||
uint16_t temp;
|
||||
int i,j;
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
for(j = i; j < 7; j++) {
|
||||
if(sampleBuf[i] > sampleBuf[j]) {
|
||||
/* Swap the values */
|
||||
temp = sampleBuf[i];
|
||||
sampleBuf[i] = sampleBuf[j];
|
||||
sampleBuf[j] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialise the mouse/touch.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ginput_lld_mouse_init(void) {
|
||||
init_board();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the mouse/touch position.
|
||||
*
|
||||
* @param[in] pt A pointer to the structure to fill
|
||||
*
|
||||
* @note For drivers that don't support returning a position
|
||||
* when the touch is up (most touch devices), it should
|
||||
* return the previous position with the new Z value.
|
||||
* The z value is the pressure for those touch devices
|
||||
* that support it (-100 to 100 where > 0 is touched)
|
||||
* or, 0 or 100 for those drivers that don't.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ginput_lld_mouse_get_reading(MouseReading *pt) {
|
||||
// If touch-off return the previous results
|
||||
if (!getpin_pressed()) {
|
||||
pt->x = lastx;
|
||||
pt->y = lasty;
|
||||
pt->z = 0;
|
||||
pt->buttons = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the port to get the touch settings
|
||||
aquire_bus();
|
||||
|
||||
/* Get the X value
|
||||
* Discard the first conversion - very noisy and keep the ADC on hereafter
|
||||
* till we are done with the sampling.
|
||||
* Once we have the readings, find the medium using our filter function
|
||||
*/
|
||||
read_x_value();
|
||||
for(i = 0; i < 7; i++)
|
||||
sampleBuf[i] = read_x_value();
|
||||
filter();
|
||||
lastx = (coord_t)sampleBuf[3];
|
||||
|
||||
/* Get the Y value using the same process as above */
|
||||
read_y_value();
|
||||
for(i = 0; i < 7; i++)
|
||||
sampleBuf[i] = read_y_value();
|
||||
filter();
|
||||
lasty = (coord_t)sampleBuf[3];
|
||||
|
||||
// Release the bus
|
||||
release_bus();
|
||||
|
||||
// Return the results
|
||||
pt->x = lastx;
|
||||
pt->y = lasty;
|
||||
pt->z = 100;
|
||||
pt->buttons = GINPUT_TOUCH_PRESSED;
|
||||
}
|
||||
|
||||
#endif /* GFX_USE_GINPUT && GINPUT_NEED_MOUSE */
|
||||
/** @} */
|
96
drivers/ginput/touch/MCU/ginput_lld_mouse_board_example.h
Normal file
96
drivers/ginput/touch/MCU/ginput_lld_mouse_board_example.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file drivers/ginput/touch/MCU/ginput_lld_mouse_board_example.h
|
||||
* @brief GINPUT Touch low level driver source for the MCU on the example board.
|
||||
*
|
||||
* @addtogroup GINPUT_MOUSE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
/**
|
||||
* @brief Initialise the board for the touch.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline void init_board(void) {
|
||||
/* Code here */
|
||||
#error "ginputMCU: You must supply a definition for init_board for your board"
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check whether the surface is currently touched
|
||||
* @return TRUE if the surface is currently touched
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline bool_t getpin_pressed(void) {
|
||||
/* Code here */
|
||||
#error "ginputMCU: You must supply a definition for getpin_pressed for your board"
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Aquire the bus ready for readings
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline void aquire_bus(void) {
|
||||
/* Code here */
|
||||
#error "ginputMCU: You must supply a definition for aquire_bus for your board"
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release the bus after readings
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline void release_bus(void) {
|
||||
/* Code here */
|
||||
#error "ginputMCU: You must supply a definition for release_bus for your board"
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read an x value from touch controller
|
||||
* @return The value read from the controller
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline uint16_t read_x_value(void) {
|
||||
/* Code here */
|
||||
#error "ginputMCU: You must supply a definition for read_x_value for your board"
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read an y value from touch controller
|
||||
* @return The value read from the controller
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline uint16_t read_y_value(void) {
|
||||
/* Code here */
|
||||
#error "ginputMCU: You must supply a definition for read_y_value for your board"
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
||||
/** @} */
|
174
drivers/ginput/touch/MCU/ginput_lld_mouse_board_unknown.h
Normal file
174
drivers/ginput/touch/MCU/ginput_lld_mouse_board_unknown.h
Normal file
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file drivers/ginput/touch/MCU/ginput_lld_mouse_board_unknown.h
|
||||
* @brief GINPUT Touch low level driver source for the MCU on some unknown board.
|
||||
*
|
||||
* @addtogroup GINPUT_MOUSE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
#define ADC_NUM_CHANNELS 2
|
||||
#define ADC_BUF_DEPTH 1
|
||||
|
||||
static const ADCConversionGroup adc_y_config = {
|
||||
FALSE,
|
||||
ADC_NUM_CHANNELS,
|
||||
NULL,
|
||||
NULL,
|
||||
0, 0,
|
||||
0, 0,
|
||||
ADC_SQR1_NUM_CH(ADC_NUM_CHANNELS),
|
||||
0,
|
||||
ADC_SQR3_SQ2_N(ADC_CHANNEL_IN12) | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN13)
|
||||
};
|
||||
|
||||
static const ADCConversionGroup adc_x_config = {
|
||||
FALSE,
|
||||
ADC_NUM_CHANNELS,
|
||||
NULL,
|
||||
NULL,
|
||||
0, 0,
|
||||
0, 0,
|
||||
ADC_SQR1_NUM_CH(ADC_NUM_CHANNELS),
|
||||
0,
|
||||
ADC_SQR3_SQ2_N(ADC_CHANNEL_IN10) | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN11)
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Initialise the board for the mouse/touch.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline void init_board(void) {
|
||||
/* Code here */
|
||||
#error "ginputMCU: You must supply a definition for init_board for your board
|
||||
|
||||
adcStart(ts->adc_driver, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check whether the surface is currently touched
|
||||
* @return TRUE if the surface is currently touched
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline bool_t getpin_pressed(void) {
|
||||
/* Code here */
|
||||
#error "ginputMCU: You must supply a definition for getpin_pressed for your board"
|
||||
palSetPadMode(ts->yd_port, ts->yd_pin, PAL_MODE_INPUT_PULLDOWN);
|
||||
palSetPadMode(ts->yu_port, ts->yu_pin, PAL_MODE_INPUT);
|
||||
palSetPadMode(ts->xl_port, ts->xl_pin, PAL_MODE_INPUT);
|
||||
palSetPadMode(ts->xr_port, ts->xr_pin, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
palSetPad(ts->xr_port, ts->xr_pin);
|
||||
|
||||
return palReadPad(ts->yd_port, ts->yd_pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Aquire the bus ready for readings
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline void aquire_bus(void) {
|
||||
/* Code here */
|
||||
#error "ginputMCU: You must supply a definition for aquire_bus for your board"
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release the bus after readings
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline void release_bus(void) {
|
||||
/* Code here */
|
||||
#error "ginputMCU: You must supply a definition for release_bus for your board"
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read an x value from touch controller
|
||||
* @return The value read from the controller
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline uint16_t read_x_value(void) {
|
||||
/* Code here */
|
||||
#error "ginputMCU: You must supply a definition for read_x_value for your board"
|
||||
uint16_t val1, val2;
|
||||
adcsample_t samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH];
|
||||
|
||||
palSetPadMode(ts->yd_port, ts->yd_pin, PAL_MODE_INPUT_ANALOG);
|
||||
palSetPadMode(ts->yu_port, ts->yu_pin, PAL_MODE_INPUT_ANALOG);
|
||||
palSetPadMode(ts->xl_port, ts->xl_pin, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
palSetPadMode(ts->xr_port, ts->xr_pin, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
|
||||
palSetPad(ts->xl_port, ts->xl_pin);
|
||||
palClearPad(ts->xr_port, ts->xr_pin);
|
||||
chThdSleepMilliseconds(1);
|
||||
adcConvert(ts->adc_driver, &adc_x_config, samples, ADC_BUF_DEPTH);
|
||||
val1 = ((samples[0] + samples[1])/2);
|
||||
|
||||
palClearPad(ts->xl_port, ts->xl_pin);
|
||||
palSetPad(ts->xr_port, ts->xr_pin);
|
||||
chThdSleepMilliseconds(1);
|
||||
adcConvert(ts->adc_driver, &adc_x_config, samples, ADC_BUF_DEPTH);
|
||||
val2 = ((samples[0] + samples[1])/2);
|
||||
|
||||
return ((val1+((1<<12)-val2))/4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read an y value from touch controller
|
||||
* @return The value read from the controller
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static __inline uint16_t read_y_value(void) {
|
||||
/* Code here */
|
||||
#error "ginputMCU: You must supply a definition for read_y_value for your board"
|
||||
uint16_t val1, val2;
|
||||
adcsample_t samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH];
|
||||
|
||||
palSetPadMode(ts->xl_port, ts->xl_pin, PAL_MODE_INPUT_ANALOG);
|
||||
palSetPadMode(ts->xr_port, ts->xr_pin, PAL_MODE_INPUT_ANALOG);
|
||||
palSetPadMode(ts->yd_port, ts->yd_pin, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
palSetPadMode(ts->yu_port, ts->yu_pin, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
|
||||
palSetPad(ts->yu_port, ts->yu_pin);
|
||||
palClearPad(ts->yd_port, ts->yd_pin);
|
||||
chThdSleepMilliseconds(1);
|
||||
adcConvert(ts->adc_driver, &adc_y_config, samples, ADC_BUF_DEPTH);
|
||||
val1 = ((samples[0] + samples[1])/2);
|
||||
|
||||
palClearPad(ts->yu_port, ts->yu_pin);
|
||||
palSetPad(ts->yd_port, ts->yd_pin);
|
||||
chThdSleepMilliseconds(1);
|
||||
adcConvert(ts->adc_driver, &adc_y_config, samples, ADC_BUF_DEPTH);
|
||||
val2 = ((samples[0] + samples[1])/2);
|
||||
|
||||
return ((val1+((1<<12)-val2))/4);
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
||||
/** @} */
|
41
drivers/ginput/touch/MCU/ginput_lld_mouse_config.h
Normal file
41
drivers/ginput/touch/MCU/ginput_lld_mouse_config.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
ChibiOS/GFX - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file drivers/ginput/touch/MCU/ginput_lld_mouse_config.h
|
||||
* @brief GINPUT LLD header file for touch driver.
|
||||
*
|
||||
* @addtogroup GINPUT_LLD_MOUSE
|
||||
* @{
|
||||
*/
|
||||
#ifndef _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
#define _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_TOUCH
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION TRUE
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR 2
|
||||
#define GINPUT_MOUSE_READ_CYCLES 4
|
||||
#define GINPUT_MOUSE_POLL_PERIOD 100
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 2
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 2
|
||||
#define GINPUT_MOUSE_CLICK_TIME 700
|
||||
|
||||
#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */
|
||||
/** @} */
|
9
drivers/ginput/touch/MCU/readme.txt
Normal file
9
drivers/ginput/touch/MCU/readme.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
To use this driver:
|
||||
|
||||
1. Add in your halconf.h:
|
||||
a) #define GFX_USE_GINPUT TRUE
|
||||
b) #define GINPUT_NEED_MOUSE TRUE
|
||||
|
||||
2. To your makefile add the following lines:
|
||||
include $(GFXLIB)/drivers/ginput/touch/MCU/ginput_lld.mk
|
||||
|
|
@ -29,12 +29,14 @@
|
|||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include "gdisp.h"
|
||||
#include "touchscreen.h"
|
||||
|
||||
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
|
||||
|
||||
/* Include mouse support code */
|
||||
#include "lld/ginput/mouse.h"
|
||||
|
||||
/* Include the emulation code for things we don't support */
|
||||
#include "gdisp_emulation.c"
|
||||
#include "lld/gdisp/emulation.c"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -60,7 +62,7 @@ static HBITMAP dcBitmap = NULL;
|
|||
static HBITMAP dcOldBitmap;
|
||||
static volatile bool_t isReady = FALSE;
|
||||
static coord_t mousex, mousey;
|
||||
static bool_t mousedn;
|
||||
static uint16_t mousebuttons;
|
||||
|
||||
static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
@ -70,28 +72,34 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|||
switch (Msg) {
|
||||
case WM_CREATE:
|
||||
break;
|
||||
#if GINPUT_NEED_MOUSE
|
||||
case WM_LBUTTONDOWN:
|
||||
mousedn = TRUE;
|
||||
mousex = (coord_t)LOWORD(lParam);
|
||||
mousey = (coord_t)HIWORD(lParam);
|
||||
break;
|
||||
mousebuttons = 0x0001;
|
||||
goto mousemove;
|
||||
case WM_LBUTTONUP:
|
||||
mousedn = FALSE;
|
||||
mousex = (coord_t)LOWORD(lParam);
|
||||
mousey = (coord_t)HIWORD(lParam);
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
mousex = (coord_t)LOWORD(lParam);
|
||||
mousey = (coord_t)HIWORD(lParam);
|
||||
break;
|
||||
case WM_LBUTTONDBLCLK:
|
||||
mousebuttons &= ~0x0001;
|
||||
goto mousemove;
|
||||
case WM_MBUTTONDOWN:
|
||||
mousebuttons = 0x0004;
|
||||
goto mousemove;
|
||||
case WM_MBUTTONUP:
|
||||
case WM_MBUTTONDBLCLK:
|
||||
mousebuttons &= ~0x0004;
|
||||
goto mousemove;
|
||||
case WM_RBUTTONDOWN:
|
||||
mousebuttons = 0x0002;
|
||||
goto mousemove;
|
||||
case WM_RBUTTONUP:
|
||||
case WM_RBUTTONDBLCLK:
|
||||
mousebuttons &= ~0x0002;
|
||||
goto mousemove;
|
||||
case WM_MOUSEMOVE:
|
||||
mousemove:
|
||||
mousex = (coord_t)LOWORD(lParam);
|
||||
mousey = (coord_t)HIWORD(lParam);
|
||||
#if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
|
||||
ginputMouseWakeup();
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYUP:
|
||||
|
@ -882,70 +890,20 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#if GFX_USE_TOUCHSCREEN /*|| defined(__DOXYGEN__)*/
|
||||
#if GINPUT_NEED_MOUSE
|
||||
|
||||
void ts_store_calibration_lld(struct cal_t *cal) {
|
||||
(void) cal;
|
||||
// Just ignore the calibration data - we implicitly know the calibration
|
||||
#include "lld/ginput/mouse.h"
|
||||
|
||||
void ginput_lld_mouse_init(void) {}
|
||||
|
||||
void ginput_lld_mouse_get_reading(MouseReading *pt) {
|
||||
pt->x = mousex;
|
||||
pt->y = mousey;
|
||||
pt->z = (mousebuttons & 0x0001) ? 100 : 0;
|
||||
pt->buttons = mousebuttons; // We auto-magicaly know that the mousebutton bits match the MouseReading bits.
|
||||
}
|
||||
|
||||
struct cal_t *ts_restore_calibration_lld(void) {
|
||||
static struct cal_t cal = { 1.0, 0.0, 0.0, 0.0, 1.0, 0.0 };
|
||||
// Our x,y is always already calibrated.
|
||||
return &cal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Low level touchscreen driver initialization.
|
||||
*
|
||||
* @param[in] ts The touchscreen driver
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ts_lld_init(const TouchscreenDriver *ts) {
|
||||
(void) ts;
|
||||
// Just ignore everything
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads out the X direction.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
uint16_t ts_lld_read_x(void) {
|
||||
return mousex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads out the Y direction.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
uint16_t ts_lld_read_y(void) {
|
||||
return mousey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads out the Z direction.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
uint16_t ts_lld_read_z(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief for checking if touchpad is pressed or not.
|
||||
*
|
||||
* @return 1 if pressed / 0 if not pressed
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
uint8_t ts_lld_pressed(void) {
|
||||
return (uint8_t)mousedn;
|
||||
}
|
||||
|
||||
#endif /* GFX_USE_TOUCHSCREEN */
|
||||
#endif /* GINPUT_NEED_MOUSE */
|
||||
|
||||
#endif /* GFX_USE_GDISP */
|
||||
/** @} */
|
5
drivers/multiple/Win32/gdisp_lld.mk
Normal file
5
drivers/multiple/Win32/gdisp_lld.mk
Normal file
|
@ -0,0 +1,5 @@
|
|||
# List the required driver.
|
||||
GFXSRC += $(GFXLIB)/drivers/multiple/Win32/gdisp_lld.c
|
||||
|
||||
# Required include directories
|
||||
GFXINC += $(GFXLIB)/drivers/multiple/Win32
|
58
drivers/multiple/Win32/ginput_lld_mouse_config.h
Normal file
58
drivers/multiple/Win32/ginput_lld_mouse_config.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
ChibiOS/GFX - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file drivers/gdisp/Win32/ginput_lld_mouse_config.h
|
||||
* @brief GINPUT LLD header file for mouse/touch driver.
|
||||
*
|
||||
* @addtogroup GINPUT_LLD_MOUSE
|
||||
* @{
|
||||
*/
|
||||
#ifndef _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
#define _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
|
||||
// This driver supports being both a mouse or a touch device (we don't actually know which it really is)
|
||||
// When operating in mouse mode a long left button click does not generate a context click.
|
||||
// When operating in touch mode we allow sloppier clicks etc
|
||||
#if GINPUT_NEED_MOUSE
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_MOUSE
|
||||
#define GINPUT_MOUSE_CLICK_TIME TIME_INFINITE // Long click != Context Click
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION FALSE
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#define GINPUT_MOUSE_READ_CYCLES 1
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR -1
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 0
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 0
|
||||
#else
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_TOUCH
|
||||
#define GINPUT_MOUSE_CLICK_TIME 700 // Long click = Context Click
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION FALSE // Can be set to TRUE just for testing
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#define GINPUT_MOUSE_READ_CYCLES 1
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR 2
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 2
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 2
|
||||
#endif
|
||||
|
||||
// This driver supports both an "interrupt" mode, and a polled mode
|
||||
#define GINPUT_MOUSE_POLL_PERIOD TIME_INFINITE // Interrupt driven by the Window thread
|
||||
//#define GINPUT_MOUSE_POLL_PERIOD 100 // Poll driven
|
||||
|
||||
#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */
|
||||
/** @} */
|
|
@ -5,7 +5,8 @@ and a touchscreen driver.
|
|||
|
||||
1. Add in your halconf.h:
|
||||
a) #define GFX_USE_GDISP TRUE
|
||||
b) #define GFX_USE_TOUCHSCREEN TRUE
|
||||
b) #define GFX_USE_GINPUT TRUE
|
||||
#define GINPUT_USE_MOUSE TRUE
|
||||
c) Any optional high level driver defines (see gdisp.h) eg: GDISP_NEED_MULTITHREAD
|
||||
d) All of the following (with appropriate values):
|
||||
#define GDISP_SCREEN_WIDTH 640
|
||||
|
@ -14,7 +15,7 @@ and a touchscreen driver.
|
|||
|
||||
2. To your makefile add the following lines:
|
||||
include $(GFXLIB)/gfx.mk
|
||||
include $(GFXLIB)/drivers/gdisp/Win32/gdisp_lld.mk
|
||||
include $(GFXLIB)/drivers/multiple/Win32/gdisp_lld.mk
|
||||
|
||||
3. Modify your makefile to add -lgdi32 to the DLIBS line. i.e.
|
||||
DLIBS = -lws2_32 -lgdi32
|
4
gfx.mk
4
gfx.mk
|
@ -7,9 +7,11 @@ GFXSRC += $(GFXLIB)/src/gdisp.c \
|
|||
$(GFXLIB)/src/gdisp_fonts.c \
|
||||
$(GFXLIB)/src/gevent.c \
|
||||
$(GFXLIB)/src/gtimer.c \
|
||||
$(GFXLIB)/src/ginput.c \
|
||||
$(GFXLIB)/src/gwin.c \
|
||||
$(GFXLIB)/src/touchscreen.c \
|
||||
$(GFXLIB)/src/graph.c \
|
||||
|
||||
GFXINC += $(GFXLIB)/include
|
||||
|
||||
include $(GFXLIB)/src/gwin/gwin.mk
|
||||
include $(GFXLIB)/src/ginput/ginput.mk
|
||||
|
|
|
@ -114,7 +114,7 @@
|
|||
/*===========================================================================*/
|
||||
|
||||
/* Include the low level driver information */
|
||||
#include "gdisp_lld.h"
|
||||
#include "lld/gdisp/gdisp_lld.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Type definitions */
|
||||
|
|
|
@ -100,10 +100,15 @@ typedef union GEvent_u {
|
|||
char pad[GEVENT_MAXIMUM_STATUS_SIZE]; // This is here to allow static initialisation of GEventObject's in the application.
|
||||
} GEvent;
|
||||
|
||||
// A special callback function
|
||||
typedef void (*GEventCallbackFn)(void *param, GEvent *pe);
|
||||
|
||||
// The Listener Object
|
||||
typedef struct GListener {
|
||||
Semaphore waitqueue; // Private: Semaphore for the listener to wait on.
|
||||
BinarySemaphore eventlock; // Private: Protect against more than one sources trying to use this event lock at the same time
|
||||
GEventCallbackFn callback; // Private: Call back Function
|
||||
void *param; // Private: Parameter for the callback function.
|
||||
GEvent event; // Public: The event object into which the event information is stored.
|
||||
} GListener;
|
||||
|
||||
|
@ -177,13 +182,29 @@ void geventDetachSource(GListener *pl, GSourceHandle gsh);
|
|||
* timeout specifies the time to wait in system ticks.
|
||||
* TIME_INFINITE means no timeout - wait forever for an event.
|
||||
* TIME_IMMEDIATE means return immediately
|
||||
* Returns NULL on timeout.
|
||||
* Returns NULL on timeout or if a callback function is already registered.
|
||||
* Note: The GEvent buffer is staticly allocated within the GListener so the event does not
|
||||
* need to be dynamicly freed however it will get overwritten by the next call to
|
||||
* this routine.
|
||||
*/
|
||||
GEvent *geventEventWait(GListener *pl, systime_t timeout);
|
||||
|
||||
/* Register a callback for an event on a listener from an assigned source.
|
||||
* The type of the event should be checked (pevent->type) and then pevent should be typecast to the
|
||||
* actual event type if it needs to be processed.
|
||||
* Note: The GEvent buffer is valid only during the time of the callback. The callback MUST NOT save
|
||||
* a pointer to the buffer for use outside the callback.
|
||||
* Note: An existing callback function is de-registered by passing a NULL for 'fn'. Any existing
|
||||
* callback function is replaced. Any thread currently waiting using geventEventWait will be sent the exit event.
|
||||
* Note: Callbacks occur in a thread context but stack space must be kept to a minumum and
|
||||
* the callback must process quickly as all other events are performed on a single thread.
|
||||
* Note: In the callback function you should never call ANY event functions using your own GListener handle
|
||||
* as it WILL create a deadlock and lock the system up.
|
||||
* Note: Applications should not use this call - geventEventWait() is the preferred mechanism for an
|
||||
* application. This call is provided for GUI objects that may not have their own thread.
|
||||
*/
|
||||
void geventRegisterCallback(GListener *pl, GEventCallbackFn fn, void *param);
|
||||
|
||||
/*---------- Source Functions --------------------------------------------*/
|
||||
|
||||
/* Sources create their own GSourceHandles which are pointers to any arbitrary structure
|
||||
|
|
253
include/ginput.h
253
include/ginput.h
|
@ -37,41 +37,6 @@
|
|||
* @name GINPUT more complex functionality to be compiled
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Should mouse functions be included.
|
||||
* @details Defaults to FALSE
|
||||
*/
|
||||
#ifndef GINPUT_NEED_MOUSE
|
||||
#define GINPUT_NEED_MOUSE FALSE
|
||||
#endif
|
||||
/**
|
||||
* @brief Should touch functions be included.
|
||||
* @details Defaults to FALSE
|
||||
*/
|
||||
#ifndef GINPUT_NEED_TOUCH
|
||||
#define GINPUT_NEED_TOUCH FALSE
|
||||
#endif
|
||||
/**
|
||||
* @brief Should keyboard functions be included.
|
||||
* @details Defaults to FALSE
|
||||
*/
|
||||
#ifndef GINPUT_NEED_KEYBOARD
|
||||
#define GINPUT_NEED_KEYBOARD FALSE
|
||||
#endif
|
||||
/**
|
||||
* @brief Should hardware toggle/switch/button (pio) functions be included.
|
||||
* @details Defaults to FALSE
|
||||
*/
|
||||
#ifndef GINPUT_NEED_TOGGLE
|
||||
#define GINPUT_NEED_TOGGLE FALSE
|
||||
#endif
|
||||
/**
|
||||
* @brief Should analog dial functions be included.
|
||||
* @details Defaults to FALSE
|
||||
*/
|
||||
#ifndef GINPUT_NEED_DIAL
|
||||
#define GINPUT_NEED_DIAL FALSE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -81,10 +46,6 @@
|
|||
#ifndef GFX_USE_GDISP
|
||||
#define GFX_USE_GDISP FALSE
|
||||
#endif
|
||||
#if GINPUT_NEED_TOUCH || !GFX_USE_GDISP
|
||||
#error "GINPUT: GFX_USE_GDISP must be defined for touch functions"
|
||||
#endif
|
||||
|
||||
#if GFX_USE_GDISP
|
||||
#include "gdisp.h"
|
||||
#else
|
||||
|
@ -94,14 +55,13 @@
|
|||
|
||||
#ifndef GFX_USE_GEVENT
|
||||
#define GFX_USE_GEVENT TRUE
|
||||
#include "gevent.h"
|
||||
#elif !GFX_USE_GEVENT
|
||||
#error "GINPUT: GFX_USE_GEVENT must be defined"
|
||||
#endif
|
||||
#include "gevent.h"
|
||||
|
||||
#ifndef GFX_USE_GTIMER
|
||||
#define GFX_USE_GTIMER TRUE
|
||||
#include "gtimer.h"
|
||||
#elif !GFX_USE_GTIMER
|
||||
#error "GINPUT: GFX_USE_GTIMER must be defined"
|
||||
#endif
|
||||
|
@ -110,138 +70,10 @@
|
|||
/* Type definitions */
|
||||
/*===========================================================================*/
|
||||
|
||||
// Event types for various ginput sources
|
||||
#define GEVENT_MOUSE (GEVENT_GINPUT_FIRST+0)
|
||||
#define GEVENT_TOUCH (GEVENT_GINPUT_FIRST+1)
|
||||
#define GEVENT_KEYBOARD (GEVENT_GINPUT_FIRST+2)
|
||||
#define GEVENT_TOGGLE (GEVENT_GINPUT_FIRST+3)
|
||||
#define GEVENT_DIAL (GEVENT_GINPUT_FIRST+4)
|
||||
|
||||
#if GINPUT_NEED_MOUSE || GINPUT_NEED_TOUCH
|
||||
typedef struct GEventMouse_t {
|
||||
GEventType type; // The type of this event (GEVENT_MOUSE or GEVENT_TOUCH)
|
||||
uint16_t instance; // The mouse/touch instance
|
||||
coord_t x, y, z; // The position of the mouse.
|
||||
// - For touch devices, Z is the current pressure if supported (otherwise 0)
|
||||
// - For mice, Z is the 3rd dimension if supported (otherwise 0)
|
||||
uint16_t current_buttons; // A bit is set if the button is down.
|
||||
// - For touch only bit 0 is relevant
|
||||
// - For mice the order of the buttons is (from 0 to n) left, right, middle, any other buttons
|
||||
// - Bit 15 being set indicates that an important mouse event has been missed.
|
||||
#define GINPUT_TOUCH_PRESSED 0x0001
|
||||
#define GINPUT_MOUSE_BTN_LEFT 0x0001
|
||||
#define GINPUT_MOUSE_BTN_RIGHT 0x0002
|
||||
#define GINPUT_MOUSE_BTN_MIDDLE 0x0004
|
||||
#define GINPUT_MOUSE_BTN_4 0x0008
|
||||
#define GINPUT_MISSED_MOUSE_EVENT 0x8000
|
||||
uint16_t last_buttons; // The value of current_buttons on the last event
|
||||
enum GMouseMeta_e {
|
||||
GMETA_NONE, // There is no meta event currently happenning
|
||||
GMETA_DOWN, GMETA_UP, // Button 0 has just gone up or down
|
||||
GMETA_CLICK, // Button 0 has just gone through a short down - up cycle
|
||||
GMETA_CXTCLICK // For mice - The right button has just been depressed
|
||||
// For touch - a long press has just occurred
|
||||
} meta;
|
||||
} GEventMouse, GEventTouch;
|
||||
|
||||
// Mouse/Touch Listen Flags - passed to geventAddSourceToListener()
|
||||
#define GLISTEN_MOUSEMETA 0x0001 // Create events for meta events such as CLICK and CXTCLICK
|
||||
#define GLISTEN_MOUSEDOWNMOVES 0x0002 // Creates mouse move events when the primary mouse button is down (touch is on the surface)
|
||||
#define GLISTEN_MOUSEUPMOVES 0x0004 // Creates mouse move events when the primary mouse button is up (touch is off the surface - if the hardware allows).
|
||||
#define GLISTEN_TOUCHMETA 0x0001 // Ditto for touch
|
||||
#define GLISTEN_TOUCHDOWNMOVES 0x0002
|
||||
#define GLISTEN_TOUCHUPMOVES 0x0004
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_KEYBOARD
|
||||
typedef struct GEventKeyboard_t {
|
||||
GEventType type; // The type of this event (GEVENT_KEYBOARD)
|
||||
uint16_t instance; // The keyboard instance
|
||||
char c; // The Ascii code for the current key press.
|
||||
// The only possible values are 0(NUL), 8(BS), 9(TAB), 13(CR), 27(ESC), 32(SPACE) to 126(~), 127(DEL)
|
||||
// 0 indicates an extended only key.
|
||||
uint16_t code; // An extended keyboard code. Codes less than 128 match their ascii equivelent.
|
||||
#define GKEY_NULL 0
|
||||
#define GKEY_BACKSPACE 8
|
||||
#define GKEY_TAB 9
|
||||
#define GKEY_CR 13
|
||||
#define GKEY_ESC 27
|
||||
#define GKEY_SPACE 32
|
||||
#define GKEY_DEL 127
|
||||
#define GKEY_UP 0x0101
|
||||
#define GKEY_DOWN 0x0102
|
||||
#define GKEY_LEFT 0x0103
|
||||
#define GKEY_RIGHT 0x0104
|
||||
#define GKEY_HOME 0x0105
|
||||
#define GKEY_END 0x0106
|
||||
#define GKEY_PAGEUP 0x0107
|
||||
#define GKEY_PAGEDOWN 0x0108
|
||||
#define GKEY_INSERT 0x0109
|
||||
#define GKEY_DELETE 0x010A
|
||||
#define GKEY_SHIFT 0x0201
|
||||
#define GKEY_CNTRL 0x0202
|
||||
#define GKEY_ALT 0x0203
|
||||
#define GKEY_WINKEY 0x0204
|
||||
#define GKEY_RCLKEY 0x0205
|
||||
#define GKEY_FNKEY 0x0206
|
||||
#define GKEY_FN1 0x0301
|
||||
#define GKEY_FN2 0x0302
|
||||
#define GKEY_FN3 0x0303
|
||||
#define GKEY_FN4 0x0304
|
||||
#define GKEY_FN5 0x0305
|
||||
#define GKEY_FN6 0x0306
|
||||
#define GKEY_FN7 0x0307
|
||||
#define GKEY_FN8 0x0308
|
||||
#define GKEY_FN9 0x0309
|
||||
#define GKEY_FN10 0x030A
|
||||
#define GKEY_FN11 0x030B
|
||||
#define GKEY_FN12 0x030C
|
||||
uint16_t current_buttons; // A bit is set to indicate various meta status.
|
||||
#define GMETA_KEYDN 0x0001
|
||||
#define GMETA_SHIFT 0x0002
|
||||
#define GMETA_CNTRL 0x0004
|
||||
#define GMETA_ALT 0x0008
|
||||
#define GMETA_WINKEY 0x0010
|
||||
#define GMETA_RCLKKEY 0x0020
|
||||
#define GMETA_FNKEY 0x0040
|
||||
#define GMETA_MISSED_EVENT 0x8000
|
||||
uint16_t last_buttons; // The value of current_buttons on the last event
|
||||
} GEventKeyboard;
|
||||
|
||||
// Keyboard Listen Flags - passed to geventAddSourceToListener()
|
||||
#define GLISTEN_KEYREPEATS 0x0001 // Return key repeats (where the key is held down to get a repeat character)
|
||||
#define GLISTEN_KEYCODES 0x0002 // Return all key presses including extended code key presses (not just ascii codes)
|
||||
#define GLISTEN_KEYALL 0x0004 // Return keyup's, keydown's and everything in between (but not repeats unless GLISTEN_KEYREPEATS is set).
|
||||
#define GLISTEN_KEYSINGLE 0x8000 // Return only when one particular extended code key is pressed or released. The particular extended code is OR'd into this value
|
||||
// eg. (GLISTEN_KEYSINGLE | GKEY_CR)
|
||||
// No other flags may be set with this flag.
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_TOGGLE
|
||||
typedef struct GEventToggle_t {
|
||||
GEventType type; // The type of this event (GEVENT_TOGGLE)
|
||||
uint16_t instance; // The toggle instance
|
||||
BOOL on; // True if the toggle/button is on
|
||||
} GEventToggle;
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_DIAL
|
||||
typedef struct GEventDial_t {
|
||||
GEventType type; // The type of this event (GEVENT_DIAL)
|
||||
uint16_t instance; // The dial instance
|
||||
uint16_t value; // The dial value
|
||||
} GEventDial;
|
||||
#endif
|
||||
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* How to use...
|
||||
|
||||
1. Get source handles for all the inputs you are interested in.
|
||||
|
@ -254,84 +86,11 @@ extern "C" {
|
|||
5. When complete destroy the listener
|
||||
*/
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
/* Mouse Functions */
|
||||
GSourceHandle ginputGetMouse(uint16_t instance); // Instance = 0 to n-1
|
||||
|
||||
/* Get the current mouse position and button status.
|
||||
* Unlike a listener event, this status cannot record meta events such as "CLICK"
|
||||
* Returns FALSE on error (eg invalid instance)
|
||||
*/
|
||||
BOOL ginputGetMouseStatus(uint16_t instance, GEventMouse *pmouse);
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_TOUCH
|
||||
/* Touch Functions */
|
||||
GSourceHandle ginputGetTouch(uint16_t instance); // Instance = 0 to n-1
|
||||
|
||||
/* Get the current touch position and button status.
|
||||
* Unlike a listener event, this status cannot record meta events such as "CLICK"
|
||||
* Returns FALSE on error (eg invalid instance)
|
||||
*/
|
||||
BOOL ginputGetTouchStatus(uint16_t instance, GEventTouch *ptouch);
|
||||
|
||||
/* Run a touch calibration.
|
||||
* Returns FALSE if the driver doesn't support it or if the handle is invalid.
|
||||
*/
|
||||
BOOL ginputCalibrateTouch(uint16_t instance);
|
||||
|
||||
/* Set the routines to save and fetch calibration data.
|
||||
* This function should be called before first calling ginputGetTouch() for a particular instance
|
||||
* as the gdispGetTouch() routine may attempt to fetch calibration data and perform a startup calibration if there is no way to get it.
|
||||
* If this is called after gdispGetTouch() has been called and the driver requires calibration storage, it will immediately save the data is has already obtained.
|
||||
* The 'requireFree' parameter indicates if the fetch buffer must be free()'d to deallocate the buffer provided by the Fetch routine.
|
||||
*/
|
||||
typedef void (*)(uint16_t instance, const uint8_t *calbuf, size_t sz) GTouchCalibrationSaveRoutine; // Save calibration data
|
||||
typedef const char * (*)(uint16_t instance) GTouchCalibrationFetchRoutine; // Fetch calibration data (returns NULL if not data saved)
|
||||
void ginputSetTouchCalibrationRoutines(uint16_t instance, GTouchCalibrationSaveRoutine fnsave, GTouchCalibrationFetchRoutine fnfetch, BOOL requireFree);
|
||||
|
||||
/* Test if a particular touch instance requires routines to save its calibration data. */
|
||||
BOOL ginputRequireTouchCalibrationStorage(uint16_t instance);
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_KEYBOARD
|
||||
/* Keyboard Functions */
|
||||
GSourceHandle ginputGetKeyboard(uint16_t instance); // Instance = 0 to n-1
|
||||
|
||||
/* Get the current keyboard button status.
|
||||
* Returns FALSE on error (eg invalid instance)
|
||||
*/
|
||||
BOOL ginputGetKeyboardStatus(uint16_t instance, GEventKeyboard *pkeyboard);
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_TOGGLE
|
||||
/* Hardware Toggle/Switch/Button Functions */
|
||||
GSourceHandle ginputGetToggle(uint16_t instance); // Instance = 0 to n-1
|
||||
void ginputInvertToggle(uint16_t instance, BOOL invert); // If invert is true, invert the on/off sense for the toggle
|
||||
|
||||
/* Get the current toggle status.
|
||||
* Returns FALSE on error (eg invalid instance)
|
||||
*/
|
||||
BOOL ginputGetToggleStatus(uint16_t instance, GEventToggle *ptoggle);
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_DIAL
|
||||
/* Dial Functions */
|
||||
GSourceHandle ginputGetDial(uint16_t instance); // Instance = 0 to n-1
|
||||
void ginputResetDialRange(uint16_t instance); // Reset the maximum value back to the hardware default.
|
||||
uint16_t ginputGetDialRange(uint16_t instance); // Get the maximum value. The readings are scaled to be 0...max-1. 0 means over the full uint16_t range.
|
||||
void ginputSetDialRange(uint16_t instance, uint16_t max); // Set the maximum value.
|
||||
void ginputSetDialSensitivity(uint16_t instance, uint16_t diff); // Set the level change required before a dial event is generated.
|
||||
// - This is done after range scaling
|
||||
/* Get the current keyboard button status.
|
||||
* Returns FALSE on error (eg invalid instance)
|
||||
*/
|
||||
BOOL ginputGetDialStatus(uint16_t instance, GEventDial *pdial);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
// Include various ginput types
|
||||
#include "ginput/ginput_mouse.h"
|
||||
#include "ginput/ginput_keyboard.h"
|
||||
#include "ginput/ginput_toggle.h"
|
||||
#include "ginput/ginput_dial.h"
|
||||
|
||||
#endif /* GFX_USE_GINPUT */
|
||||
|
||||
|
|
89
include/ginput/ginput_dial.h
Normal file
89
include/ginput/ginput_dial.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
ChibiOS/GFX - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file ginput/ginput_dial.h
|
||||
* @brief GINPUT GFX User Input subsystem header file.
|
||||
*
|
||||
* @addtogroup GINPUT
|
||||
* @{
|
||||
*/
|
||||
#ifndef _GINPUT_DIAL_H
|
||||
#define _GINPUT_DIAL_H
|
||||
|
||||
/**
|
||||
* @name GINPUT more complex functionality to be compiled
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Should analog dial functions be included.
|
||||
* @details Defaults to FALSE
|
||||
*/
|
||||
#ifndef GINPUT_NEED_DIAL
|
||||
#define GINPUT_NEED_DIAL FALSE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
#if GINPUT_NEED_DIAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver details and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Type definitions */
|
||||
/*===========================================================================*/
|
||||
|
||||
// Event types for various ginput sources
|
||||
#define GEVENT_DIAL (GEVENT_GINPUT_FIRST+4)
|
||||
|
||||
typedef struct GEventDial_t {
|
||||
GEventType type; // The type of this event (GEVENT_DIAL)
|
||||
uint16_t instance; // The dial instance
|
||||
uint16_t value; // The dial value
|
||||
} GEventDial;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Dial Functions */
|
||||
GSourceHandle ginputGetDial(uint16_t instance); // Instance = 0 to n-1
|
||||
void ginputResetDialRange(uint16_t instance); // Reset the maximum value back to the hardware default.
|
||||
uint16_t ginputGetDialRange(uint16_t instance); // Get the maximum value. The readings are scaled to be 0...max-1. 0 means over the full uint16_t range.
|
||||
void ginputSetDialRange(uint16_t instance, uint16_t max); // Set the maximum value.
|
||||
void ginputSetDialSensitivity(uint16_t instance, uint16_t diff); // Set the level change required before a dial event is generated.
|
||||
// - This is done after range scaling
|
||||
/* Get the current keyboard button status.
|
||||
* Returns FALSE on error (eg invalid instance)
|
||||
*/
|
||||
bool_t ginputGetDialStatus(uint16_t instance, GEventDial *pdial);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GINPUT_NEED_DIAL */
|
||||
|
||||
#endif /* _GINPUT_DIAL_H */
|
||||
/** @} */
|
143
include/ginput/ginput_keyboard.h
Normal file
143
include/ginput/ginput_keyboard.h
Normal file
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
ChibiOS/GFX - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file ginput/ginput_keyboard.h
|
||||
* @brief GINPUT GFX User Input subsystem header file.
|
||||
*
|
||||
* @addtogroup GINPUT
|
||||
* @{
|
||||
*/
|
||||
#ifndef _GINPUT_KEYBOARD_H
|
||||
#define _GINPUT_KEYBOARD_H
|
||||
|
||||
/**
|
||||
* @name GINPUT more complex functionality to be compiled
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Should keyboard functions be included.
|
||||
* @details Defaults to FALSE
|
||||
*/
|
||||
#ifndef GINPUT_NEED_KEYBOARD
|
||||
#define GINPUT_NEED_KEYBOARD FALSE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
#if GINPUT_NEED_KEYBOARD || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver details and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Type definitions */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define GINPUT_KEYBOARD_NUM_PORTS 1 // The total number of keyboard inputs
|
||||
|
||||
// Event types for various ginput sources
|
||||
#define GEVENT_KEYBOARD (GEVENT_GINPUT_FIRST+2)
|
||||
|
||||
typedef struct GEventKeyboard_t {
|
||||
GEventType type; // The type of this event (GEVENT_KEYBOARD)
|
||||
uint16_t instance; // The keyboard instance
|
||||
char c; // The Ascii code for the current key press.
|
||||
// The only possible values are 0(NUL), 8(BS), 9(TAB), 13(CR), 27(ESC), 32(SPACE) to 126(~), 127(DEL)
|
||||
// 0 indicates an extended only key.
|
||||
uint16_t code; // An extended keyboard code. Codes less than 128 match their ascii equivelent.
|
||||
#define GKEY_NULL 0
|
||||
#define GKEY_BACKSPACE 8
|
||||
#define GKEY_TAB 9
|
||||
#define GKEY_CR 13
|
||||
#define GKEY_ESC 27
|
||||
#define GKEY_SPACE 32
|
||||
#define GKEY_DEL 127
|
||||
#define GKEY_UP 0x0101
|
||||
#define GKEY_DOWN 0x0102
|
||||
#define GKEY_LEFT 0x0103
|
||||
#define GKEY_RIGHT 0x0104
|
||||
#define GKEY_HOME 0x0105
|
||||
#define GKEY_END 0x0106
|
||||
#define GKEY_PAGEUP 0x0107
|
||||
#define GKEY_PAGEDOWN 0x0108
|
||||
#define GKEY_INSERT 0x0109
|
||||
#define GKEY_DELETE 0x010A
|
||||
#define GKEY_SHIFT 0x0201
|
||||
#define GKEY_CNTRL 0x0202
|
||||
#define GKEY_ALT 0x0203
|
||||
#define GKEY_WINKEY 0x0204
|
||||
#define GKEY_RCLKEY 0x0205
|
||||
#define GKEY_FNKEY 0x0206
|
||||
#define GKEY_FN1 0x0301
|
||||
#define GKEY_FN2 0x0302
|
||||
#define GKEY_FN3 0x0303
|
||||
#define GKEY_FN4 0x0304
|
||||
#define GKEY_FN5 0x0305
|
||||
#define GKEY_FN6 0x0306
|
||||
#define GKEY_FN7 0x0307
|
||||
#define GKEY_FN8 0x0308
|
||||
#define GKEY_FN9 0x0309
|
||||
#define GKEY_FN10 0x030A
|
||||
#define GKEY_FN11 0x030B
|
||||
#define GKEY_FN12 0x030C
|
||||
uint16_t current_buttons; // A bit is set to indicate various meta status.
|
||||
#define GMETA_KEY_DOWN 0x0001
|
||||
#define GMETA_KEY_SHIFT 0x0002
|
||||
#define GMETA_KEY_CNTRL 0x0004
|
||||
#define GMETA_KEY_ALT 0x0008
|
||||
#define GMETA_KEY_WINKEY 0x0010
|
||||
#define GMETA_KEY_RCLKKEY 0x0020
|
||||
#define GMETA_KEY_FN 0x0040
|
||||
#define GMETA_KEY_MISSED_EVENT 0x8000
|
||||
uint16_t last_buttons; // The value of current_buttons on the last event
|
||||
} GEventKeyboard;
|
||||
|
||||
// Keyboard Listen Flags - passed to geventAddSourceToListener()
|
||||
#define GLISTEN_KEYREPEATS 0x0001 // Return key repeats (where the key is held down to get a repeat character)
|
||||
#define GLISTEN_KEYCODES 0x0002 // Return all key presses including extended code key presses (not just ascii codes)
|
||||
#define GLISTEN_KEYALL 0x0004 // Return keyup's, keydown's and everything in between (but not repeats unless GLISTEN_KEYREPEATS is set).
|
||||
#define GLISTEN_KEYSINGLE 0x8000 // Return only when one particular extended code key is pressed or released. The particular extended code is OR'd into this value
|
||||
// eg. (GLISTEN_KEYSINGLE | GKEY_CR)
|
||||
// No other flags may be set with this flag.
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Keyboard Functions */
|
||||
GSourceHandle ginputGetKeyboard(uint16_t instance); // Instance = 0 to n-1
|
||||
|
||||
/* Get the current keyboard button status.
|
||||
* Returns FALSE on error (eg invalid instance)
|
||||
*/
|
||||
bool_t ginputGetKeyboardStatus(uint16_t instance, GEventKeyboard *pkeyboard);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GINPUT_NEED_KEYBOARD */
|
||||
|
||||
#endif /* _GINPUT_KEYBOARD_H */
|
||||
/** @} */
|
135
include/ginput/ginput_mouse.h
Normal file
135
include/ginput/ginput_mouse.h
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
ChibiOS/GFX - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file ginput/ginput_mouse.h
|
||||
* @brief GINPUT GFX User Input subsystem header file for mouse and touch.
|
||||
*
|
||||
* @addtogroup GINPUT
|
||||
* @{
|
||||
*/
|
||||
#ifndef _GINPUT_MOUSE_H
|
||||
#define _GINPUT_MOUSE_H
|
||||
|
||||
/**
|
||||
* @name GINPUT more complex functionality to be compiled
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Should mouse/touch functions be included.
|
||||
* @details Defaults to FALSE
|
||||
*/
|
||||
#ifndef GINPUT_NEED_MOUSE
|
||||
#define GINPUT_NEED_MOUSE FALSE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Type definitions */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if GINPUT_NEED_MOUSE || defined(__DOXYGEN__)
|
||||
|
||||
/* This type definition is also used by touch */
|
||||
typedef struct GEventMouse_t {
|
||||
GEventType type; // The type of this event (GEVENT_MOUSE or GEVENT_TOUCH)
|
||||
uint16_t instance; // The mouse/touch instance
|
||||
coord_t x, y, z; // The position of the mouse.
|
||||
// - For touch devices, Z is the current pressure if supported (otherwise 0)
|
||||
// - For mice, Z is the 3rd dimension if supported (otherwise 0)
|
||||
uint16_t current_buttons; // A bit is set if the button is down.
|
||||
// - For touch only bit 0 is relevant
|
||||
// - For mice the order of the buttons is (from 0 to n) left, right, middle, any other buttons
|
||||
// - Bit 15 being set indicates that an important mouse event has been missed.
|
||||
#define GINPUT_MOUSE_BTN_LEFT 0x0001
|
||||
#define GINPUT_MOUSE_BTN_RIGHT 0x0002
|
||||
#define GINPUT_MOUSE_BTN_MIDDLE 0x0004
|
||||
#define GINPUT_MOUSE_BTN_4 0x0008
|
||||
#define GINPUT_MISSED_MOUSE_EVENT 0x8000
|
||||
#define GINPUT_TOUCH_PRESSED GINPUT_MOUSE_BTN_LEFT
|
||||
uint16_t last_buttons; // The value of current_buttons on the last event
|
||||
enum GMouseMeta_e {
|
||||
GMETA_NONE = 0, // There is no meta event currently happening
|
||||
GMETA_MOUSE_DOWN = 1, // Button 0 has just gone down
|
||||
GMETA_MOUSE_UP = 2, // Button 0 has just gone up
|
||||
GMETA_MOUSE_CLICK = 4, // Button 0 has just gone through a short down - up cycle
|
||||
GMETA_MOUSE_CXTCLICK = 8 // For mice - The right button has just been depressed
|
||||
// For touch - a long press has just occurred
|
||||
} meta;
|
||||
} GEventMouse;
|
||||
|
||||
// Mouse/Touch Listen Flags - passed to geventAddSourceToListener()
|
||||
#define GLISTEN_MOUSEMETA 0x0001 // Create events for meta events such as CLICK and CXTCLICK
|
||||
#define GLISTEN_MOUSEDOWNMOVES 0x0002 // Creates mouse move events when the primary mouse button is down (touch is on the surface)
|
||||
#define GLISTEN_MOUSEUPMOVES 0x0004 // Creates mouse move events when the primary mouse button is up (touch is off the surface - if the hardware allows).
|
||||
#define GLISTEN_MOUSENOFILTER 0x0008 // Don't filter out mouse moves where the position hasn't changed.
|
||||
#define GLISTEN_TOUCHMETA GLISTEN_MOUSEMETA
|
||||
#define GLISTEN_TOUCHDOWNMOVES GLISTEN_MOUSEDOWNMOVES
|
||||
#define GLISTEN_TOUCHUPMOVES GLISTEN_MOUSEUPMOVES
|
||||
#define GLISTEN_TOUCHNOFILTER GLISTEN_MOUSENOFILTER
|
||||
|
||||
#define GINPUT_MOUSE_NUM_PORTS 1 // The total number of mouse/touch inputs supported
|
||||
|
||||
// Event types for the mouse ginput source
|
||||
#define GEVENT_MOUSE (GEVENT_GINPUT_FIRST+0)
|
||||
#define GEVENT_TOUCH (GEVENT_GINPUT_FIRST+1)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Mouse Functions */
|
||||
GSourceHandle ginputGetMouse(uint16_t instance); // Instance = 0 to n-1
|
||||
|
||||
/* Get the current mouse position and button status.
|
||||
* Unlike a listener event, this status cannot record meta events such as "CLICK"
|
||||
* Returns FALSE on error (eg invalid instance)
|
||||
*/
|
||||
bool_t ginputGetMouseStatus(uint16_t instance, GEventMouse *pmouse);
|
||||
|
||||
/* Run a calibration.
|
||||
* Returns FALSE if the driver doesn't support it or if the handle is invalid.
|
||||
*/
|
||||
bool_t ginputCalibrateMouse(uint16_t instance);
|
||||
|
||||
/* Set the routines to save and fetch calibration data.
|
||||
* This function should be called before first calling ginputGetMouse() for a particular instance
|
||||
* as the gdispGetMouse() routine may attempt to fetch calibration data and perform a startup calibration if there is no way to get it.
|
||||
* If this is called after gdispGetMouse() has been called and the driver requires calibration storage, it will immediately save the data is has already obtained.
|
||||
* The 'requireFree' parameter indicates if the fetch buffer must be free()'d to deallocate the buffer provided by the Fetch routine.
|
||||
*/
|
||||
typedef void (*GMouseCalibrationSaveRoutine)(uint16_t instance, const uint8_t *calbuf, size_t sz); // Save calibration data
|
||||
typedef const char * (*GMouseCalibrationLoadRoutine)(uint16_t instance); // Load calibration data (returns NULL if not data saved)
|
||||
void ginputSetMouseCalibrationRoutines(uint16_t instance, GMouseCalibrationSaveRoutine fnsave, GMouseCalibrationLoadRoutine fnload, bool_t requireFree);
|
||||
|
||||
/* Test if a particular mouse/touch instance requires routines to save its calibration data. */
|
||||
bool_t ginputRequireMouseCalibrationStorage(uint16_t instance);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GINPUT_NEED_MOUSE */
|
||||
|
||||
#endif /* _GINPUT_MOUSE_H */
|
||||
/** @} */
|
93
include/ginput/ginput_toggle.h
Normal file
93
include/ginput/ginput_toggle.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
ChibiOS/GFX - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file ginput/ginput_toggle.h
|
||||
* @brief GINPUT GFX User Input subsystem header file.
|
||||
*
|
||||
* @addtogroup GINPUT
|
||||
* @{
|
||||
*/
|
||||
#ifndef _GINPUT_TOGGLE_H
|
||||
#define _GINPUT_TOGGLE_H
|
||||
|
||||
/**
|
||||
* @name GINPUT more complex functionality to be compiled
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Should hardware toggle/switch/button (pio) functions be included.
|
||||
* @details Defaults to FALSE
|
||||
*/
|
||||
#ifndef GINPUT_NEED_TOGGLE
|
||||
#define GINPUT_NEED_TOGGLE FALSE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
#if GINPUT_NEED_TOGGLE || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver details and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Type definitions */
|
||||
/*===========================================================================*/
|
||||
|
||||
// Event types for various ginput sources
|
||||
#define GEVENT_TOGGLE (GEVENT_GINPUT_FIRST+3)
|
||||
|
||||
// Get the hardware definitions - Number of instances etc.
|
||||
#include "ginput_lld_toggle_config.h"
|
||||
|
||||
typedef struct GEventToggle_t {
|
||||
GEventType type; // The type of this event (GEVENT_TOGGLE)
|
||||
uint16_t instance; // The toggle instance
|
||||
bool_t on; // True if the toggle/button is on
|
||||
} GEventToggle;
|
||||
|
||||
// Toggle Listen Flags - passed to geventAddSourceToListener()
|
||||
#define GLISTEN_TOGGLE_ON 0x0001 // Return an event when the toggle turns on
|
||||
#define GLISTEN_TOGGLE_OFF 0x0002 // Return an event when the toggle turns off
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Hardware Toggle/Switch/Button Functions */
|
||||
GSourceHandle ginputGetToggle(uint16_t instance); // Instance = 0 to n-1
|
||||
void ginputInvertToggle(uint16_t instance, bool_t invert); // If invert is true, invert the on/off sense for the toggle
|
||||
|
||||
/* Get the current toggle status.
|
||||
* Returns FALSE on error (eg invalid instance)
|
||||
*/
|
||||
bool_t ginputGetToggleStatus(uint16_t instance, GEventToggle *ptoggle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GINPUT_NEED_TOGGLE */
|
||||
|
||||
#endif /* _GINPUT_TOGGLE_H */
|
||||
/** @} */
|
|
@ -40,7 +40,7 @@
|
|||
/**
|
||||
* @brief Data part of a static GTimer initializer.
|
||||
*/
|
||||
#define _GTIMER_DATA() {0}
|
||||
#define _GTIMER_DATA() {0,0,0,0,0,0,0}
|
||||
/**
|
||||
* @brief Static GTimer initializer.
|
||||
*/
|
||||
|
@ -93,6 +93,7 @@ extern "C" {
|
|||
void gtimerInit(GTimer *pt);
|
||||
void gtimerStart(GTimer *pt, GTimerFunction fn, void *param, bool_t periodic, systime_t millisec);
|
||||
void gtimerStop(GTimer *pt);
|
||||
bool_t gtimerIsActive(GTimer *pt);
|
||||
void gtimerJab(GTimer *pt);
|
||||
void gtimerJabI(GTimer *pt);
|
||||
|
||||
|
|
107
include/gwin.h
107
include/gwin.h
|
@ -45,21 +45,6 @@
|
|||
* @name GWIN more complex functionality to be compiled
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Should console functions be included.
|
||||
* @details Defaults to FALSE
|
||||
*/
|
||||
#ifndef GWIN_NEED_CONSOLE
|
||||
#define GWIN_NEED_CONSOLE FALSE
|
||||
#endif
|
||||
/**
|
||||
* @brief Should button functions be included.
|
||||
* @details Defaults to FALSE
|
||||
*/
|
||||
#ifndef GWIN_NEED_BUTTON
|
||||
#define GWIN_NEED_BUTTON FALSE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -75,25 +60,13 @@
|
|||
#warning "GWIN: Drawing can occur outside the defined window as GDISP_NEED_CLIP is FALSE"
|
||||
#endif
|
||||
|
||||
#if GWIN_NEED_CONSOLE && !GDISP_NEED_TEXT
|
||||
#error "GWIN: Text support (GDISP_NEED_TEXT) is required if GWIN_NEED_CONSOLE is defined."
|
||||
#endif
|
||||
|
||||
#if GWIN_NEED_BUTTON && !GDISP_NEED_TEXT
|
||||
#error "GWIN: Text support (GDISP_NEED_TEXT) is required if GWIN_NEED_BUTTON is defined."
|
||||
#endif
|
||||
|
||||
#if GWIN_NEED_BUTTON
|
||||
#warning "GWIN: Button support is not complete yet"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Type definitions */
|
||||
/*===========================================================================*/
|
||||
|
||||
typedef enum GWindowType_e {
|
||||
GW_WINDOW, GW_CONSOLE, GW_BUTTON
|
||||
} GWindowType;
|
||||
typedef uint16_t GWindowType;
|
||||
#define GW_WINDOW 0x0000
|
||||
#define GW_FIRST_USER_WINDOW 0x8000
|
||||
|
||||
// A basic window
|
||||
typedef struct GWindowObject_t {
|
||||
|
@ -107,58 +80,6 @@ typedef struct GWindowObject_t {
|
|||
#endif
|
||||
} GWindowObject, * GHandle;
|
||||
|
||||
#if GWIN_NEED_CONSOLE
|
||||
// A console window. Supports wrapped text writing and a cursor.
|
||||
typedef struct GConsoleObject_t {
|
||||
GWindowObject gwin;
|
||||
|
||||
struct GConsoleWindowStream_t {
|
||||
const struct GConsoleWindowVMT_t *vmt;
|
||||
_base_asynchronous_channel_data
|
||||
} stream;
|
||||
|
||||
coord_t cx,cy; // Cursor position
|
||||
uint8_t fy; // Current font height
|
||||
uint8_t fp; // Current font inter-character spacing
|
||||
} GConsoleObject;
|
||||
#endif
|
||||
|
||||
#if GWIN_NEED_BUTTON
|
||||
typedef enum GButtonShape_e {
|
||||
GBTN_3D, GBTN_SQUARE, GBTN_ROUNDED, GBTN_ELLIPSE
|
||||
} GButtonShape;
|
||||
|
||||
typedef struct GButtonStyle_t {
|
||||
GButtonShape shape;
|
||||
color_t color_up_edge;
|
||||
color_t color_up_fill;
|
||||
color_t color_up_txt;
|
||||
color_t color_dn_edge;
|
||||
color_t color_dn_fill;
|
||||
color_t color_dn_txt;
|
||||
} GButtonStyle;
|
||||
|
||||
typedef enum GButtonType_e {
|
||||
GBTN_NORMAL, GBTN_TOGGLE
|
||||
} GButtonType;
|
||||
|
||||
typedef enum GButtonState_e {
|
||||
GBTN_UP, GBTN_DOWN
|
||||
} GButtonState;
|
||||
|
||||
// A button window
|
||||
typedef struct GButtonObject_t {
|
||||
GWindowObject gwin;
|
||||
|
||||
GButtonStyle style;
|
||||
GButtonState state;
|
||||
GButtonType type;
|
||||
const char * txt;
|
||||
void * callback; // To be fixed
|
||||
void * inputsrc; // To be fixed
|
||||
} GButtonObject;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
@ -268,28 +189,14 @@ void gwinDrawStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy,
|
|||
void gwinFillStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify);
|
||||
#endif
|
||||
|
||||
#if GWIN_NEED_CONSOLE
|
||||
GHandle gwinCreateConsole(GConsoleObject *gc, coord_t x, coord_t y, coord_t width, coord_t height, font_t font);
|
||||
BaseSequentialStream *gwinGetConsoleStream(GHandle gh);
|
||||
void gwinPutChar(GHandle gh, char c);
|
||||
void gwinPutString(GHandle gh, const char *str);
|
||||
void gwinPutCharArray(GHandle gh, const char *str, size_t n);
|
||||
#endif
|
||||
|
||||
#if GWIN_NEED_BUTTON
|
||||
GHandle gwinCreateButton(GButtonObject *gb, coord_t x, coord_t y, coord_t width, coord_t height, font_t font, GButtonType type);
|
||||
void gwinSetButtonStyle(GHandle gh, const GButtonStyle *style);
|
||||
void gwinSetButtonText(GHandle gh, const char *txt, bool_t useAlloc);
|
||||
void gwinButtonDraw(GHandle gh);
|
||||
#define gwinGetButtonState(gh) (((GButtonObject *)(gh))->state)
|
||||
//void gwinSetButtonCallback(GHandle gh, ????);
|
||||
//void gwinSetButtonInput(GHandle gh, ????);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Include extra window types */
|
||||
#include "gwin/gwin_console.h"
|
||||
#include "gwin/gwin_button.h"
|
||||
|
||||
#endif /* GFX_USE_GWIN */
|
||||
|
||||
#endif /* _GWIN_H */
|
||||
|
|
142
include/gwin/gwin_button.h
Normal file
142
include/gwin/gwin_button.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
ChibiOS/GFX - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file gwin/gwin_button.h
|
||||
* @brief GWIN Graphic window subsystem header file.
|
||||
*
|
||||
* @addtogroup GWIN
|
||||
* @{
|
||||
*/
|
||||
#ifndef _GWIN_BUTTON_H
|
||||
#define _GWIN_BUTTON_H
|
||||
|
||||
/**
|
||||
* @name GWIN more complex functionality to be compiled
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Should button functions be included.
|
||||
* @details Defaults to FALSE
|
||||
*/
|
||||
#ifndef GWIN_NEED_BUTTON
|
||||
#define GWIN_NEED_BUTTON FALSE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#if GWIN_NEED_BUTTON || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define GW_BUTTON 0x0002
|
||||
#define GEVENT_GWIN_BUTTON (GEVENT_GWIN_FIRST+0)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver details and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !GDISP_NEED_TEXT
|
||||
#error "GWIN: Text support (GDISP_NEED_TEXT) is required if GWIN_NEED_BUTTON is defined."
|
||||
#endif
|
||||
|
||||
#if !defined(GFX_USE_GEVENT) || !GFX_USE_GEVENT
|
||||
#error "GWIN Buttons require GFX_USE_GEVENT"
|
||||
#endif
|
||||
#include "gevent.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Type definitions */
|
||||
/*===========================================================================*/
|
||||
|
||||
typedef struct GEventGWinButton_t {
|
||||
GEventType type; // The type of this event (GEVENT_GWIN_BUTTON)
|
||||
GHandle button; // The button that has been depressed (actually triggered on release)
|
||||
} GEventGWinButton;
|
||||
|
||||
// There are currently no GEventGWinButton listening flags - use 0
|
||||
|
||||
typedef enum GButtonShape_e {
|
||||
GBTN_3D, GBTN_SQUARE, GBTN_ROUNDED, GBTN_ELLIPSE
|
||||
} GButtonShape;
|
||||
|
||||
typedef struct GButtonStyle_t {
|
||||
GButtonShape shape;
|
||||
color_t color_up_edge;
|
||||
color_t color_up_fill;
|
||||
color_t color_up_txt;
|
||||
color_t color_dn_edge;
|
||||
color_t color_dn_fill;
|
||||
color_t color_dn_txt;
|
||||
} GButtonStyle;
|
||||
|
||||
typedef enum GButtonType_e {
|
||||
GBTN_NORMAL, GBTN_TOGGLE
|
||||
} GButtonType;
|
||||
|
||||
typedef enum GButtonState_e {
|
||||
GBTN_UP, GBTN_DOWN
|
||||
} GButtonState;
|
||||
|
||||
// A button window
|
||||
typedef struct GButtonObject_t {
|
||||
GWindowObject gwin;
|
||||
|
||||
GButtonStyle style;
|
||||
GButtonState state;
|
||||
GButtonType type;
|
||||
const char * txt;
|
||||
GListener listener;
|
||||
} GButtonObject;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
GHandle gwinCreateButton(GButtonObject *gb, coord_t x, coord_t y, coord_t width, coord_t height, font_t font, GButtonType type);
|
||||
void gwinSetButtonStyle(GHandle gh, const GButtonStyle *style);
|
||||
void gwinSetButtonText(GHandle gh, const char *txt, bool_t useAlloc);
|
||||
void gwinButtonDraw(GHandle gh);
|
||||
#define gwinGetButtonState(gh) (((GButtonObject *)(gh))->state)
|
||||
|
||||
// Get the source handle so the application can listen for events
|
||||
#define gwinGetButtonSource(gh) ((GSourceHandle)(gh))
|
||||
|
||||
// Attach a source to this button. Sources recognised: Mouse, Touch and Toggle - others are ignored (returns false).
|
||||
bool_t gwinAttachButtonSource(GHandle gh, GSourceHandle gsh, GEventType type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GWIN_NEED_BUTTON */
|
||||
|
||||
#endif /* _GWIN_BUTTON_H */
|
||||
/** @} */
|
102
include/gwin/gwin_console.h
Normal file
102
include/gwin/gwin_console.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
ChibiOS/GFX - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file gwin/gwin_console.h
|
||||
* @brief GWIN Graphic window subsystem header file.
|
||||
*
|
||||
* @addtogroup GWIN
|
||||
* @{
|
||||
*/
|
||||
#ifndef _GWIN_CONSOLE_H
|
||||
#define _GWIN_CONSOLE_H
|
||||
|
||||
/**
|
||||
* @name GWIN more complex functionality to be compiled
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Should console functions be included.
|
||||
* @details Defaults to FALSE
|
||||
*/
|
||||
#ifndef GWIN_NEED_CONSOLE
|
||||
#define GWIN_NEED_CONSOLE FALSE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
#if GWIN_NEED_CONSOLE || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define GW_CONSOLE 0x0001
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver details and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if GWIN_NEED_CONSOLE && !GDISP_NEED_TEXT
|
||||
#error "GWIN: Text support (GDISP_NEED_TEXT) is required if GWIN_NEED_CONSOLE is defined."
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Type definitions */
|
||||
/*===========================================================================*/
|
||||
|
||||
// A console window. Supports wrapped text writing and a cursor.
|
||||
typedef struct GConsoleObject_t {
|
||||
GWindowObject gwin;
|
||||
|
||||
struct GConsoleWindowStream_t {
|
||||
const struct GConsoleWindowVMT_t *vmt;
|
||||
_base_asynchronous_channel_data
|
||||
} stream;
|
||||
|
||||
coord_t cx,cy; // Cursor position
|
||||
uint8_t fy; // Current font height
|
||||
uint8_t fp; // Current font inter-character spacing
|
||||
} GConsoleObject;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
GHandle gwinCreateConsole(GConsoleObject *gc, coord_t x, coord_t y, coord_t width, coord_t height, font_t font);
|
||||
BaseSequentialStream *gwinGetConsoleStream(GHandle gh);
|
||||
void gwinPutChar(GHandle gh, char c);
|
||||
void gwinPutString(GHandle gh, const char *str);
|
||||
void gwinPutCharArray(GHandle gh, const char *str, size_t n);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GWIN_NEED_CONSOLE */
|
||||
|
||||
#endif /* _GWIN_CONSOLE_H */
|
||||
/** @} */
|
|
@ -481,7 +481,7 @@
|
|||
#endif
|
||||
|
||||
#if GDISP_NEED_TEXT && !GDISP_HARDWARE_TEXT
|
||||
#include "gdisp_fonts.h"
|
||||
#include "gdisp/fonts.h"
|
||||
#endif
|
||||
|
||||
#if GDISP_NEED_TEXT && !GDISP_HARDWARE_TEXT
|
125
include/lld/ginput/mouse.h
Normal file
125
include/lld/ginput/mouse.h
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
ChibiOS/GFX - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file lld/ginput/mouse.h
|
||||
* @brief GINPUT LLD header file for mouse/touch drivers.
|
||||
*
|
||||
* @addtogroup GINPUT_MOUSE
|
||||
* @{
|
||||
*/
|
||||
#ifndef _LLD_GINPUT_MOUSE_H
|
||||
#define _LLD_GINPUT_MOUSE_H
|
||||
|
||||
#ifndef GINPUT_NEED_MOUSE
|
||||
#define GINPUT_NEED_MOUSE FALSE
|
||||
#endif
|
||||
#ifndef GINPUT_NEED_TOUCH
|
||||
#define GINPUT_NEED_TOUCH FALSE
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_MOUSE || GINPUT_NEED_TOUCH
|
||||
|
||||
#include "ginput_lld_mouse_config.h"
|
||||
|
||||
// GEVENT_MOUSE or GEVENT_TOUCH - What type of device is this.
|
||||
#ifndef GINPUT_MOUSE_EVENT_TYPE
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_MOUSE
|
||||
#endif
|
||||
|
||||
// TRUE/FALSE - Does the mouse/touch driver require calibration?
|
||||
#ifndef GINPUT_MOUSE_NEED_CALIBRATION
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION FALSE
|
||||
#endif
|
||||
|
||||
// TRUE/FALSE - Can the mouse/touch driver itself save calibration data?
|
||||
#ifndef GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#endif
|
||||
|
||||
// n or -1 - n means to test calibration result (+/- pixels), -1 means not to.
|
||||
#ifndef GINPUT_MOUSE_MAX_CALIBRATION_ERROR
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR -1
|
||||
#endif
|
||||
|
||||
// n - How many times to read (and average) per poll
|
||||
#ifndef GINPUT_MOUSE_READ_CYCLES
|
||||
#define GINPUT_MOUSE_READ_CYCLES 1
|
||||
#endif
|
||||
|
||||
// n - Millisecs between poll's
|
||||
#ifndef GINPUT_MOUSE_POLL_PERIOD
|
||||
#define GINPUT_MOUSE_POLL_PERIOD 100
|
||||
#endif
|
||||
|
||||
// n - Movement allowed without discarding the CLICK or CLICKCXT event (+/- pixels)
|
||||
#ifndef GINPUT_MOUSE_MAX_CLICK_JITTER
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 1
|
||||
#endif
|
||||
|
||||
// n - Movement allowed without discarding the MOVE event (+/- pixels)
|
||||
#ifndef GINPUT_MOUSE_MAX_MOVE_JITTER
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 0
|
||||
#endif
|
||||
|
||||
// ms - Millisecs seperating a CLICK from a CXTCLICK
|
||||
#ifndef GINPUT_MOUSE_CLICK_TIME
|
||||
#define GINPUT_MOUSE_CLICK_TIME 700
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct MouseReading_t {
|
||||
coord_t x, y, z;
|
||||
uint16_t buttons;
|
||||
} MouseReading;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void ginput_lld_mouse_init(void);
|
||||
void ginput_lld_mouse_get_reading(MouseReading *pt);
|
||||
|
||||
#if GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE
|
||||
const char *ginput_lld_mouse_calibration_load(uint16_t instance);
|
||||
void ginput_lld_mouse_calibration_save(uint16_t instance, const uint8_t *calbuf, size_t sz);
|
||||
#endif
|
||||
|
||||
/* This routine is provided to low level drivers to wakeup a value read from a thread context.
|
||||
* Particularly useful if GINPUT_MOUSE_POLL_PERIOD = TIME_INFINITE
|
||||
*/
|
||||
void ginputMouseWakeup(void);
|
||||
|
||||
/* This routine is provided to low level drivers to wakeup a value read from an ISR
|
||||
* Particularly useful if GINPUT_MOUSE_POLL_PERIOD = TIME_INFINITE
|
||||
*/
|
||||
void ginputMouseWakeupI(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GINPUT_NEED_MOUSE || GINPUT_NEED_TOUCH */
|
||||
|
||||
#endif /* _LLD_GINPUT_MOUSE_H */
|
||||
/** @} */
|
71
include/lld/ginput/toggle.h
Normal file
71
include/lld/ginput/toggle.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
ChibiOS/GFX - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file lld/ginput/toggle.h
|
||||
* @brief GINPUT header file for toggle drivers.
|
||||
*
|
||||
* @addtogroup GINPUT_TOGGLE
|
||||
* @{
|
||||
*/
|
||||
#ifndef _LLD_GINPUT_TOGGLE_H
|
||||
#define _LLD_GINPUT_TOGGLE_H
|
||||
|
||||
#ifndef GFX_USE_GINPUT
|
||||
#define GFX_USE_GINPUT FALSE
|
||||
#endif
|
||||
|
||||
#if GFX_USE_GINPUT || defined(__DOXYGEN__)
|
||||
|
||||
#if GINPUT_NEED_TOGGLE
|
||||
// Describes how the toggle bits are obtained
|
||||
typedef struct GToggleConfig_t {
|
||||
void *id;
|
||||
unsigned mask;
|
||||
unsigned invert;
|
||||
iomode_t mode;
|
||||
} GToggleConfig;
|
||||
#endif
|
||||
|
||||
// This must be included after the above type definition
|
||||
#include "ginput.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_TOGGLE
|
||||
extern const GToggleConfig GInputToggleConfigTable[GINPUT_TOGGLE_CONFIG_ENTRIES];
|
||||
|
||||
void ginput_lld_toggle_init(const GToggleConfig *ptc);
|
||||
unsigned ginput_lld_toggle_getbits(const GToggleConfig *ptc);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GFX_USE_GINPUT */
|
||||
|
||||
#endif /* _LLD_GINPUT_TOGGLE_H */
|
||||
/** @} */
|
|
@ -40,7 +40,7 @@
|
|||
/*===========================================================================*/
|
||||
|
||||
/* Include the low level driver information */
|
||||
#include "touchscreen_lld.h"
|
||||
#include "lld/touchscreen/touchscreen_lld.h"
|
||||
|
||||
/* For definitions of coord_t, we require gdisp.h */
|
||||
#include "gdisp.h"
|
||||
|
|
10
src/gdisp.c
10
src/gdisp.c
|
@ -32,7 +32,7 @@
|
|||
#if GFX_USE_GDISP || defined(__DOXYGEN__)
|
||||
|
||||
#ifdef GDISP_NEED_TEXT
|
||||
#include "gdisp_fonts.h"
|
||||
#include "gdisp/fonts.h"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -487,13 +487,13 @@
|
|||
*
|
||||
* @api
|
||||
*/
|
||||
void gdispDrawArc(coord_t x, coord_t y, coord_t radius, uint16_t start, uint16_t end, color_t color) {
|
||||
void gdispDrawArc(coord_t x, coord_t y, coord_t radius, coord_t start, coord_t end, color_t color) {
|
||||
chMtxLock(&gdispMutex);
|
||||
GDISP_LLD(drawarc)(x, y, radius, start, end, color);
|
||||
chMtxUnlock();
|
||||
}
|
||||
#elif GDISP_NEED_ARC && GDISP_NEED_ASYNC
|
||||
void gdispDrawArc(coord_t x, coord_t y, coord_t radius, uint16_t start, uint16_t end, color_t color) {
|
||||
void gdispDrawArc(coord_t x, coord_t y, coord_t radius, coord_t start, coord_t end, color_t color) {
|
||||
gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_DRAWARC);
|
||||
p->drawarc.x = x;
|
||||
p->drawarc.y = y;
|
||||
|
@ -518,13 +518,13 @@
|
|||
*
|
||||
* @api
|
||||
*/
|
||||
void gdispFillArc(coord_t x, coord_t y, coord_t radius, uint16_t start, uint16_t end, color_t color) {
|
||||
void gdispFillArc(coord_t x, coord_t y, coord_t radius, coord_t start, coord_t end, color_t color) {
|
||||
chMtxLock(&gdispMutex);
|
||||
GDISP_LLD(fillarc)(x, y, radius, start, end, color);
|
||||
chMtxUnlock();
|
||||
}
|
||||
#elif GDISP_NEED_ARC && GDISP_NEED_ASYNC
|
||||
void gdispFillArc(coord_t x, coord_t y, coord_t radius, uint16_t start, uint16_t end, color_t color) {
|
||||
void gdispFillArc(coord_t x, coord_t y, coord_t radius, coord_t start, coord_t end, color_t color) {
|
||||
gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_FILLARC);
|
||||
p->fillarc.x = x;
|
||||
p->fillarc.y = y;
|
||||
|
|
|
@ -29,7 +29,8 @@
|
|||
|
||||
#if GDISP_NEED_TEXT
|
||||
|
||||
#include "gdisp_fonts.h"
|
||||
#include "gdisp/fonts.h"
|
||||
|
||||
|
||||
/* fontSmall - for side buttons */
|
||||
#if 1
|
||||
|
|
46
src/gevent.c
46
src/gevent.c
|
@ -71,6 +71,7 @@ static void deleteAssignments(GListener *pl, GSourceHandle gsh) {
|
|||
void geventListenerInit(GListener *pl) {
|
||||
chSemInit(&pl->waitqueue, 0); // Next wait'er will block
|
||||
chBSemInit(&pl->eventlock, FALSE); // Only one thread at a time looking at the event buffer
|
||||
pl->callback = 0; // No callback active
|
||||
pl->event.type = GEVENT_NULL; // Always safety
|
||||
}
|
||||
|
||||
|
@ -165,9 +166,45 @@ void geventDetachSource(GListener *pl, GSourceHandle gsh) {
|
|||
* @return NULL on timeout
|
||||
*/
|
||||
GEvent *geventEventWait(GListener *pl, systime_t timeout) {
|
||||
if (pl->callback || chSemGetCounterI(&pl->waitqueue) < 0)
|
||||
return 0;
|
||||
return chSemWaitTimeout(&pl->waitqueue, timeout) == RDY_OK ? &pl->event : 0;
|
||||
}
|
||||
|
||||
/* @brief Register a callback for an event on a listener from an assigned source.
|
||||
* @details The type of the event should be checked (pevent->type) and then pevent should be typecast to the
|
||||
* actual event type if it needs to be processed.
|
||||
*
|
||||
* @params[in] pl The Listener
|
||||
* @params[in] fn The function to call back
|
||||
* @params[in] param A parameter to pass the callback function
|
||||
*
|
||||
* @note The GEvent buffer is valid only during the time of the callback. The callback MUST NOT save
|
||||
* a pointer to the buffer for use outside the callback.
|
||||
* @note An existing callback function is de-registered by passing a NULL for 'fn'. Any existing
|
||||
* callback function is replaced. Any thread currently waiting using geventEventWait will be sent the exit event.
|
||||
* @note Callbacks occur in a thread context but stack space must be kept to a minumum and
|
||||
* the callback must process quickly as all other events are performed on a single thread.
|
||||
* @note In the callback function you should never call ANY event functions using your own GListener handle
|
||||
* as it WILL create a deadlock and lock the system up.
|
||||
* @note Applications should not use this call - geventEventWait() is the preferred mechanism for an
|
||||
* application. This call is provided for GUI objects that may not have their own thread.
|
||||
*/
|
||||
void geventRegisterCallback(GListener *pl, GEventCallbackFn fn, void *param) {
|
||||
if (pl) {
|
||||
chMtxLock(&geventMutex);
|
||||
chBSemWait(&pl->eventlock); // Obtain the buffer lock
|
||||
pl->param = param; // Set the param
|
||||
pl->callback = fn; // Set the callback function
|
||||
if (chSemGetCounterI(&pl->waitqueue) < 0) {
|
||||
pl->event.type = GEVENT_EXIT; // Set up the EXIT event
|
||||
chSemSignal(&pl->waitqueue); // Wake up the listener
|
||||
}
|
||||
chBSemSignal(&pl->eventlock); // Release the buffer lock
|
||||
chMtxUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Called by a source with a possible event to get a listener record.
|
||||
* @details @p lastlr should be NULL on the first call and thereafter the result of the previous call.
|
||||
|
@ -215,7 +252,7 @@ GSourceListener *geventGetSourceListener(GSourceHandle gsh, GSourceListener *las
|
|||
*/
|
||||
GEvent *geventGetEventBuffer(GSourceListener *psl) {
|
||||
// We already know we have the event lock
|
||||
return chSemGetCounterI(&psl->pListener->waitqueue) < 0 ? &psl->pListener->event : 0;
|
||||
return &psl->pListener->callback || chSemGetCounterI(&psl->pListener->waitqueue) < 0 ? &psl->pListener->event : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -226,11 +263,18 @@ GEvent *geventGetEventBuffer(GSourceListener *psl) {
|
|||
*/
|
||||
void geventSendEvent(GSourceListener *psl) {
|
||||
chMtxLock(&geventMutex);
|
||||
if (psl->pListener->callback) { // This test needs to be taken inside the mutex
|
||||
chMtxUnlock();
|
||||
// We already know we have the event lock
|
||||
psl->pListener->callback(psl->pListener->param, &psl->pListener->event);
|
||||
|
||||
} else {
|
||||
// Wake up the listener
|
||||
if (chSemGetCounterI(&psl->pListener->waitqueue) < 0)
|
||||
chSemSignal(&psl->pListener->waitqueue);
|
||||
chMtxUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Detach any listener that has this source attached
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file src/ginput.c
|
||||
* @brief GINPUT Driver code.
|
||||
* @file src/ginput/dial.c
|
||||
* @brief GINPUT dial code.
|
||||
*
|
||||
* @addtogroup GINPUT
|
||||
* @{
|
||||
|
@ -29,9 +29,7 @@
|
|||
#include "hal.h"
|
||||
#include "ginput.h"
|
||||
|
||||
#if GFX_USE_GINPUT || defined(__DOXYGEN__)
|
||||
|
||||
#error "GINPUT: Not Implemented Yet"
|
||||
|
||||
#endif /* GFX_USE_GINPUT */
|
||||
#if GINPUT_NEED_DIAL || defined(__DOXYGEN__)
|
||||
#error "GINPUT: GINPUT_NEED_DIAL - Not Implemented Yet"
|
||||
#endif /* GINPUT_NEED_DIAL */
|
||||
/** @} */
|
4
src/ginput/ginput.mk
Normal file
4
src/ginput/ginput.mk
Normal file
|
@ -0,0 +1,4 @@
|
|||
GFXSRC += $(GFXLIB)/src/ginput/mouse.c \
|
||||
$(GFXLIB)/src/ginput/keyboard.c \
|
||||
$(GFXLIB)/src/ginput/toggle.c \
|
||||
$(GFXLIB)/src/ginput/dial.c
|
35
src/ginput/keyboard.c
Normal file
35
src/ginput/keyboard.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
ChibiOS/GFX - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file src/ginput/keyboard.c
|
||||
* @brief GINPUT keyboard code.
|
||||
*
|
||||
* @addtogroup GINPUT
|
||||
* @{
|
||||
*/
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include "ginput.h"
|
||||
|
||||
#if GINPUT_NEED_KEYBOARD || defined(__DOXYGEN__)
|
||||
#error "GINPUT: GINPUT_NEED_KEYBOARD - Not Implemented Yet"
|
||||
#endif /* GINPUT_NEED_KEYBOARD */
|
||||
/** @} */
|
554
src/ginput/mouse.c
Normal file
554
src/ginput/mouse.c
Normal file
|
@ -0,0 +1,554 @@
|
|||
/*
|
||||
ChibiOS/GFX - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file src/ginput/mouse.c
|
||||
* @brief GINPUT mouse/touch code.
|
||||
*
|
||||
* @addtogroup GINPUT_MOUSE
|
||||
* @{
|
||||
*/
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include "gtimer.h"
|
||||
#include "ginput.h"
|
||||
|
||||
#if GINPUT_NEED_MOUSE || defined(__DOXYGEN__)
|
||||
|
||||
#include "lld/ginput/mouse.h"
|
||||
|
||||
#if GINPUT_MOUSE_NEED_CALIBRATION
|
||||
#if !defined(GFX_USE_GDISP) || !GFX_USE_GDISP
|
||||
#error "GINPUT: GFX_USE_GDISP must be defined when mouse or touch calibration is required"
|
||||
#endif
|
||||
|
||||
#define GINPUT_MOUSE_CALIBRATION_FONT &fontUI2Double
|
||||
#define GINPUT_MOUSE_CALIBRATION_TEXT "Calibration"
|
||||
|
||||
#if GINPUT_MOUSE_MAX_CALIBRATION_ERROR < 0
|
||||
#define GINPUT_MOUSE_CALIBRATION_POINTS 3
|
||||
#else
|
||||
#define GINPUT_MOUSE_CALIBRATION_POINTS 4
|
||||
#endif
|
||||
|
||||
typedef struct Calibration_t {
|
||||
float ax;
|
||||
float bx;
|
||||
float cx;
|
||||
float ay;
|
||||
float by;
|
||||
float cy;
|
||||
} Calibration;
|
||||
#endif
|
||||
|
||||
typedef struct MousePoint_t {
|
||||
coord_t x, y;
|
||||
} MousePoint;
|
||||
|
||||
static GTIMER_DECL(MouseTimer);
|
||||
|
||||
static struct MouseConfig_t {
|
||||
MouseReading t;
|
||||
MousePoint movepos;
|
||||
MousePoint clickpos;
|
||||
systime_t clicktime;
|
||||
uint16_t last_buttons;
|
||||
uint16_t flags;
|
||||
#define FLG_INIT_DONE 0x8000
|
||||
#define FLG_CLICK_TIMER 0x0001
|
||||
#define FLG_IN_CAL 0x0010
|
||||
#define FLG_CAL_OK 0x0020
|
||||
#define FLG_CAL_SAVED 0x0040
|
||||
#define FLG_CAL_FREE 0x0080
|
||||
#if GINPUT_MOUSE_NEED_CALIBRATION
|
||||
GMouseCalibrationSaveRoutine fnsavecal;
|
||||
GMouseCalibrationLoadRoutine fnloadcal;
|
||||
Calibration caldata;
|
||||
#endif
|
||||
} MouseConfig;
|
||||
|
||||
#if GINPUT_MOUSE_NEED_CALIBRATION
|
||||
static __inline void _tsDrawCross(const MousePoint *pp) {
|
||||
gdispDrawLine(pp->x-15, pp->y, pp->x-2, pp->y, White);
|
||||
gdispDrawLine(pp->x+2, pp->y, pp->x+15, pp->y, White);
|
||||
gdispDrawLine(pp->x, pp->y-15, pp->x, pp->y-2, White);
|
||||
gdispDrawLine(pp->x, pp->y+2, pp->x, pp->y+15, White);
|
||||
|
||||
gdispDrawLine(pp->x-15, pp->y+15, pp->x-7, pp->y+15, RGB2COLOR(184,158,131));
|
||||
gdispDrawLine(pp->x-15, pp->y+7, pp->x-15, pp->y+15, RGB2COLOR(184,158,131));
|
||||
|
||||
gdispDrawLine(pp->x-15, pp->y-15, pp->x-7, pp->y-15, RGB2COLOR(184,158,131));
|
||||
gdispDrawLine(pp->x-15, pp->y-7, pp->x-15, pp->y-15, RGB2COLOR(184,158,131));
|
||||
|
||||
gdispDrawLine(pp->x+7, pp->y+15, pp->x+15, pp->y+15, RGB2COLOR(184,158,131));
|
||||
gdispDrawLine(pp->x+15, pp->y+7, pp->x+15, pp->y+15, RGB2COLOR(184,158,131));
|
||||
|
||||
gdispDrawLine(pp->x+7, pp->y-15, pp->x+15, pp->y-15, RGB2COLOR(184,158,131));
|
||||
gdispDrawLine(pp->x+15, pp->y-15, pp->x+15, pp->y-7, RGB2COLOR(184,158,131));
|
||||
}
|
||||
|
||||
static __inline void _tsClearCross(const MousePoint *pp) {
|
||||
gdispFillArea(pp->x - 15, pp->y - 15, 42, 42, Blue);
|
||||
}
|
||||
|
||||
static __inline void _tsTransform(MouseReading *pt, const Calibration *c) {
|
||||
pt->x = (coord_t) (c->ax * pt->x + c->bx * pt->y + c->cx);
|
||||
pt->y = (coord_t) (c->ay * pt->x + c->by * pt->y + c->cy);
|
||||
}
|
||||
|
||||
static __inline void _tsDo3PointCalibration(const MousePoint *cross, const MousePoint *points, Calibration *c) {
|
||||
float dx, dx0, dx1, dx2, dy0, dy1, dy2;
|
||||
|
||||
/* Compute all the required determinants */
|
||||
dx = ((float)(points[0].x - points[2].x)) * ((float)(points[1].y - points[2].y))
|
||||
- ((float)(points[1].x - points[2].x)) * ((float)(points[0].y - points[2].y));
|
||||
|
||||
dx0 = ((float)(cross[0].x - cross[2].x)) * ((float)(points[1].y - points[2].y))
|
||||
- ((float)(cross[1].x - cross[2].x)) * ((float)(points[0].y - points[2].y));
|
||||
|
||||
dx1 = ((float)(cross[1].x - cross[2].x)) * ((float)(points[0].x - points[2].x))
|
||||
- ((float)(cross[0].x - cross[2].x)) * ((float)(points[1].x - points[2].x));
|
||||
|
||||
dx2 = cross[0].x * ((float)points[1].x * (float)points[2].y - (float)points[2].x * (float)points[1].y) -
|
||||
cross[1].x * ((float)points[0].x * (float)points[2].y - (float)points[2].x * (float)points[0].y) +
|
||||
cross[2].x * ((float)points[0].x * (float)points[1].y - (float)points[1].x * (float)points[0].y);
|
||||
|
||||
dy0 = ((float)(cross[0].y - cross[2].y)) * ((float)(points[1].y - points[2].y))
|
||||
- ((float)(cross[1].y - cross[2].y)) * ((float)(points[0].y - points[2].y));
|
||||
|
||||
dy1 = ((float)(cross[1].y - cross[2].y)) * ((float)(points[0].x - points[2].x))
|
||||
- ((float)(cross[0].y - cross[2].y)) * ((float)(points[1].x - points[2].x));
|
||||
|
||||
dy2 = cross[0].y * ((float)points[1].x * (float)points[2].y - (float)points[2].x * (float)points[1].y) -
|
||||
cross[1].y * ((float)points[0].x * (float)points[2].y - (float)points[2].x * (float)points[0].y) +
|
||||
cross[2].y * ((float)points[0].x * (float)points[1].y - (float)points[1].x * (float)points[0].y);
|
||||
|
||||
/* Now, calculate all the required coefficients */
|
||||
c->ax = dx0 / dx;
|
||||
c->bx = dx1 / dx;
|
||||
c->cx = dx2 / dx;
|
||||
|
||||
c->ay = dy0 / dx;
|
||||
c->by = dy1 / dx;
|
||||
c->cy = dy2 / dx;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GINPUT_MOUSE_READ_CYCLES > 1
|
||||
static void get_raw_reading(MouseReading *pt) {
|
||||
int32_t x, y, z;
|
||||
unsigned i;
|
||||
|
||||
x = y = z = 0;
|
||||
for(i = 0; i < GINPUT_MOUSE_READ_CYCLES; i++) {
|
||||
ginput_lld_mouse_get_reading(pt);
|
||||
x += pt->x;
|
||||
y += pt->y;
|
||||
z += pt->z;
|
||||
}
|
||||
|
||||
/* Take the average of the readings */
|
||||
pt->x = x / GINPUT_MOUSE_READ_CYCLES;
|
||||
pt->y = y / GINPUT_MOUSE_READ_CYCLES;
|
||||
pt->z = z / GINPUT_MOUSE_READ_CYCLES;
|
||||
}
|
||||
#else
|
||||
#define get_raw_reading(pt) ginput_lld_mouse_get_reading(pt)
|
||||
#endif
|
||||
|
||||
static void get_calibrated_reading(MouseReading *pt) {
|
||||
#if GINPUT_MOUSE_NEED_CALIBRATION || GDISP_NEED_CONTROL
|
||||
coord_t w, h;
|
||||
#endif
|
||||
|
||||
get_raw_reading(pt);
|
||||
|
||||
#if GINPUT_MOUSE_NEED_CALIBRATION || GDISP_NEED_CONTROL
|
||||
w = gdispGetWidth();
|
||||
h = gdispGetHeight();
|
||||
#endif
|
||||
|
||||
#if GINPUT_MOUSE_NEED_CALIBRATION
|
||||
_tsTransform(pt, &MouseConfig.caldata);
|
||||
#endif
|
||||
|
||||
#if GDISP_NEED_CONTROL
|
||||
switch(gdispGetOrientation()) {
|
||||
case GDISP_ROTATE_0:
|
||||
break;
|
||||
case GDISP_ROTATE_90:
|
||||
{
|
||||
coord_t t = pt->y;
|
||||
pt->y = h - 1 - pt->x;
|
||||
pt->x = t;
|
||||
}
|
||||
break;
|
||||
case GDISP_ROTATE_180:
|
||||
pt->x = w - 1 - pt->x;
|
||||
pt->y = h - 1 - pt->y;
|
||||
break;
|
||||
case GDISP_ROTATE_270:
|
||||
{
|
||||
coord_t t = pt->x;
|
||||
pt->x = w - 1 - pt->y;
|
||||
pt->y = t;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GINPUT_MOUSE_NEED_CALIBRATION
|
||||
if (pt->x < 0) pt->x = 0;
|
||||
else if (pt->x >= w) pt->x = w-1;
|
||||
if (pt->y < 0) pt->y = 0;
|
||||
else if (pt->y >= h) pt->y = h-1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void MousePoll(void *param) {
|
||||
(void) param;
|
||||
GSourceListener *psl;
|
||||
GEventMouse *pe;
|
||||
unsigned meta;
|
||||
uint16_t tbtns;
|
||||
uint32_t cdiff;
|
||||
uint32_t mdiff;
|
||||
|
||||
// Save the last mouse state
|
||||
MouseConfig.last_buttons = MouseConfig.t.buttons;
|
||||
|
||||
// Get the new mouse reading
|
||||
get_calibrated_reading(&MouseConfig.t);
|
||||
|
||||
// Calculate out new event meta value and handle CLICK and CXTCLICK
|
||||
meta = GMETA_NONE;
|
||||
|
||||
// Calculate the position difference from our movement reference (update the reference if out of range)
|
||||
mdiff = (MouseConfig.t.x - MouseConfig.movepos.x) * (MouseConfig.t.x - MouseConfig.movepos.x) +
|
||||
(MouseConfig.t.y - MouseConfig.movepos.y) * (MouseConfig.t.y - MouseConfig.movepos.y);
|
||||
if (mdiff > GINPUT_MOUSE_MAX_MOVE_JITTER * GINPUT_MOUSE_MAX_MOVE_JITTER) {
|
||||
MouseConfig.movepos.x = MouseConfig.t.x;
|
||||
MouseConfig.movepos.y = MouseConfig.t.y;
|
||||
}
|
||||
|
||||
// Check if the click has moved outside the click area and if so cancel the click
|
||||
if ((MouseConfig.flags & FLG_CLICK_TIMER)) {
|
||||
cdiff = (MouseConfig.t.x - MouseConfig.clickpos.x) * (MouseConfig.t.x - MouseConfig.clickpos.x) +
|
||||
(MouseConfig.t.y - MouseConfig.clickpos.y) * (MouseConfig.t.y - MouseConfig.clickpos.y);
|
||||
if (cdiff > GINPUT_MOUSE_MAX_CLICK_JITTER * GINPUT_MOUSE_MAX_CLICK_JITTER)
|
||||
MouseConfig.flags &= ~FLG_CLICK_TIMER;
|
||||
}
|
||||
|
||||
// Mouse down
|
||||
tbtns = MouseConfig.t.buttons & ~MouseConfig.last_buttons;
|
||||
if ((tbtns & GINPUT_MOUSE_BTN_LEFT))
|
||||
meta |= GMETA_MOUSE_DOWN;
|
||||
if ((tbtns & (GINPUT_MOUSE_BTN_LEFT|GINPUT_MOUSE_BTN_RIGHT))) {
|
||||
MouseConfig.clickpos.x = MouseConfig.t.x;
|
||||
MouseConfig.clickpos.y = MouseConfig.t.y;
|
||||
MouseConfig.clicktime = chTimeNow();
|
||||
MouseConfig.flags |= FLG_CLICK_TIMER;
|
||||
}
|
||||
|
||||
// Mouse up
|
||||
tbtns = ~MouseConfig.t.buttons & MouseConfig.last_buttons;
|
||||
if ((tbtns & GINPUT_MOUSE_BTN_LEFT))
|
||||
meta |= GMETA_MOUSE_UP;
|
||||
if ((tbtns & (GINPUT_MOUSE_BTN_LEFT|GINPUT_MOUSE_BTN_RIGHT))) {
|
||||
if ((MouseConfig.flags & FLG_CLICK_TIMER)) {
|
||||
if ((tbtns & GINPUT_MOUSE_BTN_LEFT)
|
||||
#if GINPUT_MOUSE_CLICK_TIME != TIME_INFINITE
|
||||
&& chTimeNow() - MouseConfig.clicktime < MS2ST(GINPUT_MOUSE_CLICK_TIME)
|
||||
#endif
|
||||
)
|
||||
meta |= GMETA_MOUSE_CLICK;
|
||||
else
|
||||
meta |= GMETA_MOUSE_CXTCLICK;
|
||||
MouseConfig.flags &= ~FLG_CLICK_TIMER;
|
||||
}
|
||||
}
|
||||
|
||||
// Send the event to the listeners that are interested.
|
||||
psl = 0;
|
||||
while ((psl = geventGetSourceListener((GSourceHandle)(&MouseConfig), psl))) {
|
||||
if (!(pe = (GEventMouse *)geventGetEventBuffer(psl))) {
|
||||
// This listener is missing - save the meta events that have happened
|
||||
psl->srcflags |= meta;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we haven't really moved (and there are no meta events) don't bother sending the event
|
||||
if (mdiff <= GINPUT_MOUSE_MAX_MOVE_JITTER * GINPUT_MOUSE_MAX_MOVE_JITTER && !psl->srcflags && !meta && !(psl->listenflags & GLISTEN_MOUSENOFILTER))
|
||||
continue;
|
||||
|
||||
// Send the event if we are listening for it
|
||||
if (((MouseConfig.t.buttons & GINPUT_MOUSE_BTN_LEFT) && (psl->listenflags & GLISTEN_MOUSEDOWNMOVES))
|
||||
|| (!(MouseConfig.t.buttons & GINPUT_MOUSE_BTN_LEFT) && (psl->listenflags & GLISTEN_MOUSEUPMOVES))
|
||||
|| (meta && (psl->listenflags & GLISTEN_MOUSEMETA))) {
|
||||
pe->type = GINPUT_MOUSE_EVENT_TYPE;
|
||||
pe->instance = 0;
|
||||
pe->x = MouseConfig.t.x;
|
||||
pe->y = MouseConfig.t.y;
|
||||
pe->z = MouseConfig.t.z;
|
||||
pe->current_buttons = MouseConfig.t.buttons;
|
||||
pe->last_buttons = MouseConfig.last_buttons;
|
||||
pe->meta = meta;
|
||||
if (psl->srcflags) {
|
||||
pe->current_buttons |= GINPUT_MISSED_MOUSE_EVENT;
|
||||
pe->meta |= psl->srcflags;
|
||||
psl->srcflags = 0;
|
||||
}
|
||||
geventSendEvent(psl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Mouse Functions */
|
||||
GSourceHandle ginputGetMouse(uint16_t instance) {
|
||||
#if GINPUT_MOUSE_NEED_CALIBRATION
|
||||
Calibration *pc;
|
||||
#endif
|
||||
|
||||
// We only support a single mouse instance currently
|
||||
if (instance)
|
||||
return 0;
|
||||
|
||||
// Do we need to initialise the mouse subsystem?
|
||||
if (!(MouseConfig.flags & FLG_INIT_DONE)) {
|
||||
ginput_lld_mouse_init();
|
||||
|
||||
#if GINPUT_MOUSE_NEED_CALIBRATION
|
||||
#if GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE
|
||||
if (!MouseConfig.fnloadcal) {
|
||||
MouseConfig.fnloadcal = ginput_lld_mouse_calibration_load;
|
||||
MouseConfig.flags &= ~FLG_CAL_FREE;
|
||||
}
|
||||
if (!MouseConfig.fnsavecal)
|
||||
MouseConfig.fnsavecal = ginput_lld_mouse_calibration_save;
|
||||
#endif
|
||||
if (MouseConfig.fnloadcal && (pc = (Calibration *)MouseConfig.fnloadcal(instance))) {
|
||||
MouseConfig.caldata = pc[0];
|
||||
MouseConfig.flags |= (FLG_CAL_OK|FLG_CAL_SAVED);
|
||||
if ((MouseConfig.flags & FLG_CAL_FREE))
|
||||
chHeapFree((void *)pc);
|
||||
} else
|
||||
ginputCalibrateMouse(instance);
|
||||
#endif
|
||||
|
||||
// Get the first reading
|
||||
MouseConfig.last_buttons = 0;
|
||||
get_calibrated_reading(&MouseConfig.t);
|
||||
|
||||
// Mark init as done and start the Poll timer
|
||||
MouseConfig.flags |= FLG_INIT_DONE;
|
||||
gtimerStart(&MouseTimer, MousePoll, 0, TRUE, GINPUT_MOUSE_POLL_PERIOD);
|
||||
}
|
||||
|
||||
// Return our structure as the handle
|
||||
return (GSourceHandle)&MouseConfig;
|
||||
}
|
||||
|
||||
/* Get the current mouse position and button status.
|
||||
* Unlike a listener event, this status cannot record meta events such as "CLICK"
|
||||
* Returns FALSE on error (eg invalid instance)
|
||||
*/
|
||||
bool_t ginputGetMouseStatus(uint16_t instance, GEventMouse *pe) {
|
||||
if (instance || (MouseConfig.flags & (FLG_INIT_DONE|FLG_IN_CAL)) != FLG_INIT_DONE)
|
||||
return FALSE;
|
||||
|
||||
pe->type = GINPUT_MOUSE_EVENT_TYPE;
|
||||
pe->instance = instance;
|
||||
pe->x = MouseConfig.t.x;
|
||||
pe->y = MouseConfig.t.y;
|
||||
pe->z = MouseConfig.t.z;
|
||||
pe->current_buttons = MouseConfig.t.buttons;
|
||||
pe->last_buttons = MouseConfig.last_buttons;
|
||||
if (pe->current_buttons & ~pe->last_buttons & GINPUT_MOUSE_BTN_LEFT)
|
||||
pe->meta = GMETA_MOUSE_DOWN;
|
||||
else if (~pe->current_buttons & pe->last_buttons & GINPUT_MOUSE_BTN_LEFT)
|
||||
pe->meta = GMETA_MOUSE_UP;
|
||||
else
|
||||
pe->meta = GMETA_NONE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Run a mouse calibration.
|
||||
* Returns FALSE if the driver doesn't support it or if the handle is invalid.
|
||||
*/
|
||||
bool_t ginputCalibrateMouse(uint16_t instance) {
|
||||
#if !GINPUT_MOUSE_NEED_CALIBRATION
|
||||
(void) instance;
|
||||
|
||||
return FALSE;
|
||||
#else
|
||||
|
||||
const coord_t height = gdispGetHeight();
|
||||
const coord_t width = gdispGetWidth();
|
||||
const MousePoint cross[] = {{(width / 4), (height / 4)},
|
||||
{(width - (width / 4)) , (height / 4)},
|
||||
{(width - (width / 4)) , (height - (height / 4))},
|
||||
{(width / 2), (height / 2)}}; /* Check point */
|
||||
MousePoint points[GINPUT_MOUSE_CALIBRATION_POINTS];
|
||||
const MousePoint *pc;
|
||||
MousePoint *pt;
|
||||
int32_t px, py;
|
||||
unsigned i, j;
|
||||
|
||||
if (instance || (MouseConfig.flags & FLG_IN_CAL))
|
||||
return FALSE;
|
||||
|
||||
MouseConfig.flags |= FLG_IN_CAL;
|
||||
gtimerStop(&MouseTimer);
|
||||
MouseConfig.flags &= ~(FLG_CAL_OK|FLG_CAL_SAVED);
|
||||
|
||||
#if GDISP_NEED_CONTROL
|
||||
gdispSetOrientation(GDISP_ROTATE_0);
|
||||
#endif
|
||||
|
||||
gdispClear(Blue);
|
||||
|
||||
gdispFillStringBox(0, 5, width, 30, GINPUT_MOUSE_CALIBRATION_TEXT, GINPUT_MOUSE_CALIBRATION_FONT, White, Blue, justifyCenter);
|
||||
|
||||
#if GINPUT_MOUSE_MAX_CALIBRATION_ERROR >= 0
|
||||
do {
|
||||
#endif
|
||||
for(i = 0, pt = points, pc = cross; i < GINPUT_MOUSE_CALIBRATION_POINTS; i++, pt++, pc++) {
|
||||
_tsDrawCross(pc);
|
||||
|
||||
do {
|
||||
|
||||
/* Wait for the mouse to be pressed */
|
||||
while(get_raw_reading(&MouseConfig.t), !(MouseConfig.t.buttons & GINPUT_MOUSE_BTN_LEFT))
|
||||
chThdSleepMilliseconds(20);
|
||||
|
||||
/* Average all the samples while the mouse is down */
|
||||
for(px = py = 0, j = 0;
|
||||
chThdSleepMilliseconds(20), /* Settling time between readings */
|
||||
get_raw_reading(&MouseConfig.t),
|
||||
(MouseConfig.t.buttons & GINPUT_MOUSE_BTN_LEFT);
|
||||
j++) {
|
||||
px += MouseConfig.t.x;
|
||||
py += MouseConfig.t.y;
|
||||
}
|
||||
|
||||
} while(!j);
|
||||
|
||||
pt->x = px / j;
|
||||
pt->y = py / j;
|
||||
|
||||
_tsClearCross(pc);
|
||||
}
|
||||
|
||||
/* Apply 3 point calibration algorithm */
|
||||
_tsDo3PointCalibration(cross, points, &MouseConfig.caldata);
|
||||
|
||||
/* Verification of correctness of calibration (optional) :
|
||||
* See if the 4th point (Middle of the screen) coincides with the calibrated
|
||||
* result. If point is within +/- Squareroot(ERROR) pixel margin, then successful calibration
|
||||
* Else, start from the beginning.
|
||||
*/
|
||||
#if GINPUT_MOUSE_MAX_CALIBRATION_ERROR >= 0
|
||||
/* Transform the co-ordinates */
|
||||
MouseConfig.t.x = points[3].x;
|
||||
MouseConfig.t.y = points[3].y;
|
||||
_tsTransform(&MouseConfig.t, &MouseConfig.caldata);
|
||||
|
||||
/* Calculate the delta */
|
||||
px = (MouseConfig.t.x - cross[3].x) * (MouseConfig.t.x - cross[3].x) +
|
||||
(MouseConfig.t.y - cross[3].y) * (MouseConfig.t.y - cross[3].y);
|
||||
|
||||
} while (px > GINPUT_MOUSE_MAX_CALIBRATION_ERROR * GINPUT_MOUSE_MAX_CALIBRATION_ERROR);
|
||||
#endif
|
||||
|
||||
// Restart everything
|
||||
MouseConfig.flags |= FLG_CAL_OK;
|
||||
MouseConfig.last_buttons = 0;
|
||||
get_calibrated_reading(&MouseConfig.t);
|
||||
MouseConfig.flags &= ~FLG_IN_CAL;
|
||||
if ((MouseConfig.flags & FLG_INIT_DONE))
|
||||
gtimerStart(&MouseTimer, MousePoll, 0, TRUE, GINPUT_MOUSE_POLL_PERIOD);
|
||||
|
||||
// Save the calibration data (if possible)
|
||||
if (MouseConfig.fnsavecal) {
|
||||
MouseConfig.fnsavecal(instance, (const uint8_t *)&MouseConfig.caldata, sizeof(MouseConfig.caldata));
|
||||
MouseConfig.flags |= FLG_CAL_SAVED;
|
||||
}
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Set the routines to save and fetch calibration data.
|
||||
* This function should be called before first calling ginputGetMouse() for a particular instance
|
||||
* as the gdispGetMouse() routine may attempt to fetch calibration data and perform a startup calibration if there is no way to get it.
|
||||
* If this is called after gdispGetMouse() has been called and the driver requires calibration storage, it will immediately save the data is has already obtained.
|
||||
* The 'requireFree' parameter indicates if the fetch buffer must be free()'d to deallocate the buffer provided by the Fetch routine.
|
||||
*/
|
||||
void ginputSetMouseCalibrationRoutines(uint16_t instance, GMouseCalibrationSaveRoutine fnsave, GMouseCalibrationLoadRoutine fnload, bool_t requireFree) {
|
||||
#if GINPUT_MOUSE_NEED_CALIBRATION
|
||||
if (instance)
|
||||
return;
|
||||
|
||||
MouseConfig.fnloadcal = fnload;
|
||||
MouseConfig.fnsavecal = fnsave;
|
||||
if (requireFree)
|
||||
MouseConfig.flags |= FLG_CAL_FREE;
|
||||
else
|
||||
MouseConfig.flags &= ~FLG_CAL_FREE;
|
||||
#if GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE
|
||||
if (!MouseConfig.fnloadcal) {
|
||||
MouseConfig.fnloadcal = ginput_lld_mouse_calibration_load;
|
||||
MouseConfig.flags &= ~FLG_CAL_FREE;
|
||||
}
|
||||
if (!MouseConfig.fnsavecal)
|
||||
MouseConfig.fnsavecal = ginput_lld_mouse_calibration_save;
|
||||
#endif
|
||||
if (MouseConfig.fnsavecal && (MouseConfig.flags & (FLG_CAL_OK|FLG_CAL_SAVED)) == FLG_CAL_OK) {
|
||||
MouseConfig.fnsavecal(instance, (const uint8_t *)&MouseConfig.caldata, sizeof(MouseConfig.caldata));
|
||||
MouseConfig.flags |= FLG_CAL_SAVED;
|
||||
}
|
||||
#else
|
||||
(void)instance, (void)fnsave, (void)fnload, (void)requireFree;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Test if a particular mouse instance requires routines to save its calibration data. */
|
||||
bool_t ginputRequireMouseCalibrationStorage(uint16_t instance) {
|
||||
if (instance)
|
||||
return FALSE;
|
||||
|
||||
#if GINPUT_MOUSE_NEED_CALIBRATION && !GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Wake up the mouse driver from an interrupt service routine (there may be new readings available) */
|
||||
void ginputMouseWakeup(void) {
|
||||
gtimerJab(&MouseTimer);
|
||||
}
|
||||
|
||||
/* Wake up the mouse driver from an interrupt service routine (there may be new readings available) */
|
||||
void ginputMouseWakeupI(void) {
|
||||
gtimerJabI(&MouseTimer);
|
||||
}
|
||||
|
||||
#endif /* GINPUT_NEED_MOUSE */
|
||||
/** @} */
|
161
src/ginput/toggle.c
Normal file
161
src/ginput/toggle.c
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
ChibiOS/GFX - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file src/ginput/toggle.c
|
||||
* @brief GINPUT toggle code.
|
||||
*
|
||||
* @addtogroup GINPUT_TOGGLE
|
||||
* @{
|
||||
*/
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include "gtimer.h"
|
||||
#include "ginput.h"
|
||||
|
||||
#if GINPUT_NEED_TOGGLE || defined(__DOXYGEN__)
|
||||
|
||||
#include "lld/ginput/toggle.h"
|
||||
|
||||
#ifndef GINPUT_TOGGLE_POLL_PERIOD
|
||||
#define GINPUT_TOGGLE_POLL_PERIOD 250
|
||||
#endif
|
||||
|
||||
#define GINPUT_TOGGLE_ISON 0x01
|
||||
#define GINPUT_TOGGLE_INVERT 0x02
|
||||
|
||||
static GTIMER_DECL(ToggleTimer);
|
||||
static struct GEventToggleStatus_t {
|
||||
uint8_t status;
|
||||
} ToggleStatus[GINPUT_TOGGLE_NUM_PORTS];
|
||||
|
||||
// Our polling function
|
||||
static void TogglePoll(void *param) {
|
||||
(void) param;
|
||||
|
||||
const GToggleConfig *ptc;
|
||||
GSourceListener *psl;
|
||||
GEventToggle *pe;
|
||||
unsigned i, bits, mask;
|
||||
uint8_t state;
|
||||
|
||||
// Loop while there are bits to get
|
||||
for(ptc = GInputToggleConfigTable, i=0; i < GINPUT_TOGGLE_NUM_PORTS; ptc++) {
|
||||
|
||||
// Get the next block of bits
|
||||
bits = ginput_lld_toggle_getbits(ptc) ^ ptc->invert;
|
||||
|
||||
// Extract the bits of use
|
||||
for(mask = ptc->mask; i < GINPUT_TOGGLE_NUM_PORTS && mask; mask >>= 1, bits >>= 1) {
|
||||
// Ignore bits not in our mask
|
||||
if (!(mask & 1))
|
||||
continue;
|
||||
|
||||
// Calculate our new state
|
||||
state = ToggleStatus[i].status & ~GINPUT_TOGGLE_ISON;
|
||||
if (state & GINPUT_TOGGLE_INVERT)
|
||||
bits ^= 1;
|
||||
if (bits & 1)
|
||||
state |= GINPUT_TOGGLE_ISON;
|
||||
|
||||
// Has it changed?
|
||||
if ((state ^ ToggleStatus[i].status) & GINPUT_TOGGLE_ISON) {
|
||||
|
||||
// Save the new state
|
||||
ToggleStatus[i].status = state;
|
||||
|
||||
// Send the event to the listeners that are interested.
|
||||
psl = 0;
|
||||
while ((psl = geventGetSourceListener((GSourceHandle)(ToggleStatus+i), psl))) {
|
||||
if (!(pe = (GEventToggle *)geventGetEventBuffer(psl)))
|
||||
continue;
|
||||
if ((state & GINPUT_TOGGLE_ISON)) {
|
||||
if ((psl->listenflags & GLISTEN_TOGGLE_ON)) {
|
||||
pe->type = GEVENT_TOGGLE;
|
||||
pe->instance = i;
|
||||
pe->on = TRUE;
|
||||
geventSendEvent(psl);
|
||||
}
|
||||
} else {
|
||||
if ((psl->listenflags & GLISTEN_TOGGLE_OFF)) {
|
||||
pe->type = GEVENT_TOGGLE;
|
||||
pe->instance = i;
|
||||
pe->on = FALSE;
|
||||
geventSendEvent(psl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Next toggle switch
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Hardware Toggle/Switch/Button Functions */
|
||||
GSourceHandle ginputGetToggle(uint16_t instance) {
|
||||
const GToggleConfig *ptc;
|
||||
|
||||
if (instance >= GINPUT_TOGGLE_NUM_PORTS)
|
||||
return 0;
|
||||
|
||||
// Do we need to initialise the toggle subsystem?
|
||||
if (!gtimerIsActive(&ToggleTimer)) {
|
||||
for(ptc = GInputToggleConfigTable; ptc < GInputToggleConfigTable+sizeof(GInputToggleConfigTable)/sizeof(GInputToggleConfigTable[0]); ptc++)
|
||||
ginput_lld_toggle_init(ptc);
|
||||
gtimerStart(&ToggleTimer, TogglePoll, 0, TRUE, GINPUT_TOGGLE_POLL_PERIOD);
|
||||
}
|
||||
|
||||
// OK - return this input
|
||||
return (GSourceHandle)(ToggleStatus+instance);
|
||||
}
|
||||
|
||||
// If invert is true, invert the on/off sense for the toggle
|
||||
void ginputInvertToggle(uint16_t instance, bool_t invert) {
|
||||
if (instance >= GINPUT_TOGGLE_NUM_PORTS)
|
||||
return;
|
||||
if (invert) {
|
||||
if (!(ToggleStatus[instance].status & GINPUT_TOGGLE_INVERT)) {
|
||||
ToggleStatus[instance].status |= GINPUT_TOGGLE_INVERT;
|
||||
ToggleStatus[instance].status ^= GINPUT_TOGGLE_ISON;
|
||||
}
|
||||
} else {
|
||||
if ((ToggleStatus[instance].status & GINPUT_TOGGLE_INVERT)) {
|
||||
ToggleStatus[instance].status &= ~GINPUT_TOGGLE_INVERT;
|
||||
ToggleStatus[instance].status ^= GINPUT_TOGGLE_ISON;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the current toggle status.
|
||||
* Returns FALSE on error (eg invalid instance)
|
||||
*/
|
||||
bool_t ginputGetToggleStatus(uint16_t instance, GEventToggle *ptoggle) {
|
||||
if (instance >= GINPUT_TOGGLE_NUM_PORTS)
|
||||
return FALSE;
|
||||
ptoggle->type = GEVENT_TOGGLE;
|
||||
ptoggle->instance = instance;
|
||||
ptoggle->on = (ToggleStatus[instance].status & GINPUT_TOGGLE_ISON) ? TRUE : FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* GINPUT_NEED_TOGGLE */
|
||||
/** @} */
|
52
src/gtimer.c
52
src/gtimer.c
|
@ -36,14 +36,14 @@
|
|||
#define GTIMER_FLG_JABBED 0x0004
|
||||
#define GTIMER_FLG_SCHEDULED 0x0008
|
||||
|
||||
#define TimeIsWithin(time, start, end) (end > start ? (time >= start && time <= end) : (time >= start || time <= end))
|
||||
/* Don't rework this macro to use a ternary operator - the gcc compiler stuffs it up */
|
||||
#define TimeIsWithin(x, start, end) ((end >= start && x >= start && x <= end) || (end < start && (x >= start || x <= end)))
|
||||
|
||||
// This mutex protects access to our tables
|
||||
static MUTEX_DECL(mutex);
|
||||
static Thread *pThread = 0;
|
||||
static GTimer *pTimerHead = 0;
|
||||
static systime_t lastTime = 0;
|
||||
static SEMAPHORE_DECL(waitsem, 0);
|
||||
static BSEMAPHORE_DECL(waitsem, TRUE);
|
||||
static WORKING_AREA(waTimerThread, GTIMER_THREAD_STACK_SIZE);
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -55,7 +55,7 @@ static msg_t GTimerThreadHandler(void *arg) {
|
|||
GTimer *pt;
|
||||
systime_t tm;
|
||||
systime_t nxtTimeout;
|
||||
systime_t tmptime;
|
||||
systime_t lastTime;
|
||||
GTimerFunction fn;
|
||||
void *param;
|
||||
|
||||
|
@ -64,9 +64,11 @@ static msg_t GTimerThreadHandler(void *arg) {
|
|||
#endif
|
||||
|
||||
nxtTimeout = TIME_INFINITE;
|
||||
lastTime = 0;
|
||||
while(1) {
|
||||
/* Wait for work to do. */
|
||||
chSemWaitTimeout(&waitsem, nxtTimeout);
|
||||
chThdYield(); // Give someone else a go no matter how busy we are
|
||||
chBSemWaitTimeout(&waitsem, nxtTimeout);
|
||||
|
||||
restartTimerChecks:
|
||||
|
||||
|
@ -87,9 +89,11 @@ static msg_t GTimerThreadHandler(void *arg) {
|
|||
if ((pt->flags & GTIMER_FLG_PERIODIC) && pt->period != TIME_IMMEDIATE) {
|
||||
// Yes - Update ready for the next period
|
||||
if (!(pt->flags & GTIMER_FLG_INFINITE)) {
|
||||
do {
|
||||
pt->when += pt->period; // We may have skipped a period
|
||||
} while (TimeIsWithin(pt->when, lastTime, tm));
|
||||
// We may have skipped a period.
|
||||
// We use this complicated formulae rather than a loop
|
||||
// because the gcc compiler stuffs up the loop so that it
|
||||
// either loops forever or doesn't get executed at all.
|
||||
pt->when += ((tm + pt->period - pt->when) / pt->period) * pt->period;
|
||||
}
|
||||
|
||||
// We are definitely no longer jabbed
|
||||
|
@ -120,10 +124,8 @@ static msg_t GTimerThreadHandler(void *arg) {
|
|||
}
|
||||
|
||||
// Find when we next need to wake up
|
||||
if (!(pt->flags & GTIMER_FLG_INFINITE)) {
|
||||
tmptime = pt->when - tm;
|
||||
if (tmptime < nxtTimeout) nxtTimeout = tmptime;
|
||||
}
|
||||
if (!(pt->flags & GTIMER_FLG_INFINITE) && pt->when - tm < nxtTimeout)
|
||||
nxtTimeout = pt->when - tm;
|
||||
pt = pt->next;
|
||||
} while(pt != pTimerHead);
|
||||
}
|
||||
|
@ -201,11 +203,13 @@ void gtimerStart(GTimer *pt, GTimerFunction fn, void *param, bool_t periodic, sy
|
|||
pt->flags = GTIMER_FLG_SCHEDULED;
|
||||
if (periodic)
|
||||
pt->flags |= GTIMER_FLG_PERIODIC;
|
||||
if (millisec != TIME_INFINITE) {
|
||||
if (millisec == TIME_INFINITE) {
|
||||
pt->flags |= GTIMER_FLG_INFINITE;
|
||||
pt->period = TIME_INFINITE;
|
||||
} else {
|
||||
pt->period = MS2ST(millisec);
|
||||
pt->when = chTimeNow() + pt->period;
|
||||
} else
|
||||
pt->flags |= GTIMER_FLG_INFINITE;
|
||||
}
|
||||
|
||||
// Just pop it on the end of the queue
|
||||
if (pTimerHead) {
|
||||
|
@ -217,7 +221,8 @@ void gtimerStart(GTimer *pt, GTimerFunction fn, void *param, bool_t periodic, sy
|
|||
pt->next = pt->prev = pTimerHead = pt;
|
||||
|
||||
// Bump the thread
|
||||
chSemSignal(&waitsem);
|
||||
if (!(pt->flags & GTIMER_FLG_INFINITE))
|
||||
chBSemSignal(&waitsem);
|
||||
chMtxUnlock();
|
||||
}
|
||||
|
||||
|
@ -248,6 +253,17 @@ void gtimerStop(GTimer *pt) {
|
|||
chMtxUnlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test if a timer is currently active
|
||||
*
|
||||
* @param[in] pt Pointer to a GTimer structure
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
bool_t gtimerIsActive(GTimer *pt) {
|
||||
return (pt->flags & GTIMER_FLG_SCHEDULED) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Jab a timer causing the current period to immediate expire
|
||||
* @details The callback function will be called as soon as possible.
|
||||
|
@ -268,7 +284,7 @@ void gtimerJab(GTimer *pt) {
|
|||
pt->flags |= GTIMER_FLG_JABBED;
|
||||
|
||||
// Bump the thread
|
||||
chSemSignal(&waitsem);
|
||||
chBSemSignal(&waitsem);
|
||||
chMtxUnlock();
|
||||
}
|
||||
|
||||
|
@ -291,7 +307,7 @@ void gtimerJabI(GTimer *pt) {
|
|||
pt->flags |= GTIMER_FLG_JABBED;
|
||||
|
||||
// Bump the thread
|
||||
chSemSignalI(&waitsem);
|
||||
chBSemSignalI(&waitsem);
|
||||
}
|
||||
|
||||
#endif /* GFX_USE_GTIMER */
|
||||
|
|
368
src/gwin.c
368
src/gwin.c
|
@ -31,17 +31,11 @@
|
|||
|
||||
#if GFX_USE_GWIN || defined(__DOXYGEN__)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define GWIN_CONSOLE_USE_CLEAR_LINES TRUE
|
||||
#define GWIN_CONSOLE_USE_FILLED_CHARS FALSE
|
||||
|
||||
#define GWIN_FLG_DYNAMIC 0x0001
|
||||
#define GWIN_FIRST_CONTROL_FLAG 0x0002
|
||||
#define GBTN_FLG_ALLOCTXT (GWIN_FIRST_CONTROL_FLAG<<0)
|
||||
#include "gwin/gwin_internal.h"
|
||||
|
||||
// Internal routine for use by GWIN components only
|
||||
// Initialise a window creating it dynamicly if required.
|
||||
static GHandle gwinInit(GWindowObject *gw, coord_t x, coord_t y, coord_t width, coord_t height, size_t size) {
|
||||
GHandle _gwinInit(GWindowObject *gw, coord_t x, coord_t y, coord_t width, coord_t height, size_t size) {
|
||||
coord_t w, h;
|
||||
|
||||
// Check the window size against the screen size
|
||||
|
@ -90,7 +84,7 @@ static GHandle gwinInit(GWindowObject *gw, coord_t x, coord_t y, coord_t width,
|
|||
* @api
|
||||
*/
|
||||
GHandle gwinCreateWindow(GWindowObject *gw, coord_t x, coord_t y, coord_t width, coord_t height) {
|
||||
if (!(gw = (GWindowObject *)gwinInit((GWindowObject *)gw, x, y, width, height, sizeof(GWindowObject))))
|
||||
if (!(gw = (GWindowObject *)_gwinInit((GWindowObject *)gw, x, y, width, height, sizeof(GWindowObject))))
|
||||
return 0;
|
||||
gw->type = GW_WINDOW;
|
||||
return (GHandle)gw;
|
||||
|
@ -536,360 +530,6 @@ void gwinFillStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy,
|
|||
}
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
#if GWIN_NEED_CONSOLE || defined(__DOXYGEN__)
|
||||
|
||||
/*
|
||||
* Stream interface implementation. The interface is write only
|
||||
*/
|
||||
|
||||
#define Stream2GWindow(ip) ((GHandle)(((char *)(ip)) - (size_t)(&(((GConsoleObject *)0)->stream))))
|
||||
|
||||
static size_t GWinStreamWrite(void *ip, const uint8_t *bp, size_t n) { gwinPutCharArray(Stream2GWindow(ip), (const char *)bp, n); return RDY_OK; }
|
||||
static size_t GWinStreamRead(void *ip, uint8_t *bp, size_t n) { (void)ip; (void)bp; (void)n; return 0; }
|
||||
static msg_t GWinStreamPut(void *ip, uint8_t b) { gwinPutChar(Stream2GWindow(ip), (char)b); return RDY_OK; }
|
||||
static msg_t GWinStreamGet(void *ip) {(void)ip; return RDY_OK; }
|
||||
static msg_t GWinStreamPutTimed(void *ip, uint8_t b, systime_t time) { (void)time; gwinPutChar(Stream2GWindow(ip), (char)b); return RDY_OK; }
|
||||
static msg_t GWinStreamGetTimed(void *ip, systime_t timeout) { (void)ip; (void)timeout; return RDY_OK; }
|
||||
static size_t GWinStreamWriteTimed(void *ip, const uint8_t *bp, size_t n, systime_t time) { (void)time; gwinPutCharArray(Stream2GWindow(ip), (const char *)bp, n); return RDY_OK; }
|
||||
static size_t GWinStreamReadTimed(void *ip, uint8_t *bp, size_t n, systime_t time) { (void)ip; (void)bp; (void)n; (void)time; return 0; }
|
||||
|
||||
struct GConsoleWindowVMT_t {
|
||||
_base_asynchronous_channel_methods
|
||||
};
|
||||
|
||||
static const struct GConsoleWindowVMT_t GWindowConsoleVMT = {
|
||||
GWinStreamWrite,
|
||||
GWinStreamRead,
|
||||
GWinStreamPut,
|
||||
GWinStreamGet,
|
||||
GWinStreamPutTimed,
|
||||
GWinStreamGetTimed,
|
||||
GWinStreamWriteTimed,
|
||||
GWinStreamReadTimed
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a console window.
|
||||
* @details A console window allows text to be written using chprintf() (and the console functions defined here).
|
||||
* @brief Text in a console window supports newlines and will wrap text as required.
|
||||
* @return NULL if there is no resultant drawing area, otherwise a window handle.
|
||||
*
|
||||
* @param[in] gc The GConsoleObject structure to initialise. If this is NULL the structure is dynamically allocated.
|
||||
* @param[in] x,y The screen co-ordinates for the bottom left corner of the window
|
||||
* @param[in] width The width of the window
|
||||
* @param[in] height The height of the window
|
||||
* @param[in] font The font to use
|
||||
* @note The console is not automatically cleared on creation. You must do that by calling gwinClear() (possibly after changing your background color)
|
||||
* @note If the dispay does not support scrolling, the window will be cleared when the bottom line is reached.
|
||||
* @note The default drawing color gets set to White and the background drawing color to Black.
|
||||
* @note The dimensions and position may be changed to fit on the real screen.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
GHandle gwinCreateConsole(GConsoleObject *gc, coord_t x, coord_t y, coord_t width, coord_t height, font_t font) {
|
||||
if (!(gc = (GConsoleObject *)gwinInit((GWindowObject *)gc, x, y, width, height, sizeof(GConsoleObject))))
|
||||
return 0;
|
||||
gc->gwin.type = GW_CONSOLE;
|
||||
gwinSetFont(&gc->gwin, font);
|
||||
gc->stream.vmt = &GWindowConsoleVMT;
|
||||
gc->cx = 0;
|
||||
gc->cy = 0;
|
||||
return (GHandle)gc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a stream from a console window suitable for use with chprintf().
|
||||
* @return The stream handle or NULL if this is not a console window.
|
||||
*
|
||||
* @param[in] gh The window handle (must be a console window)
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
BaseSequentialStream *gwinGetConsoleStream(GHandle gh) {
|
||||
if (gh->type != GW_CONSOLE)
|
||||
return 0;
|
||||
return (BaseSequentialStream *)&(((GConsoleObject *)(gh))->stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Put a character at the cursor position in the window.
|
||||
* @note Uses the current foreground color to draw the character and fills the background using the background drawing color
|
||||
*
|
||||
* @param[in] gh The window handle (must be a console window)
|
||||
* @param[in] c The character to draw
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gwinPutChar(GHandle gh, char c) {
|
||||
uint8_t width;
|
||||
#define gcw ((GConsoleObject *)gh)
|
||||
|
||||
if (gh->type != GW_CONSOLE || !gh->font) return;
|
||||
|
||||
#if GDISP_NEED_CLIP
|
||||
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
|
||||
#endif
|
||||
|
||||
if (c == '\n') {
|
||||
gcw->cx = 0;
|
||||
gcw->cy += gcw->fy;
|
||||
// We use lazy scrolling here and only scroll when the next char arrives
|
||||
} else if (c == '\r') {
|
||||
// gcw->cx = 0;
|
||||
} else {
|
||||
width = gdispGetCharWidth(c, gh->font) + gcw->fp;
|
||||
if (gcw->cx + width >= gh->width) {
|
||||
gcw->cx = 0;
|
||||
gcw->cy += gcw->fy;
|
||||
}
|
||||
|
||||
if (gcw->cy + gcw->fy > gh->height) {
|
||||
#if GDISP_NEED_SCROLL
|
||||
/* scroll the console */
|
||||
gdispVerticalScroll(gh->x, gh->y, gh->width, gh->height, gcw->fy, gh->bgcolor);
|
||||
/* reset the cursor to the start of the last line */
|
||||
gcw->cx = 0;
|
||||
gcw->cy = (((coord_t)(gh->height/gcw->fy))-1)*gcw->fy;
|
||||
#else
|
||||
/* clear the console */
|
||||
gdispFillArea(gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
|
||||
/* reset the cursor to the top of the window */
|
||||
gcw->cx = 0;
|
||||
gcw->cy = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if GWIN_CONSOLE_USE_CLEAR_LINES
|
||||
/* clear to the end of the line */
|
||||
if (gcw->cx == 0)
|
||||
gdispFillArea(gh->x, gh->y + gcw->cy, gh->width, gcw->fy, gh->bgcolor);
|
||||
#endif
|
||||
#if GWIN_CONSOLE_USE_FILLED_CHARS
|
||||
gdispFillChar(gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, gh->color, gh->bgcolor);
|
||||
#else
|
||||
gdispDrawChar(gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, gh->color);
|
||||
#endif
|
||||
|
||||
/* update cursor */
|
||||
gcw->cx += width;
|
||||
}
|
||||
#undef gcw
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Put a string at the cursor position in the window. It will wrap lines as required.
|
||||
* @note Uses the current foreground color to draw the string and fills the background using the background drawing color
|
||||
*
|
||||
* @param[in] gh The window handle (must be a console window)
|
||||
* @param[in] str The string to draw
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gwinPutString(GHandle gh, const char *str) {
|
||||
while(*str)
|
||||
gwinPutChar(gh, *str++);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Put the character array at the cursor position in the window. It will wrap lines as required.
|
||||
* @note Uses the current foreground color to draw the string and fills the background using the background drawing color
|
||||
*
|
||||
* @param[in] gh The window handle (must be a console window)
|
||||
* @param[in] str The string to draw
|
||||
* @param[in] n The number of characters to draw
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gwinPutCharArray(GHandle gh, const char *str, size_t n) {
|
||||
while(n--)
|
||||
gwinPutChar(gh, *str++);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
#if GWIN_NEED_BUTTON || defined(__DOXYGEN__)
|
||||
|
||||
static const GButtonStyle GButtonDefaultStyle = {
|
||||
GBTN_3D,
|
||||
HTML2COLOR(0x404040), // color_up_edge;
|
||||
HTML2COLOR(0xE0E0E0), // color_up_fill;
|
||||
HTML2COLOR(0x000000), // color_up_txt;
|
||||
HTML2COLOR(0x404040), // color_dn_edge;
|
||||
HTML2COLOR(0x808080), // color_dn_fill;
|
||||
HTML2COLOR(0x404040), // color_dn_txt;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a button window.
|
||||
* @return NULL if there is no resultant drawing area, otherwise a window handle.
|
||||
*
|
||||
* @param[in] gb The GConsoleWindow structure to initialise. If this is NULL the structure is dynamically allocated.
|
||||
* @param[in] x,y The screen co-ordinates for the bottom left corner of the window
|
||||
* @param[in] width The width of the window
|
||||
* @param[in] height The height of the window
|
||||
* @param[in] font The font to use
|
||||
* @param[in] type The type of button
|
||||
* @note The drawing color gets set to White and the background drawing color to Black.
|
||||
* @note The dimensions and position may be changed to fit on the real screen.
|
||||
* @note The button is not automatically drawn. Call gwinButtonDraw() after changing the button style or setting the text.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
GHandle gwinCreateButton(GButtonObject *gb, coord_t x, coord_t y, coord_t width, coord_t height, font_t font, GButtonType type) {
|
||||
if (!(gb = (GButtonObject *)gwinInit((GWindowObject *)gb, x, y, width, height, sizeof(GButtonObject))))
|
||||
return 0;
|
||||
gb->gwin.type = GW_BUTTON;
|
||||
gwinSetFont(&gb->gwin, font);
|
||||
gwinSetButtonStyle(&gb->gwin, &GButtonDefaultStyle);
|
||||
gb->type = type;
|
||||
gb->state = GBTN_UP;
|
||||
gb->txt = "";
|
||||
gb->callback = 0;
|
||||
gb->inputsrc = 0;
|
||||
return (GHandle)gb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the style of a button.
|
||||
* @details The button style is defined by its shape and colours.
|
||||
*
|
||||
* @param[in] gh The window handle (must be a button window)
|
||||
* @param[in] style The button style to set.
|
||||
* @note The button is not automatically redrawn. Call gwinButtonDraw() after changing the button style
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gwinSetButtonStyle(GHandle gh, const GButtonStyle *style) {
|
||||
#define gbw ((GButtonObject *)gh)
|
||||
if (gh->type != GW_BUTTON)
|
||||
return;
|
||||
|
||||
gbw->style.shape = style->shape;
|
||||
gbw->style.color_up_edge = style->color_up_edge;
|
||||
gbw->style.color_up_fill = style->color_up_fill;
|
||||
gbw->style.color_dn_edge = style->color_dn_edge;
|
||||
gbw->style.color_dn_fill = style->color_dn_fill;
|
||||
gbw->style.color_up_txt = style->color_up_txt;
|
||||
gbw->style.color_dn_txt = style->color_dn_txt;
|
||||
#undef gbw
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the text of a button.
|
||||
*
|
||||
* @param[in] gh The window handle (must be a button window)
|
||||
* @param[in] txt The button text to set. This must be a constant string unless useAlloc is set.
|
||||
* @param[in] useAlloc If TRUE the string specified will be copied into dynamically allocated memory.
|
||||
* @note The button is not automatically redrawn. Call gwinButtonDraw() after changing the button text.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gwinSetButtonText(GHandle gh, const char *txt, bool_t useAlloc) {
|
||||
#define gbw ((GButtonObject *)gh)
|
||||
if (gh->type != GW_BUTTON)
|
||||
return;
|
||||
|
||||
// Dispose of the old string
|
||||
if ((gh->flags & GBTN_FLG_ALLOCTXT)) {
|
||||
gh->flags &= ~GBTN_FLG_ALLOCTXT;
|
||||
if (gbw->txt) {
|
||||
chHeapFree((void *)gbw->txt);
|
||||
gbw->txt = "";
|
||||
}
|
||||
}
|
||||
// Alloc the new text if required
|
||||
if (txt && useAlloc) {
|
||||
char *str;
|
||||
|
||||
if ((str = (char *)chHeapAlloc(NULL, strlen(txt)+1))) {
|
||||
gh->flags |= GBTN_FLG_ALLOCTXT;
|
||||
strcpy(str, txt);
|
||||
}
|
||||
txt = (const char *)str;
|
||||
}
|
||||
|
||||
gbw->txt = txt ? txt : "";
|
||||
#undef gbw
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Redraw the button.
|
||||
*
|
||||
* @param[in] gh The window handle (must be a button window)
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gwinButtonDraw(GHandle gh) {
|
||||
color_t cedge;
|
||||
color_t cfill;
|
||||
color_t ctxt;
|
||||
const char * txt;
|
||||
#define gbw ((GButtonObject *)gh)
|
||||
#define RND_CNR_SIZE 5
|
||||
|
||||
if (gh->type != GW_BUTTON)
|
||||
return;
|
||||
|
||||
#if GDISP_NEED_CLIP
|
||||
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
|
||||
#endif
|
||||
|
||||
// Get the text (safely)
|
||||
txt = gh->font && gbw->txt ? gbw->txt : "";
|
||||
|
||||
// Determine the colors to use
|
||||
switch(gbw->state) {
|
||||
case GBTN_DOWN:
|
||||
cedge = gbw->style.color_dn_edge;
|
||||
cfill = gbw->style.color_dn_fill;
|
||||
ctxt = gbw->style.color_dn_txt;
|
||||
break;
|
||||
case GBTN_UP: default:
|
||||
cedge = gbw->style.color_up_edge;
|
||||
cfill = gbw->style.color_up_fill;
|
||||
ctxt = gbw->style.color_up_txt;
|
||||
break;
|
||||
}
|
||||
|
||||
// Draw according to the shape specified.
|
||||
switch(gbw->style.shape) {
|
||||
#if GDISP_NEED_ARC
|
||||
case GBTN_ROUNDED:
|
||||
if (gh->width >= 2*RND_CNR_SIZE+10) {
|
||||
gdispFillRoundedBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, RND_CNR_SIZE-1, cfill);
|
||||
gdispDrawStringBox(gh->x+1, gh->y+RND_CNR_SIZE, gh->width-2, gh->height-(2*RND_CNR_SIZE), txt, gh->font, ctxt, justifyCenter);
|
||||
gdispDrawRoundedBox(gh->x, gh->y, gh->width, gh->height, RND_CNR_SIZE, cedge);
|
||||
break;
|
||||
}
|
||||
/* Fall Through */
|
||||
#endif
|
||||
case GBTN_SQUARE:
|
||||
gdispFillStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, ctxt, cfill, justifyCenter);
|
||||
gdispDrawBox(gh->x, gh->y, gh->width, gh->height, cedge);
|
||||
break;
|
||||
#if GDISP_NEED_ELLIPSE
|
||||
case GBTN_ELLIPSE:
|
||||
gdispFillEllipse(gh->x+1, gh->y+1, gh->width/2-1, gh->height/2-1, cfill);
|
||||
gdispDrawStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, ctxt, justifyCenter);
|
||||
gdispDrawEllipse(gh->x, gh->y, gh->width/2, gh->height/2, cedge);
|
||||
break;
|
||||
#endif
|
||||
case GBTN_3D: default:
|
||||
gdispFillStringBox(gh->x, gh->y, gh->width-1, gh->height-1, txt, gh->font, ctxt, cfill, justifyCenter);
|
||||
gdispDrawLine(gh->x+gh->width-1, gh->y, gh->x+gh->width-1, gh->y+gh->height-1, cedge);
|
||||
gdispDrawLine(gh->x, gh->y+gh->height-1, gh->x+gh->width-2, gh->y+gh->height-1, cedge);
|
||||
break;
|
||||
}
|
||||
#undef gbw
|
||||
}
|
||||
|
||||
//void gwinSetButtonCallback(GHandle gh, ????);
|
||||
//void gwinSetButtonInput(GHandle gh, ????);
|
||||
#endif
|
||||
|
||||
#endif /* GFX_USE_GWIN */
|
||||
/** @} */
|
||||
|
||||
|
|
331
src/gwin/button.c
Normal file
331
src/gwin/button.c
Normal file
|
@ -0,0 +1,331 @@
|
|||
/*
|
||||
ChibiOS/GFX - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file src/gwin/button.c
|
||||
* @brief GWIN Driver code.
|
||||
*
|
||||
* @addtogroup GWIN_BUTTON
|
||||
* @{
|
||||
*/
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include "gwin.h"
|
||||
#include "ginput.h"
|
||||
|
||||
#if !defined(GFX_USE_GINPUT) || !GFX_USE_GINPUT
|
||||
#error "GWIN Buttons require GFX_USE_GINPUT"
|
||||
#endif
|
||||
|
||||
#if (GFX_USE_GWIN && GWIN_NEED_BUTTON) || defined(__DOXYGEN__)
|
||||
|
||||
#include <string.h>
|
||||
#include "gwin_internal.h"
|
||||
|
||||
static const GButtonStyle GButtonDefaultStyle = {
|
||||
GBTN_3D,
|
||||
HTML2COLOR(0x404040), // color_up_edge;
|
||||
HTML2COLOR(0xE0E0E0), // color_up_fill;
|
||||
HTML2COLOR(0x000000), // color_up_txt;
|
||||
HTML2COLOR(0x404040), // color_dn_edge;
|
||||
HTML2COLOR(0x808080), // color_dn_fill;
|
||||
HTML2COLOR(0x404040), // color_dn_txt;
|
||||
};
|
||||
|
||||
// Process an event callback
|
||||
static void gwinButtonCallback(void *param, GEvent *pe) {
|
||||
GSourceListener *psl;
|
||||
#define gh ((GHandle)param)
|
||||
#define gbw ((GButtonObject *)param)
|
||||
#define gsh ((GSourceHandle)param)
|
||||
#define pme ((GEventMouse *)pe)
|
||||
#define pte ((GEventTouch *)pe)
|
||||
#define pxe ((GEventToggle *)pe)
|
||||
#define pbe ((GEventGWinButton *)pe)
|
||||
|
||||
switch (pe->type) {
|
||||
#if defined(GINPUT_NEED_MOUSE) && GINPUT_NEED_MOUSE
|
||||
case GEVENT_MOUSE:
|
||||
case GEVENT_TOUCH:
|
||||
// Ignore anything other than the primary mouse button going up or down
|
||||
if (!((pme->current_buttons ^ pme->last_buttons) & GINPUT_MOUSE_BTN_LEFT))
|
||||
return;
|
||||
|
||||
if (gbw->state == GBTN_UP) {
|
||||
// Our button is UP: Test for button down over the button
|
||||
if ((pme->current_buttons & GINPUT_MOUSE_BTN_LEFT)
|
||||
&& pme->x >= gbw->gwin.x && pme->x < gbw->gwin.x + gbw->gwin.width
|
||||
&& pme->y >= gbw->gwin.y && pme->y < gbw->gwin.y + gbw->gwin.height) {
|
||||
gbw->state = GBTN_DOWN;
|
||||
gwinButtonDraw((GHandle)param);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Our button is DOWN
|
||||
|
||||
// Skip more mouse downs
|
||||
if ((pme->current_buttons & GINPUT_MOUSE_BTN_LEFT))
|
||||
return;
|
||||
|
||||
// This must be a mouse up - set the button as UP
|
||||
gbw->state = GBTN_UP;
|
||||
gwinButtonDraw((GHandle)param);
|
||||
|
||||
// If the mouse up was over the button then create the event
|
||||
if (pme->x >= gbw->gwin.x && pme->x < gbw->gwin.x + gbw->gwin.width
|
||||
&& pme->y >= gbw->gwin.y && pme->y < gbw->gwin.y + gbw->gwin.height)
|
||||
break;
|
||||
|
||||
return;
|
||||
#endif
|
||||
|
||||
#if defined(GINPUT_NEED_TOGGLE) && GINPUT_NEED_TOGGLE
|
||||
case GEVENT_TOGGLE:
|
||||
// State has changed - update the button
|
||||
gbw->state = pxe->on ? GBTN_DOWN : GBTN_UP;
|
||||
gwinButtonDraw((GHandle)param);
|
||||
|
||||
// Trigger the event on button down (different than for mouse/touch)
|
||||
if (gbw->state == GBTN_DOWN)
|
||||
break;
|
||||
|
||||
return;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// Trigger a GWIN Button Event
|
||||
psl = 0;
|
||||
while ((psl = geventGetSourceListener(gsh, psl))) {
|
||||
if (!(pe = geventGetEventBuffer(psl)))
|
||||
continue;
|
||||
pbe->type = GEVENT_GWIN_BUTTON;
|
||||
pbe->button = gh;
|
||||
geventSendEvent(psl);
|
||||
}
|
||||
|
||||
#undef pbe
|
||||
#undef pme
|
||||
#undef pte
|
||||
#undef pxe
|
||||
#undef gsh
|
||||
#undef gbw
|
||||
#undef gh
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a button window.
|
||||
* @return NULL if there is no resultant drawing area, otherwise a window handle.
|
||||
*
|
||||
* @param[in] gb The GConsoleWindow structure to initialise. If this is NULL the structure is dynamically allocated.
|
||||
* @param[in] x,y The screen co-ordinates for the bottom left corner of the window
|
||||
* @param[in] width The width of the window
|
||||
* @param[in] height The height of the window
|
||||
* @param[in] font The font to use
|
||||
* @param[in] type The type of button
|
||||
* @note The drawing color gets set to White and the background drawing color to Black.
|
||||
* @note The dimensions and position may be changed to fit on the real screen.
|
||||
* @note The button is not automatically drawn. Call gwinButtonDraw() after changing the button style or setting the text.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
GHandle gwinCreateButton(GButtonObject *gb, coord_t x, coord_t y, coord_t width, coord_t height, font_t font, GButtonType type) {
|
||||
if (!(gb = (GButtonObject *)_gwinInit((GWindowObject *)gb, x, y, width, height, sizeof(GButtonObject))))
|
||||
return 0;
|
||||
gb->gwin.type = GW_BUTTON;
|
||||
gwinSetFont(&gb->gwin, font);
|
||||
gwinSetButtonStyle(&gb->gwin, &GButtonDefaultStyle);
|
||||
gb->type = type;
|
||||
gb->state = GBTN_UP;
|
||||
gb->txt = "";
|
||||
geventListenerInit(&gb->listener);
|
||||
geventRegisterCallback(&gb->listener, gwinButtonCallback, gb);
|
||||
return (GHandle)gb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the style of a button.
|
||||
* @details The button style is defined by its shape and colours.
|
||||
*
|
||||
* @param[in] gh The window handle (must be a button window)
|
||||
* @param[in] style The button style to set.
|
||||
* @note The button is not automatically redrawn. Call gwinButtonDraw() after changing the button style
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gwinSetButtonStyle(GHandle gh, const GButtonStyle *style) {
|
||||
#define gbw ((GButtonObject *)gh)
|
||||
if (gh->type != GW_BUTTON)
|
||||
return;
|
||||
|
||||
gbw->style.shape = style->shape;
|
||||
gbw->style.color_up_edge = style->color_up_edge;
|
||||
gbw->style.color_up_fill = style->color_up_fill;
|
||||
gbw->style.color_dn_edge = style->color_dn_edge;
|
||||
gbw->style.color_dn_fill = style->color_dn_fill;
|
||||
gbw->style.color_up_txt = style->color_up_txt;
|
||||
gbw->style.color_dn_txt = style->color_dn_txt;
|
||||
#undef gbw
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the text of a button.
|
||||
*
|
||||
* @param[in] gh The window handle (must be a button window)
|
||||
* @param[in] txt The button text to set. This must be a constant string unless useAlloc is set.
|
||||
* @param[in] useAlloc If TRUE the string specified will be copied into dynamically allocated memory.
|
||||
* @note The button is not automatically redrawn. Call gwinButtonDraw() after changing the button text.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gwinSetButtonText(GHandle gh, const char *txt, bool_t useAlloc) {
|
||||
#define gbw ((GButtonObject *)gh)
|
||||
if (gh->type != GW_BUTTON)
|
||||
return;
|
||||
|
||||
// Dispose of the old string
|
||||
if ((gh->flags & GBTN_FLG_ALLOCTXT)) {
|
||||
gh->flags &= ~GBTN_FLG_ALLOCTXT;
|
||||
if (gbw->txt) {
|
||||
chHeapFree((void *)gbw->txt);
|
||||
gbw->txt = "";
|
||||
}
|
||||
}
|
||||
// Alloc the new text if required
|
||||
if (txt && useAlloc) {
|
||||
char *str;
|
||||
|
||||
if ((str = (char *)chHeapAlloc(NULL, strlen(txt)+1))) {
|
||||
gh->flags |= GBTN_FLG_ALLOCTXT;
|
||||
strcpy(str, txt);
|
||||
}
|
||||
txt = (const char *)str;
|
||||
}
|
||||
|
||||
gbw->txt = txt ? txt : "";
|
||||
#undef gbw
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Redraw the button.
|
||||
*
|
||||
* @param[in] gh The window handle (must be a button window)
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gwinButtonDraw(GHandle gh) {
|
||||
color_t cedge;
|
||||
color_t cfill;
|
||||
color_t ctxt;
|
||||
const char * txt;
|
||||
#define gbw ((GButtonObject *)gh)
|
||||
#define RND_CNR_SIZE 5
|
||||
|
||||
if (gh->type != GW_BUTTON)
|
||||
return;
|
||||
|
||||
#if GDISP_NEED_CLIP
|
||||
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
|
||||
#endif
|
||||
|
||||
// Get the text (safely)
|
||||
txt = gh->font && gbw->txt ? gbw->txt : "";
|
||||
|
||||
// Determine the colors to use
|
||||
switch(gbw->state) {
|
||||
case GBTN_DOWN:
|
||||
cedge = gbw->style.color_dn_edge;
|
||||
cfill = gbw->style.color_dn_fill;
|
||||
ctxt = gbw->style.color_dn_txt;
|
||||
break;
|
||||
case GBTN_UP: default:
|
||||
cedge = gbw->style.color_up_edge;
|
||||
cfill = gbw->style.color_up_fill;
|
||||
ctxt = gbw->style.color_up_txt;
|
||||
break;
|
||||
}
|
||||
|
||||
// Draw according to the shape specified.
|
||||
switch(gbw->style.shape) {
|
||||
#if GDISP_NEED_ARC
|
||||
case GBTN_ROUNDED:
|
||||
if (gh->width >= 2*RND_CNR_SIZE+10) {
|
||||
gdispFillRoundedBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, RND_CNR_SIZE-1, cfill);
|
||||
gdispDrawStringBox(gh->x+1, gh->y+RND_CNR_SIZE, gh->width-2, gh->height-(2*RND_CNR_SIZE), txt, gh->font, ctxt, justifyCenter);
|
||||
gdispDrawRoundedBox(gh->x, gh->y, gh->width, gh->height, RND_CNR_SIZE, cedge);
|
||||
break;
|
||||
}
|
||||
/* Fall Through */
|
||||
#endif
|
||||
case GBTN_SQUARE:
|
||||
gdispFillStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, ctxt, cfill, justifyCenter);
|
||||
gdispDrawBox(gh->x, gh->y, gh->width, gh->height, cedge);
|
||||
break;
|
||||
#if GDISP_NEED_ELLIPSE
|
||||
case GBTN_ELLIPSE:
|
||||
gdispFillEllipse(gh->x+1, gh->y+1, gh->width/2-1, gh->height/2-1, cfill);
|
||||
gdispDrawStringBox(gh->x+1, gh->y+1, gh->width-2, gh->height-2, txt, gh->font, ctxt, justifyCenter);
|
||||
gdispDrawEllipse(gh->x, gh->y, gh->width/2, gh->height/2, cedge);
|
||||
break;
|
||||
#endif
|
||||
case GBTN_3D: default:
|
||||
gdispFillStringBox(gh->x, gh->y, gh->width-1, gh->height-1, txt, gh->font, ctxt, cfill, justifyCenter);
|
||||
gdispDrawLine(gh->x+gh->width-1, gh->y, gh->x+gh->width-1, gh->y+gh->height-1, cedge);
|
||||
gdispDrawLine(gh->x, gh->y+gh->height-1, gh->x+gh->width-2, gh->y+gh->height-1, cedge);
|
||||
break;
|
||||
}
|
||||
#undef gbw
|
||||
}
|
||||
|
||||
// Attach a source to this button. Sources recognised: Mouse, Touch and Toggle - others are ignored (returns false).
|
||||
bool_t gwinAttachButtonSource(GHandle gh, GSourceHandle gsh, GEventType type) {
|
||||
#define gbw ((GButtonObject *)gh)
|
||||
unsigned flags;
|
||||
|
||||
switch (type) {
|
||||
#if defined(GINPUT_NEED_MOUSE) && GINPUT_NEED_MOUSE
|
||||
case GEVENT_MOUSE:
|
||||
flags = 0;
|
||||
break;
|
||||
#endif
|
||||
#if defined(GINPUT_NEED_TOUCH) && GINPUT_NEED_TOUCH
|
||||
case GEVENT_TOUCH:
|
||||
flags = 0;
|
||||
break;
|
||||
#endif
|
||||
#if defined(GINPUT_NEED_TOGGLE) && GINPUT_NEED_TOGGLE
|
||||
case GEVENT_TOGGLE:
|
||||
flags = GLISTEN_TOGGLE_OFF|GLISTEN_TOGGLE_ON;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return geventAttachSource(&gbw->listener, gsh, flags);
|
||||
|
||||
#undef gbw
|
||||
}
|
||||
|
||||
#endif /* GFX_USE_GWIN && GWIN_NEED_BUTTON */
|
||||
/** @} */
|
||||
|
210
src/gwin/console.c
Normal file
210
src/gwin/console.c
Normal file
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
ChibiOS/GFX - Copyright (C) 2012
|
||||
Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
|
||||
This file is part of ChibiOS/GFX.
|
||||
|
||||
ChibiOS/GFX 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file src/gwin/console.c
|
||||
* @brief GWIN Driver code.
|
||||
*
|
||||
* @addtogroup GWIN_CONSOLE
|
||||
* @{
|
||||
*/
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include "gwin.h"
|
||||
|
||||
#if (GFX_USE_GWIN && GWIN_NEED_CONSOLE) || defined(__DOXYGEN__)
|
||||
|
||||
#include <string.h>
|
||||
#include "gwin_internal.h"
|
||||
|
||||
|
||||
#define GWIN_CONSOLE_USE_CLEAR_LINES TRUE
|
||||
#define GWIN_CONSOLE_USE_FILLED_CHARS FALSE
|
||||
|
||||
/*
|
||||
* Stream interface implementation. The interface is write only
|
||||
*/
|
||||
|
||||
#define Stream2GWindow(ip) ((GHandle)(((char *)(ip)) - (size_t)(&(((GConsoleObject *)0)->stream))))
|
||||
|
||||
static size_t GWinStreamWrite(void *ip, const uint8_t *bp, size_t n) { gwinPutCharArray(Stream2GWindow(ip), (const char *)bp, n); return RDY_OK; }
|
||||
static size_t GWinStreamRead(void *ip, uint8_t *bp, size_t n) { (void)ip; (void)bp; (void)n; return 0; }
|
||||
static msg_t GWinStreamPut(void *ip, uint8_t b) { gwinPutChar(Stream2GWindow(ip), (char)b); return RDY_OK; }
|
||||
static msg_t GWinStreamGet(void *ip) {(void)ip; return RDY_OK; }
|
||||
static msg_t GWinStreamPutTimed(void *ip, uint8_t b, systime_t time) { (void)time; gwinPutChar(Stream2GWindow(ip), (char)b); return RDY_OK; }
|
||||
static msg_t GWinStreamGetTimed(void *ip, systime_t timeout) { (void)ip; (void)timeout; return RDY_OK; }
|
||||
static size_t GWinStreamWriteTimed(void *ip, const uint8_t *bp, size_t n, systime_t time) { (void)time; gwinPutCharArray(Stream2GWindow(ip), (const char *)bp, n); return RDY_OK; }
|
||||
static size_t GWinStreamReadTimed(void *ip, uint8_t *bp, size_t n, systime_t time) { (void)ip; (void)bp; (void)n; (void)time; return 0; }
|
||||
|
||||
struct GConsoleWindowVMT_t {
|
||||
_base_asynchronous_channel_methods
|
||||
};
|
||||
|
||||
static const struct GConsoleWindowVMT_t GWindowConsoleVMT = {
|
||||
GWinStreamWrite,
|
||||
GWinStreamRead,
|
||||
GWinStreamPut,
|
||||
GWinStreamGet,
|
||||
GWinStreamPutTimed,
|
||||
GWinStreamGetTimed,
|
||||
GWinStreamWriteTimed,
|
||||
GWinStreamReadTimed
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a console window.
|
||||
* @details A console window allows text to be written using chprintf() (and the console functions defined here).
|
||||
* @brief Text in a console window supports newlines and will wrap text as required.
|
||||
* @return NULL if there is no resultant drawing area, otherwise a window handle.
|
||||
*
|
||||
* @param[in] gc The GConsoleObject structure to initialise. If this is NULL the structure is dynamically allocated.
|
||||
* @param[in] x,y The screen co-ordinates for the bottom left corner of the window
|
||||
* @param[in] width The width of the window
|
||||
* @param[in] height The height of the window
|
||||
* @param[in] font The font to use
|
||||
* @note The console is not automatically cleared on creation. You must do that by calling gwinClear() (possibly after changing your background color)
|
||||
* @note If the dispay does not support scrolling, the window will be cleared when the bottom line is reached.
|
||||
* @note The default drawing color gets set to White and the background drawing color to Black.
|
||||
* @note The dimensions and position may be changed to fit on the real screen.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
GHandle gwinCreateConsole(GConsoleObject *gc, coord_t x, coord_t y, coord_t width, coord_t height, font_t font) {
|
||||
if (!(gc = (GConsoleObject *)_gwinInit((GWindowObject *)gc, x, y, width, height, sizeof(GConsoleObject))))
|
||||
return 0;
|
||||
gc->gwin.type = GW_CONSOLE;
|
||||
gwinSetFont(&gc->gwin, font);
|
||||
gc->stream.vmt = &GWindowConsoleVMT;
|
||||
gc->cx = 0;
|
||||
gc->cy = 0;
|
||||
return (GHandle)gc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a stream from a console window suitable for use with chprintf().
|
||||
* @return The stream handle or NULL if this is not a console window.
|
||||
*
|
||||
* @param[in] gh The window handle (must be a console window)
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
BaseSequentialStream *gwinGetConsoleStream(GHandle gh) {
|
||||
if (gh->type != GW_CONSOLE)
|
||||
return 0;
|
||||
return (BaseSequentialStream *)&(((GConsoleObject *)(gh))->stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Put a character at the cursor position in the window.
|
||||
* @note Uses the current foreground color to draw the character and fills the background using the background drawing color
|
||||
*
|
||||
* @param[in] gh The window handle (must be a console window)
|
||||
* @param[in] c The character to draw
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gwinPutChar(GHandle gh, char c) {
|
||||
uint8_t width;
|
||||
#define gcw ((GConsoleObject *)gh)
|
||||
|
||||
if (gh->type != GW_CONSOLE || !gh->font) return;
|
||||
|
||||
#if GDISP_NEED_CLIP
|
||||
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
|
||||
#endif
|
||||
|
||||
if (c == '\n') {
|
||||
gcw->cx = 0;
|
||||
gcw->cy += gcw->fy;
|
||||
// We use lazy scrolling here and only scroll when the next char arrives
|
||||
} else if (c == '\r') {
|
||||
// gcw->cx = 0;
|
||||
} else {
|
||||
width = gdispGetCharWidth(c, gh->font) + gcw->fp;
|
||||
if (gcw->cx + width >= gh->width) {
|
||||
gcw->cx = 0;
|
||||
gcw->cy += gcw->fy;
|
||||
}
|
||||
|
||||
if (gcw->cy + gcw->fy > gh->height) {
|
||||
#if GDISP_NEED_SCROLL
|
||||
/* scroll the console */
|
||||
gdispVerticalScroll(gh->x, gh->y, gh->width, gh->height, gcw->fy, gh->bgcolor);
|
||||
/* reset the cursor to the start of the last line */
|
||||
gcw->cx = 0;
|
||||
gcw->cy = (((coord_t)(gh->height/gcw->fy))-1)*gcw->fy;
|
||||
#else
|
||||
/* clear the console */
|
||||
gdispFillArea(gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
|
||||
/* reset the cursor to the top of the window */
|
||||
gcw->cx = 0;
|
||||
gcw->cy = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if GWIN_CONSOLE_USE_CLEAR_LINES
|
||||
/* clear to the end of the line */
|
||||
if (gcw->cx == 0)
|
||||
gdispFillArea(gh->x, gh->y + gcw->cy, gh->width, gcw->fy, gh->bgcolor);
|
||||
#endif
|
||||
#if GWIN_CONSOLE_USE_FILLED_CHARS
|
||||
gdispFillChar(gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, gh->color, gh->bgcolor);
|
||||
#else
|
||||
gdispDrawChar(gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, gh->color);
|
||||
#endif
|
||||
|
||||
/* update cursor */
|
||||
gcw->cx += width;
|
||||
}
|
||||
#undef gcw
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Put a string at the cursor position in the window. It will wrap lines as required.
|
||||
* @note Uses the current foreground color to draw the string and fills the background using the background drawing color
|
||||
*
|
||||
* @param[in] gh The window handle (must be a console window)
|
||||
* @param[in] str The string to draw
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gwinPutString(GHandle gh, const char *str) {
|
||||
while(*str)
|
||||
gwinPutChar(gh, *str++);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Put the character array at the cursor position in the window. It will wrap lines as required.
|
||||
* @note Uses the current foreground color to draw the string and fills the background using the background drawing color
|
||||
*
|
||||
* @param[in] gh The window handle (must be a console window)
|
||||
* @param[in] str The string to draw
|
||||
* @param[in] n The number of characters to draw
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gwinPutCharArray(GHandle gh, const char *str, size_t n) {
|
||||
while(n--)
|
||||
gwinPutChar(gh, *str++);
|
||||
}
|
||||
|
||||
#endif /* GFX_USE_GWIN && GWIN_NEED_CONSOLE */
|
||||
/** @} */
|
||||
|
2
src/gwin/gwin.mk
Normal file
2
src/gwin/gwin.mk
Normal file
|
@ -0,0 +1,2 @@
|
|||
GFXSRC += $(GFXLIB)/src/gwin/console.c \
|
||||
$(GFXLIB)/src/gwin/button.c
|
|
@ -17,34 +17,37 @@
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file drivers/gdisp/Win32/touchscreen_lld_config.h
|
||||
* @brief Touchscreen Driver subsystem low level driver.
|
||||
* @file gwin_internal.h
|
||||
* @brief GWIN Graphic window subsystem header file.
|
||||
*
|
||||
* @addtogroup TOUCHSCREEN
|
||||
* @addtogroup GWIN
|
||||
* @{
|
||||
*/
|
||||
#ifndef _GWIN_INTERNAL_H
|
||||
#define _GWIN_INTERNAL_H
|
||||
|
||||
#ifndef TOUCHSCREEN_LLD_CONFIG_H
|
||||
#define TOUCHSCREEN_LLD_CONFIG_H
|
||||
|
||||
#if GFX_USE_TOUCHSCREEN /*|| defined(__DOXYGEN__)*/
|
||||
#if GFX_USE_GWIN || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver hardware support. */
|
||||
/* Sub-system constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define TOUCHSCREEN_HAS_PRESSED TRUE
|
||||
#define TOUCHSCREEN_HAS_PRESSURE FALSE
|
||||
#define TOUCHSCREEN_XY_INVERTED FALSE
|
||||
#define TOUCHSCREEN_STORE_CALIBRATION TRUE
|
||||
#define TOUCHSCREEN_CONVERSIONS 1
|
||||
#define GWIN_FLG_DYNAMIC 0x0001
|
||||
#define GWIN_FIRST_CONTROL_FLAG 0x0002
|
||||
#define GBTN_FLG_ALLOCTXT (GWIN_FIRST_CONTROL_FLAG<<0)
|
||||
|
||||
struct TouchscreenDriver {};
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#endif /* GFX_USE_TOUCHSCREEN */
|
||||
GHandle _gwinInit(GWindowObject *gw, coord_t x, coord_t y, coord_t width, coord_t height, size_t size);
|
||||
|
||||
#endif /* TOUCHSCREEN_LLD_CONFIG_H */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GFX_USE_GWIN */
|
||||
|
||||
#endif /* _GWIN_INTERNAL_H */
|
||||
/** @} */
|
||||
|
Loading…
Add table
Reference in a new issue