10 Commits

Author SHA1 Message Date
Johannes Maibaum
2f5b69c021 [WIP] Allow building with GTK+ 3.16+.
Set CMake option `ENABLE_GTK3` to `ON` to build with GTK+ 3.0.

In GTK3 mode:

- Use `GtkGrid` instead of `GtkTable`
- Don't use `GtkMisc` to set `GtkLabel`'s alignments
- `PianoKeyboard`'s draw() code still needs to be refactored (doesn't
  show key presses).
- Grab keyboard functionality still needs to be ported (doesn't work
  yet).
2016-09-18 16:33:36 +02:00
Johannes Maibaum
44980fc2f5 Replace deprecated gtk_type_new with g_object_new. 2016-09-17 12:24:48 +02:00
Johannes Maibaum
c1fe0e7c15 sustain_event_handler listens to toggled signal.
This removes the deprecated calls to gtk_button_{pressed,released}.
2016-09-17 12:01:47 +02:00
Johannes Maibaum
f57e31dba5 Fix GSEAL_ENABLE errors for src/pianokeyboard.c. 2016-09-11 21:15:13 +02:00
Johannes Maibaum
6d5bbaca0a Use cairo for drawing. 2016-09-11 20:03:56 +02:00
Johannes Maibaum
2bd9ca2b9b Fix GSEAL_ENABLE errors for src/jack-keyboard.c. 2016-09-11 20:03:48 +02:00
Johannes Maibaum
2f4bdf615b Let GDK and GTK+ report deprecated stuff. 2016-09-11 20:03:41 +02:00
Johannes Maibaum
884ded8b95 Replace GDK_<keyname> with GDK_KEY_<keyname>. 2016-09-11 20:03:05 +02:00
Johannes Maibaum
0941f4abaa Remove calls to deprecated GLib functions.
GLib 2.32 (released in March 2012) deprecated `g_atexit()` [1] and
`g_thread_init()` [2].

[1]: https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-atexit
[2]: https://developer.gnome.org/glib/stable/glib-Threads.html
2016-09-11 20:03:00 +02:00
Johannes Maibaum
bb80fe24b2 Remove trailing whitespace. 2016-09-11 20:02:53 +02:00
21 changed files with 609 additions and 964 deletions

21
.gitignore vendored
View File

@@ -1,21 +0,0 @@
*.[oa]
Makefile.in
Makefile
config.h
/build
/man/Makefile.in
/pixmaps/Makefile.in
/src/Makefile.in
/src/.deps/
/src/jack-keyboard
stamp-h1
config.h.in
config.log
config.status
configure
depcomp
install-sh
missing
aclocal.m4
autom4te.cache
compile

View File

@@ -2,5 +2,3 @@ Edward Tomasz Napierała <trasz@FreeBSD.org>
Hans Petter Selasky <hselasky@FreeBSD.org>
Jeff Snyder <jeff@caffeinated.me.uk>
Dan Muresan <danmbox@gmail.com>
Markus Schmidt <schmidt@boomshop.net>
AlkorZ3 <alkorz2@rx3.net>

91
CMakeLists.txt Normal file
View File

@@ -0,0 +1,91 @@
#
# Copyright (c) 2011 Hans Petter Selasky. All rights reserved.
#
# 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
#
#
# Makefile for Jack Keyboard
#
cmake_minimum_required(VERSION 2.8)
option(ENABLE_GTK2 "Enable GTK2 Version" ON)
option(ENABLE_GTK3 "Enable GTK3 Version" OFF)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/")
set(VERSION "2.7.2")
set(JackEnable ON CACHE BOOL "Enable support for Jack")
set(LashEnable ON CACHE BOOL "Enable support for Lash")
set(X11Enable ON CACHE BOOL "Enable support for X11")
project(jack-keyboard)
add_executable(jack-keyboard src/jack-keyboard src/pianokeyboard)
find_package(PkgConfig REQUIRED)
if(ENABLE_GTK3)
set(ENABLE_GTK2 OFF)
PKG_CHECK_MODULES(GTK3 "gtk+-3.0 >= 3.16" REQUIRED)
include_directories(${GTK3_INCLUDE_DIRS})
target_link_libraries(jack-keyboard ${GTK3_LIBRARIES})
endif()
if(ENABLE_GTK2)
PKG_CHECK_MODULES(GTK2 "gtk+-2.0 >= 2.20" REQUIRED)
include_directories(${GTK2_INCLUDE_DIRS})
target_link_libraries(jack-keyboard ${GTK2_LIBRARIES})
endif()
# In preparation for GTK+3:
# Set GDK/GTK+ flags to report deprecated includes and symbols.
set(GTK_DEPRECATED_FLAGS "-DGTK_DISABLE_SINGLE_INCLUDES \
-DGDK_DISABLE_DEPRECATED \
-DGTK_DISABLE_DEPRECATED \
-DGSEAL_ENABLE")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GTK_DEPRECATED_FLAGS}")
if(JackEnable)
find_package(JACK)
include_directories(${JACK_INCLUDE_DIR})
target_link_libraries(jack-keyboard ${JACK_LIBRARIES})
add_definitions(-DHAVE_JACK=1)
endif()
if(LashEnable)
find_package(LASH)
include_directories(${LASH_INCLUDE_DIR})
target_link_libraries(jack-keyboard ${LASH_LIBRARIES})
add_definitions(-DHAVE_LASH=1)
endif()
if(X11Enable)
find_package(X11)
include_directories(${X11_INCLUDE_DIR})
target_link_libraries(jack-keyboard ${X11_LIBRARIES})
add_definitions(-DHAVE_X11=1)
endif()
install(TARGETS jack-keyboard RUNTIME DESTINATION bin)
install(FILES pixmaps/jack-keyboard.png DESTINATION share/pixmaps)
install(FILES src/jack-keyboard.desktop DESTINATION share/applications)
install(FILES man/jack-keyboard.1 DESTINATION man/man1)

48
Makefile Normal file
View File

@@ -0,0 +1,48 @@
VERSION?=2.7.2
help:
@echo "Targets: configure all clean install package"
configure:
rm -rf build
mkdir build
cd build ; cmake ..
all:
make -C build all
install:
make -C build install
clean:
make -C build clean
package:
make -C build clean || echo -n
tar -cvf temp.tar --exclude="*~" --exclude="*#" \
--exclude=".svn" --exclude="*.orig" --exclude="*.rej" \
AUTHORS \
CMakeLists.txt \
COPYING \
Makefile \
NEWS \
README \
TODO \
cmake \
man \
pixmaps \
src
rm -rf jack-keyboard-${VERSION}
mkdir jack-keyboard-${VERSION}
tar -xvf temp.tar -C jack-keyboard-${VERSION}
rm -rf temp.tar
tar -zcvf jack-keyboard-${VERSION}.tar.gz jack-keyboard-${VERSION}

View File

@@ -1,2 +0,0 @@
SUBDIRS = src man pixmaps

3
NEWS
View File

@@ -1,6 +1,3 @@
User-visible changes between 2.7.2 and 2.8.0 include:
- Drop CMake and now use autotools
User-visible changes between 2.7.1 and 2.7.2 include:
User-visible changes between 2.6 and 2.7.1 include:

5
README
View File

@@ -15,9 +15,8 @@ If you're using FreeBSD, install from ports - audio/jack-keyboard.
Otherwise, you need JACK with MIDI support, gtk+ 2.6 or higher,
make(1), gcc and all the standard headers. Untar the file, type
'make install' and that's it.
If Makefile is not present, you can generate it with:
aclocal && autoheader && automake --add-missing && autoconf && ./configure
'make install' and that's it. If there is any problem, drop me
an email (trasz@FreeBSD.org) and I will help you. Really.
How to use it?
--------------

128
README.md
View File

