]> cygwin.com Git - cygwin-apps/setup.git/blame - desktop.cc
2002-04-29 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / desktop.cc
CommitLineData
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
22static const char *cvsid =
23 "\n%%% $Id$\n";
24#endif
8507f105 25
904d24fe 26#include "win32.h"
ad09bcd9 27#include <shlobj.h>
904d24fe
DD
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <unistd.h>
32
33#include "resource.h"
ef2007fd 34#include "ini.h"
904d24fe
DD
35#include "msg.h"
36#include "state.h"
904d24fe 37#include "dialog.h"
ef2007fd 38#include "version.h"
a351e48c 39#include "mount.h"
904d24fe
DD
40
41#include "port.h"
42
b24c88b3 43#include "mklink2.h"
904d24fe 44
bb849dbd
RC
45#include "package_db.h"
46#include "package_meta.h"
47#include "package_version.h"
48
3c054baf
RC
49#include "filemanip.h"
50#include "String++.h"
51#include "io_stream.h"
52
ab57ceaa 53#include "desktop.h"
6908b7d7 54#include "getopt++/BoolOption.h"
ab57ceaa 55
6908b7d7 56static BoolOption NoShortcutsOption (false, 'n', "no-shortcuts", "Disable creation of desktop and start menu shortcuts");
3c054baf 57
3a8e3956
DD
58static OSVERSIONINFO verinfo;
59
60/* Lines starting with '@' are conditionals - include 'N' for NT,
61 '5' for Win95, '8' for Win98, '*' for all, like this:
62 echo foo
63 @N8
64 echo NT or 98
65 @*
66 */
67
b24c88b3 68static const char *etc_profile[] = {
a6100861 69 "PATH=\"/usr/local/bin:/usr/bin:/bin:$PATH\"",
e0c3d906 70 "",
40aef45e 71 "USER=\"`id -un`\"",
e0c3d906
DD
72 "",
73 "# Set up USER's home directory",
74 "if [ -z \"$HOME\" ]; then",
40aef45e 75 " HOME=\"/home/$USER\"",
e0c3d906
DD
76 "fi",
77 "",
40aef45e
DD
78 "if [ ! -d \"$HOME\" ]; then",
79 " mkdir -p \"$HOME\"",
e0c3d906
DD
80 "fi",
81 "",
82 "export HOME USER",
83 "",
84 "for i in /etc/profile.d/*.sh ; do",
85 " if [ -f $i ]; then",
86 " . $i",
87 " fi",
88 "done",
89 "",
bf1d5889 90 "export MAKE_MODE=unix",
dd3f7f9b
DD
91 "export PS1='\\[\\033]0;\\w\\007",
92 "\\033[32m\\]\\u@\\h \\[\\033[33m\\w\\033[0m\\]",
e0c3d906
DD
93 "$ '",
94 "",
40aef45e 95 "cd \"$HOME\"",
e0c3d906
DD
96 0
97};
98
3c054baf
RC
99#define COMMAND9XARGS String("/E:4096 /c")
100#define COMMAND9XEXE String("\\command.com")
904d24fe 101
3c054baf
RC
102static String batname;
103static String iconname;
904d24fe 104
904d24fe 105static void
3c054baf 106make_link (String const &linkpath, String const &title, String const &target)
904d24fe 107{
3c054baf 108 String fname = linkpath + "/" + title + ".lnk";
904d24fe 109
3c054baf 110 if (_access (fname.cstr_oneuse(), 0) == 0)
b24c88b3 111 return; /* already exists */
904d24fe 112
1ac649ed
RC
113 msg ("make_link %s, %s, %s\n",
114 fname.cstr_oneuse(), title.cstr_oneuse(), target.cstr_oneuse());
904d24fe 115
2fa7c5a4 116 io_stream::mkpath_p (PATH_TO_FILE, String ("file://") + fname);
904d24fe 117
3c054baf 118 String exepath;
904d24fe 119
3c054baf 120 String argbuf;
904d24fe 121 /* If we are running Win9x, build a command line. */
904d24fe
DD
122 if (verinfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
123 {
3c054baf
RC
124 exepath = target;
125 argbuf = " ";
126// sprintf (argbuf, " ");
904d24fe
DD
127 }
128 else
129 {
904d24fe
DD
130 char windir[MAX_PATH];
131
132 GetWindowsDirectory (windir, sizeof (windir));
3c054baf
RC
133 exepath = String(windir) + COMMAND9XEXE;
134 argbuf = COMMAND9XARGS + " " + target;
135// sprintf (argbuf, "%s %s", COMMAND9XARGS, target.cstr_oneuse());
904d24fe
DD
136 }
137
1ac649ed
RC
138 msg ("make_link_2 (%s, %s, %s, %s)",
139 exepath.cstr_oneuse(), argbuf.cstr_oneuse(),
140 iconname.cstr_oneuse(), fname.cstr_oneuse());
141 make_link_2 (exepath.cstr_oneuse(), argbuf.cstr_oneuse(),
142 iconname.cstr_oneuse(), fname.cstr_oneuse());
904d24fe
DD
143}
144
145static void
3c054baf 146start_menu (String const &title, String const &target)
904d24fe 147{
904d24fe 148 LPITEMIDLIST id;
24e259bb 149 int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
b24c88b3
RC
150 SHGetSpecialFolderLocation (NULL,
151 issystem ? CSIDL_COMMON_PROGRAMS :
152 CSIDL_PROGRAMS, &id);
3c054baf
RC
153 char _path[_MAX_PATH];
154 SHGetPathFromIDList (id, _path);
155 String path(_path);
156 // Win95 does not use common programs unless multiple users for Win95 is enabled
157 msg ("Program directory for program link: %s", path.cstr_oneuse());
158 if (path.size() == 0)
b24c88b3
RC
159 {
160 SHGetSpecialFolderLocation (NULL, CSIDL_PROGRAMS, &id);
3c054baf
RC
161 SHGetPathFromIDList (id, _path);
162 path = String(_path);
1ac649ed
RC
163 msg ("Program directory for program link changed to: %s",
164 path.cstr_oneuse());
b24c88b3 165 }
50225eae 166// end of Win95 addition
3c054baf 167 path += "/Cygwin";
904d24fe
DD
168 make_link (path, title, target);
169}
170
171static void
3c054baf 172desktop_icon (String const &title, String const &target)
904d24fe
DD
173{
174 char path[_MAX_PATH];
175 LPITEMIDLIST id;
24e259bb 176 int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
50225eae 177 //SHGetSpecialFolderLocation (NULL, issystem ? CSIDL_DESKTOP : CSIDL_COMMON_DESKTOPDIRECTORY, &id);
b24c88b3
RC
178 SHGetSpecialFolderLocation (NULL,
179 issystem ? CSIDL_COMMON_DESKTOPDIRECTORY :
180 CSIDL_DESKTOPDIRECTORY, &id);
904d24fe 181 SHGetPathFromIDList (id, path);
50225eae
DD
182// following lines added because it appears Win95 does not use common programs
183// unless it comes into play when multiple users for Win95 is enabled
b24c88b3
RC
184 msg ("Desktop directory for desktop link: %s", path);
185 if (strlen (path) == 0)
186 {
187 SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOPDIRECTORY, &id);
188 SHGetPathFromIDList (id, path);
189 msg ("Desktop directory for deskop link changed to: %s", path);
190 }
50225eae 191// end of Win95 addition
904d24fe
DD
192 make_link (path, title, target);
193}
194
195static void
196make_cygwin_bat ()
197{
1ac649ed 198 batname = backslash (cygpath ("/cygwin.bat"));
904d24fe
DD
199
200 /* if the batch file exists, don't overwrite it */
3c054baf 201 if (_access (batname.cstr_oneuse(), 0) == 0)
904d24fe
DD
202 return;
203
3c054baf 204 FILE *bat = fopen (batname.cstr_oneuse(), "wt");
904d24fe
DD
205 if (!bat)
206 return;
207
208 fprintf (bat, "@echo off\n\n");
209
3c054baf 210 fprintf (bat, "%.2s\n", get_root_dir ().cstr_oneuse());
b24c88b3 211 fprintf (bat, "chdir %s\n\n",
3c054baf 212 backslash (get_root_dir () + "/bin").cstr_oneuse());
904d24fe
DD
213
214 fprintf (bat, "bash --login -i\n");
215
216 fclose (bat);
904d24fe
DD
217}
218
e0c3d906
DD
219static void
220make_etc_profile ()
221{
1ac649ed 222 String fname = cygpath ("/etc/profile");
e0c3d906
DD
223
224 /* if the file exists, don't overwrite it */
3c054baf 225 if (_access (fname.cstr_oneuse(), 0) == 0)
e0c3d906
DD
226 return;
227
3a8e3956
DD
228 char os;
229 switch (verinfo.dwPlatformId)
230 {
b24c88b3
RC
231 case VER_PLATFORM_WIN32_NT:
232 os = 'N';
233 break;
234 case VER_PLATFORM_WIN32_WINDOWS:
235 if (verinfo.dwMinorVersion == 0)
236 os = '5';
237 else
238 os = '8';
239 break;
240 default:
241 os = '?';
242 break;
3a8e3956
DD
243 }
244 msg ("os is %c", os);
245
3c054baf 246 FILE *p = fopen (fname.cstr_oneuse(), "wb");
e0c3d906
DD
247 if (!p)
248 return;
249
b24c88b3
RC
250 int i, allow = 1;
251 for (i = 0; etc_profile[i]; i++)
3a8e3956
DD
252 {
253 if (etc_profile[i][0] == '@')
254 {
255 allow = 0;
256 msg ("profile: %s", etc_profile[i]);
b24c88b3 257 for (const char *cp = etc_profile[i] + 1; *cp; cp++)
3a8e3956
DD
258 if (*cp == os || *cp == '*')
259 allow = 1;
260 msg ("allow is %d\n", allow);
261 }
262 else if (allow)
263 fprintf (p, "%s\n", etc_profile[i]);
264 }
265
266 fclose (p);
267}
268
f57c332f 269static int
b24c88b3 270uexists (const char *path)
f57c332f 271{
1ac649ed 272 String f = cygpath (path);
3c054baf 273 int a = _access (f.cstr_oneuse(), 0);
f57c332f
DD
274 if (a == 0)
275 return 1;
276 return 0;
277}
278
3a8e3956 279static void
f57c332f 280make_passwd_group ()
3a8e3956 281{
1ac649ed 282 String fname = cygpath ("/etc/postinstall/passwd-grp.bat");
2fa7c5a4 283 io_stream::mkpath_p (PATH_TO_FILE, String("file://") + fname);
31324d15 284
2fa7c5a4
RC
285 if ((uexists ("/etc/passwd") || uexists ("/etc/passwd.lnk"))
286 && (uexists ("/etc/group") || uexists ("/etc/group.lnk")))
31324d15 287 return;
bb087dce 288
3a8e3956 289 if (verinfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
ef2007fd 290 {
bb849dbd 291 packagedb db;
cbfc4215 292 packagemeta *pkg = db.packages.getbykey ("cygwin");
bb849dbd 293 if (pkg && pkg->installed)
ef2007fd 294 {
c46a33a9 295 /* mkpasswd and mkgroup are not working on 9x/ME up to 1.1.5-4 */
3c054baf
RC
296 String border_version = canonicalize_version ("1.1.5-4");
297 String inst_version =
bb849dbd 298 canonicalize_version (pkg->installed->Canonical_version ());
3c054baf 299 if (inst_version.compare(border_version) <= 0)
bb087dce 300 return;
ef2007fd
CV
301 }
302 }
3a8e3956 303
bb087dce
RC
304 FILE *p = fopen (fname.cstr_oneuse(), "wt");
305 if (!p)
306 return;
2fa7c5a4 307 if (!(uexists ("/etc/passwd") || uexists ("/etc/passwd.lnk")))
f57c332f 308 fprintf (p, "bin\\mkpasswd -l > etc\\passwd\n");
2fa7c5a4 309 if (!(uexists ("/etc/group") || uexists ("/etc/group.lnk")))
f57c332f 310 fprintf (p, "bin\\mkgroup -l > etc\\group\n");
e0c3d906
DD
311 fclose (p);
312}
313
904d24fe
DD
314static void
315save_icon ()
316{
1ac649ed 317 iconname = backslash (cygpath ("/cygwin.ico"));
904d24fe
DD
318
319 HRSRC rsrc = FindResource (NULL, "CYGWIN.ICON", "FILE");
320 if (rsrc == NULL)
321 {
322 fatal ("FindResource failed");
323 }
324 HGLOBAL res = LoadResource (NULL, rsrc);
325 char *data = (char *) LockResource (res);
326 int len = SizeofResource (NULL, rsrc);
327
3c054baf 328 FILE *f = fopen (iconname.cstr_oneuse(), "wb");
904d24fe
DD
329 if (f)
330 {
331 fwrite (data, 1, len, f);
332 fclose (f);
333 }
334}
335
50225eae 336static void
b24c88b3 337do_desktop_setup ()
50225eae
DD
338{
339 save_icon ();
340
341 make_cygwin_bat ();
342 make_etc_profile ();
343 make_passwd_group ();
344
b24c88b3
RC
345 if (root_menu)
346 {
347 start_menu ("Cygwin Bash Shell", batname);
348 }
50225eae 349
b24c88b3
RC
350 if (root_desktop)
351 {
352 desktop_icon ("Cygwin", batname);
353 }
50225eae
DD
354}
355
356static int da[] = { IDC_ROOT_DESKTOP, 0 };
357static int ma[] = { IDC_ROOT_MENU, 0 };
358
359static void
360check_if_enable_next (HWND h)
361{
362 EnableWindow (GetDlgItem (h, IDOK), 1);
363}
364
365static void
366load_dialog (HWND h)
367{
368 rbset (h, da, root_desktop);
369 rbset (h, ma, root_menu);
370 check_if_enable_next (h);
371}
372
b24c88b3 373static int
3c054baf 374check_desktop (String const title, String const target)
50225eae
DD
375{
376 char path[_MAX_PATH];
377 LPITEMIDLIST id;
378 int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
b24c88b3
RC
379 SHGetSpecialFolderLocation (NULL,
380 issystem ? CSIDL_COMMON_DESKTOPDIRECTORY :
381 CSIDL_DESKTOPDIRECTORY, &id);
50225eae
DD
382 SHGetPathFromIDList (id, path);
383 // following lines added because it appears Win95 does not use common programs
384 // unless it comes into play when multiple users for Win95 is enabled
b24c88b3
RC
385 msg ("Desktop directory for desktop link: %s", path);
386 if (strlen (path) == 0)
387 {
388 SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOPDIRECTORY, &id);
389 SHGetPathFromIDList (id, path);
390 msg ("Desktop directory for deskop link changed to: %s", path);
391 }
50225eae 392 // end of Win95 addition
1ac649ed 393 String fname = String (path) + "/" + title + ".lnk";
50225eae 394
3c054baf 395 if (_access (fname.cstr_oneuse(), 0) == 0)
b24c88b3 396 return 0; /* already exists */
42bf5b92 397
1ac649ed 398 fname = String (path) + "/" + title + ".pif"; /* check for a pif as well */
42bf5b92 399
3c054baf 400 if (_access (fname.cstr_oneuse(), 0) == 0)
b24c88b3 401 return 0; /* already exists */
50225eae
DD
402
403 return IDC_ROOT_DESKTOP;
404}
405
b24c88b3 406static int
3c054baf 407check_startmenu (String const title, String const target)
50225eae
DD
408{
409 char path[_MAX_PATH];
410 LPITEMIDLIST id;
411 int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
b24c88b3
RC
412 SHGetSpecialFolderLocation (NULL,
413 issystem ? CSIDL_COMMON_PROGRAMS :
414 CSIDL_PROGRAMS, &id);
50225eae
DD
415 SHGetPathFromIDList (id, path);
416 // following lines added because it appears Win95 does not use common programs
417 // unless it comes into play when multiple users for Win95 is enabled
b24c88b3
RC
418 msg ("Program directory for program link: %s", path);
419 if (strlen (path) == 0)
420 {
421 SHGetSpecialFolderLocation (NULL, CSIDL_PROGRAMS, &id);
422 SHGetPathFromIDList (id, path);
423 msg ("Program directory for program link changed to: %s", path);
424 }
50225eae 425 // end of Win95 addition
398dd7b2 426 strcat (path, "/Cygwin");
1ac649ed 427 String fname = String (path) + "/" + title + ".lnk";
50225eae 428
3c054baf 429 if (_access (fname.cstr_oneuse(), 0) == 0)
b24c88b3 430 return 0; /* already exists */
42bf5b92 431
1ac649ed 432 fname = String (path) + "/" + title + ".pif"; /* check for a pif as well */
42bf5b92 433
3c054baf 434 if (_access (fname.cstr_oneuse(), 0) == 0)
b24c88b3 435 return 0; /* already exists */
42bf5b92 436
50225eae
DD
437 return IDC_ROOT_MENU;
438}
439
440static void
441save_dialog (HWND h)
442{
b24c88b3 443 root_desktop = rbget (h, da);
50225eae
DD
444 root_menu = rbget (h, ma);
445}
446
447static BOOL
448dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
449{
450 switch (id)
451 {
452
453 case IDC_ROOT_DESKTOP:
454 case IDC_ROOT_MENU:
455 save_dialog (h);
456 check_if_enable_next (h);
457 break;
50225eae 458 }
b24c88b3 459 return 0;
50225eae
DD
460}
461
ab57ceaa
RC
462bool
463DesktopSetupPage::Create ()
50225eae 464{
ab57ceaa 465 return PropertyPage::Create (NULL, dialog_cmd, IDD_DESKTOP);
50225eae
DD
466}
467
904d24fe 468void
ab57ceaa 469DesktopSetupPage::OnInit ()
904d24fe 470{
ab57ceaa 471 // FIXME: This CoInitialize() feels like it could be moved to startup in main.cc.
904d24fe 472 CoInitialize (NULL);
3a8e3956
DD
473 verinfo.dwOSVersionInfoSize = sizeof (verinfo);
474 GetVersionEx (&verinfo);
b24c88b3 475 root_desktop =
1ac649ed 476 check_desktop ("Cygwin", backslash (cygpath ("/cygwin.bat")));
b24c88b3
RC
477 root_menu =
478 check_startmenu ("Cygwin Bash Shell",
1ac649ed 479 backslash (cygpath ("/cygwin.bat")));
6908b7d7 480 if (NoShortcutsOption)
1be8f8fd
RC
481 {
482 root_desktop=false;
483 root_menu=false;
484 OnFinish();
485 }
486 else
487 load_dialog (GetHWND ());
ab57ceaa 488}
42bf5b92 489
ab57ceaa
RC
490long
491DesktopSetupPage::OnBack ()
492{
493 HWND h = GetHWND ();
494 save_dialog (h);
495 NEXT (IDD_CHOOSE);
496 return IDD_CHOOSER;
497}
498
499bool
500DesktopSetupPage::OnFinish ()
501{
502 HWND h = GetHWND ();
503 save_dialog (h);
504 do_desktop_setup ();
505 NEXT (IDD_S_POSTINSTALL);
506 do_postinstall (GetInstance (), h);
904d24fe 507
ab57ceaa 508 return true;
904d24fe 509}
This page took 0.089572 seconds and 5 git commands to generate.