448
+ − 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 #include "log.h"
+ − 33
+ − 34 static int is_showing = 0;
+ − 35 static HWND gw_dialog = 0;
+ − 36 static HWND gw_url = 0;
+ − 37 static HWND gw_rate = 0;
+ − 38 static HWND gw_progress = 0;
+ − 39 static HANDLE init_event;
+ − 40 static int max_bytes = 0;
+ − 41
+ − 42 static BOOL
+ − 43 dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
+ − 44 {
+ − 45 switch (id)
+ − 46 {
+ − 47 case IDCANCEL:
+ − 48 exit_setup (0);
+ − 49 }
+ − 50 return FALSE;
+ − 51 }
+ − 52
+ − 53 static BOOL CALLBACK
+ − 54 dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
+ − 55 {
+ − 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:
+ − 66 return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd);
+ − 67 }
+ − 68 return FALSE;
+ − 69 }
+ − 70
+ − 71 static DWORD WINAPI
+ − 72 dialog (void *)
+ − 73 {
+ − 74 MSG m;
672
+ − 75 HWND lgw_dialog = CreateDialog (hinstance, MAKEINTRESOURCE (IDD_DLSTATUS),
448
+ − 76 0, dialog_proc);
672
+ − 77 ShowWindow (lgw_dialog, SW_SHOWNORMAL);
+ − 78 UpdateWindow (lgw_dialog);
448
+ − 79 while (GetMessage (&m, 0, 0, 0) > 0) {
+ − 80 TranslateMessage (&m);
+ − 81 DispatchMessage (&m);
+ − 82 }
+ − 83 return FALSE;
+ − 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 }
+ − 117 start_tics = GetTickCount ();
+ − 118 }
+ − 119
+ − 120
+ − 121 static void
+ − 122 progress (int bytes)
+ − 123 {
+ − 124 static char buf[100];
+ − 125 int kbps;
+ − 126 static DWORD last_tics = 0;
+ − 127 DWORD tics = GetTickCount ();
+ − 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);
+ − 136 if (max_bytes > 100)
+ − 137 {
+ − 138 int perc = bytes / (max_bytes / 100);
+ − 139 SendMessage (gw_progress, PBM_SETPOS, (WPARAM) perc, 0);
+ − 140 sprintf (buf, "%3d %% (%dk/%dk) %d kb/s\n",
+ − 141 perc, bytes/1000, max_bytes/1000, kbps);
+ − 142 }
+ − 143 else
+ − 144 sprintf (buf, "%d %d kb/s\n", bytes, kbps);
+ − 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 log (LOG_BABBLE, "get_url_to_string %s", _url);
+ − 159 init_dialog (_url, 0);
+ − 160 NetIO *n = NetIO::open (_url);
+ − 161 if (!n || !n->ok ())
+ − 162 {
+ − 163 delete n;
+ − 164 log (LOG_BABBLE, "get_url_to_string failed!");
+ − 165 return 0;
+ − 166 }
+ − 167
+ − 168 if (n->file_size)
+ − 169 max_bytes = n->file_size;
+ − 170
+ − 171 GUBuf *bufs = 0;
+ − 172 GUBuf **nextp = &bufs;
+ − 173 int total_bytes = 1; /* for the NUL */
+ − 174 progress (0);
+ − 175 while (1)
+ − 176 {
+ − 177 GUBuf *b = new GUBuf;
+ − 178 *nextp = b;
+ − 179 b->next = 0;
+ − 180 nextp = &(b->next);
+ − 181
+ − 182 b->count = n->read (b->buf, sizeof (b->buf));
+ − 183 if (b->count <= 0)
+ − 184 break;
+ − 185 total_bytes += b->count;
+ − 186 progress (total_bytes);
+ − 187 }
+ − 188
+ − 189 char *rv = (char *) malloc (total_bytes);
+ − 190 char *rvp = rv;
+ − 191 while (bufs && bufs->count > 0)
+ − 192 {
+ − 193 GUBuf *tmp = bufs->next;
+ − 194 memcpy (rvp, bufs->buf, bufs->count);
+ − 195 rvp += bufs->count;
+ − 196 delete bufs;
+ − 197 bufs = tmp;
+ − 198 }
+ − 199 *rvp = 0;
672
+ − 200
+ − 201 if (n)
+ − 202 delete n;
+ − 203
448
+ − 204 return rv;
+ − 205 }
+ − 206
+ − 207 int
+ − 208 get_url_to_file (char *_url, char *_filename, int expected_length)
+ − 209 {
+ − 210 log (LOG_BABBLE, "get_url_to_file %s %s", _url, _filename);
+ − 211 init_dialog (_url, expected_length);
+ − 212
+ − 213 remove (_filename); /* but ignore errors */
+ − 214
+ − 215 NetIO *n = NetIO::open (_url);
+ − 216 if (!n || !n->ok ())
+ − 217 {
+ − 218 delete n;
+ − 219 log (LOG_BABBLE, "get_url_to_file failed!");
+ − 220 return 1;
+ − 221 }
+ − 222
+ − 223 FILE *f = fopen (_filename, "wb");
+ − 224 if (!f)
+ − 225 {
+ − 226 char *err = strerror (errno);
+ − 227 if (!err)
+ − 228 err = "(unknown error)";
+ − 229 fatal (IDS_ERR_OPEN_WRITE, _filename, err);
+ − 230 }
+ − 231
+ − 232 if (n->file_size)
+ − 233 max_bytes = n->file_size;
+ − 234
+ − 235 int total_bytes = 0;
+ − 236 progress (0);
+ − 237 while (1)
+ − 238 {
+ − 239 char buf[8192];
+ − 240 int count;
+ − 241 count = n->read (buf, sizeof (buf));
+ − 242 if (count <= 0)
+ − 243 break;
+ − 244 fwrite (buf, 1, count, f);
+ − 245 total_bytes += count;
+ − 246 progress (total_bytes);
+ − 247 }
+ − 248
+ − 249 fclose (f);
+ − 250
672
+ − 251 if (n)
+ − 252 delete n;
+ − 253
448
+ − 254 return 0;
+ − 255 }
+ − 256
+ − 257 void
+ − 258 dismiss_url_status_dialog ()
+ − 259 {
+ − 260 ShowWindow (gw_dialog, SW_HIDE);
+ − 261 is_showing = 0;
+ − 262 }