Example #1
0
void geventDetachSource(GListener *pl, GSourceHandle gsh) {
	if (pl) {
		gfxMutexEnter(&geventMutex);
		deleteAssignments(pl, gsh);
		if (!gsh && gfxSemCounter(&pl->waitqueue) < 0) {
			gfxSemWait(&pl->eventlock, TIME_INFINITE);		// Obtain the buffer lock
			pl->event.type = GEVENT_EXIT;					// Set up the EXIT event
			gfxSemSignal(&pl->waitqueue);					// Wake up the listener
			gfxSemSignal(&pl->eventlock);					// Release the buffer lock
		}
		gfxMutexExit(&geventMutex);
	}
}
Example #2
0
void geventRegisterCallback(GListener *pl, GEventCallbackFn fn, void *param) {
	if (pl) {
		gfxMutexEnter(&geventMutex);
		gfxSemWait(&pl->eventlock, TIME_INFINITE);			// Obtain the buffer lock
		pl->param = param;									// Set the param
		pl->callback = fn;									// Set the callback function
		if (gfxSemCounter(&pl->waitqueue) < 0) {
			pl->event.type = GEVENT_EXIT;			// Set up the EXIT event
			gfxSemSignal(&pl->waitqueue);			// Wake up the listener
		}
		gfxSemSignal(&pl->eventlock);				// Release the buffer lock
		gfxMutexExit(&geventMutex);
	}
}
Example #3
0
/*	Null is treated as a wildcard. */
static void deleteAssignments(GListener *pl, GSourceHandle gsh) {
	GSourceListener *psl;

	for(psl = Assignments; psl < Assignments+GEVENT_MAX_SOURCE_LISTENERS; psl++) {
		if ((!pl || psl->pListener == pl) && (!gsh || psl->pSource == gsh)) {
			if (gfxSemCounter(&psl->pListener->waitqueue) < 0) {
				gfxSemWait(&psl->pListener->eventlock, TIME_INFINITE);	// Obtain the buffer lock
				psl->pListener->event.type = GEVENT_EXIT;				// Set up the EXIT event
				gfxSemSignal(&psl->pListener->waitqueue);				// Wake up the listener
				gfxSemSignal(&psl->pListener->eventlock);				// Release the buffer lock
			}
			psl->pListener = 0;
		}
	}
}
Example #4
0
File: gevent.c Project: bigzed/uGFX
void geventSendEvent(GSourceListener *psl) {
	gfxMutexEnter(&geventMutex);
	if (psl->pListener->callback) {

		// Mark it back as free and as sent. This is early to be marking as free but it protects
		//	if the callback alters the listener in any way
		psl->pListener->flags &= ~(GLISTENER_WITHSOURCE|GLISTENER_EVENTBUSY|GLISTENER_PENDING);
		gfxMutexExit(&geventMutex);

		// Do the callback
		psl->pListener->callback(psl->pListener->param, &psl->pListener->event);

	} else {
		// Wake up the listener
		psl->pListener->flags &= ~GLISTENER_WITHSOURCE;
		if ((psl->pListener->flags & GLISTENER_WAITING)) {
			psl->pListener->flags &= ~(GLISTENER_WAITING|GLISTENER_PENDING);
			gfxSemSignal(&psl->pListener->waitqueue);
		} else
			psl->pListener->flags |= GLISTENER_PENDING;

		// The listener thread will free the event buffer when ready
		gfxMutexExit(&geventMutex);
	}
}
Example #5
0
File: gqueue.c Project: bigzed/uGFX
	void gfxQueueFSyncRemove(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem) {
		gfxQueueFSyncItem *pi;

		if (!pitem) return;				// Safety
		gfxSystemLock();
		if (pqueue->head) {
			if (pqueue->head == pitem) {
				pqueue->head = pitem->next;
			found:
				pitem->next = 0;
				gfxSystemUnlock();
				gfxSemSignal(&pitem->sem);
				gfxSemDestroy(&pitem->sem);
				return;
			}
			for(pi = pqueue->head; pi->next; pi = pi->next) {
				if (pi->next == pitem) {
					pi->next = pitem->next;
					if (pqueue->tail == pitem)
						pqueue->tail = pi;
					goto found;
				}
			}
		}
		gfxSystemUnlock();
	}
