Index: src/squeezeplay_fab4/src/fab4_bsp.c =================================================================== --- src/squeezeplay_fab4/src/fab4_bsp.c (revision 4785) +++ src/squeezeplay_fab4/src/fab4_bsp.c Fri Mar 13 14:05:41 PDT 2009 @@ -7,6 +7,7 @@ #include "common.h" #include "ui/jive.h" +#include "syna_chiral_api.h" #include #include @@ -64,6 +65,9 @@ int flick_y = 0; int flick_x = 0; + int clearpad_x = -1; + int clearpad_y = -1; + rd = read(fd, ev, sizeof(struct input_event) * 64); if (rd < (int) sizeof(struct input_event)) { @@ -80,7 +84,7 @@ switch (ev[i].code) { case ABS_X: new_mouse_x = (Uint16) 480 - ((ev[i].value / (double)clearpad_max_x) * 480); - + clearpad_x = ev[i].value; //jitter correction - for stablizing drag when finger is stopped if (abs(new_mouse_x - clearpad_event.u.mouse.x) == 1) { //movement by only one pixel, confirm finger has deviated far enough to trigger a switch @@ -101,6 +105,7 @@ break; case ABS_Y: new_mouse_y = (Uint16) 272 - ((ev[i].value / (double)clearpad_max_y) * 272); + clearpad_y = ev[i].value; // fprintf(stderr, "clearpad_event.u.mouse.y %d maxY %d ev[i].value:%d y: %d fractional y: %f clearpad dev: %d required: %f \n", // clearpad_event.u.mouse.y, clearpad_max_y, ev[i].value, new_mouse_y, 272.0 - ((ev[i].value / (double)clearpad_max_y) * 272), // abs(ev[i].value - last_change_clearpad_y) , (.7 * clearpad_max_y/(double)272)); @@ -185,7 +190,7 @@ } - /* We must move more than 10 pixels to enter a + /* We must move more than 10 pixels to enter a * finger drag. */ if (clearpad_state == 1 && @@ -216,16 +221,57 @@ event.type = (JiveEventType) JIVE_EVENT_MOUSE_UP; clearpad_state = 0; + + fprintf(stderr, " ***** CHIRAL END\n"); + event.u.mouse.chiral_active = false; + event.u.mouse.chiral_value = 0; + syna_chiral_end(); } else if (clearpad_state == 0) { event.type = (JiveEventType) JIVE_EVENT_MOUSE_DOWN; clearpad_state = 1; + + /* + * Start the Chiral module. + */ + if(syna_chiral_start() == 0) { + syna_chiral_set_direction(eDirectionHorizontal); + syna_chiral_set_gain(50000); + syna_chiral_set_min_radius(40); + syna_chiral_set_noise_parameter(1); + syna_chiral_set_release_change(8); + fprintf(stderr, " ***** CHIRAL START\n"); + + + } else { + fprintf(stderr, " ***** CHIRAL START FAILED\n"); + - } + } + } else if (clearpad_state == 1) { event.type = (JiveEventType) JIVE_EVENT_MOUSE_DRAG; clearpad_state = 3; } + if (clearpad_state == 3) { + if (clearpad_x >= 0 && clearpad_y >=0) { + int chiral_value, chirality; + chiral_value = syna_chiral_process_abs(clearpad_x, clearpad_y); + chirality = syna_chiral_get_chirality(); + if (chiral_value * chirality < 0) { + //when chirality and chiral val are opposite signs, invert the chiral value so CW is always the same direction + chiral_value = chiral_value * -1; + } + + //Invert chiral value polarity so CW motion is always positive + event.u.mouse.chiral_value = -1 * chiral_value; + if (chiral_value != 0) { + event.u.mouse.chiral_active = true; + } +// fprintf(stderr, "CHIRAL CURRENT1: %d for clearpad_x: %d clearpad_y: %d in_origin:%d out_origin:%d direction:%d chirality:%d \n", chiral_value , clearpad_x, clearpad_y, syna_chiral_get_input_origin(), syna_chiral_get_output_origin(), syna_chiral_get_direction(), syna_chiral_get_chirality()); + } + } + memcpy(&clearpad_event, &event, sizeof(JiveEvent)); jive_queue_event(&event); } @@ -489,3 +535,34 @@ return 1; } + + +/* + We are not using this , but it must be here for compilation +*/ +void syna_print(char const *msg) +{ + /* + * Add platform specifc message print function below + * to print diagnostic information. + * + * !!!!!!!! The Maximum possible msg string length is 120 chars !!!!!!!! + * !!!!!!!! The Maximum possible msg string length is 120 chars !!!!!!!! + * !!!!!!!! The Maximum possible msg string length is 120 chars !!!!!!!! + */ + + /* + * Example print function usage. + * + * ***** Replace this with similar functions on application platforms ***** + * ***** Replace this with similar functions on application platforms ***** + * ***** Replace this with similar functions on application platforms ***** + */ + + + +//#if 0 +// fprintf(stderr, "syna_print: %s", msg); +//#endif + +} Index: src/squeezeplay/src/ui/jive.h =================================================================== --- src/squeezeplay/src/ui/jive.h (revision 4785) +++ src/squeezeplay/src/ui/jive.h Tue Feb 24 09:38:42 PST 2009 @@ -223,6 +223,8 @@ Uint16 finger_count; Uint16 finger_pressure; Uint16 finger_width; + Sint16 chiral_value; + bool chiral_active; }; struct jive_motion_event { Index: src/squeezeplay_fab4/src/syna_chiral_api.h =================================================================== --- src/squeezeplay_fab4/src/syna_chiral_api.h Mon Mar 09 18:35:16 PDT 2009 +++ src/squeezeplay_fab4/src/syna_chiral_api.h Mon Mar 09 18:35:16 PDT 2009 @@ -0,0 +1,296 @@ +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Copyright © 2008 Synaptics Incorporated. All rights reserved. +// +// The information in this file is confidential under the terms +// of a non-disclosure agreement with Synaptics and is provided +// AS IS. +// +// The information in this file shall remain the exclusive property +// of Synaptics and may be the subject of Synaptics’ patents, in +// whole or part. Synaptics’ intellectual property rights in the +// information in this file are not expressly or implicitly licensed +// or otherwise transferred to you as a result of such information +// being made available to you. +// +// $RCSfile: syna_chiral_api.h,v $ +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Revision datestamp 12/01/2008 +// + +/**************************************************************************** + * + * syna_chiral_api.h + * + * This header file is part of the release of Synaptics Chiral Application Development Kit (ADK) + * for Synaptics Chiral C Library (SCCLib). + * + * + * + * ================ PART OF THE ADK RELEASE ================= + * ================ PART OF THE ADK RELEASE ================= + * ================ PART OF THE ADK RELEASE ================= + * + * + * This is the implementation of the Application Progamming Interface (API) + * layer of Synaptics Chiral C Library (SCCLib). + * + * The SCCLib is written in C only. + * + * It provides a single instance of the chiral module. + * + * It can take either relative or absolute x/y position + * and produces a chiral value of signed integral for application use. + * + * The exposure of the APIs implemented in this file is via the header file + * syna_chiral_api.h. + * + * Teh following files are needed for an application to compile using the SCCLib APIs: + * + * syna_chiral_api.h, + * syna_diagnostic_api.c. + * + * The operation of the chiral module is steightfoward. The following is + * a typical sequence of API calling: + * + * + * 1. Call syna_chiral_start() to start the module. + * 2. Call parameter initialzation APIs to setup the chiral module. + * 3. Get x/y data. + * 4. Call syna_chiral_process_abs(x, y) or syna_chiral_process_rel(x, y) to get a chiral value. + * 5. Aplly the chiral value to produce any effect (e.g. scroll). + * 6. Go to step 3 repeatedly for a continuous effect. + * 7. Call syna_chiral_end() to clean up and stop the module after use. + * + * Example code with typical applicaiton and parameter setup will be provided + * as part of this Application Development Kit (ADK). + * + * + ****************************************************************************/ + + +#ifndef _syna_chiral_api_h +#define _syna_chiral_api_h + +#ifndef _syna_chiral_typedef +#define _syna_chiral_typedef + +typedef enum EChirality +{ + eChiralRacemic = 0, + eChiralCCW = -1, + eChiralCW = 1 +} +EChirality; + +typedef enum +{ + eDirectionUnset = 0, + eDirectionVertical, + eDirectionHorizontal +} +EScrollDirection; + +typedef enum +{ + eTopLeft = 0, + eTopRight = 1, + eBottomLeft = 2, + eBottomRight = 3 +} +EOrigin; + +#endif /* _syna_chiral_typedef */ + + +#ifdef _WIN32 + #define EXPORT __declspec(dllexport) +#else + #define EXPORT extern +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +/*------------------------------------------------------------------* + * + * Chiral Module Level APIs. + * + *------------------------------------------------------------------*/ + +/* + * Must be called first before using any other chiral APIs. + * + * It will create all the resources needed for the operation + * of the chiral module. + * + * return 0 if suceeded, negative numbers if failed. + * + * It will free any resources already allocated if failed. + */ +EXPORT +int syna_chiral_start(void); + +/* + * Must be called the last after any chiral APIs + * and must be called to free any resources alllocated + * by the syna_chiral_start() function. + * + * No chiral APIs except for syna_chiral_start() and + * syna_info_chiral_version() shall be used + * after calling syna_chiral_end(). + * Undetermined consequences will happen otherwise. + */ +EXPORT +void syna_chiral_end(void); + +/*------------------------------------------------------------------* + * + * Chiral Processing APIs. + * + *------------------------------------------------------------------*/ + +/* + * This is the only and main fxn for accually processing + * the RELATIVE x/y postion information and produce + * the chiral effect. + * + * It should be called repeatedly to process each update + * of the relative x/y position to produce the chiral effect. + * + * It produces and returns a chiral value of signed integeral + * that can be used by applications. + */ +EXPORT +int syna_chiral_process_rel(int dx, int dy); + +/* + * This is the only and main fxn for accually processing + * the ABSOLUTE x/y postion information and produce + * the chiral effect. + * + * It should be called repeatedly to process each update + * of the absolute x/y position to produce the chiral effect. + * + * It produces and returns a chiral value of signed integeral + * that can be used by applications. + */ +EXPORT +int syna_chiral_process_abs(int x, int y); + +EXPORT +void syna_chiral_reset(void); + + +/*------------------------------------------------------------------* + * + * Chiral Parameter Initialization and Setup APIs. + * + *------------------------------------------------------------------*/ + +EXPORT +void syna_chiral_set_direction(EScrollDirection eScrollDirection); + +EXPORT +void syna_chiral_set_start_distance(int iDistance); + +EXPORT +void syna_chiral_set_gain(int iGain); + +EXPORT +void syna_chiral_set_min_radius(int iMinRadius); + +EXPORT +void syna_chiral_set_noise_parameter(int iNoise); + +EXPORT +void syna_chiral_set_system_origin(EOrigin eSystemOrigin); + +EXPORT +void syna_chiral_set_input_origin(EOrigin eInputOrigin); + +EXPORT +void syna_chiral_set_output_origin(EOrigin eOutputOrigin); + +EXPORT +void syna_chiral_set_release_change(int iChange); + +/*------------------------------------------------------------------* + * + * Chiral Parameter Setup and State Information Inquiry APIs. + * + *------------------------------------------------------------------*/ + +EXPORT +EChirality syna_chiral_get_chirality(void); + +EXPORT +EScrollDirection syna_chiral_get_direction(void); + +EXPORT +int syna_chiral_get_start_distance(void); + +EXPORT +int syna_chiral_get_gain(void); + +EXPORT +int syna_chiral_get_min_radius(void); + +EXPORT +int syna_chiral_get_noise_parameter(void); + +EXPORT +EOrigin syna_chiral_get_input_origin(void); + +EXPORT +EOrigin syna_chiral_get_output_origin(void); + +EXPORT +int syna_chiral_get_release_change(void); + +/*------------------------------------------------------------------* + * + * SCCLib Information Inquiry APIs. + * + *------------------------------------------------------------------*/ + +EXPORT +char *syna_chiral_version(void); + + +/* + * Synaptics diagnostic functions. + * + * The diagnostic function syna_print(char const *msg) can be called to sent + * information about the chiral library and its operation. + * + * Users can provide their platform specific print function(s) inside the + * syna_print(char const *msg) to display the library sent information + * on their platform display device. + * + * Leave it empty if users don't want to display the information from the library. + * + * A minimum of Synaptics Chiral C Library version information will be + * sent. More information may be sent if necessary. + * + * When provided with the platform specific print function(s) the display of + * the library version string is also an indication of the successful start up + * of the chiral library and its readyness for operation. + * + * The example of print function for Synaptic platforms is placed here for + * reference purpose only. Users should replace their print function(s) + * to display the information from the chiral library. + */ + +void syna_print(char const *msg); + +#ifdef __cplusplus +} +#endif + +#endif /* _syna_chiral_api_h */ + +/* + * End of file. + */ Index: src/squeezeplay/share/jive/ui/Menu.lua =================================================================== --- src/squeezeplay/share/jive/ui/Menu.lua (revision 4785) +++ src/squeezeplay/share/jive/ui/Menu.lua Fri Mar 13 14:18:57 PDT 2009 @@ -78,7 +78,7 @@ local EVENT_CONSUME = jive.ui.EVENT_CONSUME local EVENT_UNUSED = jive.ui.EVENT_UNUSED - + local KEY_FWD = jive.ui.KEY_FWD local KEY_REW = jive.ui.KEY_REW local KEY_GO = jive.ui.KEY_GO @@ -91,6 +91,8 @@ local KEY_PAGE_UP = jive.ui.KEY_PAGE_UP local KEY_PAGE_DOWN = jive.ui.KEY_PAGE_DOWN +local CLEARPAD_PER_PIXEL_Y = 4248/272 +local CHIRAL_GAIN = .4 -- our class module(...) @@ -174,7 +176,7 @@ end -function handleDrag(self, dragAmountY, byItemOnly) +function handleDrag(self, dragAmountY, byItemOnly, forceAccel) if dragAmountY ~= 0 then -- log:error("handleDrag dragAmountY: ", dragAmountY ) @@ -204,7 +206,7 @@ log:debug("self:scrollBy( itemShift ) ", itemShift, " self.pixelOffsetY: ", self.pixelOffsetY ) self:_updateScrollbar() - self:scrollBy( itemShift, true, false ) + self:scrollBy( itemShift, true, false, forceAccel ) if self.selected == 1 or self.selected == self.listSize then self:resetDragData() @@ -411,6 +413,11 @@ --Note: on a down outside the scrollbar boundary, we don't want to forward this to the scrollbar --Normally that should never happen, but will if an up event is nevet sent to this widget, which would have cleared the -- sliderDragInProgress flag + if self:mouseInside(event) and not self.scrollbar:mouseInside(event) and self.chiralGestureInProgress then + --for chiral, let body area take over focus again + self.sliderDragInProgress = false + end + if self.scrollbar:mouseInside(event) or (self.sliderDragInProgress and evtype ~= EVENT_MOUSE_DOWN ) then if (evtype ~= EVENT_MOUSE_MOVE) then --allows slider drag to continue even when listitem area is entered @@ -489,7 +496,7 @@ self.dragOrigin.x, self.dragOrigin.y = event:getMouse(); end - local mouseX, mouseY = event:getMouse() + local mouseX, mouseY, fingerCount, fingerWidth, fingerPressure, chiralValue = event:getMouse() local dragAmountY = self.dragOrigin.y - mouseY @@ -498,15 +505,21 @@ self.flick:updateFlickData(event) + if chiralValue then + self.chiralGestureInProgress = true + dragAmountY = chiralValue/(CLEARPAD_PER_PIXEL_Y) * CHIRAL_GAIN + self:handleDrag(dragAmountY, false, true) + else - self:handleDrag(dragAmountY) + self:handleDrag(dragAmountY) + end - + -- log:error("self.pixelOffsetY : ", self.pixelOffsetY) end end return EVENT_CONSUME end - + elseif evtype == EVENT_MOUSE_UP then --todo: UP not called if we are outside widget bounds, need this widget to handle events when drag in progress @@ -514,7 +527,7 @@ local flickSpeed, flickDirection = self.flick:getFlickSpeed(self.itemHeight) - if flickSpeed then + if flickSpeed and not self.chiralGestureInProgress then self.flick:flick(flickSpeed, flickDirection) end @@ -523,6 +536,8 @@ self.sliderDragInProgress = false self.bodyDragInProgress = false + self.chiralGestureInProgress = false + --turn off accel keys (may have been on from a scrollbar slide) if (self.accel or self.accelKey) then self.accel = false @@ -575,10 +590,10 @@ local obj = oo.rawnew(self, Widget(style)) obj.irAccel = IRMenuAccel() - + obj.scroll = ScrollAccel(function(...) if itemAvailable then - + else return true end @@ -633,11 +648,11 @@ obj:reLayout() end, true) - + obj.accelKeyTimer = Timer(500, function() obj.accelKey = nil - obj:reLayout() + obj:reLayout() end, true) @@ -645,7 +660,7 @@ function (event) return (_eventHandler(obj, event)) end) - + return obj end @@ -711,7 +726,7 @@ function getVisibleIndicies(self) local min = self.topItem local max = min + self.numWidgets - 1 - + if max > self.listSize then return min, min + self.listSize else @@ -784,7 +799,7 @@ =head2 jive.ui.Menu:setSelectedIndex(index) -Sets I as the selected menu item. +Sets I as the selected menu item. =cut --]] @@ -926,20 +941,20 @@ selected = self.listSize elseif selected < 1 then selected = _coerce(1, self.listSize) - end + end elseif isNewOperation == true then if selected > self.listSize then selected = _coerce(1, self.listSize) elseif selected < 1 then selected = self.listSize - end - + end + else -- isNewOperation nil, so use breakthrough barrier -- virtual barrier when scrolling off the ends of the list if self.barrier and Framework:getTicks() > self.barrier + 1000 then self.barrier = nil end - + if selected > self.listSize then selected = self.listSize if self.barrier == nil then @@ -948,7 +963,7 @@ selected = _coerce(1, self.listSize) self.barrier = nil end - + elseif selected < 1 then selected = _coerce(1, self.listSize) if self.barrier == nil then @@ -957,7 +972,7 @@ selected = self.listSize self.barrier = nil end - + else self.barrier = nil end @@ -993,7 +1008,7 @@ -- show the first item if the first item is selected if selected == 1 then topItem = 1 - + -- otherwise, try to leave one item above the selected one (we've scrolled out of the view) elseif selected <= topItem then -- if we land here, selected > 1 so topItem cannot become < 1 @@ -1006,7 +1021,7 @@ else topItem = self.listSize - self.numWidgets + 1 end - + -- otherwise, try to leave one item below the selected one (we've scrolled out of the view) elseif selected >= topItem + self.numWidgets - 1 then topItem = selected - self.numWidgets + 2 Index: src/squeezeplay_fab4/Makefile.am =================================================================== --- src/squeezeplay_fab4/Makefile.am (revision 4785) +++ src/squeezeplay_fab4/Makefile.am Fri Mar 13 14:59:04 PDT 2009 @@ -17,6 +17,8 @@ fab4_bsp_la_SOURCES = \ src/fab4_bsp.c +fab4_bsp_la_LIBADD = src/libsyna_chiral_lt_gcc.a + JIVE_BUILD_DIR = $(DESTDIR)$(datadir)/jive include Makefile.am.jive-install.include Index: src/squeezeplay/src/ui/jive_event.c =================================================================== --- src/squeezeplay/src/ui/jive_event.c (revision 4785) +++ src/squeezeplay/src/ui/jive_event.c Fri Mar 13 14:59:04 PDT 2009 @@ -192,7 +192,13 @@ lua_pushinteger(L, event->u.mouse.finger_count); lua_pushinteger(L, event->u.mouse.finger_width); lua_pushinteger(L, event->u.mouse.finger_pressure); - return 5; + if (event->u.mouse.chiral_active) { + lua_pushinteger(L, event->u.mouse.chiral_value); + } + else { + lua_pushnil(L); + } + return 6; default: luaL_error(L, "Not a mouse event"); @@ -328,7 +334,7 @@ case JIVE_EVENT_MOUSE_DOWN: if (event->u.mouse.finger_count) { - lua_pushfstring(L, "FINGER_DOWN x=%d,y=%d,n=%d,w=%d,p=%d", event->u.mouse.x, event->u.mouse.y, event->u.mouse.finger_count, event->u.mouse.finger_width, event->u.mouse.finger_pressure); + lua_pushfstring(L, "FINGER_DOWN x=%d,y=%d,n=%d,w=%d,p=%d,c=%d", event->u.mouse.x, event->u.mouse.y, event->u.mouse.finger_count, event->u.mouse.finger_width, event->u.mouse.finger_pressure, event->u.mouse.chiral_value); } else { lua_pushfstring(L, "MOUSE_DOWN x=%d,y=%d", event->u.mouse.x, event->u.mouse.y); @@ -336,7 +342,7 @@ break; case JIVE_EVENT_MOUSE_UP: if (event->u.mouse.finger_count) { - lua_pushfstring(L, "FINGER_UP x=%d,y=%d,n=%d,w=%d,p=%d", event->u.mouse.x, event->u.mouse.y, event->u.mouse.finger_count, event->u.mouse.finger_width, event->u.mouse.finger_pressure); + lua_pushfstring(L, "FINGER_UP x=%d,y=%d,n=%d,w=%d,p=%d,c=%d", event->u.mouse.x, event->u.mouse.y, event->u.mouse.finger_count, event->u.mouse.finger_width, event->u.mouse.finger_pressure, event->u.mouse.chiral_value); } else { lua_pushfstring(L, "MOUSE_UP x=%d,y=%d", event->u.mouse.x, event->u.mouse.y); @@ -344,7 +350,7 @@ break; case JIVE_EVENT_MOUSE_PRESS: if (event->u.mouse.finger_count) { - lua_pushfstring(L, "FINGER_PRESS x=%d,y=%d,n=%d,w=%d,p=%d", event->u.mouse.x, event->u.mouse.y, event->u.mouse.finger_count, event->u.mouse.finger_width, event->u.mouse.finger_pressure); + lua_pushfstring(L, "FINGER_PRESS x=%d,y=%d,n=%d,w=%d,p=%d,c=%d", event->u.mouse.x, event->u.mouse.y, event->u.mouse.finger_count, event->u.mouse.finger_width, event->u.mouse.finger_pressure, event->u.mouse.chiral_value); } else { lua_pushfstring(L, "MOUSE_PRESS x=%d,y=%d", event->u.mouse.x, event->u.mouse.y); @@ -352,7 +358,7 @@ break; case JIVE_EVENT_MOUSE_HOLD: if (event->u.mouse.finger_count) { - lua_pushfstring(L, "FINGER_HOLD x=%d,y=%d,n=%d,w=%d,p=%d", event->u.mouse.x, event->u.mouse.y, event->u.mouse.finger_count, event->u.mouse.finger_width, event->u.mouse.finger_pressure); + lua_pushfstring(L, "FINGER_HOLD x=%d,y=%d,n=%d,w=%d,p=%d,c=%d", event->u.mouse.x, event->u.mouse.y, event->u.mouse.finger_count, event->u.mouse.finger_width, event->u.mouse.finger_pressure, event->u.mouse.chiral_value); } else { lua_pushfstring(L, "MOUSE_HOLD x=%d,y=%d", event->u.mouse.x, event->u.mouse.y); @@ -360,7 +366,7 @@ break; case JIVE_EVENT_MOUSE_MOVE: if (event->u.mouse.finger_count) { - lua_pushfstring(L, "FINGER_MOVE x=%d,y=%d,n=%d,w=%d,p=%d", event->u.mouse.x, event->u.mouse.y, event->u.mouse.finger_count, event->u.mouse.finger_width, event->u.mouse.finger_pressure); + lua_pushfstring(L, "FINGER_MOVE x=%d,y=%d,n=%d,w=%d,p=%d,c=%d", event->u.mouse.x, event->u.mouse.y, event->u.mouse.finger_count, event->u.mouse.finger_width, event->u.mouse.finger_pressure, event->u.mouse.chiral_value); } else { lua_pushfstring(L, "MOUSE_MOVE x=%d,y=%d", event->u.mouse.x, event->u.mouse.y); @@ -368,7 +374,7 @@ break; case JIVE_EVENT_MOUSE_DRAG: if (event->u.mouse.finger_count) { - lua_pushfstring(L, "FINGER_DRAG x=%d,y=%d,n=%d,w=%d,p=%d", event->u.mouse.x, event->u.mouse.y, event->u.mouse.finger_count, event->u.mouse.finger_width, event->u.mouse.finger_pressure); + lua_pushfstring(L, "FINGER_DRAG x=%d,y=%d,n=%d,w=%d,p=%d,c=%d", event->u.mouse.x, event->u.mouse.y, event->u.mouse.finger_count, event->u.mouse.finger_width, event->u.mouse.finger_pressure, event->u.mouse.chiral_value); } else { lua_pushfstring(L, "MOUSE_DRAG x=%d,y=%d", event->u.mouse.x, event->u.mouse.y);