Exemplo n.º 1
0
// The reading callback function
static void DialCallback(uint16_t instance, uint16_t rawvalue) {
	struct DialStatus_t *pds;
	GSourceListener		*psl;
	GEventDial			*pe;

	/* Get the information we need */
	pds = DialStatus+instance;

	/* Range scale - if needed */
	if (pds->max != GINPUT_DIAL_MAX_VALUE)
		rawvalue = (uint16_t)((uint32_t)rawvalue * pds->max / GINPUT_DIAL_MAX_VALUE);

	/* Forget about changes below our sensitivity threshold */
	if (rawvalue >= pds->lastvalue) {
		if (rawvalue - pds->lastvalue < pds->sensitivity) return;
	} else {
		if (pds->lastvalue - rawvalue < pds->sensitivity) return;
	}

	/* Save the value */
	pds->lastvalue = rawvalue;

	// Send the event to the listeners that are interested.
	psl = 0;
	while ((psl = geventGetSourceListener((GSourceHandle)(DialStatus+instance), psl))) {
		if (!(pe = (GEventDial *)geventGetEventBuffer(psl)))
			continue;
		pe->type = GEVENT_DIAL;
		pe->instance = instance;
		pe->value = pds->lastvalue;
		geventSendEvent(psl);
	}
}
Exemplo n.º 2
0
static void SendMouseEvent(GSourceListener	*psl, GMouse *m, GMouseReading *r) {
	GEventMouse		*pe;

	// If there is no event buffer just mark a missed event
	if (!(pe = (GEventMouse *)geventGetEventBuffer(psl))) {
		// This listener is missing - save the meta events that have happened
		psl->srcflags |= ((r->buttons & GMETA_MASK)|GINPUT_MISSED_MOUSE_EVENT);
		return;
	}

	// If we haven't really moved (and there are no meta events) don't bother sending the event
	if (!(r->buttons & GMETA_MASK) && !psl->srcflags && !(psl->listenflags & GLISTEN_MOUSENOFILTER)
			&& r->x == m->r.x && r->y == m->r.y && (r->buttons & GINPUT_MOUSE_BTN_MASK) == (m->r.buttons & GINPUT_MOUSE_BTN_MASK))
		return;

	// Send the event only if we are listening for it
	if (!((r->buttons & GINPUT_MOUSE_BTN_LEFT) && (psl->listenflags & GLISTEN_MOUSEDOWNMOVES))
			&& !(!(r->buttons & GINPUT_MOUSE_BTN_LEFT) && (psl->listenflags & GLISTEN_MOUSEUPMOVES))
			&& !((r->buttons & GMETA_MASK) && (psl->listenflags & GLISTEN_MOUSEMETA)))
		return;

	#if !GINPUT_TOUCH_NOTOUCH
		pe->type = (gmvmt(m)->d.flags & GMOUSE_VFLG_TOUCH) ? GEVENT_TOUCH : GEVENT_MOUSE;
	#else
		pe->type = GEVENT_MOUSE;
	#endif
	pe->x = r->x;
	pe->y = r->y;
	pe->z = r->z;
	pe->buttons = r->buttons | psl->srcflags;
	psl->srcflags = 0;
	pe->display = m->display;
	geventSendEvent(psl);
}
Exemplo n.º 3
0
void _gwinSendEvent(GHandle gh, GEventType type) {
	GSourceListener	*	psl;
	GEventGWin *		pge;

	// Trigger a GWIN Event
	psl = 0;
	while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) {
		if (!(pge = (GEventGWin *)geventGetEventBuffer(psl)))
			continue;
		pge->type = type;
		pge->gwin = gh;
		#if GWIN_WIDGET_TAGS
			pge->tag = (gh->flags & GWIN_FLG_WIDGET) ? ((GWidgetObject *)gh)->tag : 0;
		#endif
		geventSendEvent(psl);
	}
}
Exemplo n.º 4
0
// Send the button event
static void SendButtonEvent(GWidgetObject *gw) {
	GSourceListener	*	psl;
	GEvent *			pe;
	#define pbe			((GEventGWinButton *)pe)

	// Trigger a GWIN Button Event
	psl = 0;
	while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) {
		if (!(pe = geventGetEventBuffer(psl)))
			continue;
		pbe->type = GEVENT_GWIN_BUTTON;
		pbe->button = (GHandle)gw;
		geventSendEvent(psl);
	}

	#undef pbe
}
Exemplo n.º 5
0
// Send the checkbox event
static void SendCheckboxEvent(GWidgetObject *gw) {
	GSourceListener	*	psl;
	GEvent *			pe;
	#define pce			((GEventGWinCheckbox *)pe)

	// Trigger a GWIN Checkbox Event
	psl = 0;
	while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) {
		if (!(pe = geventGetEventBuffer(psl)))
			continue;
		pce->type = GEVENT_GWIN_CHECKBOX;
		pce->checkbox = &gw->g;
		pce->isChecked = (gw->g.flags & GCHECKBOX_FLG_CHECKED) ? TRUE : FALSE;
		geventSendEvent(psl);
	}

	#undef pce
}
Exemplo n.º 6
0
static void SendKeyboardEventToListener(GSourceListener	*psl, GKeyboard *k) {
    GEventKeyboard		*pe;
    int					i;

    // If there is no event buffer just mark a missed event
    if (!(pe = (GEventKeyboard *)geventGetEventBuffer(psl))) {
        // This listener is missing - save the meta events that have happened
        psl->srcflags |= GKEYSTATE_MISSED_EVENT;
        return;
    }

    if ((psl->listenflags & GLISTEN_KEYRAW)) {
        pe->type = GEVENT_KEYBOARD;
        pe->bytecount = k->cntsc;
        for(i = 0; i < k->cntsc; i++)	pe->c[i] = k->sc[i];
        for(; i < 8; i++)				pe->c[i] = 0;
        pe->keystate = k->keystate | psl->srcflags | GKEYSTATE_RAW;
        psl->srcflags = 0;
        return;
    }

    if ((psl->listenflags & GLISTEN_KEYREPEATSOFF) && (k->keystate & GKEYSTATE_REPEAT))
        return;

    if ((psl->listenflags & GLISTEN_KEYNOSPECIALS) && (k->keystate & GKEYSTATE_SPECIAL))
        return;

    if (!(psl->listenflags & GLISTEN_KEYUP) && (k->keystate & GKEYSTATE_KEYUP))
        k->cntc = 0;

    if (!(psl->listenflags & GLISTEN_KEYTRANSITIONS) && !k->cntc)
        return;

    pe->type = GEVENT_KEYBOARD;
    pe->bytecount = k->cntc;
    for(i = 0; i < k->cntc; i++)	pe->c[i] = k->c[i];
    for(; i < 8; i++)				pe->c[i] = 0;
    pe->keystate = k->keystate | psl->srcflags;
    psl->srcflags = 0;
    geventSendEvent(psl);
}
Exemplo n.º 7
0
// Send the button event
static void SendRadioEvent(GWidgetObject *gw) {
	GSourceListener	*	psl;
	GEvent *			pe;
	#define pbe			((GEventGWinRadio *)pe)

	// Trigger a GWIN Button Event
	psl = 0;
	while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) {
		if (!(pe = geventGetEventBuffer(psl)))
			continue;
		pbe->type = GEVENT_GWIN_RADIO;
		pbe->gwin = (GHandle)gw;
		pbe->group = ((GRadioObject *)gw)->group;
		#if GWIN_WIDGET_TAGS
			pbe->tag = gw->tag;
		#endif
		geventSendEvent(psl);
	}

	#undef pbe
}
Exemplo n.º 8
0
static void sendListEvent(GWidgetObject *gw, int item) {
	GSourceListener*	psl;
	GEvent*				pe;

	// Trigger a GWIN list event
	psl = 0;

	while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) {
		if (!(pe = geventGetEventBuffer(psl)))
			continue;

		ple->type = GEVENT_GWIN_LIST;
		ple->gwin = (GHandle)gw;
		ple->item = item;
		#if GWIN_WIDGET_TAGS
			ple->tag = gw->tag;
		#endif

		geventSendEvent(psl);
	}
}
Exemplo n.º 9
0
	static void HighSpeedGTimerCallback(void *param) {
		(void) param;
		GSourceListener	*psl;
		GEventADC		*pe;

		psl = 0;
		while ((psl = geventGetSourceListener((GSourceHandle)(&HighSpeedGTimer), psl))) {
			if (!(pe = (GEventADC *)geventGetEventBuffer(psl))) {
				// This listener is missing - save this.
				psl->srcflags |= GADC_HSADC_LOSTEVENT;
				continue;
			}

			pe->type = GEVENT_ADC;
			pe->count = hs.lastcount;
			pe->buffer = hs.lastbuffer;
			pe->flags = hs.lastflags | psl->srcflags;
			psl->srcflags = 0;
			geventSendEvent(psl);
		}
	}
Exemplo n.º 10
0
	static void AudGTimerCallback(void *param) {
		(void) param;
		GSourceListener	*psl;
		GEventADC		*pe;

		psl = 0;
		while ((psl = geventGetSourceListener((GSourceHandle)(&aud), psl))) {
			if (!(pe = (GEventAudioIn *)geventGetEventBuffer(psl))) {
				// This listener is missing - save this.
				psl->srcflags |= GADC_AUDIO_IN_LOSTEVENT;
				continue;
			}

			pe->type = GEVENT_AUDIO_IN;
			pe->channel = aud.channel;
			pe->count = lastcount;
			pe->buffer = lastbuffer;
			pe->flags = psl->srcflags;
			psl->srcflags = 0;
			geventSendEvent(psl);
		}
	}
Exemplo n.º 11
0
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);
		}
	}
}
Exemplo n.º 12
0
static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {
    (void)arg;

    GListener event_listener;
    geventListenerInit(&event_listener);
    geventAttachSource(&event_listener, (GSourceHandle)&current_status, 0);

    visualizer_keyboard_status_t initial_status = {
        .default_layer = 0xFFFFFFFF,
        .layer = 0xFFFFFFFF,
        .mods = 0xFF,
        .leds = 0xFFFFFFFF,
        .suspended = false,
    };

    visualizer_state_t state = {
        .status = initial_status,
        .current_lcd_color = 0,
#ifdef LCD_ENABLE
        .font_fixed5x8 = gdispOpenFont("fixed_5x8"),
        .font_dejavusansbold12 = gdispOpenFont("DejaVuSansBold12")
#endif
    };
    initialize_user_visualizer(&state);
    state.prev_lcd_color = state.current_lcd_color;

#ifdef LCD_BACKLIGHT_ENABLE
    lcd_backlight_color(
            LCD_HUE(state.current_lcd_color),
            LCD_SAT(state.current_lcd_color),
            LCD_INT(state.current_lcd_color));
#endif

    systemticks_t sleep_time = TIME_INFINITE;
    systemticks_t current_time = gfxSystemTicks();

    while(true) {
        systemticks_t new_time = gfxSystemTicks();
        systemticks_t delta = new_time - current_time;
        current_time = new_time;
        bool enabled = visualizer_enabled;
        if (!same_status(&state.status, &current_status)) {
            if (visualizer_enabled) {
                if (current_status.suspended) {
                    stop_all_keyframe_animations();
                    visualizer_enabled = false;
                    state.status = current_status;
                    user_visualizer_suspend(&state);
                }
                else {
                    state.status = current_status;
                    update_user_visualizer_state(&state);
                }
                state.prev_lcd_color = state.current_lcd_color;
            }
        }
        if (!enabled && state.status.suspended && current_status.suspended == false) {
            // Setting the status to the initial status will force an update
            // when the visualizer is enabled again
            state.status = initial_status;
            state.status.suspended = false;
            stop_all_keyframe_animations();
            user_visualizer_resume(&state);
            state.prev_lcd_color = state.current_lcd_color;
        }
        sleep_time = TIME_INFINITE;
        for (int i=0;i<MAX_SIMULTANEOUS_ANIMATIONS;i++) {
            if (animations[i]) {
                update_keyframe_animation(animations[i], &state, delta, &sleep_time);
            }
        }
#ifdef LED_ENABLE
        gdispGFlush(LED_DISPLAY);
#endif

#ifdef EMULATOR
        draw_emulator();
#endif
        // The animation can enable the visualizer
        // And we might need to update the state when that happens
        // so don't sleep
        if (enabled != visualizer_enabled) {
            sleep_time = 0;
        }

        systemticks_t after_update = gfxSystemTicks();
        unsigned update_delta = after_update - current_time;
        if (sleep_time != TIME_INFINITE) {
            if (sleep_time > update_delta) {
                sleep_time -= update_delta;
            }
            else {
                sleep_time = 0;
            }
        }
        dprintf("Update took %d, last delta %d, sleep_time %d\n", update_delta, delta, sleep_time);
#ifdef PROTOCOL_CHIBIOS
        // The gEventWait function really takes milliseconds, even if the documentation says ticks.
        // Unfortunately there's no generic ugfx conversion from system time to milliseconds,
        // so let's do it in a platform dependent way.

        // On windows the system ticks is the same as milliseconds anyway
        if (sleep_time != TIME_INFINITE) {
            sleep_time = ST2MS(sleep_time);
        }
#endif
        geventEventWait(&event_listener, sleep_time);
    }
#ifdef LCD_ENABLE
    gdispCloseFont(state.font_fixed5x8);
    gdispCloseFont(state.font_dejavusansbold12);
#endif

    return 0;
}

