Added translation using Weblate (Japanese)
[cygwin-setup.git] / desktop.cc
blobbe7cc6ecae82ec08f37af4da8510ef3ab996d184
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 #include "win32.h"
22 #include <shlobj.h>
23 #include "desktop.h"
24 #include "propsheet.h"
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <unistd.h>
30 #include "ini.h"
31 #include "resource.h"
32 #include "state.h"
33 #include "dialog.h"
34 #include "mount.h"
35 #include "mklink2.h"
36 #include "package_db.h"
37 #include "package_meta.h"
38 #include "filemanip.h"
39 #include "io_stream.h"
40 #include "getopt++/BoolOption.h"
41 #include "LogFile.h"
43 BoolOption NoShortcutsOption (false, 'n', "no-shortcuts", IDS_HELPTEXT_NO_SHORTCUTS);
44 BoolOption NoStartMenuOption (false, 'N', "no-startmenu", IDS_HELPTEXT_NO_STARTMENU);
45 static BoolOption NoDesktopOption (false, 'd', "no-desktop", IDS_HELPTEXT_NO_DESKTOP);
47 /* Lines starting with '@' are conditionals - include 'N' for NT,
48 '5' for Win95, '8' for Win98, '*' for all, like this:
49 echo foo
50 @N8
51 echo NT or 98
55 static std::string batname;
56 static ControlAdjuster::ControlInfo DesktopControlsInfo[] = {
57 {IDC_DESKTOP_SEPARATOR, CP_STRETCH, CP_BOTTOM},
58 {IDC_STATUS, CP_LEFT, CP_BOTTOM},
59 {IDC_STATUS_HEADER, CP_LEFT, CP_BOTTOM},
60 {0, CP_LEFT, CP_TOP}
63 DesktopSetupPage::DesktopSetupPage ()
65 sizeProcessor.AddControlInfo (DesktopControlsInfo);
68 static void
69 make_link (const std::string& linkpath,
70 const std::string& title,
71 const std::string& target,
72 const std::string& arg,
73 const std::string& icon)
75 std::string fname = linkpath + "/" + title + ".lnk";
77 if (_access (fname.c_str(), 0) == 0)
78 return; /* already exists */
80 LogBabblePrintf ("make_link %s, %s, %s\n",
81 fname.c_str(), title.c_str(), target.c_str());
83 io_stream::mkpath_p (PATH_TO_FILE, std::string ("file://") + fname, 0);
85 std::string exepath;
86 std::string argbuf;
88 exepath = target;
89 argbuf = arg;
91 LogBabblePrintf ("make_link_2 (%s, %s, %s, %s)",
92 exepath.c_str(), argbuf.c_str(),
93 icon.c_str(), fname.c_str());
94 make_link_2 (exepath.c_str(), argbuf.c_str(),
95 icon.c_str(), fname.c_str());
98 const char *startmenusuffix()
100 if (!is_64bit && (WowNativeMachine() != IMAGE_FILE_MACHINE_I386))
101 return " (32-bit)";
102 #ifdef __x86_64__
103 if (WowNativeMachine() != IMAGE_FILE_MACHINE_AMD64)
104 return " (x86_64)";
105 #endif
106 else
107 return "";
110 static const char *startmenudir()
112 return "/Cygwin";
115 static void
116 start_menu (const std::string& title, const std::string& target,
117 const std::string& arg, const std::string& iconpath)
119 /* Special folders always < MAX_PATH. */
120 char path[MAX_PATH];
121 LPITEMIDLIST id;
122 int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
123 SHGetSpecialFolderLocation (NULL,
124 issystem ? CSIDL_COMMON_PROGRAMS :
125 CSIDL_PROGRAMS, &id);
126 SHGetPathFromIDList (id, path);
127 strncat (path, startmenudir(), MAX_PATH - strlen(path) - 1);
128 strncat (path, startmenusuffix(), MAX_PATH - strlen(path) - 1);
129 LogBabblePrintf ("Program directory for program link: %s", path);
130 make_link (path, title, target, arg, iconpath);
133 static void
134 desktop_icon (const std::string& title, const std::string& target,
135 const std::string& arg, const std::string& iconpath)
137 /* Special folders always < MAX_PATH. */
138 char path[MAX_PATH];
139 LPITEMIDLIST id;
140 int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
141 SHGetSpecialFolderLocation (NULL,
142 issystem ? CSIDL_COMMON_DESKTOPDIRECTORY :
143 CSIDL_DESKTOPDIRECTORY, &id);
144 SHGetPathFromIDList (id, path);
145 LogBabblePrintf ("Desktop directory for desktop link: %s", path);
146 make_link (path, title, target, arg, iconpath);
149 static void
150 make_cygwin_bat ()
152 batname = backslash (cygpath ("/Cygwin.bat"));
153 FILE *bat;
155 size_t len = batname.size () + 7;
156 WCHAR wname[len];
157 mklongpath (wname, batname.c_str (), len);
159 /* if the batch file exists, don't overwrite it */
160 if (GetFileAttributesW (wname) != INVALID_FILE_ATTRIBUTES)
161 return;
163 bat = nt_wfopen (wname, "wt", 0755);
165 if (!bat)
166 return;
168 fprintf (bat, "@echo off\n\n");
170 fprintf (bat, "%.2s\n", get_root_dir ().c_str());
171 fprintf (bat, "chdir %s\n\n",
172 replace(backslash(get_root_dir() + "/bin"), "%", "%%").c_str());
174 fprintf (bat, "bash --login -i\n");
176 fclose (bat);
179 static void
180 save_icon (std::string &iconpath, const char *resource_name)
182 HRSRC rsrc = FindResource (NULL, resource_name, "FILE");
183 if (rsrc == NULL)
185 Log (LOG_PLAIN) << "FindResource failed" << GetLastError() << endLog;
186 return;
189 HGLOBAL res = LoadResource (NULL, rsrc);
190 char *data = (char *) LockResource (res);
191 int len = SizeofResource (NULL, rsrc);
193 FILE *f;
194 WIN32_FILE_ATTRIBUTE_DATA attr;
196 size_t ilen = iconpath.size () + 7;
197 WCHAR wname[ilen];
198 mklongpath (wname, iconpath.c_str (), ilen);
199 if (GetFileAttributesExW (wname, GetFileExInfoStandard, &attr)
200 && attr.dwFileAttributes != INVALID_FILE_ATTRIBUTES
201 && attr.nFileSizeLow > 7022) /* Size of old icon */
202 return;
204 f = nt_wfopen (wname, "wb", 0644);
205 if (f)
207 fwrite (data, 1, len, f);
208 fclose (f);
212 #define TARGET "/bin/mintty"
213 #define DEFAULTICON "/Cygwin.ico"
214 #define TERMINALICON "/Cygwin-Terminal.ico"
215 #define TERMINALTITLE (is_64bit ? "Cygwin64 Terminal" \
216 : "Cygwin Terminal")
218 static void
219 do_desktop_setup ()
221 std::string target = backslash (cygpath (TARGET));
222 std::string defaulticon = backslash (cygpath (DEFAULTICON));
223 std::string terminalicon = backslash (cygpath (TERMINALICON));
225 save_icon (defaulticon, "CYGWIN.ICON");
226 save_icon (terminalicon, "CYGWIN-TERMINAL.ICON");
228 make_cygwin_bat ();
230 if (root_menu)
231 start_menu (TERMINALTITLE, target, "-i " TERMINALICON " -", terminalicon);
233 if (root_desktop)
234 desktop_icon (TERMINALTITLE, target, "-i " TERMINALICON " -", terminalicon);
237 static int da[] = { IDC_ROOT_DESKTOP, 0 };
238 static int ma[] = { IDC_ROOT_MENU, 0 };
240 static void
241 check_if_enable_next (HWND h)
243 EnableWindow (GetDlgItem (h, IDOK), 1);
246 static void
247 set_status (HWND h)
249 std::wstring fmt = LoadStringW(Logger ().getExitMsg ());
250 std::wstring buf = format(fmt, backslash (Logger ().getFileName (LOG_BABBLE)).c_str ());
251 eset (h, IDC_STATUS, buf);
254 static void
255 load_dialog (HWND h)
257 if (source == IDC_SOURCE_DOWNLOAD)
259 // Don't need the checkboxes
260 EnableWindow (GetDlgItem (h, IDC_ROOT_DESKTOP), FALSE);
261 EnableWindow (GetDlgItem (h, IDC_ROOT_MENU), FALSE);
262 ShowWindow (GetDlgItem(h, IDC_DESKTOP_HEADER_DOWNLOAD), SW_SHOW);
263 ShowWindow (GetDlgItem(h, IDC_DESKTOP_HEADER_TITLE_DOWNLOAD), SW_SHOW);
264 ShowWindow (GetDlgItem(h, IDC_DESKTOP_HEADER_INSTALL), SW_HIDE);
265 ShowWindow (GetDlgItem(h, IDC_DESKTOP_HEADER_TITLE_INSTALL), SW_HIDE);
267 else
269 EnableWindow (GetDlgItem (h, IDC_ROOT_DESKTOP), TRUE);
270 EnableWindow (GetDlgItem (h, IDC_ROOT_MENU), TRUE);
271 ShowWindow (GetDlgItem(h, IDC_DESKTOP_HEADER_DOWNLOAD), SW_HIDE);
272 ShowWindow (GetDlgItem(h, IDC_DESKTOP_HEADER_TITLE_DOWNLOAD), SW_HIDE);
273 ShowWindow (GetDlgItem(h, IDC_DESKTOP_HEADER_INSTALL), SW_SHOW);
274 ShowWindow (GetDlgItem(h, IDC_DESKTOP_HEADER_TITLE_INSTALL), SW_SHOW);
275 rbset (h, da, root_desktop);
276 rbset (h, ma, root_menu);
278 check_if_enable_next (h);
279 set_status (h);
282 static int
283 check_desktop (const std::string title, const std::string target)
285 /* Special folders always < MAX_PATH. */
286 char path[MAX_PATH];
287 LPITEMIDLIST id;
288 int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
289 SHGetSpecialFolderLocation (NULL,
290 issystem ? CSIDL_COMMON_DESKTOPDIRECTORY :
291 CSIDL_DESKTOPDIRECTORY, &id);
292 SHGetPathFromIDList (id, path);
293 LogBabblePrintf ("Desktop directory for desktop link: %s", path);
294 std::string fname = std::string(path) + "/" + title + ".lnk";
296 if (_access (fname.c_str(), 0) == 0)
297 return 0; /* already exists */
299 return IDC_ROOT_DESKTOP;
302 static int
303 check_startmenu (const std::string title, const std::string target)
305 /* Special folders always < MAX_PATH. */
306 char path[MAX_PATH];
307 LPITEMIDLIST id;
308 int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
309 SHGetSpecialFolderLocation (NULL,
310 issystem ? CSIDL_COMMON_PROGRAMS :
311 CSIDL_PROGRAMS, &id);
312 SHGetPathFromIDList (id, path);
313 LogBabblePrintf ("Program directory for program link: %s", path);
314 strcat (path, startmenudir());
315 strcat (path, startmenusuffix());
316 std::string fname = std::string(path) + "/" + title + ".lnk";
318 if (_access (fname.c_str(), 0) == 0)
319 return 0; /* already exists */
321 return IDC_ROOT_MENU;
324 static void
325 save_dialog (HWND h)
327 root_desktop = rbget (h, da);
328 root_menu = rbget (h, ma);
331 static BOOL
332 dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
334 switch (id)
337 case IDC_ROOT_DESKTOP:
338 case IDC_ROOT_MENU:
339 save_dialog (h);
340 check_if_enable_next (h);
341 break;
343 return 0;
346 bool
347 DesktopSetupPage::Create ()
349 return PropertyPage::Create (NULL, dialog_cmd, IDD_DESKTOP);
352 void
353 DesktopSetupPage::OnInit ()
355 SetDlgItemFont(IDC_STATUS_HEADER, "MS Shell Dlg", 8, FW_BOLD);
358 void
359 DesktopSetupPage::OnActivate ()
361 if (NoShortcutsOption || source == IDC_SOURCE_DOWNLOAD)
363 root_desktop = root_menu = 0;
365 else
367 std::string target = backslash (cygpath (TARGET));
369 if (NoStartMenuOption)
371 root_menu = 0;
373 else
375 root_menu = check_startmenu (TERMINALTITLE, target);
378 if (NoDesktopOption)
380 root_desktop = 0;
382 else
384 root_desktop = check_desktop (TERMINALTITLE, target);
388 load_dialog (GetHWND ());
391 long
392 DesktopSetupPage::OnBack ()
394 HWND h = GetHWND ();
395 save_dialog (h);
396 return IDD_CHOOSE;
399 bool
400 DesktopSetupPage::OnFinish ()
402 HWND h = GetHWND ();
403 save_dialog (h);
404 if (source != IDC_SOURCE_DOWNLOAD)
405 do_desktop_setup ();
407 return true;
410 long
411 DesktopSetupPage::OnUnattended ()
413 Window::PostMessageNow (WM_APP_UNATTENDED_FINISH);
414 // GetOwner ()->PressButton(PSBTN_FINISH);
415 return -1;
418 bool
419 DesktopSetupPage::OnMessageApp (UINT uMsg, WPARAM wParam, LPARAM lParam)
421 switch (uMsg)
423 case WM_APP_UNATTENDED_FINISH:
425 GetOwner ()->PressButton(PSBTN_FINISH);
426 break;
428 default:
430 // Not handled
431 return false;
435 return true;