[SOLVED] I need help getting a progressbar in GTK with C, with libcurl

Hello programmers,

Recently I converted one of the RuneScape Client for Unix's perl scripts to C. This particular script downloads a file from Jagex's server (RuneScape developer), extracts it and places it in a directory. It worked succesfully (and was my first "own" application) but now I want to write a GUI around it, using GTK.

I am already making some good progress I think and now I got to the point in which I want to fill a progressbar when the application is downloading said file from Jagex's server. To download this file, I am using libcurl. I searched extensively on Google but to no avail: I only found outdated examples which I could not get to work.

I can get an empty progressbar to show up and I can succesfully download the file in the background; I just can not get it to actually fill the progressbar with the progress it is making. I've been trying different solutions all day and nothing has worked so far, so I am asking your help. Functions you might have to look at are write_data, update_progressbar and downloadwindowsclient.

If you need more information, please ask and I will deliver!

Here's the code I currently have: EDIT: see second post for up-to-date code!

Re: [SOLVED] I need help getting a progressbar in GTK with C, with libcurl

Oke I did some more work. I now get output (printed in terminal) of what it has currently downloaded and what is the total amount it needs to download. Also it now shows a filled progressbar when the download is finished. Now all that is left (I think) is to get some maths in there so both values are between 0 and 1 (GtkProgressbar only accepts values between 0 and 1, I believe) and then it might just work.

However, both values are pretty big (download total is 2,36421e+07) so I wonder if there is some simple utility I can use instead of extensive maths?

Re: [SOLVED] I need help getting a progressbar in GTK with C, with libcurl

Size of the values doesn't matter - how extensive would the math have to be? Assuming the current and total values are in appropriate data types (double or long double perhaps) just do set the progressbar value to current/total.

Re: [SOLVED] I need help getting a progressbar in GTK with C, with libcurl

Trilby wrote:

Size of the values doesn't matter - how extensive would the math have to be? Assuming the current and total values are in appropriate data types (double or long double perhaps) just do set the progressbar value to current/total.

I have no idea. I am under the impression that GtkProgressbar only accepts values between 0.0 and 1.0 so my fraction variable should be between that. You are right though that the sizes of dlnow and dltotal do not matter (as much) then, I don't know what I was thinking

Libcurl outputs dlnow and dltotal as double and GtkProgressbar needs a gdouble. Is that the information you need?

EDIT: fraction is indeed always between 0.0 and 1.0, so I do not need any maths. I don't know why it doesn't work then, perhaps I'm feeding too much numbers into GtkProgressbar? Right now, fraction contains as much as eight decimals (is that the correct English term?) and perhaps I can only feed it two.

Last edited by Unia (2013-02-03 15:25:04)

If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Re: [SOLVED] I need help getting a progressbar in GTK with C, with libcurl

It looks right to me - but I've never really used GTK. Does it need any calls to a flush/udpate function (analogous to Xlib's XFlush())?

Can you test just the progressbar in a loop that progressively increases the value?

EDIT: the number of decimal places is irrelevant. If there are too many they would be truncated by the assignment. But in this case that doesn't even happen as gdouble is simply a typedef of double (ridiculous "branding" for the sake of branding).

EDIT: When I use gtk_progressbar_get_fraction to read the fraction the progressbar is supposed to show, it does return correct values. I'm thinking I need a call somewhere to update the progressbar but I can't find anything in the documentation. Or perhaps I need to use something like fraction += new_fraction - fraction, as the example?

EDIT2: Tested my above question: still no result.

Last edited by Unia (2013-02-03 17:21:26)

If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Re: [SOLVED] I need help getting a progressbar in GTK with C, with libcurl

Oke new update. I can check the value of fraction with gtk_progress_bar_get_fraction(). I do that with these piece of code and as you can see I print it next to the value of fraction I feed the progressbar. Both are the same (as we would expect). What is strange, however, is that apparently the progressbar does have the fraction; it just doesn't display it. Does anyone have a clue what's going on here?

Here's my function as it is now, reporting both the fraction I feed the progressbar and the fraction it returns (fraction2):

Re: [SOLVED] I need help getting a progressbar in GTK with C, with libcurl

It is outdated, I have already checked it. The method used there I can not apply anymore.

I'm thinking I have to move my call to gtk_progress_bar_set_fraction somewhere else. The problem with this however, is that the update_progressbar function has to return 0, because that is required by libcurl. If I would move the call to gtk_progress_bar_set_fraction, I would have to have the update_progressbar function return fraction, which will make it crash. Any ideas?

Last edited by Unia (2013-02-03 18:21:41)

If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Re: [SOLVED] I need help getting a progressbar in GTK with C, with libcurl

I think the problem is probably that curl is doing the download in the only thread of your process, and after your call to gtk_progress_bar_set_fraction GTK doesn't get to process events to refresh the UI. That's why the curl example falconindy linked to uses another thread to have curl do its work, so that GTK can process events & refresh the UI in the main thread.

A solution would be to do the same, run curl into another thread, but make sure the call to gtk_progress_bar_set_fraction happens in the main thread. Or you might try to simply add some call to gtk_main_iteration after you set the fraction, to give GTK a chance to refresh the UI. E.g:

Re: [SOLVED] I need help getting a progressbar in GTK with C, with libcurl

You are the man jjacky! After two days of tinkering with it it FINALLY works! I'm going to read into this so I will never make this mistake again.

Thanks a ton jjacky!

EDIT: I should probably apologise to falconindy then, as I just discarded his suggestion even though it did contain a pointer to the solution. When I tried that code though, it said gdk_thread_* was deprecated and as I started Googling, I came accros references that said these functions are done automatically now. That's why I didn't think of it. Sorry, falconindy.

Last edited by Unia (2013-02-03 19:23:57)

If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres