Fix MD5sum.str () formatting bug
[cygwin-setup.git] / desktop.cc
blob1add57a7de31527b82102da12ef5be9ec9331ee5
1 /*
2 * Copyright (c) 2000, 2001 Red Hat, Inc.
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.
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
12 * Written by DJ Delorie <dj@cygnus.com>
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 */
21 #if 0
22 static const char *cvsid =
23 "\n%%% $Id$\n";
24 #endif
26 #include "win32.h"
27 #include <shlobj.h>
28 #include "desktop.h"
29 #include "propsheet.h"
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <unistd.h>
35 #include "ini.h"
36 #include "resource.h"
37 #include "state.h"
38 #include "dialog.h"
39 #include "mount.h"
40 #include "mklink2.h"
41 #include "package_db.h"
42 #include "package_meta.h"
43 #include "package_version.h"
44 #include "filemanip.h"
45 #include "io_stream.h"
46 #include "getopt++/BoolOption.h"
47 #include "PackageSpecification.h"
48 #include "LogFile.h"
50 static BoolOption NoShortcutsOption (false, 'n', "no-shortcuts", "Disable creation of desktop and start menu shortcuts");
51 static BoolOption NoStartMenuOption (false, 'N', "no-startmenu", "Disable creation of start menu shortcut");
52 static BoolOption NoDesktopOption (false, 'd', "no-desktop", "Disable creation of desktop shortcut");
54 /* Lines starting with '@' are conditionals - include 'N' for NT,
55 '5' for Win95, '8' for Win98, '*' for all, like this:
56 echo foo
57 @N8
58 echo NT or 98
62 static std::string batname;
63 static ControlAdjuster::ControlInfo DesktopControlsInfo[] = {
64 {IDC_DESKTOP_SEPARATOR, CP_STRETCH, CP_BOTTOM},
65 {IDC_STATUS, CP_LEFT, CP_BOTTOM},
66 {IDC_STATUS_HEADER, CP_LEFT, CP_BOTTOM},
67 {0, CP_LEFT, CP_TOP}
70 DesktopSetupPage::DesktopSetupPage ()
72 sizeProcessor.AddControlInfo (DesktopControlsInfo);
75 static void
76 make_link (const std::string& linkpath,
77 const std::string& title,
78 const std::string& target,
79 const std::string& arg,
80 const std::string& icon)
82 std::string fname = linkpath + "/" + title + ".lnk";
84 if (_access (fname.c_str(), 0) == 0)
85 return; /* already exists */
87 LogBabblePrintf ("make_link %s, %s, %s\n",
88 fname.c_str(), title.c_str(), target.c_str());
90 io_stream::mkpath_p (PATH_TO_FILE, std::string ("file://") + fname, 0);
92 std::string exepath;
93 std::string argbuf;
95 exepath = target;
96 argbuf = arg;
98 LogBabblePrintf ("make_link_2 (%s, %s, %s, %s)",
99 exepath.c_str(), argbuf.c_str(),
100 icon.c_str(), fname.c_str());
101 make_link_2 (exepath.c_str(), argbuf.c_str(),
102 icon.c_str(), fname.c_str());
105 static void
106 start_menu (const std::string& title, const std::string& target,
107 const std::string& arg, const std::string& iconpath)
109 /* Special folders always < MAX_PATH. */
110 char path[MAX_PATH];
111 LPITEMIDLIST id;
112 int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
113 SHGetSpecialFolderLocation (NULL,
114 issystem ? CSIDL_COMMON_PROGRAMS :
115 CSIDL_PROGRAMS, &id);
116 SHGetPathFromIDList (id, path);
117 strncat (path, "/Cygwin", MAX_PATH);
118 LogBabblePrintf ("Program directory for program link: %s", path);
119 make_link (path, title, target, arg, iconpath);
122 static void
123 desktop_icon (const std::string& title, const std::string& target,
124 const std::string& arg, const std::string& iconpath)
126 /* Special folders always < MAX_PATH. */
127 char path[MAX_PATH];
128 LPITEMIDLIST id;
129 int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
130 SHGetSpecialFolderLocation (NULL,
131 issystem ? CSIDL_COMMON_DESKTOPDIRECTORY :
132 CSIDL_DESKTOPDIRECTORY, &id);
133 SHGetPathFromIDList (id, path);
134 LogBabblePrintf ("Desktop directory for desktop link: %s", path);
135 make_link (path, title, target, arg, iconpath);
138 static void
139 make_cygwin_bat ()
141 batname = backslash (cygpath ("/Cygwin.bat"));
142 FILE *bat;
144 size_t len = batname.size () + 7;
145 WCHAR wname[len];
146 mklongpath (wname, batname.c_str (), len);
148 /* if the batch file exists, don't overwrite it */
149 if (GetFileAttributesW (wname) != INVALID_FILE_ATTRIBUTES)
150 return;
152 bat = nt_wfopen (wname, "wt", 0755);
154 if (!bat)
155 return;
157 fprintf (bat, "@echo off\n\n");
159 fprintf (bat, "%.2s\n", get_root_dir ().c_str());
160 fprintf (bat, "chdir %s\n\n",
161 replace(backslash(get_root_dir() + "/bin"), "%", "%%").c_str());
163 fprintf (bat, "bash --login -i\n");
165 fclose (bat);
168 static void
169 save_icon (std::string &iconpath, const char *resource_name)
171 HRSRC rsrc = FindResource (NULL, resource_name, "FILE");
172 if (rsrc == NULL)
174 fatal ("FindResource failed");
176 HGLOBAL res = LoadResource (NULL, rsrc);
177 char *data = (char *) LockResource (res);
178 int len = SizeofResource (NULL, rsrc);
180 FILE *f;
181 WIN32_FILE_ATTRIBUTE_DATA attr;
183 size_t ilen = iconpath.size () + 7;
184 WCHAR wname[ilen];
185 mklongpath (wname, iconpath.c_str (), ilen);
186 if (GetFileAttributesExW (wname, GetFileExInfoStandard, &attr)
187 && attr.dwFileAttributes != INVALID_FILE_ATTRIBUTES
188 && attr.nFileSizeLow > 7022) /* Size of old icon */
189 return;
191 f = nt_wfopen (wname, "wb", 0644);
192 if (f)
194 fwrite (data, 1, len, f);
195 fclose (f);
199 #define TARGET "/bin/mintty"
200 #define DEFAULTICON "/Cygwin.ico"
201 #define TERMINALICON "/Cygwin-Terminal.ico"
202 #define TERMINALTITLE (is_64bit ? "Cygwin64 Terminal" \
203 : "Cygwin Terminal")
204 #define STARTMENUDIR "/Cygwin"
206 static void
207 do_desktop_setup ()
209 std::string target = backslash (cygpath (TARGET));
210 std::string defaulticon = backslash (cygpath (DEFAULTICON));
211 std::string terminalicon = backslash (cygpath (TERMINALICON));
213 save_icon (defaulticon, "CYGWIN.ICON");
214 save_icon (terminalicon, "CYGWIN-TERMINAL.ICON");
216 make_cygwin_bat ();
218 if (root_menu)
219 start_menu (TERMINALTITLE, target, "-i " TERMINALICON " -", terminalicon);
221 if (root_desktop)
222 desktop_icon (TERMINALTITLE, target, "-i " TERMINALICON " -", terminalicon);
225 static int da[] = { IDC_ROOT_DESKTOP, 0 };
226 static int ma[] = { IDC_ROOT_MENU, 0 };
228 static void
229 check_if_enable_next (HWND h)
231 EnableWindow (GetDlgItem (h, IDOK), 1);
234 static void
235 set_status (HWND h)
237 char buf[1000], fmt[1000];
238 if (LoadString (hinstance, Logger ().getExitMsg (), fmt, sizeof (fmt)) > 0)
240 snprintf (buf, 1000, fmt,
241 backslash (Logger ().getFileName (LOG_BABBLE)).c_str ());
242 eset (h, IDC_STATUS, buf);
246 static char *header_string = NULL;
247 static char *message_string = NULL;
248 static void
249 load_dialog (HWND h)
251 if (source == IDC_SOURCE_DOWNLOAD)
253 // Don't need the checkboxes
254 EnableWindow (GetDlgItem (h, IDC_ROOT_DESKTOP), FALSE);
255 EnableWindow (GetDlgItem (h, IDC_ROOT_MENU), FALSE);
256 if (header_string == NULL)
257 header_string = eget (h, IDC_STATIC_HEADER_TITLE, header_string);
258 if (message_string == NULL)
259 message_string = eget (h, IDC_STATIC_HEADER, message_string);
260 eset (h, IDC_STATIC_HEADER_TITLE, "Installation complete");
261 eset (h, IDC_STATIC_HEADER, "Shows installation status in download-only mode.");
263 else
265 EnableWindow (GetDlgItem (h, IDC_ROOT_DESKTOP), TRUE);
266 EnableWindow (GetDlgItem (h, IDC_ROOT_MENU), TRUE);
267 if (header_string != NULL)
268 eset (h, IDC_STATIC_HEADER_TITLE, header_string);
269 if (message_string != NULL)
270 eset (h, IDC_STATIC_HEADER, message_string);
271 rbset (h, da, root_desktop);
272 rbset (h, ma, root_menu);
274 check_if_enable_next (h);
275 set_status (h);
278 static int
279 check_desktop (const std::string title, const std::string target)
281 /* Special folders always < MAX_PATH. */
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_DESKTOPDIRECTORY :
287 CSIDL_DESKTOPDIRECTORY, &id);
288 SHGetPathFromIDList (id, path);
289 LogBabblePrintf ("Desktop directory for desktop link: %s", path);
290 std::string fname = std::string(path) + "/" + title + ".lnk";
292 if (_access (fname.c_str(), 0) == 0)
293 return 0; /* already exists */
295 return IDC_ROOT_DESKTOP;
298 static int
299 check_startmenu (const std::string title, const std::string target)
301 /* Special folders always < MAX_PATH. */
302 char path[MAX_PATH];
303 LPITEMIDLIST id;
304 int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
305 SHGetSpecialFolderLocation (NULL,
306 issystem ? CSIDL_COMMON_PROGRAMS :
307 CSIDL_PROGRAMS, &id);
308 SHGetPathFromIDList (id, path);
309 LogBabblePrintf ("Program directory for program link: %s", path);
310 strcat (path, STARTMENUDIR);
311 std::string fname = std::string(path) + "/" + title + ".lnk";
313 if (_access (fname.c_str(), 0) == 0)
314 return 0; /* already exists */
316 return IDC_ROOT_MENU;
319 static void
320 save_dialog (HWND h)
322 root_desktop = rbget (h, da);
323 root_menu = rbget (h, ma);
326 static BOOL
327 dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
329 switch (id)
332 case IDC_ROOT_DESKTOP:
333 case IDC_ROOT_MENU:
334 save_dialog (h);
335 check_if_enable_next (h);
336 break;
338 return 0;
341 bool
342 DesktopSetupPage::Create ()
344 return PropertyPage::Create (NULL, dialog_cmd, IDD_DESKTOP);
347 void
348 DesktopSetupPage::OnInit ()
350 SetDlgItemFont(IDC_STATUS_HEADER, "MS Shell Dlg", 8, FW_BOLD);
353 void
354 DesktopSetupPage::OnActivate ()
356 if (NoShortcutsOption || source == IDC_SOURCE_DOWNLOAD)
358 root_desktop = root_menu = 0;
360 else
362 std::string target = backslash (cygpath (TARGET));
364 if (NoStartMenuOption)
366 root_menu = 0;
368 else
370 root_menu = check_startmenu (TERMINALTITLE, target);
373 if (NoDesktopOption)
375 root_desktop = 0;
377 else
379 root_desktop = check_desktop (TERMINALTITLE, target);
383 load_dialog (GetHWND ());
386 long
387 DesktopSetupPage::OnBack ()
389 HWND h = GetHWND ();
390 save_dialog (h);
391 return IDD_CHOOSE;
394 bool
395 DesktopSetupPage::OnFinish ()
397 HWND h = GetHWND ();
398 save_dialog (h);
399 if (source != IDC_SOURCE_DOWNLOAD)
400 do_desktop_setup ();
402 return true;
405 long
406 DesktopSetupPage::OnUnattended ()
408 Window::PostMessageNow (WM_APP_UNATTENDED_FINISH);
409 // GetOwner ()->PressButton(PSBTN_FINISH);
410 return -1;
413 bool
414 DesktopSetupPage::OnMessageApp (UINT uMsg, WPARAM wParam, LPARAM lParam)
416 switch (uMsg)
418 case WM_APP_UNATTENDED_FINISH:
420 GetOwner ()->PressButton(PSBTN_FINISH);
421 break;
423 default:
425 // Not handled
426 return false;
430 return true;