]>
Commit | Line | Data |
---|---|---|
23c9e63c DD |
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 | #include "win32.h" | |
21 | #include "commctrl.h" | |
22 | ||
23 | #include <stdio.h> | |
24 | #include <stdlib.h> | |
25 | #include <errno.h> | |
26 | ||
27 | #include "dialog.h" | |
28 | #include "geturl.h" | |
29 | #include "resource.h" | |
30 | #include "netio.h" | |
31 | #include "msg.h" | |
32 | ||
33 | static int is_showing = 0; | |
34 | static HWND gw_dialog = 0; | |
35 | static HWND gw_url = 0; | |
36 | static HWND gw_rate = 0; | |
37 | static HWND gw_progress = 0; | |
38 | static HANDLE init_event; | |
39 | static int max_bytes = 0; | |
40 | ||
41 | static BOOL | |
42 | dialog_cmd (HWND h, int id, HWND hwndctl, UINT code) | |
43 | { | |
44 | switch (id) | |
45 | { | |
46 | case IDCANCEL: | |
1fd6d0a2 | 47 | ExitProcess (0); |
23c9e63c DD |
48 | } |
49 | } | |
50 | ||
51 | static BOOL CALLBACK | |
52 | dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam) | |
53 | { | |
54 | int i, j; | |
55 | HWND listbox; | |
56 | switch (message) | |
57 | { | |
58 | case WM_INITDIALOG: | |
59 | gw_dialog = h; | |
60 | gw_url = GetDlgItem (h, IDC_DLS_URL); | |
61 | gw_rate = GetDlgItem (h, IDC_DLS_RATE); | |
62 | gw_progress = GetDlgItem (h, IDC_DLS_PROGRESS); | |
63 | SetEvent (init_event); | |
64 | return FALSE; | |
65 | case WM_COMMAND: | |
1fd6d0a2 | 66 | return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd); |
23c9e63c DD |
67 | } |
68 | return FALSE; | |
69 | } | |
70 | ||
71 | static WINAPI DWORD | |
72 | dialog (void *) | |
73 | { | |
74 | int rv = 0; | |
75 | MSG m; | |
76 | HANDLE gw_dialog = CreateDialog (hinstance, MAKEINTRESOURCE (IDD_DLSTATUS), | |
77 | 0, dialog_proc); | |
78 | ShowWindow (gw_dialog, SW_SHOWNORMAL); | |
79 | UpdateWindow (gw_dialog); | |
80 | while (GetMessage (&m, 0, 0, 0) > 0) { | |
81 | TranslateMessage (&m); | |
82 | DispatchMessage (&m); | |
83 | } | |
84 | } | |
85 | ||
86 | static DWORD start_tics; | |
87 | ||
88 | static void | |
89 | init_dialog (char *url, int length) | |
90 | { | |
91 | if (gw_dialog == 0) | |
92 | { | |
93 | DWORD tid; | |
94 | HANDLE thread; | |
95 | init_event = CreateEvent (0, 0, 0, 0); | |
96 | thread = CreateThread (0, 0, dialog, 0, 0, &tid); | |
97 | WaitForSingleObject (init_event, 1000); | |
98 | CloseHandle (init_event); | |
99 | SendMessage (gw_progress, PBM_SETRANGE, 0, MAKELPARAM (0, 100)); | |
100 | is_showing = 0; | |
101 | } | |
102 | char *sl=url, *cp; | |
103 | for (cp=url; *cp; cp++) | |
104 | if (*cp == '/' || *cp == '\\' || *cp == ':') | |
105 | sl = cp+1; | |
106 | max_bytes = length; | |
107 | SetWindowText (gw_url, sl); | |
108 | SetWindowText (gw_rate, "Connecting..."); | |
109 | SendMessage (gw_progress, PBM_SETPOS, (WPARAM) 0, 0); | |
110 | ShowWindow (gw_progress, (length > 0) ? SW_SHOW : SW_HIDE); | |
111 | ShowWindow (gw_dialog, SW_SHOWNORMAL); | |
112 | if (!is_showing) | |
113 | { | |
114 | SetForegroundWindow (gw_dialog); | |
115 | is_showing = 1; | |
116 | } | |
1fd6d0a2 | 117 | start_tics = GetTickCount (); |
23c9e63c DD |
118 | } |
119 | ||
120 | ||
121 | static void | |
122 | progress (int bytes) | |
123 | { | |
124 | static char buf[100]; | |
125 | int kbps; | |
126 | static int last_tics = 0; | |
1fd6d0a2 | 127 | DWORD tics = GetTickCount (); |
23c9e63c DD |
128 | if (tics == start_tics) // to prevent division by zero |
129 | return; | |
130 | if (tics < last_tics + 200) // to prevent flickering updates | |
131 | return; | |
132 | last_tics = tics; | |
133 | ||
134 | kbps = bytes / (tics - start_tics); | |
135 | ShowWindow (gw_progress, (max_bytes > 0) ? SW_SHOW : SW_HIDE); | |
bf1d5889 | 136 | if (max_bytes > 100) |
23c9e63c | 137 | { |
bf1d5889 | 138 | int perc = bytes / (max_bytes / 100); |
23c9e63c | 139 | SendMessage (gw_progress, PBM_SETPOS, (WPARAM) perc, 0); |
1fd6d0a2 DD |
140 | sprintf (buf, "%3d %% (%dk/%dk) %d kb/s\n", |
141 | perc, bytes/1000, max_bytes/1000, kbps); | |
23c9e63c DD |
142 | } |
143 | else | |
1fd6d0a2 | 144 | sprintf (buf, "%d %d kb/s\n", bytes, kbps); |
23c9e63c DD |
145 | |
146 | SetWindowText (gw_rate, buf); | |
147 | } | |
148 | ||
149 | struct GUBuf { | |
150 | GUBuf *next; | |
151 | int count; | |
152 | char buf[2000]; | |
153 | }; | |
154 | ||
155 | char * | |
156 | get_url_to_string (char *_url) | |
157 | { | |
158 | init_dialog (_url, 0); | |
159 | NetIO *n = NetIO::open (_url); | |
160 | if (!n || !n->ok ()) | |
161 | { | |
162 | delete n; | |
163 | return 0; | |
164 | } | |
165 | ||
166 | if (n->file_size) | |
167 | max_bytes = n->file_size; | |
168 | ||
169 | GUBuf *bufs = 0; | |
170 | GUBuf **nextp = &bufs; | |
171 | int total_bytes = 1; /* for the NUL */ | |
172 | progress (0); | |
173 | while (1) | |
174 | { | |
175 | GUBuf *b = new GUBuf; | |
176 | *nextp = b; | |
177 | b->next = 0; | |
178 | nextp = &(b->next); | |
179 | ||
180 | b->count = n->read (b->buf, sizeof (b->buf)); | |
181 | if (b->count <= 0) | |
182 | break; | |
183 | total_bytes += b->count; | |
184 | progress (total_bytes); | |
185 | } | |
186 | ||
187 | char *rv = (char *) malloc (total_bytes); | |
188 | char *rvp = rv; | |
189 | while (bufs && bufs->count > 0) | |
190 | { | |
191 | GUBuf *tmp = bufs->next; | |
192 | memcpy (rvp, bufs->buf, bufs->count); | |
193 | rvp += bufs->count; | |
194 | delete bufs; | |
195 | bufs = tmp; | |
196 | } | |
197 | *rvp = 0; | |
198 | return rv; | |
199 | } | |
200 | ||
201 | int | |
202 | get_url_to_file (char *_url, char *_filename, int expected_length) | |
203 | { | |
204 | init_dialog (_url, expected_length); | |
205 | ||
206 | remove (_filename); /* but ignore errors */ | |
207 | ||
208 | NetIO *n = NetIO::open (_url); | |
209 | if (!n || !n->ok ()) | |
210 | { | |
211 | delete n; | |
212 | return 1; | |
213 | } | |
214 | ||
1fd6d0a2 | 215 | FILE *f = fopen (_filename, "wb"); |
23c9e63c DD |
216 | if (!f) |
217 | { | |
218 | char *err = strerror (errno); | |
219 | if (!err) | |
220 | err = "(unknown error)"; | |
221 | fatal (IDS_ERR_OPEN_WRITE, _filename, err); | |
222 | } | |
223 | ||
224 | if (n->file_size) | |
225 | max_bytes = n->file_size; | |
226 | ||
227 | int total_bytes = 0; | |
228 | progress (0); | |
229 | while (1) | |
230 | { | |
231 | char buf[2048]; | |
232 | int count; | |
233 | count = n->read (buf, sizeof (buf)); | |
234 | if (count <= 0) | |
235 | break; | |
236 | fwrite (buf, 1, count, f); | |
237 | total_bytes += count; | |
238 | progress (total_bytes); | |
239 | } | |
240 | ||
241 | fclose (f); | |
242 | ||
243 | return 0; | |
244 | } | |
245 | ||
246 | void | |
247 | dismiss_url_status_dialog () | |
248 | { | |
249 | ShowWindow (gw_dialog, SW_HIDE); | |
250 | is_showing = 0; | |
251 | } |