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