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 let the user choose which packages
|
|
17 to install, and which versions of the package when more than one
|
|
18 version is provided. The "trust" level serves as an indication as
|
|
19 to which version should be the default choice. At the moment, all
|
|
20 we do is compare with previously installed packages to skip any
|
|
21 that are already installed (by setting the action to ACTION_SAME).
|
|
22 While the "trust" stuff is supported, it's not really implemented
|
|
23 yet. We always prefer the "current" option. In the future, this
|
|
24 file might have a user dialog added to let the user choose to not
|
|
25 install packages, or to install packages that aren't installed by
|
|
26 default. */
|
|
27
|
|
28 #include "win32.h"
|
|
29 #include <stdio.h>
|
|
30 #include <stdlib.h>
|
|
31 #include <ctype.h>
|
|
32
|
|
33 #include "dialog.h"
|
|
34 #include "resource.h"
|
|
35 #include "state.h"
|
|
36 #include "ini.h"
|
|
37 #include "concat.h"
|
|
38 #include "msg.h"
|
|
39 #include "log.h"
|
|
40 #include "find.h"
|
|
41 #include "reginfo.h"
|
|
42
|
|
43 #define HMARGIN 10
|
|
44 #define ROW_MARGIN 5
|
|
45 #define ICON_MARGIN 4
|
|
46
|
|
47 #define CHECK_SIZE 11
|
|
48
|
|
49 #define TRUST_KEEP 101
|
|
50 #define TRUST_UNINSTALL 102
|
|
51 #define TRUST_NONE 103
|
|
52
|
|
53 static int initialized = 0;
|
|
54
|
|
55 static int full_list = 0;
|
|
56
|
|
57 static int scroll_ulc_x, scroll_ulc_y;
|
|
58
|
|
59 static HWND lv, nextbutton;
|
|
60 static TEXTMETRIC tm;
|
|
61 static int header_height;
|
|
62 static HANDLE sysfont;
|
|
63 static int row_height;
|
|
64 static HANDLE bm_spin, bm_rtarrow, bm_checkyes, bm_checkno, bm_checkna;
|
|
65 static HDC bitmap_dc;
|
|
66
|
|
67 static struct {
|
|
68 char *text;
|
|
69 int slen;
|
|
70 int width;
|
|
71 int x;
|
|
72 } headers[] = {
|
|
73 { "Current", 7, 0, 0 },
|
|
74 #define CURRENT_COL 0
|
|
75 { "New", 3, 0, 0 },
|
|
76 #define NEW_COL 1
|
|
77 { "Src?", 4, 0, 0 },
|
|
78 #define SRC_COL 2
|
|
79 { "Package", 7, 0, 0 },
|
|
80 #define PACKAGE_COL 3
|
|
81 { 0, 0, 0, 0 }
|
|
82 };
|
|
83 #define NUM_COLUMNS (sizeof(headers)/(sizeof(headers[0]))-1)
|
|
84
|
|
85 int *package_indexes, nindexes;
|
|
86
|
|
87 struct ExtraPackageInfo {
|
|
88 char *installed_file; /* filename of previous "install" file */
|
|
89 char *installed_ver; /* version part */
|
|
90 int installed_size; /* ditto, size. */
|
|
91
|
|
92 int in_partial_list;
|
|
93 int pick;
|
|
94 int npick;
|
|
95 int which_is_installed; /* == TRUST* or -1 */
|
|
96
|
|
97 struct {
|
|
98 int src_avail;
|
|
99 int trust; /* may be keep or uninstall */
|
|
100 char *caption; /* ==0 at EOL */
|
|
101 } chooser[NTRUST+3]; /* one extra for NULL above */
|
|
102 };
|
|
103
|
|
104 static ExtraPackageInfo *extra;
|
|
105
|
|
106 static void
|
|
107 paint (HWND hwnd)
|
|
108 {
|
|
109 HDC hdc;
|
|
110 PAINTSTRUCT ps;
|
|
111 int x, y, i, ii;
|
|
112
|
|
113 hdc = BeginPaint (hwnd, &ps);
|
|
114
|
|
115 SelectObject (hdc, sysfont);
|
|
116
|
|
117 RECT cr;
|
|
118 GetClientRect (hwnd, &cr);
|
|
119
|
|
120 POINT p;
|
|
121
|
|
122 x = cr.left - scroll_ulc_x;
|
|
123 y = cr.top - scroll_ulc_y + header_height;
|
|
124
|
|
125
|
|
126 for (i=0; headers[i].text; i++)
|
|
127 {
|
|
128 TextOut (hdc, x+headers[i].x, 3, headers[i].text, headers[i].slen);
|
|
129 MoveToEx (hdc, x+headers[i].x, header_height-3, &p);
|
|
130 LineTo (hdc, x+headers[i].x+headers[i].width, header_height-3);
|
|
131 }
|
|
132
|
|
133 IntersectClipRect (hdc, cr.left, cr.top+header_height, cr.right, cr.bottom);
|
|
134
|
|
135 for (ii=0; ii<nindexes; ii++)
|
|
136 {
|
|
137 i = package_indexes[ii];
|
|
138 int r = y + ii * row_height;
|
|
139 int by = r + tm.tmHeight - 11;
|
|
140 if (extra[i].installed_ver && extra[i].installed_ver[0])
|
|
141 {
|
|
142 TextOut (hdc, x+headers[CURRENT_COL].x, r,
|
|
143 extra[i].installed_ver, strlen (extra[i].installed_ver));
|
|
144 SelectObject (bitmap_dc, bm_rtarrow);
|
|
145 BitBlt (hdc, x+headers[CURRENT_COL].x+headers[0].width+ICON_MARGIN/2+HMARGIN/2, by,
|
|
146 11, 11, bitmap_dc, 0, 0, SRCCOPY);
|
|
147 }
|
|
148
|
|
149 char *s = extra[i].chooser[extra[i].pick].caption;
|
|
150 if (s)
|
|
151 {
|
|
152 TextOut (hdc, x+headers[NEW_COL].x + 11 + ICON_MARGIN, r,
|
|
153 s, strlen (s));
|
|
154 if (extra[i].npick > 1)
|
|
155 {
|
|
156 SelectObject (bitmap_dc, bm_spin);
|
|
157 BitBlt (hdc, x+headers[NEW_COL].x, by, 11, 11,
|
|
158 bitmap_dc, 0, 0, SRCCOPY);
|
|
159 }
|
|
160 }
|
|
161
|
|
162 HANDLE check_bm = bm_checkna;
|
|
163 if (extra[i].chooser[extra[i].pick].src_avail)
|
|
164 {
|
|
165 if (package[i].srcaction == SRCACTION_NO)
|
|
166 check_bm = bm_checkno;
|
|
167 else if (package[i].srcaction == SRCACTION_YES)
|
|
168 check_bm = bm_checkyes;
|
|
169 }
|
|
170 SelectObject (bitmap_dc, check_bm);
|
|
171 BitBlt (hdc, x+headers[SRC_COL].x, by, 11, 11,
|
|
172 bitmap_dc, 0, 0, SRCCOPY);
|
|
173
|
|
174 if (package[i].name)
|
|
175 TextOut (hdc, x+headers[PACKAGE_COL].x, r, package[i].name, strlen(package[i].name));
|
|
176 }
|
|
177
|
|
178 if (nindexes == 0)
|
|
179 {
|
|
180 static char *m = "Nothing to Install/Update";
|
|
181 TextOut (hdc, HMARGIN, header_height, m, strlen (m));
|
|
182 }
|
|
183
|
|
184 EndPaint (hwnd, &ps);
|
|
185 }
|
|
186
|
|
187 static void
|
|
188 scroll_common (HWND hwnd, int which, int *var, int code)
|
|
189 {
|
|
190 SCROLLINFO si;
|
|
191 si.cbSize = sizeof (si);
|
|
192 si.fMask = SIF_ALL;
|
|
193 GetScrollInfo (hwnd, which, &si);
|
|
194
|
|
195 switch (code)
|
|
196 {
|
|
197 case SB_THUMBTRACK:
|
|
198 si.nPos = si.nTrackPos;
|
|
199 break;
|
|
200 case SB_THUMBPOSITION:
|
|
201 break;
|
|
202 case SB_BOTTOM:
|
|
203 si.nPos = si.nMax;
|
|
204 break;
|
|
205 case SB_TOP:
|
|
206 si.nPos = 0;
|
|
207 break;
|
|
208 case SB_LINEDOWN:
|
|
209 si.nPos += row_height;
|
|
210 break;
|
|
211 case SB_LINEUP:
|
|
212 si.nPos -= row_height;
|
|
213 break;
|
|
214 case SB_PAGEDOWN:
|
|
215 si.nPos += si.nPage * 9/10;
|
|
216 break;
|
|
217 case SB_PAGEUP:
|
|
218 si.nPos -= si.nPage * 9/10;
|
|
219 break;
|
|
220 }
|
|
221
|
|
222 if ((int)si.nPos < 0)
|
|
223 si.nPos = 0;
|
|
224 if ((int)(si.nPos + si.nPage) > si.nMax)
|
|
225 si.nPos = si.nMax - si.nPage;
|
|
226
|
|
227 si.fMask = SIF_POS;
|
|
228 SetScrollInfo (hwnd, which, &si, TRUE);
|
|
229
|
|
230 int ox = scroll_ulc_x;
|
|
231 int oy = scroll_ulc_y;
|
|
232 *var = si.nPos;
|
|
233
|
|
234 RECT cr, sr;
|
|
235 GetClientRect (hwnd, &cr);
|
|
236 sr = cr;
|
|
237 sr.top += header_height;
|
|
238 ScrollWindow (hwnd, ox - scroll_ulc_x, oy - scroll_ulc_y, &sr, &sr);
|
|
239 sr.bottom = sr.top;
|
|
240 sr.top = cr.top;
|
|
241 ScrollWindow (hwnd, ox - scroll_ulc_x, 0, &sr, &sr);
|
|
242 }
|
|
243
|
|
244 static LRESULT CALLBACK
|
|
245 list_vscroll (HWND hwnd, HWND hctl, UINT code, int pos)
|
|
246 {
|
|
247 scroll_common (hwnd, SB_VERT, &scroll_ulc_y, code);
|
|
248 return FALSE;
|
|
249 }
|
|
250
|
|
251 static LRESULT CALLBACK
|
|
252 list_hscroll (HWND hwnd, HWND hctl, UINT code, int pos)
|
|
253 {
|
|
254 scroll_common (hwnd, SB_HORZ, &scroll_ulc_x, code);
|
|
255 return FALSE;
|
|
256 }
|
|
257
|
|
258 static LRESULT CALLBACK
|
|
259 list_click (HWND hwnd, BOOL dblclk, int x, int y, UINT hitCode)
|
|
260 {
|
|
261 int r;
|
|
262
|
|
263 if (nindexes == 0)
|
|
264 return 0;
|
|
265
|
|
266 if (y < header_height)
|
|
267 return 0;
|
|
268 x += scroll_ulc_x;
|
|
269 y += scroll_ulc_y - header_height;
|
|
270
|
|
271 r = (y + ROW_MARGIN/2) / row_height;
|
|
272
|
|
273 if (r < 0 || r >= npackages)
|
|
274 return 0;
|
|
275
|
|
276 int p = package_indexes[r];
|
|
277
|
|
278 if (x >= headers[NEW_COL].x - HMARGIN/2 && x <= headers[NEW_COL+1].x - HMARGIN/2)
|
|
279 {
|
|
280 extra[p].pick ++;
|
|
281 if (extra[p].chooser[extra[p].pick].caption == 0)
|
|
282 extra[p].pick = 0;
|
|
283 }
|
|
284
|
|
285 if (x >= headers[SRC_COL].x - HMARGIN/2 && x <= headers[SRC_COL+1].x - HMARGIN/2)
|
|
286 {
|
|
287 if (extra[p].chooser[extra[p].pick].src_avail)
|
|
288 package[p].srcaction ^= (SRCACTION_NO^SRCACTION_YES);
|
|
289 }
|
|
290
|
|
291 RECT rect;
|
|
292 rect.left = headers[NEW_COL].x - scroll_ulc_x;
|
|
293 rect.right = headers[SRC_COL+1].x - scroll_ulc_x;
|
|
294 rect.top = header_height + r * row_height - scroll_ulc_y;
|
|
295 rect.bottom = rect.top + row_height;
|
|
296 InvalidateRect (hwnd, &rect, TRUE);
|
|
297 return FALSE;
|
|
298 }
|
|
299
|
|
300 static LRESULT CALLBACK
|
|
301 listview_proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
302 {
|
|
303 switch (message) {
|
|
304 case WM_HSCROLL:
|
|
305 return HANDLE_WM_HSCROLL (hwnd, wParam, lParam, list_hscroll);
|
|
306 case WM_VSCROLL:
|
|
307 return HANDLE_WM_VSCROLL (hwnd, wParam, lParam, list_vscroll);
|
|
308 case WM_LBUTTONDOWN:
|
|
309 return HANDLE_WM_LBUTTONDOWN (hwnd, wParam, lParam, list_click);
|
|
310 case WM_PAINT:
|
|
311 paint (hwnd);
|
|
312 return 0;
|
|
313 default:
|
|
314 return DefWindowProc (hwnd, message, wParam, lParam);
|
|
315 }
|
|
316 }
|
|
317
|
|
318 static void
|
|
319 register_windows (HINSTANCE hinst)
|
|
320 {
|
|
321 WNDCLASSEX wcex;
|
|
322 static int done = 0;
|
|
323
|
|
324 if (done)
|
|
325 return;
|
|
326 done = 1;
|
|
327
|
|
328 memset (&wcex, 0, sizeof (wcex));
|
|
329 wcex.cbSize = sizeof (WNDCLASSEX);
|
|
330 wcex.style = CS_HREDRAW | CS_VREDRAW;
|
|
331 wcex.lpfnWndProc = listview_proc;
|
|
332 wcex.hInstance = hinst;
|
|
333 wcex.hIcon = LoadIcon (0, IDI_APPLICATION);
|
|
334 wcex.hCursor = LoadCursor (0, IDC_ARROW);
|
|
335 wcex.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
|
|
336 wcex.lpszClassName = "listview";
|
|
337
|
|
338 RegisterClassEx (&wcex);
|
|
339 }
|
|
340
|
|
341 static void
|
|
342 note_width (HDC dc, char *string, int addend, int column)
|
|
343 {
|
|
344 if (!string)
|
|
345 return;
|
|
346 SIZE s;
|
|
347 GetTextExtentPoint32 (dc, string, strlen (string), &s);
|
|
348 if (headers[column].width < s.cx + addend)
|
|
349 headers[column].width = s.cx + addend;
|
|
350 }
|
|
351
|
|
352 static int
|
|
353 best_trust (int p, int trust)
|
|
354 {
|
|
355 int t;
|
|
356 for (t=trust; t>=0; t--)
|
|
357 if (package[p].info[t].install)
|
|
358 return t;
|
|
359 for (t=trust+1; t<=NTRUST; t++)
|
|
360 if (package[p].info[t].install)
|
|
361 return t;
|
|
362 if (extra[p].installed_file)
|
|
363 return TRUST_KEEP;
|
|
364 return TRUST_NONE;
|
|
365 }
|
|
366
|
|
367 static void
|
|
368 default_trust (HWND h, int trust)
|
|
369 {
|
|
370 int i, t, c;
|
|
371
|
|
372 for (i=0; i<npackages; i++)
|
|
373 {
|
|
374 t = best_trust (i, trust);
|
|
375 extra[i].pick = 1;
|
|
376 for (c=0; c<extra[i].npick; c++)
|
|
377 if (t == extra[i].chooser[c].trust)
|
|
378 extra[i].pick = c;
|
|
379 if (install_type == IDC_INSTALL_NATIVE
|
|
380 && package[i].type == TY_CYGWIN
|
|
381 ||
|
|
382 install_type == IDC_INSTALL_CYGWIN
|
|
383 && package[i].type == TY_NATIVE)
|
|
384 extra[i].pick = extra[i].npick -1;
|
|
385 }
|
|
386 RECT r;
|
|
387 GetClientRect (h, &r);
|
|
388 InvalidateRect (h, &r, TRUE);
|
|
389 if (nextbutton)
|
|
390 SetFocus (nextbutton);
|
|
391 }
|
|
392
|
|
393 static void
|
|
394 set_full_list (HWND h, int isfull)
|
|
395 {
|
|
396 int i, j;
|
|
397 full_list = isfull;
|
|
398 if (package_indexes == 0)
|
|
399 package_indexes = (int *) malloc (npackages * sizeof (int));
|
|
400 for (i=j=0; i<npackages; i++)
|
|
401 {
|
|
402 if (isfull || extra[i].in_partial_list)
|
|
403 package_indexes[j++] = i;
|
|
404 }
|
|
405 nindexes = j;
|
|
406
|
|
407 RECT r;
|
|
408 GetClientRect (h, &r);
|
|
409 SCROLLINFO si;
|
|
410 memset (&si, 0, sizeof (si));
|
|
411 si.cbSize = sizeof (si);
|
|
412 si.fMask = SIF_ALL;
|
|
413 si.nMin = 0;
|
|
414 si.nMax = headers[2].x + headers[2].width + HMARGIN;
|
|
415 si.nPage = r.right;
|
|
416 SetScrollInfo (h, SB_HORZ, &si, TRUE);
|
|
417
|
|
418 si.nMax = nindexes * row_height;
|
|
419 si.nPage = r.bottom - header_height;
|
|
420 SetScrollInfo (h, SB_VERT, &si, TRUE);
|
|
421
|
|
422 scroll_ulc_x = scroll_ulc_y = 0;
|
|
423
|
|
424 InvalidateRect (h, &r, TRUE);
|
|
425
|
|
426 if (nextbutton)
|
|
427 SetFocus (nextbutton);
|
|
428 }
|
|
429
|
|
430 static void
|
|
431 build_labels ()
|
|
432 {
|
|
433 int i;
|
|
434 for (i=0; i<npackages; i++)
|
|
435 {
|
|
436 int c = 0, t;
|
|
437
|
|
438 #define C extra[i].chooser[c]
|
|
439 if (extra[i].installed_ver)
|
|
440 {
|
|
441 C.caption = "Uninstall";
|
|
442 C.trust = TRUST_UNINSTALL;
|
|
443 c++;
|
|
444 C.caption = "Keep";
|
|
445 C.trust = TRUST_KEEP;
|
|
446 c++;
|
|
447 }
|
|
448
|
|
449 for (t=TRUST_PREV; t<NTRUST; t++)
|
|
450 if (package[i].info[t].install)
|
|
451 if (t != extra[i].which_is_installed)
|
|
452 {
|
|
453 C.caption = package[i].info[t].version;
|
|
454 if (C.caption == 0 || C.caption[0] == 0)
|
|
455 C.caption = "0.0";
|
|
456 C.trust = t;
|
|
457 if (package[i].info[t].source)
|
|
458 C.src_avail = 1;
|
|
459 c++;
|
|
460 /* we intentionally skip TRUST_PREV */
|
|
461 if (t != TRUST_PREV || !extra[i].installed_ver)
|
|
462 extra[i].in_partial_list = 1;
|
|
463
|
|
464 }
|
|
465
|
|
466 if (c == 0)
|
|
467 {
|
|
468 C.caption = "N/A";
|
|
469 C.trust = TRUST_NONE;
|
|
470 c++;
|
|
471 }
|
|
472
|
|
473 if (! extra[i].installed_file)
|
|
474 {
|
|
475 C.caption = "Skip";
|
|
476 C.trust = TRUST_NONE;
|
|
477 c++;
|
|
478 }
|
|
479
|
|
480 C.caption = 0;
|
|
481 extra[i].npick = c;
|
|
482 #undef C
|
|
483 }
|
|
484 }
|
|
485
|
|
486 static void
|
|
487 create_listview (HWND dlg, RECT *r)
|
|
488 {
|
|
489 int i, t;
|
|
490 lv = CreateWindowEx (WS_EX_CLIENTEDGE,
|
|
491 "listview",
|
|
492 "listviewwindow",
|
|
493 WS_CHILD | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE,
|
|
494 r->left, r->top,
|
|
495 r->right-r->left+1, r->bottom-r->top+1,
|
|
496 dlg,
|
|
497 NULL, // ??? MAKEINTRESOURCE(IDC_CHOOSE_LIST),
|
|
498 hinstance,
|
|
499 0);
|
|
500 ShowWindow (lv, SW_SHOW);
|
|
501
|
|
502 for (i=0; headers[i].text; i++)
|
|
503 headers[i].width = 0;
|
|
504
|
|
505 HDC dc = GetDC (lv);
|
|
506 sysfont = GetStockObject (DEFAULT_GUI_FONT);
|
|
507 SelectObject (dc, sysfont);
|
|
508 GetTextMetrics (dc, &tm);
|
|
509 header_height = tm.tmHeight + 5 + 3;
|
|
510
|
|
511 bitmap_dc = CreateCompatibleDC (dc);
|
|
512
|
|
513 row_height = (tm.tmHeight + tm.tmExternalLeading + ROW_MARGIN);
|
|
514 int irh = tm.tmExternalLeading + tm.tmDescent + 11 + ROW_MARGIN;
|
|
515 if (row_height < irh)
|
|
516 row_height = irh;
|
|
517
|
|
518 for (i=0; headers[i].text; i++)
|
|
519 note_width (dc, headers[i].text, 0, i);
|
|
520 for (i=0; i<npackages; i++)
|
|
521 {
|
|
522 note_width (dc, extra[i].installed_ver, 0, CURRENT_COL);
|
|
523 note_width (dc, extra[i].installed_ver, 11+ICON_MARGIN, NEW_COL);
|
|
524 for (t=0; t<NTRUST; t++)
|
|
525 note_width (dc, package[i].info[t].version, 11+ICON_MARGIN, NEW_COL);
|
|
526 note_width (dc, package[i].name, 0, PACKAGE_COL);
|
|
527 note_width (dc, package[i].sdesc, 0, PACKAGE_COL);
|
|
528 }
|
|
529 note_width (dc, "keep", 11+ICON_MARGIN, NEW_COL);
|
|
530 note_width (dc, "uninstall", 11+ICON_MARGIN, NEW_COL);
|
|
531
|
|
532 headers[CURRENT_COL].x = HMARGIN/2;
|
|
533 headers[NEW_COL].x = (headers[CURRENT_COL].x + headers[CURRENT_COL].width
|
|
534 + HMARGIN + 11 + ICON_MARGIN);
|
|
535 headers[SRC_COL].x = headers[NEW_COL].x + headers[NEW_COL].width + HMARGIN;
|
|
536 headers[PACKAGE_COL].x = headers[SRC_COL].x + headers[SRC_COL].width + HMARGIN;
|
|
537
|
|
538 set_full_list (lv, full_list);
|
|
539 default_trust (lv, TRUST_CURR);
|
|
540
|
|
541 ReleaseDC (lv, dc);
|
|
542 }
|
|
543
|
|
544 static BOOL
|
|
545 dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
|
|
546 {
|
|
547 switch (id)
|
|
548 {
|
|
549
|
|
550 case IDC_CHOOSE_PREV:
|
|
551 default_trust (lv, TRUST_PREV);
|
|
552 break;
|
|
553 case IDC_CHOOSE_CURR:
|
|
554 default_trust (lv, TRUST_CURR);
|
|
555 break;
|
|
556 case IDC_CHOOSE_EXP:
|
|
557 default_trust (lv, TRUST_TEST);
|
|
558 break;
|
|
559 case IDC_CHOOSE_FULLPART:
|
|
560 set_full_list (lv, !full_list);
|
|
561 break;
|
|
562
|
|
563 case IDOK:
|
|
564 if (source == IDC_SOURCE_CWD)
|
|
565 NEXT (IDD_S_INSTALL);
|
|
566 else
|
|
567 NEXT (IDD_S_DOWNLOAD);
|
|
568 break;
|
|
569
|
|
570 case IDC_BACK:
|
|
571 initialized = 0;
|
|
572 if (source == IDC_SOURCE_CWD)
|
|
573 NEXT (IDD_ROOT);
|
|
574 else
|
|
575 NEXT (IDD_SITE);
|
|
576 break;
|
|
577
|
|
578 case IDCANCEL:
|
|
579 NEXT (0);
|
|
580 break;
|
|
581 }
|
|
582 return FALSE;
|
|
583 }
|
|
584
|
|
585 static void
|
|
586 GetParentRect (HWND parent, HWND child, RECT *r)
|
|
587 {
|
|
588 POINT p;
|
|
589 GetWindowRect (child, r);
|
|
590 p.x = r->left;
|
|
591 p.y = r->top;
|
|
592 ScreenToClient (parent, &p);
|
|
593 r->left = p.x;
|
|
594 r->top = p.y;
|
|
595 p.x = r->right;
|
|
596 p.y = r->bottom;
|
|
597 ScreenToClient (parent, &p);
|
|
598 r->right = p.x;
|
|
599 r->bottom = p.y;
|
|
600 }
|
|
601
|
|
602 static BOOL CALLBACK
|
|
603 dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
|
|
604 {
|
|
605 HWND frame;
|
|
606 RECT r;
|
|
607 switch (message)
|
|
608 {
|
|
609 case WM_INITDIALOG:
|
|
610 nextbutton = GetDlgItem (h, IDOK);
|
|
611 frame = GetDlgItem (h, IDC_LISTVIEW_POS);
|
|
612 GetParentRect (h, frame, &r);
|
|
613 r.top += 2;
|
|
614 r.bottom -= 2;
|
|
615 create_listview (h, &r);
|
|
616 #if 0
|
|
617 load_dialog (h);
|
|
618 #endif
|
|
619 return FALSE;
|
|
620 case WM_COMMAND:
|
|
621 return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd);
|
|
622 }
|
|
623 return FALSE;
|
|
624 }
|
|
625
|
657
|
626 char *
|
448
|
627 base (char *s)
|
|
628 {
|
|
629 if (!s)
|
|
630 return 0;
|
|
631 char *rv = s;
|
|
632 while (*s)
|
|
633 {
|
|
634 if ((*s == '/' || *s == ':' || *s == '\\') && s[1])
|
|
635 rv = s+1;
|
|
636 s++;
|
|
637 }
|
|
638 return rv;
|
|
639 }
|
|
640
|
|
641 static void
|
|
642 scan2 (char *path, unsigned int size)
|
|
643 {
|
|
644 int i, t;
|
|
645 for (i=0; i<npackages; i++)
|
|
646 for (t=0; t<NTRUST; t++)
|
|
647 if (package[i].info[t].install
|
|
648 && strcmp (base (package[i].info[t].install), base (path)) == 0
|
|
649 && package[i].info[t].install_size == (int)size)
|
|
650 {
|
|
651 extra[i].installed_file = package[i].info[t].install;
|
|
652 extra[i].installed_size = size;
|
|
653 extra[i].which_is_installed = t;
|
|
654 extra[i].installed_ver = package[i].info[t].version;
|
|
655 if (!extra[i].installed_ver)
|
|
656 extra[i].installed_ver = "0";
|
|
657 }
|
|
658 }
|
|
659
|
|
660 static void
|
|
661 scan_downloaded_files ()
|
|
662 {
|
|
663 find (".", scan2);
|
|
664 }
|
|
665
|
|
666 static void
|
|
667 read_installed_db ()
|
|
668 {
|
|
669 int i;
|
|
670 if (!root_dir)
|
|
671 return;
|
|
672
|
|
673 char line[1000], pkg[1000], inst[1000], src[1000];
|
|
674 int instsz, srcsz;
|
|
675
|
|
676 FILE *db = fopen (concat (root_dir, XEMACS_SETUP_DIR, "installed.db", 0), "rt");
|
|
677 if (!db)
|
|
678 return;
|
|
679
|
|
680 while (fgets (line, 1000, db))
|
|
681 {
|
|
682 src[0] = 0;
|
|
683 srcsz = 0;
|
|
684 sscanf (line, "%s %s %d %s %d", pkg, inst, &instsz, src, &srcsz);
|
|
685
|
|
686 for (i=0; i<npackages; i++)
|
|
687 if (strcmp (package[i].name, pkg) == 0)
|
|
688 {
|
|
689 int t;
|
|
690 extra[i].installed_file = inst;
|
|
691 extra[i].installed_size = instsz;
|
|
692
|
|
693 for (t=0; t<NTRUST; t++)
|
|
694 if (package[i].info[t].install
|
|
695 && strcmp (base (package[i].info[t].install), base (inst)) == 0)
|
|
696 {
|
|
697 extra[i].which_is_installed = t;
|
|
698 extra[i].installed_ver = package[i].info[t].version;
|
|
699 break;
|
|
700 }
|
|
701
|
|
702 if (extra[i].installed_ver == 0) /* still */
|
|
703 {
|
|
704 char *v, *d;
|
|
705 for (v=base (inst); *v; v++)
|
|
706 if (*v == '-' && isdigit(v[1]))
|
|
707 {
|
|
708 v++;
|
|
709 break;
|
|
710 }
|
|
711 if (!v)
|
|
712 v = inst;
|
|
713 for (d=v; *d; d++)
|
|
714 if (strncmp (d, ".tar", 4) == 0
|
|
715 || strncmp (d, "-pkg", 4) == 0)
|
|
716 {
|
|
717 *d = 0;
|
|
718 break;
|
|
719 }
|
|
720 if (v[0])
|
|
721 extra[i].installed_ver = strdup (v);
|
|
722 else
|
|
723 extra[i].installed_ver = "0";
|
|
724 }
|
|
725 break;
|
|
726 }
|
|
727 }
|
|
728 fclose (db);
|
|
729 }
|
|
730
|
|
731 int CDECL
|
|
732 package_sort (const void *va, const void *vb)
|
|
733 {
|
|
734 Package *a = (Package *)va;
|
|
735 Package *b = (Package *)vb;
|
|
736 return strcmp (a->name, b->name);
|
|
737 }
|
|
738
|
|
739 void
|
|
740 do_choose (HINSTANCE h)
|
|
741 {
|
|
742 int rv, i;
|
|
743
|
|
744 qsort (package, npackages, sizeof (package[0]), package_sort);
|
|
745
|
|
746 nextbutton = 0;
|
|
747 bm_spin = LoadImage (h, MAKEINTRESOURCE (IDB_SPIN), IMAGE_BITMAP, 0, 0, 0);
|
|
748 bm_rtarrow = LoadImage (h, MAKEINTRESOURCE (IDB_RTARROW), IMAGE_BITMAP, 0, 0, 0);
|
|
749
|
|
750 bm_checkyes = LoadImage (h, MAKEINTRESOURCE (IDB_CHECK_YES), IMAGE_BITMAP, 0, 0, 0);
|
|
751 bm_checkno = LoadImage (h, MAKEINTRESOURCE (IDB_CHECK_NO), IMAGE_BITMAP, 0, 0, 0);
|
|
752 bm_checkna = LoadImage (h, MAKEINTRESOURCE (IDB_CHECK_NA), IMAGE_BITMAP, 0, 0, 0);
|
|
753
|
|
754 extra = (ExtraPackageInfo *) malloc (npackages * sizeof (ExtraPackageInfo));
|
|
755 memset (extra, 0, npackages * sizeof (ExtraPackageInfo));
|
|
756 for (i=0; i<npackages; i++)
|
|
757 extra[i].which_is_installed = -1;
|
|
758
|
|
759 register_windows (h);
|
|
760
|
|
761 if (source == IDC_SOURCE_DOWNLOAD)
|
|
762 scan_downloaded_files ();
|
|
763 else
|
|
764 read_installed_db ();
|
|
765 build_labels ();
|
|
766
|
|
767 rv = DialogBox (h, MAKEINTRESOURCE (IDD_CHOOSE), 0, dialog_proc);
|
|
768 if (rv == -1)
|
|
769 fatal (IDS_DIALOG_FAILED);
|
|
770
|
|
771 for (i=0; i<npackages; i++)
|
|
772 {
|
|
773 switch (extra[i].chooser[extra[i].pick].trust)
|
|
774 {
|
|
775 case TRUST_PREV:
|
|
776 case TRUST_CURR:
|
|
777 case TRUST_TEST:
|
|
778 if (extra[i].installed_file)
|
|
779 package[i].action = ACTION_UPGRADE;
|
|
780 else
|
|
781 package[i].action = ACTION_NEW;
|
|
782 package[i].trust = extra[i].chooser[extra[i].pick].trust;
|
|
783 // pick up the actual core package to install
|
|
784 if (package[i].type == TY_CYGWIN || package[i].type == TY_NATIVE
|
|
785 && xemacs_package == 0)
|
|
786 xemacs_package = &package[i];
|
|
787 break;
|
|
788
|
|
789 case TRUST_UNINSTALL:
|
|
790 package[i].action = ACTION_UNINSTALL;
|
|
791 break;
|
|
792
|
|
793 case TRUST_KEEP:
|
|
794 case TRUST_NONE:
|
|
795 default:
|
|
796 package[i].action = ACTION_SAME;
|
|
797 break;
|
|
798 }
|
|
799 }
|
|
800
|
|
801 log (LOG_BABBLE, "Chooser results...");
|
|
802 for (i=0; i<npackages; i++)
|
|
803 {
|
|
804 static char *infos[] = {"prev", "curr", "test"};
|
|
805 const char *trust = ((package[i].trust == TRUST_PREV) ? "prev"
|
|
806 : (package[i].trust == TRUST_CURR) ? "curr"
|
|
807 : (package[i].trust == TRUST_TEST) ? "test"
|
|
808 : "unknown");
|
|
809 const char *action = ((package[i].action == ACTION_UNKNOWN) ? "unknown"
|
|
810 : (package[i].action == ACTION_SAME) ? "same"
|
|
811 : (package[i].action == ACTION_NEW) ? "new"
|
|
812 : (package[i].action == ACTION_UPGRADE) ? "upgrade"
|
|
813 : (package[i].action == ACTION_UNINSTALL) ? "uninstall"
|
|
814 : (package[i].action == ACTION_ERROR) ? "error"
|
|
815 : "unknown");
|
|
816
|
|
817 log (LOG_BABBLE, "[%s] action=%s trust=%s src? %s", package[i].name, action, trust,
|
|
818 package[i].srcaction == SRCACTION_NO ? "no" : "yes");
|
|
819 for (int t=0; t<NTRUST; t++)
|
|
820 {
|
|
821 if (package[i].info[t].install)
|
|
822 log (LOG_BABBLE, "[%s] ver %s inst %s %d src %s %d",
|
|
823 infos[t],
|
|
824 package[i].info[t].version ? package[i].info[t].version : "(none)",
|
|
825 package[i].info[t].install ? package[i].info[t].install : "(none)",
|
|
826 package[i].info[t].install_size,
|
|
827 package[i].info[t].source ? package[i].info[t].source : "(none)",
|
|
828 package[i].info[t].source_size);
|
|
829 }
|
|
830 }
|
|
831 }
|