I am encountering the following error (twice) when I try to disable an entry field:
(SDS-CW:7145): Pango-CRITICAL **: 16:38:37.521: pango_layout_get_cursor_pos: assertion 'index >= 0 && index <= layout->length' failed
(SDS-CW:7145): Pango-CRITICAL **: 16:38:37.521: pango_layout_get_cursor_pos: assertion 'index >= 0 && index <= layout->length' failed
The idea is to take an IP Address from an entry field into the program. This all worked perfectly until I started trying to validate the entry was a valid IP Address however. It used to disable the field as soon as the submit button was pressed to prevent the user changing the entered text, however now the field blanks and seems to break, as shown below.
When the entry field is not disabled, I do not get the errors.
However, the validate function seems to run fine, and the check function wait_for_connction()
(being run in a new thread) starts running, but consistently after 1 iteration of the function the pango error is thrown.
Here is the full console output when I enter 192.168.0.254
in the entry field:
/home/csc/CLionProjects/SDS-CW/GUIs/Server/cmake-build-debug/SDS-CW
Valid IP
Selected Server IP: xxx.xxx.xxx.xxx
Checking server...
(SDS-CW:7423): Pango-CRITICAL **: 16:57:11.582: pango_layout_get_cursor_pos: assertion 'index >= 0 && index <= layout->length' failed
(SDS-CW:7423): Pango-CRITICAL **: 16:57:11.582: pango_layout_get_cursor_pos: assertion 'index >= 0 && index <= layout->length' failed
Checking server...
Checking server...
Checking server...
Checking server...
Connected to: xxx.xxx.xxx.xxx
Conn success
Interestingly, I also seem to get the errors again every time the GTK window loses focus and then again when it regains focus.
Here is the callback for the button:
int connect_server(GtkButton *button, gpointer user_data) {
struct data *server_data = (struct data*)user_data;
GtkWidget *serverIPEntry = server_data->serverIPEntry;
GtkWidget *sererPortEntry = server_data->serverPortEntry;
GtkWidget *connectButton = server_data->connectButton;
GtkWidget *serverIPErrorLabel = server_data->serverIPErrorLabel;
GtkWidget *serverPortErrorLabel = server_data->serverPortErrorLabel;
char* serverIP = (char*)gtk_entry_get_text(GTK_ENTRY(serverIPEntry));
char* serverPortStr = (char*)gtk_entry_get_text(GTK_ENTRY(sererPortEntry));
int serverPort = atoi(serverPortStr);
int status;
gtk_widget_set_name(serverIPEntry, "fieldsNormal");
gtk_label_set_text(GTK_LABEL(serverIPErrorLabel), "");
// TODO: Check for valid IP and Port
if (strcmp(serverIP, "") == 0) {
gtk_widget_set_name(serverIPEntry, "fieldsError");
gtk_label_set_text(GTK_LABEL(serverIPErrorLabel), "Please enter an IP");
return -1;
} else if (validate_ip(serverIP) == 1){
// TODO: Check if IP Address given is valid
g_print("Valid IP\n");
} else {
g_print("Invalid IP\n");
}
g_print("Selected Server IP: %s\n", selectedServerStr);
gtk_widget_set_sensitive(connectButton, FALSE);
append_to_log("Attempting connection, please wait...\n", 1);
gtk_widget_set_sensitive(serverIPEntry, FALSE); // ERROR HAPPENING WHEN I RUN THIS LINE
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(workingSetProgressBar), "Connecting...");
status = pthread_create(&connThread, NULL, wait_for_connection, server_data);
// TODO: Check thread status code
if (status != 0) {
printf("Thread returned error code %d\n", status);
exit(-1);
}
return 1;
}
void *wait_for_connection(void* server_data) {
struct data *srvDat = server_data;
GtkWidget *disconnectButton = srvDat->disconnectButton;
GtkWidget *connectButton = srvDat->connectButton;
GtkWidget *statLabel = srvDat->statLabel;
GtkWidget *serverIPEntry = srvDat->serverIPEntry;
requestConnect = 1;
for (int i = 0; i < 10; i++) {
gtk_progress_bar_pulse(GTK_PROGRESS_BAR(workingSetProgressBar));
g_print("Checking server...\n");
// THIS BELOW IS FOR TESTING ONLY
if (i == 4) {
connected = 1;
}
// THIS ABOVE IS FOR TESTING ONLY
if (connected == 1) {
connSuccess = 1;
break;
}
connSuccess = 0;
sleep(1);
}
if (connSuccess == 1) {
g_print("Connected to: %s\n", selectedServerStr);
printf("Conn success\n");
// TODO: Change button to disconnect button
// TODO: Set progress to 0
gtk_widget_hide(connectButton);
gtk_widget_show(disconnectButton);
gtk_widget_set_name(statLabel, "connLabel");
gtk_label_set_text(GTK_LABEL(statLabel), "Connected");
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(workingSetProgressBar), 0);
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(workingSetProgressBar), NULL);
char* connLog = "Connected To: ";
char* strToLog;
if((strToLog = malloc(strlen(connLog)+strlen(selectedServerStr)+5)) != NULL){
strToLog[0] = '\0';
strcat(strToLog, connLog);
strcat(strToLog, selectedServerStr);
strcat(strToLog, "\n");
} else {
// TODO: Deal with failed malloc
}
append_to_log(strToLog, 1);
pthread_exit(&connThread);
} else if (connSuccess == 0) {
gtk_widget_set_sensitive(serverIPEntry, TRUE);
gtk_widget_set_sensitive(connectButton, TRUE);
printf("Conn failed\n");
append_to_log("Connection failed\n", 1);
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(workingSetProgressBar), 0);
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(workingSetProgressBar), "Disconnected");
pthread_exit(&connThread);
}
}
And here is the function validate_ip()
that I am using to validate the entry as an IP Address, which seems to have led to this issue:
int validate_number(char *str) {
while (*str) {
if(!isdigit(*str)){ //if the character is not a number, return false
return 0;
}
str++; //point to next character
}
return 1;
}
int validate_ip(char *ip) { //check whether the IP is valid or not
int i, num, dots = 0;
char *ptr;
if (ip == NULL)
return 0;
ptr = strtok((char*)ip, "."); //cut the string using dot delimiter
if (ptr == NULL)
return 0;
while (ptr) {
if (!validate_number(ptr)) //check whether the sub string is holding only number or not
return 0;
num = atoi(ptr); //convert substring to number
if (num >= 0 && num <= 255) {
ptr = strtok(NULL, "."); //cut the next part of the string
if (ptr != NULL)
dots++; //increase the dot count
} else
return 0;
}
if (dots != 3) //if the number of dots are not 3, return false
return 0;
return 1;
}
Any help would be greatly appreciated. Thanks!
Just managed to fix this issue by changing the start of the validate_ip()
function to as follows:
int validate_ip(char *ipOrig) { //check whether the IP is valid or not
char* ip[17];
strcpy((char*)ip, ipOrig);
int i, num, dots = 0;
char *ptr;
....
Looks like it was an issue to do with the validate_ip()
function changing the value of the variable passed into it, so I duplicated the incoming variable to be used within the function.