@@ -1,128 +0,0 @@
# jack-keyboard
![Screenshot of jack-keyboard](jack_keyboard.png)
## What is it?
jack-keyboard is a virtual MIDI keyboard - a program that allows you to
send JACK MIDI events (play ;-) using your PC keyboard. It's somewhat
similar to vkeybd, except it uses JACK MIDI instead of ALSA, and the
keyboard mapping is much better - it uses the same layout as trackers
(like Impulse Tracker) did, so you have two and half octaves under your
fingers.
## How to compile it?
If you're using FreeBSD, install from ports - audio/jack-keyboard.
Otherwise, you need JACK with MIDI support, gtk+ 2.6 or higher,
make(1), gcc and all the standard headers. Untar the file, type
'make install' and that's it.
If Makefile is not present, you can generate it with:
aclocal && autoheader && automake --add-missing && autoconf && ./configure
## How to use it?
You need JACK with MIDI support and some softsynth that accepts
JACK MIDI as input. Ghostess, http://home.jps.net/~musound/,
is a good choice. Of course you will also need some DSSI plugin
that will make the actual sound. WhySynth is nice.
When you have all of these installed: first, run jackd. Then run
ghostess with a plugin of choice. Then run jack-keyboard. Press
'z' key. You should hear sound.
## Keyboard
Keyboard mapping is the same as in Impulse Tracker. This is your
QWERTY keyboard:
+----+----+ +----+----+----+ +----+----+
| 2 | 3 | | 5 | 6 | 7 | | 9 | 0 |
+----+----+----+----+----+----+----+----+----+----+
| q | w | e | r | t | y | u | i | o | p |
+----+----+----+----+----+----+----+----+----+----+
| s | d | | g | h | j |
+----+----+----+----+----+----+----+
| z | x | c | v | b | n | m |
+----+----+----+----+----+----+----+
And this is MIDI mapping.
+----+----+ +----+----+----+ +----+----+
|C#5 |D#5 | |F#5 |G#5 |A#5 | |C#6 |D#6 |
+----+----+----+----+----+----+----+----+----+----+
| C5 | D5 | E5 | F5 | G5 | A5 | B5 | C6 | D6 | E6 |
+----+----+----+----+----+----+----+----+----+----+
|C#4 |D#4 | |F#4 |G#4 |A#4 |
+----+----+----+----+----+----+----+
| C4 | D4 | E4 | F4 | G4 | A4 | B4 |
+----+----+----+----+----+----+----+
Spacebar is a sustain key. Holding it when pressing or releasing key
will make that key sustained, i.e. Note Off MIDI event won't be sent
after releasing the key. To release (stop) all the sustained notes,
press and release spacebar.
Holding Shift when pressing note will make it louder (it increases
velocity). Holding Ctrl will do the opposite. You can change the
default velocity by moving the Velocity slider. You can change the
"high" and "low" velocity values by moving the slider while holding
Shift or Ctrl keys.
Pressing "-" and "+" keys on numeric keypad changes the octave your
keyboard is mapped to. Pressing "*" and "/" on numeric keypad changes
MIDI program (instrument). Pressing Insert or Delete keys will connect
jack-keyboard to the next/previous MIDI input port (it will cycle
between running instances of ghostess, for example). Home and End keys
change the MIDI channel. Page Up and Page Down keys switch the MIDI
bank.
Esc works as a panic key - when you press it, all sound stops.
## Setting channel/bank/program number directly
To switch directly to a channel, bank or program, enter its number on
the numeric keypad (it won't be shown in any way) and press Home or End
(to change channel), Page Up or Page Down (to change bank) or "/" or
"*" (to change program). For example, to change to program number 123,
type, on the numeric keypad, "123/", without quotes.
## Titlebar
When -G xor -T is given, some informational messages in the title bar
appear. They are supposed to be self explanatory. If you see
"bank/program change not sent", it means that the bank/program numbers
as seen in the title bar were not sent. In other words, synth the
jack-keyboard is connected to may use different values. This happens
at startup and after switching between synths (using Insert/Delete
keys). To send bank/program change at startup, use -b and -p parame-
ters. To automatically send bank/program change after reconnect, use
the -u option.
## Pianola mode
In addition to the MIDI output port, jack-keyboard also opens MIDI
input (listening) port. MIDI events going into this port will be
passed to the output port unmodified, except for channel number, which
will be set to the one jack-keyboard is configured to use. Note On and
Note Off MIDI events will cause visible effect (pressing and releasing)
on keys, just like if they were being pressed using keyboard or mouse.
jack-keyboard will never connect to it's own MIDI input port. It will
also refuse to connect to any other client whose name begins in "jack-
keyboard", unless the "-k" option is given. It is, however, possible
to connect these ports manually, using jack_connect or qjackctl; this
may create feedback loop.
## License
JACK Keyboard is distributed under the BSD license, two clause.
## Contact
If you have any questions, comments, suggestions, patches or anything,
let us know:
* Edward Tomasz Napierala <trasz@FreeBSD.org> (initial version)
* Hans Petter Selasky <hselasky@FreeBSD.org> (further development, gtk3)
* Markus Schmidt <schmidt@boomshop.net> (further development, UX/UI)

2
TODO
View File

@@ -1,5 +1,7 @@
Things to do, eventually:
- I know nothing about designing GUIs, and I'm afraid it shows. Redesign.
- Jack-keyboard does strange things to input focus and keyboard event
handling. Verify that it does not cause any problems.

28
cmake/FindJACK.cmake Normal file
View File

@@ -0,0 +1,28 @@
# - Try to find Jack library
# Once done this will define:
# JACK_FOUND - system has JACK
# JACK_INCLUDE_DIR - incude paths to use
# JACK_LIBRARIES - Link these to use
SET(JACK_FOUND 0)
FIND_PATH(JACK_INCLUDE_DIR jack/ringbuffer.h
/usr/local/include
/usr/include
)
FIND_LIBRARY(JACK_LIBRARIES jack
/usr/local/lib
/usr/lib
)
# handle the QUIETLY and REQUIRED arguments and set JACK_FOUND to TRUE
# if all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(JACK DEFAULT_MSG JACK_LIBRARIES JACK_INCLUDE_DIR)
MARK_AS_ADVANCED(
JACK_INCLUDE_DIR
JACK_LIBRARIES
)

27
cmake/FindLASH.cmake Normal file
View File

@@ -0,0 +1,27 @@
# - Try to find Lash library
# Once done this will define:
# LASH_FOUND - system has LASH
# LASH_INCLUDE_DIR - incude paths to use
# LASH_LIBRARIES - Link these to use
SET(LASH_FOUND 0)
FIND_PATH(LASH_INCLUDE_DIR lash/lash.h
/usr/local/include/lash-1.0
/usr/include/lash-1.0
)
FIND_LIBRARY(LASH_LIBRARIES lash
/usr/local/lib
/usr/lib
)
# handle the QUIETLY and REQUIRED arguments and set LASH_FOUND to TRUE
# if all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LASH DEFAULT_MSG LASH_LIBRARIES LASH_INCLUDE_DIR)
MARK_AS_ADVANCED(
LASH_INCLUDE_DIR
LASH_LIBRARIES
)

View File

@@ -1,81 +0,0 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
AC_INIT([jack-keyboard], [2.8], [alkorz3@rx3.net])
AM_INIT_AUTOMAKE([-Wall foreign])
AC_CONFIG_SRCDIR([config.h.in])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([stdlib.h string.h sys/time.h unistd.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_HEADER_TIME
AC_C_VOLATILE
# Checks for library functions.
AC_FUNC_MALLOC
AC_FUNC_STRTOD
AC_CHECK_FUNCS([gettimeofday memset strcasecmp strdup])
PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.2)
AC_SUBST(GTK_CFLAGS)
AC_SUBST(GTK_LIBS)
PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.2)
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.2)
AC_SUBST(GTHREAD_CFLAGS)
AC_SUBST(GTHREAD_LIBS)
AC_ARG_WITH([x11],
[AS_HELP_STRING([--with-x11],
[support keyboard grabbing @<:@default=check@:>@])],
[],
[with_x11=check])
AS_IF([test "x$with_x11" != xno],
[PKG_CHECK_MODULES(X11, x11, AC_DEFINE([HAVE_X11], [], [Defined if we have X11 support.]),
[if test "x$with_x11" != xcheck; then
AC_MSG_FAILURE([--with-x11 was given, but x11 was not found])
fi
])])
AC_SUBST(X11_CFLAGS)
AC_SUBST(X11_LIBS)
PKG_CHECK_MODULES(JACK, jack >= 0.102.0)
AC_SUBST(JACK_CFLAGS)
AC_SUBST(JACK_LIBS)
PKG_CHECK_MODULES(JACK_MIDI_NEEDS_NFRAMES, jack < 0.105.00, AC_DEFINE(JACK_MIDI_NEEDS_NFRAMES, 1, [whether or not JACK routines need nframes parameter]), true)
AC_ARG_WITH([lash],
[AS_HELP_STRING([--with-lash],
[support LASH @<:@default=check@:>@])],
[],
[with_lash=check])
AS_IF([test "x$with_lash" != xno],
[PKG_CHECK_MODULES(LASH, lash-1.0, AC_DEFINE([HAVE_LASH], [], [Defined if we have LASH support.]),
[if test "x$with_lash" != xcheck; then
AC_MSG_FAILURE([--with-lash was given, but LASH was not found])
fi
])])
AC_SUBST(LASH_CFLAGS)
AC_SUBST(LASH_LIBS)
AC_CONFIG_FILES([Makefile src/Makefile man/Makefile pixmaps/Makefile])
AC_OUTPUT

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -1,4 +0,0 @@
man_MANS = jack-keyboard.1
EXTRA_DIST = $(man_MANS)

View File

@@ -1,17 +0,0 @@
pixmapsdir = $(datadir)/pixmaps
pixmaps_DATA = jack-keyboard.png
EXTRA_DIST = $(pixmaps_DATA)
gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
install-data-hook: update-icon-cache
uninstall-hook: update-icon-cache
update-icon-cache:
@-if test -z "$(DESTDIR)"; then \
echo "Updating Gtk icon cache."; \
$(gtk_update_icon_cache); \
else \
echo "*** Icon cache not updated. After (un)install, run this:"; \
echo "*** $(gtk_update_icon_cache)"; \
fi

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 161 B

View File

@@ -1,205 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="256"
height="256"
viewBox="0 0 256 256"
id="svg2"
version="1.1"
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
sodipodi:docname="jack-keyboard.svg"
inkscape:export-filename="/home/markus/Programmierung/jack-keyboard/pixmaps/jack-keyboard.png"
inkscape:export-xdpi="48"
inkscape:export-ydpi="48">
<defs
id="defs">
<linearGradient
inkscape:collect="always"
id="linearGradient932">
<stop
style="stop-color:#ffffff;stop-opacity:0.38283062"
offset="0"
id="stop928" />
<stop
style="stop-color:#ffffff;stop-opacity:1"
offset="1"
id="stop930" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient918">
<stop
style="stop-color:#ffffff;stop-opacity:0.07656612"
offset="0"
id="stop914" />
<stop
id="stop926"
offset="0.13388273"
style="stop-color:#ffffff;stop-opacity:0.66473317" />
<stop
id="stop922"
offset="0.46153846"
style="stop-color:#ffffff;stop-opacity:0.45011601" />
<stop
style="stop-color:#ffffff;stop-opacity:0.29234338"
offset="0.46153846"
id="stop924" />
<stop
style="stop-color:#ffffff;stop-opacity:0.23433875"
offset="1"
id="stop916" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient901">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop897" />
<stop
id="stop905"
offset="0.11764706"
style="stop-color:#4f4f4f;stop-opacity:1" />
<stop
style="stop-color:#000000;stop-opacity:1"
offset="1"
id="stop899" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient828">
<stop
style="stop-color:#6f6f5d;stop-opacity:1"
offset="0"
id="stop824" />
<stop
id="stop832"
offset="0.125"
style="stop-color:#fbfbfb;stop-opacity:1" />
<stop
style="stop-color:#d7d6b6;stop-opacity:1"
offset="1"
id="stop826" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient828"
id="linearGradient830"
x1="128"
y1="0"
x2="128"
y2="256"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient901"
id="linearGradient903"
x1="128"
y1="0"
x2="128"
y2="136"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient918"
id="linearGradient920"
x1="128"
y1="0"
x2="128"
y2="104"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient932"
id="linearGradient934"
x1="8"
y1="0"
x2="8"
y2="80"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.44097686"
inkscape:cx="685.32502"
inkscape:cy="-202.20348"
inkscape:document-units="px"
inkscape:current-layer="svg2"
showgrid="true"
units="px"
inkscape:window-width="2880"
inkscape:window-height="1553"
inkscape:window-x="0"
inkscape:window-y="41"
inkscape:window-maximized="1"
inkscape:snap-bbox="true"
inkscape:bbox-nodes="true"
inkscape:object-paths="true"
inkscape:object-nodes="true"
inkscape:snap-smooth-nodes="true"
inkscape:snap-object-midpoints="true"
inkscape:snap-center="true"
inkscape:snap-others="false"
showborder="false">
<inkscape:grid
type="xygrid"
id="grid1"
empspacing="8"
visible="false" />
</sodipodi:namedview>
<metadata
id="metadata">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1" />
<rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient830);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.51181102;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect816"
width="256"
height="256"
x="0"
y="0" />
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.921;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient934);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.51181102;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="M 0 0 L 0 256 L 4 256 L 4 0 L 0 0 z M 64 0 L 64 256 L 68 256 L 68 0 L 64 0 z M 128 0 L 128 256 L 132 256 L 132 0 L 128 0 z M 192 0 L 192 256 L 196 256 L 196 0 L 192 0 z "
id="rect818" />
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.51300001;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.51181102;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 60,0 v 256 h 4 V 0 Z m 64,0 v 256 h 4 V 0 Z m 64,0 v 256 h 4 V 0 Z"
id="rect834"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccccccc" />
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient903);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5118109;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="M 40 0 L 40 136 L 88 136 L 88 0 L 40 0 z M 104 0 L 104 136 L 152 136 L 152 0 L 104 0 z M 168 0 L 168 136 L 216 136 L 216 0 L 168 0 z "
id="rect820" />
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient920);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.51181102;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="M 48 0 L 48 104 L 80 104 L 80 0 L 48 0 z M 112 0 L 112 104 L 144 104 L 144 0 L 112 0 z M 176 0 L 176 104 L 208 104 L 208 0 L 176 0 z "
id="rect907" />
</svg>

