From: Martin Read Date: Sun, 30 Nov 2014 18:41:21 +0000 (+0000) Subject: Initial commit X-Git-Tag: v1.0.0~2 X-Git-Url: http://git.blackswordsonics.com/?a=commitdiff_plain;h=c732ecaf8f865e656f799d8773b10c9cbd88d513;p=keyrhythm Initial commit --- c732ecaf8f865e656f799d8773b10c9cbd88d513 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c81d16b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.mk diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..27aa60f --- /dev/null +++ b/MANIFEST @@ -0,0 +1,5 @@ +Makefile.in +configure +keyrhythm.c +keyrhythm.h +man/keyrhythm.1 diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..a25a9f0 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,128 @@ +#!/usr/bin/make -f +# +# Makefile skeleton +# +# Copyright © 2014 Martin Read +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include colophon.mk +include dirs.mk +include features.mk + +vpath %.o . + +GENERATED_MAKES:=dirs.mk features.mk colophon.mk Makefile +HANDWRITTEN_OBJS:=keyrhythm.o +MAIN_EXE_OBJS:=$(GENERATED_OBJS) $(HANDWRITTEN_OBJS) +MAJVERS:=1 +MINVERS:=0 +PATCHVERS:=0 +INCPATH:=-I$(srcdir) +DEFINES:=-DMAJVERS=$(MAJVERS) -DMINVERS=$(MINVERS) -DPATCHVERS=$(PATCHVERS) -D_FORTIFY_SOURCE=2 +COMMON_CFLAGS:=-Wall -Wwrite-strings -Wunreachable-code -Wformat -Wextra -Wno-unused-but-set-variable -Wno-unused-parameter -Wmissing-declarations -Wredundant-decls -Wdisabled-optimization -Werror=format-security -fstack-protector --param=ssp-buffer-size=4 -std=gnu11 $(DEFINES) $(INCPATH) +COMMON_CXXFLAGS:=-Wall -Wextra -Wwrite-strings -Wno-unused-but-set-variable -Wredundant-decls -Wdisabled-optimization -Wunreachable-code -Wundef -Wredundant-decls -Wmissing-declarations -Wno-unused -Wno-unused-parameter -Werror=format-security -fstack-protector --param=ssp-buffer-size=4 -std=gnu++11 $(DEFINES) $(INCPATH) +PRODUCTION_CFLAGS:=$(COMMON_CFLAGS) -O2 +DEVELOPMENT_CFLAGS:=$(COMMON_CFLAGS) -g -Werror +PRODUCTION_CXXFLAGS:=$(COMMON_CXXFLAGS) -O2 +DEVELOPMENT_CXXFLAGS:=$(COMMON_CXXFLAGS) -g -Werror +ARCHIVEDIR:=$(main_dirname)-$(MAJVERS).$(MINVERS).$(PATCHVERS) +ARCHIVENAME:=$(main_dirname)_$(MAJVERS).$(MINVERS).$(PATCHVERS) +COMMON_LDFLAGS:=-Wl,-z,relro +DEVELOPMENT_LDFLAGS:=$(COMMON_LDFLAGS) -g +SUBDIRS:=man + +## PHONY targets in this section, please + +.PHONY: all archive clean code-docs code-docs-clean debianize-archive install debworkflow debclean spotless distclean + +all: $(main_exename) + +archive: clean + mkdir $(ARCHIVEDIR) + for i in $(SUBDIRS) ; do mkdir -p $(ARCHIVEDIR)/"$$i" ; done + for i in `cat MANIFEST` ; do cp "$$i" $(ARCHIVEDIR)/"$$i" ; done + tar czf $(ARCHIVENAME).tar.gz $(ARCHIVEDIR) + rm -r $(ARCHIVEDIR) + +debianize-archive: archive + mv $(ARCHIVENAME).tar.gz $(ARCHIVENAME).orig.tar.gz + +debworkflow: debclean debianize-archive + mkdir archive-test + mv $(ARCHIVENAME).orig.tar.gz archive-test + (cd archive-test && tar xzf $(ARCHIVENAME).orig.tar.gz) + cp -R debian archive-test/$(ARCHIVEDIR)/debian + (cd archive-test/$(ARCHIVEDIR) && debuild -uc -us) + +debclean: + -rm -rf archive-test + +clean: + -rm -rf $(ARCHIVEDIR) + -rm -f *.o $(main_exename) *.tar.gz + +distclean: gitclean + +code-docs: + doxygen Doxyfile + +code-docs-clean: + -rm -rf html latex + +gitclean: spotless + -rm -rf $(GENERATED_MAKES) + +generated-clean: + -rm -f $(GENERATED_SOURCE) + +install: all + install -D $(main_exename) $(DESTDIR)$(bindir)/$(main_exename) + install -D $(srcdir)/man/$(main_exename).1 $(DESTDIR)$(man1dir)/$(main_exename).1 + +install-assets: + rm -r $(DESTDIR)$(datadir) + install -D genbitmaps/floor-tiles.png $(DESTDIR)$(datadir)/bitmaps/floor-tiles.png + install -D genbitmaps/unique-walls.png $(DESTDIR)$(datadir)/bitmaps/unique-walls.png + install -D genbitmaps/unique-walls.png $(DESTDIR)$(datadir)/bitmaps/unique-walls.png + install -D $(srcdir)/main_frag.glsl $(DESTDIR)$(datadir)/shaders/main_frag.glsl + install -D $(srcdir)/main_vert.glsl $(DESTDIR)$(datadir)/shaders/main_vert.glsl + +spotless: clean code-docs-clean debclean generated-clean + +## pattern rules + +%.o: $(srcdir)/%.cc + $(CXX) -c $(DEVELOPMENT_CXXFLAGS) $(CPPFLAGS) $(CXXFLAGS) $< -o $@ + +%.o: $(srcdir)/%.c + $(CC) -c $(DEVELOPMENT_CFLAGS) $(CPPFLAGS) $(CFLAGS) $< -o $@ + +## "real" targets + +$(main_exename): $(MAIN_EXE_OBJS) + $(CC) $(DEVELOPMENT_LDFLAGS) $(LDFLAGS) $(MAIN_EXE_OBJS) -o $(main_exename) + +## Build dependencies +keyrhythm.o: $(srcdir)/keyrhythm.c $(srcdir)/keyrhythm.h + +# vim:ts=8:sts=8:sw=8:noexpandtab diff --git a/configure b/configure new file mode 100755 index 0000000..9efbedf --- /dev/null +++ b/configure @@ -0,0 +1,201 @@ +#! /usr/bin/perl -w + +# Copyright © 2014 Martin Read +# +# 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 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. + +use strict; +use Getopt::Long; +use English; + +##### TODO move these into a configuration input file +our $main_title = "Keyrhythm"; +our $main_header = "keyrhythm.h"; +our $main_exename = "keyrhythm"; +our $main_dirname = "keyrhythm"; +##### + +# Prefixes +my $prefix='/usr/local'; +my $exec_prefix='$(prefix)'; + +# Bin and lib dirs +my $bindir='$(exec_prefix)/bin'; +my $sbindir='$(exec_prefix)/sbin'; +my $libdir='$(exec_prefix)/lib'; +my $libexecdir='$(exec_prefix)/libexec'; +my $gamesdir='$(prefix)/games'; +my $srcdir=undef; + +my $datarootdir='$(prefix)/share'; +my $datadir='$(datarootdir)/$(main_dirname)'; +my $sysconfdir='$(prefix)/etc'; +my $sharedstatedir='$(prefix)/com'; +my $localstatedir='$(prefix)/var'; + +my $includedir='$(prefix)/include'; +my $oldincludedir='/usr/include'; + +my $docdir='$(datarootdir)/doc/$(main_dirname)'; +my $htmldir='$(docdir)'; +my $dvidir='$(docdir)'; +my $pdfdir='$(docdir)'; +my $psdir='$(docdir)'; + +my $localedir='$(datarootdir)/locale'; + +my $infodir='$(datarootdir)/info'; + +my $mandir='$(datarootdir)/man'; +my $man1dir='$(mandir)/man1'; +my $man3dir='$(mandir)/man3'; +my $man5dir='$(mandir)/man5'; +my $man6dir='$(mandir)/man6'; +my $man7dir='$(mandir)/man7'; +my $man1ext='.1'; +my $man3ext='.3'; +my $man5ext='.5'; +my $man6ext='.6'; +my $man7ext='.7'; + +# feature control +my $disable_statics='false'; + +my $verbose=1; +GetOptions( +'prefix=s' => \$prefix, 'exec_prefix=s' => \$exec_prefix, +'bindir=s' => \$bindir, 'libdir=s' => \$libdir, +'srcdir=s' => \$srcdir, +'libexecdir=s' => \$libexecdir, 'gamesdir=s' => \$gamesdir, +'includedir=s' => \$includedir, 'oldincludedir=s' => \$oldincludedir, +'datarootdir=s' => \$datarootdir, 'datadir=s' => \$datadir, +'sysconfdir=s' => \$sysconfdir, 'sharedstatedir=s' => \$sharedstatedir, +'localstatedir=s' => \$localstatedir, 'localedir=s' => \$localedir, +'mandir=s' => \$mandir, +'man1dir=s' => \$man1dir, 'man3dir=s' => \$man3dir, +'man5dir=s' => \$man5dir, 'man6dir=s' => \$man6dir, +'man7dir=s' => \$man7ext, +'man1ext=s' => \$man1ext, 'man3ext=s' => \$man3ext, +'man5ext=s' => \$man5ext, 'man6ext=s' => \$man6ext, +'man7ext=s' => \$man7ext, +'docdir=s' => \$docdir, 'htmldir=s' => \$htmldir, +'dvidir=s' => \$dvidir, 'pdfdir=s' => \$pdfdir, +'psdir=s' => \$psdir, 'infodir=s' => \$infodir, +'verbose' => \$verbose, +'disable-statics' => sub { $disable_statics='true' }, +'quiet' => sub { $verbose = 0; } ); + +print STDOUT "Configuring ${main_title} build/install process...\n" if $verbose; + +my $cmdresults; +my $probably_in_main_dir = 0; + +if (!defined($srcdir)) +{ + # Heuristic check when srcdir undefined: If the main header file is here, + # srcdir should be "."; if the main header file is not here but is in the + # parent dir, srcdir should be "..". + if (-f "./${main_header}") + { + # We're probably in srcdir. + $srcdir = "." + } + elsif (-f "../${main_header}") + { + # We're probably in an immediate child of srcdir. + $srcdir = ".." + } + else + { + die "configure: couldn't identify location of source code. Please use --srcdir=/some/directory and try again\n"; + } +} +print STDOUT "Testing 'mkdir -p' ...\n" if $verbose; +rmdir "billy/bob"; +rmdir "billy"; +$cmdresults=`mkdir -p billy/bob 2>&1`; +if ($CHILD_ERROR != 0) { + print STDERR "configure: mkdir -p billy/bob failed\n"; + rmdir "billy"; + die "Please install a POSIX-compliant mkdir.\n"; +} +rmdir "billy/bob"; +rmdir "billy"; + +if ($includedir eq $oldincludedir) { $oldincludedir = ''; } + +print STDOUT "Writing dirs.mk...\n" if $verbose; +open(DIRS_MK, '>', "dirs.mk") or die $!; +print DIRS_MK "prefix:=${prefix}\n"; +print DIRS_MK "exec_prefix:=${exec_prefix}\n"; +print DIRS_MK "bindir:=${bindir}\n"; +print DIRS_MK "sbindir:=${sbindir}\n"; +print DIRS_MK "libdir:=${libdir}\n"; +print DIRS_MK "libexecdir:=${libexecdir}\n"; +print DIRS_MK "gamesdir:=${gamesdir}\n"; +print DIRS_MK "srcdir:=${srcdir}\n"; +print DIRS_MK "datarootdir:=${datarootdir}\n"; +print DIRS_MK "datadir:=${datadir}\n"; +print DIRS_MK "sysconfdir:=${sysconfdir}\n"; +print DIRS_MK "sharedstatedir:=${sharedstatedir}\n"; +print DIRS_MK "localstatedir:=${localstatedir}\n"; +print DIRS_MK "localedir:=${localedir}\n"; +print DIRS_MK "includedir:=${includedir}\n"; +print DIRS_MK "oldincludedir:=${oldincludedir}\n"; +print DIRS_MK "mandir:=${mandir}\n"; +print DIRS_MK "man1dir:=${man1dir}\n"; +print DIRS_MK "man3dir:=${man3dir}\n"; +print DIRS_MK "man5dir:=${man5dir}\n"; +print DIRS_MK "man6dir:=${man6dir}\n"; +print DIRS_MK "man7dir:=${man7dir}\n"; +print DIRS_MK "man1ext:=${man1ext}\n"; +print DIRS_MK "man3ext:=${man3ext}\n"; +print DIRS_MK "man5ext:=${man5ext}\n"; +print DIRS_MK "man6ext:=${man6ext}\n"; +print DIRS_MK "man7ext:=${man7ext}\n"; +print DIRS_MK "docdir:=${docdir}\n"; +print DIRS_MK "htmldir:=${htmldir}\n"; +print DIRS_MK "dvidir:=${dvidir}\n"; +print DIRS_MK "pdfdir:=${pdfdir}\n"; +print DIRS_MK "psdir:=${psdir}\n"; +print DIRS_MK "infodir:=${infodir}\n"; +close(DIRS_MK); + +print STDOUT "Writing features.mk...\n" if $verbose; +open(FEATURES_MK, '>', "features.mk") or die $!; +print FEATURES_MK "# This file is automatically generated by the configure script. Do not edit.\n"; +print FEATURES_MK "DISABLE_STATICS:=${disable_statics}\n"; +close(FEATURES_MK); + +print STDOUT "Writing colophon.mk...\n" if $verbose; +open(COLOPHON_MK, '>', "colophon.mk") or die $!; +print COLOPHON_MK "# This file is automatically generated by the configure script. Do not edit.\n"; +print COLOPHON_MK "main_header:=${main_header}\n"; +print COLOPHON_MK "main_exename:=${main_exename}\n"; +print COLOPHON_MK "main_dirname:=${main_dirname}\n"; +print COLOPHON_MK "main_title:=${main_title}\n"; +close COLOPHON_MK; + +open MAKEFILE_IN, "<", "${srcdir}/Makefile.in"; +my @makefile = ; +close MAKEFILE_IN; +print STDOUT "Writing Makefile...\n" if $verbose; +open MAKEFILE_OUT, ">", "./Makefile"; +print MAKEFILE_OUT @makefile; +close MAKEFILE_OUT; diff --git a/copyright b/copyright new file mode 100644 index 0000000..196dd6b --- /dev/null +++ b/copyright @@ -0,0 +1,20 @@ +Copyright © 2014 Martin Read + +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 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. + diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..cd2e878 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +keyrhythm (1.0.0-1) UNRELEASED; urgency=medium + + * Initial release. (Closes: #XXXXXX) + + -- Martin Read Sun, 30 Nov 2014 00:54:22 +0000 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..c0a6a74 --- /dev/null +++ b/debian/control @@ -0,0 +1,16 @@ +Source: keyrhythm +Maintainer: Martin Read +Section: misc +Priority: optional +Standards-Version: 3.9.6 +Build-Depends: debhelper (>= 9) + +Package: keyrhythm +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Suggests: csound +Description: keyboard input timing recorder + keyrhythm records the timing of the user's alphanumeric keystrokes; the + author envisages it as a useful tool for generating rhythm timings to put + into a Csound score file, hence the name. + diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..196dd6b --- /dev/null +++ b/debian/copyright @@ -0,0 +1,20 @@ +Copyright © 2014 Martin Read + +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 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. + diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..78c7615 --- /dev/null +++ b/debian/rules @@ -0,0 +1,3 @@ +#! /usr/bin/make -f +%: + dh $@ diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/keyrhythm.c b/keyrhythm.c new file mode 100644 index 0000000..5927b10 --- /dev/null +++ b/keyrhythm.c @@ -0,0 +1,136 @@ +/*! \file keyrhythm.cc + * \brief main source file for Keyrhythm + */ + +/* Copyright © 2014 Martin Read + * + * 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 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *outfile_name = NULL; +FILE *outfp; + +struct option options[] = +{ + { + "output-file", + required_argument, + NULL, + 'o' + }, + { + NULL, + no_argument, + NULL, + 0 + } +}; + +volatile bool quitflag = false; + +static void sigint_catcher(int unused) +{ + quitflag = true; +} + +int main(int argc, char *argv[]) +{ + int i; + if (!isatty(0)) + { + fprintf(stderr, "keyrhythm: stdin is not a terminal\n"); + exit(1); + } + do + { + i = getopt_long(argc, argv, "o:", options, NULL); + switch (i) + { + case -1: + break; + case 'o': + outfile_name = strdup(optarg); + break; + default: + fprintf(stderr, "keyrhythm: unrecognized command-line option\n"); + exit(1); + } + } while (i != -1); + if (outfile_name == NULL) + { + outfile_name = strdup("keyrhythm.out"); + } + puts("Keyrhythm recording. Press Ctrl-C to finish."); + outfp = fopen(outfile_name, "w"); + struct termios ti_orig; + struct termios ti_new; + memset(&ti_orig, '\0', sizeof ti_orig); + tcgetattr(0, &ti_orig); + memcpy(&ti_new, &ti_orig, sizeof ti_orig); + ti_new.c_lflag &= ~(ICANON | ECHO); + tcsetattr(0, TCSANOW, &ti_new); + struct sigaction sa; + sa.sa_handler = sigint_catcher; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_restorer = NULL; + sigaction(SIGINT, &sa, NULL); + struct timeval launch_tv; + bool started = false; + do + { + int i; + struct timeval tv; + i = getchar(); + if (i > 0) + { + gettimeofday(&tv, NULL); + if (isascii(i) && isalnum(i)) + { + if (!started) + { + launch_tv = tv; + started = true; + } + unsigned long long secdiff; + + unsigned long long usecdiff; + secdiff = tv.tv_sec - launch_tv.tv_sec; + usecdiff = secdiff * 1000000ull + tv.tv_usec - launch_tv.tv_usec; + fprintf(outfp, "%c %llu.%06llu\n", i, usecdiff / 1000000ull, usecdiff % 1000000ull); + } + } + } while (!quitflag); + tcsetattr(0, TCSANOW, &ti_orig); + fclose(outfp); + puts("Done."); + return 0; +} + +/* keyrhythm.cc */ diff --git a/keyrhythm.h b/keyrhythm.h new file mode 100644 index 0000000..df7af9a --- /dev/null +++ b/keyrhythm.h @@ -0,0 +1,25 @@ +/*! \file keyrhythm.hh + * \brief common header for Keyrhythm + */ + +/* Copyright © 2014 Martin Read + * + * 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 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. */ + + diff --git a/man/keyrhythm.1 b/man/keyrhythm.1 new file mode 100644 index 0000000..2763e44 --- /dev/null +++ b/man/keyrhythm.1 @@ -0,0 +1,21 @@ +.TH KEYRHYTHM 1 "November 30, 2014" "Keyrhythm Version 1.0.0" "Keyrhythm User Manual" +.SH NAME +keyrhythm \- a keyboard timing recorder +.SH SYNOPSIS +keyrhythm [-o NAME] + +.SH DESCRIPTION +.I keyrhythm +records the timing of incoming alphanumeric keystrokes relative to the time at +which the program starts. + +.TP +\fB-o\fR, \fB\-\-output\fR=\fINAME\fR +record timings to this file (the default is "keyrhythm.out") + +.SH BUGS + +None identified yet. + +.SH AUTHOR +Martin Read