root/branches/3.00/src/desktop.cc

Revision 842, 10.8 kB (checked in by fujii, 2 years ago)

Add start menu when install.exe is invoked.

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