Bonjour,

Je suis en train de coder un mini-chat. Il y a un serveur et un ou plusieurs clients. J'utilise les sockets et les threads.
Je voudrais que l'espace, où l'utilisateur écrit, se vide une fois que le message est envoyé.
Aucun soucis quand il clique sur Envoyer, mais si il appuie sur la touche Entrée, il restera un saut de ligne après que l'espace soit vidé.

Les différentes variables :
- text_view : le fameux espace (variable globale)
- view_chat : l'espace d'affichage des messages (variable globale)
- label2 : les personnes connectées (variable globale)

Le code pour les signaux :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
g_signal_connect(G_OBJECT(window2), "key_press_event", G_CALLBACK(on_key_press_chat), NULL);
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(envoi), NULL);
Le code pour l'envoi de message :
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
/* Envoi des messages */
void envoi (GtkWidget* widget) {
	GtkTextBuffer* text_buffer = 0;
	GtkTextIter start;
	GtkTextIter end;
	gchar* buf = 0;
	gdouble upper;
 
	printf("Envoi d'un message au serveur. \n");
 
	// On récupère le buffer
	text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view)); 
	// On récupère l'origine du buffer
	gtk_text_buffer_get_start_iter(text_buffer, &start);
	// On récupère la fin du buffer
	gtk_text_buffer_get_end_iter(text_buffer, &end);
	// On copie le contenu du buffer dans une variable
	buf = gtk_text_buffer_get_text(text_buffer, &start, &end, TRUE);
 
	printf("Message envoye : %s \n", buf);
 
	if (buf[0] != ' ' && buf[0] != '\n') {
		// Envoi du message vers le serveur (strnlen)
		if ((write(socket_descriptor, buf, strlen(buf))) < 0) {
			perror("Erreur : impossible d'ecrire le message destine au serveur");
			exit(1);
		}
	}
 
	g_free(buf);
 
	printf("Fin envoi\n");
}
 
/* Envoie un message en appuyant sur la touche Enter */
gboolean on_key_press_chat (GtkWidget* widget, GdkEventKey* event) {
	if (event->keyval == GDK_Return) {
		envoi(widget);
	}
 
	return 0;
}
Quand l'utilisateur se connecte avec son pseudo au serveur, il y a un thread d'activé. Le code pour la réception de message :
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
/* Réception des messages */
void* reception (void* donnee) {
	GtkTextBuffer* text_buffer = 0;
	GtkTextIter start;
	GtkTextIter end;
	int longueur;
        int connecte = 1;
        int i = 0;
 
        while (1) {
		char buffer[1024] = "";
		char pseudo[50] = "";
                if ((longueur = read(socket_descriptor, buffer, sizeof(buffer))) > 0) {
			printf("Message destinataire : \n");
			write(1, buffer, longueur);
			if (buffer[0] == '/' && buffer[1] == 'z') {
				gtk_label_set_text(GTK_LABEL(label2), str_sub(buffer, 3, longueur));
			}
			else {
				text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view_chat));
				gtk_text_buffer_get_end_iter(text_buffer, &end);
 
				int j = 0;
				// Récupération du pseudo pour le mettre en gras
				while (buffer[j] != ':') {
					sprintf(pseudo, "%s%c", pseudo, buffer[j]);
					j++;
				}
 
				// A faire : Si il existe déjà, ne pas le recrée
				gtk_text_buffer_create_tag(text_buffer, "bold", "weight", PANGO_WEIGHT_BOLD, NULL);
 
				gtk_text_buffer_insert_with_tags_by_name(text_buffer, &end, pseudo, -1, "bold", NULL);
				text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view_chat));
				gtk_text_buffer_get_end_iter(text_buffer, &end);
				gtk_text_buffer_insert(text_buffer, &end, g_locale_to_utf8(str_sub(buffer, j, longueur), -1, NULL, NULL, NULL), -1);
 
				// Ajustement scrollbar				
				GtkTextMark* text_mark = gtk_text_buffer_create_mark(text_buffer, NULL, &end, FALSE);
				gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(view_chat), text_mark, 0, FALSE, 0, 0);
 
				printf("\nFin de la reception via Reception \n");
			}
		}
    }
}
Avec tout ces codes, le text_view n'est pas vidé.
Donc j'ai ajouté la fonction suivante :
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
/* Vider le text_view */
void clearTextView() {
	GtkTextBuffer* text_buffer = 0;
	GtkTextIter start;
	GtkTextIter end;
 
	// On récupère le buffer
	text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view)); 
	// On récupère l'origine du buffer
	gtk_text_buffer_get_start_iter(text_buffer, &start);
	// On récupère la fin du buffer
	gtk_text_buffer_get_end_iter(text_buffer, &end);
	// Supprimer message dans le view_text
	gtk_text_buffer_get_bounds(text_buffer, &start, &end);
	gtk_text_buffer_delete(text_buffer, &start, &end);
}
Et j'ai placé l'appel de cette fonction à différents endroits.
Quand je le place à la fin de la fonction "envoi", ça fait la même chose que ce que j'ai décrit au début de ce message.

Quand je le place à la fin de la fonction "reception", mais avant : printf("\nFin de la reception via Reception \n"), j'ai des erreurs aléatoires quand j'appuie sur la touche Entrée. Mais le saut de ligne est bien supprimé. Il ne se passe rien d'anormal quand je clique sur Envoyer.
Voici les erreurs, elles ne surviennent pas toutes en même temps :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
(client:1934): Gtk-ERROR **: Byte index 0 is off the end of the line
Trappe pour point d'arrêt et de trace (core dumped)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
Erreur de segmentation (core dumped)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
(client:1945): Gtk-WARNING **: Invalid text buffer iterator: either the iterator is uninitialized, or the characters/pixbufs/widgets in the buffer have been modified since the iterator was created.
You must use marks, character numbers, or line numbers to preserve a position across buffer modifications.
You can apply tags and insert marks without invalidating your iterators,
but any mutation that affects 'indexable' buffer contents (contents that can be referred to by character offset)
will invalidate all outstanding iterators
Erreur de segmentation (core dumped)
En espérant que quelqu'un a une idée. Merci