]> cygwin.com Git - cygwin-apps/setup.git/blob - geturl.cc
* resource.h: Add new field IDC_CHOOSE_INST_TEXT. Modify
[cygwin-apps/setup.git] / geturl.cc
1 /*
2 * Copyright (c) 2000, Red Hat, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by DJ Delorie <dj@cygnus.com>
13 *
14 */
15
16 /* The purpose of this file is to act as a pretty interface to
17 netio.cc. We add a progress dialog and some convenience functions
18 (like collect to string or file */
19
20 static char *cvsid = "\n%%% $Id$\n";
21
22 #include "win32.h"
23 #include "commctrl.h"
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <errno.h>
28
29 #include "dialog.h"
30 #include "geturl.h"
31 #include "resource.h"
32 #include "netio.h"
33 #include "msg.h"
34 #include "log.h"
35 #include "state.h"
36 #include "diskfull.h"
37
38 static int is_showing = 0;
39 static HWND gw_dialog = 0;
40 static HWND gw_url = 0;
41 static HWND gw_rate = 0;
42 static HWND gw_progress = 0;
43 static HWND gw_pprogress = 0;
44 static HWND gw_iprogress = 0;
45 static HWND gw_progress_text = 0;
46 static HWND gw_pprogress_text = 0;
47 static HWND gw_iprogress_text = 0;
48 static HANDLE init_event;
49 static int max_bytes = 0;
50
51 int total_download_bytes = 0;
52 int total_download_bytes_sofar = 0;
53
54 static BOOL
55 dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
56 {
57 switch (id)
58 {
59 case IDCANCEL:
60 exit_setup (0);
61 }
62 }
63
64 static BOOL CALLBACK
65 dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
66 {
67 int i, j;
68 HWND listbox;
69 switch (message)
70 {
71 case WM_INITDIALOG:
72 gw_dialog = h;
73 gw_url = GetDlgItem (h, IDC_DLS_URL);
74 gw_rate = GetDlgItem (h, IDC_DLS_RATE);
75 gw_progress = GetDlgItem (h, IDC_DLS_PROGRESS);
76 gw_pprogress = GetDlgItem (h, IDC_DLS_PPROGRESS);
77 gw_iprogress = GetDlgItem (h, IDC_DLS_IPROGRESS);
78 gw_progress_text = GetDlgItem (h, IDC_DLS_PROGRESS_TEXT);
79 gw_pprogress_text = GetDlgItem (h, IDC_DLS_PPROGRESS_TEXT);
80 gw_iprogress_text = GetDlgItem (h, IDC_DLS_IPROGRESS_TEXT);
81 SetEvent (init_event);
82 return FALSE;
83 case WM_COMMAND:
84 return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd);
85 }
86 return FALSE;
87 }
88
89 static WINAPI DWORD
90 dialog (void *)
91 {
92 int rv = 0;
93 MSG m;
94 HWND gw_dialog = CreateDialog (hinstance, MAKEINTRESOURCE (IDD_DLSTATUS),
95 0, dialog_proc);
96 ShowWindow (gw_dialog, SW_SHOWNORMAL);
97 UpdateWindow (gw_dialog);
98 while (GetMessage (&m, 0, 0, 0) > 0) {
99 TranslateMessage (&m);
100 DispatchMessage (&m);
101 }
102 }
103
104 static DWORD start_tics;
105
106 static void
107 init_dialog (char *url, int length)
108 {
109 if (gw_dialog == 0)
110 {
111 DWORD tid;
112 HANDLE thread;
113 init_event = CreateEvent (0, 0, 0, 0);
114 thread = CreateThread (0, 0, dialog, 0, 0, &tid);
115 WaitForSingleObject (init_event, 1000);
116 CloseHandle (init_event);
117 SendMessage (gw_progress, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
118 SendMessage (gw_pprogress, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
119 SendMessage (gw_iprogress, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
120 is_showing = 0;
121 }
122 char *sl=url, *cp;
123 for (cp=url; *cp; cp++)
124 if (*cp == '/' || *cp == '\\' || *cp == ':')
125 sl = cp+1;
126 max_bytes = length;
127 SetWindowText (gw_url, sl);
128 SetWindowText (gw_rate, "Connecting...");
129 SendMessage (gw_progress, PBM_SETPOS, (WPARAM) 0, 0);
130 ShowWindow (gw_progress, (length > 0) ? SW_SHOW : SW_HIDE);
131 if (length > 0 )
132 SetWindowText (gw_progress_text, "Package");
133 else
134 SetWindowText (gw_progress_text, " ");
135 ShowWindow (gw_pprogress, (total_download_bytes > 0) ? SW_SHOW : SW_HIDE);
136 if (total_download_bytes > 0)
137 {
138 SetWindowText (gw_pprogress_text, "Total");
139 SetWindowText (gw_iprogress_text, "Disk");
140 }
141 else
142 {
143 SetWindowText (gw_pprogress_text, " ");
144 SetWindowText (gw_iprogress_text, " ");
145 }
146 ShowWindow (gw_iprogress, (total_download_bytes > 0) ? SW_SHOW : SW_HIDE);
147 ShowWindow (gw_dialog, SW_SHOWNORMAL);
148 if (!is_showing)
149 {
150 SetForegroundWindow (gw_dialog);
151 is_showing = 1;
152 }
153 start_tics = GetTickCount ();
154 }
155
156
157 static void
158 progress (int bytes)
159 {
160 static char buf[100];
161 int kbps;
162 static int last_tics = 0;
163 DWORD tics = GetTickCount ();
164 if (tics == start_tics) // to prevent division by zero
165 return;
166 if (tics < last_tics + 200) // to prevent flickering updates
167 return;
168 last_tics = tics;
169
170 kbps = bytes / (tics - start_tics);
171 ShowWindow (gw_progress, (max_bytes > 0) ? SW_SHOW : SW_HIDE);
172 ShowWindow (gw_pprogress, (total_download_bytes > 0) ? SW_SHOW : SW_HIDE);
173 ShowWindow (gw_iprogress, (total_download_bytes > 0) ? SW_SHOW : SW_HIDE);
174 if (max_bytes > 100)
175 {
176 int perc = bytes / (max_bytes / 100);
177 SendMessage (gw_progress, PBM_SETPOS, (WPARAM) perc, 0);
178 sprintf (buf, "%3d %% (%dk/%dk) %d kb/s\n",
179 perc, bytes/1000, max_bytes/1000, kbps);
180 if (total_download_bytes > 0)
181 {
182 int totalperc = (total_download_bytes_sofar + bytes) / (
183 total_download_bytes / 100);
184 SendMessage (gw_pprogress, PBM_SETPOS, (WPARAM) totalperc, 0);
185 }
186 }
187 else
188 sprintf (buf, "%d %d kb/s\n", bytes, kbps);
189
190 SetWindowText (gw_rate, buf);
191 }
192
193 struct GUBuf {
194 GUBuf *next;
195 int count;
196 char buf[2000];
197 };
198
199 char *
200 get_url_to_string (char *_url)
201 {
202 log (LOG_BABBLE, "get_url_to_string %s", _url);
203 init_dialog (_url, 0);
204 NetIO *n = NetIO::open (_url);
205 if (!n || !n->ok ())
206 {
207 delete n;
208 log (LOG_BABBLE, "get_url_to_string failed!");
209 return 0;
210 }
211
212 if (n->file_size)
213 max_bytes = n->file_size;
214
215 GUBuf *bufs = 0;
216 GUBuf **nextp = &bufs;
217 int total_bytes = 1; /* for the NUL */
218 progress (0);
219 while (1)
220 {
221 GUBuf *b = new GUBuf;
222 *nextp = b;
223 b->next = 0;
224 nextp = &(b->next);
225
226 b->count = n->read (b->buf, sizeof (b->buf));
227 if (b->count <= 0)
228 break;
229 total_bytes += b->count;
230 progress (total_bytes);
231 }
232
233 char *rv = (char *) malloc (total_bytes);
234 char *rvp = rv;
235 while (bufs && bufs->count > 0)
236 {
237 GUBuf *tmp = bufs->next;
238 memcpy (rvp, bufs->buf, bufs->count);
239 rvp += bufs->count;
240 delete bufs;
241 bufs = tmp;
242 }
243 *rvp = 0;
244 return rv;
245 }
246
247 int
248 get_url_to_file (char *_url, char *_filename, int expected_length)
249 {
250 log (LOG_BABBLE, "get_url_to_file %s %s", _url, _filename);
251 if (total_download_bytes > 0)
252 {
253 int df = diskfull (root_dir);
254 SendMessage (gw_iprogress, PBM_SETPOS, (WPARAM) df, 0);
255 }
256 init_dialog (_url, expected_length);
257
258 remove (_filename); /* but ignore errors */
259
260 NetIO *n = NetIO::open (_url);
261 if (!n || !n->ok ())
262 {
263 delete n;
264 log (LOG_BABBLE, "get_url_to_file failed!");
265 return 1;
266 }
267
268 FILE *f = fopen (_filename, "wb");
269 if (!f)
270 {
271 char *err = strerror (errno);
272 if (!err)
273 err = "(unknown error)";
274 fatal (IDS_ERR_OPEN_WRITE, _filename, err);
275 }
276
277 if (n->file_size)
278 max_bytes = n->file_size;
279
280 int total_bytes = 0;
281 progress (0);
282 while (1)
283 {
284 char buf[8192];
285 int count;
286 count = n->read (buf, sizeof (buf));
287 if (count <= 0)
288 break;
289 fwrite (buf, 1, count, f);
290 total_bytes += count;
291 progress (total_bytes);
292 }
293
294 total_download_bytes_sofar += total_bytes;
295
296 fclose (f);
297
298 if (total_download_bytes > 0)
299 {
300 int df = diskfull (root_dir);
301 SendMessage (gw_iprogress, PBM_SETPOS, (WPARAM) df, 0);
302 }
303
304 return 0;
305 }
306
307 void
308 dismiss_url_status_dialog ()
309 {
310 ShowWindow (gw_dialog, SW_HIDE);
311 is_showing = 0;
312 }
This page took 0.053274 seconds and 6 git commands to generate.