void visualizer_init(void) {
    gfxInit();

#ifdef LCD_BACKLIGHT_ENABLE
    lcd_backlight_init();
#endif

#ifdef SERIAL_LINK_ENABLE
    add_remote_objects(remote_objects, sizeof(remote_objects) / sizeof(remote_object_t*) );
#endif

#ifdef LCD_ENABLE
    LCD_DISPLAY = get_lcd_display();
#endif
#ifdef LED_ENABLE
    LED_DISPLAY = get_led_display();
#endif

    // We are using a low priority thread, the idea is to have it run only
    // when the main thread is sleeping during the matrix scanning
    gfxThreadCreate(visualizerThreadStack, sizeof(visualizerThreadStack),
                              VISUALIZER_THREAD_PRIORITY, visualizerThread, NULL);
}

void update_status(bool changed) {
    if (changed) {
        GSourceListener* listener = geventGetSourceListener((GSourceHandle)&current_status, NULL);
        if (listener) {
            geventSendEvent(listener);
        }
    }
#ifdef SERIAL_LINK_ENABLE
    static systime_t last_update = 0;
    systime_t current_update = chVTGetSystemTimeX();
    systime_t delta = current_update - last_update;
    if (changed || delta > MS2ST(10)) {
        last_update = current_update;
        visualizer_keyboard_status_t* r = begin_write_current_status();
        *r = current_status;
        end_write_current_status();
    }
#endif
}

