| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043 |
- /*
- * Copyright © 2013 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
- #include <config.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <libinput.h>
- #include <math.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <valgrind/valgrind.h>
- #include "libinput-util.h"
- #include "litest.h"
- enum cardinal { N, NE, E, SE, S, SW, W, NW };
- static void
- test_relative_event(struct litest_device *dev, double dx, double dy)
- {
- struct libinput *li = dev->libinput;
- struct libinput_event_pointer *ptrev;
- struct libinput_event *event;
- double ev_dx, ev_dy;
- double expected_dir;
- double expected_length;
- double actual_dir;
- double actual_length;
- const char *prop;
- int dpi = 1000;
- litest_event(dev, EV_REL, REL_X, dx);
- litest_event(dev, EV_REL, REL_Y, dy);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- event = libinput_get_event(li);
- ptrev = litest_is_motion_event(event);
- /* low-dpi devices scale up, not down, especially for slow motion.
- * so a 1 unit movement in a 200dpi mouse still sends a 1 pixel
- * movement. Work aorund this here by checking for the MOUSE_DPI
- * property.
- */
- _unref_(udev_device) *ud =
- libinput_device_get_udev_device(dev->libinput_device);
- litest_assert_ptr_notnull(ud);
- prop = udev_device_get_property_value(ud, "MOUSE_DPI");
- if (prop) {
- dpi = parse_mouse_dpi_property(prop);
- litest_assert_int_ne(dpi, 0);
- dx *= 1000.0 / dpi;
- dy *= 1000.0 / dpi;
- }
- expected_length = sqrt(4 * dx * dx + 4 * dy * dy);
- expected_dir = atan2(dx, dy);
- ev_dx = libinput_event_pointer_get_dx(ptrev);
- ev_dy = libinput_event_pointer_get_dy(ptrev);
- actual_length = sqrt(ev_dx * ev_dx + ev_dy * ev_dy);
- actual_dir = atan2(ev_dx, ev_dy);
- /* Check the length of the motion vector (tolerate 1.0 indifference). */
- litest_assert_double_ge(fabs(expected_length), actual_length);
- /* Check the direction of the motion vector (tolerate 2π/4 radians
- * indifference). */
- litest_assert_double_lt(fabs(expected_dir - actual_dir), M_PI_2);
- libinput_event_destroy(event);
- litest_drain_events(dev->libinput);
- }
- static void
- disable_button_scrolling(struct litest_device *device)
- {
- struct libinput_device *dev = device->libinput_device;
- enum libinput_config_status status, expected;
- status = libinput_device_config_scroll_set_method(
- dev,
- LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
- expected = LIBINPUT_CONFIG_STATUS_SUCCESS;
- litest_assert_int_eq(status, expected);
- }
- START_TEST(pointer_motion_relative)
- {
- struct litest_device *dev = litest_current_device();
- /* send a single event, the first movement
- is always decelerated by 0.3 */
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(dev->libinput);
- litest_drain_events(dev->libinput);
- test_relative_event(dev, 1, 0);
- test_relative_event(dev, 1, 1);
- test_relative_event(dev, 1, -1);
- test_relative_event(dev, 0, 1);
- test_relative_event(dev, -1, 0);
- test_relative_event(dev, -1, 1);
- test_relative_event(dev, -1, -1);
- test_relative_event(dev, 0, -1);
- }
- END_TEST
- START_TEST(pointer_motion_relative_zero)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- int i;
- /* NOTE: this test does virtually nothing. The kernel should not
- * allow 0/0 events to be passed to userspace. If it ever happens,
- * let's hope this test fails if we do the wrong thing.
- */
- litest_drain_events(li);
- for (i = 0; i < 5; i++) {
- litest_event(dev, EV_REL, REL_X, 0);
- litest_event(dev, EV_REL, REL_Y, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- }
- litest_assert_empty_queue(li);
- /* send a single event, the first movement
- is always decelerated by 0.3 */
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- libinput_event_destroy(libinput_get_event(li));
- litest_assert_empty_queue(li);
- for (i = 0; i < 5; i++) {
- litest_event(dev, EV_REL, REL_X, 0);
- litest_event(dev, EV_REL, REL_Y, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(dev->libinput);
- }
- litest_assert_empty_queue(li);
- }
- END_TEST
- START_TEST(pointer_motion_relative_min_decel)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- struct libinput_event_pointer *ptrev;
- struct libinput_event *event;
- double evx, evy;
- int dx, dy;
- double len;
- enum cardinal direction =
- litest_test_param_get_i32(test_env->params, "direction");
- switch (direction) {
- case N:
- dx = 0;
- dy = 1;
- break;
- case NE:
- dx = 1;
- dy = 1;
- break;
- case E:
- dx = 1;
- dy = 0;
- break;
- case SE:
- dx = 1;
- dy = -1;
- break;
- case S:
- dx = 0;
- dy = -1;
- break;
- case SW:
- dx = -1;
- dy = -1;
- break;
- case W:
- dx = -1;
- dy = 0;
- break;
- case NW:
- dx = -1;
- dy = 1;
- break;
- default:
- litest_abort_msg("Invalid direction %d", direction);
- }
- litest_drain_events(dev->libinput);
- litest_event(dev, EV_REL, REL_X, dx);
- litest_event(dev, EV_REL, REL_Y, dy);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- event = libinput_get_event(li);
- ptrev = litest_is_motion_event(event);
- evx = libinput_event_pointer_get_dx(ptrev);
- evy = libinput_event_pointer_get_dy(ptrev);
- litest_assert((evx == 0.0) == (dx == 0));
- litest_assert((evy == 0.0) == (dy == 0));
- len = hypot(evx, evy);
- litest_assert_double_ge(fabs(len), 0.3);
- libinput_event_destroy(event);
- }
- END_TEST
- static void
- test_absolute_event(struct litest_device *dev, double x, double y)
- {
- struct libinput *li = dev->libinput;
- struct libinput_event *event;
- struct libinput_event_pointer *ptrev;
- double ex, ey;
- enum libinput_event_type type = LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE;
- litest_touch_down(dev, 0, x, y);
- litest_dispatch(li);
- event = libinput_get_event(li);
- litest_assert_notnull(event);
- litest_assert_int_eq(libinput_event_get_type(event), type);
- ptrev = libinput_event_get_pointer_event(event);
- litest_assert_ptr_notnull(ptrev);
- ex = libinput_event_pointer_get_absolute_x_transformed(ptrev, 100);
- ey = libinput_event_pointer_get_absolute_y_transformed(ptrev, 100);
- litest_assert_int_eq((int)(ex + 0.5), (int)x);
- litest_assert_int_eq((int)(ey + 0.5), (int)y);
- libinput_event_destroy(event);
- }
- START_TEST(pointer_motion_absolute)
- {
- struct litest_device *dev = litest_current_device();
- litest_drain_events(dev->libinput);
- test_absolute_event(dev, 0, 100);
- test_absolute_event(dev, 100, 0);
- test_absolute_event(dev, 50, 50);
- }
- END_TEST
- START_TEST(pointer_absolute_initial_state)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *libinput1;
- struct libinput_event *ev1, *ev2;
- struct libinput_event_pointer *p1, *p2;
- int axis = litest_test_param_get_i32(test_env->params, "axis");
- libinput1 = dev->libinput;
- litest_touch_down(dev, 0, 40, 60);
- litest_touch_up(dev, 0);
- /* device is now on some x/y value */
- litest_drain_events(libinput1);
- _litest_context_destroy_ struct libinput *libinput2 = litest_create_context();
- libinput_path_add_device(libinput2, libevdev_uinput_get_devnode(dev->uinput));
- litest_drain_events(libinput2);
- if (axis == ABS_X)
- litest_touch_down(dev, 0, 40, 70);
- else
- litest_touch_down(dev, 0, 70, 60);
- litest_touch_up(dev, 0);
- litest_wait_for_event(libinput1);
- litest_wait_for_event(libinput2);
- while (libinput_next_event_type(libinput1)) {
- ev1 = libinput_get_event(libinput1);
- ev2 = libinput_get_event(libinput2);
- litest_assert_enum_eq(libinput_event_get_type(ev1),
- LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE);
- litest_assert_enum_eq(libinput_event_get_type(ev1),
- libinput_event_get_type(ev2));
- p1 = libinput_event_get_pointer_event(ev1);
- p2 = libinput_event_get_pointer_event(ev2);
- litest_assert_double_eq(libinput_event_pointer_get_absolute_x(p1),
- libinput_event_pointer_get_absolute_x(p2));
- litest_assert_double_eq(libinput_event_pointer_get_absolute_y(p1),
- libinput_event_pointer_get_absolute_y(p2));
- libinput_event_destroy(ev1);
- libinput_event_destroy(ev2);
- }
- }
- END_TEST
- static void
- test_unaccel_event(struct litest_device *dev, int dx, int dy)
- {
- struct libinput *li = dev->libinput;
- struct libinput_event *event;
- struct libinput_event_pointer *ptrev;
- double ev_dx, ev_dy;
- litest_event(dev, EV_REL, REL_X, dx);
- litest_event(dev, EV_REL, REL_Y, dy);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- event = libinput_get_event(li);
- ptrev = litest_is_motion_event(event);
- ev_dx = libinput_event_pointer_get_dx_unaccelerated(ptrev);
- ev_dy = libinput_event_pointer_get_dy_unaccelerated(ptrev);
- litest_assert_int_eq(dx, ev_dx);
- litest_assert_int_eq(dy, ev_dy);
- libinput_event_destroy(event);
- litest_drain_events(dev->libinput);
- }
- START_TEST(pointer_motion_unaccel)
- {
- struct litest_device *dev = litest_current_device();
- litest_drain_events(dev->libinput);
- test_unaccel_event(dev, 10, 0);
- test_unaccel_event(dev, 10, 10);
- test_unaccel_event(dev, 10, -10);
- test_unaccel_event(dev, 0, 10);
- test_unaccel_event(dev, -10, 0);
- test_unaccel_event(dev, -10, 10);
- test_unaccel_event(dev, -10, -10);
- test_unaccel_event(dev, 0, -10);
- }
- END_TEST
- static void
- test_button_event(struct litest_device *dev, unsigned int button, int state)
- {
- struct libinput *li = dev->libinput;
- litest_button_click_debounced(dev, li, button, state);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_assert_button_event(li,
- button,
- state ? LIBINPUT_BUTTON_STATE_PRESSED
- : LIBINPUT_BUTTON_STATE_RELEASED);
- }
- START_TEST(pointer_button)
- {
- struct litest_device *dev = litest_current_device();
- disable_button_scrolling(dev);
- litest_drain_events(dev->libinput);
- test_button_event(dev, BTN_LEFT, 1);
- test_button_event(dev, BTN_LEFT, 0);
- /* press it twice for good measure */
- test_button_event(dev, BTN_LEFT, 1);
- test_button_event(dev, BTN_LEFT, 0);
- if (libinput_device_pointer_has_button(dev->libinput_device, BTN_RIGHT)) {
- test_button_event(dev, BTN_RIGHT, 1);
- test_button_event(dev, BTN_RIGHT, 0);
- }
- /* Skip middle button test on trackpoints (used for scrolling) */
- if (libinput_device_pointer_has_button(dev->libinput_device, BTN_MIDDLE)) {
- test_button_event(dev, BTN_MIDDLE, 1);
- test_button_event(dev, BTN_MIDDLE, 0);
- }
- }
- END_TEST
- START_TEST(pointer_button_auto_release)
- {
- struct litest_device *dev;
- struct libinput_event *event;
- enum libinput_event_type type;
- struct libinput_event_pointer *pevent;
- struct {
- int code;
- int released;
- } buttons[] = {
- {
- .code = BTN_LEFT,
- },
- {
- .code = BTN_MIDDLE,
- },
- {
- .code = BTN_EXTRA,
- },
- {
- .code = BTN_SIDE,
- },
- {
- .code = BTN_BACK,
- },
- {
- .code = BTN_FORWARD,
- },
- {
- .code = BTN_4,
- },
- };
- int events[2 * (ARRAY_LENGTH(buttons) + 1)];
- unsigned i;
- int button;
- int valid_code;
- /* Enable all tested buttons on the device */
- for (i = 0; i < 2 * ARRAY_LENGTH(buttons);) {
- button = buttons[i / 2].code;
- events[i++] = EV_KEY;
- events[i++] = button;
- }
- events[i++] = -1;
- events[i++] = -1;
- _litest_context_destroy_ struct libinput *libinput = litest_create_context();
- dev = litest_add_device_with_overrides(libinput,
- LITEST_MOUSE,
- "Generic mouse",
- NULL,
- NULL,
- events);
- litest_drain_events(libinput);
- /* Send pressed events, without releasing */
- for (i = 0; i < ARRAY_LENGTH(buttons); ++i) {
- test_button_event(dev, buttons[i].code, 1);
- }
- litest_drain_events(libinput);
- /* "Disconnect" device */
- litest_device_destroy(dev);
- /* Mark all released buttons until device is removed */
- while (1) {
- event = libinput_get_event(libinput);
- litest_assert_notnull(event);
- type = libinput_event_get_type(event);
- if (type == LIBINPUT_EVENT_DEVICE_REMOVED) {
- libinput_event_destroy(event);
- break;
- }
- litest_assert_event_type(event, LIBINPUT_EVENT_POINTER_BUTTON);
- pevent = libinput_event_get_pointer_event(event);
- litest_assert_enum_eq(libinput_event_pointer_get_button_state(pevent),
- LIBINPUT_BUTTON_STATE_RELEASED);
- button = libinput_event_pointer_get_button(pevent);
- valid_code = 0;
- for (i = 0; i < ARRAY_LENGTH(buttons); ++i) {
- if (buttons[i].code == button) {
- litest_assert_int_eq(buttons[i].released, 0);
- buttons[i].released = 1;
- valid_code = 1;
- }
- }
- litest_assert_int_eq(valid_code, 1);
- libinput_event_destroy(event);
- }
- /* Check that all pressed buttons has been released. */
- for (i = 0; i < ARRAY_LENGTH(buttons); ++i) {
- litest_assert_int_eq(buttons[i].released, 1);
- }
- }
- END_TEST
- START_TEST(pointer_button_has_no_button)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- unsigned int code;
- litest_assert(
- !libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER));
- for (code = BTN_LEFT; code < KEY_OK; code++)
- litest_assert_int_eq(-1,
- libinput_device_pointer_has_button(device, code));
- }
- END_TEST
- START_TEST(pointer_recover_from_lost_button_count)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- struct libevdev *evdev = dev->evdev;
- disable_button_scrolling(dev);
- litest_drain_events(dev->libinput);
- litest_button_click_debounced(dev, li, BTN_LEFT, 1);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- /* Grab for the release to make libinput lose count */
- libevdev_grab(evdev, LIBEVDEV_GRAB);
- litest_button_click_debounced(dev, li, BTN_LEFT, 0);
- libevdev_grab(evdev, LIBEVDEV_UNGRAB);
- litest_assert_empty_queue(li);
- litest_button_click_debounced(dev, li, BTN_LEFT, 1);
- litest_assert_empty_queue(li);
- litest_button_click_debounced(dev, li, BTN_LEFT, 0);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- END_TEST
- static inline double
- wheel_click_count(struct litest_device *dev, int which)
- {
- const char *prop = NULL;
- int count;
- double angle = 0.0;
- _unref_(udev_device) *d = libinput_device_get_udev_device(dev->libinput_device);
- litest_assert_ptr_notnull(d);
- if (which == REL_HWHEEL)
- prop = udev_device_get_property_value(
- d,
- "MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL");
- if (!prop)
- prop = udev_device_get_property_value(d, "MOUSE_WHEEL_CLICK_COUNT");
- if (prop) {
- count = parse_mouse_wheel_click_count_property(prop);
- litest_assert_int_ne(count, 0);
- angle = 360.0 / count;
- }
- return angle;
- }
- static inline double
- wheel_click_angle(struct litest_device *dev, int which)
- {
- const char *prop = NULL;
- const int default_angle = 15;
- double angle;
- angle = wheel_click_count(dev, which);
- if (angle != 0.0)
- return angle;
- angle = default_angle;
- _unref_(udev_device) *d = libinput_device_get_udev_device(dev->libinput_device);
- litest_assert_ptr_notnull(d);
- if (which == REL_HWHEEL)
- prop = udev_device_get_property_value(
- d,
- "MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL");
- if (!prop)
- prop = udev_device_get_property_value(d, "MOUSE_WHEEL_CLICK_ANGLE");
- if (prop) {
- angle = parse_mouse_wheel_click_angle_property(prop);
- if (angle == 0.0)
- angle = default_angle;
- }
- return angle;
- }
- static void
- test_high_and_low_wheel_events_value(struct litest_device *dev,
- int which,
- int v120_amount)
- {
- struct libinput *li = dev->libinput;
- struct libinput_event *event;
- struct libinput_event_pointer *ptrev;
- enum libinput_pointer_axis axis;
- enum libinput_pointer_axis_source source;
- double scroll_step, expected, discrete, v120;
- scroll_step = wheel_click_angle(dev, which);
- source = LIBINPUT_POINTER_AXIS_SOURCE_WHEEL;
- expected = scroll_step * (v120_amount / 120);
- discrete = v120_amount / 120;
- v120 = v120_amount;
- if (libinput_device_config_scroll_get_natural_scroll_enabled(
- dev->libinput_device)) {
- expected *= -1;
- discrete *= -1;
- v120 *= -1;
- }
- double angle = libinput_device_config_rotation_get_angle(dev->libinput_device);
- if (angle >= 160.0 && angle <= 220.0) {
- expected *= -1;
- discrete *= -1;
- v120 *= -1;
- }
- axis = (which == REL_WHEEL || which == REL_WHEEL_HI_RES)
- ? LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL
- : LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
- event = libinput_get_event(li);
- litest_assert_notnull(event);
- bool have_lores = false, have_hires = false;
- while (event) {
- ptrev = litest_is_axis_event(event,
- LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
- axis,
- source);
- if (litest_is_high_res_axis_event(event)) {
- have_hires = true;
- litest_assert_double_eq(
- libinput_event_pointer_get_scroll_value_v120(ptrev,
- axis),
- v120);
- } else {
- have_lores = true;
- litest_assert_double_eq(
- libinput_event_pointer_get_axis_value(ptrev, axis),
- expected);
- litest_assert_double_eq(
- libinput_event_pointer_get_axis_value_discrete(ptrev,
- axis),
- discrete);
- }
- libinput_event_destroy(event);
- event = libinput_get_event(li);
- }
- if (have_lores)
- litest_assert_msg(have_hires, "Missing high-res wheels events");
- }
- static void
- test_wheel_event(struct litest_device *dev, int which, int amount)
- {
- struct libinput *li = dev->libinput;
- int event_amount = amount;
- switch (which) {
- case REL_WHEEL:
- case REL_HWHEEL:
- break;
- default:
- litest_assert_msg("Invalid axis for %s", __func__);
- break;
- }
- /* mouse scroll wheels are 'upside down' */
- if (which == REL_WHEEL)
- event_amount *= -1;
- litest_event(dev, EV_REL, which, event_amount);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- test_high_and_low_wheel_events_value(dev, which, amount * 120);
- }
- START_TEST(pointer_scroll_wheel)
- {
- struct litest_device *dev = litest_current_device();
- litest_drain_events(dev->libinput);
- /* make sure we hit at least one of the below two conditions */
- litest_assert(libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL) ||
- libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL));
- if (libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL)) {
- test_wheel_event(dev, REL_WHEEL, -1);
- test_wheel_event(dev, REL_WHEEL, 1);
- test_wheel_event(dev, REL_WHEEL, -5);
- test_wheel_event(dev, REL_WHEEL, 6);
- }
- if (libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL)) {
- test_wheel_event(dev, REL_HWHEEL, -1);
- test_wheel_event(dev, REL_HWHEEL, 1);
- test_wheel_event(dev, REL_HWHEEL, -5);
- test_wheel_event(dev, REL_HWHEEL, 6);
- }
- }
- END_TEST
- static void
- test_hi_res_wheel_event(struct litest_device *dev, int which, int v120_amount)
- {
- struct libinput *li = dev->libinput;
- switch (which) {
- case REL_WHEEL_HI_RES:
- /* mouse scroll wheels are 'upside down' */
- litest_event(dev, EV_REL, REL_WHEEL_HI_RES, -1 * v120_amount);
- litest_event(dev, EV_REL, REL_WHEEL, -1 * v120_amount / 120);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- break;
- case REL_HWHEEL_HI_RES:
- litest_event(dev, EV_REL, REL_HWHEEL_HI_RES, v120_amount);
- litest_event(dev, EV_REL, REL_HWHEEL, v120_amount / 120);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- break;
- default:
- abort();
- }
- litest_dispatch(li);
- test_high_and_low_wheel_events_value(dev, which, v120_amount);
- }
- START_TEST(pointer_scroll_wheel_hires)
- {
- struct litest_device *dev = litest_current_device();
- unsigned int axis = litest_test_param_get_i32(test_env->params, "axis");
- if (!libevdev_has_event_code(dev->evdev, EV_REL, axis))
- return LITEST_NOT_APPLICABLE;
- litest_drain_events(dev->libinput);
- test_hi_res_wheel_event(dev, axis, -120);
- test_hi_res_wheel_event(dev, axis, 120);
- test_hi_res_wheel_event(dev, axis, -5 * 120);
- test_hi_res_wheel_event(dev, axis, 6 * 120);
- if (dev->which == LITEST_MOUSE_WHEEL_HIRES_DISABLED)
- return LITEST_NOT_APPLICABLE;
- test_hi_res_wheel_event(dev, axis, 30);
- test_hi_res_wheel_event(dev, axis, -60);
- test_hi_res_wheel_event(dev, axis, -40);
- test_hi_res_wheel_event(dev, axis, 180);
- }
- END_TEST
- START_TEST(pointer_scroll_wheel_hires_send_only_lores)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- unsigned int lores_code, hires_code;
- int direction;
- enum libinput_pointer_axis axis =
- litest_test_param_get_i32(test_env->params, "axis");
- switch (axis) {
- case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
- lores_code = REL_WHEEL;
- hires_code = REL_WHEEL_HI_RES;
- direction = -1;
- break;
- case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
- lores_code = REL_HWHEEL;
- hires_code = REL_HWHEEL_HI_RES;
- direction = 1;
- break;
- default:
- litest_abort_msg("Invalid test axis '%d'", axis);
- }
- if (dev->which == LITEST_MOUSE_WHEEL_HIRES_DISABLED)
- return LITEST_NOT_APPLICABLE;
- if (!libevdev_has_event_code(dev->evdev, EV_REL, lores_code) ||
- !libevdev_has_event_code(dev->evdev, EV_REL, hires_code))
- return LITEST_NOT_APPLICABLE;
- /* Device claims to have HI_RES, but doesn't send events for it. Make
- * sure we handle this correctly.
- */
- litest_drain_events(dev->libinput);
- litest_with_logcapture(li, capture) {
- litest_event(dev, EV_REL, lores_code, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- test_high_and_low_wheel_events_value(dev, lores_code, direction * 120);
- litest_event(dev, EV_REL, lores_code, -1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- test_high_and_low_wheel_events_value(dev, lores_code, direction * -120);
- litest_event(dev, EV_REL, lores_code, 2);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- test_high_and_low_wheel_events_value(dev, lores_code, direction * 240);
- litest_assert_empty_queue(li);
- litest_assert_strv_substring(
- capture->bugs,
- "only low-resolution events have been received.");
- }
- }
- END_TEST
- START_TEST(pointer_scroll_wheel_hires_disabled)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- int direction;
- unsigned int lores_code, hires_code;
- enum libinput_pointer_axis axis =
- litest_test_param_get_i32(test_env->params, "axis");
- switch (axis) {
- case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
- lores_code = REL_WHEEL;
- hires_code = REL_WHEEL_HI_RES;
- direction = -1;
- break;
- case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
- lores_code = REL_HWHEEL;
- hires_code = REL_HWHEEL_HI_RES;
- direction = 1;
- break;
- default:
- litest_abort_msg("Invalid test axis '%d'", axis);
- }
- litest_drain_events(li);
- litest_log_group("High-res events on this device should be ignored") {
- for (size_t i = 0; i < 4; i++) {
- litest_event(dev, EV_REL, hires_code, 60);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_assert_empty_queue(li);
- }
- litest_log_group("Only low-res events should be handled") {
- for (size_t i = 0; i < 4; i++) {
- litest_event(dev, EV_REL, hires_code, 60);
- litest_event(dev, EV_REL, lores_code, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_drain_events_of_type(li, LIBINPUT_EVENT_POINTER_AXIS);
- _destroy_(libinput_event) *ev = libinput_get_event(li);
- struct libinput_event_pointer *pev = litest_is_axis_event(
- ev,
- LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
- axis,
- 0);
- int v120 =
- libinput_event_pointer_get_scroll_value_v120(pev, axis);
- litest_assert_int_eq(v120, direction * 120);
- }
- litest_drain_events_of_type(li, LIBINPUT_EVENT_POINTER_AXIS);
- litest_assert_empty_queue(li);
- }
- }
- END_TEST
- START_TEST(pointer_scroll_wheel_inhibit_small_deltas)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- uint32_t delta = litest_test_param_get_u32(test_env->params, "hires-delta");
- if (!libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL_HI_RES) ||
- !libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL_HI_RES))
- return LITEST_NOT_APPLICABLE;
- if (dev->which == LITEST_MOUSE_WHEEL_HIRES_DISABLED)
- return LITEST_NOT_APPLICABLE;
- litest_drain_events(dev->libinput);
- /* A single delta (below the hardcoded threshold 60) is ignored */
- litest_event(dev, EV_REL, REL_WHEEL_HI_RES, delta);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_assert_empty_queue(li);
- /* Once we get two events in the same direction trigger scroll */
- litest_event(dev, EV_REL, REL_WHEEL_HI_RES, delta);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- test_high_and_low_wheel_events_value(dev, REL_WHEEL_HI_RES, -2 * delta);
- /* Once the threshold is reached, every scroll deltas are reported */
- litest_event(dev, EV_REL, REL_WHEEL_HI_RES, delta);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- test_high_and_low_wheel_events_value(dev, REL_WHEEL_HI_RES, -delta);
- /* When the scroll timeout is triggered, ignore small deltas again */
- litest_timeout_wheel_scroll(li);
- litest_event(dev, EV_REL, REL_WHEEL_HI_RES, -delta);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_assert_empty_queue(li);
- litest_event(dev, EV_REL, REL_HWHEEL_HI_RES, delta);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_assert_empty_queue(li);
- }
- END_TEST
- START_TEST(pointer_scroll_wheel_inhibit_small_deltas_reduce_delta)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- if (!libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL_HI_RES) ||
- !libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL_HI_RES))
- return LITEST_NOT_APPLICABLE;
- if (dev->which == LITEST_MOUSE_WHEEL_HIRES_DISABLED)
- return LITEST_NOT_APPLICABLE;
- litest_drain_events(dev->libinput);
- /* A single delta (below the hardcoded threshold 30) is ignored */
- litest_event(dev, EV_REL, REL_WHEEL_HI_RES, 29);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_assert_empty_queue(li);
- /* A second smaller delta changes the internal threshold */
- litest_event(dev, EV_REL, REL_WHEEL_HI_RES, 5);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- test_high_and_low_wheel_events_value(dev, REL_WHEEL_HI_RES, -34);
- litest_timeout_wheel_scroll(li);
- /* Internal threshold is now 5 so two deltas of 5 trigger */
- litest_log_group("Internal threshold is now 5 so two deltas of 5 trigger") {
- litest_event(dev, EV_REL, REL_WHEEL_HI_RES, 5);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_assert_empty_queue(li);
- litest_event(dev, EV_REL, REL_WHEEL_HI_RES, 5);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- test_high_and_low_wheel_events_value(dev, REL_WHEEL_HI_RES, -10);
- }
- litest_timeout_wheel_scroll(li);
- litest_log_group("Internal threshold is now 5 so one delta of 10 trigger") {
- litest_event(dev, EV_REL, REL_WHEEL_HI_RES, 10);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- test_high_and_low_wheel_events_value(dev, REL_WHEEL_HI_RES, -10);
- }
- }
- END_TEST
- START_TEST(pointer_scroll_wheel_inhibit_dir_change)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- uint32_t delta = litest_test_param_get_u32(test_env->params, "hires-delta");
- if (!libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL_HI_RES))
- return LITEST_NOT_APPLICABLE;
- if (dev->which == LITEST_MOUSE_WHEEL_HIRES_DISABLED)
- return LITEST_NOT_APPLICABLE;
- litest_drain_events(dev->libinput);
- /* Scroll one detent and a bit */
- litest_event(dev, EV_REL, REL_WHEEL_HI_RES, 120 + delta);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- test_high_and_low_wheel_events_value(dev, REL_WHEEL_HI_RES, -120 - delta);
- /* Scroll below the threshold in the oposite direction should be ignored */
- litest_event(dev, EV_REL, REL_WHEEL_HI_RES, -delta);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_assert_empty_queue(li);
- /* But should be triggered if the scroll continues in the same direction */
- litest_event(dev, EV_REL, REL_WHEEL_HI_RES, -2 * delta);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- test_high_and_low_wheel_events_value(dev, REL_WHEEL_HI_RES, 3 * delta);
- /* Scroll above the threshold in the same dir should be triggered */
- litest_event(dev, EV_REL, REL_WHEEL_HI_RES, 2 * delta);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- test_high_and_low_wheel_events_value(dev, REL_WHEEL_HI_RES, -2 * delta);
- }
- END_TEST
- START_TEST(pointer_scroll_wheel_no_inhibit_small_deltas_when_virtual)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- litest_drain_events(li);
- /* Scroll deltas below the threshold (60) must *not* be ignored */
- litest_event(dev, EV_REL, REL_WHEEL_HI_RES, 15);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- test_high_and_low_wheel_events_value(dev, REL_WHEEL_HI_RES, -15);
- }
- END_TEST
- START_TEST(pointer_scroll_wheel_lenovo_scrollpoint)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- struct libinput_event *event;
- struct libinput_event_pointer *ptrev;
- double v;
- litest_drain_events(dev->libinput);
- /* Lenovo ScrollPoint has a trackstick instead of a wheel, data sent
- * via REL_WHEEL is close to x/y coordinate space.
- */
- litest_event(dev, EV_REL, REL_WHEEL, 30);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_REL, REL_WHEEL, -60);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- /* Hi-res scroll event first */
- event = libinput_get_event(li);
- litest_assert(litest_is_high_res_axis_event(event));
- ptrev = litest_is_axis_event(event,
- LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
- v = libinput_event_pointer_get_scroll_value(
- ptrev,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
- litest_assert_double_eq(v, -30.0);
- libinput_event_destroy(event);
- /* legacy lo-res scroll event */
- event = libinput_get_event(li);
- litest_assert(!litest_is_high_res_axis_event(event));
- ptrev = litest_is_axis_event(event,
- LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
- v = libinput_event_pointer_get_axis_value(
- ptrev,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
- litest_assert_double_eq(v, -30.0);
- libinput_event_destroy(event);
- /* Hi-res scroll event first */
- event = libinput_get_event(li);
- ptrev = litest_is_axis_event(event,
- LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
- v = libinput_event_pointer_get_scroll_value(
- ptrev,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
- litest_assert_double_eq(v, 60.0);
- libinput_event_destroy(event);
- /* legacy lo-res scroll event */
- event = libinput_get_event(li);
- litest_assert(!litest_is_high_res_axis_event(event));
- ptrev = litest_is_axis_event(event,
- LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
- v = libinput_event_pointer_get_axis_value(
- ptrev,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
- litest_assert_double_eq(v, 60.0);
- libinput_event_destroy(event);
- }
- END_TEST
- START_TEST(pointer_scroll_natural_defaults)
- {
- struct litest_device *dev = litest_current_device();
- litest_assert_int_ge(
- libinput_device_config_scroll_has_natural_scroll(dev->libinput_device),
- 1);
- litest_assert_int_eq(libinput_device_config_scroll_get_natural_scroll_enabled(
- dev->libinput_device),
- 0);
- litest_assert_int_eq(
- libinput_device_config_scroll_get_default_natural_scroll_enabled(
- dev->libinput_device),
- 0);
- }
- END_TEST
- START_TEST(pointer_scroll_natural_defaults_noscroll)
- {
- struct litest_device *dev = litest_current_device();
- if (libinput_device_config_scroll_has_natural_scroll(dev->libinput_device))
- return LITEST_NOT_APPLICABLE;
- litest_assert_int_eq(libinput_device_config_scroll_get_natural_scroll_enabled(
- dev->libinput_device),
- 0);
- litest_assert_int_eq(
- libinput_device_config_scroll_get_default_natural_scroll_enabled(
- dev->libinput_device),
- 0);
- }
- END_TEST
- START_TEST(pointer_scroll_natural_enable_config)
- {
- struct litest_device *dev = litest_current_device();
- enum libinput_config_status status;
- status = libinput_device_config_scroll_set_natural_scroll_enabled(
- dev->libinput_device,
- 1);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- litest_assert_int_eq(libinput_device_config_scroll_get_natural_scroll_enabled(
- dev->libinput_device),
- 1);
- status = libinput_device_config_scroll_set_natural_scroll_enabled(
- dev->libinput_device,
- 0);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- litest_assert_int_eq(libinput_device_config_scroll_get_natural_scroll_enabled(
- dev->libinput_device),
- 0);
- }
- END_TEST
- START_TEST(pointer_scroll_natural_wheel)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- litest_drain_events(dev->libinput);
- libinput_device_config_scroll_set_natural_scroll_enabled(device, 1);
- /* make sure we hit at least one of the below two conditions */
- litest_assert(libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL) ||
- libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL));
- if (libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL)) {
- test_wheel_event(dev, REL_WHEEL, -1);
- test_wheel_event(dev, REL_WHEEL, 1);
- test_wheel_event(dev, REL_WHEEL, -5);
- test_wheel_event(dev, REL_WHEEL, 6);
- }
- if (libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL)) {
- test_wheel_event(dev, REL_HWHEEL, -1);
- test_wheel_event(dev, REL_HWHEEL, 1);
- test_wheel_event(dev, REL_HWHEEL, -5);
- test_wheel_event(dev, REL_HWHEEL, 6);
- }
- }
- END_TEST
- START_TEST(pointer_scroll_has_axis_invalid)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- struct libinput_event *event;
- struct libinput_event_pointer *pev;
- litest_drain_events(dev->libinput);
- if (!libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL))
- return LITEST_NOT_APPLICABLE;
- litest_event(dev, EV_REL, REL_WHEEL, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- event = libinput_get_event(li);
- pev = litest_is_axis_event(event,
- LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- 0);
- litest_assert_int_eq(libinput_event_pointer_has_axis(pev, -1), 0);
- litest_assert_int_eq(libinput_event_pointer_has_axis(pev, 2), 0);
- litest_assert_int_eq(libinput_event_pointer_has_axis(pev, 3), 0);
- litest_assert_int_eq(libinput_event_pointer_has_axis(pev, 0xffff), 0);
- libinput_event_destroy(event);
- }
- END_TEST
- START_TEST(pointer_scroll_with_rotation)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- struct libinput_device *device = dev->libinput_device;
- double angle = litest_test_param_get_double(test_env->params, "angle");
- litest_drain_events(li);
- libinput_device_config_rotation_set_angle(device, angle);
- /* make sure we hit at least one of the below two conditions */
- litest_assert(libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL) ||
- libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL));
- if (libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL)) {
- test_wheel_event(dev, REL_WHEEL, -1);
- test_wheel_event(dev, REL_WHEEL, 1);
- test_wheel_event(dev, REL_WHEEL, -5);
- test_wheel_event(dev, REL_WHEEL, 6);
- }
- if (libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL)) {
- test_wheel_event(dev, REL_HWHEEL, -1);
- test_wheel_event(dev, REL_HWHEEL, 1);
- test_wheel_event(dev, REL_HWHEEL, -5);
- test_wheel_event(dev, REL_HWHEEL, 6);
- }
- }
- END_TEST
- START_TEST(pointer_seat_button_count)
- {
- struct litest_device *devices[4];
- const int num_devices = ARRAY_LENGTH(devices);
- struct libinput_event *ev;
- struct libinput_event_pointer *tev;
- int i;
- int seat_button_count = 0;
- int expected_seat_button_count = 0;
- char device_name[255];
- _litest_context_destroy_ struct libinput *libinput = litest_create_context();
- for (i = 0; i < num_devices; ++i) {
- sprintf(device_name, "litest Generic mouse (%d)", i);
- devices[i] = litest_add_device_with_overrides(libinput,
- LITEST_MOUSE,
- device_name,
- NULL,
- NULL,
- NULL);
- }
- for (i = 0; i < num_devices; ++i)
- litest_button_click_debounced(devices[i], libinput, BTN_LEFT, true);
- litest_dispatch(libinput);
- while ((ev = libinput_get_event(libinput))) {
- if (libinput_event_get_type(ev) != LIBINPUT_EVENT_POINTER_BUTTON) {
- libinput_event_destroy(ev);
- litest_dispatch(libinput);
- continue;
- }
- tev = libinput_event_get_pointer_event(ev);
- litest_assert_notnull(tev);
- litest_assert_int_eq(libinput_event_pointer_get_button(tev),
- (unsigned int)BTN_LEFT);
- litest_assert_enum_eq(libinput_event_pointer_get_button_state(tev),
- LIBINPUT_BUTTON_STATE_PRESSED);
- ++expected_seat_button_count;
- seat_button_count = libinput_event_pointer_get_seat_button_count(tev);
- litest_assert_int_eq(expected_seat_button_count, seat_button_count);
- libinput_event_destroy(ev);
- litest_dispatch(libinput);
- }
- litest_assert_int_eq(seat_button_count, num_devices);
- for (i = 0; i < num_devices; ++i)
- litest_button_click_debounced(devices[i], libinput, BTN_LEFT, false);
- litest_dispatch(libinput);
- while ((ev = libinput_get_event(libinput))) {
- if (libinput_event_get_type(ev) != LIBINPUT_EVENT_POINTER_BUTTON) {
- libinput_event_destroy(ev);
- litest_dispatch(libinput);
- continue;
- }
- tev = libinput_event_get_pointer_event(ev);
- litest_assert_notnull(tev);
- litest_assert_int_eq(libinput_event_pointer_get_button(tev),
- (unsigned int)BTN_LEFT);
- litest_assert_enum_eq(libinput_event_pointer_get_button_state(tev),
- LIBINPUT_BUTTON_STATE_RELEASED);
- --expected_seat_button_count;
- seat_button_count = libinput_event_pointer_get_seat_button_count(tev);
- litest_assert_int_eq(expected_seat_button_count, seat_button_count);
- libinput_event_destroy(ev);
- litest_dispatch(libinput);
- }
- litest_assert_int_eq(seat_button_count, 0);
- for (i = 0; i < num_devices; ++i)
- litest_device_destroy(devices[i]);
- }
- END_TEST
- START_TEST(pointer_no_calibration)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *d = dev->libinput_device;
- enum libinput_config_status status;
- int rc;
- float calibration[6] = { 0 };
- rc = libinput_device_config_calibration_has_matrix(d);
- litest_assert_int_eq(rc, 0);
- rc = libinput_device_config_calibration_get_matrix(d, calibration);
- litest_assert_int_eq(rc, 0);
- rc = libinput_device_config_calibration_get_default_matrix(d, calibration);
- litest_assert_int_eq(rc, 0);
- status = libinput_device_config_calibration_set_matrix(d, calibration);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
- }
- END_TEST
- START_TEST(pointer_left_handed_defaults)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *d = dev->libinput_device;
- int rc;
- if (libevdev_get_id_vendor(dev->evdev) == VENDOR_ID_APPLE &&
- libevdev_get_id_product(dev->evdev) == PRODUCT_ID_APPLE_APPLETOUCH)
- return LITEST_NOT_APPLICABLE;
- rc = libinput_device_config_left_handed_is_available(d);
- litest_assert_int_ne(rc, 0);
- rc = libinput_device_config_left_handed_get(d);
- litest_assert_int_eq(rc, 0);
- rc = libinput_device_config_left_handed_get_default(d);
- litest_assert_int_eq(rc, 0);
- }
- END_TEST
- START_TEST(pointer_left_handed)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *d = dev->libinput_device;
- struct libinput *li = dev->libinput;
- enum libinput_config_status status;
- status = libinput_device_config_left_handed_set(d, 1);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- litest_drain_events(li);
- litest_button_click_debounced(dev, li, BTN_LEFT, 1);
- litest_button_click_debounced(dev, li, BTN_LEFT, 0);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_button_click_debounced(dev, li, BTN_RIGHT, 1);
- litest_button_click_debounced(dev, li, BTN_RIGHT, 0);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- if (libinput_device_pointer_has_button(d, BTN_MIDDLE)) {
- litest_button_click_debounced(dev, li, BTN_MIDDLE, 1);
- litest_button_click_debounced(dev, li, BTN_MIDDLE, 0);
- litest_assert_button_event(li,
- BTN_MIDDLE,
- LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li,
- BTN_MIDDLE,
- LIBINPUT_BUTTON_STATE_RELEASED);
- }
- }
- END_TEST
- START_TEST(pointer_left_handed_during_click)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *d = dev->libinput_device;
- struct libinput *li = dev->libinput;
- enum libinput_config_status status;
- litest_drain_events(li);
- litest_button_click_debounced(dev, li, BTN_LEFT, 1);
- litest_dispatch(li);
- /* Change while button is down, expect correct release event */
- status = libinput_device_config_left_handed_set(d, 1);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- litest_button_click_debounced(dev, li, BTN_LEFT, 0);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- }
- END_TEST
- START_TEST(pointer_left_handed_during_click_multiple_buttons)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *d = dev->libinput_device;
- struct libinput *li = dev->libinput;
- enum libinput_config_status status;
- if (!libinput_device_pointer_has_button(d, BTN_MIDDLE))
- return LITEST_NOT_APPLICABLE;
- litest_disable_middleemu(dev);
- litest_drain_events(li);
- litest_button_click_debounced(dev, li, BTN_LEFT, 1);
- litest_dispatch(li);
- status = libinput_device_config_left_handed_set(d, 1);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- /* No left-handed until all buttons were down */
- litest_button_click_debounced(dev, li, BTN_RIGHT, 1);
- litest_button_click_debounced(dev, li, BTN_RIGHT, 0);
- litest_button_click_debounced(dev, li, BTN_LEFT, 0);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- }
- END_TEST
- START_TEST(pointer_left_handed_disable_with_button_down)
- {
- _litest_context_destroy_ struct libinput *li = litest_create_context();
- struct litest_device *dev = litest_add_device(li, LITEST_MOUSE);
- enum libinput_config_status status;
- status = libinput_device_config_left_handed_set(dev->libinput_device, 1);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- litest_drain_events(li);
- litest_button_click_debounced(dev, li, BTN_LEFT, 1);
- litest_dispatch(li);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_device_destroy(dev);
- litest_dispatch(li);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
- struct libinput_event *event = libinput_get_event(li);
- litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_REMOVED);
- litest_assert_empty_queue(li);
- libinput_event_destroy(event);
- }
- END_TEST
- START_TEST(pointer_scroll_button)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- /* Make left button switch to scrolling mode */
- libinput_device_config_scroll_set_method(dev->libinput_device,
- LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
- libinput_device_config_scroll_set_button(dev->libinput_device, BTN_LEFT);
- litest_drain_events(li);
- litest_button_scroll(dev, BTN_LEFT, 1, 6);
- litest_assert_scroll(li,
- LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- 6);
- litest_button_scroll(dev, BTN_LEFT, 1, -7);
- litest_assert_scroll(li,
- LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- -7);
- litest_button_scroll(dev, BTN_LEFT, 8, 1);
- litest_assert_scroll(li,
- LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
- LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
- 8);
- litest_button_scroll(dev, BTN_LEFT, -9, 1);
- litest_assert_scroll(li,
- LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
- LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
- -9);
- /* scroll smaller than the threshold should not generate axis events */
- litest_button_scroll(dev, BTN_LEFT, 1, 1);
- litest_button_scroll(dev, BTN_LEFT, 0, 0);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- /* Restore default scroll behavior */
- libinput_device_config_scroll_set_method(
- dev->libinput_device,
- libinput_device_config_scroll_get_default_method(dev->libinput_device));
- libinput_device_config_scroll_set_button(
- dev->libinput_device,
- libinput_device_config_scroll_get_default_button(dev->libinput_device));
- }
- END_TEST
- START_TEST(pointer_scroll_button_noscroll)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- uint32_t methods, button;
- enum libinput_config_status status;
- methods = libinput_device_config_scroll_get_method(device);
- litest_assert_int_eq(methods & LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN, 0U);
- button = libinput_device_config_scroll_get_button(device);
- litest_assert_int_eq(button, 0U);
- button = libinput_device_config_scroll_get_default_button(device);
- litest_assert_int_eq(button, 0U);
- status = libinput_device_config_scroll_set_method(
- device,
- LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
- status = libinput_device_config_scroll_set_button(device, BTN_LEFT);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
- }
- END_TEST
- START_TEST(pointer_scroll_button_no_event_before_timeout)
- {
- struct litest_device *device = litest_current_device();
- struct libinput *li = device->libinput;
- int i;
- if (!libinput_device_pointer_has_button(device->libinput_device, BTN_MIDDLE))
- return LITEST_NOT_APPLICABLE;
- litest_disable_middleemu(device);
- disable_button_scrolling(device);
- libinput_device_config_scroll_set_method(device->libinput_device,
- LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
- libinput_device_config_scroll_set_button(device->libinput_device, BTN_LEFT);
- litest_drain_events(li);
- litest_button_click_debounced(device, li, BTN_LEFT, true);
- litest_assert_empty_queue(li);
- for (i = 0; i < 10; i++) {
- litest_event(device, EV_REL, REL_Y, 1);
- litest_event(device, EV_SYN, SYN_REPORT, 0);
- }
- litest_assert_empty_queue(li);
- litest_timeout_buttonscroll(li);
- litest_button_click_debounced(device, li, BTN_LEFT, false);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- END_TEST
- START_TEST(pointer_scroll_button_middle_emulation)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- struct libinput *li = dev->libinput;
- enum libinput_config_status status;
- int i;
- status = libinput_device_config_middle_emulation_set_enabled(
- device,
- LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
- if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
- return LITEST_NOT_APPLICABLE;
- status = libinput_device_config_scroll_set_method(
- device,
- LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- status = libinput_device_config_scroll_set_button(device, BTN_MIDDLE);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- litest_drain_events(li);
- litest_button_click(dev, BTN_LEFT, 1);
- litest_button_click(dev, BTN_RIGHT, 1);
- litest_timeout_buttonscroll(li);
- for (i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_Y, -1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_dispatch(li);
- litest_button_click(dev, BTN_LEFT, 0);
- litest_button_click(dev, BTN_RIGHT, 0);
- litest_dispatch(li);
- litest_assert_scroll(li,
- LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- -1);
- litest_assert_empty_queue(li);
- /* Restore default scroll behavior */
- libinput_device_config_scroll_set_method(
- dev->libinput_device,
- libinput_device_config_scroll_get_default_method(dev->libinput_device));
- libinput_device_config_scroll_set_button(
- dev->libinput_device,
- libinput_device_config_scroll_get_default_button(dev->libinput_device));
- }
- END_TEST
- START_TEST(pointer_scroll_button_device_remove_while_down)
- {
- struct litest_device *dev;
- _litest_context_destroy_ struct libinput *li = litest_create_context();
- dev = litest_add_device(li, LITEST_MOUSE);
- libinput_device_config_scroll_set_method(dev->libinput_device,
- LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
- libinput_device_config_scroll_set_button(dev->libinput_device, BTN_LEFT);
- litest_drain_events(li);
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- /* delete the device while the timer is still active */
- litest_device_destroy(dev);
- litest_dispatch(li);
- }
- END_TEST
- static void
- litest_enable_scroll_button_lock(struct litest_device *dev, unsigned int button)
- {
- struct libinput_device *device = dev->libinput_device;
- enum libinput_config_status status;
- status = libinput_device_config_scroll_set_method(
- device,
- LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- status = libinput_device_config_scroll_set_button(device, button);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- status = libinput_device_config_scroll_set_button_lock(
- device,
- LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- }
- START_TEST(pointer_scroll_button_lock)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- litest_enable_scroll_button_lock(dev, BTN_LEFT);
- litest_disable_middleemu(dev);
- litest_drain_events(li);
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_assert_empty_queue(li);
- litest_timeout_buttonscroll(li);
- for (int i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_dispatch(li);
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_dispatch(li);
- litest_assert_scroll(li,
- LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- 6);
- litest_assert_empty_queue(li);
- /* back to motion */
- for (int i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
- }
- END_TEST
- START_TEST(pointer_scroll_button_lock_defaults)
- {
- struct litest_device *dev = litest_current_device();
- enum libinput_config_scroll_button_lock_state state;
- state = libinput_device_config_scroll_get_button_lock(dev->libinput_device);
- litest_assert_enum_eq(state, LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED);
- state = libinput_device_config_scroll_get_default_button_lock(
- dev->libinput_device);
- litest_assert_enum_eq(state, LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED);
- }
- END_TEST
- START_TEST(pointer_scroll_button_lock_config)
- {
- struct litest_device *dev = litest_current_device();
- enum libinput_config_status status;
- enum libinput_config_scroll_button_lock_state state;
- state = libinput_device_config_scroll_get_button_lock(dev->libinput_device);
- litest_assert_enum_eq(state, LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED);
- state = libinput_device_config_scroll_get_default_button_lock(
- dev->libinput_device);
- litest_assert_enum_eq(state, LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED);
- status = libinput_device_config_scroll_set_button_lock(
- dev->libinput_device,
- LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- state = libinput_device_config_scroll_get_button_lock(dev->libinput_device);
- litest_assert_enum_eq(state, LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED);
- status = libinput_device_config_scroll_set_button_lock(
- dev->libinput_device,
- LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- state = libinput_device_config_scroll_get_button_lock(dev->libinput_device);
- litest_assert_enum_eq(state, LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED);
- status = libinput_device_config_scroll_set_button_lock(
- dev->libinput_device,
- LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED + 1);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
- }
- END_TEST
- START_TEST(pointer_scroll_button_lock_enable_while_down)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- litest_disable_middleemu(dev);
- litest_drain_events(li);
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- /* Enable lock while button is down */
- litest_enable_scroll_button_lock(dev, BTN_LEFT);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_empty_queue(li);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- for (int i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- /* no scrolling yet */
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
- /* but on the next button press we scroll lock */
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_timeout_buttonscroll(li);
- for (int i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_assert_scroll(li,
- LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- 6);
- litest_assert_empty_queue(li);
- /* back to motion */
- for (int i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
- }
- END_TEST
- START_TEST(pointer_scroll_button_lock_enable_while_down_just_lock)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- litest_disable_middleemu(dev);
- litest_drain_events(li);
- /* switch method first, but enable lock when we already have a
- * button down */
- libinput_device_config_scroll_set_method(dev->libinput_device,
- LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
- libinput_device_config_scroll_set_button(dev->libinput_device, BTN_LEFT);
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- libinput_device_config_scroll_set_button_lock(
- dev->libinput_device,
- LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- for (int i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- /* no scrolling yet */
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
- /* but on the next button press we scroll lock */
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_timeout_buttonscroll(li);
- for (int i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_assert_scroll(li,
- LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- 6);
- litest_assert_empty_queue(li);
- /* back to motion */
- for (int i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
- }
- END_TEST
- START_TEST(pointer_scroll_button_lock_otherbutton)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- litest_disable_middleemu(dev);
- litest_drain_events(li);
- litest_enable_scroll_button_lock(dev, BTN_LEFT);
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_assert_empty_queue(li);
- litest_timeout_buttonscroll(li);
- /* other button passes on normally */
- litest_button_click_debounced(dev, li, BTN_RIGHT, true);
- litest_button_click_debounced(dev, li, BTN_RIGHT, false);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- for (int i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
- /* other button passes on normally */
- litest_button_click_debounced(dev, li, BTN_RIGHT, true);
- litest_button_click_debounced(dev, li, BTN_RIGHT, false);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
- /* stop scroll lock */
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
- /* other button passes on normally */
- litest_button_click_debounced(dev, li, BTN_RIGHT, true);
- litest_button_click_debounced(dev, li, BTN_RIGHT, false);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- END_TEST
- START_TEST(pointer_scroll_button_lock_enable_while_otherbutton_down)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- litest_disable_middleemu(dev);
- litest_drain_events(li);
- litest_button_click_debounced(dev, li, BTN_RIGHT, true);
- litest_timeout_middlebutton(li);
- litest_drain_events(li);
- /* Enable lock while button is down */
- litest_enable_scroll_button_lock(dev, BTN_LEFT);
- /* We only enable once we go to a neutral state so this still counts
- * as normal button event */
- for (int twice = 0; twice < 2; twice++) {
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li,
- BTN_LEFT,
- LIBINPUT_BUTTON_STATE_RELEASED);
- for (int i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
- }
- litest_button_click_debounced(dev, li, BTN_RIGHT, false);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- /* now we should trigger it */
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_timeout_buttonscroll(li);
- litest_assert_empty_queue(li);
- for (int i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_assert_scroll(li,
- LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- 6);
- litest_assert_empty_queue(li);
- /* back to motion */
- for (int i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
- }
- END_TEST
- enum mb_buttonorder {
- LLRR, /* left down, left up, r down, r up */
- LRLR, /* left down, right down, left up, right up */
- LRRL,
- RRLL,
- RLRL,
- RLLR
- };
- START_TEST(pointer_scroll_button_lock_middlebutton)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- enum mb_buttonorder buttonorder =
- litest_test_param_get_i32(test_env->params, "buttonorder");
- if (!libinput_device_config_middle_emulation_is_available(dev->libinput_device))
- return LITEST_NOT_APPLICABLE;
- litest_enable_middleemu(dev);
- litest_enable_scroll_button_lock(dev, BTN_LEFT);
- litest_drain_events(li);
- /* We expect scroll lock to work only where left and right are never
- * held down simultaneously. Everywhere else we expect middle button
- * instead.
- */
- switch (buttonorder) {
- case LLRR:
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_button_click_debounced(dev, li, BTN_RIGHT, true);
- litest_button_click_debounced(dev, li, BTN_RIGHT, false);
- break;
- case LRLR:
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_RIGHT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_button_click_debounced(dev, li, BTN_RIGHT, false);
- break;
- case LRRL:
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_RIGHT, true);
- litest_button_click_debounced(dev, li, BTN_RIGHT, false);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- break;
- case RRLL:
- litest_button_click_debounced(dev, li, BTN_RIGHT, true);
- litest_button_click_debounced(dev, li, BTN_RIGHT, false);
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- break;
- case RLRL:
- litest_button_click_debounced(dev, li, BTN_RIGHT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_RIGHT, false);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- break;
- case RLLR:
- litest_button_click_debounced(dev, li, BTN_RIGHT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_button_click_debounced(dev, li, BTN_RIGHT, false);
- break;
- default:
- abort();
- }
- litest_timeout_middlebutton(li);
- litest_timeout_buttonscroll(li);
- /* motion events are the same for all of them */
- for (int i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_dispatch(li);
- switch (buttonorder) {
- case LLRR:
- case RRLL:
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- break;
- default:
- break;
- }
- litest_dispatch(li);
- switch (buttonorder) {
- case LLRR:
- case RRLL:
- litest_assert_button_event(li,
- BTN_RIGHT,
- LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li,
- BTN_RIGHT,
- LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_scroll(li,
- LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- 6);
- litest_assert_empty_queue(li);
- break;
- case LRLR:
- case LRRL:
- case RLRL:
- case RLLR:
- litest_assert_button_event(li,
- BTN_MIDDLE,
- LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li,
- BTN_MIDDLE,
- LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
- break;
- default:
- abort();
- }
- }
- END_TEST
- START_TEST(pointer_scroll_button_lock_doubleclick_nomove)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- litest_disable_middleemu(dev);
- litest_enable_scroll_button_lock(dev, BTN_LEFT);
- litest_drain_events(li);
- /* double click without move in between counts as single click */
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_assert_empty_queue(li);
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- /* But a non-scroll button it should work normally */
- litest_button_click_debounced(dev, li, BTN_RIGHT, true);
- litest_button_click_debounced(dev, li, BTN_RIGHT, false);
- litest_button_click_debounced(dev, li, BTN_RIGHT, true);
- litest_button_click_debounced(dev, li, BTN_RIGHT, false);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- END_TEST
- START_TEST(pointer_scroll_button_lock_scroll_releases)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- litest_enable_scroll_button_lock(dev, BTN_LEFT);
- litest_disable_middleemu(dev);
- litest_drain_events(li);
- /* Press, wait for buttonscroll timeout, scroll, wait past grace
- period, release. The lock should NOT engage. */
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_timeout_buttonscroll(li);
- litest_dispatch(li);
- for (int i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_dispatch(li);
- litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
- litest_timeout_scroll_button_lock_grace(li);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_dispatch(li);
- /* Expect scroll stop, no lock */
- litest_assert_scroll(li, LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS, 0, 0);
- /* Subsequent motion should be pointer motion, not scroll */
- for (int i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
- }
- END_TEST
- START_TEST(pointer_scroll_button_lock_scroll_within_grace)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- litest_enable_scroll_button_lock(dev, BTN_LEFT);
- litest_disable_middleemu(dev);
- litest_drain_events(li);
- /* Press, wait for buttonscroll timeout, scroll briefly, release
- immediately (total < 500ms from press). The lock SHOULD engage
- since we're within the grace period. */
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_timeout_buttonscroll(li);
- litest_dispatch(li);
- for (int i = 0; i < 3; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_dispatch(li);
- /* Release immediately (still within grace period) */
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_dispatch(li);
- /* Lock should be engaged: drain scroll events from the hold */
- litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
- /* Motion while locked should produce scroll events */
- for (int i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_dispatch(li);
- litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
- /* Click again to unlock */
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_dispatch(li);
- litest_assert_scroll(li, LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS, 0, 0);
- /* Back to normal motion */
- for (int i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
- }
- END_TEST
- START_TEST(pointer_scroll_button_lock_hold_no_move_still_locks)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- litest_enable_scroll_button_lock(dev, BTN_LEFT);
- litest_disable_middleemu(dev);
- litest_drain_events(li);
- /* Press, wait past 500ms, release without moving.
- button_scroll_state == READY (not SCROLLING), so lock
- engages as normal click. */
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_timeout_buttonscroll(li);
- litest_timeout_scroll_button_lock_grace(li);
- litest_dispatch(li);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_dispatch(li);
- /* Lock should be engaged (release was filtered).
- The scroll SM was in READY state, so it emits button press/release
- (since no scrolling occurred), but the lock SM filtered the release.
- Subsequent motion should produce scroll events. */
- litest_assert_empty_queue(li);
- for (int i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 6);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_dispatch(li);
- litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
- /* Click to unlock */
- litest_button_click_debounced(dev, li, BTN_LEFT, true);
- litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_dispatch(li);
- litest_assert_scroll(li, LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS, 0, 0);
- }
- END_TEST
- START_TEST(pointer_scroll_nowheel_defaults)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- enum libinput_config_scroll_method method, expected;
- uint32_t button;
- /* button scrolling is only enabled if there is a
- middle button present */
- if (libinput_device_pointer_has_button(device, BTN_MIDDLE) &&
- dev->which != LITEST_LENOVO_SCROLLPOINT)
- expected = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
- else
- expected = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
- method = libinput_device_config_scroll_get_method(device);
- litest_assert_int_eq(method, expected);
- method = libinput_device_config_scroll_get_default_method(device);
- litest_assert_int_eq(method, expected);
- if (method == LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) {
- button = libinput_device_config_scroll_get_button(device);
- litest_assert_int_eq(button, (unsigned int)BTN_MIDDLE);
- button = libinput_device_config_scroll_get_default_button(device);
- litest_assert_int_eq(button, (unsigned int)BTN_MIDDLE);
- }
- }
- END_TEST
- START_TEST(pointer_scroll_defaults_logitech_marble)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- enum libinput_config_scroll_method method;
- uint32_t button;
- method = libinput_device_config_scroll_get_method(device);
- litest_assert_enum_eq(method, LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
- method = libinput_device_config_scroll_get_default_method(device);
- litest_assert_enum_eq(method, LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
- button = libinput_device_config_scroll_get_button(device);
- litest_assert_int_eq(button, (unsigned int)BTN_SIDE);
- }
- END_TEST
- START_TEST(pointer_accel_defaults)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- enum libinput_config_status status;
- double speed;
- litest_assert(libinput_device_config_accel_is_available(device));
- litest_assert_double_eq(libinput_device_config_accel_get_default_speed(device),
- 0.0);
- litest_assert_double_eq(libinput_device_config_accel_get_speed(device), 0.0);
- for (speed = -2.0; speed < -1.0; speed += 0.2) {
- status = libinput_device_config_accel_set_speed(device, speed);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
- litest_assert_double_eq(libinput_device_config_accel_get_speed(device),
- 0.0);
- }
- for (speed = -1.0; speed <= 1.0; speed += 0.2) {
- status = libinput_device_config_accel_set_speed(device, speed);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- litest_assert_double_eq(libinput_device_config_accel_get_speed(device),
- speed);
- }
- for (speed = 1.2; speed <= 2.0; speed += 0.2) {
- status = libinput_device_config_accel_set_speed(device, speed);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
- litest_assert_double_eq(libinput_device_config_accel_get_speed(device),
- 1.0);
- }
- }
- END_TEST
- START_TEST(pointer_accel_invalid)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- enum libinput_config_status status;
- litest_assert(libinput_device_config_accel_is_available(device));
- status = libinput_device_config_accel_set_speed(device, NAN);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
- status = libinput_device_config_accel_set_speed(device, INFINITY);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
- }
- END_TEST
- START_TEST(pointer_accel_defaults_absolute)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- enum libinput_config_status status;
- double speed;
- litest_assert(!libinput_device_config_accel_is_available(device));
- litest_assert_double_eq(libinput_device_config_accel_get_default_speed(device),
- 0.0);
- litest_assert_double_eq(libinput_device_config_accel_get_speed(device), 0.0);
- for (speed = -2.0; speed <= 2.0; speed += 0.2) {
- status = libinput_device_config_accel_set_speed(device, speed);
- if (speed >= -1.0 && speed <= 1.0)
- litest_assert_enum_eq(status,
- LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
- else
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
- litest_assert_double_eq(libinput_device_config_accel_get_speed(device),
- 0.0);
- }
- }
- END_TEST
- START_TEST(pointer_accel_defaults_absolute_relative)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- litest_assert(libinput_device_config_accel_is_available(device));
- litest_assert_double_eq(libinput_device_config_accel_get_default_speed(device),
- 0.0);
- litest_assert_double_eq(libinput_device_config_accel_get_speed(device), 0.0);
- }
- END_TEST
- START_TEST(pointer_accel_direction_change)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- struct libinput_event *event;
- struct libinput_event_pointer *pev;
- int i;
- double delta;
- litest_drain_events(li);
- for (i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_X, -1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- }
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- event = libinput_get_event(li);
- do {
- pev = libinput_event_get_pointer_event(event);
- delta = libinput_event_pointer_get_dx(pev);
- litest_assert_double_le(delta, 0.0);
- libinput_event_destroy(event);
- event = libinput_get_event(li);
- } while (libinput_next_event_type(li) != LIBINPUT_EVENT_NONE);
- pev = libinput_event_get_pointer_event(event);
- delta = libinput_event_pointer_get_dx(pev);
- litest_assert_double_gt(delta, 0.0);
- libinput_event_destroy(event);
- }
- END_TEST
- START_TEST(pointer_accel_profile_defaults)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- enum libinput_config_status status;
- enum libinput_config_accel_profile profile;
- uint32_t profiles;
- litest_assert(libinput_device_config_accel_is_available(device));
- profile = libinput_device_config_accel_get_default_profile(device);
- litest_assert_enum_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
- profile = libinput_device_config_accel_get_profile(device);
- litest_assert_enum_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
- profiles = libinput_device_config_accel_get_profiles(device);
- litest_assert(profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
- litest_assert(profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
- litest_assert(profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM);
- status = libinput_device_config_accel_set_profile(
- device,
- LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- profile = libinput_device_config_accel_get_profile(device);
- litest_assert_enum_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
- profile = libinput_device_config_accel_get_default_profile(device);
- litest_assert_enum_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
- status = libinput_device_config_accel_set_profile(
- device,
- LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- profile = libinput_device_config_accel_get_profile(device);
- litest_assert_enum_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
- status = libinput_device_config_accel_set_profile(
- device,
- LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- profile = libinput_device_config_accel_get_profile(device);
- litest_assert_enum_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM);
- }
- END_TEST
- START_TEST(pointer_accel_config_reset_to_defaults)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- double default_speed = libinput_device_config_accel_get_default_speed(device);
- /* There are no settings for these profiles to toggle, so we expect it
- * to simply reset to defaults */
- enum libinput_config_accel_profile profiles[] = {
- LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
- LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
- };
- ARRAY_FOR_EACH(profiles, profile) {
- litest_assert_enum_eq(
- libinput_device_config_accel_set_speed(device, 1.0),
- LIBINPUT_CONFIG_STATUS_SUCCESS);
- litest_assert_double_eq(libinput_device_config_accel_get_speed(device),
- 1.0);
- struct libinput_config_accel *config = libinput_config_accel_create(
- LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
- litest_assert_enum_eq(
- libinput_device_config_accel_apply(device, config),
- LIBINPUT_CONFIG_STATUS_SUCCESS);
- litest_assert_double_eq(libinput_device_config_accel_get_speed(device),
- default_speed);
- libinput_config_accel_destroy(config);
- }
- }
- END_TEST
- START_TEST(pointer_accel_config)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- enum libinput_config_status status;
- enum libinput_config_accel_profile profile;
- enum libinput_config_status valid = LIBINPUT_CONFIG_STATUS_SUCCESS,
- invalid = LIBINPUT_CONFIG_STATUS_INVALID;
- enum libinput_config_accel_type accel_types[] = {
- LIBINPUT_ACCEL_TYPE_FALLBACK,
- LIBINPUT_ACCEL_TYPE_MOTION,
- LIBINPUT_ACCEL_TYPE_SCROLL,
- };
- struct custom_config_test {
- double step;
- double points[4];
- enum libinput_config_status expected_status;
- } tests[] = {
- { 0.5, { 1.0, 2.0, 2.5, 2.6 }, valid },
- { 0.003, { 0.1, 0.3, 0.4, 0.45 }, valid },
- { 2.7, { 1.0, 3.0, 4.5, 4.5 }, valid },
- { 0, { 1.0, 2.0, 2.5, 2.6 }, invalid },
- { -1, { 1.0, 2.0, 2.5, 2.6 }, invalid },
- { 1e10, { 1.0, 2.0, 2.5, 2.6 }, invalid },
- { 1, { 1.0, 2.0, -2.5, 2.6 }, invalid },
- { 1, { 1.0, 2.0, 1e10, 2.6 }, invalid },
- };
- litest_assert(libinput_device_config_accel_is_available(device));
- struct libinput_config_accel *config_custom_default =
- libinput_config_accel_create(LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM);
- struct libinput_config_accel *config_custom_changed =
- libinput_config_accel_create(LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM);
- litest_assert_ptr_notnull(config_custom_default);
- litest_assert_ptr_notnull(config_custom_changed);
- ARRAY_FOR_EACH(tests, t) {
- ARRAY_FOR_EACH(accel_types, accel_type) {
- status = libinput_config_accel_set_points(
- config_custom_changed,
- *accel_type,
- t->step,
- ARRAY_LENGTH(t->points),
- t->points);
- litest_assert_int_eq(status, t->expected_status);
- status = libinput_device_config_accel_apply(
- device,
- config_custom_changed);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- profile = libinput_device_config_accel_get_profile(device);
- litest_assert_enum_eq(profile,
- LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM);
- status = libinput_device_config_accel_apply(
- device,
- config_custom_default);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- profile = libinput_device_config_accel_get_profile(device);
- litest_assert_enum_eq(profile,
- LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM);
- }
- }
- libinput_config_accel_destroy(config_custom_default);
- libinput_config_accel_destroy(config_custom_changed);
- }
- END_TEST
- START_TEST(pointer_accel_profile_invalid)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- enum libinput_config_status status;
- litest_assert(libinput_device_config_accel_is_available(device));
- status = libinput_device_config_accel_set_profile(
- device,
- LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
- status = libinput_device_config_accel_set_profile(
- device,
- LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE + 1);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
- status = libinput_device_config_accel_set_profile(
- device,
- LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE |
- LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
- status = libinput_device_config_accel_set_profile(
- device,
- LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM |
- LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
- }
- END_TEST
- START_TEST(pointer_accel_profile_noaccel)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- enum libinput_config_status status;
- enum libinput_config_accel_profile profile;
- litest_assert(!libinput_device_config_accel_is_available(device));
- profile = libinput_device_config_accel_get_default_profile(device);
- litest_assert_enum_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
- profile = libinput_device_config_accel_get_profile(device);
- litest_assert_enum_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
- status = libinput_device_config_accel_set_profile(
- device,
- LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
- status = libinput_device_config_accel_set_profile(
- device,
- LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE + 1);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
- status = libinput_device_config_accel_set_profile(
- device,
- LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE |
- LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
- }
- END_TEST
- START_TEST(pointer_accel_profile_flat_motion_relative)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- libinput_device_config_accel_set_profile(device,
- LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
- litest_drain_events(dev->libinput);
- test_relative_event(dev, 1, 0);
- test_relative_event(dev, 1, 1);
- test_relative_event(dev, 1, -1);
- test_relative_event(dev, 0, 1);
- test_relative_event(dev, -1, 0);
- test_relative_event(dev, -1, 1);
- test_relative_event(dev, -1, -1);
- test_relative_event(dev, 0, -1);
- }
- END_TEST
- START_TEST(middlebutton)
- {
- struct litest_device *device = litest_current_device();
- struct libinput *li = device->libinput;
- enum libinput_config_status status;
- unsigned int i;
- const int btn[][4] = {
- { BTN_LEFT, BTN_RIGHT, BTN_LEFT, BTN_RIGHT },
- { BTN_LEFT, BTN_RIGHT, BTN_RIGHT, BTN_LEFT },
- { BTN_RIGHT, BTN_LEFT, BTN_LEFT, BTN_RIGHT },
- { BTN_RIGHT, BTN_LEFT, BTN_RIGHT, BTN_LEFT },
- };
- disable_button_scrolling(device);
- status = libinput_device_config_middle_emulation_set_enabled(
- device->libinput_device,
- LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
- if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
- return LITEST_NOT_APPLICABLE;
- litest_drain_events(li);
- for (i = 0; i < ARRAY_LENGTH(btn); i++) {
- litest_button_click_debounced(device, li, btn[i][0], true);
- litest_button_click_debounced(device, li, btn[i][1], true);
- litest_assert_button_event(li,
- BTN_MIDDLE,
- LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_empty_queue(li);
- litest_button_click_debounced(device, li, btn[i][2], false);
- litest_button_click_debounced(device, li, btn[i][3], false);
- litest_assert_button_event(li,
- BTN_MIDDLE,
- LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- }
- END_TEST
- START_TEST(middlebutton_nostart_while_down)
- {
- struct litest_device *device = litest_current_device();
- struct libinput *li = device->libinput;
- enum libinput_config_status status;
- unsigned int i;
- const int btn[][4] = {
- { BTN_LEFT, BTN_RIGHT, BTN_LEFT, BTN_RIGHT },
- { BTN_LEFT, BTN_RIGHT, BTN_RIGHT, BTN_LEFT },
- { BTN_RIGHT, BTN_LEFT, BTN_LEFT, BTN_RIGHT },
- { BTN_RIGHT, BTN_LEFT, BTN_RIGHT, BTN_LEFT },
- };
- if (!libinput_device_pointer_has_button(device->libinput_device, BTN_MIDDLE))
- return LITEST_NOT_APPLICABLE;
- disable_button_scrolling(device);
- status = libinput_device_config_middle_emulation_set_enabled(
- device->libinput_device,
- LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
- if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
- return LITEST_NOT_APPLICABLE;
- litest_button_click_debounced(device, li, BTN_MIDDLE, true);
- litest_drain_events(li);
- for (i = 0; i < ARRAY_LENGTH(btn); i++) {
- litest_button_click_debounced(device, li, btn[i][0], true);
- litest_assert_button_event(li,
- btn[i][0],
- LIBINPUT_BUTTON_STATE_PRESSED);
- litest_button_click_debounced(device, li, btn[i][1], true);
- litest_assert_button_event(li,
- btn[i][1],
- LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_empty_queue(li);
- litest_button_click_debounced(device, li, btn[i][2], false);
- litest_assert_button_event(li,
- btn[i][2],
- LIBINPUT_BUTTON_STATE_RELEASED);
- litest_button_click_debounced(device, li, btn[i][3], false);
- litest_assert_button_event(li,
- btn[i][3],
- LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- litest_button_click_debounced(device, li, BTN_MIDDLE, false);
- litest_drain_events(li);
- }
- END_TEST
- START_TEST(middlebutton_timeout)
- {
- struct litest_device *device = litest_current_device();
- struct libinput *li = device->libinput;
- enum libinput_config_status status;
- unsigned int button;
- disable_button_scrolling(device);
- status = libinput_device_config_middle_emulation_set_enabled(
- device->libinput_device,
- LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
- if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
- return LITEST_NOT_APPLICABLE;
- for (button = BTN_LEFT; button <= BTN_RIGHT; button++) {
- litest_drain_events(li);
- litest_button_click_debounced(device, li, button, true);
- litest_assert_empty_queue(li);
- litest_timeout_middlebutton(li);
- litest_assert_button_event(li, button, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_button_click_debounced(device, li, button, false);
- litest_assert_button_event(li, button, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- }
- END_TEST
- START_TEST(middlebutton_doubleclick)
- {
- struct litest_device *device = litest_current_device();
- struct libinput *li = device->libinput;
- enum libinput_config_status status;
- unsigned int i;
- const int btn[][4] = {
- { BTN_LEFT, BTN_RIGHT, BTN_LEFT, BTN_RIGHT },
- { BTN_LEFT, BTN_RIGHT, BTN_RIGHT, BTN_LEFT },
- { BTN_RIGHT, BTN_LEFT, BTN_LEFT, BTN_RIGHT },
- { BTN_RIGHT, BTN_LEFT, BTN_RIGHT, BTN_LEFT },
- };
- disable_button_scrolling(device);
- status = libinput_device_config_middle_emulation_set_enabled(
- device->libinput_device,
- LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
- if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
- return LITEST_NOT_APPLICABLE;
- litest_drain_events(li);
- for (i = 0; i < ARRAY_LENGTH(btn); i++) {
- litest_button_click_debounced(device, li, btn[i][0], true);
- litest_button_click_debounced(device, li, btn[i][1], true);
- litest_assert_button_event(li,
- BTN_MIDDLE,
- LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_empty_queue(li);
- litest_button_click_debounced(device, li, btn[i][2], false);
- litest_button_click_debounced(device, li, btn[i][2], true);
- litest_assert_button_event(li,
- BTN_MIDDLE,
- LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_button_event(li,
- BTN_MIDDLE,
- LIBINPUT_BUTTON_STATE_PRESSED);
- litest_button_click_debounced(device, li, btn[i][3], false);
- litest_assert_button_event(li,
- BTN_MIDDLE,
- LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- }
- END_TEST
- START_TEST(middlebutton_middleclick)
- {
- struct litest_device *device = litest_current_device();
- struct libinput *li = device->libinput;
- enum libinput_config_status status;
- unsigned int button;
- disable_button_scrolling(device);
- if (!libinput_device_pointer_has_button(device->libinput_device, BTN_MIDDLE))
- return LITEST_NOT_APPLICABLE;
- status = libinput_device_config_middle_emulation_set_enabled(
- device->libinput_device,
- LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
- if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
- return LITEST_NOT_APPLICABLE;
- /* one button down, then middle -> release buttons */
- for (button = BTN_LEFT; button <= BTN_RIGHT; button++) {
- /* release button before middle */
- litest_drain_events(li);
- litest_button_click_debounced(device, li, button, true);
- litest_button_click_debounced(device, li, BTN_MIDDLE, true);
- litest_assert_button_event(li, button, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li,
- BTN_MIDDLE,
- LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_empty_queue(li);
- litest_button_click_debounced(device, li, button, false);
- litest_assert_button_event(li, button, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_button_click_debounced(device, li, BTN_MIDDLE, false);
- litest_assert_button_event(li,
- BTN_MIDDLE,
- LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- /* release middle before button */
- litest_button_click_debounced(device, li, button, true);
- litest_button_click_debounced(device, li, BTN_MIDDLE, true);
- litest_assert_button_event(li, button, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li,
- BTN_MIDDLE,
- LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_empty_queue(li);
- litest_button_click_debounced(device, li, BTN_MIDDLE, false);
- litest_assert_button_event(li,
- BTN_MIDDLE,
- LIBINPUT_BUTTON_STATE_RELEASED);
- litest_button_click_debounced(device, li, button, false);
- litest_assert_button_event(li, button, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- }
- END_TEST
- START_TEST(middlebutton_middleclick_during)
- {
- struct litest_device *device = litest_current_device();
- struct libinput *li = device->libinput;
- enum libinput_config_status status;
- unsigned int button;
- disable_button_scrolling(device);
- if (!libinput_device_pointer_has_button(device->libinput_device, BTN_MIDDLE))
- return LITEST_NOT_APPLICABLE;
- status = libinput_device_config_middle_emulation_set_enabled(
- device->libinput_device,
- LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
- if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
- return LITEST_NOT_APPLICABLE;
- litest_drain_events(li);
- /* trigger emulation, then real middle */
- for (button = BTN_LEFT; button <= BTN_RIGHT; button++) {
- litest_button_click_debounced(device, li, BTN_LEFT, true);
- litest_button_click_debounced(device, li, BTN_RIGHT, true);
- litest_assert_button_event(li,
- BTN_MIDDLE,
- LIBINPUT_BUTTON_STATE_PRESSED);
- litest_button_click_debounced(device, li, BTN_MIDDLE, true);
- litest_assert_button_event(li,
- BTN_MIDDLE,
- LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_button_event(li,
- BTN_MIDDLE,
- LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_empty_queue(li);
- /* middle still down, release left/right */
- litest_button_click_debounced(device, li, button, false);
- litest_assert_empty_queue(li);
- litest_button_click_debounced(device, li, button, true);
- litest_assert_button_event(li, button, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_empty_queue(li);
- /* release both */
- litest_button_click_debounced(device, li, BTN_LEFT, false);
- litest_button_click_debounced(device, li, BTN_RIGHT, false);
- litest_assert_button_event(li, button, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- litest_button_click_debounced(device, li, BTN_MIDDLE, false);
- litest_assert_button_event(li,
- BTN_MIDDLE,
- LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- }
- END_TEST
- START_TEST(middlebutton_default_enabled)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- enum libinput_config_status status;
- int available;
- enum libinput_config_middle_emulation_state state;
- if (!libinput_device_pointer_has_button(dev->libinput_device, BTN_MIDDLE))
- return LITEST_NOT_APPLICABLE;
- available = libinput_device_config_middle_emulation_is_available(device);
- litest_assert(available);
- state = libinput_device_config_middle_emulation_get_enabled(device);
- litest_assert_enum_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
- state = libinput_device_config_middle_emulation_get_default_enabled(device);
- litest_assert_enum_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
- status = libinput_device_config_middle_emulation_set_enabled(
- device,
- LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- status = libinput_device_config_middle_emulation_set_enabled(
- device,
- LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- status = libinput_device_config_middle_emulation_set_enabled(device, 3);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
- }
- END_TEST
- START_TEST(middlebutton_default_clickpad)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- enum libinput_config_status status;
- enum libinput_config_middle_emulation_state state;
- int available;
- available = libinput_device_config_middle_emulation_is_available(device);
- litest_assert(available);
- state = libinput_device_config_middle_emulation_get_enabled(device);
- litest_assert_enum_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
- state = libinput_device_config_middle_emulation_get_default_enabled(device);
- litest_assert_enum_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
- status = libinput_device_config_middle_emulation_set_enabled(
- device,
- LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- status = libinput_device_config_middle_emulation_set_enabled(
- device,
- LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- status = libinput_device_config_middle_emulation_set_enabled(device, 3);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
- }
- END_TEST
- START_TEST(middlebutton_default_touchpad)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- enum libinput_config_middle_emulation_state state;
- int available;
- const char *name = libinput_device_get_name(dev->libinput_device);
- if (streq(name, "litest AlpsPS/2 ALPS GlidePoint") ||
- streq(name, "litest AlpsPS/2 ALPS DualPoint TouchPad"))
- return LITEST_NOT_APPLICABLE;
- available = libinput_device_config_middle_emulation_is_available(device);
- litest_assert(!available);
- if (libinput_device_pointer_has_button(device, BTN_MIDDLE))
- return LITEST_NOT_APPLICABLE;
- state = libinput_device_config_middle_emulation_get_enabled(device);
- litest_assert_enum_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
- state = libinput_device_config_middle_emulation_get_default_enabled(device);
- litest_assert_enum_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
- }
- END_TEST
- START_TEST(middlebutton_default_alps)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- enum libinput_config_middle_emulation_state state;
- int available;
- available = libinput_device_config_middle_emulation_is_available(device);
- litest_assert(available);
- state = libinput_device_config_middle_emulation_get_enabled(device);
- litest_assert_enum_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
- state = libinput_device_config_middle_emulation_get_default_enabled(device);
- litest_assert_enum_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
- }
- END_TEST
- START_TEST(middlebutton_default_disabled)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- enum libinput_config_middle_emulation_state state;
- enum libinput_config_status status;
- int available;
- available = libinput_device_config_middle_emulation_is_available(device);
- litest_assert(!available);
- state = libinput_device_config_middle_emulation_get_enabled(device);
- litest_assert_enum_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
- state = libinput_device_config_middle_emulation_get_default_enabled(device);
- litest_assert_enum_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
- status = libinput_device_config_middle_emulation_set_enabled(
- device,
- LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
- status = libinput_device_config_middle_emulation_set_enabled(
- device,
- LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
- litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
- }
- END_TEST
- START_TEST(middlebutton_button_scrolling)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- struct libinput *li = dev->libinput;
- enum libinput_config_status status;
- struct libinput_event *ev;
- struct libinput_event_pointer *pev;
- int i;
- status = libinput_device_config_middle_emulation_set_enabled(
- device,
- LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
- if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
- return LITEST_NOT_APPLICABLE;
- status = libinput_device_config_scroll_set_method(
- device,
- LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
- if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
- return LITEST_NOT_APPLICABLE;
- status = libinput_device_config_scroll_set_button(device, BTN_LEFT);
- if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
- return LITEST_NOT_APPLICABLE;
- litest_drain_events(li);
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- /* middle emulation discards */
- litest_assert_empty_queue(li);
- litest_timeout_middlebutton(li);
- /* scroll discards */
- litest_assert_empty_queue(li);
- litest_timeout_buttonscroll(li);
- for (i = 0; i < 10; i++) {
- litest_event(dev, EV_REL, REL_Y, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- }
- ev = libinput_get_event(li);
- do {
- pev = litest_is_axis_event(ev,
- LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
- litest_assert_double_gt(litest_event_pointer_get_value(
- pev,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
- 0.0);
- libinput_event_destroy(ev);
- ev = libinput_get_event(li);
- } while (ev);
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_assert_axis_end_sequence(li,
- LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
- /* no button release */
- litest_assert_empty_queue(li);
- }
- END_TEST
- START_TEST(middlebutton_button_scrolling_middle)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- struct libinput *li = dev->libinput;
- enum libinput_config_status status;
- status = libinput_device_config_middle_emulation_set_enabled(
- device,
- LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
- if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
- return LITEST_NOT_APPLICABLE;
- status = libinput_device_config_scroll_set_method(
- device,
- LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
- if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
- return LITEST_NOT_APPLICABLE;
- status = libinput_device_config_scroll_set_button(device, BTN_LEFT);
- if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
- return LITEST_NOT_APPLICABLE;
- litest_drain_events(li);
- /* button scrolling should not stop middle emulation */
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_RIGHT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_assert_button_event(li, BTN_MIDDLE, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_RIGHT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_assert_button_event(li, BTN_MIDDLE, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- END_TEST
- START_TEST(middlebutton_device_remove_while_down)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- struct libinput *li = dev->libinput;
- enum libinput_config_status status;
- libinput_device_config_scroll_set_method(device,
- LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
- status = libinput_device_config_middle_emulation_set_enabled(
- device,
- LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
- if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
- return LITEST_NOT_APPLICABLE;
- litest_drain_events(li);
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_RIGHT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_assert_button_event(li, BTN_MIDDLE, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_empty_queue(li);
- }
- END_TEST
- START_TEST(middlebutton_device_remove_while_one_is_down)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- struct libinput *li = dev->libinput;
- enum libinput_config_status status;
- libinput_device_config_scroll_set_method(device,
- LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
- status = libinput_device_config_middle_emulation_set_enabled(
- device,
- LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
- if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
- return LITEST_NOT_APPLICABLE;
- litest_drain_events(li);
- litest_event(dev, EV_KEY, BTN_RIGHT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_assert_empty_queue(li);
- }
- END_TEST
- START_TEST(pointer_time_usec)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- struct libinput_event_pointer *ptrev;
- struct libinput_event *event;
- uint64_t time_usec;
- litest_drain_events(dev->libinput);
- litest_event(dev, EV_REL, REL_X, 1);
- litest_event(dev, EV_REL, REL_Y, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_wait_for_event(li);
- event = libinput_get_event(li);
- ptrev = litest_is_motion_event(event);
- time_usec = libinput_event_pointer_get_time_usec(ptrev);
- litest_assert_int_eq(libinput_event_pointer_get_time(ptrev),
- (uint32_t)(time_usec / 1000));
- libinput_event_destroy(event);
- litest_drain_events(dev->libinput);
- }
- END_TEST
- START_TEST(debounce_bounce)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- unsigned int button = litest_test_param_get_i32(test_env->params, "button");
- if (!libinput_device_pointer_has_button(dev->libinput_device, button))
- return LITEST_NOT_APPLICABLE;
- litest_disable_middleemu(dev);
- disable_button_scrolling(dev);
- litest_drain_events(li);
- litest_event(dev, EV_KEY, button, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, button, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, button, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_timeout_debounce(li);
- litest_assert_button_event(li, button, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_empty_queue(li);
- litest_event(dev, EV_KEY, button, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, button, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, button, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_timeout_debounce(li);
- litest_assert_button_event(li, button, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- END_TEST
- START_TEST(debounce_bounce_high_delay)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- unsigned int button = litest_test_param_get_i32(test_env->params, "button");
- if (!libinput_device_pointer_has_button(dev->libinput_device, button))
- return LITEST_NOT_APPLICABLE;
- litest_disable_middleemu(dev);
- disable_button_scrolling(dev);
- litest_drain_events(li);
- /* Debouncing timeout is 25ms after a button down or up. Make sure we go
- * over 25ms for the total bouncing duration, but stay under 25ms for
- * each single event. */
- litest_event(dev, EV_KEY, button, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- msleep(15);
- litest_event(dev, EV_KEY, button, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- msleep(15);
- litest_event(dev, EV_KEY, button, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_timeout_debounce(li);
- litest_assert_button_event(li, button, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_empty_queue(li);
- litest_event(dev, EV_KEY, button, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- msleep(15);
- litest_event(dev, EV_KEY, button, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- msleep(15);
- litest_event(dev, EV_KEY, button, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_timeout_debounce(li);
- litest_assert_button_event(li, button, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- END_TEST
- START_TEST(debounce_bounce_check_immediate)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- litest_disable_middleemu(dev);
- disable_button_scrolling(dev);
- litest_drain_events(li);
- /* Press must be sent without delay */
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_timeout_debounce(li);
- litest_assert_empty_queue(li);
- /* held down & past timeout, we expect releases to be immediate */
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_timeout_debounce(li);
- litest_assert_empty_queue(li);
- }
- END_TEST
- /* Triggers the event sequence that initializes the spurious
- * debouncing behavior */
- static inline void
- debounce_trigger_spurious(struct litest_device *dev, struct libinput *li)
- {
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_timeout_debounce(li);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_timeout_debounce(li);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- /* gets filtered now */
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_timeout_debounce(li);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- START_TEST(debounce_spurious)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- unsigned int button = litest_test_param_get_i32(test_env->params, "button");
- if (!libinput_device_pointer_has_button(dev->libinput_device, button))
- return LITEST_NOT_APPLICABLE;
- litest_disable_middleemu(dev);
- disable_button_scrolling(dev);
- litest_drain_events(li);
- debounce_trigger_spurious(dev, li);
- for (int i = 0; i < 3; i++) {
- litest_event(dev, EV_KEY, button, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_timeout_debounce(li);
- /* Not all devices can disable middle button emulation, time out on
- * middle button here to make sure the initial button press event
- * was flushed.
- */
- litest_timeout_middlebutton(li);
- litest_assert_button_event(li, button, LIBINPUT_BUTTON_STATE_PRESSED);
- /* bouncy bouncy bouncy */
- litest_event(dev, EV_KEY, button, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, button, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_assert_empty_queue(li);
- litest_event(dev, EV_KEY, button, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_timeout_debounce(li);
- litest_assert_button_event(li, button, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- }
- END_TEST
- START_TEST(debounce_spurious_multibounce)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- litest_disable_middleemu(dev);
- litest_drain_events(li);
- debounce_trigger_spurious(dev, li);
- litest_drain_events(li);
- /* Let's assume our button has ventricular fibrilation and sends a
- * lot of clicks. Debouncing is now enabled, ventricular
- * fibrillation should cause one button down for the first press and
- * one release for the last release.
- */
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_timeout_debounce(li);
- /* Not all devices can disable middle button emulation, time out on
- * middle button here to make sure the initial button press event
- * was flushed.
- */
- litest_timeout_middlebutton(li);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_assert_empty_queue(li);
- litest_timeout_debounce(li);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- END_TEST
- START_TEST(debounce_spurious_trigger_high_delay)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput *li = dev->libinput;
- litest_disable_middleemu(dev);
- litest_drain_events(li);
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_timeout_debounce(li);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- /* Spurious timeout is 12ms after a button down or up. Make sure we go
- * over 12ms for the total bouncing duration, but stay under 12ms for
- * each single event. */
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- msleep(5);
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- msleep(5);
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- msleep(5);
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_timeout_debounce(li);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- /* gets filtered now */
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_timeout_debounce(li);
- litest_assert_empty_queue(li);
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_timeout_debounce(li);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- END_TEST
- START_TEST(debounce_spurious_dont_enable_on_otherbutton)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- struct libinput *li = dev->libinput;
- if (!libinput_device_config_middle_emulation_is_available(device))
- return LITEST_NOT_APPLICABLE;
- litest_disable_middleemu(dev);
- disable_button_scrolling(dev);
- litest_drain_events(li);
- /* Don't trigger spurious debouncing on otherbutton events */
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_timeout_debounce(li);
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_RIGHT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_RIGHT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- /* Expect release to be immediate */
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_timeout_debounce(li);
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- }
- END_TEST
- START_TEST(debounce_spurious_cancel_debounce_otherbutton)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- struct libinput *li = dev->libinput;
- if (!libinput_device_config_middle_emulation_is_available(device))
- return LITEST_NOT_APPLICABLE;
- litest_disable_middleemu(dev);
- disable_button_scrolling(dev);
- litest_drain_events(li);
- debounce_trigger_spurious(dev, li);
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_timeout_debounce(li);
- /* spurious debouncing is on but the release should get flushed by
- * the other button */
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_RIGHT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_RIGHT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- END_TEST
- START_TEST(debounce_spurious_switch_to_otherbutton)
- {
- struct litest_device *dev = litest_current_device();
- struct libinput_device *device = dev->libinput_device;
- struct libinput *li = dev->libinput;
- if (!libinput_device_config_middle_emulation_is_available(device))
- return LITEST_NOT_APPLICABLE;
- litest_drain_events(li);
- debounce_trigger_spurious(dev, li);
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_timeout_debounce(li);
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- /* release is now held back,
- * other button should flush the release */
- litest_event(dev, EV_KEY, BTN_RIGHT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_RIGHT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- /* bouncing right button triggers debounce */
- litest_event(dev, EV_KEY, BTN_RIGHT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_RIGHT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
- litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_empty_queue(li);
- }
- END_TEST
- START_TEST(debounce_remove_device_button_up)
- {
- struct litest_device *dev;
- _litest_context_destroy_ struct libinput *li = litest_create_context();
- dev = litest_add_device(li, LITEST_MOUSE);
- litest_drain_events(li);
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_event(dev, EV_KEY, BTN_LEFT, 0);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- /* delete the device while the timer is still active */
- litest_device_destroy(dev);
- litest_timeout_debounce(li);
- }
- END_TEST
- START_TEST(debounce_remove_device_button_down)
- {
- struct litest_device *dev;
- _litest_context_destroy_ struct libinput *li = litest_create_context();
- dev = litest_add_device(li, LITEST_MOUSE);
- litest_drain_events(li);
- litest_event(dev, EV_KEY, BTN_LEFT, 1);
- litest_event(dev, EV_SYN, SYN_REPORT, 0);
- litest_dispatch(li);
- /* delete the device the timer is still active */
- litest_device_destroy(dev);
- litest_timeout_debounce(li);
- }
- END_TEST
- TEST_COLLECTION(pointer)
- {
- /* clang-format off */
- litest_add(pointer_motion_relative, LITEST_RELATIVE, LITEST_POINTINGSTICK);
- litest_add_for_device(pointer_motion_relative_zero, LITEST_MOUSE);
- litest_with_parameters(params,
- "direction", 'I', 8, litest_named_i32(N), litest_named_i32(NE),
- litest_named_i32(E), litest_named_i32(SE),
- litest_named_i32(S), litest_named_i32(SW),
- litest_named_i32(W), litest_named_i32(NW)) {
- litest_add_parametrized(pointer_motion_relative_min_decel, LITEST_RELATIVE, LITEST_POINTINGSTICK, params);
- }
- litest_add(pointer_motion_absolute, LITEST_ABSOLUTE, LITEST_ANY);
- litest_add(pointer_motion_unaccel, LITEST_RELATIVE, LITEST_ANY);
- litest_add(pointer_button, LITEST_BUTTON, LITEST_CLICKPAD);
- litest_add_no_device(pointer_button_auto_release);
- litest_add_no_device(pointer_seat_button_count);
- litest_add_for_device(pointer_button_has_no_button, LITEST_KEYBOARD);
- litest_add(pointer_recover_from_lost_button_count, LITEST_BUTTON, LITEST_CLICKPAD);
- litest_add(pointer_scroll_wheel, LITEST_WHEEL, LITEST_TABLET);
- litest_with_parameters(params, "axis", 'I', 2, litest_named_i32(REL_WHEEL_HI_RES, "vertical"),
- litest_named_i32(REL_HWHEEL_HI_RES, "horizontal")) {
- litest_add_parametrized(pointer_scroll_wheel_hires, LITEST_WHEEL, LITEST_TABLET, params);
- }
- litest_with_parameters(params, "axis", 'I', 2, litest_named_i32(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, "vertical"),
- litest_named_i32(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, "horizontal")) {
- litest_add_parametrized(pointer_scroll_wheel_hires_send_only_lores, LITEST_WHEEL, LITEST_TABLET, params);
- litest_add_parametrized_for_device(pointer_scroll_wheel_hires_disabled, LITEST_MOUSE_WHEEL_HIRES_DISABLED, params);
- }
- litest_with_parameters(params, "hires-delta", 'u', 3, 5, 15, 20) {
- litest_add_parametrized(pointer_scroll_wheel_inhibit_small_deltas, LITEST_WHEEL, LITEST_TABLET, params);
- litest_add_parametrized(pointer_scroll_wheel_inhibit_dir_change, LITEST_WHEEL, LITEST_TABLET, params);
- }
- litest_add(pointer_scroll_wheel_inhibit_small_deltas_reduce_delta, LITEST_WHEEL, LITEST_TABLET);
- litest_add_for_device(pointer_scroll_wheel_no_inhibit_small_deltas_when_virtual, LITEST_MOUSE_VIRTUAL);
- litest_add_for_device(pointer_scroll_wheel_lenovo_scrollpoint, LITEST_LENOVO_SCROLLPOINT);
- litest_add(pointer_scroll_button, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
- litest_add(pointer_scroll_button_noscroll, LITEST_ABSOLUTE|LITEST_BUTTON, LITEST_RELATIVE);
- litest_add(pointer_scroll_button_noscroll, LITEST_ANY, LITEST_RELATIVE|LITEST_BUTTON);
- litest_add(pointer_scroll_button_no_event_before_timeout, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
- litest_add(pointer_scroll_button_middle_emulation, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
- litest_add_no_device(pointer_scroll_button_device_remove_while_down);
- litest_add(pointer_scroll_button_lock, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
- litest_add(pointer_scroll_button_lock_defaults, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
- litest_add(pointer_scroll_button_lock_config, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
- litest_add(pointer_scroll_button_lock_enable_while_down, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
- litest_add(pointer_scroll_button_lock_enable_while_down_just_lock, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
- litest_add(pointer_scroll_button_lock_otherbutton, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
- litest_add(pointer_scroll_button_lock_enable_while_otherbutton_down, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
- litest_with_parameters(params, "buttonorder", 'I', 6, litest_named_i32(LLRR),
- litest_named_i32(LRLR),
- litest_named_i32(LRRL),
- litest_named_i32(RRLL),
- litest_named_i32(RLRL),
- litest_named_i32(RLLR)) {
- litest_add_parametrized(pointer_scroll_button_lock_middlebutton, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY, params);
- }
- litest_add(pointer_scroll_button_lock_doubleclick_nomove, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
- litest_add(pointer_scroll_button_lock_scroll_releases, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
- litest_add(pointer_scroll_button_lock_scroll_within_grace, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
- litest_add(pointer_scroll_button_lock_hold_no_move_still_locks, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
- litest_add(pointer_scroll_nowheel_defaults, LITEST_RELATIVE|LITEST_BUTTON, LITEST_WHEEL);
- litest_add_for_device(pointer_scroll_defaults_logitech_marble , LITEST_LOGITECH_TRACKBALL);
- litest_add(pointer_scroll_natural_defaults, LITEST_WHEEL, LITEST_TABLET);
- litest_add(pointer_scroll_natural_defaults_noscroll, LITEST_ANY, LITEST_WHEEL);
- litest_add(pointer_scroll_natural_enable_config, LITEST_WHEEL, LITEST_TABLET);
- litest_add(pointer_scroll_natural_wheel, LITEST_WHEEL, LITEST_TABLET);
- litest_add(pointer_scroll_has_axis_invalid, LITEST_WHEEL, LITEST_TABLET);
- litest_with_parameters(params, "angle", 'd', 18, 0.0, 20.0, 40.0, 60.0, 80.0, 100.0, 120.0, 140.0, 160.0,
- 180.0, 200.0, 220.0, 240.0, 260.0, 280.0, 300.0, 320.0, 340.0) {
- litest_add_parametrized(pointer_scroll_with_rotation, LITEST_WHEEL, LITEST_TABLET, params);
- }
- litest_add(pointer_no_calibration, LITEST_ANY, LITEST_TOUCH|LITEST_SINGLE_TOUCH|LITEST_ABSOLUTE|LITEST_PROTOCOL_A|LITEST_TABLET);
- /* tests touchpads too */
- litest_add(pointer_left_handed_defaults, LITEST_BUTTON, LITEST_ANY);
- litest_add(pointer_left_handed, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
- litest_add(pointer_left_handed_during_click, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
- litest_add(pointer_left_handed_during_click_multiple_buttons, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
- litest_add_no_device(pointer_left_handed_disable_with_button_down);
- litest_add(pointer_accel_defaults, LITEST_RELATIVE, LITEST_ANY);
- litest_add(pointer_accel_invalid, LITEST_RELATIVE, LITEST_ANY);
- litest_add(pointer_accel_defaults_absolute, LITEST_ABSOLUTE, LITEST_RELATIVE);
- litest_add(pointer_accel_defaults_absolute_relative, LITEST_ABSOLUTE|LITEST_RELATIVE, LITEST_ANY);
- litest_add(pointer_accel_direction_change, LITEST_RELATIVE, LITEST_POINTINGSTICK);
- litest_add(pointer_accel_profile_defaults, LITEST_RELATIVE, LITEST_TOUCHPAD);
- litest_add(pointer_accel_profile_defaults, LITEST_TOUCHPAD, LITEST_ANY);
- litest_add(pointer_accel_config_reset_to_defaults, LITEST_RELATIVE, LITEST_ANY);
- litest_add(pointer_accel_config, LITEST_RELATIVE, LITEST_ANY);
- litest_add(pointer_accel_profile_invalid, LITEST_RELATIVE, LITEST_ANY);
- litest_add(pointer_accel_profile_noaccel, LITEST_ANY, LITEST_TOUCHPAD|LITEST_RELATIVE|LITEST_TABLET);
- litest_add(pointer_accel_profile_flat_motion_relative, LITEST_RELATIVE, LITEST_TOUCHPAD);
- litest_add(middlebutton, LITEST_BUTTON, LITEST_CLICKPAD);
- litest_add(middlebutton_nostart_while_down, LITEST_BUTTON, LITEST_CLICKPAD);
- litest_add(middlebutton_timeout, LITEST_BUTTON, LITEST_CLICKPAD);
- litest_add(middlebutton_doubleclick, LITEST_BUTTON, LITEST_CLICKPAD);
- litest_add(middlebutton_middleclick, LITEST_BUTTON, LITEST_CLICKPAD);
- litest_add(middlebutton_middleclick_during, LITEST_BUTTON, LITEST_CLICKPAD);
- litest_add(middlebutton_default_enabled, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_POINTINGSTICK);
- litest_add(middlebutton_default_clickpad, LITEST_CLICKPAD, LITEST_ANY);
- litest_add(middlebutton_default_touchpad, LITEST_TOUCHPAD, LITEST_CLICKPAD);
- litest_add(middlebutton_default_disabled, LITEST_ANY, LITEST_BUTTON);
- litest_add_for_device(middlebutton_default_alps, LITEST_ALPS_SEMI_MT);
- litest_add(middlebutton_button_scrolling, LITEST_RELATIVE|LITEST_BUTTON, LITEST_CLICKPAD);
- litest_add(middlebutton_button_scrolling_middle, LITEST_RELATIVE|LITEST_BUTTON, LITEST_CLICKPAD);
- litest_add(middlebutton_device_remove_while_down, LITEST_BUTTON, LITEST_CLICKPAD);
- litest_add(middlebutton_device_remove_while_one_is_down, LITEST_BUTTON, LITEST_CLICKPAD);
- litest_with_parameters(params, "axis", 'I', 2, litest_named_i32(ABS_X), litest_named_i32(ABS_Y)) {
- litest_add_parametrized(pointer_absolute_initial_state, LITEST_ABSOLUTE, LITEST_ANY, params);
- }
- litest_add(pointer_time_usec, LITEST_RELATIVE, LITEST_ANY);
- litest_with_parameters(params, "button", 'I', 8, litest_named_i32(BTN_LEFT),
- litest_named_i32(BTN_RIGHT),
- litest_named_i32(BTN_MIDDLE),
- litest_named_i32(BTN_SIDE),
- litest_named_i32(BTN_EXTRA),
- litest_named_i32(BTN_FORWARD),
- litest_named_i32(BTN_BACK),
- litest_named_i32(BTN_TASK)) {
- litest_add_parametrized(debounce_bounce, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE, params);
- litest_add_parametrized(debounce_spurious, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE, params);
- /* Timing-sensitive test, valgrind is too slow */
- if (!RUNNING_ON_VALGRIND)
- litest_add_parametrized(debounce_bounce_high_delay, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE, params);
- }
- litest_add(debounce_bounce_check_immediate, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
- litest_add(debounce_spurious_multibounce, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
- if (!RUNNING_ON_VALGRIND)
- litest_add(debounce_spurious_trigger_high_delay, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
- litest_add(debounce_spurious_dont_enable_on_otherbutton, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
- litest_add(debounce_spurious_cancel_debounce_otherbutton, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
- litest_add(debounce_spurious_switch_to_otherbutton, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
- litest_add_no_device(debounce_remove_device_button_down);
- litest_add_no_device(debounce_remove_device_button_up);
- /* clang-format off */
- }
|