Example #6
0
File: gqueue.c Project: bigzed/uGFX
	bool_t gfxQueueFSyncInsert(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, gfxQueueASyncItem *pafter, delaytime_t ms) {
		if (!pitem) return;				// Safety
		gfxSemInit(&pitem->sem, 0, 1);

		gfxSystemLock();
		if (pafter && gfxQueueGSyncIsInI(pqueue, pafter)) {
			pitem->next = pafter->next;
			pafter->next = pitem;
			if (pqueue->tail == pafter)
				pqueue->tail = pitem;
		} else {
			pitem->next = 0;
			if (!pqueue->head) {
				pqueue->head = pqueue->tail = pitem;
			} else {
				pqueue->tail->next = pitem;
				pqueue->tail = pitem;
			}
		}
		gfxSystemUnlock();

		gfxSemSignal(&pqueue->sem);

		return gfxSemWait(&pitem->sem, ms);

	}
Example #7
0
File: gevent.c Project: bigzed/uGFX
/* We already have the geventMutex */
static void doExitEvent(GListener *pl) {
	// Don't do the exit if someone else currently has the event lock
	if ((pl->flags & (GLISTENER_WAITING|GLISTENER_EVENTBUSY)) == GLISTENER_WAITING) {
		pl->flags |= GLISTENER_EVENTBUSY;							// Event buffer is in use
		pl->event.type = GEVENT_EXIT;								// Set up the EXIT event
		pl->flags &= ~GLISTENER_WAITING;							// Wake up the listener (with data)
		gfxSemSignal(&pl->waitqueue);
	}
}
Example #8
0
void gtimerJab(GTimer *pt) {
	gfxMutexEnter(&mutex);
	
	// Jab it!
	pt->flags |= GTIMER_FLG_JABBED;

	// Bump the thread
	gfxSemSignal(&waitsem);
	gfxMutexExit(&mutex);
}
Example #9
0
	void gfxQueueGSyncPush(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) {
		gfxSystemLock();
		pitem->next = pqueue->head;
		pqueue->head = pitem;
		if (!pitem->next)
			pqueue->tail = pitem;
		gfxSystemUnlock();

		gfxSemSignal(&pqueue->sem);
	}
Example #10
0
void _gwinDrawEnd(GHandle gh) {
	// Ensure there is no clip set
	#if GDISP_NEED_CLIP
		gdispGUnsetClip(gh->display);
	#endif

	// Look for something to redraw
	_gwinFlushRedraws(REDRAW_INSESSION);

	// Release the lock
	gfxSemSignal(&gwinsem);
}
Example #11
0
	bool_t gfxQueueFSyncPush(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, delaytime_t ms) {
		gfxSemInit(&pitem->sem, 0, 1);

		gfxSystemLock();
		pitem->next = pqueue->head;
		pqueue->head = pitem;
		if (!pitem->next)
			pqueue->tail = pitem;
		gfxSystemUnlock();

		gfxSemSignal(&pqueue->sem);
		return gfxSemWait(&pitem->sem, ms);
	}
