]>
Commit | Line | Data |
---|---|---|
904d24fe | 1 | /* |
31324d15 | 2 | * Copyright (c) 2000, 2001 Red Hat, Inc. |
904d24fe DD |
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 manage all the desktop setup, such | |
17 | as start menu, batch files, desktop icons, and shortcuts. Note | |
18 | that unlike other do_* functions, this one is called directly from | |
19 | install.cc */ | |
20 | ||
b24c88b3 RC |
21 | #if 0 |
22 | static const char *cvsid = | |
23 | "\n%%% $Id$\n"; | |
24 | #endif | |
8507f105 | 25 | |
904d24fe | 26 | #include "win32.h" |
ad09bcd9 | 27 | #include <shlobj.h> |
cfae3b8d | 28 | #include "desktop.h" |
f2ff9838 | 29 | #include "propsheet.h" |
904d24fe DD |
30 | |
31 | #include <stdio.h> | |
32 | #include <stdlib.h> | |
33 | #include <unistd.h> | |
34 | ||
35 | #include "resource.h" | |
36 | #include "msg.h" | |
37 | #include "state.h" | |
904d24fe | 38 | #include "dialog.h" |
ef2007fd | 39 | #include "version.h" |
a351e48c | 40 | #include "mount.h" |
904d24fe DD |
41 | |
42 | #include "port.h" | |
43 | ||
b24c88b3 | 44 | #include "mklink2.h" |
904d24fe | 45 | |
bb849dbd RC |
46 | #include "package_db.h" |
47 | #include "package_meta.h" | |
48 | #include "package_version.h" | |
49 | ||
3c054baf RC |
50 | #include "filemanip.h" |
51 | #include "String++.h" | |
52 | #include "io_stream.h" | |
53 | ||
6908b7d7 | 54 | #include "getopt++/BoolOption.h" |
ab57ceaa | 55 | |
cfae3b8d RC |
56 | #include "PackageSpecification.h" |
57 | ||
6908b7d7 | 58 | static BoolOption NoShortcutsOption (false, 'n', "no-shortcuts", "Disable creation of desktop and start menu shortcuts"); |
f2ff9838 RC |
59 | static BoolOption NoStartMenuOption (false, 'N', "no-startmenu", "Disable creation of start menu shortcut"); |
60 | static BoolOption NoDesktopOption (false, 'd', "no-desktop", "Disable creation of desktop shortcut"); | |
3c054baf | 61 | |
3a8e3956 DD |
62 | static OSVERSIONINFO verinfo; |
63 | ||
64 | /* Lines starting with '@' are conditionals - include 'N' for NT, | |
65 | '5' for Win95, '8' for Win98, '*' for all, like this: | |
66 | echo foo | |
67 | @N8 | |
68 | echo NT or 98 | |
69 | @* | |
70 | */ | |
71 | ||
3c054baf RC |
72 | #define COMMAND9XARGS String("/E:4096 /c") |
73 | #define COMMAND9XEXE String("\\command.com") | |
904d24fe | 74 | |
3c054baf RC |
75 | static String batname; |
76 | static String iconname; | |
904d24fe | 77 | |
904d24fe | 78 | static void |
3c054baf | 79 | make_link (String const &linkpath, String const &title, String const &target) |
904d24fe | 80 | { |
3c054baf | 81 | String fname = linkpath + "/" + title + ".lnk"; |
904d24fe | 82 | |
3c054baf | 83 | if (_access (fname.cstr_oneuse(), 0) == 0) |
b24c88b3 | 84 | return; /* already exists */ |
904d24fe | 85 | |
1ac649ed RC |
86 | msg ("make_link %s, %s, %s\n", |
87 | fname.cstr_oneuse(), title.cstr_oneuse(), target.cstr_oneuse()); | |
904d24fe | 88 | |
2fa7c5a4 | 89 | io_stream::mkpath_p (PATH_TO_FILE, String ("file://") + fname); |
904d24fe | 90 | |
3c054baf | 91 | String exepath; |
904d24fe | 92 | |
3c054baf | 93 | String argbuf; |
904d24fe | 94 | /* If we are running Win9x, build a command line. */ |
904d24fe DD |
95 | if (verinfo.dwPlatformId == VER_PLATFORM_WIN32_NT) |
96 | { | |
3c054baf RC |
97 | exepath = target; |
98 | argbuf = " "; | |
99 | // sprintf (argbuf, " "); | |
904d24fe DD |
100 | } |
101 | else | |
102 | { | |
904d24fe DD |
103 | char windir[MAX_PATH]; |
104 | ||
105 | GetWindowsDirectory (windir, sizeof (windir)); | |
3c054baf RC |
106 | exepath = String(windir) + COMMAND9XEXE; |
107 | argbuf = COMMAND9XARGS + " " + target; | |
108 | // sprintf (argbuf, "%s %s", COMMAND9XARGS, target.cstr_oneuse()); | |
904d24fe DD |
109 | } |
110 | ||
1ac649ed RC |
111 | msg ("make_link_2 (%s, %s, %s, %s)", |
112 | exepath.cstr_oneuse(), argbuf.cstr_oneuse(), | |
113 | iconname.cstr_oneuse(), fname.cstr_oneuse()); | |
114 | make_link_2 (exepath.cstr_oneuse(), argbuf.cstr_oneuse(), | |
115 | iconname.cstr_oneuse(), fname.cstr_oneuse()); | |
904d24fe DD |
116 | } |
117 | ||
118 | static void | |
3c054baf | 119 | start_menu (String const &title, String const &target) |
904d24fe | 120 | { |
904d24fe | 121 | LPITEMIDLIST id; |
24e259bb | 122 | int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0; |
b24c88b3 RC |
123 | SHGetSpecialFolderLocation (NULL, |
124 | issystem ? CSIDL_COMMON_PROGRAMS : | |
125 | CSIDL_PROGRAMS, &id); | |
3c054baf RC |
126 | char _path[_MAX_PATH]; |
127 | SHGetPathFromIDList (id, _path); | |
128 | String path(_path); | |
129 | // Win95 does not use common programs unless multiple users for Win95 is enabled | |
130 | msg ("Program directory for program link: %s", path.cstr_oneuse()); | |
131 | if (path.size() == 0) | |
b24c88b3 RC |
132 | { |
133 | SHGetSpecialFolderLocation (NULL, CSIDL_PROGRAMS, &id); | |
3c054baf RC |
134 | SHGetPathFromIDList (id, _path); |
135 | path = String(_path); | |
1ac649ed RC |
136 | msg ("Program directory for program link changed to: %s", |
137 | path.cstr_oneuse()); | |
b24c88b3 | 138 | } |
50225eae | 139 | // end of Win95 addition |
3c054baf | 140 | path += "/Cygwin"; |
904d24fe DD |
141 | make_link (path, title, target); |
142 | } | |
143 | ||
144 | static void | |
3c054baf | 145 | desktop_icon (String const &title, String const &target) |
904d24fe DD |
146 | { |
147 | char path[_MAX_PATH]; | |
148 | LPITEMIDLIST id; | |
24e259bb | 149 | int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0; |
50225eae | 150 | //SHGetSpecialFolderLocation (NULL, issystem ? CSIDL_DESKTOP : CSIDL_COMMON_DESKTOPDIRECTORY, &id); |
b24c88b3 RC |
151 | SHGetSpecialFolderLocation (NULL, |
152 | issystem ? CSIDL_COMMON_DESKTOPDIRECTORY : | |
153 | CSIDL_DESKTOPDIRECTORY, &id); | |
904d24fe | 154 | SHGetPathFromIDList (id, path); |
50225eae DD |
155 | // following lines added because it appears Win95 does not use common programs |
156 | // unless it comes into play when multiple users for Win95 is enabled | |
b24c88b3 RC |
157 | msg ("Desktop directory for desktop link: %s", path); |
158 | if (strlen (path) == 0) | |
159 | { | |
160 | SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOPDIRECTORY, &id); | |
161 | SHGetPathFromIDList (id, path); | |
162 | msg ("Desktop directory for deskop link changed to: %s", path); | |
163 | } | |
50225eae | 164 | // end of Win95 addition |
904d24fe DD |
165 | make_link (path, title, target); |
166 | } | |
167 | ||
168 | static void | |
169 | make_cygwin_bat () | |
170 | { | |
1ac649ed | 171 | batname = backslash (cygpath ("/cygwin.bat")); |
904d24fe DD |
172 | |
173 | /* if the batch file exists, don't overwrite it */ | |
3c054baf | 174 | if (_access (batname.cstr_oneuse(), 0) == 0) |
904d24fe DD |
175 | return; |
176 | ||
3c054baf | 177 | FILE *bat = fopen (batname.cstr_oneuse(), "wt"); |
904d24fe DD |
178 | if (!bat) |
179 | return; | |
180 | ||
181 | fprintf (bat, "@echo off\n\n"); | |
182 | ||
3c054baf | 183 | fprintf (bat, "%.2s\n", get_root_dir ().cstr_oneuse()); |
b24c88b3 | 184 | fprintf (bat, "chdir %s\n\n", |
3c054baf | 185 | backslash (get_root_dir () + "/bin").cstr_oneuse()); |
904d24fe DD |
186 | |
187 | fprintf (bat, "bash --login -i\n"); | |
188 | ||
189 | fclose (bat); | |
904d24fe DD |
190 | } |
191 | ||
192 | static void | |
193 | save_icon () | |
194 | { | |
1ac649ed | 195 | iconname = backslash (cygpath ("/cygwin.ico")); |
904d24fe DD |
196 | |
197 | HRSRC rsrc = FindResource (NULL, "CYGWIN.ICON", "FILE"); | |
198 | if (rsrc == NULL) | |
199 | { | |
200 | fatal ("FindResource failed"); | |
201 | } | |
202 | HGLOBAL res = LoadResource (NULL, rsrc); | |
203 | char *data = (char *) LockResource (res); | |
204 | int len = SizeofResource (NULL, rsrc); | |
205 | ||
3c054baf | 206 | FILE *f = fopen (iconname.cstr_oneuse(), "wb"); |
904d24fe DD |
207 | if (f) |
208 | { | |
209 | fwrite (data, 1, len, f); | |
210 | fclose (f); | |
211 | } | |
212 | } | |
213 | ||
50225eae | 214 | static void |
b24c88b3 | 215 | do_desktop_setup () |
50225eae DD |
216 | { |
217 | save_icon (); | |
218 | ||
219 | make_cygwin_bat (); | |
50225eae | 220 | |
b24c88b3 RC |
221 | if (root_menu) |
222 | { | |
223 | start_menu ("Cygwin Bash Shell", batname); | |
224 | } | |
50225eae | 225 | |
b24c88b3 RC |
226 | if (root_desktop) |
227 | { | |
228 | desktop_icon ("Cygwin", batname); | |
229 | } | |
50225eae DD |
230 | } |
231 | ||
232 | static int da[] = { IDC_ROOT_DESKTOP, 0 }; | |
233 | static int ma[] = { IDC_ROOT_MENU, 0 }; | |
234 | ||
235 | static void | |
236 | check_if_enable_next (HWND h) | |
237 | { | |
238 | EnableWindow (GetDlgItem (h, IDOK), 1); | |
239 | } | |
240 | ||
241 | static void | |
242 | load_dialog (HWND h) | |
243 | { | |
244 | rbset (h, da, root_desktop); | |
245 | rbset (h, ma, root_menu); | |
246 | check_if_enable_next (h); | |
247 | } | |
248 | ||
b24c88b3 | 249 | static int |
3c054baf | 250 | check_desktop (String const title, String const target) |
50225eae DD |
251 | { |
252 | char path[_MAX_PATH]; | |
253 | LPITEMIDLIST id; | |
254 | int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0; | |
b24c88b3 RC |
255 | SHGetSpecialFolderLocation (NULL, |
256 | issystem ? CSIDL_COMMON_DESKTOPDIRECTORY : | |
257 | CSIDL_DESKTOPDIRECTORY, &id); | |
50225eae DD |
258 | SHGetPathFromIDList (id, path); |
259 | // following lines added because it appears Win95 does not use common programs | |
260 | // unless it comes into play when multiple users for Win95 is enabled | |
b24c88b3 RC |
261 | msg ("Desktop directory for desktop link: %s", path); |
262 | if (strlen (path) == 0) | |
263 | { | |
264 | SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOPDIRECTORY, &id); | |
265 | SHGetPathFromIDList (id, path); | |
266 | msg ("Desktop directory for deskop link changed to: %s", path); | |
267 | } | |
50225eae | 268 | // end of Win95 addition |
1ac649ed | 269 | String fname = String (path) + "/" + title + ".lnk"; |
50225eae | 270 | |
3c054baf | 271 | if (_access (fname.cstr_oneuse(), 0) == 0) |
b24c88b3 | 272 | return 0; /* already exists */ |
42bf5b92 | 273 | |
1ac649ed | 274 | fname = String (path) + "/" + title + ".pif"; /* check for a pif as well */ |
42bf5b92 | 275 | |
3c054baf | 276 | if (_access (fname.cstr_oneuse(), 0) == 0) |
b24c88b3 | 277 | return 0; /* already exists */ |
50225eae DD |
278 | |
279 | return IDC_ROOT_DESKTOP; | |
280 | } | |
281 | ||
b24c88b3 | 282 | static int |
3c054baf | 283 | check_startmenu (String const title, String const target) |
50225eae DD |
284 | { |
285 | char path[_MAX_PATH]; | |
286 | LPITEMIDLIST id; | |
287 | int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0; | |
b24c88b3 RC |
288 | SHGetSpecialFolderLocation (NULL, |
289 | issystem ? CSIDL_COMMON_PROGRAMS : | |
290 | CSIDL_PROGRAMS, &id); | |
50225eae DD |
291 | SHGetPathFromIDList (id, path); |
292 | // following lines added because it appears Win95 does not use common programs | |
293 | // unless it comes into play when multiple users for Win95 is enabled | |
b24c88b3 RC |
294 | msg ("Program directory for program link: %s", path); |
295 | if (strlen (path) == 0) | |
296 | { | |
297 | SHGetSpecialFolderLocation (NULL, CSIDL_PROGRAMS, &id); | |
298 | SHGetPathFromIDList (id, path); | |
299 | msg ("Program directory for program link changed to: %s", path); | |
300 | } | |
50225eae | 301 | // end of Win95 addition |
398dd7b2 | 302 | strcat (path, "/Cygwin"); |
1ac649ed | 303 | String fname = String (path) + "/" + title + ".lnk"; |
50225eae | 304 | |
3c054baf | 305 | if (_access (fname.cstr_oneuse(), 0) == 0) |
b24c88b3 | 306 | return 0; /* already exists */ |
42bf5b92 | 307 | |
1ac649ed | 308 | fname = String (path) + "/" + title + ".pif"; /* check for a pif as well */ |
42bf5b92 | 309 | |
3c054baf | 310 | if (_access (fname.cstr_oneuse(), 0) == 0) |
b24c88b3 | 311 | return 0; /* already exists */ |
42bf5b92 | 312 | |
50225eae DD |
313 | return IDC_ROOT_MENU; |
314 | } | |
315 | ||
316 | static void | |
317 | save_dialog (HWND h) | |
318 | { | |
b24c88b3 | 319 | root_desktop = rbget (h, da); |
50225eae DD |
320 | root_menu = rbget (h, ma); |
321 | } | |
322 | ||
323 | static BOOL | |
324 | dialog_cmd (HWND h, int id, HWND hwndctl, UINT code) | |
325 | { | |
326 | switch (id) | |
327 | { | |
328 | ||
329 | case IDC_ROOT_DESKTOP: | |
330 | case IDC_ROOT_MENU: | |
331 | save_dialog (h); | |
332 | check_if_enable_next (h); | |
333 | break; | |
50225eae | 334 | } |
b24c88b3 | 335 | return 0; |
50225eae DD |
336 | } |
337 | ||
ab57ceaa RC |
338 | bool |
339 | DesktopSetupPage::Create () | |
50225eae | 340 | { |
ab57ceaa | 341 | return PropertyPage::Create (NULL, dialog_cmd, IDD_DESKTOP); |
50225eae DD |
342 | } |
343 | ||
904d24fe | 344 | void |
ab57ceaa | 345 | DesktopSetupPage::OnInit () |
904d24fe | 346 | { |
ab57ceaa | 347 | // FIXME: This CoInitialize() feels like it could be moved to startup in main.cc. |
904d24fe | 348 | CoInitialize (NULL); |
3a8e3956 DD |
349 | verinfo.dwOSVersionInfoSize = sizeof (verinfo); |
350 | GetVersionEx (&verinfo); | |
f2ff9838 RC |
351 | |
352 | if (NoShortcutsOption) | |
1be8f8fd | 353 | { |
f2ff9838 | 354 | root_desktop = root_menu = 0; |
1be8f8fd RC |
355 | } |
356 | else | |
f2ff9838 RC |
357 | { |
358 | if (NoStartMenuOption) | |
359 | { | |
360 | root_menu = 0; | |
361 | MessageBox(NULL, "NoStartMenuOption", "NoStartMenuOption", MB_OK); | |
362 | } | |
363 | else | |
364 | { | |
365 | root_menu = | |
366 | check_startmenu ("Cygwin Bash Shell", | |
367 | backslash (cygpath ("/cygwin.bat"))); | |
368 | } | |
369 | ||
370 | if (NoDesktopOption) | |
371 | { | |
372 | root_desktop = 0; | |
373 | } | |
374 | else | |
375 | { | |
376 | root_desktop = | |
377 | check_desktop ("Cygwin", backslash (cygpath ("/cygwin.bat"))); | |
378 | } | |
379 | } | |
380 | ||
381 | load_dialog (GetHWND ()); | |
382 | ||
ab57ceaa | 383 | } |
42bf5b92 | 384 | |
ab57ceaa RC |
385 | long |
386 | DesktopSetupPage::OnBack () | |
387 | { | |
388 | HWND h = GetHWND (); | |
389 | save_dialog (h); | |
390 | NEXT (IDD_CHOOSE); | |
f6a81f69 | 391 | return IDD_CHOOSE; |
ab57ceaa RC |
392 | } |
393 | ||
394 | bool | |
395 | DesktopSetupPage::OnFinish () | |
396 | { | |
397 | HWND h = GetHWND (); | |
398 | save_dialog (h); | |
399 | do_desktop_setup (); | |
904d24fe | 400 | |
ab57ceaa | 401 | return true; |
904d24fe | 402 | } |
f2ff9838 RC |
403 | |
404 | long | |
405 | DesktopSetupPage::OnUnattended () | |
406 | { | |
407 | Window::PostMessage (WM_APP_UNATTENDED_FINISH); | |
408 | // GetOwner ()->PressButton(PSBTN_FINISH); | |
409 | return -1; | |
410 | } | |
411 | ||
412 | bool | |
413 | DesktopSetupPage::OnMessageApp (UINT uMsg, WPARAM wParam, LPARAM lParam) | |
414 | { | |
415 | switch (uMsg) | |
416 | { | |
417 | case WM_APP_UNATTENDED_FINISH: | |
418 | { | |
419 | GetOwner ()->PressButton(PSBTN_FINISH); | |
420 | break; | |
421 | } | |
422 | default: | |
423 | { | |
424 | // Not handled | |
425 | return false; | |
426 | } | |
427 | } | |
428 | ||
429 | return true; | |
430 | } |