make midimap obey channels
[galan.git] / plugins / libjoyport.c
blobb7a95fede8e3048b42de54a5dfc0a3ba4a6b25a6
1 /* gAlan - Graphical Audio Language
2 * Copyright (C) 1999 Tony Garnock-Jones
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stdio.h>
22 #include <stddef.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <unistd.h>
29 #include <linux/joystick.h>
31 #include <gdk/gdk.h>
32 #include <gtk/gtk.h>
34 #include "global.h"
35 #include "generator.h"
36 #include "comp.h"
37 #include "control.h"
38 #include "gencomp.h"
39 #include "msgbox.h"
41 #define GENERATOR_CLASS_NAME "joyport"
42 #define GENERATOR_CLASS_PATH "Controls/Joyport"
46 /*
47 * Here is the Data....
51 enum EVT_INPUTS {
52 NUM_EVENT_INPUTS = 0
55 enum EVT_OUTPUTS {
56 EVT_AXIS0 = 0,
57 EVT_AXIS1,
58 EVT_AXIS2,
59 EVT_AXIS3,
60 EVT_AXIS4,
61 EVT_AXIS5,
62 EVT_BTNDOWN,
63 EVT_BTNUP,
64 NUM_EVENT_OUTPUTS
67 typedef struct Data {
68 char *dev_name;
69 gint fd;
70 gint input_tag;
71 } Data;
75 * This is the input callback....
76 * Seems to bo ok for now..
78 * now with the buttons its ok...
79 * (??? Is sending the number ok with evtcomp)
84 PRIVATE void input_callback( Generator *g, gint source, GdkInputCondition condition ) {
86 struct js_event jsevent;
87 AEvent event;
89 read( source, &jsevent, sizeof( struct js_event ) );
91 jsevent.type &= 0x7f;
93 switch( jsevent.type ) {
95 case JS_EVENT_AXIS:
97 if( jsevent.number < 6 ) {
98 gen_init_aevent(&event, AE_NUMBER, NULL, 0, NULL, 0, gen_get_sampletime() );
99 event.d.number = ((gdouble) jsevent.value) / 32767;
100 gen_send_events(g, jsevent.number, -1, &event);
103 break;
106 case JS_EVENT_BUTTON:
108 gen_init_aevent(&event, AE_NUMBER, NULL, 0, NULL, 0, gen_get_sampletime() );
109 event.d.number = ((gdouble) jsevent.number);
110 if( jsevent.value == 1 )
111 gen_send_events(g, EVT_BTNDOWN, -1, &event);
112 else
113 gen_send_events(g, EVT_BTNUP, -1, &event);
115 break;
117 default:
118 //printf( "unknown event: type %d, num %d, val %d \n", jsevent.type, jsevent.number, jsevent.value );
119 break;
126 * Constuctor and Destructor
128 * I have to add a global-property to get /dev/input/js0 from config.
129 * Of course make it configurable in plugin-properties.
131 * then i need asserts... But hey it works now :-)
132 * Instance can be added even if configured for js1 and only js0
133 * available (??? confusing having non working component )
137 PRIVATE int init_instance(Generator *g) {
138 Data *data = safe_malloc(sizeof(Data));
139 g->data = data;
140 data->dev_name = safe_string_dup("/dev/input/js0");
142 data->fd = open( data->dev_name, O_RDONLY );
143 data->input_tag = gdk_input_add( data->fd, GDK_INPUT_READ, (GdkInputFunction) input_callback, (gpointer) g );
144 return 1;
147 PRIVATE void destroy_instance(Generator *g) {
148 Data *data = g->data;
150 gdk_input_remove( data->input_tag );
151 close( data->fd );
153 if( data->dev_name )
154 free( data->dev_name );
156 free(g->data);
161 * pickle and unpickle
163 * are straight forward....
167 PRIVATE void unpickle_instance(Generator *g, ObjectStoreItem *item, ObjectStore *db) {
168 Data *data = safe_malloc(sizeof(Data));
169 g->data = data;
170 data->dev_name = safe_string_dup( objectstore_item_get_string(item, "dev_name", "/dev/input/js0" ) );
172 data->fd = open( data->dev_name, O_RDONLY );
173 data->input_tag = gdk_input_add( data->fd, GDK_INPUT_READ, (GdkInputFunction) input_callback, g );
176 PRIVATE void pickle_instance(Generator *g, ObjectStoreItem *item, ObjectStore *db) {
177 Data *data = g->data;
178 if (data->dev_name != NULL)
179 objectstore_item_set_string(item, "dev_name", data->dev_name);
183 * controls....
185 * Shall there ever be controls ???
186 * i am a control :-)
190 PRIVATE ControlDescriptor controls[] = {
191 /* { kind, name, min,max,step,page, size,editable, is_dst,queue_number,
192 init,destroy,refresh,refresh_data }, */
193 { CONTROL_KIND_NONE, }
196 // Properties...
198 PRIVATE void propgen(Component *c, Generator *g) {
199 Data *data = g->data;
201 GtkWidget *hb = gtk_hbox_new(FALSE, 5);
202 GtkWidget *label = gtk_label_new("Joystick Device:");
203 GtkWidget *text = gtk_entry_new();
205 gtk_box_pack_start(GTK_BOX(hb), label, TRUE, FALSE, 0);
206 gtk_box_pack_start(GTK_BOX(hb), text, TRUE, FALSE, 0);
208 gtk_widget_show(label);
209 gtk_widget_show(text);
211 gtk_entry_set_text(GTK_ENTRY(text), data->dev_name );
213 popup_dialog("Properties", MSGBOX_DISMISS, 0, MSGBOX_DISMISS, hb, NULL, 0);
215 if( data->dev_name )
216 free( data->dev_name );
218 data->dev_name = safe_string_dup(gtk_entry_get_text(GTK_ENTRY(text)));
220 gdk_input_remove( data->input_tag );
221 close( data->fd );
223 data->fd = open( data->dev_name, O_RDONLY );
224 data->input_tag = gdk_input_add( data->fd, GDK_INPUT_READ, (GdkInputFunction) input_callback, (gpointer) g );
228 * setup Class
230 * much TODO here....
232 * check how many buttons and axes we have...
233 * can i change this dynamicly ???
237 PRIVATE void setup_class(void) {
238 GeneratorClass *k = gen_new_generatorclass(GENERATOR_CLASS_NAME, FALSE, NUM_EVENT_INPUTS, NUM_EVENT_OUTPUTS,
239 NULL, NULL, controls,
240 init_instance, destroy_instance,
241 unpickle_instance, pickle_instance);
243 gen_configure_event_output(k, EVT_AXIS0, "Axxis0");
244 gen_configure_event_output(k, EVT_AXIS1, "Axxis1");
245 gen_configure_event_output(k, EVT_AXIS2, "Axxis2");
246 gen_configure_event_output(k, EVT_AXIS3, "Axxis3");
247 gen_configure_event_output(k, EVT_AXIS4, "Axxis4");
248 gen_configure_event_output(k, EVT_AXIS5, "Axxis5");
249 gen_configure_event_output(k, EVT_BTNDOWN, "ButtonDown");
250 gen_configure_event_output(k, EVT_BTNUP, "ButtonUp");
252 gencomp_register_generatorclass(k, FALSE, GENERATOR_CLASS_PATH, NULL, propgen);
255 PUBLIC void init_plugin(void) {
256 setup_class();