aboutsummaryrefslogtreecommitdiff
path: root/keyboard_layout.c
blob: 4c7c88ec73d08cecfd40e26d72d6fe9749bdba3d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* Copyright 2006 Fredrik Olofsson
 * Copyright 2007 Free Software Foundation
 *   ported to Pd by Hans-Christoph Steiner <hans@at.or.at> from f0.keyboard_layout.c
 */

#ifdef __APPLE__

#include "m_pd.h"
#include <Carbon/Carbon.h>

static t_class *keyboard_layout_class;

typedef struct _keyboard_layout {
	t_object    x_obj;
    t_outlet*   x_data_outlet;
    t_outlet*   x_status_outlet;
} t_keyboard_layout;

/*
void keyboard_layout_assist(t_keyboard_layout *x, Object *m, long msg, long arg, char *dst) {
	if(msg==ASSIST_INLET) {
		sprintf(dst, "bang to get current, symbol to set");
	} else if(msg==ASSIST_OUTLET) {
		switch(arg) {
			case 0:
				sprintf(dst, "current keyboard layout (symbol)");
				break;
			case 1:
				sprintf(dst, "dump outlet (for menu)");
				break;
		}
	}
}
*/

//----------------------------------------------------------------------------------------------
void keyboard_layout_bang(t_keyboard_layout *x) {
	//OSStatus err;
	KeyboardLayoutRef currentLayoutRef;
	CFStringRef keyboardName;
	char cKeyboardName[100];
	
	KLGetCurrentKeyboardLayout(&currentLayoutRef);
	KLGetKeyboardLayoutProperty(currentLayoutRef, kKLName, (const void **)&keyboardName);
	CFStringGetCString(keyboardName, cKeyboardName, 100, kCFStringEncodingASCII);
	
    outlet_anything(x->x_data_outlet, gensym(cKeyboardName), 0, NULL);
}

void keyboard_layout_menu(t_keyboard_layout *x) {
	//OSStatus err;
	KeyboardLayoutRef currentLayoutRef;
	CFStringRef keyboardName;
	char cKeyboardName[100];
	CFIndex countOfLayouts;
	CFIndex i;
	t_atom name;
	
// TODO this should probably output [menu clear( so other messages work too
    outlet_anything(x->x_status_outlet, gensym("clear"), 0, NULL);
	
	KLGetKeyboardLayoutCount(&countOfLayouts);
	for(i= 0; i<countOfLayouts; i++) {
		KLGetKeyboardLayoutAtIndex(i, &currentLayoutRef);
		KLGetKeyboardLayoutProperty(currentLayoutRef, kKLName, (const void **)&keyboardName);
		CFStringGetCString(keyboardName, cKeyboardName, 100, kCFStringEncodingASCII);
		
		SETSYMBOL(&name, gensym(cKeyboardName));
// TODO this should probably output [menu append( so other messages work too
        outlet_anything(x->x_status_outlet, gensym("append"), 1, &name);
	}
}

void keyboard_layout_anything(t_keyboard_layout *x, t_symbol *s, short argc, t_atom *argv) {
	//OSStatus err;
	KeyboardLayoutRef currentLayoutRef;
	CFStringRef keyboardName;
	char cKeyboardName[100];
	
	keyboardName= CFStringCreateWithCString(NULL, s->s_name, kCFStringEncodingASCII);
	KLGetKeyboardLayoutWithName(keyboardName, &currentLayoutRef);
	KLGetKeyboardLayoutProperty(currentLayoutRef, kKLName, (const void **)&keyboardName);
	CFStringGetCString(keyboardName, cKeyboardName, 100, kCFStringEncodingASCII);
	KLSetCurrentKeyboardLayout(currentLayoutRef);
	//outlet_anything(x->t_out, s, 0, NULL);
	keyboard_layout_bang(x);
}

void *keyboard_layout_new(void) {
    t_keyboard_layout *x = (t_keyboard_layout *)pd_new(keyboard_layout_class);

    x->x_data_outlet = outlet_new(&x->x_obj, &s_float);
    x->x_status_outlet = outlet_new(&x->x_obj, &s_symbol);

    return (x);
}

//----------------------------------------------------------------------------------------------
void keyboard_layout_setup(void) {
    keyboard_layout_class = class_new(gensym("keyboard_layout"), 
                                      (t_newmethod)keyboard_layout_new, 
                                      NULL,
                                      sizeof(t_keyboard_layout),
                                      0, A_GIMME, 0);
	
	class_addbang(keyboard_layout_class, (t_method)keyboard_layout_bang);
	class_addanything(keyboard_layout_class, (t_method)keyboard_layout_anything);

	class_addmethod(keyboard_layout_class, (t_method)keyboard_layout_menu, 
                    gensym("menu"), 0);
//	class_addmethod(keyboard_layout_class, (t_method)keyboard_layout_assist, 
//                    gensym("assist"), A_CANT, 0);
	
	post("f0.keyboard_layout v1.1-ub; distributed under GNU GPL license");		//target specific
}


#else /* GNU/Linux and Windows */


void keyboard_layout_new(void)
{
	post("f0.keyboard_layout v1.1-ub; distributed under GNU GPL license");
    post("ERROR: this objectclass is currently only for Mac OS X");
}

void keyboard_layout_setup(void)
{
    keyboard_layout_class = class_new(gensym("text"), (t_method)keyboard_layout_new, 
                                 NULL, sizeof(t_keyboard_layout), 0, 0);
}

#endif /* __APPLE__ */