]> cygwin.com Git - cygwin-apps/setup.git/blob - choose.cc
* choose.cc (do_choose): Fix incorrect assignment of trust setting to use when
[cygwin-apps/setup.git] / choose.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 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 static char *cvsid = "\n%%% $Id$\n";
29
30 #include "win32.h"
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <io.h>
34 #include <ctype.h>
35
36 #include "dialog.h"
37 #include "resource.h"
38 #include "state.h"
39 #include "ini.h"
40 #include "concat.h"
41 #include "msg.h"
42 #include "log.h"
43 #include "find.h"
44 #include "filemanip.h"
45 #include "mount.h"
46
47 #include "port.h"
48
49 #define HMARGIN 10
50 #define ROW_MARGIN 5
51 #define ICON_MARGIN 4
52
53 #define CHECK_SIZE 11
54
55 #define TRUST_KEEP 101
56 #define TRUST_UNINSTALL 102
57 #define TRUST_NONE 103
58 #define TRUST_REDO 104
59 #define TRUST_SRC_ONLY 105
60
61 static int initialized = 0;
62
63 static int full_list = 0;
64
65 static int scroll_ulc_x, scroll_ulc_y;
66
67 static HWND lv, nextbutton, choose_inst_text;
68 static TEXTMETRIC tm;
69 static int header_height;
70 static HANDLE sysfont;
71 static int row_height;
72 static HANDLE bm_spin, bm_rtarrow, bm_checkyes, bm_checkno, bm_checkna;
73 static HDC bitmap_dc;
74
75 static struct
76 {
77 char *text;
78 int slen;
79 int width;
80 int x;
81 }
82 headers[] = {
83 { "Current", 7, 0, 0 },
84 #define CURRENT_COL 0
85 { "New", 3, 0, 0 },
86 #define NEW_COL 1
87 { "Src?", 4, 0, 0 },
88 #define SRC_COL 2
89 { "Package", 7, 0, 0 },
90 #define PACKAGE_COL 3
91 { 0, 0, 0, 0 }
92 };
93 #define NUM_COLUMNS (sizeof (headers) / (sizeof (headers[0])) - 1)
94
95 int *package_indexes, nindexes;
96
97 struct ExtraPackageInfo
98 {
99 char *installed_file; /* filename of previous "install" file */
100 char *installed_ver; /* version part */
101 int installed_size; /* ditto, size. */
102
103 int in_partial_list;
104 int pick;
105 int npick;
106 int which_is_installed; /* == TRUST* or -1 */
107
108 struct
109 {
110 int src_avail;
111 int trust; /* may be keep or uninstall */
112 char *caption; /* ==0 at EOL */
113 }
114 chooser[NTRUST + 3]; /* one extra for NULL above */
115 };
116
117 static ExtraPackageInfo *extra;
118
119 static void
120 paint (HWND hwnd)
121 {
122 HDC hdc;
123 PAINTSTRUCT ps;
124 int x, y, i, j, ii;
125
126 hdc = BeginPaint (hwnd, &ps);
127
128 SelectObject (hdc, sysfont);
129 SetBkColor (hdc, GetSysColor (COLOR_WINDOW));
130
131 RECT cr;
132 GetClientRect (hwnd, &cr);
133
134 POINT p;
135
136 x = cr.left - scroll_ulc_x;
137 y = cr.top - scroll_ulc_y + header_height;
138
139
140 for (i = 0; headers[i].text; i++)
141 {
142 TextOut (hdc, x + headers[i].x, 3, headers[i].text, headers[i].slen);
143 MoveToEx (hdc, x + headers[i].x, header_height-3, &p);
144 LineTo (hdc, x + headers[i].x + headers[i].width, header_height-3);
145 }
146
147 IntersectClipRect (hdc, cr.left, cr.top + header_height, cr.right, cr.bottom);
148
149 for (ii = 0; ii < nindexes; ii++)
150 {
151 i = package_indexes[ii];
152 int r = y + ii * row_height;
153 int by = r + tm.tmHeight - 11;
154 if (extra[i].installed_ver && extra[i].installed_ver[0])
155 {
156 TextOut (hdc, x + headers[CURRENT_COL].x, r,
157 extra[i].installed_ver, strlen (extra[i].installed_ver));
158 SelectObject (bitmap_dc, bm_rtarrow);
159 BitBlt (hdc, x + headers[CURRENT_COL].x + headers[0].width + ICON_MARGIN/2 + HMARGIN/2, by,
160 11, 11, bitmap_dc, 0, 0, SRCCOPY);
161 }
162
163 char *s = extra[i].chooser[extra[i].pick].caption;
164 if (s)
165 {
166 TextOut (hdc, x + headers[NEW_COL].x + 11 + ICON_MARGIN, r,
167 s, strlen (s));
168 if (extra[i].npick > 1)
169 {
170 SelectObject (bitmap_dc, bm_spin);
171 BitBlt (hdc, x + headers[NEW_COL].x, by, 11, 11,
172 bitmap_dc, 0, 0, SRCCOPY);
173 }
174 }
175
176 HANDLE check_bm = bm_checkna;
177 if (extra[i].chooser[extra[i].pick].src_avail)
178 {
179 if (package[i].srcaction == SRCACTION_NO &&
180 extra[i].chooser[extra[i].pick].trust != TRUST_SRC_ONLY)
181 check_bm = bm_checkno;
182 else if (package[i].srcaction == SRCACTION_YES ||
183 extra[i].chooser[extra[i].pick].trust == TRUST_SRC_ONLY)
184 check_bm = bm_checkyes;
185 }
186 SelectObject (bitmap_dc, check_bm);
187 BitBlt (hdc, x + headers[SRC_COL].x, by, 11, 11,
188 bitmap_dc, 0, 0, SRCCOPY);
189
190 if (package[i].name)
191 TextOut (hdc, x + headers[PACKAGE_COL].x, r, package[i].name, strlen (package[i].name));
192 }
193
194 if (nindexes == 0)
195 {
196 static char *msg = "Nothing to Install/Update";
197 if (source == IDC_SOURCE_DOWNLOAD)
198 msg = "Nothing to Download";
199 TextOut (hdc, HMARGIN, header_height, msg, strlen (msg));
200 }
201
202 EndPaint (hwnd, &ps);
203 }
204
205 static void
206 scroll_common (HWND hwnd, int which, int *var, int code)
207 {
208 int v = *var;
209
210 SCROLLINFO si;
211 si.cbSize = sizeof (si);
212 si.fMask = SIF_ALL;
213 GetScrollInfo (hwnd, which, &si);
214
215 switch (code)
216 {
217 case SB_THUMBTRACK:
218 si.nPos = si.nTrackPos;
219 break;
220 case SB_THUMBPOSITION:
221 break;
222 case SB_BOTTOM:
223 si.nPos = si.nMax;
224 break;
225 case SB_TOP:
226 si.nPos = 0;
227 break;
228 case SB_LINEDOWN:
229 si.nPos += row_height;
230 break;
231 case SB_LINEUP:
232 si.nPos -= row_height;
233 break;
234 case SB_PAGEDOWN:
235 si.nPos += si.nPage * 9/10;
236 break;
237 case SB_PAGEUP:
238 si.nPos -= si.nPage * 9/10;
239 break;
240 }
241
242 if ((int)si.nPos < 0)
243 si.nPos = 0;
244 if (si.nPos + si.nPage > si.nMax)
245 si.nPos = si.nMax - si.nPage;
246
247 si.fMask = SIF_POS;
248 SetScrollInfo (hwnd, which, &si, TRUE);
249
250 int ox = scroll_ulc_x;
251 int oy = scroll_ulc_y;
252 *var = si.nPos;
253
254 RECT cr, sr;
255 GetClientRect (hwnd, &cr);
256 sr = cr;
257 sr.top += header_height;
258 ScrollWindow (hwnd, ox - scroll_ulc_x, oy - scroll_ulc_y, &sr, &sr);
259 sr.bottom = sr.top;
260 sr.top = cr.top;
261 ScrollWindow (hwnd, ox - scroll_ulc_x, 0, &sr, &sr);
262 }
263
264 static LRESULT CALLBACK
265 list_vscroll (HWND hwnd, HWND hctl, UINT code, int pos)
266 {
267 scroll_common (hwnd, SB_VERT, &scroll_ulc_y, code);
268 }
269
270 static LRESULT CALLBACK
271 list_hscroll (HWND hwnd, HWND hctl, UINT code, int pos)
272 {
273 scroll_common (hwnd, SB_HORZ, &scroll_ulc_x, code);
274 }
275
276 static LRESULT CALLBACK
277 list_click (HWND hwnd, BOOL dblclk, int x, int y, UINT hitCode)
278 {
279 int r;
280
281 if (nindexes == 0)
282 return 0;
283
284 if (y < header_height)
285 return 0;
286 x += scroll_ulc_x;
287 y += scroll_ulc_y - header_height;
288
289 r = (y + ROW_MARGIN/2) / row_height;
290
291 if (r < 0 || r >= npackages)
292 return 0;
293
294 int p = package_indexes[r];
295
296 if (x >= headers[NEW_COL].x - HMARGIN/2 && x <= headers[NEW_COL + 1].x - HMARGIN/2)
297 {
298 extra[p].pick++;
299 while (extra[p].chooser[extra[p].pick].trust < NTRUST &&
300 (package[p].info[extra[p].chooser[extra[p].pick].trust].install_exists
301 ==0 && source == IDC_SOURCE_CWD) &&
302 package[p].info[extra[p].chooser[extra[p].pick].trust].install &&
303 extra[p].chooser[extra[p].pick].caption != 0)
304 extra[p].pick++;
305 if (extra[p].chooser[extra[p].pick].caption == 0)
306 extra[p].pick = 0;
307 }
308
309 if (x >= headers[SRC_COL].x - HMARGIN/2 && x <= headers[SRC_COL + 1].x - HMARGIN/2)
310 {
311 if (extra[p].chooser[extra[p].pick].src_avail)
312 package[p].srcaction ^= (SRCACTION_NO^SRCACTION_YES);
313 }
314
315 RECT rect;
316 rect.left = headers[NEW_COL].x - scroll_ulc_x;
317 rect.right = headers[SRC_COL + 1].x - scroll_ulc_x;
318 rect.top = header_height + r * row_height - scroll_ulc_y;
319 rect.bottom = rect.top + row_height;
320 InvalidateRect (hwnd, &rect, TRUE);
321 }
322
323 static LRESULT CALLBACK
324 listview_proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
325 {
326 switch (message)
327 {
328 case WM_HSCROLL:
329 return HANDLE_WM_HSCROLL (hwnd, wParam, lParam, list_hscroll);
330 case WM_VSCROLL:
331 return HANDLE_WM_VSCROLL (hwnd, wParam, lParam, list_vscroll);
332 case WM_LBUTTONDOWN:
333 return HANDLE_WM_LBUTTONDOWN (hwnd, wParam, lParam, list_click);
334 case WM_PAINT:
335 paint (hwnd);
336 return 0;
337 default:
338 return DefWindowProc (hwnd, message, wParam, lParam);
339 }
340 }
341
342 static void
343 register_windows (HINSTANCE hinst)
344 {
345 WNDCLASSEX wcex;
346 static int done = 0;
347
348 if (done)
349 return;
350 done = 1;
351
352 memset (&wcex, 0, sizeof (wcex));
353 wcex.cbSize = sizeof (WNDCLASSEX);
354 wcex.style = CS_HREDRAW | CS_VREDRAW;
355 wcex.lpfnWndProc = listview_proc;
356 wcex.hInstance = hinst;
357 wcex.hIcon = LoadIcon (0, IDI_APPLICATION);
358 wcex.hCursor = LoadCursor (0, IDC_ARROW);
359 wcex.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
360 wcex.lpszClassName = "listview";
361
362 RegisterClassEx (&wcex);
363 }
364
365 static void
366 note_width (HDC dc, char *string, int addend, int column)
367 {
368 if (!string)
369 return;
370 SIZE s;
371 GetTextExtentPoint32 (dc, string, strlen (string), &s);
372 if (headers[column].width < s.cx + addend)
373 headers[column].width = s.cx + addend;
374 }
375
376 static int
377 check_existence (int p, int trust, int check_src)
378 {
379 if (source == IDC_SOURCE_NETINST)
380 return 1;
381 if (source == IDC_SOURCE_DOWNLOAD)
382 {
383 if (check_src == 0 && _access (package[p].info[trust].install, 0) == 0)
384 return 1;
385 else if (check_src == 1 && _access (package[p].info[trust].source, 0) == 0)
386 return 1;
387 else
388 return 0;
389 }
390 if (source == IDC_SOURCE_CWD)
391 {
392 if (check_src == 0 && package[p].info[trust].install &&
393 _access (package[p].info[trust].install, 0) == 0)
394 return 1;
395 else if (check_src == 1 && package[p].info[trust].source &&
396 _access (package[p].info[trust].source, 0) == 0)
397 return 1;
398 }
399 return 0;
400 }
401
402 static void
403 set_existence ()
404 {
405 for (int i = 0; i < npackages; i++)
406 {
407 for (int t = 0; t < NTRUST; t++)
408 {
409 /* 0 = check install file */
410 package[i].info[t].install_exists = check_existence (i, t, 0);
411 /* 1 = check source file */
412 package[i].info[t].source_exists = check_existence (i, t, 1);
413 }
414 for (int t = 0; t < NTRUST; t++)
415 {
416 if (package[i].info[t].install &&
417 extra[i].installed_ver != package[i].info[t].version)
418 {
419 if (source == IDC_SOURCE_NETINST)
420 package[i].info[t].partial_list_display = 1;
421 else if (source == IDC_SOURCE_DOWNLOAD)
422 package[i].info[t].partial_list_display = 1-package[i].info[t].install_exists;
423 else if (source == IDC_SOURCE_CWD)
424 if (package[i].info[t].install_exists)
425 package[i].info[t].partial_list_display = 1;
426 else
427 package[i].info[t].partial_list_display = 0;
428 }
429 if (package[i].info[t].partial_list_display)
430 extra[i].in_partial_list = 1;
431
432 }
433 }
434 }
435
436 static int
437 best_trust (int p, int trust)
438 {
439 int t;
440 t = trust;
441 if (package[p].info[t].install &&
442 ((package[p].info[t].install_exists && source == IDC_SOURCE_CWD) ||
443 (package[p].info[t].install_exists == 0 &&
444 source == IDC_SOURCE_DOWNLOAD) || source == IDC_SOURCE_NETINST))
445 return t;
446 if (extra[p].installed_file && extra[p].installed_ver == package[p].info[t].version)
447 return TRUST_KEEP;
448 return TRUST_NONE;
449 }
450
451 static void
452 default_trust (HWND h, int trust)
453 {
454 int i, t, c;
455
456 for (i = 0; i < npackages; i++)
457 {
458 t = best_trust (i, trust);
459 extra[i].pick = 1;
460 package[i].trust = t;
461 for (c = 0; c < extra[i].npick; c++)
462 if (t == extra[i].chooser[c].trust)
463 extra[i].pick = c;
464 }
465 RECT r;
466 GetClientRect (h, &r);
467 InvalidateRect (h, &r, TRUE);
468 if (nextbutton)
469 SetFocus (nextbutton);
470 }
471
472 static void
473 set_full_list (HWND h, int isfull)
474 {
475 int i, j;
476 full_list = isfull;
477 if (package_indexes == 0)
478 package_indexes = (int *) malloc (npackages * sizeof (int));
479 for (i = j = 0; i < npackages; i++)
480 {
481 if ((isfull || (extra[i].in_partial_list &&
482 extra[i].chooser[extra[i].pick].trust != TRUST_KEEP &&
483 extra[i].chooser[extra[i].pick].trust != TRUST_NONE)) &&
484 (source == IDC_SOURCE_DOWNLOAD || source == IDC_SOURCE_NETINST ||
485 package[i].info[TRUST_PREV].install_exists ||
486 package[i].info[TRUST_CURR].install_exists ||
487 package[i].info[TRUST_TEST].install_exists))
488 package_indexes[j++] = i;
489 }
490 nindexes = j;
491
492 RECT r;
493 GetClientRect (h, &r);
494 SCROLLINFO si;
495 memset (&si, 0, sizeof (si));
496 si.cbSize = sizeof (si);
497 si.fMask = SIF_ALL;
498 si.nMin = 0;
499 si.nMax = headers[2].x + headers[2].width + HMARGIN;
500 si.nPage = r.right;
501 SetScrollInfo (h, SB_HORZ, &si, TRUE);
502
503 si.nMax = nindexes * row_height;
504 si.nPage = r.bottom - header_height;
505 SetScrollInfo (h, SB_VERT, &si, TRUE);
506
507 scroll_ulc_x = scroll_ulc_y = 0;
508
509 InvalidateRect (h, &r, TRUE);
510
511 if (nextbutton)
512 SetFocus (nextbutton);
513 }
514
515 static void
516 build_labels ()
517 {
518 int i;
519 for (i = 0; i < npackages; i++)
520 {
521 int c = 0, t;
522
523 #define C extra[i].chooser[c]
524 if (extra[i].installed_ver)
525 {
526 C.caption = "Uninstall";
527 C.trust = TRUST_UNINSTALL;
528 c++;
529 C.caption = "Keep";
530 C.trust = TRUST_KEEP;
531 c++;
532 }
533
534 if (extra[i].installed_ver &&
535 package[i].info[extra[i].which_is_installed].source &&
536 ((package[i].info[extra[i].which_is_installed].source_exists &&
537 source==IDC_SOURCE_CWD) ||
538 source==IDC_SOURCE_DOWNLOAD || source==IDC_SOURCE_NETINST ))
539 {
540 C.caption = "Sources";
541 if (package[i].info[extra[i].which_is_installed].source_exists == 1 &&
542 source == IDC_SOURCE_DOWNLOAD)
543 C.caption = "Redo Sources";
544 C.trust = TRUST_SRC_ONLY;
545 C.src_avail = 1;
546 c++;
547 }
548
549 for (t = TRUST_PREV; t < NTRUST; t++)
550 if (package[i].info[t].install)
551 if (t != extra[i].which_is_installed)
552 {
553 C.caption = package[i].info[t].version;
554 if (C.caption == 0 || C.caption[0] == 0)
555 C.caption = "0.0";
556 C.trust = t;
557 if (package[i].info[t].source &&
558 ((package[i].info[t].source_exists &&
559 source==IDC_SOURCE_CWD) ||
560 (package[i].info[t].source_exists==0 &&
561 source==IDC_SOURCE_DOWNLOAD) || source==IDC_SOURCE_NETINST))
562 C.src_avail = 1;
563 c++;
564 }
565 else
566 {
567 if (source == IDC_SOURCE_DOWNLOAD)
568 {
569 C.caption = "ReDownload";
570 }
571 else
572 {
573 C.caption = "ReInstall";
574 }
575 if (package[i].info[t].source &&
576 ((package[i].info[t].source_exists &&
577 source==IDC_SOURCE_CWD) ||
578 source == IDC_SOURCE_DOWNLOAD || source==IDC_SOURCE_NETINST))
579 C.src_avail = 1;
580 C.trust = TRUST_REDO;
581 c++;
582 }
583
584 if (c == 0)
585 {
586 C.caption = "N/A";
587 C.trust = TRUST_NONE;
588 c++;
589 }
590
591 if (! extra[i].installed_file)
592 {
593 C.caption = "Skip";
594 C.trust = TRUST_NONE;
595 c++;
596 }
597
598 C.caption = 0;
599 extra[i].npick = c;
600 #undef C
601 }
602 }
603
604 static void
605 create_listview (HWND dlg, RECT *r)
606 {
607 int i, t;
608 lv = CreateWindowEx (WS_EX_CLIENTEDGE,
609 "listview",
610 "listviewwindow",
611 WS_CHILD | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE,
612 r->left, r->top,
613 r->right-r->left + 1, r->bottom-r->top + 1,
614 dlg,
615 (HMENU) MAKEINTRESOURCE(IDC_CHOOSE_LIST),
616 hinstance,
617 0);
618 ShowWindow (lv, SW_SHOW);
619
620 for (i = 0; headers[i].text; i++)
621 headers[i].width = 0;
622
623 HDC dc = GetDC (lv);
624 sysfont = GetStockObject (DEFAULT_GUI_FONT);
625 SelectObject (dc, sysfont);
626 GetTextMetrics (dc, &tm);
627 header_height = tm.tmHeight + 5 + 3;
628
629 bitmap_dc = CreateCompatibleDC (dc);
630
631 row_height = (tm.tmHeight + tm.tmExternalLeading + ROW_MARGIN);
632 int irh = tm.tmExternalLeading + tm.tmDescent + 11 + ROW_MARGIN;
633 if (row_height < irh)
634 row_height = irh;
635
636 for (i = 0; headers[i].text; i++)
637 note_width (dc, headers[i].text, 0, i);
638 for (i = 0; i < npackages; i++)
639 {
640 note_width (dc, extra[i].installed_ver, 0, CURRENT_COL);
641 note_width (dc, extra[i].installed_ver, 11 + ICON_MARGIN, NEW_COL);
642 for (t = 0; t < NTRUST; t++)
643 note_width (dc, package[i].info[t].version, 11 + ICON_MARGIN, NEW_COL);
644 note_width (dc, package[i].name, 0, PACKAGE_COL);
645 note_width (dc, package[i].sdesc, 0, PACKAGE_COL);
646 }
647 note_width (dc, "keep", 11 + ICON_MARGIN, NEW_COL);
648 note_width (dc, "uninstall", 11 + ICON_MARGIN, NEW_COL);
649
650 headers[CURRENT_COL].x = HMARGIN/2;
651 headers[NEW_COL].x = (headers[CURRENT_COL].x + headers[CURRENT_COL].width
652 + HMARGIN + 11 + ICON_MARGIN);
653 headers[SRC_COL].x = headers[NEW_COL].x + headers[NEW_COL].width + HMARGIN;
654 headers[PACKAGE_COL].x = headers[SRC_COL].x + headers[SRC_COL].width + HMARGIN;
655
656 default_trust (lv, TRUST_CURR);
657 set_full_list (lv, full_list);
658 static int ta[] = { IDC_CHOOSE_CURR, 0 };
659 rbset (dlg, ta, IDC_CHOOSE_CURR);
660
661 ReleaseDC (lv, dc);
662 }
663
664 static BOOL
665 dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
666 {
667 switch (id)
668 {
669 case IDC_CHOOSE_PREV:
670 default_trust (lv, TRUST_PREV);
671 set_full_list (lv, full_list);
672 break;
673 case IDC_CHOOSE_CURR:
674 default_trust (lv, TRUST_CURR);
675 set_full_list (lv, full_list);
676 break;
677 case IDC_CHOOSE_EXP:
678 default_trust (lv, TRUST_TEST);
679 set_full_list (lv, full_list);
680 break;
681 case IDC_CHOOSE_FULLPART:
682 set_full_list (lv, !full_list);
683 break;
684
685 case IDOK:
686 if (source == IDC_SOURCE_CWD)
687 NEXT (IDD_S_INSTALL);
688 else
689 NEXT (IDD_S_DOWNLOAD);
690 break;
691
692 case IDC_BACK:
693 initialized = 0;
694 if (source == IDC_SOURCE_CWD)
695 NEXT (IDD_ROOT);
696 else
697 NEXT (IDD_SITE);
698 break;
699
700 case IDCANCEL:
701 NEXT (0);
702 break;
703 }
704 }
705
706 static void
707 GetParentRect (HWND parent, HWND child, RECT *r)
708 {
709 POINT p;
710 GetWindowRect (child, r);
711 p.x = r->left;
712 p.y = r->top;
713 ScreenToClient (parent, &p);
714 r->left = p.x;
715 r->top = p.y;
716 p.x = r->right;
717 p.y = r->bottom;
718 ScreenToClient (parent, &p);
719 r->right = p.x;
720 r->bottom = p.y;
721 }
722
723 static BOOL CALLBACK
724 dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
725 {
726 int i, j;
727 HWND frame;
728 RECT r;
729 switch (message)
730 {
731 case WM_INITDIALOG:
732 nextbutton = GetDlgItem (h, IDOK);
733 frame = GetDlgItem (h, IDC_LISTVIEW_POS);
734 choose_inst_text = GetDlgItem(h,IDC_CHOOSE_INST_TEXT);
735 if (source == IDC_SOURCE_DOWNLOAD)
736 SetWindowText (choose_inst_text, "Select packages to download ");
737 else
738 SetWindowText (choose_inst_text, "Select packages to install ");
739 GetParentRect (h, frame, &r);
740 r.top += 2;
741 r.bottom -= 2;
742 create_listview (h, &r);
743 #if 0
744 load_dialog (h);
745 #endif
746 return FALSE;
747 case WM_COMMAND:
748 return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd);
749 }
750 return FALSE;
751 }
752
753 static char *
754 base (char *s)
755 {
756 if (!s)
757 return 0;
758 char *rv = s;
759 while (*s)
760 {
761 if ((*s == '/' || *s == ':' || *s == '\\') && s[1])
762 rv = s + 1;
763 s++;
764 }
765 return rv;
766 }
767
768 static void
769 get_package_version (int p , int trust)
770 {
771 char *v, *d;
772 char instpkg[_MAX_PATH];
773 instpkg[0]=0; /* make sure empty to start with */
774 if (trust == -1)
775 strcpy (instpkg, extra[p].installed_file);
776 else
777 strcpy (instpkg, package[p].info[trust].install);
778 for (v = base (instpkg); *v; v++)
779 if (*v == '-' && isdigit (v[1]))
780 {
781 v++;
782 break;
783 }
784 if (!v)
785 v = instpkg;
786 for (d = v; *d; d++)
787 if (strncmp (d, ".tar", 4) == 0)
788 {
789 *d = 0;
790 break;
791 }
792 if (v[0])
793 {
794 if (trust != -1)
795 package[p].info[trust].version = strdup (v);
796 extra[p].installed_ver = strdup (v);
797 }
798 else
799 {
800 if (trust != -1)
801 package[p].info[trust].version = "0";
802 extra[p].installed_ver = "0";
803 }
804 }
805
806 int
807 find_tar_ext (const char *path)
808 {
809 char *p = strchr (path, '\0') - 7;
810 if (p <= path)
811 return 0;
812 if (*p == '.')
813 {
814 if (strcmp (p, ".tar.gz") != 0)
815 return 0;
816 }
817 else if (--p <= path || strcmp (p, ".tar.bz2") != 0)
818 return 0;
819
820 return p - path;
821 }
822
823 static void
824 scan2 (char *path, unsigned int size)
825 {
826 int i, t, c, tarext;
827 int matched;
828
829 tarext = find_tar_ext (path);
830 if (!tarext)
831 return;
832
833 char mainpkg[_MAX_PATH], pkginfo[_MAX_PATH], tarpkg[_MAX_PATH],
834 *ver, *verinfo;
835
836 strcpy (mainpkg, path);
837 strcpy (tarpkg, path);
838 mainpkg[tarext] = 0; /* strip off the tar.[bg]z2? */
839
840 for (ver = mainpkg; *ver; ver++)
841 if ((*ver == '-' || *ver == '_') && isdigit (ver[1]))
842 {
843 *ver++ = 0;
844 break;
845 }
846
847 for (i = 0; i < npackages; i++)
848 {
849 pkginfo[0] = 0;
850 for (t = 0; t < NTRUST; t++)
851 {
852 if (package[i].info[t].install)
853 {
854 strcpy (pkginfo, package[i].info[t].install);
855 pkginfo[find_tar_ext (pkginfo)] = '\0'; /* strip off the tar.gz */
856 for (verinfo = pkginfo; *verinfo; verinfo++)
857 {
858 if ((*verinfo == '-' || *verinfo == '_') && isdigit (verinfo[1]))
859 {
860 *verinfo++ = 0;
861 break;
862 }
863 }
864 break;
865 }
866 }
867 if (strcmp (pkginfo, mainpkg) == 0)
868 {
869 for (t = 0; t < NTRUST; t++)
870 if ((package[i].info[t].install &&
871 strcmp (base (package[i].info[t].install), base (path)) == 0) ||
872 (package[i].info[t].source &&
873 strcmp (base (package[i].info[t].source), base (path)) == 0))
874 {
875 if (strcmp (base (package[i].info[t].install), base (path)) == 0)
876 package[i].info[t].install_exists = 1;
877 else
878 package[i].info[t].source_exists = 1;
879 break;
880 }
881 else if (t >= NTRUST - 1)
882 if (!package[i].info[TRUST_CURR].install)
883 {
884 package[i].info[TRUST_CURR].version = 0;
885 int tarsrcext = tarext - 4;
886 if (tarsrcext > 0 && strncmp (path + tarsrcext , "-src", 4) == 0)
887 {
888 int n = find_tar_ext (tarpkg);
889 memmove (tarpkg + n - 4, tarpkg + n, strlen (tarpkg + n) + 1);
890 package[i].info[TRUST_CURR].install = strdup (tarpkg);
891 if (!package[i].info[TRUST_CURR].source)
892 package[i].info[TRUST_CURR].source = strdup (path);
893 package[i].info[TRUST_CURR].source_size = size;
894 package[i].info[TRUST_CURR].source_exists = 1;
895 if (package[i].info[TRUST_CURR].version == 0)
896 get_package_version (i, TRUST_CURR);
897 }
898 else
899 {
900 package[i].info[TRUST_CURR].install = strdup (path);
901 package[i].info[TRUST_CURR].install_size = size;
902 package[i].info[TRUST_CURR].install_exists = 1;
903 if (package[i].info[TRUST_CURR].version == 0)
904 get_package_version (i, TRUST_CURR);
905 }
906 break;
907 }
908 else if (!package[i].info[TRUST_PREV].install)
909 {
910 package[i].info[TRUST_PREV].version = 0;
911 int tarsrcext = tarext - 4;
912 if (tarsrcext > 0 && strncmp (path + tarsrcext , "-src", 4) == 0)
913 {
914 int n = find_tar_ext (tarpkg);
915 memmove (tarpkg + n - 4, tarpkg + n, strlen (tarpkg + n) + 1);
916 package[i].info[TRUST_PREV].install = strdup (tarpkg);
917 if (!package[i].info[TRUST_PREV].source)
918 package[i].info[TRUST_PREV].source = strdup (path);
919 package[i].info[TRUST_PREV].source_size = size;
920 package[i].info[TRUST_PREV].source_exists = 1;
921 if (package[i].info[TRUST_PREV].version == 0)
922 get_package_version (i, TRUST_PREV);
923 }
924 else
925 {
926 package[i].info[TRUST_PREV].install = strdup (path);
927 package[i].info[TRUST_PREV].install_size = size;
928 package[i].info[TRUST_PREV].install_exists = 1;
929 if (package[i].info[TRUST_PREV].version == 0)
930 get_package_version (i, TRUST_PREV);
931 }
932 break;
933 }
934 break;
935 }
936 }
937 }
938
939 static void
940 scan_downloaded_files ()
941 {
942 find (".", scan2);
943 }
944
945 static void
946 read_installed_db ()
947 {
948 int i;
949 if (!root_dir)
950 return;
951
952 char line[1000], pkg[1000], inst[1000], src[1000];
953 int instsz, srcsz;
954
955 FILE *db = fopen (cygpath ("/etc/setup/installed.db", 0), "rt");
956 if (!db)
957 return;
958
959 while (fgets (line, 1000, db))
960 {
961 src[0] = 0;
962 srcsz = 0;
963 sscanf (line, "%s %s %d %s %d", pkg, inst, &instsz, src, &srcsz);
964
965 for (i = 0; i < npackages; i++)
966 if (strcmp (package[i].name, pkg) == 0)
967 {
968 int t;
969 extra[i].installed_file = inst;
970 extra[i].installed_size = instsz;
971 get_package_version (i, -1);
972
973 char *binst = base (inst);
974 int n = find_tar_ext (binst) + 4;
975 for (t = 0; t < NTRUST; t++)
976 if (package[i].info[t].install
977 && strncmp (base (package[i].info[t].install), binst, n) == 0)
978 {
979 extra[i].which_is_installed = t;
980 extra[i].installed_ver = package[i].info[t].version;
981 if (extra[i].installed_ver == 0) /* still */
982 get_package_version (i, t);
983 break;
984 }
985
986 if (extra[i].installed_ver == 0) /* still */
987 get_package_version (i, -1);
988 break;
989 }
990 }
991 fclose (db);
992 }
993
994 int
995 package_sort (const void *va, const void *vb)
996 {
997 Package *a = (Package *)va;
998 Package *b = (Package *)vb;
999 return strcmp (a->name, b->name);
1000 }
1001
1002 void
1003 do_choose (HINSTANCE h)
1004 {
1005 int rv, i;
1006
1007 qsort (package, npackages, sizeof (package[0]), package_sort);
1008
1009 nextbutton = 0;
1010 bm_spin = LoadImage (h, MAKEINTRESOURCE (IDB_SPIN), IMAGE_BITMAP, 0, 0, 0);
1011 bm_rtarrow = LoadImage (h, MAKEINTRESOURCE (IDB_RTARROW), IMAGE_BITMAP, 0, 0, 0);
1012
1013 bm_checkyes = LoadImage (h, MAKEINTRESOURCE (IDB_CHECK_YES), IMAGE_BITMAP, 0, 0, 0);
1014 bm_checkno = LoadImage (h, MAKEINTRESOURCE (IDB_CHECK_NO), IMAGE_BITMAP, 0, 0, 0);
1015 bm_checkna = LoadImage (h, MAKEINTRESOURCE (IDB_CHECK_NA), IMAGE_BITMAP, 0, 0, 0);
1016
1017 extra = (ExtraPackageInfo *) malloc (npackages * sizeof (ExtraPackageInfo));
1018 memset (extra, 0, npackages * sizeof (ExtraPackageInfo));
1019 for (i = 0; i < npackages; i++)
1020 {
1021 extra[i].which_is_installed = -1;
1022 extra[i].in_partial_list = 0;
1023 extra[i].pick = 1;
1024 extra[i].chooser[extra[i].pick].trust = TRUST_NONE;
1025 for (int t = 0; t < NTRUST; t++)
1026 {
1027 package[i].info[t].partial_list_display = 0;
1028 package[i].info[t].install_exists = 0;
1029 package[i].info[t].source_exists = 0;
1030 }
1031 }
1032
1033 register_windows (h);
1034
1035 if (source == IDC_SOURCE_DOWNLOAD || source == IDC_SOURCE_CWD)
1036 scan_downloaded_files ();
1037
1038 read_installed_db ();
1039 set_existence ();
1040 build_labels ();
1041
1042 rv = DialogBox (h, MAKEINTRESOURCE (IDD_CHOOSE), 0, dialog_proc);
1043 if (rv == -1)
1044 fatal (IDS_DIALOG_FAILED);
1045
1046 for (i = 0; i < npackages; i++)
1047 {
1048 switch (extra[i].chooser[extra[i].pick].trust)
1049 {
1050 case TRUST_PREV:
1051 case TRUST_CURR:
1052 case TRUST_TEST:
1053 if (extra[i].installed_file)
1054 package[i].action = ACTION_UPGRADE;
1055 else
1056 package[i].action = ACTION_NEW;
1057 package[i].trust = extra[i].chooser[extra[i].pick].trust;
1058 break;
1059
1060 case TRUST_REDO:
1061 package[i].action = ACTION_REDO;
1062 if ( extra[i].which_is_installed >= 0
1063 && extra[i].which_is_installed <= TRUST_TEST)
1064 package[i].trust = extra[i].which_is_installed;
1065 else
1066 package[i].trust = TRUST_CURR;
1067 break;
1068
1069 case TRUST_UNINSTALL:
1070 package[i].action = ACTION_UNINSTALL;
1071 if (package[i].srcaction == SRCACTION_YES)
1072 package[i].action = ACTION_SRC_ONLY;
1073 break;
1074
1075 case TRUST_SRC_ONLY:
1076 package[i].action = ACTION_SRC_ONLY;
1077 if ( extra[i].which_is_installed >= 0
1078 && extra[i].which_is_installed <= TRUST_TEST)
1079 package[i].trust = extra[i].which_is_installed;
1080 else
1081 package[i].trust = TRUST_CURR;
1082 package[i].srcaction = SRCACTION_YES;
1083 break;
1084
1085 case TRUST_KEEP:
1086 case TRUST_NONE:
1087 default:
1088 package[i].action = ACTION_SAME;
1089 if (package[i].srcaction == SRCACTION_YES)
1090 package[i].action = ACTION_SRC_ONLY;
1091 break;
1092 }
1093 }
1094
1095 log (LOG_BABBLE, "Chooser results...");
1096 for (i = 0; i < npackages; i++)
1097 {
1098 static char *infos[] = {"prev", "curr", "test"};
1099 const char *trust = ((package[i].trust == TRUST_PREV) ? "prev"
1100 : (package[i].trust == TRUST_CURR) ? "curr"
1101 : (package[i].trust == TRUST_TEST) ? "test"
1102 : "unknown");
1103 const char *action = ((package[i].action == ACTION_UNKNOWN) ? "unknown"
1104 : (package[i].action == ACTION_SAME) ? "same"
1105 : (package[i].action == ACTION_NEW) ? "new"
1106 : (package[i].action == ACTION_UPGRADE) ? "upgrade"
1107 : (package[i].action == ACTION_UNINSTALL) ? "uninstall"
1108 : (package[i].action == ACTION_REDO &&
1109 source == IDC_SOURCE_DOWNLOAD) ? "redownload"
1110 : (package[i].action == ACTION_REDO &&
1111 source != IDC_SOURCE_DOWNLOAD) ? "reinstall"
1112 : (package[i].action == ACTION_SRC_ONLY) ? "sources"
1113 : (package[i].action == ACTION_ERROR) ? "error"
1114 : "unknown");
1115 const char *installed = ((extra[i].which_is_installed == -1) ? "none"
1116 : (extra[i].which_is_installed == TRUST_PREV) ? "prev"
1117 : (extra[i].which_is_installed == TRUST_CURR) ? "curr"
1118 : (extra[i].which_is_installed == TRUST_TEST) ? "test"
1119 : "unknown");
1120 const char *partial_list = ((extra[i].in_partial_list == 1) ? "yes" : "no");
1121
1122 log (LOG_BABBLE, "[%s] action=%s trust=%s installed=%s partial_list=%s src?=%s",
1123 package[i].name, action, trust, installed,
1124 partial_list, package[i].srcaction == SRCACTION_NO ? "no" : "yes");
1125 for (int t = 0; t < NTRUST; t++)
1126 {
1127 if (package[i].info[t].install)
1128 log (LOG_BABBLE, " [%s] ver=%s partial_list=%s \r\n inst=%s %d exists=%s \r\n src=%s %d exists=%s",
1129 infos[t],
1130 package[i].info[t].version ?: "(none)",
1131 (package[i].info[t].partial_list_display == 1) ? "yes":"no",
1132 package[i].info[t].install ?: "(none)",
1133 package[i].info[t].install_size,
1134 (package[i].info[t].install_exists == 1) ? "yes":"no",
1135 package[i].info[t].source ?: "(none)",
1136 package[i].info[t].source_size,
1137 (package[i].info[t].source_exists == 1) ? "yes":"no");
1138 }
1139 }
1140 }
This page took 0.08164 seconds and 5 git commands to generate.