diff options
| -rw-r--r-- | drivers/multiple/uGFXnet/gdisp_lld_uGFXnet.c | 3 | ||||
| -rw-r--r-- | src/gdisp/driver.h | 36 | ||||
| -rw-r--r-- | src/gdisp/gdisp_gdisp.c | 106 | ||||
| -rw-r--r-- | src/gdriver/gdriver_gdriver.c | 47 | ||||
| -rw-r--r-- | src/gdriver/sys_defs.h | 17 | 
5 files changed, 146 insertions, 63 deletions
diff --git a/drivers/multiple/uGFXnet/gdisp_lld_uGFXnet.c b/drivers/multiple/uGFXnet/gdisp_lld_uGFXnet.c index bfe430df..802f2822 100644 --- a/drivers/multiple/uGFXnet/gdisp_lld_uGFXnet.c +++ b/drivers/multiple/uGFXnet/gdisp_lld_uGFXnet.c @@ -12,7 +12,7 @@  #define GDISP_DRIVER_VMT			GDISPVMT_uGFXnet  #include "drivers/multiple/uGFXnet/gdisp_lld_config.h"  #include "src/gdisp/driver.h" -#include "drivers/multiple/uGFXnet/uGFXnetProtocol.h" +#include "uGFXnetProtocol.h"  #ifndef GDISP_SCREEN_WIDTH  	#define GDISP_SCREEN_WIDTH	640 @@ -47,6 +47,7 @@  #if defined(WIN32) || GFX_USE_OS_WIN32  	#include <winsock.h>  	#define SOCKET_TYPE				SOCKET +	#define socklen_t		int  	static void StopSockets(void) {  		WSACleanup(); diff --git a/src/gdisp/driver.h b/src/gdisp/driver.h index 82435589..5213e5ae 100644 --- a/src/gdisp/driver.h +++ b/src/gdisp/driver.h @@ -37,6 +37,17 @@   * @{   */  	/** +	 * @brief   The display hardware can benefit from being de-initialized when usage is complete. +	 * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT +	 * +	 * @note	HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1 +	 * @note	This is most useful for displays such as remote network displays. +	 */ +	#ifndef GDISP_HARDWARE_DEINIT +		#define GDISP_HARDWARE_DEINIT		HARDWARE_DEFAULT +	#endif + +	/**  	 * @brief   The display hardware can benefit from being flushed.  	 * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT  	 * @@ -215,7 +226,7 @@  struct GDisplay {  	struct GDriver				d;					// This must be the first element -		#define gvmt(g)		((const GDISPVMT const *)(g)->d.vmt)	// For ease of access to the vmt member +		#define gvmt(g)		((const GDISPVMT const *)((g)->d.vmt))	// For ease of access to the vmt member  	struct GDISPControl {  		coord_t					Width; @@ -278,6 +289,7 @@ struct GDisplay {  typedef struct GDISPVMT {  	GDriverVMT	vmtdriver;  	bool_t (*init)(GDisplay *g); +	void (*deinit)(GDisplay *g);  	void (*writestart)(GDisplay *g);				// Uses p.x,p.y  p.cx,p.cy  	void (*writepos)(GDisplay *g);					// Uses p.x,p.y  	void (*writecolor)(GDisplay *g);				// Uses p.color @@ -318,6 +330,17 @@ typedef struct GDISPVMT {  	 */  	LLDSPEC	bool_t gdisp_lld_init(GDisplay *g); +	#if GDISP_HARDWARE_DEINIT || defined(__DOXYGEN__) +		/** +		 * @brief   The driver is being de-initialized +		 * @pre		GDISP_HARDWARE_FLUSH is TRUE +		 * +		 * @param[in]	g				The driver structure +		 * +		 */ +		LLDSPEC	void gdisp_lld_deinit(GDisplay *g); +	#endif +  	#if GDISP_HARDWARE_FLUSH || defined(__DOXYGEN__)  		/**  		 * @brief   Flush the current drawing operations to the display @@ -559,6 +582,7 @@ typedef struct GDISPVMT {  #else  	#define gdisp_lld_init(g)				gvmt(g)->init(g) +	#define gdisp_lld_deinit(g)				gvmt(g)->deinit(g)  	#define gdisp_lld_flush(g)				gvmt(g)->flush(g)  	#define gdisp_lld_write_start(g)		gvmt(g)->writestart(g)  	#define gdisp_lld_write_pos(g)			gvmt(g)->writepos(g) @@ -594,12 +618,18 @@ typedef struct GDISPVMT {  	// Routines needed by the general driver VMT  	bool_t _gdispInitDriver(GDriver *g, int driverinstance, int systeminstance); -	void _gdispDeinitDriver(GDriver *g); +	void _gdispPostInitDriver(GDriver *g); +	void _gdispDeInitDriver(GDriver *g);  	// Build the VMT  	const GDISPVMT const GDISP_DRIVER_VMT[1] = {{ -		{ GDRIVER_TYPE_DISPLAY, 0, sizeof(GDisplay), _gdispInitDriver, _gdispDeinitDriver }, +		{ GDRIVER_TYPE_DISPLAY, 0, sizeof(GDisplay), _gdispInitDriver, _gdispPostInitDriver, _gdispDeInitDriver },  		gdisp_lld_init, +		#if GDISP_HARDWARE_DEINIT +			gdisp_lld_deinit, +		#else +			0, +		#endif  		#if GDISP_HARDWARE_STREAM_WRITE  			gdisp_lld_write_start,  			#if GDISP_HARDWARE_STREAM_POS diff --git a/src/gdisp/gdisp_gdisp.c b/src/gdisp/gdisp_gdisp.c index 5b99da6c..a34788b2 100644 --- a/src/gdisp/gdisp_gdisp.c +++ b/src/gdisp/gdisp_gdisp.c @@ -55,10 +55,12 @@ GDisplay	*GDISP;  	#define MUTEX_INIT(g)		gfxMutexInit(&(g)->mutex)  	#define MUTEX_ENTER(g)		gfxMutexEnter(&(g)->mutex)  	#define MUTEX_EXIT(g)		gfxMutexExit(&(g)->mutex) +	#define MUTEX_DEINIT(g)		gfxMutexDestroy(&(g)->mutex)  #else  	#define MUTEX_INIT(g)  	#define MUTEX_ENTER(g)  	#define MUTEX_EXIT(g) +	#define MUTEX_DEINIT(g)  #endif  #define NEED_CLIPPING	(GDISP_HARDWARE_CLIP != TRUE && (GDISP_NEED_VALIDATION || GDISP_NEED_CLIP)) @@ -564,18 +566,68 @@ static void line_clip(GDisplay *g) {  void _gdispInit(void)  { +	// Both GDISP_CONTROLLER_LIST and GDISP_CONTROLLER_DISPLAYS are defined - create the required numbers of each controller +	#if defined(GDISP_CONTROLLER_LIST) && defined(GDISP_CONTROLLER_DISPLAYS) +		{ +			int		i, cnt; + +			extern GDriverVMTList					GDISP_CONTROLLER_LIST; +			static const struct GDriverVMT const *	dclist[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_LIST}; +			static const unsigned					dnlist[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_DISPLAYS}; + +			for(i = 0; i < GDISP_TOTAL_CONTROLLERS; i++) { +				for(cnt = dnlist[i]; cnt; cnt--) +					gdriverRegister(dclist[i]); +			} +		} + +	// Only GDISP_CONTROLLER_LIST is defined - create one of each controller +	#elif defined(GDISP_CONTROLLER_LIST) +		{ +			int		i; + +			extern GDriverVMTList					GDISP_CONTROLLER_LIST; +			static const struct GDriverVMT const *	dclist[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_LIST}; + +			for(i = 0; i < GDISP_TOTAL_CONTROLLERS; i++) +				gdriverRegister(dclist[i]); +		} + +	// Only GDISP_TOTAL_DISPLAYS is defined - create the required number of the one controller +	#elif GDISP_TOTAL_DISPLAYS > 1 +		{ +			int		cnt; + +			extern GDriverVMTList 					GDISPVMT_OnlyOne; + +			for(cnt = 0; cnt < GDISP_TOTAL_DISPLAYS; cnt++) +				gdriverRegister(GDISPVMT_OnlyOne); +		} + +	// One and only one display +	#else +		{ +			extern GDriverVMTList					GDISPVMT_OnlyOne; + +			gdriverRegister(GDISPVMT_OnlyOne); +		} +	#endif +  	// Re-clear the display after the timeout if we added the logo  	#if GDISP_STARTUP_LOGO_TIMEOUT > 0 -		GDisplay	*g; +		{ +			GDisplay	*g; -		gfxSleepMilliseconds(GDISP_STARTUP_LOGO_TIMEOUT); -		initDone = TRUE; +			gfxSleepMilliseconds(GDISP_STARTUP_LOGO_TIMEOUT); -		for(g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, 0); g; g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g)) { -			gdispGClear(g, GDISP_STARTUP_COLOR); -			#if GDISP_HARDWARE_FLUSH -				gdispGFlush(g); -			#endif +			for(g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, 0); g; g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g)) { +				gdispGClear(g, GDISP_STARTUP_COLOR); +				#if GDISP_HARDWARE_FLUSH +					gdispGFlush(g); +				#endif +			} + +			initDone = TRUE;  		}  	#endif @@ -605,22 +657,32 @@ bool_t _gdispInitDriver(GDriver *g, int driverinstance, int systeminstance) {  	MUTEX_ENTER(gd);  	ret = gdisp_lld_init(gd);  	MUTEX_EXIT(gd); -	if (!ret) return FALSE; +	return ret; -	// Set orientation, clip, blankscreen, startup logo and then flush +	#undef gd +} + +void _gdispPostInitDriver(GDriver *g) { +	#define		gd		((GDisplay *)g) + +	// Set orientation, clip  	#if defined(GDISP_DEFAULT_ORIENTATION) && GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL  		gdispGControl(gd, GDISP_CONTROL_ORIENTATION, (void *)GDISP_DEFAULT_ORIENTATION);  	#endif  	#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP  		gdispGSetClip(gd, 0, 0, gd->g.Width, gd->g.Height);  	#endif + +	// Clear the Screen  	gdispGClear(gd, GDISP_STARTUP_COLOR); +	// Display the startup logo if this is a static initialised display  	#if GDISP_STARTUP_LOGO_TIMEOUT > 0  		if (!initDone)  			StartupLogoDisplay(gd);  	#endif +	// Flush  	#if GDISP_HARDWARE_FLUSH  		gdispGFlush(gd);  	#endif @@ -629,14 +691,28 @@ bool_t _gdispInitDriver(GDriver *g, int driverinstance, int systeminstance) {  	if (!GDISP)  		GDISP = gd; -	return TRUE; -  	#undef gd  } -void _gdispDeinitDriver(GDriver *g) { -	(void) g; -	// For now do nothing +void _gdispDeInitDriver(GDriver *g) { +	#define		gd		((GDisplay *)g) + +	if (GDISP == gd) +		GDISP = (GDisplay *)gdriverGetInstance(GDRIVER_TYPE_DISPLAY, 0); + +	#if GDISP_HARDWARE_DEINIT +		#if GDISP_HARDWARE_DEINIT == HARDWARE_AUTODETECT +			if (gvmt(gd)->deinit) +		#endif +		{ +			MUTEX_ENTER(gd); +			gdisp_lld_deinit(gd); +			MUTEX_EXIT(gd); +		} +	#endif +	MUTEX_DEINIT(gd); + +	#undef gd  }  GDisplay *gdispGetDisplay(unsigned display) { diff --git a/src/gdriver/gdriver_gdriver.c b/src/gdriver/gdriver_gdriver.c index 2c73719e..90a1d932 100644 --- a/src/gdriver/gdriver_gdriver.c +++ b/src/gdriver/gdriver_gdriver.c @@ -14,51 +14,8 @@  // Define the tables to hold the driver instances.  static GDriver *dhead; -// Definition that allows getting addresses of structures -typedef const struct GDriverVMT const	VMT_EL[1]; -  // The system initialization.  void _gdriverInit(void) { -	#if GFX_USE_GDISP -	{ -		// Both GDISP_CONTROLLER_LIST and GDISP_CONTROLLER_DISPLAYS are defined - create the required numbers of each controller -		#if defined(GDISP_CONTROLLER_LIST) && defined(GDISP_CONTROLLER_DISPLAYS) -			int		i, cnt; - - -			extern VMT_EL							GDISP_CONTROLLER_LIST; -			static const struct GDriverVMT const *	dclist[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_LIST}; -			static const unsigned					dnlist[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_DISPLAYS}; -			for(i = 0; i < GDISP_TOTAL_CONTROLLERS; i++) { -				for(cnt = dnlist[i]; cnt; cnt--) -					gdriverRegister(dclist[i]); -			} - -		// Only GDISP_CONTROLLER_LIST is defined - create one of each controller -		#elif defined(GDISP_CONTROLLER_LIST) -			int		i; - - -			extern VMT_EL							GDISP_CONTROLLER_LIST; -			static const struct GDriverVMT const *	dclist[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_LIST}; -			for(i = 0; i < GDISP_TOTAL_CONTROLLERS; i++) -				gdriverRegister(dclist[i]); - -		// Only GDISP_TOTAL_DISPLAYS is defined - create the required number of the one controller -		#elif GDISP_TOTAL_DISPLAYS > 1 -			int		cnt; - -			extern VMT_EL GDISPVMT_OnlyOne; -			for(cnt = 0; cnt < GDISP_TOTAL_DISPLAYS; cnt++) -				gdriverRegister(GDISPVMT_OnlyOne); - -		// One and only one display -		#else -			extern VMT_EL GDISPVMT_OnlyOne; -			gdriverRegister(GDISPVMT_OnlyOne); -		#endif -	} -	#endif  	// Drivers not loaded yet  	// GINPUT_NEED_MOUSE @@ -107,6 +64,10 @@ GDriver *gdriverRegister(const GDriverVMT *vmt) {  	else  		dhead = pd; +	// Do the post init +	if (vmt->postinit) +		vmt->postinit(pd); +  	return pd;  } diff --git a/src/gdriver/sys_defs.h b/src/gdriver/sys_defs.h index c5ab9862..7f50fc6d 100644 --- a/src/gdriver/sys_defs.h +++ b/src/gdriver/sys_defs.h @@ -67,12 +67,27 @@ typedef struct GDriverVMT {  	uint16_t	type;																// @< What type of driver this is  	uint16_t	flags;																// @< Flags for the driver. Meaning is specific to each driver type.  	uint32_t	objsize;															// @< How big the runtime driver structure is -	bool_t		(*init)(GDriver *driver, int driverinstance, int systeminstance);	// @< Initialise the driver. +	bool_t		(*init)(GDriver *driver, int driverinstance, int systeminstance);	// @< Initialise the driver. Returns TRUE if OK.  																					//		driverinstance is the instance 0..n of this driver.  																					//		systeminstance is the instance 0..n of this type of device. +	void		(*postinit)(GDriver *driver);										// @< Called once the driver is registered.  	void		(*deinit)(GDriver *driver);											// @< De-initialise the driver  } GDriverVMT; +/** + * @brief	A definition that allows getting addresses of GDriverVMT structures to put into a list. + * @note	eg. <code> + * 				const MyDriverVMTtype a[1] = {{...}}; + * 				const MyDriverVMTtype b[1] = {{...}}; + * 				... + * 				#define DRIVER_LIST		a, b + * 				extern GDriverVMTList	DRIVER_LIST;	// Now treated as single element arrays of GDriverVMT + * 				const GDriverVMT const * mylist = { DRIVER_LIST }; + * 				</code> + * + */ +typedef const struct GDriverVMT const	GDriverVMTList[1]; +  /*===========================================================================*/  /* External declarations.                                                    */  /*===========================================================================*/  | 
