libxputty 0.1
Loading...
Searching...
No Matches
xmidi_keyboard.c
Go to the documentation of this file.
1/*
2 * 0BSD
3 *
4 * BSD Zero Clause License
5 *
6 * Copyright (c) 2019 Hermann Meyer
7 *
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted.
10
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 *
19 */
20
21#include "xmidi_keyboard.h"
22
23
24void mk_keysym_azerty_to_midi_key(long inkey, float *midi_key) {
25 switch(inkey) {
26 case(XK_w) : (*midi_key) = 12.0; /* w = C0 */
27 break;
28 case(XK_s) : (*midi_key) = 13.0; /* s */
29 break;
30 case(XK_x) : (*midi_key) = 14.0; /* x */
31 break;
32 case(XK_d) : (*midi_key) = 15.0; /* d */
33 break;
34 case(XK_c) : (*midi_key) = 16.0; /* c */
35 break;
36 case(XK_v) : (*midi_key) = 17.0; /* v */
37 break;
38 case(XK_g) : (*midi_key) = 18.0; /* g */
39 break;
40 case(XK_b) : (*midi_key) = 19.0; /* b */
41 break;
42 case(XK_h) : (*midi_key) = 20.0; /* h */
43 break;
44 case(XK_n) : (*midi_key) = 21.0; /* n */
45 break;
46 case(XK_j) : (*midi_key) = 22.0; /* j */
47 break;
48 case(XK_comma) : (*midi_key) = 23.0; /* , */
49 break;
50 case(XK_a) : (*midi_key) = 24.0; /* a */
51 break;
52 case(XK_eacute) : (*midi_key) = 25.0; /* eacute */
53 break;
54 case(XK_z) : (*midi_key) = 26.0; /* z */
55 break;
56 case(XK_quotedbl) : (*midi_key) = 27.0; /* quotedbl */
57 break;
58 case(XK_e) : (*midi_key) = 28.0; /* e */
59 break;
60 case(XK_r) : (*midi_key) = 29.0; /* r */
61 break;
62 case(XK_parenleft) : (*midi_key) = 30.0; /* parenleft */
63 break;
64 case(XK_t) : (*midi_key) = 31.0; /* t */
65 break;
66 case(XK_minus) : (*midi_key) = 32.0; /* minus */
67 break;
68 case(XK_y) : (*midi_key) = 33.0; /* y */
69 break;
70 case(XK_egrave) : (*midi_key) = 34.0; /* egrave */
71 break;
72 case(XK_u) : (*midi_key) = 35.0; /* u */
73 break;
74 case(XK_i) : (*midi_key) = 36.0; /* i */
75 break;
76 case(XK_ccedilla) : (*midi_key) = 37.0; /* ccedilla */
77 break;
78 case(XK_o) : (*midi_key) = 38.0; /* o */
79 break;
80 case(XK_agrave) : (*midi_key) = 39.0; /* agrave */
81 break;
82 case(XK_p) : (*midi_key) = 40.0; /* p */
83 break;
84 case(XK_dead_diaeresis) :
85 case(XK_dead_circumflex) : (*midi_key) = 41.0; /* dead circumflex */
86 break;
87 }
88}
89
90void mk_keysym_qwertz_to_midi_key(long inkey, float *midi_key) {
91 switch(inkey) {
92 case(XK_y) : (*midi_key) = 12.0; /* y = C0 */
93 break;
94 case(XK_s) : (*midi_key) = 13.0; /* s */
95 break;
96 case(XK_x) : (*midi_key) = 14.0; /* x */
97 break;
98 case(XK_d) : (*midi_key) = 15.0; /* d */
99 break;
100 case(XK_c) : (*midi_key) = 16.0; /* c */
101 break;
102 case(XK_v) : (*midi_key) = 17.0; /* v */
103 break;
104 case(XK_g) : (*midi_key) = 18.0; /* g */
105 break;
106 case(XK_b) : (*midi_key) = 19.0; /* b */
107 break;
108 case(XK_h) : (*midi_key) = 20.0; /* h */
109 break;
110 case(XK_n) : (*midi_key) = 21.0; /* n */
111 break;
112 case(XK_j) : (*midi_key) = 22.0; /* j */
113 break;
114 case(XK_m) : (*midi_key) = 23.0; /* m */
115 break;
116 case(XK_q) : (*midi_key) = 24.0; /* q */
117 break;
118 case(XK_2) : (*midi_key) = 25.0; /* 2 */
119 break;
120 case(XK_w) : (*midi_key) = 26.0; /* w */
121 break;
122 case(XK_3) : (*midi_key) = 27.0; /* 3 */
123 break;
124 case(XK_e) : (*midi_key) = 28.0; /* e */
125 break;
126 case(XK_r) : (*midi_key) = 29.0; /* r */
127 break;
128 case(XK_5) : (*midi_key) = 30.0; /* 5 */
129 break;
130 case(XK_t) : (*midi_key) = 31.0; /* t */
131 break;
132 case(XK_6) : (*midi_key) = 32.0; /* 6 */
133 break;
134 case(XK_z) : (*midi_key) = 33.0; /* z */
135 break;
136 case(XK_7) : (*midi_key) = 34.0; /* 7 */
137 break;
138 case(XK_u) : (*midi_key) = 35.0; /* u */
139 break;
140 case(XK_i) : (*midi_key) = 36.0; /* i */
141 break;
142 case(XK_9) : (*midi_key) = 37.0; /* 9 */
143 break;
144 case(XK_o) : (*midi_key) = 38.0; /* o */
145 break;
146 case(XK_0) : (*midi_key) = 39.0; /* 0 */
147 break;
148 case(XK_p) : (*midi_key) = 40.0; /* p */
149 break;
150 case(XK_udiaeresis) : (*midi_key) = 41.0; /* ΓΌ */
151 break;
152 case(XK_plus) : (*midi_key) = 42.0; /* + */
153 break;
154 }
155}
156
157void mk_keysym_qwerty_to_midi_key(unsigned int inkey, float *midi_key) {
158 mk_keysym_qwertz_to_midi_key(inkey,midi_key);
159 if ((*midi_key) == 12) (*midi_key) = 33;
160 else if ((*midi_key) == 33) (*midi_key) = 12;
161}
162
163static void set_key_in_matrix(unsigned long *key_matrix, int key, bool set) {
164 unsigned long *use_matrix = &key_matrix[0];
165
166 if(key>94) {
167 use_matrix = &key_matrix[3];
168 key -=94;
169 } else if(key>62) {
170 use_matrix = &key_matrix[2];
171 key -=62;
172 } else if(key>31) {
173 use_matrix = &key_matrix[1];
174 key -= 31;
175 }
176 if (set) {
177 (*use_matrix) |= (1 << key);
178 }else {
179 (*use_matrix) &= (~(1 << key));
180 }
181}
182
183bool mk_is_key_in_matrix(unsigned long *key_matrix, int key) {
184 unsigned long *use_matrix = &key_matrix[0];
185
186
187 if(key>94) {
188 use_matrix = &key_matrix[3];
189 key -=94;
190 } else if(key>62) {
191 use_matrix = &key_matrix[2];
192 key -=62;
193 } else if(key>31) {
194 use_matrix = &key_matrix[1];
195 key -= 31;
196 }
197 bool ret = false;
198 if((*use_matrix) & (1<<key)) {
199 ret = true;
200 }
201 return ret;
202}
203
204bool mk_have_key_in_matrix(unsigned long *key_matrix) {
205
206 bool ret = false;
207 int i = 0;
208 int j = 0;
209 for(;j<4;j++) {
210 for(;i<32;i++) {
211 if(key_matrix[j] & (1<<i)) {
212 ret = true;
213 break;
214 }
215 }
216 i = 0;
217 }
218 return ret;
219}
220
221void mk_clear_key_matrix(unsigned long *key_matrix) {
222 int i = 0;
223 int j = 0;
224 for(;j<4;j++) {
225 for(;i<32;i++) {
226 key_matrix[j] &= (~(1 << i));
227 }
228 i = 0;
229 }
230}
231void mk_draw_knob(void *w_, void* user_data) {
232 Widget_t *w = (Widget_t*)w_;
233 Metrics_t metrics;
234 os_get_window_metrics(w, &metrics);
235 int width = metrics.width-2;
236 int height = metrics.height-2;
237 if (!metrics.visible) return;
238
239 const double scale_zero = 20 * (M_PI/180); // defines "dead zone" for knobs
240 int arc_offset = 2;
241 int knob_x = 0;
242 int knob_y = 0;
243
244 int grow = (width > height) ? height:width;
245 knob_x = grow-1;
246 knob_y = grow-1;
249 int knobx = (width - knob_x) * 0.5;
250 int knobx1 = width* 0.5;
251
252 int knoby = (height - knob_y) * 0.5;
253 int knoby1 = height * 0.5;
254
255 double knobstate = adj_get_state(w->adj_y);
256 double angle = scale_zero + knobstate * 2 * (M_PI - scale_zero);
257
258 double pointer_off =knob_x/3.5;
259 double radius = min(knob_x-pointer_off, knob_y-pointer_off) / 2;
260 double lengh_x = (knobx+radius+pointer_off/2) - radius * sin(angle);
261 double lengh_y = (knoby+radius+pointer_off/2) + radius * cos(angle);
262 double radius_x = (knobx+radius+pointer_off/2) - radius/ 1.18 * sin(angle);
263 double radius_y = (knoby+radius+pointer_off/2) + radius/ 1.18 * cos(angle);
264 cairo_pattern_t* pat;
265 cairo_new_path (w->crb);
266
267 pat = cairo_pattern_create_linear (0, 0, 0, knob_y);
268 cairo_pattern_add_color_stop_rgba (pat, 1, 0.3, 0.3, 0.3, 1.0);
269 cairo_pattern_add_color_stop_rgba (pat, 0.75, 0.2, 0.2, 0.2, 1.0);
270 cairo_pattern_add_color_stop_rgba (pat, 0.5, 0.15, 0.15, 0.15, 1.0);
271 cairo_pattern_add_color_stop_rgba (pat, 0.25, 0.1, 0.1, 0.1, 1.0);
272 cairo_pattern_add_color_stop_rgba (pat, 0, 0.05, 0.05, 0.05, 1.0);
273
274 cairo_scale (w->crb, 0.95, 1.05);
275 cairo_arc(w->crb,knobx1+arc_offset/2, knoby1-arc_offset, knob_x/2.2, 0, 2 * M_PI );
276 cairo_set_source (w->crb, pat);
277 cairo_fill_preserve (w->crb);
278 cairo_set_source_rgb (w->crb, 0.1, 0.1, 0.1);
279 cairo_set_line_width(w->crb,1);
280 cairo_stroke(w->crb);
281 cairo_scale (w->crb, 1.05, 0.95);
282 cairo_new_path (w->crb);
283 cairo_pattern_destroy (pat);
284 pat = NULL;
285
286 pat = cairo_pattern_create_linear (0, 0, 0, knob_y);
287 cairo_pattern_add_color_stop_rgba (pat, 0, 0.3, 0.3, 0.3, 1.0);
288 cairo_pattern_add_color_stop_rgba (pat, 0.25, 0.2, 0.2, 0.2, 1.0);
289 cairo_pattern_add_color_stop_rgba (pat, 0.5, 0.15, 0.15, 0.15, 1.0);
290 cairo_pattern_add_color_stop_rgba (pat, 0.75, 0.1, 0.1, 0.1, 1.0);
291 cairo_pattern_add_color_stop_rgba (pat, 1, 0.05, 0.05, 0.05, 1.0);
292
293 cairo_arc(w->crb,knobx1, knoby1, knob_x/2.6, 0, 2 * M_PI );
294 cairo_set_source (w->crb, pat);
295 cairo_fill_preserve (w->crb);
296 cairo_set_source_rgb (w->crb, 0.1, 0.1, 0.1);
297 cairo_set_line_width(w->crb,1);
298 cairo_stroke(w->crb);
299 cairo_new_path (w->crb);
300 cairo_pattern_destroy (pat);
301
303 cairo_set_line_cap(w->crb, CAIRO_LINE_CAP_ROUND);
304 cairo_set_line_join(w->crb, CAIRO_LINE_JOIN_BEVEL);
305 cairo_move_to(w->crb, radius_x, radius_y);
306 cairo_line_to(w->crb,lengh_x,lengh_y);
307 cairo_set_line_width(w->crb,3);
308 cairo_set_source_rgb (w->crb,0.63,0.63,0.63);
309 cairo_stroke(w->crb);
310 cairo_new_path (w->crb);
311
312 cairo_text_extents_t extents;
314 if (w->state) {
315 char s[64];
316 snprintf(s, 63,"%d", (int) w->adj_y->value);
317 cairo_set_source_rgb (w->crb, 0.6, 0.6, 0.6);
318 cairo_set_font_size (w->crb, knobx1/3);
319 cairo_text_extents(w->crb, s, &extents);
320 cairo_move_to (w->crb, knobx1-extents.width/2, knoby1+extents.height/2);
321 cairo_show_text(w->crb, s);
322 cairo_new_path (w->crb);
323 }
324
327 float font_size = ((height/2.2 < (width*0.5)/3) ? height/2.2 : (width*0.5)/3);
328 cairo_set_font_size (w->crb, font_size);
329 cairo_text_extents(w->crb,w->label , &extents);
330
331 cairo_move_to (w->crb, knobx1-extents.width/2, height );
332 cairo_show_text(w->crb, w->label);
333 cairo_new_path (w->crb);
334}
335
336static void draw_keyboard(void *w_, void* user_data) {
337 Widget_t *w = (Widget_t*)w_;
338 Metrics_t metrics;
339 os_get_window_metrics(w, &metrics);
340 int width_t = metrics.width;
341 int height_t = metrics.height;
342 if (!metrics.visible) return;
344
345 cairo_rectangle(w->crb,0,0,width_t,height_t*0.4);
347 cairo_fill (w->crb);
348 //set_pattern(w,&w->color_scheme->normal,&w->color_scheme->selected,BACKGROUND_);
350 cairo_rectangle(w->crb,0,height_t*0.38,width_t,height_t*0.02);
351 cairo_fill_preserve (w->crb);
353
354 cairo_set_line_width(w->crb, 1.0);
355 cairo_stroke(w->crb);
356 int space = 2;
357 int set = 0;
358 int i = 0;
359 int k = 0;
360
361 for(;i<width_t;i++) {
362 cairo_rectangle(w->crb,i,height_t*0.4,25,height_t*0.6);
363 if ( k+keys->octave == keys->active_key || mk_is_key_in_matrix(keys->key_matrix,k+keys->octave)) {
365 cairo_set_line_width(w->crb, 1.0);
366 } else if ( k+keys->octave == keys->prelight_key) {
368 cairo_set_line_width(w->crb, 2.0);
369 } else {
371 cairo_set_line_width(w->crb, 1.0);
372 }
373
374 cairo_fill_preserve(w->crb);
376 cairo_stroke(w->crb);
377
378 if (space!=4) {
379 k++;
380 } else {
381 if (set <= 3) {
382 space = 0;
383 set = 0;
384 } else if (set == 4) {
385 space = 1;
386 set = 0;
387 }
388 }
389
390 if (k>127) break;
391 i+=24;
392 space++;
393 set++;
394 k++;
395 }
396
397 space = 1;
398 set = 0;
399 k = 1;
400 i = 0;
401
402 for(;i<width_t;i++) {
403
404 if (space!=3) {
405 cairo_set_line_width(w->crb, 1.0);
406 cairo_rectangle(w->crb,i+15,height_t*0.4,20,height_t*0.39);
407 if ( k+keys->octave == keys->active_key || mk_is_key_in_matrix(keys->key_matrix,k+keys->octave)) {
409 cairo_set_line_width(w->crb, 1.0);
410 } else if ( k+keys->octave == keys->prelight_key) {
412 cairo_set_line_width(w->crb, 2.0);
413 } else {
415 cairo_set_line_width(w->crb, 1.0);
416 }
417
418 cairo_fill_preserve(w->crb);
420 cairo_stroke(w->crb);
421
422 k++;
423 space++;
424 set++;
425
426 } else {
427
428 if (set == 2) {
429 space = 0;
430 set = 0;
431 } else if (set == 3) {
432 space = 1;
433 set = 0;
434 }
435
436 }
437
438 i+=24;
439 k++;
440 if(k>127)break;
441 }
442}
443
444static void keyboard_motion(void *w_, void* xmotion_, void* user_data) {
445 Widget_t *w = (Widget_t*)w_;
446 Widget_t *p = (Widget_t *)w->parent;
448 XMotionEvent *xmotion = (XMotionEvent*)xmotion_;
449 Metrics_t metrics;
450 os_get_window_metrics(w, &metrics);
451 int width = metrics.width;
452 int height = metrics.height;
453 if (!metrics.visible) return;
454
455 bool catchit = false;
456
457 if(xmotion->y < height*0.4) {
458 keys->active_key = keys->prelight_key = -1;
459 expose_widget(w);
460 return;
461 }
462
463 if(xmotion->y < height*0.8) {
464 int space = 1;
465 int set = 0;
466 int set_key = 1;
467 int i = 0;
468 for(;i<width;i++) {
469 if (space!=3) {
470 if(xmotion->x > i+15 && xmotion->x < i+35) {
471 keys->prelight_key = set_key+keys->octave;
472 if(xmotion->state & Button1Mask) {
473 if (keys->active_key != keys->prelight_key) {
474 keys->send_key = keys->active_key;
475 keys->mk_send_note(p, &keys->send_key,false);
476 keys->active_key = keys->prelight_key;
477 keys->send_key = keys->active_key;
478 keys->mk_send_note(p, &keys->send_key,true);
479 }
480 }
481 catchit = true;
482 expose_widget(w);
483 break;
484 }
485 space++;
486 set++;
487 set_key++;
488 } else {
489 if (set == 2) {
490 space = 0;
491 set = 0;
492 } else if (set == 3) {
493 space = 1;
494 set = 0;
495 }
496 }
497 i+=24;
498 set_key++;
499 }
500 }
501
502 if (!catchit) {
503 int space = 2;
504 int set = 0;
505 int i = 0;
506 int k = 0;
507
508 for(;i<width;i++) {
509 if(xmotion->x > i && xmotion->x < i+25) {
510 keys->prelight_key = k+keys->octave;
511 if(xmotion->state & Button1Mask) {
512 if (keys->active_key != keys->prelight_key) {
513 keys->send_key = keys->active_key;
514 keys->mk_send_note(p, &keys->send_key,false);
515 keys->active_key = keys->prelight_key;
516 keys->send_key = keys->active_key;
517 keys->mk_send_note(p, &keys->send_key,true);
518 }
519 }
520 expose_widget(w);
521 break;
522 }
523
524 if (space!=4) {
525 k++;
526 } else {
527 if (set <= 3) {
528 space = 0;
529 set = 0;
530 } else if (set == 4) {
531 space = 1;
532 set = 0;
533 }
534 }
535
536 i+=24;
537 space++;
538 set++;
539 k++;
540 }
541 }
542}
543
544static void get_outkey(MidiKeyboard_mk *keys, KeySym sym, float *outkey) {
545 switch(keys->layout) {
546 case(0):mk_keysym_qwertz_to_midi_key(sym, outkey);
547 break;
548 case(1):mk_keysym_qwerty_to_midi_key(sym, outkey);
549 break;
550 case(2):mk_keysym_azerty_to_midi_key(sym, outkey);
551 break;
552 default:mk_keysym_qwertz_to_midi_key(sym, outkey);
553 break;
554 }
555}
556
557static void key_press(void *w_, void *key_, void *user_data) {
558 Widget_t *w = (Widget_t*)w_;
559 Widget_t *p = (Widget_t *)w->parent;
560 if (!w) return;
562 XKeyEvent *key = (XKeyEvent*)key_;
563 if (!key) return;
564 float outkey = 0.0;
565#ifdef _WIN32 //KeybHandler
566 KeySym sym = key->keycode;
567 if (key->vk_is_final_char) return; // only real KEY_DOWN, dead-key support not required/wanted
568#else
569 KeySym sym = XLookupKeysym (key, 0);
570#endif
571 get_outkey(keys, sym, &outkey);
572
573 if ((int)outkey && !mk_is_key_in_matrix(keys->key_matrix, (int)outkey+keys->octave)) {
574 set_key_in_matrix(keys->key_matrix,(int)outkey+keys->octave,true);
575 keys->send_key = (int)outkey+keys->octave;
576 keys->mk_send_note(p, &keys->send_key,true);
577 expose_widget(w);
578 }
579 if (sym == XK_space) {
581 keys->mk_send_all_sound_off(p, NULL);
582 expose_widget(w);
583 }
584}
585
586static void key_release(void *w_, void *key_, void *user_data) {
587 Widget_t *w = (Widget_t*)w_;
588 Widget_t *p = (Widget_t *)w->parent;
589 if (!w) return;
591 XKeyEvent *key = (XKeyEvent*)key_;
592 if (!key) return;
593 float outkey = 0.0;
594#ifdef _WIN32 //KeybHandler
595 KeySym sym = key->keycode;
596 if (key->vk_is_final_char) return; // only real KEY_DOWN, dead-key support not required/wanted
597#else
598 KeySym sym = XLookupKeysym (key, 0);
599#endif
600 get_outkey(keys, sym, &outkey);
601 if ((int)outkey && mk_is_key_in_matrix(keys->key_matrix, (int)outkey+keys->octave)) {
602 set_key_in_matrix(keys->key_matrix,(int)outkey+keys->octave,false);
603 keys->send_key = (int)outkey+keys->octave;
604 keys->mk_send_note(p,&keys->send_key,false);
605 expose_widget(w);
606 }
607}
608
609static void leave_keyboard(void *w_, void* user_data) {
610 Widget_t *w = (Widget_t*)w_;
612 keys->prelight_key = -1;
613 expose_widget(w);
614}
615
616static void button_pressed_keyboard(void *w_, void* button_, void* user_data) {
617 Widget_t *w = (Widget_t*)w_;
618 Widget_t *p = (Widget_t *)w->parent;
619 if (w->flags & HAS_POINTER) {
621 XButtonEvent *xbutton = (XButtonEvent*)button_;
622 if(xbutton->button == Button1) {
623 keys->active_key = keys->prelight_key;
624 keys->send_key = keys->active_key;
625 keys->mk_send_note(p,&keys->send_key,true);
626 expose_widget(w);
627 }
628 }
629}
630
631static void button_released_keyboard(void *w_, void* button_, void* user_data) {
632 Widget_t *w = (Widget_t*)w_;
633 Widget_t *p = (Widget_t *)w->parent;
634 if (w->flags & HAS_POINTER) {
636 XButtonEvent *xbutton = (XButtonEvent*)button_;
637 if(xbutton->button == Button1) {
638 keys->send_key = keys->active_key;
639 keys->mk_send_note(p,&keys->send_key,false);
640 keys->active_key = -1;
641 expose_widget(w);
642 }
643 }
644}
645
646static void octave_callback(void *w_, void* user_data) {
647 Widget_t *w = (Widget_t*)w_;
648 Widget_t *p = (Widget_t *)w->parent;
649 MidiKeyboard_mk *keys = (MidiKeyboard_mk*)p->parent_struct;
650 keys->octave = (int)12*adj_get_value(w->adj);
651}
652
653static void layout_callback(void *w_, void* user_data) {
654 Widget_t *w = (Widget_t*)w_;
655 Widget_t *p = (Widget_t *)w->parent;
656 MidiKeyboard_mk *keys = (MidiKeyboard_mk*)p->parent_struct;
657 keys->layout = (int)adj_get_value(w->adj);
658}
659
660static void modwheel_callback(void *w_, void* user_data) {
661 Widget_t *w = (Widget_t*)w_;
662 Widget_t *p = (Widget_t *)w->parent;
663 Widget_t *pa = (Widget_t *)p->parent;
664 MidiKeyboard_mk *keys = (MidiKeyboard_mk*)p->parent_struct;
665 keys->modwheel = (int)adj_get_value(w->adj);
666 keys->mk_send_mod(pa, &keys->modwheel);
667}
668
669static void detune_callback(void *w_, void* user_data) {
670 Widget_t *w = (Widget_t*)w_;
671 Widget_t *p = (Widget_t *)w->parent;
672 Widget_t *pa = (Widget_t *)p->parent;
673 MidiKeyboard_mk *keys = (MidiKeyboard_mk*)p->parent_struct;
674 keys->detune = (int)adj_get_value(w->adj);
675 keys->mk_send_detune(pa, &keys->detune);
676}
677
678static void attack_callback(void *w_, void* user_data) {
679 Widget_t *w = (Widget_t*)w_;
680 Widget_t *p = (Widget_t *)w->parent;
681 Widget_t *pa = (Widget_t *)p->parent;
682 MidiKeyboard_mk *keys = (MidiKeyboard_mk*)p->parent_struct;
683 keys->attack = (int)adj_get_value(w->adj);
684 keys->mk_send_attack(pa, &keys->attack);
685}
686
687static void sustain_callback(void *w_, void* user_data) {
688 Widget_t *w = (Widget_t*)w_;
689 Widget_t *p = (Widget_t *)w->parent;
690 Widget_t *pa = (Widget_t *)p->parent;
691 MidiKeyboard_mk *keys = (MidiKeyboard_mk*)p->parent_struct;
692 keys->sustain = (int)adj_get_value(w->adj);
693 keys->mk_send_sustain(pa, &keys->sustain);
694}
695
696static void release_callback(void *w_, void* user_data) {
697 Widget_t *w = (Widget_t*)w_;
698 Widget_t *p = (Widget_t *)w->parent;
699 Widget_t *pa = (Widget_t *)p->parent;
700 MidiKeyboard_mk *keys = (MidiKeyboard_mk*)p->parent_struct;
701 keys->release = (int)adj_get_value(w->adj);
702 keys->mk_send_release(pa, &keys->release);
703}
704
705static void volume_callback(void *w_, void* user_data) {
706 Widget_t *w = (Widget_t*)w_;
707 Widget_t *p = (Widget_t *)w->parent;
708 Widget_t *pa = (Widget_t *)p->parent;
709 MidiKeyboard_mk *keys = (MidiKeyboard_mk*)p->parent_struct;
710 keys->volume = (int)adj_get_value(w->adj);
711 keys->mk_send_volume(pa, &keys->volume);
712}
713
714static void velocity_callback(void *w_, void* user_data) {
715 Widget_t *w = (Widget_t*)w_;
716 Widget_t *p = (Widget_t *)w->parent;
717 Widget_t *pa = (Widget_t *)p->parent;
718 MidiKeyboard_mk *keys = (MidiKeyboard_mk*)p->parent_struct;
719 keys->velocity = (int)adj_get_value(w->adj);
720 keys->mk_send_velocity(pa, &keys->velocity);
721}
722
723static void pitchwheel_callback(void *w_, void* user_data) {
724 Widget_t *w = (Widget_t*)w_;
725 Widget_t *p = (Widget_t *)w->parent;
726 Widget_t *pa = (Widget_t *)p->parent;
727 MidiKeyboard_mk *keys = (MidiKeyboard_mk*)p->parent_struct;
728 keys->pitchwheel = (int)adj_get_value(w->adj);
729 keys->mk_send_pitch(pa,&keys->pitchwheel);
730}
731
732static void pitchsensity_callback(void *w_, void* user_data) {
733 Widget_t *w = (Widget_t*)w_;
734 Widget_t *p = (Widget_t *)w->parent;
735 Widget_t *pa = (Widget_t *)p->parent;
736 MidiKeyboard_mk *keys = (MidiKeyboard_mk*)p->parent_struct;
737 keys->pitchsensity = (int)adj_get_value(w->adj);
738 keys->mk_send_pitchsensity(pa,&keys->pitchsensity);
739}
740
741static void wheel_key_release(void *w_, void *key_, void *user_data) {
742 Widget_t *w = (Widget_t*)w_;
743 Widget_t *p = (Widget_t *)w->parent;
744 p->func.key_release_callback(p, key_, user_data);
745}
746
747static void wheel_key_press(void *w_, void *key_, void *user_data) {
748 Widget_t *w = (Widget_t*)w_;
749 Widget_t *p = (Widget_t *)w->parent;
750 p->func.key_press_callback(p, key_, user_data);
751}
752
760static void keyboard_mem_free(void *w_, void* user_data) {
761 Widget_t *w = (Widget_t*)w_;
763 free(keys);
764}
765
766static void map_keyboard(void *w_, void* user_data) {
767 Widget_t *w = (Widget_t*)w_;
768 Widget_t *pa = (Widget_t*)w->parent;
770 keys->mk_send_pitchsensity(pa,&keys->pitchsensity);
771 keys->mk_send_pitch(pa,&keys->pitchwheel);
772 keys->mk_send_velocity(pa, &keys->velocity);
773 keys->mk_send_volume(pa, &keys->volume);
774 keys->mk_send_sustain(pa, &keys->sustain);
775 keys->mk_send_mod(pa, &keys->modwheel);
776}
777
778static void key_dummy(Widget_t *w,int *key, bool on_off) {
779 //if (on_off)
780 //fprintf(stderr, "send note on %i\n",(*key));
781 //else
782 //fprintf(stderr, "send note off %i\n",(*key));
783}
784
785static void wheel_dummy(Widget_t *w,int *value) {
786 //fprintf(stderr, "send wheel value %i\n",(*value));
787}
788
789Widget_t *add_keyboard_knob(Widget_t *parent, const char * label,
790 int x, int y, int width, int height) {
791 Widget_t *wid = add_knob(parent,label, x, y, width, height);
792 wid->flags |= NO_AUTOREPEAT;
793 set_adjustment(wid->adj,64.0, 64.0, 0.0, 127.0, 1.0, CL_CONTINUOS);
795 wid->func.key_press_callback = wheel_key_press;
796 wid->func.key_release_callback = wheel_key_release;
797 return wid;
798}
799
801 Widget_t *wid = create_window(w->app, os_get_root_window(w->app, IS_WINDOW), 0, 0, 700, 200);
803 MidiKeyboard_mk *keys = (MidiKeyboard_mk*)malloc(sizeof(MidiKeyboard_mk));
804 wid->parent_struct = keys;
805 wid->parent = w;
806 wid->flags |= HAS_MEM | NO_AUTOREPEAT;
807 keys->prelight_key = -1;
808 keys->active_key = -1;
809 keys->send_key = -1;
810 keys->octave = 12*2;
811 keys->layout = 0;
812 int j = 0;
813 for(;j<4;j++) {
814 keys->key_matrix[j] = 0;
815 }
816
817 wid->func.expose_callback = draw_keyboard;
818 wid->func.motion_callback = keyboard_motion;
819 wid->func.leave_callback = leave_keyboard;
820 wid->func.button_press_callback = button_pressed_keyboard;
821 wid->func.button_release_callback = button_released_keyboard;
822 wid->func.key_press_callback = key_press;
823 wid->func.key_release_callback = key_release;
824 wid->func.mem_free_callback = keyboard_mem_free;
825 wid->func.map_notify_callback = map_keyboard;
826 widget_set_icon_from_png(wid, LDVAR(midikeyboard_png));
827 widget_set_title(wid, "Midi Keyboard");
828 keys->mk_send_note = key_dummy;
829 keys->mk_send_pitch = wheel_dummy;
830 keys->mk_send_pitchsensity = wheel_dummy;
831 keys->mk_send_mod = wheel_dummy;
832 keys->mk_send_detune = wheel_dummy;
833 keys->mk_send_attack = wheel_dummy;
834 keys->mk_send_sustain = wheel_dummy;
835 keys->mk_send_release = wheel_dummy;
836 keys->mk_send_volume = wheel_dummy;
837 keys->mk_send_velocity = wheel_dummy;
838 keys->mk_send_all_sound_off = wheel_dummy;
839
840 Widget_t *p = add_keyboard_knob(wid, "PitchBend", 5, 0, 60, 75);
841 p->func.value_changed_callback = pitchwheel_callback;
842 keys->pitchwheel = (int)adj_get_value(p->adj);
843
844 Widget_t *s = add_keyboard_knob(wid, "P.Sensity", 65, 0, 60, 75);
845 s->func.value_changed_callback = pitchsensity_callback;
846 keys->pitchsensity = (int)adj_get_value(s->adj);
847
848 Widget_t *m = add_keyboard_knob(wid, "ModWheel", 125, 0, 60, 75);
849 m->func.value_changed_callback = modwheel_callback;
850 keys->modwheel = (int)adj_get_value(m->adj);
851
852 Widget_t *de = add_keyboard_knob(wid, "Detune", 185, 0, 60, 75);
853 de->func.value_changed_callback = detune_callback;
854 keys->detune = (int)adj_get_value(de->adj);
855
856 Widget_t *at = add_keyboard_knob(wid, "Attack", 245, 0, 60, 75);
857 at->func.value_changed_callback = attack_callback;
858 keys->attack = (int)adj_get_value(at->adj);
859
860 Widget_t *su = add_keyboard_knob(wid, "Sustain", 305, 0, 60, 75);
861 su->func.value_changed_callback = sustain_callback;
862 keys->sustain = (int)adj_get_value(su->adj);
863
864 Widget_t *re = add_keyboard_knob(wid, "Release", 365, 0, 60, 75);
865 re->func.value_changed_callback = release_callback;
866 keys->release = (int)adj_get_value(re->adj);
867
868 Widget_t *v = add_keyboard_knob(wid, "Volume", 425, 0, 60, 75);
869 v->func.value_changed_callback = volume_callback;
870 keys->volume = (int)adj_get_value(v->adj);
871
872 Widget_t *ve = add_keyboard_knob(wid, "Velocity", 485, 0, 60, 75);
873 set_adjustment(ve->adj,127.0, 127.0, 0.0, 127.0, 1.0, CL_CONTINUOS);
874 ve->func.value_changed_callback = velocity_callback;
875 keys->velocity = (int)adj_get_value(ve->adj);
876
877 Widget_t *b = add_hslider(wid, "Keyboard mapping", 540, 40, 160, 35);
878 b->flags |= NO_AUTOREPEAT;
879 set_adjustment(b->adj,2.0, 2.0, 0.0, 4.0, 1.0, CL_CONTINUOS);
880 adj_set_scale(b->adj, 0.05);
881 b->func.value_changed_callback = octave_callback;
882
883 Widget_t *layout = add_combobox(wid, "", 550, 2, 130, 30);
884 layout->flags |= NO_AUTOREPEAT;
885 layout->scale.gravity = ASPECT;
886 combobox_add_entry(layout,"qwertz");
887 combobox_add_entry(layout,"qwerty");
888 combobox_add_entry(layout,"azerty");
889 combobox_set_active_entry(layout, 0);
890 set_adjustment(layout->adj,0.0, 0.0, 0.0, 2.0, 1.0, CL_ENUM);
891 layout->func.value_changed_callback = layout_callback;
892
893 return wid;
894}
evfunc button_release_callback
Definition xwidget.h:101
xevfunc map_notify_callback
Definition xwidget.h:94
xevfunc expose_callback
Definition xwidget.h:85
evfunc key_release_callback
Definition xwidget.h:105
evfunc key_press_callback
Definition xwidget.h:104
xevfunc leave_callback
Definition xwidget.h:88
xevfunc value_changed_callback
Definition xwidget.h:90
xevfunc mem_free_callback
Definition xwidget.h:92
evfunc motion_callback
Definition xwidget.h:103
evfunc button_press_callback
Definition xwidget.h:100
Metrics_t - struct to receive window size, position & visibility Pass this struct to os_get_window_...
mk_midiwheelfunc mk_send_attack
mk_midiwheelfunc mk_send_sustain
mk_midiwheelfunc mk_send_detune
mk_midikeyfunc mk_send_note
mk_midiwheelfunc mk_send_volume
mk_midiwheelfunc mk_send_mod
mk_midiwheelfunc mk_send_pitchsensity
mk_midiwheelfunc mk_send_velocity
unsigned long key_matrix[4]
mk_midiwheelfunc mk_send_all_sound_off
mk_midiwheelfunc mk_send_release
mk_midiwheelfunc mk_send_pitch
Gravity gravity
Definition xwidget.h:347
Widget_t - struct to hold the basic Widget_t info.
Definition xwidget.h:457
Resize_t scale
Definition xwidget.h:525
Adjustment_t * adj_y
Definition xwidget.h:495
XColor_t * color_scheme
Definition xwidget.h:467
Adjustment_t * adj
Definition xwidget.h:497
void * parent
Definition xwidget.h:471
cairo_t * crb
Definition xwidget.h:489
int state
Definition xwidget.h:511
long long flags
Definition xwidget.h:461
const char * label
Definition xwidget.h:463
void * parent_struct
Definition xwidget.h:473
Func_t func
Definition xwidget.h:481
Xputty * app
Definition xwidget.h:465
Colors normal
Definition xcolor.h:106
Colors selected
Definition xcolor.h:108
bool vk_is_final_char
unsigned int state
int button
int keycode
float adj_get_value(Adjustment_t *adj)
adj_get_value - get the current value of the Adjustment_t
void set_adjustment(Adjustment_t *adj, float std_value, float value, float min_value, float max_value, float step, CL_type type)
*set_adjustment - set a new range to a existing Adjustment_t or create if it not exists yet
Definition xadjustment.c:80
@ CL_CONTINUOS
Definition xadjustment.h:49
@ CL_ENUM
Definition xadjustment.h:55
float adj_get_state(Adjustment_t *adj)
adj_get_state - get the current state of the Adjustment_t
void adj_set_scale(Adjustment_t *adj, float value)
adj_set_scale - internal use to scale the pointer movement (0.1 -1.0)
Color_state get_color_state(Widget_t *wid)
get_color_state - get the Color_state to use in relation to the Widget_t state
Definition xcolor.c:222
void use_text_color_scheme(Widget_t *w, Color_state st)
use_text_color_scheme - use text Colors to paint on Widget_t
Definition xcolor.c:266
@ BACKGROUND_
Definition xcolor.h:65
void use_bg_color_scheme(Widget_t *w, Color_state st)
use_bg_color_scheme - use background Colors to paint on Widget_t
Definition xcolor.c:252
void use_fg_color_scheme(Widget_t *w, Color_state st)
use_fg_color_scheme - use forground Colors to paint on Widget_t
Definition xcolor.c:245
void set_pattern(Widget_t *w, Colors *from, Colors *to, Color_mod mod)
set_pattern - set pattern for the selected Colors
Definition xcolor.c:308
void use_base_color_scheme(Widget_t *w, Color_state st)
use_base_color_scheme - use base Colors to paint on Widget_t
Definition xcolor.c:259
@ NORMAL_
Definition xcolor.h:44
@ SELECTED_
Definition xcolor.h:46
@ PRELIGHT_
Definition xcolor.h:45
@ ACTIVE_
Definition xcolor.h:47
void combobox_set_active_entry(Widget_t *w, int active)
combobox_set_active_entry - set the active combobox entry
Definition xcombobox.c:27
void combobox_add_entry(Widget_t *wid, const char *label)
combobox_add_entry - add a entry to the combobox
Definition xcombobox.c:175
Widget_t * add_combobox(Widget_t *parent, const char *label, int x, int y, int width, int height)
add_combobox - add a combobox
Definition xcombobox.c:152
Widget_t * add_knob(Widget_t *parent, const char *label, int x, int y, int width, int height)
add_knob - add a knob to a Widget_t connect to func.value_changed_callback to implement your actions ...
Definition xknob.c:26
void mk_draw_knob(void *w_, void *user_data)
void mk_keysym_qwerty_to_midi_key(unsigned int inkey, float *midi_key)
void mk_clear_key_matrix(unsigned long *key_matrix)
Widget_t * add_keyboard_knob(Widget_t *parent, const char *label, int x, int y, int width, int height)
bool mk_is_key_in_matrix(unsigned long *key_matrix, int key)
bool mk_have_key_in_matrix(unsigned long *key_matrix)
Widget_t * mk_open_midi_keyboard(Widget_t *w)
void mk_keysym_qwertz_to_midi_key(long inkey, float *midi_key)
void mk_keysym_azerty_to_midi_key(long inkey, float *midi_key)
void widget_set_icon_from_png(Widget_t *w, const unsigned char *name)
widget_set_icon_from_png - set icon image from png binary to Widget_t those icon will be used in the ...
Definition xpngloader.c:159
XID KeySym
Widget_t * add_hslider(Widget_t *parent, const char *label, int x, int y, int width, int height)
add_hslider - add a horizontal slider to a Widget_t connect to func.value_changed_callback to impleme...
Definition xslider.c:51
void os_get_window_metrics(Widget_t *w, Metrics_t *metrics)
os_get_window_metrics - Get the Merics_t struct related to a Widget_t
Window os_get_root_window(Xputty *main, int flag)
os_get_root_window - get a pointer to the root window (desktop)
void os_set_input_mask(Widget_t *w)
os_set_input_mask - set the Event mask to a Widget_t only work on linux, stub on Windows
void widget_set_title(Widget_t *w, const char *title)
widget_set_title - set window title for a Widget_t
Definition xwidget.c:359
void expose_widget(Widget_t *w)
expose_widgets - send a expose event (EXPOSE) to a Widget_t
Definition xwidget.c:445
Widget_t * create_window(Xputty *app, Window win, int x, int y, int width, int height)
*create_window - create a Window You need to create as least minimun one Window to get started....
Definition xwidget.c:163
@ ASPECT
Definition xwidget.h:322
@ HAS_POINTER
Definition xwidget.h:402
@ NO_AUTOREPEAT
Definition xwidget.h:408
@ HAS_MEM
Definition xwidget.h:406
@ IS_WINDOW
Definition xwidget.h:390