Bonjour à tous,

Je suis en train d'essayer de développer un petit mixer son avec une interface graphique GTK.
Je crée un second thread grâce à g_idle_add() et comme ma fonction avait besoin de plus d'arguments (g_idle_add est limité à 1 argument), j'ai crée un pointeur sur structure pour passer plusieurs arguments à cette fonction : l'objet slider et le volume.

Mon soucis se situe au niveau des fonctions GTK comme gtk_range_get_value() et gtk_range_set_value() qui me créent des segmentation fault.

J'ai beau chercher je n'arrive pas à en trouver la cause ...
J'ai essayé de revoir mes cours sur les pointeurs mais pas moyen de trouver où est l'erreur.

Voici le code :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <math.h>
#include <alsa/asoundlib.h>
#include <alsa/mixer.h>
 
struct soundth_args {
	long volume;
	GtkScale *slider;
};
 
int       	sound_thread(gpointer user_data);
int		get_volume(long *volume);
//int		write_volume(const char mixer[], gdouble volume);
static void	quit(GtkWidget *icon, gpointer user_data); 
static void	show_window(GtkWidget *icon, GtkWidget *win);
static void	slider_moved(GtkWidget *range, gpointer user_data);
static void	view_popup_menu(GtkWidget *icon, gpointer user_data);
 
 
int
sound_thread(gpointer user_data) {
	struct soundth_args *args = user_data;
	if(get_volume(args->volume) != gtk_range_get_value(GTK_RANGE(&(args->slider)))) {
		get_volume(&(args->volume));
		g_print("%d\n",args->volume);
		gtk_range_set_value(args->slider, args->volume);	
	}
//	gtk_range_set_adjustment(GTK_RANGE(args->slider),args->volume);
//	gtk_scale_set_value_pos(args->slider, args->volume);
}
 
static void
view_popup_menu(GtkWidget *icon, gpointer user_data) {
	GtkWidget *menu, *menuitem;
 
	menu = gtk_menu_new();
	menuitem = gtk_menu_item_new_with_label("Quit");
 
	g_signal_connect(menuitem, "activate", G_CALLBACK(quit), icon);
 
	gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
	gtk_widget_show_all(menu);
 
	gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, NULL, NULL);
}
/*
int
write_volume(const char mixer[], gdouble volume) {
	int fd_mixer, vol, v;
 
	if((fd_mixer = open(mixer, O_RDWR)) < 0) {
		printf("write_volume(): open %s failed !!\n", mixer);
		perror(mixer);
		exit(1);
	}
 
	v = volume;
	vol = 10*log((v << 8) | v);
 
	if(ioctl(fd_mixer, SOUND_MIXER_WRITE_VOLUME, &vol) == -1) 
		perror("ioctl");
 
	close(fd_mixer);
}
*/
static void
quit(GtkWidget *icon, gpointer user_data) {
	gtk_main_quit();
}
 
static void
show_window(GtkWidget *icon, GtkWidget *win) {
	if(gtk_widget_get_visible(win))
		gtk_widget_hide(win);
	else
		gtk_widget_show_all(win);
}
 
static void 
slider_moved(GtkWidget *range, gpointer user_data) {
	gdouble pos = gtk_range_get_value(GTK_RANGE(range));
	//g_print(g_strdup_printf("%d\n", pos));
	//write_volume(mixer_dev, pos);
}
 
int
get_volume(long *volume) {
	long minv, maxv;
	snd_mixer_t *handle;
	snd_mixer_selem_id_t *sid;
	const char *card = "default";
	snd_mixer_elem_t *elem;
 
	if((snd_mixer_open(&handle, 0)) < 0) {
		snd_mixer_close(handle);
		return -1;
	}
 
	if((snd_mixer_attach(handle, card)) < 0) {
		snd_mixer_close(handle);
		return -2;
	}
 
	if((snd_mixer_selem_register(handle, NULL, NULL)) < 0) {
		snd_mixer_close(handle);
		return -3;
	}
 
	if(snd_mixer_load(handle) < 0) {
		snd_mixer_close(handle);
		return -4;
	}
 
	snd_mixer_selem_id_alloca(&sid);
	snd_mixer_selem_id_set_index(sid, 0);
	snd_mixer_selem_id_set_name(sid, "Master");
 
	elem = snd_mixer_find_selem(handle, sid);
	if(!elem) {
		snd_mixer_close(handle);
		return -5;
	}
 
	snd_mixer_selem_get_playback_volume_range(elem, &minv, &maxv);
	if(snd_mixer_selem_get_playback_volume(elem, 0, volume) < 0) {
		snd_mixer_close(handle);
		return -6;
	}
	*volume -= minv;
	maxv -= minv;
	minv = 0;
	*volume = 100 * (*volume) / maxv;
	snd_mixer_close(handle);
}
 
int
main (int argc, char **argv)  {
	long volume;
	GtkWidget *window;
	GtkScale *slider;
	GtkAdjustment *adjust;
	GtkMenu *menu;
	GtkStatusIcon *tray;
	GdkRectangle area;
	struct soundth_args *args = malloc(sizeof(*args));
 
	get_volume(&volume);
	get_volume(&(args->volume));
	args->slider = slider;
 
	gtk_init(&argc, &argv);
 
	tray = gtk_status_icon_new_from_file("./vol.png");
	gtk_status_icon_get_geometry(tray, NULL, &area, NULL);
	window = gtk_window_new(GTK_WINDOW_POPUP);
	gtk_window_set_default_size(GTK_WINDOW(window), 40, 150);
	gtk_window_move(GTK_WINDOW(window), area.x, area.y-160);
 
	adjust = gtk_adjustment_new(volume, 0, 101, 1, 1, 1);
	slider = gtk_scale_new(GTK_ORIENTATION_VERTICAL, adjust);
	gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(slider));
 
	g_idle_add(sound_thread, args); 
 
	g_signal_connect(tray, "activate", G_CALLBACK(show_window), window);
	g_signal_connect(slider, "value-changed", G_CALLBACK(slider_moved), NULL);
	g_signal_connect(tray, "popup-menu", G_CALLBACK(view_popup_menu), menu);
 
	gtk_main();
	free(args);
 
	return EXIT_SUCCESS;
 
}
Merci pour votre aide.