uint8_t visualizer_get_mods() {
  uint8_t mods = get_mods();

#ifndef NO_ACTION_ONESHOT
  if (!has_oneshot_mods_timed_out()) {
    mods |= get_oneshot_mods();
  }
#endif  
  return mods;
}

void visualizer_update(uint32_t default_state, uint32_t state, uint8_t mods, uint32_t leds) {
    // Note that there's a small race condition here, the thread could read
    // a state where one of these are set but not the other. But this should
    // not really matter as it will be fixed during the next loop step.
    // Alternatively a mutex could be used instead of the volatile variables

    bool changed = false;
#ifdef SERIAL_LINK_ENABLE
    if (is_serial_link_connected ()) {
        visualizer_keyboard_status_t* new_status = read_current_status();
        if (new_status) {
            if (!same_status(&current_status, new_status)) {
                changed = true;
                current_status = *new_status;
            }
        }
    }
    else {
#else
   {
#endif
        visualizer_keyboard_status_t new_status = {
            .layer = state,
            .default_layer = default_state,
            .mods = mods,
            .leds = leds,
            .suspended = current_status.suspended,
        };
        if (!same_status(&current_status, &new_status)) {
            changed = true;
            current_status = new_status;
        }
    }
    update_status(changed);
}

void visualizer_suspend(void) {
    current_status.suspended = true;
    update_status(true);
}

void visualizer_resume(void) {
    current_status.suspended = false;
    update_status(true);
}
Exemplo n.º 13
0
	static void mouseDown(GWidgetObject *gw, coord_t mx, coord_t my) {
		GHandle		ph, gh;
		int			cnt;

		if (my < 0 || my > ((GTabsetObject *)gw)->border_top)
			return;

		// Work out which tab was pressed
		{
			coord_t		x, w, y;

			cnt = 0;
			x = w = 0;
			y = GWIN_TABSET_TABHEIGHT;
			gh = 0;
			for(ph = gwinGetFirstChild(&gw->g); ph; ph = gwinGetSibling(ph)) {
				if (ph->vmt == (gwinVMT *)&tabpageVMT) {
					w = gdispGetStringWidth(((GWidgetObject *)ph)->text, gw->g.font) + TEXT_PADDING*2;
					x += w;
					if (x > gw->g.width) {
						y += GWIN_TABSET_TABHEIGHT;
						x = w;
					}
					if (my < y && mx < x) {
						gh = ph;
						break;
					}
					cnt++;
				}
			}
			if (!gh || (gh->flags & GWIN_FLG_VISIBLE))
				return;
		}

		// Mark the existing tab as not visible
		for(ph = gwinGetFirstChild(&gw->g); ph; ph = gwinGetSibling(ph)) {
			if (ph->vmt == (gwinVMT *)&tabpageVMT && (ph->flags & GWIN_FLG_VISIBLE)) {
				// Mark this page invisible
				ph->flags &= ~GWIN_FLG_VISIBLE;
				break;
			}
		}

		// Mark this tab as visible
		gh->flags |= GWIN_FLG_VISIBLE;
		_gwinRippleVisibility();

		// Force a redraw of the whole tabset
		_gwinUpdate(&gw->g);

		// Send the Tabset Event
		{
			GSourceListener	*	psl;
			GEventGWinTabset *	pge;

			psl = 0;
			while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) {
				if (!(pge = (GEventGWinTabset *)geventGetEventBuffer(psl)))
					continue;
				pge->type = GEVENT_GWIN_TABSET;
				pge->gwin = &gw->g;
				#if GWIN_WIDGET_TAGS
					pge->tag = gw->tag;
				#endif
				pge->ghPage = gh;
				pge->nPage = cnt;
				geventSendEvent(psl);
			}
		}
	}