Example #12
0
void gtimerStart(GTimer *pt, GTimerFunction fn, void *param, bool_t periodic, delaytime_t millisec) {
	gfxMutexEnter(&mutex);
	
	// Start our thread if not already going
	if (!hThread) {
		hThread = gfxThreadCreate(waTimerThread, GTIMER_THREAD_WORKAREA_SIZE, GTIMER_THREAD_PRIORITY, GTimerThreadHandler, 0);
		if (hThread) {gfxThreadClose(hThread);}		// We never really need the handle again
	}

	// Is this already scheduled?
	if (pt->flags & GTIMER_FLG_SCHEDULED) {
		// Cancel it!
		if (pt->next == pt)
			pTimerHead = 0;
		else {
			pt->next->prev = pt->prev;
			pt->prev->next = pt->next;
			if (pTimerHead == pt)
				pTimerHead = pt->next;
		}
	}
	
	// Set up the timer structure
	pt->fn = fn;
	pt->param = param;
	pt->flags = GTIMER_FLG_SCHEDULED;
	if (periodic)
		pt->flags |= GTIMER_FLG_PERIODIC;
	if (millisec == TIME_INFINITE) {
		pt->flags |= GTIMER_FLG_INFINITE;
		pt->period = TIME_INFINITE;
	} else {
		pt->period = gfxMillisecondsToTicks(millisec);
		pt->when = gfxSystemTicks() + pt->period;
	}

	// Just pop it on the end of the queue
	if (pTimerHead) {
		pt->next = pTimerHead;
		pt->prev = pTimerHead->prev;
		pt->prev->next = pt;
		pt->next->prev = pt;
	} else
		pt->next = pt->prev = pTimerHead = pt;

	// Bump the thread
	if (!(pt->flags & GTIMER_FLG_INFINITE))
		gfxSemSignal(&waitsem);
	gfxMutexExit(&mutex);
}
Example #13
0
	void gfxQueueGSyncPut(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) {
		pitem->next = 0;

		gfxSystemLock();
		if (!pqueue->head) {
			pqueue->head = pqueue->tail = pitem;
		} else {
			pqueue->tail->next = pitem;
			pqueue->tail = pitem;
		}
		gfxSystemUnlock();

		gfxSemSignal(&pqueue->sem);
	}
Example #14
0
void geventSendEvent(GSourceListener *psl) {
	gfxMutexEnter(&geventMutex);
	if (psl->pListener->callback) {				// This test needs to be taken inside the mutex
		gfxMutexExit(&geventMutex);
		// We already know we have the event lock
		psl->pListener->callback(psl->pListener->param, &psl->pListener->event);

	} else {
		// Wake up the listener
		if (gfxSemCounter(&psl->pListener->waitqueue) <= 0)
			gfxSemSignal(&psl->pListener->waitqueue);
		gfxMutexExit(&geventMutex);
	}
}
Example #15
0
File: gqueue.c Project: bigzed/uGFX
	gfxQueueFSyncItem *gfxQueueFSyncGet(gfxQueueFSync *pqueue, delaytime_t ms) {
		gfxQueueFSyncItem	*pi;

		if (!gfxSemWait(&pqueue->sem, ms))
			return 0;

		gfxSystemLock();
		pi = pqueue->head;
		pqueue->head = pi->next;
		pi->next = 0;
		gfxSystemUnlock();

		gfxSemSignal(&pi->sem);
		gfxSemDestroy(&pi->sem);

		return pi;
	}
Example #16
0
File: gqueue.c Project: bigzed/uGFX
	bool_t gfxQueueFSyncPut(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, delaytime_t ms) {
		if (!pitem) return;				// Safety
		gfxSemInit(&pitem->sem, 0, 1);
		pitem->next = 0;

		gfxSystemLock();
		if (!pqueue->head) {
			pqueue->head = pqueue->tail = pitem;
		} else {
			pqueue->tail->next = pitem;
			pqueue->tail = pitem;
		}
		gfxSystemUnlock();

		gfxSemSignal(&pqueue->sem);

		return gfxSemWait(&pitem->sem, ms);
	}
Example #17
0
bool_t geventAttachSource(GListener *pl, GSourceHandle gsh, unsigned flags) {
	GSourceListener *psl, *pslfree;

	// Safety first
	if (!pl || !gsh) {
		GEVENT_ASSERT(FALSE);
		return FALSE;
	}

	gfxMutexEnter(&geventMutex);

	// Check if this pair is already in the table (scan for a free slot at the same time)
	pslfree = 0;
	for(psl = Assignments; psl < Assignments+GEVENT_MAX_SOURCE_LISTENERS; psl++) {
		
		if (pl == psl->pListener && gsh == psl->pSource) {
			// Just update the flags
			gfxSemWait(&pl->eventlock, TIME_INFINITE);		// Safety first - just in case a source is using it
			psl->listenflags = flags;
			gfxSemSignal(&pl->eventlock);			// Release this lock
			gfxMutexExit(&geventMutex);
			return TRUE;
		}
		if (!pslfree && !psl->pListener)
			pslfree = psl;
	}
	
	// A free slot was found - allocate it
	if (pslfree) {
		pslfree->pListener = pl;
		pslfree->pSource = gsh;
		pslfree->listenflags = flags;
		pslfree->srcflags = 0;
	}
	gfxMutexExit(&geventMutex);
	GEVENT_ASSERT(pslfree != 0);
	return pslfree != 0;
}
Example #18
0
GSourceListener *geventGetSourceListener(GSourceHandle gsh, GSourceListener *lastlr) {
	GSourceListener *psl;

	// Safety first
	if (!gsh)
		return 0;

	gfxMutexEnter(&geventMutex);

	// Unlock the last listener event buffer
	if (lastlr)
		gfxSemSignal(&lastlr->pListener->eventlock);
		
	// Loop through the table looking for attachments to this source
	for(psl = lastlr ? (lastlr+1) : Assignments; psl < Assignments+GEVENT_MAX_SOURCE_LISTENERS; psl++) {
		if (gsh == psl->pSource) {
			gfxSemWait(&psl->pListener->eventlock, TIME_INFINITE);		// Obtain a lock on the listener event buffer
			gfxMutexExit(&geventMutex);
			return psl;
		}
	}
	gfxMutexExit(&geventMutex);
	return 0;
}
Example #19
0
void _gwinFlushRedraws(GRedrawMethod how) {
	GHandle		gh;

	// Do we really need to do anything?
	if (!RedrawPending)
		return;

	// Obtain the drawing lock
	if (how == REDRAW_WAIT)
		gfxSemWait(&gwinsem, TIME_INFINITE);
	else if (how == REDRAW_NOWAIT && !gfxSemWait(&gwinsem, TIME_IMMEDIATE))
		// Someone is drawing - They will do the redraw when they are finished
		return;

	// Do loss of visibility first
	while ((RedrawPending & DOREDRAW_INVISIBLES)) {
		RedrawPending &= ~DOREDRAW_INVISIBLES;				// Catch new requests

		for(gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) {
			if ((gh->flags & (GWIN_FLG_NEEDREDRAW|GWIN_FLG_SYSVISIBLE)) != GWIN_FLG_NEEDREDRAW)
				continue;

			// Do the redraw
			#if GDISP_NEED_CLIP
				gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
				_GWINwm->vmt->Redraw(gh);
				gdispGUnsetClip(gh->display);
			#else
				_GWINwm->vmt->Redraw(gh);
			#endif

			// Postpone further redraws
			#if !GWIN_REDRAW_IMMEDIATE && !GWIN_REDRAW_SINGLEOP
				if (how == REDRAW_NOWAIT) {
					RedrawPending |= DOREDRAW_INVISIBLES;
					TriggerRedraw();
					goto releaselock;
				}
			#endif
		}
	}

	// Do the visible windows next
	while ((RedrawPending & DOREDRAW_VISIBLES)) {
		RedrawPending &= ~DOREDRAW_VISIBLES;				// Catch new requests

		for(gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) {
			if ((gh->flags & (GWIN_FLG_NEEDREDRAW|GWIN_FLG_SYSVISIBLE)) != (GWIN_FLG_NEEDREDRAW|GWIN_FLG_SYSVISIBLE))
				continue;

			// Do the redraw
			#if GDISP_NEED_CLIP
				gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
				_GWINwm->vmt->Redraw(gh);
				gdispGUnsetClip(gh->display);
			#else
				_GWINwm->vmt->Redraw(gh);
			#endif

			// Postpone further redraws (if there are any and the options are set right)
			#if !GWIN_REDRAW_IMMEDIATE && !GWIN_REDRAW_SINGLEOP
				if (how == REDRAW_NOWAIT) {
					while((gh = gwinGetNextWindow(gh))) {
						if ((gh->flags & (GWIN_FLG_NEEDREDRAW|GWIN_FLG_SYSVISIBLE)) == (GWIN_FLG_NEEDREDRAW|GWIN_FLG_SYSVISIBLE)) {
							RedrawPending |= DOREDRAW_VISIBLES;
							TriggerRedraw();
							break;
						}
					}
					goto releaselock;
				}
			#endif
		}
	}

	#if !GWIN_REDRAW_IMMEDIATE && !GWIN_REDRAW_SINGLEOP
		releaselock:
	#endif

	// Release the lock
	if (how == REDRAW_WAIT || how == REDRAW_NOWAIT)
		gfxSemSignal(&gwinsem);
}