Before

Width:  |  Height:  |  Size: 8.8 KiB

View File

@@ -1,10 +0,0 @@
bin_PROGRAMS = jack-keyboard
jack_keyboard_SOURCES = jack-keyboard.c pianokeyboard.c pianokeyboard.h
jack_keyboard_LDADD = $(GTK_LIBS) $(GLIB_LIBS) $(GTHREAD_LIBS) $(X11_LIBS) $(JACK_LIBS) $(LASH_LIBS)
jack_keyboard_CFLAGS = $(GTK_CFLAGS) $(GLIB_CFLAGS) $(GTHREAD_CFLAGS) $(X11_CFLAGS) $(JACK_CFLAGS) $(LASH_CFLAGS) \
-DG_LOG_DOMAIN=\"jack-keyboard\"
desktopdir = $(datadir)/applications
desktop_DATA = jack-keyboard.desktop
EXTRA_DIST = $(desktop_DATA)

View File

@@ -67,15 +67,6 @@
#define VELOCITY_LOW 32
#define VELOCITY_MIN 1
#define MOD_MIN 0
#define MOD_MAX 127
#define MOD_INIT 0
#define PITCH_MIN -100
#define PITCH_MAX 100
#define PITCH_INIT 0
#define PITCH_RANGE 8192
#define OUTPUT_PORT_NAME "midi_out"
#define INPUT_PORT_NAME "midi_in"
#define PACKAGE_NAME "jack-keyboard"
@@ -109,15 +100,13 @@ lash_client_t *lash_client;
#define MIDI_NOTE_OFF 0x80
#define MIDI_PROGRAM_CHANGE 0xC0
#define MIDI_CONTROLLER 0xB0
#define MIDI_PITCH 0xE0
#define MIDI_RESET 0xFF
#define MIDI_RESET 0xFF
#define MIDI_HOLD_PEDAL 64
#define MIDI_ALL_SOUND_OFF 120
#define MIDI_ALL_MIDI_CONTROLLERS_OFF 121
#define MIDI_ALL_NOTES_OFF 123
#define MIDI_BANK_SELECT_MSB 0
#define MIDI_BANK_SELECT_LSB 32
#define MIDI_MOD_CC 1
#define BANK_MIN 0
#define BANK_MAX 127
@@ -126,58 +115,8 @@ lash_client_t *lash_client;
#define CHANNEL_MIN 1
#define CHANNEL_MAX 16
const char *rc_style = "style \"default\"\n"
"{\n"
" xthickness = 3\n"
" ythickness = 2\n"
" fg[NORMAL] = \"#fff\"\n"
" fg[PRELIGHT] = \"#fff\"\n"
" fg[ACTIVE] = \"#fff\"\n"
" fg[SELECTED] = \"#fff\"\n"
" fg[INSENSITIVE] = \"#aaa\"\n"
" bg[NORMAL] = \"#222\"\n"
" bg[PRELIGHT] = \"#444\"\n"
" bg[ACTIVE] = \"#222\"\n"
" bg[SELECTED] = \"#0af\"\n"
" bg[INSENSITIVE] = \"#666\"\n"
" base[NORMAL] = \"#000\"\n"
" base[PRELIGHT] = \"#444\"\n"
" base[ACTIVE] = \"#444\"\n"
" base[SELECTED] = \"#444\"\n"
" base[INSENSITIVE] = \"#333\"\n"
" text[NORMAL] = \"#fff\"\n"
" text[PRELIGHT] = \"#fff\"\n"
" text[ACTIVE] = \"#f80\"\n"
" text[SELECTED] = \"#f80\"\n"
" text[INSENSITIVE] = \"#666\"\n"
"}\n"
"style \"button\"\n"
"{\n"
" fg[NORMAL] = \"#fff\"\n"
" bg[NORMAL] = \"#000\"\n"
" bg[PRELIGHT] = \"#333\"\n"
" bg[ACTIVE] = \"#444\"\n"
" bg[INSENSITIVE] = \"#222\"\n"
"}\n"
"style \"scale\"\n"
"{\n"
" bg[NORMAL] = \"#555\"\n"
" bg[PRELIGHT] = \"#000\"\n"
" bg[ACTIVE] = \"#000\"\n"
" bg[INSENSITIVE] = \"#333\"\n"
"}\n"
"style \"label\"\n"
"{\n"
" fg[NORMAL] = \"#aaa\"\n"
"}\n"
"widget \"*\" style : rc \"default\"\n"
"widget_class\"*Gtk*Scale*\" style : highest \"scale\"\n"
"widget_class\"*GtkLabel*\" style : highest \"label\"\n"
"widget_class\"*GtkButton*\" style : highest \"button\"\n"
"widget_class\"*GtkToggle*\" style : highest \"button\"\n";
GtkWidget *window, *sustain_button, *channel_spin, *bank_spin, *program_spin, *connected_to_combo,
*velocity_scale, *grab_keyboard_checkbutton, *octave_spin, *mod_scale, *pitch_scale, *panic_button;
*velocity_hscale, *grab_keyboard_checkbutton, *octave_spin;
PianoKeyboard *keyboard;
GtkListStore *connected_to_store;
@@ -213,7 +152,7 @@ int channel = 0;
void draw_note(int key);
void queue_message(struct MidiMessage *ev);
double
double
get_time(void)
{
double seconds;
@@ -279,7 +218,7 @@ process_received_message_async(gpointer evp)
if (ev->data[2] == 0)
piano_keyboard_set_note_off(keyboard, ev->data[1]);
else
piano_keyboard_set_note_on(keyboard, ev->data[1], ev->data[2]);
piano_keyboard_set_note_on(keyboard, ev->data[1]);
}
if (b0 == MIDI_NOTE_OFF) {
@@ -317,7 +256,7 @@ warning_async(gpointer s)
{
const char *str = (const char *)s;
g_warning("%s",str);
g_warning(str);
return (FALSE);
}
@@ -460,7 +399,7 @@ process_midi_output(jack_nframes_t nframes)
}
}
int
int
process_callback(jack_nframes_t nframes, void *notused)
{
#ifdef MEASURE_TIME
@@ -501,7 +440,7 @@ queue_message(struct MidiMessage *ev)
g_warning("jack_ringbuffer_write failed, NOTE LOST.");
}
void
void
queue_new_message(int b0, int b1, int b2)
{
struct MidiMessage ev;
@@ -585,7 +524,7 @@ update_connected_to_combo_async(gpointer notused)
return (FALSE);
}
void
void
draw_window_title(void)
{
int i, off = 0;
@@ -638,7 +577,7 @@ update_window_title_async(gpointer notused)
return (FALSE);
}
int
int
graph_order_callback(void *notused)
{
g_idle_add(update_window_title_async, NULL);
@@ -686,7 +625,7 @@ connect_to_input_port(const char *port)
g_warning("Cannot connect to %s.", port);
return (-4);
}
}
g_warning("Connected to %s.", port);
@@ -786,19 +725,19 @@ connected:
free(connected_ports);
}
void
void
connect_to_next_input_port(void)
{
connect_to_another_input_port(1);
}
void
void
connect_to_prev_input_port(void)
{
connect_to_another_input_port(0);
}
void
void
init_jack(void)
{
int err;
@@ -876,7 +815,7 @@ load_config_from_lash(void)
int value;
while ((config = lash_get_config(lash_client))) {
key = lash_config_get_key(config);
value = lash_config_get_value_int(config);
@@ -920,7 +859,7 @@ load_config_from_lash(void)
g_warning("Bad value '%d' for 'velocity_normal' property received from LASH.", value);
} else {
velocity_normal = value;
gtk_range_set_value(GTK_RANGE(velocity_scale), *current_velocity);
gtk_range_set_value(GTK_RANGE(velocity_hscale), *current_velocity);
}
} else if (!strcmp(key, "velocity_high")) {
@@ -928,7 +867,7 @@ load_config_from_lash(void)
g_warning("Bad value '%d' for 'velocity_high' property received from LASH.", value);
} else {
velocity_high = value;
gtk_range_set_value(GTK_RANGE(velocity_scale), *current_velocity);
gtk_range_set_value(GTK_RANGE(velocity_hscale), *current_velocity);
}
} else if (!strcmp(key, "velocity_low")) {
@@ -936,7 +875,7 @@ load_config_from_lash(void)
g_warning("Bad value '%d' for 'velocity_low' property received from LASH.", value);
} else {
velocity_low = value;
gtk_range_set_value(GTK_RANGE(velocity_scale), *current_velocity);
gtk_range_set_value(GTK_RANGE(velocity_hscale), *current_velocity);
}
} else {
@@ -1021,15 +960,12 @@ init_lash(lash_args_t *args)
#endif /* HAVE_LASH */
gboolean
sustain_event_handler(GtkToggleButton *widget, gpointer pressed)
sustain_event_handler(GtkToggleButton *widget, gpointer not_used)
{
if (pressed) {
gtk_toggle_button_set_active(widget, TRUE);
if (gtk_toggle_button_get_active(widget))
piano_keyboard_sustain_press(keyboard);
} else {
gtk_toggle_button_set_active(widget, FALSE);
else
piano_keyboard_sustain_release(keyboard);
}
return (FALSE);
}
@@ -1089,32 +1025,11 @@ velocity_event_handler(GtkRange *range, gpointer notused)
assert(current_velocity);
*current_velocity = gtk_range_get_value(range);
keyboard->current_velocity = gtk_range_get_value(range);
}
void
mod_event_handler(GtkRange *range, gpointer notused)
{
int val = (int) gtk_range_get_value(range);
queue_new_message(MIDI_CONTROLLER, MIDI_MOD_CC, val);
}
void
pitch_event_handler(GtkRange *range, gpointer notused)
{
uint16_t val = (uint16_t) (gtk_range_get_value(range) * ((float)PITCH_RANGE / (float)PITCH_MAX) + (float)PITCH_RANGE);
queue_new_message(MIDI_PITCH, val & 127, (val >> 7) & 127);
}
void
panic_event_handler(GtkWidget *widget)
{
panic();
}
#ifdef HAVE_X11
int grab_x_error_handler(Display *dpy, XErrorEvent *notused)
int grab_x_error_handler(Display *dpy, XErrorEvent *notused)
{
keyboard_grabbed = 0;
@@ -1124,6 +1039,7 @@ int grab_x_error_handler(Display *dpy, XErrorEvent *notused)
GdkFilterReturn
keyboard_grab_filter(GdkXEvent *xevent, GdkEvent *event, gpointer notused)
{
#if !GTK_CHECK_VERSION(3,0,0)
XEvent *xe;
XKeyEvent *xke;
@@ -1136,14 +1052,16 @@ keyboard_grab_filter(GdkXEvent *xevent, GdkEvent *event, gpointer notused)
/* Lie to GDK, pretending we are the proper recipient of this XEvent. Without it,
GDK would discard it. */
xke->window = GDK_WINDOW_XWINDOW(window->window);
xke->window = GDK_WINDOW_XID(gtk_widget_get_window(window));
#endif /* GTK_CHECK_VERSION */
return (GDK_FILTER_CONTINUE);
}
void
ungrab_keyboard(void)
{
#if !GTK_CHECK_VERSION(3,0,0)
static int (*standard_x_error_handler)(Display *dpy, XErrorEvent *notused);
standard_x_error_handler = XSetErrorHandler(grab_x_error_handler);
@@ -1154,11 +1072,13 @@ ungrab_keyboard(void)
XSetErrorHandler(standard_x_error_handler);
keyboard_grabbed = 0;
#endif /* GTK_CHECK_VERSION */
}
void
grab_keyboard(void)
{
#if !GTK_CHECK_VERSION(3,0,0)
int i;
static int (*standard_x_error_handler)(Display *dpy, XErrorEvent *notused);
@@ -1167,7 +1087,7 @@ grab_keyboard(void)
XK_q, XK_w, XK_e, XK_r, XK_t, XK_y, XK_u, XK_i, XK_o, XK_p,
XK_a, XK_s, XK_d, XK_f, XK_g, XK_h, XK_j, XK_k, XK_l,
XK_z, XK_x, XK_c, XK_v, XK_b, XK_n, XK_m,
XK_Shift_L, XK_Shift_R, XK_Control_L, XK_Control_R, XK_space,
XK_Shift_L, XK_Shift_R, XK_Control_L, XK_Control_R, XK_space,
XK_Insert, XK_Delete, XK_Home, XK_End, XK_Page_Up, XK_Page_Down,
XK_KP_1, XK_KP_2, XK_KP_3, XK_KP_4, XK_KP_5, XK_KP_6, XK_KP_7, XK_KP_8, XK_KP_9, XK_KP_0,
XK_Num_Lock, XK_KP_Multiply, XK_KP_Divide, XK_KP_Subtract, XK_KP_Add, XK_KP_Enter,
@@ -1179,7 +1099,7 @@ grab_keyboard(void)
if (keyboard_grabbed)
return;
dpy = GDK_WINDOW_XDISPLAY(window->window);
dpy = GDK_WINDOW_XDISPLAY(gtk_widget_get_window(window));
keyboard_grabbed = 1;
@@ -1213,9 +1133,8 @@ grab_keyboard(void)
return;
}
g_atexit(ungrab_keyboard);
gdk_window_add_filter(NULL, keyboard_grab_filter, NULL);
#endif /* GTK_CHECK_VERSION */
}
#else /* ! HAVE_X11 */
@@ -1251,7 +1170,7 @@ octave_event_handler(GtkSpinButton *spinbutton, gpointer notused)
piano_keyboard_set_octave(keyboard, octave);
}
void
void
panic(void)
{
int i;
@@ -1299,70 +1218,70 @@ maybe_add_digit(GdkEventKey *event)
* XXX: This is silly. Find a way to enter the number without
* all these contitional instructions.
*/
if (event->keyval == GDK_KP_0 || event->keyval == GDK_KP_Insert) {
if (event->keyval == GDK_KEY_KP_0 || event->keyval == GDK_KEY_KP_Insert) {
if (event->type == GDK_KEY_PRESS)
add_digit(0);
return (TRUE);
}
if (event->keyval == GDK_KP_1 || event->keyval == GDK_KP_End) {
if (event->keyval == GDK_KEY_KP_1 || event->keyval == GDK_KEY_KP_End) {
if (event->type == GDK_KEY_PRESS)
add_digit(1);
return (TRUE);
}
if (event->keyval == GDK_KP_2 || event->keyval == GDK_KP_Down) {
if (event->keyval == GDK_KEY_KP_2 || event->keyval == GDK_KEY_KP_Down) {
if (event->type == GDK_KEY_PRESS)
add_digit(2);
return (TRUE);
}
if (event->keyval == GDK_KP_3 || event->keyval == GDK_KP_Page_Down) {
if (event->keyval == GDK_KEY_KP_3 || event->keyval == GDK_KEY_KP_Page_Down) {
if (event->type == GDK_KEY_PRESS)
add_digit(3);
return (TRUE);
}
if (event->keyval == GDK_KP_4 || event->keyval == GDK_KP_Left) {
if (event->keyval == GDK_KEY_KP_4 || event->keyval == GDK_KEY_KP_Left) {
if (event->type == GDK_KEY_PRESS)
add_digit(4);
return (TRUE);
}
if (event->keyval == GDK_KP_5 || event->keyval == GDK_KP_Begin) {
if (event->keyval == GDK_KEY_KP_5 || event->keyval == GDK_KEY_KP_Begin) {
if (event->type == GDK_KEY_PRESS)
add_digit(5);
return (TRUE);
}
if (event->keyval == GDK_KP_6 || event->keyval == GDK_KP_Right) {
if (event->keyval == GDK_KEY_KP_6 || event->keyval == GDK_KEY_KP_Right) {
if (event->type == GDK_KEY_PRESS)
add_digit(6);
return (TRUE);
}
if (event->keyval == GDK_KP_7 || event->keyval == GDK_KP_Home) {
if (event->keyval == GDK_KEY_KP_7 || event->keyval == GDK_KEY_KP_Home) {
if (event->type == GDK_KEY_PRESS)
add_digit(7);
return (TRUE);
}
if (event->keyval == GDK_KP_8 || event->keyval == GDK_KP_Up) {
if (event->keyval == GDK_KEY_KP_8 || event->keyval == GDK_KEY_KP_Up) {
if (event->type == GDK_KEY_PRESS)
add_digit(8);
return (TRUE);
}
if (event->keyval == GDK_KP_9 || event->keyval == GDK_KP_Page_Up) {
if (event->keyval == GDK_KEY_KP_9 || event->keyval == GDK_KEY_KP_Page_Up) {
if (event->type == GDK_KEY_PRESS)
add_digit(9);
@@ -1396,7 +1315,7 @@ clip(int val, int lo, int hi)
return (val);
}
gint
gint
keyboard_event_handler(GtkWidget *widget, GdkEventKey *event, gpointer notused)
{
int tmp;
@@ -1418,14 +1337,14 @@ keyboard_event_handler(GtkWidget *widget, GdkEventKey *event, gpointer notused)
/*
* '+' key shifts octave up. '-' key shifts octave down.
*/
if (event->keyval == GDK_KP_Add || event->keyval == GDK_equal) {
if (event->keyval == GDK_KEY_KP_Add || event->keyval == GDK_KEY_equal) {
if (event->type == GDK_KEY_PRESS && octave < OCTAVE_MAX)
gtk_spin_button_set_value(GTK_SPIN_BUTTON(octave_spin), octave + 1);
return (TRUE);
}
if (event->keyval == GDK_KP_Subtract || event->keyval == GDK_minus) {
if (event->keyval == GDK_KEY_KP_Subtract || event->keyval == GDK_KEY_minus) {
if (event->type == GDK_KEY_PRESS && octave > OCTAVE_MIN)
gtk_spin_button_set_value(GTK_SPIN_BUTTON(octave_spin), octave - 1);
@@ -1435,7 +1354,7 @@ keyboard_event_handler(GtkWidget *widget, GdkEventKey *event, gpointer notused)
/*
* '*' character increases program number. '/' character decreases it.
*/
if (event->keyval == GDK_KP_Multiply) {
if (event->keyval == GDK_KEY_KP_Multiply) {
if (event->type == GDK_KEY_PRESS) {
tmp = get_entered_number();
@@ -1449,7 +1368,7 @@ keyboard_event_handler(GtkWidget *widget, GdkEventKey *event, gpointer notused)
return (TRUE);
}
if (event->keyval == GDK_KP_Divide) {
if (event->keyval == GDK_KEY_KP_Divide) {
if (event->type == GDK_KEY_PRESS) {
tmp = get_entered_number();
@@ -1466,7 +1385,7 @@ keyboard_event_handler(GtkWidget *widget, GdkEventKey *event, gpointer notused)
/*
* PgUp key increases bank number, PgDown decreases it.
*/
if (event->keyval == GDK_Page_Up) {
if (event->keyval == GDK_KEY_Page_Up) {
if (event->type == GDK_KEY_PRESS) {
tmp = get_entered_number();
@@ -1480,7 +1399,7 @@ keyboard_event_handler(GtkWidget *widget, GdkEventKey *event, gpointer notused)
return (TRUE);
}
if (event->keyval == GDK_Page_Down) {
if (event->keyval == GDK_KEY_Page_Down) {
if (event->type == GDK_KEY_PRESS) {
tmp = get_entered_number();
@@ -1497,7 +1416,7 @@ keyboard_event_handler(GtkWidget *widget, GdkEventKey *event, gpointer notused)
/*
* Home key increases channel number, End decreases it.
*/
if (event->keyval == GDK_Home) {
if (event->keyval == GDK_KEY_Home) {
if (event->type == GDK_KEY_PRESS) {
tmp = get_entered_number();
@@ -1511,7 +1430,7 @@ keyboard_event_handler(GtkWidget *widget, GdkEventKey *event, gpointer notused)
return (TRUE);
}
if (event->keyval == GDK_End) {
if (event->keyval == GDK_KEY_End) {
if (event->type == GDK_KEY_PRESS) {
tmp = get_entered_number();
@@ -1528,21 +1447,21 @@ keyboard_event_handler(GtkWidget *widget, GdkEventKey *event, gpointer notused)
/*
* Insert key connects to the next input port. Delete connects to the previous one.
*/
if (event->keyval == GDK_Insert) {
if (event->keyval == GDK_KEY_Insert) {
if (event->type == GDK_KEY_PRESS)
connect_to_next_input_port();
return (TRUE);
}
if (event->keyval == GDK_Delete) {
if (event->keyval == GDK_KEY_Delete) {
if (event->type == GDK_KEY_PRESS)
connect_to_prev_input_port();
return (TRUE);
}
if (event->keyval == GDK_Escape) {
if (event->keyval == GDK_KEY_Escape) {
if (event->type == GDK_KEY_PRESS)
panic();
@@ -1556,11 +1475,11 @@ keyboard_event_handler(GtkWidget *widget, GdkEventKey *event, gpointer notused)
* the sustained notes end (it will send 'note off' midi messages for
* all the sustained notes).
*/
if (event->keyval == GDK_space) {
if (event->keyval == GDK_KEY_space) {
if (event->type == GDK_KEY_PRESS)
gtk_button_pressed(GTK_BUTTON(sustain_button));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sustain_button), TRUE);
else
gtk_button_released(GTK_BUTTON(sustain_button));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sustain_button), FALSE);
return (TRUE);
}
@@ -1569,25 +1488,25 @@ keyboard_event_handler(GtkWidget *widget, GdkEventKey *event, gpointer notused)
* Shift increases velocity, i.e. holding it while pressing note key
* will make the sound louder. Ctrl decreases velocity.
*/
if (event->keyval == GDK_Shift_L || event->keyval == GDK_Shift_R) {
if (event->keyval == GDK_KEY_Shift_L || event->keyval == GDK_KEY_Shift_R) {
if (event->type == GDK_KEY_PRESS)
current_velocity = &velocity_high;
else
current_velocity = &velocity_normal;
gtk_range_set_value(GTK_RANGE(velocity_scale), *current_velocity);
gtk_range_set_value(GTK_RANGE(velocity_hscale), *current_velocity);
return (TRUE);
}
if (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R) {
if (event->keyval == GDK_KEY_Control_L || event->keyval == GDK_KEY_Control_R) {
if (event->type == GDK_KEY_PRESS)
current_velocity = &velocity_low;
else
current_velocity = &velocity_normal;
gtk_range_set_value(GTK_RANGE(velocity_scale), *current_velocity);
gtk_range_set_value(GTK_RANGE(velocity_hscale), *current_velocity);
return (TRUE);
}
@@ -1632,80 +1551,107 @@ init_gtk_1(int *argc, char ***argv)
/* Window. */
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width(GTK_CONTAINER(window), 2);
gtk_rc_parse_string (rc_style);
}
void
init_gtk_2(void)
{
keyboard = PIANO_KEYBOARD(piano_keyboard_new());
if (!enable_gui) {
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(keyboard));
return;
}
#if GTK_CHECK_VERSION(3,0,0)
GtkWidget *grid;
#else
GtkTable *table;
#endif
GtkWidget *label;
/* Main Table. */
GtkTable *maintable = GTK_TABLE(gtk_table_new(3, 4, FALSE));
gtk_table_set_row_spacings(maintable, 5);
gtk_table_set_col_spacings(maintable, 5);
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(maintable));
/* Num Table. */
GtkTable *numtable = GTK_TABLE(gtk_table_new(2, 4, FALSE));
gtk_table_set_row_spacings(numtable, 5);
gtk_table_set_col_spacings(numtable, 5);
gtk_table_attach(maintable, numtable, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
GtkCellRenderer *renderer;
#if GTK_CHECK_VERSION(3,0,0)
grid = gtk_grid_new();
gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
gtk_grid_set_column_spacing(GTK_GRID(grid), 5);
#else
/* Table. */
table = GTK_TABLE(gtk_table_new(4, 8, FALSE));
gtk_table_set_row_spacings(table, 5);
gtk_table_set_col_spacings(table, 5);
#endif
if (enable_gui)
#if GTK_CHECK_VERSION(3,0,0)
gtk_container_add(GTK_CONTAINER(window), grid);
#else
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(table));
#endif
/* Channel label and spin. */
label = gtk_label_new("Chan");
gtk_table_attach(numtable, label, 0, 1, 0, 1,GTK_FILL, GTK_FILL, 0, 0);
label = gtk_label_new("Channel:");
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_set_hexpand(label, TRUE);
gtk_label_set_xalign(GTK_LABEL(label), 1);
gtk_container_add(GTK_CONTAINER(grid), label);
#else
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
gtk_table_attach(table, label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
#endif
channel_spin = gtk_spin_button_new_with_range(1, CHANNEL_MAX, 1);
GTK_WIDGET_UNSET_FLAGS(channel_spin, GTK_CAN_FOCUS);
gtk_table_attach(numtable, channel_spin, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_set_can_focus(channel_spin, FALSE);
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_set_hexpand(channel_spin, TRUE);
gtk_grid_attach_next_to(GTK_GRID(grid), channel_spin, label, GTK_POS_RIGHT, 1, 1);
#else
gtk_table_attach(table, channel_spin, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
#endif
g_signal_connect(G_OBJECT(channel_spin), "value-changed", G_CALLBACK(channel_event_handler), NULL);
/* Octave label and spin. */
label = gtk_label_new("Oct");
gtk_table_attach(numtable, label, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
octave_spin = gtk_spin_button_new_with_range(OCTAVE_MIN, OCTAVE_MAX, 1);
GTK_WIDGET_UNSET_FLAGS(octave_spin, GTK_CAN_FOCUS);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(octave_spin), octave);
gtk_table_attach(numtable, octave_spin, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
g_signal_connect(G_OBJECT(octave_spin), "value-changed", G_CALLBACK(octave_event_handler), NULL);
/* Bank label and spin. */
label = gtk_label_new("Bank");
gtk_table_attach(numtable, label, 2, 3, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
label = gtk_label_new("Bank:");
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_set_hexpand(label, TRUE);
gtk_label_set_xalign(GTK_LABEL(label), 1);
gtk_grid_attach_next_to(GTK_GRID(grid), label, channel_spin, GTK_POS_RIGHT, 1, 1);
#else
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
gtk_table_attach(table, label, 2, 3, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
#endif
bank_spin = gtk_spin_button_new_with_range(0, BANK_MAX, 1);
GTK_WIDGET_UNSET_FLAGS(bank_spin, GTK_CAN_FOCUS);
gtk_table_attach(numtable, bank_spin, 2, 3, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_set_can_focus(bank_spin, FALSE);
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_set_hexpand(bank_spin, TRUE);
gtk_grid_attach_next_to(GTK_GRID(grid), bank_spin, label, GTK_POS_RIGHT, 1, 1);
#else
gtk_table_attach(table, bank_spin, 3, 4, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
#endif
g_signal_connect(G_OBJECT(bank_spin), "value-changed", G_CALLBACK(bank_event_handler), NULL);
/* Program label and spin. */
label = gtk_label_new("Prog");
gtk_table_attach(numtable, label, 3, 4, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
label = gtk_label_new("Program:");
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_set_hexpand(label, TRUE);
gtk_label_set_xalign(GTK_LABEL(label), 1);
gtk_grid_attach_next_to(GTK_GRID(grid), label, bank_spin, GTK_POS_RIGHT, 1, 1);
#else
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
gtk_table_attach(table, label, 4, 5, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
#endif
program_spin = gtk_spin_button_new_with_range(0, PROGRAM_MAX, 1);
GTK_WIDGET_UNSET_FLAGS(program_spin, GTK_CAN_FOCUS);
gtk_table_attach(numtable, program_spin, 3, 4, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_set_can_focus(program_spin, FALSE);
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_set_hexpand(program_spin, TRUE);
gtk_grid_attach_next_to(GTK_GRID(grid), program_spin, label, GTK_POS_RIGHT, 1, 1);
#else
gtk_table_attach(table, program_spin, 5, 6, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
#endif
g_signal_connect(G_OBJECT(program_spin), "value-changed", G_CALLBACK(program_event_handler), NULL);
/* PANIC!!1 */
panic_button = gtk_button_new_with_label(" Panic! ");
gtk_button_set_focus_on_click(GTK_BUTTON(panic_button), FALSE);
gtk_table_attach(maintable, panic_button, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
g_signal_connect(G_OBJECT(panic_button), "pressed", G_CALLBACK(panic_event_handler), NULL);
/* "Connected to" label and combo box. */
GtkCellRenderer *renderer;
label = gtk_label_new("Connect");
gtk_table_attach(numtable, label, 4, 5, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
label = gtk_label_new("Connected to:");
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_set_hexpand(label, TRUE);
gtk_label_set_xalign(GTK_LABEL(label), 1);
gtk_grid_attach_next_to(GTK_GRID(grid), label, program_spin, GTK_POS_RIGHT, 1, 1);
#else
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
gtk_table_attach(table, label, 6, 7, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
#endif
connected_to_store = gtk_list_store_new(1, G_TYPE_STRING);
connected_to_combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(connected_to_store));
@@ -1714,84 +1660,113 @@ init_gtk_2(void)
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(connected_to_combo), renderer, FALSE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT(connected_to_combo), renderer, "text", 0, NULL);
GTK_WIDGET_UNSET_FLAGS(connected_to_combo, GTK_CAN_FOCUS);
gtk_widget_set_can_focus(connected_to_combo, FALSE);
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_set_focus_on_click(connected_to_combo, FALSE);
gtk_widget_set_hexpand(connected_to_combo, TRUE);
gtk_grid_attach_next_to(GTK_GRID(grid), connected_to_combo, label, GTK_POS_RIGHT, 1, 1);
#else
gtk_combo_box_set_focus_on_click(GTK_COMBO_BOX(connected_to_combo), FALSE);
gtk_table_attach(numtable, connected_to_combo, 4, 5, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_set_size_request(GTK_WIDGET(connected_to_combo), 160, -1);
gtk_table_attach(table, connected_to_combo, 7, 8, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
#endif
gtk_widget_set_size_request(GTK_WIDGET(connected_to_combo), 200, -1);
g_signal_connect(G_OBJECT(connected_to_combo), "changed", G_CALLBACK(connected_to_event_handler), NULL);
/* "Grab keyboard" label and checkbutton. */
label = gtk_label_new("Grab Keyboard");
gtk_table_attach(numtable, label, 5, 6, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
grab_keyboard_checkbutton = gtk_check_button_new();
GTK_WIDGET_UNSET_FLAGS(grab_keyboard_checkbutton, GTK_CAN_FOCUS);
g_signal_connect(G_OBJECT(grab_keyboard_checkbutton), "toggled", G_CALLBACK(grab_keyboard_handler), NULL);
gtk_table_attach(numtable, grab_keyboard_checkbutton, 5, 6, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
/* Octave label and spin. */
label = gtk_label_new("Octave:");
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_set_hexpand(label, TRUE);
gtk_label_set_xalign(GTK_LABEL(label), 1);
gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1);
#else
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
gtk_table_attach(table, label, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
#endif
octave_spin = gtk_spin_button_new_with_range(OCTAVE_MIN, OCTAVE_MAX, 1);
gtk_widget_set_can_focus(octave_spin, FALSE);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(octave_spin), octave);
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_set_hexpand(octave_spin, TRUE);
gtk_grid_attach_next_to(GTK_GRID(grid), octave_spin, label, GTK_POS_RIGHT, 1, 1);
#else
gtk_table_attach(table, octave_spin, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
#endif
g_signal_connect(G_OBJECT(octave_spin), "value-changed", G_CALLBACK(octave_event_handler), NULL);
/* "Grab keyboard" label and checkbutton. */
label = gtk_label_new("Grab keyboard:");
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_set_hexpand(label, TRUE);
gtk_label_set_xalign(GTK_LABEL(label), 1);
gtk_grid_attach(GTK_GRID(grid), label, 4, 1, 1, 1);
#else
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
gtk_table_attach(table, label, 4, 5, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
#endif
grab_keyboard_checkbutton = gtk_check_button_new();
gtk_widget_set_can_focus(grab_keyboard_checkbutton, FALSE);
g_signal_connect(G_OBJECT(grab_keyboard_checkbutton), "toggled", G_CALLBACK(grab_keyboard_handler), NULL);
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_set_hexpand(grab_keyboard_checkbutton, TRUE);
gtk_grid_attach_next_to(GTK_GRID(grid), grab_keyboard_checkbutton, label, GTK_POS_RIGHT, 1, 1);
#else
gtk_table_attach(table, grab_keyboard_checkbutton, 5, 6, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
#endif
/* Velocity label and hscale */
label = gtk_label_new("Velocity:");
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_set_hexpand(label, TRUE);
gtk_label_set_xalign(GTK_LABEL(label), 1);
gtk_grid_attach_next_to(GTK_GRID(grid), label, grab_keyboard_checkbutton, GTK_POS_RIGHT, 1, 1);
velocity_hscale = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, VELOCITY_MIN, VELOCITY_MAX, 1);
#else
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
gtk_table_attach(table, label, 6, 7, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
velocity_hscale = gtk_hscale_new_with_range(VELOCITY_MIN, VELOCITY_MAX, 1);
#endif
gtk_scale_set_draw_value(GTK_SCALE(velocity_hscale), FALSE);
gtk_widget_set_can_focus(velocity_hscale, FALSE);
g_signal_connect(G_OBJECT(velocity_hscale), "value-changed", G_CALLBACK(velocity_event_handler), NULL);
gtk_range_set_value(GTK_RANGE(velocity_hscale), VELOCITY_NORMAL);
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_set_hexpand(velocity_hscale, TRUE);
gtk_grid_attach_next_to(GTK_GRID(grid), velocity_hscale, label, GTK_POS_RIGHT, 1, 1);
#else
gtk_table_attach(table, velocity_hscale, 7, 8, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
#endif
gtk_widget_set_size_request(GTK_WIDGET(velocity_hscale), 200, -1);
/* Sustain. It's a toggle button, not an ordinary one, because we want gtk_whatever_set_active() to work.*/
sustain_button = gtk_toggle_button_new_with_label("Sustain");
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_set_focus_on_click(sustain_button, FALSE);
gtk_widget_set_hexpand(sustain_button, TRUE);
gtk_grid_attach(GTK_GRID(grid), sustain_button, 0, 2, 8, 1);
#else
gtk_button_set_focus_on_click(GTK_BUTTON(sustain_button), FALSE);
gtk_table_attach(maintable, sustain_button, 0, 3, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
g_signal_connect(G_OBJECT(sustain_button), "pressed", G_CALLBACK(sustain_event_handler), (void *)1);
g_signal_connect(G_OBJECT(sustain_button), "released", G_CALLBACK(sustain_event_handler), (void *)0);
/* Mod Table. */
GtkTable *modtable = GTK_TABLE(gtk_table_new(2, 3, FALSE));
gtk_table_set_row_spacings(modtable, 2);
gtk_table_set_col_spacings(modtable, 5);
gtk_table_attach(maintable, modtable, 3, 4, 0, 3, GTK_FILL, GTK_FILL, 0, 0);
/* Velocity label and hscale */
label = gtk_label_new("Vel");
gtk_table_attach(modtable, label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
gtk_table_attach(table, sustain_button, 0, 8, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
#endif
g_signal_connect(G_OBJECT(sustain_button), "toggled", G_CALLBACK(sustain_event_handler), NULL);
velocity_scale = gtk_vscale_new_with_range(VELOCITY_MIN, VELOCITY_MAX, 1);
gtk_scale_set_value_pos(GTK_SCALE(velocity_scale), GTK_POS_BOTTOM);
GTK_WIDGET_UNSET_FLAGS(velocity_scale, GTK_CAN_FOCUS);
g_signal_connect(G_OBJECT(velocity_scale), "value-changed", G_CALLBACK(velocity_event_handler), NULL);
gtk_range_set_value(GTK_RANGE(velocity_scale), VELOCITY_NORMAL);
gtk_range_set_inverted(GTK_RANGE(velocity_scale), TRUE);
gtk_range_set_round_digits(GTK_RANGE(velocity_scale), 0);
gtk_table_attach(modtable, velocity_scale, 0, 1, 1, 2, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
gtk_widget_set_size_request(GTK_WIDGET(velocity_scale), 40, 160);
/* Modulation label and vscale */
label = gtk_label_new("Mod");
gtk_table_attach(modtable, label, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
/* PianoKeyboard widget. */
keyboard = PIANO_KEYBOARD(piano_keyboard_new());
mod_scale = gtk_vscale_new_with_range(MOD_MIN, MOD_MAX, 1);
gtk_scale_set_value_pos(GTK_SCALE(mod_scale), GTK_POS_BOTTOM);
GTK_WIDGET_UNSET_FLAGS(mod_scale, GTK_CAN_FOCUS);
gtk_range_set_value(GTK_RANGE(mod_scale), MOD_INIT);
gtk_range_set_inverted(GTK_RANGE(mod_scale), TRUE);
gtk_range_set_round_digits(GTK_RANGE(mod_scale), 0);
g_signal_connect(G_OBJECT(mod_scale), "value-changed", G_CALLBACK(mod_event_handler), NULL);
gtk_table_attach(modtable, mod_scale, 1, 2, 1, 2, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
gtk_widget_set_size_request(GTK_WIDGET(mod_scale), 40, 160);
/* Pitch Bend label and vscale */
label = gtk_label_new("Pitch");
gtk_table_attach(modtable, label, 2, 3, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
if (enable_gui)
#if GTK_CHECK_VERSION(3,0,0)
{
gtk_widget_set_hexpand(GTK_WIDGET(keyboard), TRUE);
gtk_widget_set_vexpand(GTK_WIDGET(keyboard), TRUE);
gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(keyboard), 0, 3, 8, 1);
}
#else
gtk_table_attach_defaults(table, GTK_WIDGET(keyboard), 0, 8, 3, 4);
#endif
else
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(keyboard));
pitch_scale = gtk_vscale_new_with_range(PITCH_MIN, PITCH_MAX, 1);
gtk_scale_set_value_pos(GTK_SCALE(pitch_scale), GTK_POS_BOTTOM);
GTK_WIDGET_UNSET_FLAGS(pitch_scale, GTK_CAN_FOCUS);
gtk_range_set_value(GTK_RANGE(pitch_scale), PITCH_INIT);
gtk_range_set_inverted(GTK_RANGE(pitch_scale), TRUE);
gtk_range_set_round_digits(GTK_RANGE(pitch_scale), 0);
g_signal_connect(G_OBJECT(pitch_scale), "value-changed", G_CALLBACK(pitch_event_handler), NULL);
gtk_table_attach(modtable, pitch_scale, 2, 3, 1, 2, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
gtk_widget_set_size_request(GTK_WIDGET(pitch_scale), 40, 160);
/* Keyboard */
gtk_table_attach(maintable, GTK_WIDGET(keyboard), 0, 3, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
g_signal_connect(G_OBJECT(keyboard), "note-on", G_CALLBACK(note_on_event_handler), NULL);
g_signal_connect(G_OBJECT(keyboard), "note-off", G_CALLBACK(note_off_event_handler), NULL);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
@@ -1802,7 +1777,7 @@ init_gtk_2(void)
draw_window_title();
}
void
void
log_handler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer notused)
{
GtkWidget *dialog;
@@ -1810,8 +1785,8 @@ log_handler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *mess
fprintf(stderr, "%s: %s\n", log_domain, message);
if ((log_level | G_LOG_LEVEL_CRITICAL) == G_LOG_LEVEL_CRITICAL) {
dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE, "%s", message);
dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE, message);
gtk_dialog_run(GTK_DIALOG(dialog));
@@ -1840,7 +1815,7 @@ usage(void)
exit(EX_USAGE);
}
int
int
main(int argc, char *argv[])
{
int ch, enable_keyboard_cue = 0, initial_channel = 1, initial_bank = 0, initial_program = 0, full_midi_keyboard = 0;
@@ -1848,11 +1823,6 @@ main(int argc, char *argv[])
#ifdef HAVE_LASH
lash_args_t *lash_args;
#endif
g_thread_init(NULL);
#ifdef HAVE_LASH
lash_args = lash_extract_args(&argc, &argv);
#endif
@@ -1898,11 +1868,11 @@ main(int argc, char *argv[])
case 'l':
keyboard_layout = strdup(optarg);
break;
case 't':
time_offsets_are_zero = 1;
break;
case 'u':
send_program_change_at_reconnect = 1;
break;
@@ -2005,6 +1975,9 @@ main(int argc, char *argv[])
gtk_main();
if (keyboard_grabbed)
ungrab_keyboard();
return (0);
}

View File

@@ -35,8 +35,6 @@
#include <string.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <cairo.h>
#include <math.h>
#include "pianokeyboard.h"
@@ -57,34 +55,53 @@ draw_keyboard_cue(PianoKeyboard *pk)
int w, h, first_note_in_lower_row, last_note_in_lower_row,
first_note_in_higher_row, last_note_in_higher_row;
GdkGC *gc;
w = pk->notes[0].w;
h = pk->notes[0].h;
gc = GTK_WIDGET(pk)->style->fg_gc[0];
first_note_in_lower_row = (pk->octave + 5) * 12;
last_note_in_lower_row = (pk->octave + 6) * 12 - 1;
first_note_in_higher_row = (pk->octave + 6) * 12;
last_note_in_higher_row = (pk->octave + 7) * 12 + 4;
gdk_draw_line(GTK_WIDGET(pk)->window, gc, pk->notes[first_note_in_lower_row].x + 3,
h - 6, pk->notes[last_note_in_lower_row].x + w - 3, h - 6);
cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(GTK_WIDGET(pk)));
gdk_draw_line(GTK_WIDGET(pk)->window, gc, pk->notes[first_note_in_higher_row].x + 3,
h - 9, pk->notes[last_note_in_higher_row].x + w - 3, h - 9);
cairo_move_to(cr, pk->notes[first_note_in_lower_row].x + 3, h - 6);
cairo_line_to(cr, pk->notes[last_note_in_lower_row].x + w - 3, h - 6);
cairo_move_to(cr, pk->notes[first_note_in_higher_row].x + 3, h - 9);
cairo_line_to(cr, pk->notes[last_note_in_higher_row].x + w - 3, h - 9);
cairo_destroy(cr);
}
static void
static void
#if GTK_CHECK_VERSION(3,0,0)
draw_note(PianoKeyboard *pk, cairo_t *cr, int note)
#else
draw_note(PianoKeyboard *pk, int note)
#endif
{
GtkWidget *widget = GTK_WIDGET(pk);
if (note < pk->min_note)
return;
if (note > pk->max_note)
return;
int is_white, x, w, h, pressed;
int is_white, x, w, h;
#if GTK_CHECK_VERSION(3,0,0)
if (!cr)
cr = gdk_cairo_create(gtk_widget_get_window(GTK_WIDGET(pk)));
GdkRGBA black = { .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
GdkRGBA white = { .red = 1.0, .green = 1.0, .blue = 1.0, .alpha = 1.0};
#else
cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(GTK_WIDGET(pk)));
GdkColor black = {0, 0, 0, 0};
GdkColor white = {0, 65535, 65535, 65535};
GtkWidget *widget;
GtkAllocation allocation;
#endif
is_white = pk->notes[note].white;
@@ -92,23 +109,53 @@ draw_note(PianoKeyboard *pk, int note)
w = pk->notes[note].w;
h = pk->notes[note].h;
pressed = (int)(pk->notes[note].pressed || pk->notes[note].sustained);
if (is_white) {
piano_keyboard_draw_white_key(widget, x, 0, w, h, pressed, pk->notes[note].velocity);
} else {
piano_keyboard_draw_black_key(widget, x, 0, w, h, pressed, pk->notes[note].velocity);
}
if (note < NNOTES - 2 && !pk->notes[note + 1].white)
draw_note(pk, note + 1);
if (note > 0 && !pk->notes[note - 1].white)
draw_note(pk, note - 1);
if (pk->notes[note].pressed || pk->notes[note].sustained)
is_white = !is_white;
if (is_white)
#if GTK_CHECK_VERSION(3,0,0)
gdk_cairo_set_source_rgba(cr, &white);
#else
gdk_cairo_set_source_color(cr, &white);
#endif
else
#if GTK_CHECK_VERSION(3,0,0)
gdk_cairo_set_source_rgba(cr, &black);
#else
gdk_cairo_set_source_color(cr, &black);
#endif
cairo_rectangle(cr, x, 0, w, h);
cairo_fill(cr);
#if GTK_CHECK_VERSION(3,0,0)
gdk_cairo_set_source_rgba(cr, &black);
#else
gdk_cairo_set_source_color(cr, &black);
#endif
cairo_rectangle(cr, x, 0, w, h);
cairo_stroke(cr);
#if !GTK_CHECK_VERSION(3,0,0)
cairo_destroy(cr);
#endif
if (pk->enable_keyboard_cue)
draw_keyboard_cue(pk);
/* We need to redraw black keys that partially obscure the white one. */
if (note < NNOTES - 2 && !pk->notes[note + 1].white)
#if GTK_CHECK_VERSION(3,0,0)
draw_note(pk, cr, note + 1);
#else
draw_note(pk, note + 1);
#endif
if (note > 0 && !pk->notes[note - 1].white)
#if GTK_CHECK_VERSION(3,0,0)
draw_note(pk, cr, note - 1);
#else
draw_note(pk, note - 1);
/*
* XXX: This doesn't really belong here. Originally I wanted to pack PianoKeyboard into GtkFrame
* packed into GtkAlignment. I failed to make it behave the way I want. GtkFrame would need
@@ -116,12 +163,14 @@ draw_note(PianoKeyboard *pk, int note)
* that didn't work.
*/
widget = GTK_WIDGET(pk);
gtk_paint_shadow(widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL,
widget, NULL, pk->widget_margin, 0, widget->allocation.width - pk->widget_margin * 2 + 1,
widget->allocation.height);
gtk_widget_get_allocation(widget, &allocation);
gtk_paint_shadow(gtk_widget_get_style(widget), gtk_widget_get_window(widget), GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL,
widget, NULL, pk->widget_margin, 0, allocation.width - pk->widget_margin * 2 + 1,
allocation.height);
#endif
}
static int
static int
press_key(PianoKeyboard *pk, int key)
{
assert(key >= 0);
@@ -139,15 +188,18 @@ press_key(PianoKeyboard *pk, int key)
pk->notes[key].sustained = 0;
pk->notes[key].pressed = 1;
pk->notes[key].velocity = pk->current_velocity;
g_signal_emit_by_name(GTK_WIDGET(pk), "note-on", key);
#if GTK_CHECK_VERSION(3,0,0)
draw_note(pk, NULL, key);
#else
draw_note(pk, key);
#endif
return (1);
}
static int
static int
release_key(PianoKeyboard *pk, int key)
{
assert(key >= 0);
@@ -167,12 +219,16 @@ release_key(PianoKeyboard *pk, int key)
return (0);
g_signal_emit_by_name(GTK_WIDGET(pk), "note-off", key);
#if GTK_CHECK_VERSION(3,0,0)
draw_note(pk, NULL, key);
#else
draw_note(pk, key);
#endif
return (1);
}
static void
static void
stop_unsustained_notes(PianoKeyboard *pk)
{
int i;
@@ -181,12 +237,16 @@ stop_unsustained_notes(PianoKeyboard *pk)
if (pk->notes[i].pressed && !pk->notes[i].sustained) {
pk->notes[i].pressed = 0;
g_signal_emit_by_name(GTK_WIDGET(pk), "note-off", i);
#if GTK_CHECK_VERSION(3,0,0)
draw_note(pk, NULL, i);
#else
draw_note(pk, i);
#endif
}
}
}
static void
static void
stop_sustained_notes(PianoKeyboard *pk)
{
int i;
@@ -196,7 +256,11 @@ stop_sustained_notes(PianoKeyboard *pk)
pk->notes[i].pressed = 0;
pk->notes[i].sustained = 0;
g_signal_emit_by_name(GTK_WIDGET(pk), "note-off", i);
#if GTK_CHECK_VERSION(3,0,0)
draw_note(pk, NULL, i);
#else
draw_note(pk, i);
#endif
}
}
}
@@ -230,7 +294,7 @@ clear_notes(PianoKeyboard *pk)
g_array_set_size(pk->key_bindings, 0);
}
static void
static void
bind_keys_qwerty(PianoKeyboard *pk)
{
clear_notes(pk);
@@ -284,7 +348,7 @@ bind_keys_qwerty(PianoKeyboard *pk)
bind_key(pk, 51, 45); /* yes, really, at least here... */
}
static gint
static gint
keyboard_event_handler(GtkWidget *mk, GdkEventKey *event, gpointer notused)
{
int note;
@@ -312,12 +376,14 @@ keyboard_event_handler(GtkWidget *mk, GdkEventKey *event, gpointer notused)
return (TRUE);
}
static int
static int
get_note_for_xy(PianoKeyboard *pk, int x, int y)
{
int height, note;
GtkAllocation allocation;
height = GTK_WIDGET(pk)->allocation.height;
gtk_widget_get_allocation(GTK_WIDGET(pk), &allocation);
height = allocation.height;
if (y <= ((height * 2) / 3)) { /* might be a black key */
for (note = 0; note <= pk->max_note; ++note) {
@@ -340,7 +406,7 @@ get_note_for_xy(PianoKeyboard *pk, int x, int y)
return (-1);
}
static gboolean
static gboolean
mouse_button_event_handler(PianoKeyboard *pk, GdkEventButton *event, gpointer notused)
{
int x, y, note;
@@ -382,7 +448,7 @@ mouse_button_event_handler(PianoKeyboard *pk, GdkEventButton *event, gpointer no
return (TRUE);
}
static gboolean
static gboolean
mouse_motion_event_handler(PianoKeyboard *pk, GdkEventMotion *event, gpointer notused)
{
int note;
@@ -393,7 +459,7 @@ mouse_motion_event_handler(PianoKeyboard *pk, GdkEventMotion *event, gpointer no
note = get_note_for_xy(pk, event->x, event->y);
if (note != pk->note_being_pressed_using_mouse && note >= 0) {
if (pk->note_being_pressed_using_mouse >= 0)
release_key(pk, pk->note_being_pressed_using_mouse);
press_key(pk, note);
@@ -404,23 +470,45 @@ mouse_motion_event_handler(PianoKeyboard *pk, GdkEventMotion *event, gpointer no
}
static gboolean
#if GTK_CHECK_VERSION(3,0,0)
piano_keyboard_draw(GtkWidget *widget, cairo_t *cr)
#else
piano_keyboard_expose(GtkWidget *widget, GdkEventExpose *event)
#endif
{
int i;
PianoKeyboard *pk = PIANO_KEYBOARD(widget);
for (i = 0; i < NNOTES; i++)
#if GTK_CHECK_VERSION(3,0,0)
draw_note(pk, NULL, i);
#else
draw_note(pk, i);
#endif
return (TRUE);
}
static void
#if GTK_CHECK_VERSION(3,0,0)
static void
piano_keyboard_get_preferred_width(GtkWidget *widget, gint *minimal_width, gint *natural_width)
{
*minimal_width = *natural_width = PIANO_KEYBOARD_DEFAULT_WIDTH;
}
static void
piano_keyboard_get_preferred_height(GtkWidget *widget, gint *minimal_height, gint *natural_height)
{
*minimal_height = *natural_height = PIANO_KEYBOARD_DEFAULT_HEIGHT;
}
#else
static void
piano_keyboard_size_request(GtkWidget *widget, GtkRequisition *requisition)
{
requisition->width = PIANO_KEYBOARD_DEFAULT_WIDTH;
requisition->height = PIANO_KEYBOARD_DEFAULT_HEIGHT;
}
#endif
static int is_black(int key)
{
@@ -457,6 +545,7 @@ recompute_dimensions(PianoKeyboard *pk)
{
int number_of_white_keys = 0, skipped_white_keys = 0, key_width, black_key_width, useful_width, note,
white_key, width, height;
GtkAllocation allocation;
for (note = pk->min_note; note <= pk->max_note; ++note)
if (!is_black(note))
@@ -465,8 +554,9 @@ recompute_dimensions(PianoKeyboard *pk)
if (!is_black(note))
++skipped_white_keys;
width = GTK_WIDGET(pk)->allocation.width;
height = GTK_WIDGET(pk)->allocation.height;
gtk_widget_get_allocation(GTK_WIDGET(pk), &allocation);
width = allocation.width;
height = allocation.height;
key_width = width / number_of_white_keys;
black_key_width = key_width * 0.8;
@@ -476,11 +566,11 @@ recompute_dimensions(PianoKeyboard *pk)
for (note = 0, white_key = -skipped_white_keys; note < NNOTES; note++) {
if (is_black(note)) {
/* This note is black key. */
pk->notes[note].x = pk->widget_margin +
pk->notes[note].x = pk->widget_margin +
(white_key * key_width) -
(black_key_width * black_key_left_shift(note));
pk->notes[note].w = black_key_width;
pk->notes[note].h = (height * 3) / 5;
pk->notes[note].h = (height * 2) / 3;
pk->notes[note].white = 0;
continue;
}
@@ -502,12 +592,12 @@ piano_keyboard_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
g_return_if_fail(widget != NULL);
g_return_if_fail(allocation != NULL);
widget->allocation = *allocation;
gtk_widget_set_allocation(widget, allocation);
recompute_dimensions(PIANO_KEYBOARD(widget));
if (GTK_WIDGET_REALIZED(widget))
gdk_window_move_resize (widget->window, allocation->x, allocation->y, allocation->width, allocation->height);
if (gtk_widget_get_realized(widget))
gdk_window_move_resize (gtk_widget_get_window(widget), allocation->x, allocation->y, allocation->width, allocation->height);
}
static void
@@ -524,10 +614,16 @@ piano_keyboard_class_init(PianoKeyboardClass *klass)
G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
0, NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
widget_klass = (GtkWidgetClass*)klass;
widget_klass = (GtkWidgetClass*)klass;
#if GTK_CHECK_VERSION(3,0,0)
widget_klass->draw = piano_keyboard_draw;
widget_klass->get_preferred_width = piano_keyboard_get_preferred_width;
widget_klass->get_preferred_height = piano_keyboard_get_preferred_height;
#else
widget_klass->expose_event = piano_keyboard_expose;
widget_klass->size_request = piano_keyboard_size_request;
#endif
widget_klass->size_allocate = piano_keyboard_size_allocate;
}
@@ -573,7 +669,7 @@ piano_keyboard_new(void)
GtkWidget *widget;
PianoKeyboard *pk;
widget = gtk_type_new(piano_keyboard_get_type());
widget = g_object_new(TYPE_PIANO_KEYBOARD, NULL);
pk = PIANO_KEYBOARD(widget);
pk->maybe_stop_sustained_notes = 0;
@@ -606,7 +702,7 @@ piano_keyboard_sustain_press(PianoKeyboard *pk)
}
}
void
void
piano_keyboard_sustain_release(PianoKeyboard *pk)
{
if (pk->maybe_stop_sustained_notes)
@@ -616,12 +712,15 @@ piano_keyboard_sustain_release(PianoKeyboard *pk)
}
void
piano_keyboard_set_note_on(PianoKeyboard *pk, int note, int vel)
piano_keyboard_set_note_on(PianoKeyboard *pk, int note)
{
if (pk->notes[note].pressed == 0) {
pk->notes[note].pressed = 1;
pk->notes[note].velocity = vel;
#if GTK_CHECK_VERSION(3,0,0)
draw_note(pk, NULL, note);
#else
draw_note(pk, note);
#endif
}
}
@@ -631,7 +730,11 @@ piano_keyboard_set_note_off(PianoKeyboard *pk, int note)
if (pk->notes[note].pressed || pk->notes[note].sustained) {
pk->notes[note].pressed = 0;
pk->notes[note].sustained = 0;
#if GTK_CHECK_VERSION(3,0,0)
draw_note(pk, NULL, note);
#else
draw_note(pk, note);
#endif
}
}
@@ -667,137 +770,3 @@ piano_keyboard_enable_all_midi_notes(PianoKeyboard* pk)
recompute_dimensions(pk);
}
void
piano_keyboard_draw_white_key (GtkWidget *widget, int x, int y, int w, int h, int pressed, int vel)
{
cairo_pattern_t *pat;
GdkWindow *window = widget->window;
cairo_t *c = gdk_cairo_create(GDK_DRAWABLE(window));
cairo_set_line_join(c, CAIRO_LINE_JOIN_MITER);
cairo_set_line_width(c, 1);
cairo_rectangle(c, x, y, w, h);
cairo_clip_preserve(c);
pat = cairo_pattern_create_linear (x, y, x, y + h);
cairo_pattern_add_color_stop_rgb (pat, 0.0, 0.25, 0.25, 0.2);
cairo_pattern_add_color_stop_rgb (pat, 0.1, 0.957, 0.914, 0.925);
cairo_pattern_add_color_stop_rgb (pat, 1.0, 0.796, 0.787, 0.662);
cairo_set_source(c, pat);
cairo_fill(c);
cairo_move_to(c, x + 0.5, y);
cairo_line_to(c, x + 0.5, y + h);
cairo_set_source_rgba(c, 1, 1, 1, 0.75);
cairo_stroke(c);
cairo_move_to(c, x + w - 0.5, y);
cairo_line_to(c, x + w - 0.5, y + h);
cairo_set_source_rgba(c, 0, 0, 0, 0.5);
cairo_stroke(c);
if (pressed)
piano_keyboard_draw_pressed(c, x, y, w, h, vel);
piano_keyboard_draw_key_shadow(c, x, y, w, h);
cairo_destroy(c);
}
void
piano_keyboard_draw_black_key (GtkWidget *widget, int x, int y, int w, int h, int pressed, int vel)
{
cairo_pattern_t *pat;
GdkWindow *window = widget->window;
cairo_t *c = gdk_cairo_create(GDK_DRAWABLE(window));
cairo_set_line_join(c, CAIRO_LINE_JOIN_MITER);
cairo_set_line_width(c, 1);
cairo_rectangle(c, x, y, w, h);
cairo_clip_preserve(c);
pat = cairo_pattern_create_linear (x, y, x, y + h);
cairo_pattern_add_color_stop_rgb (pat, 0.0, 0, 0, 0);
cairo_pattern_add_color_stop_rgb (pat, 0.1, 0.27, 0.27, 0.27);
cairo_pattern_add_color_stop_rgb (pat, 1.0, 0, 0, 0);
cairo_set_source(c, pat);
cairo_fill(c);
pat = cairo_pattern_create_linear (x + 1, y, x + 1, y + h - w);
cairo_pattern_add_color_stop_rgb (pat, 0.0, 0, 0, 0);
cairo_pattern_add_color_stop_rgb (pat, 0.1, 0.55, 0.55, 0.55);
cairo_pattern_add_color_stop_rgb (pat, 0.5, 0.45, 0.45, 0.45);
cairo_pattern_add_color_stop_rgb (pat, 0.5001, 0.35, 0.35, 0.35);
cairo_pattern_add_color_stop_rgb (pat, 1.0, 0.25, 0.25, 0.25);
cairo_set_source(c, pat);
cairo_rectangle(c, x + 1, y, w - 2, y + h - w);
cairo_fill(c);
if (pressed)
piano_keyboard_draw_pressed(c, x, y, w, h, vel);
piano_keyboard_draw_key_shadow(c, x, y, w, h);
cairo_destroy(c);
}
void
piano_keyboard_draw_pressed (cairo_t *c, int x, int y, int w, int h, int vel)
{
float m = w * .15; // margin
float s = w - m * 2.; // size
float _vel = ((float)vel / 127.);
float hue = _vel * 140 + 220; // hue 220 .. 360 - blue over pink to red
float sat = .5 + _vel * 0.3; // saturation 0.5 .. 0.8
float val = 1. - _vel * 0.2; // lightness 1.0 .. 0.8
cairo_rectangle(c, x + m, y + h - m - s * 2, s, s * 2);
hsv HSV = {hue, sat, val};
rgb RGB = hsv2rgb(HSV);
cairo_set_source_rgb(c, RGB.r, RGB.g, RGB.b);
cairo_fill(c);
}
void
piano_keyboard_draw_key_shadow (cairo_t *c, int x, int y, int w, int h)
{
cairo_pattern_t *pat;
pat = cairo_pattern_create_linear (x, y, x, y + (int)(h * 0.2));
cairo_pattern_add_color_stop_rgba (pat, 0.0, 0, 0, 0, 0.4);
cairo_pattern_add_color_stop_rgba (pat, 1.0, 0, 0, 0, 0);
cairo_rectangle(c, x, y, w, (int)(h * 0.2));
cairo_set_source(c, pat);
cairo_fill(c);
}
rgb
hsv2rgb(hsv HSV)
{
rgb RGB;
double H = HSV.h, S = HSV.s, V = HSV.v,
P, Q, T,
fract;
(H == 360.)?(H = 0.):(H /= 60.);
fract = H - floor(H);
P = V*(1. - S);
Q = V*(1. - S*fract);
T = V*(1. - S*(1. - fract));
if (0. <= H && H < 1.)
RGB = (rgb){.r = V, .g = T, .b = P};
else if (1. <= H && H < 2.)
RGB = (rgb){.r = Q, .g = V, .b = P};
else if (2. <= H && H < 3.)
RGB = (rgb){.r = P, .g = V, .b = T};
else if (3. <= H && H < 4.)
RGB = (rgb){.r = P, .g = Q, .b = V};
else if (4. <= H && H < 5.)
RGB = (rgb){.r = T, .g = P, .b = V};
else if (5. <= H && H < 6.)
RGB = (rgb){.r = V, .g = P, .b = Q};
else
RGB = (rgb){.r = 0., .g = 0., .b = 0.};
return RGB;
}

View File

@@ -6,10 +6,10 @@
* 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.
* 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.
* 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 AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -65,7 +65,6 @@ struct Note {
int w; /* Width of the key, in pixels. */
int h; /* Height of the key, in pixels. */
int white; /* 1 if key is white; 0 otherwise. */
int velocity;
};
struct _PianoKeyboard
@@ -79,7 +78,6 @@ struct _PianoKeyboard
int note_being_pressed_using_mouse;
int min_note;
int max_note;
int current_velocity;
volatile struct Note notes[NNOTES];
/* Table used to translate from PC keyboard character to MIDI note number. */
GArray *key_bindings;
@@ -90,33 +88,16 @@ struct _PianoKeyboardClass
GtkDrawingAreaClass parent_class;
};
typedef struct {
double r;
double g;
double b;
} rgb;
typedef struct {
double h;
double s;
double v;
} hsv;
GType piano_keyboard_get_type (void) G_GNUC_CONST;
GtkWidget* piano_keyboard_new (void);
void piano_keyboard_sustain_press (PianoKeyboard *pk);
void piano_keyboard_sustain_release (PianoKeyboard *pk);
void piano_keyboard_set_note_on (PianoKeyboard *pk, int note, int vel);
void piano_keyboard_set_note_on (PianoKeyboard *pk, int note);
void piano_keyboard_set_note_off (PianoKeyboard *pk, int note);
void piano_keyboard_set_keyboard_cue (PianoKeyboard *pk, int enabled);
void piano_keyboard_set_octave (PianoKeyboard *pk, int octave);
gboolean piano_keyboard_set_keyboard_layout (PianoKeyboard *pk, const char *layout);
void piano_keyboard_enable_all_midi_notes(PianoKeyboard* pk);
void piano_keyboard_draw_white_key (GtkWidget *widget, int x, int y, int w, int h, int pressed, int val);
void piano_keyboard_draw_black_key (GtkWidget *widget, int x, int y, int w, int h, int pressed, int val);
void piano_keyboard_draw_pressed (cairo_t *c, int x, int y, int w, int h, int val);
void piano_keyboard_draw_key_shadow (cairo_t *c, int x, int y, int w, int h);
rgb hsv2rgb(hsv HSV);
G_END_DECLS