Initial revision
[chise/xemacs-chise.git] / netinstall / desktop.cc
1 /*
2  * Copyright (c) 2000, 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
22 #include "win32.h"
23 #include <shlobj.h>
24
25 #include <io.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #ifndef WIN32_NATIVE
29 #include <unistd.h>
30 #endif
31
32 #include "resource.h"
33 #include "ini.h"
34 #include "msg.h"
35 #include "state.h"
36 #include "concat.h"
37 #include "mkdir.h"
38 #include "dialog.h"
39 #include "version.h"
40 #include "reginfo.h"
41 #include "regedit.h"
42 #include "port.h"
43
44 extern "C" {
45   void make_link_2 (char *exepath, char *args, char *icon, char *lname);
46 };
47
48 static OSVERSIONINFO verinfo;
49
50 /* Lines starting with '@' are conditionals - include 'N' for NT,
51    '5' for Win95, '8' for Win98, '*' for all, like this:
52         echo foo
53         @N8
54         echo NT or 98
55         @*
56    */
57
58 #define COMMAND9XARGS "/E:4096 /c"
59 #define COMMAND9XEXE  "\\command.com"
60
61 static char *iconname;
62 static char *batname;
63
64 static void
65 make_link (char *linkpath, char *title, char *target)
66 {
67   char argbuf[_MAX_PATH];
68   char *fname = concat (linkpath, "/", title, ".lnk", 0);
69
70   if (_access (fname, 0) == 0)
71     return; /* already exists */
72
73   msg ("make_link %s, %s, %s\n", fname, title, target);
74
75   mkdir_p (0, fname);
76
77   char *exepath, *args;
78
79   /* If we are running Win9x, build a command line. */
80   if (verinfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
81     {
82       exepath = target;
83       args = "";
84     }
85   else
86     {
87       char windir[MAX_PATH];
88
89       GetWindowsDirectory (windir, sizeof (windir));
90       exepath = concat (windir, COMMAND9XEXE, 0);
91       sprintf (argbuf, "%s %s", COMMAND9XARGS, target);
92       args = argbuf;
93     }
94
95   msg ("make_link_2 (%s, %s, %s, %s)", exepath, args, iconname, fname);
96   make_link_2 (exepath, args, iconname, fname);
97 }
98
99 static char* 
100 find_xemacs_exe_path ()
101 {
102   if (xemacs_package->type == TY_CYGWIN)
103     return backslash (concat (root_dir, "/bin/", XEMACS_CYGWIN_ARCH_NAME, 0));
104   else
105     return backslash (concat (root_dir, "\\XEmacs-",
106                               xemacs_package->info[xemacs_package->trust].version, 
107                               "\\", XEMACS_NATIVE_ARCH_NAME, 0));
108 }
109
110 static char* 
111 find_xemacs_exe_name ()
112 {
113   if (xemacs_package->type == TY_CYGWIN)
114     return backslash (concat ("xemacs-",
115                               xemacs_package->info[xemacs_package->trust].version, 
116                               ".exe", 0));
117   else
118     return strdup ("xemacs.exe");
119 }
120
121 static void
122 start_menu (char *title, char *target)
123 {
124   char path[_MAX_PATH];
125   LPITEMIDLIST id;
126   int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
127   SHGetSpecialFolderLocation (NULL, issystem ? CSIDL_COMMON_PROGRAMS : CSIDL_PROGRAMS, &id);
128   SHGetPathFromIDList (id, path);
129 // following lines added because it appears Win95 does not use common programs
130 // unless it comes into play when multiple users for Win95 is enabled
131   msg("Program directory for program link: %s",path);
132   if ( strlen(path) == 0) {
133      SHGetSpecialFolderLocation (NULL, CSIDL_PROGRAMS, &id);
134      SHGetPathFromIDList (id, path);
135      msg("Program directory for program link changed to: %s",path);
136   }
137 // end of Win95 addition
138   strcat (path, "/");
139   strcat (path, XEMACS_INFO_XEMACS_ORG_REGISTRY_NAME);
140   make_link (path, title, target);
141 }
142
143 static void
144 desktop_icon (char *title, char *target)
145 {
146   char path[_MAX_PATH];
147   LPITEMIDLIST id;
148   int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
149   //SHGetSpecialFolderLocation (NULL, issystem ? CSIDL_DESKTOP : CSIDL_COMMON_DESKTOPDIRECTORY, &id);
150   SHGetSpecialFolderLocation (NULL, issystem ? CSIDL_COMMON_DESKTOPDIRECTORY : 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      SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOPDIRECTORY, &id);
157      SHGetPathFromIDList (id, path);
158      msg("Desktop directory for deskop link changed to: %s",path);
159   }
160 // end of Win95 addition
161   make_link (path, title, target);
162 }
163
164 static int
165 uexists (char *path)
166 {
167   char *f = concat (root_dir, path, 0);
168   int a = _access (f, 0);
169   free (f);
170   if (a == 0)
171     return 1;
172   return 0;
173 }
174
175 static void
176 make_passwd_group ()
177 {
178   if (verinfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
179     {
180       int i;
181
182       LOOP_PACKAGES
183         {
184           if (!strcmp (package[i].name, "cygwin"))
185             {
186               /* mkpasswd and mkgroup are not working on 9x/ME up to 1.1.5-4 */
187               char *border_version = canonicalize_version ("1.1.5-4");
188               char *inst_version = canonicalize_version (pi.version);
189
190               if (strcmp (inst_version, border_version) <= 0)
191                 return;
192
193               break;
194             }
195         }
196     }
197
198   if (uexists ("/etc/passwd") && uexists ("/etc/group"))
199     return;
200
201   char *fname = concat (root_dir, "/etc/postinstall/passwd-grp.bat", 0);
202   mkdir_p (0, fname);
203
204   FILE *p = fopen (fname, "wb");
205   if (!p)
206     return;
207
208   if (!uexists ("/etc/passwd"))
209     fprintf (p, "bin\\mkpasswd -l > etc\\passwd\n");
210   if (!uexists ("/etc/group"))
211     fprintf (p, "bin\\mkgroup -l > etc\\group\n");
212
213   fclose (p);
214 }
215
216 static void
217 save_icon ()
218 {
219   iconname = backslash (concat (root_dir, XEMACS_RESOURCE_DIR, 
220                                 "xemacs.ico", 0));
221
222   HRSRC rsrc = FindResource (NULL, "XEMACS.ICON", "FILE");
223   if (rsrc == NULL)
224     {
225       fatal ("FindResource failed");
226     }
227   HGLOBAL res = LoadResource (NULL, rsrc);
228   char *data = (char *) LockResource (res);
229   int len = SizeofResource (NULL, rsrc);
230
231   FILE *f = fopen (iconname, "wb");
232   if (f)
233     {
234       fwrite (data, 1, len, f);
235       fclose (f);
236     }
237 }
238
239 static void
240 do_desktop_setup()
241 {
242   save_icon ();
243
244   if (root_menu && batname) {
245     start_menu ("XEmacs", batname);
246   }
247
248   if (root_desktop && batname) {
249     desktop_icon ("XEmacs", batname);
250   }
251
252   // set regkeys for the application
253   if (xemacs_package != 0)
254     {
255       int issystem = (root_scope == IDC_ROOT_SYSTEM ? 1 : 0);
256       if (xemacs_package->type == TY_NATIVE)
257         {
258 #define FROB(exe)         set_app_path ((exe), \
259                         find_xemacs_exe_path (), \
260                         issystem)
261           FROB (find_xemacs_exe_name ());
262           FROB ("runemacs.exe");
263           FROB ("xemacs.exe");
264 #undef FROB
265         }
266       else if (xemacs_package->type == TY_CYGWIN)
267         {
268           int junk;
269           char* root = find_cygwin_root (&junk);
270 #define FROB(exe)       set_app_path ((exe), \
271                         concat (find_xemacs_exe_path (), ";", \
272                                 root, "\\bin;", \
273                                 root, "\\usr\\bin", 0), \
274                         issystem)
275           FROB (find_xemacs_exe_name ());
276           FROB ("runemacs.exe");
277           FROB ("xemacs.exe");
278 #undef FROB
279         }
280     }
281 }
282
283 static int da[] = { IDC_ROOT_DESKTOP, 0 };
284 static int ma[] = { IDC_ROOT_MENU, 0 };
285
286 static void
287 check_if_enable_next (HWND h)
288 {
289   EnableWindow (GetDlgItem (h, IDOK), 1);
290 }
291
292 static void
293 load_dialog (HWND h)
294 {
295   rbset (h, da, root_desktop);
296   rbset (h, ma, root_menu);
297   check_if_enable_next (h);
298 }
299
300 static int check_desktop (char *title, char *target)
301 {
302   char path[_MAX_PATH];
303   LPITEMIDLIST id;
304   int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
305   SHGetSpecialFolderLocation (NULL, issystem ? CSIDL_COMMON_DESKTOPDIRECTORY : CSIDL_DESKTOPDIRECTORY, &id);
306   SHGetPathFromIDList (id, path);
307   // following lines added because it appears Win95 does not use common programs
308   // unless it comes into play when multiple users for Win95 is enabled
309   msg ("Desktop directory for desktop link: %s",path);
310   if (strlen (path) == 0) {
311      SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOPDIRECTORY, &id);
312      SHGetPathFromIDList (id, path);
313      msg ("Desktop directory for deskop link changed to: %s",path);
314   }
315   // end of Win95 addition
316   char *fname = concat (path, "/", title, ".lnk", 0);
317
318   if (_access (fname, 0) == 0)
319     return 0; /* already exists */
320   
321   fname = concat (path, "/", title, ".pif", 0); /* check for a pif as well */
322   
323   if (_access (fname, 0) == 0)
324     return 0; /* already exists */
325
326   return IDC_ROOT_DESKTOP;
327 }
328
329 static int check_startmenu (char *title, char *target)
330 {
331   char path[_MAX_PATH];
332   LPITEMIDLIST id;
333   int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
334   SHGetSpecialFolderLocation (NULL, issystem ? CSIDL_COMMON_PROGRAMS : CSIDL_PROGRAMS, &id);
335   SHGetPathFromIDList (id, path);
336   // following lines added because it appears Win95 does not use common programs
337   // unless it comes into play when multiple users for Win95 is enabled
338   msg ("Program directory for program link: %s",path);
339   if (strlen (path) == 0) {
340      SHGetSpecialFolderLocation (NULL, CSIDL_PROGRAMS, &id);
341      SHGetPathFromIDList (id, path);
342      msg ("Program directory for program link changed to: %s",path);
343   }
344   // end of Win95 addition
345   strcat (path, "/");
346   strcat (path, XEMACS_INFO_XEMACS_ORG_REGISTRY_NAME);
347   char *fname = concat (path, "/", title, ".lnk", 0);
348
349   if (_access (fname, 0) == 0)
350     return 0; /* already exists */
351   
352   fname = concat (path, "/", title, ".pif", 0); /* check for a pif as well */
353   
354   if (_access (fname, 0) == 0)
355     return 0; /* already exists */
356   
357   return IDC_ROOT_MENU;
358 }
359
360 static void
361 save_dialog (HWND h)
362 {
363   root_desktop= rbget (h, da);
364   root_menu = rbget (h, ma);
365 }
366
367 static BOOL
368 dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
369 {
370   switch (id)
371     {
372
373     case IDC_ROOT_DESKTOP:
374     case IDC_ROOT_MENU:
375       save_dialog (h);
376       check_if_enable_next (h);
377       break;
378
379     case IDOK:
380       save_dialog (h);
381       do_desktop_setup();
382       NEXT (IDD_S_POSTINSTALL);
383       break;
384
385     case IDC_BACK:
386       save_dialog (h);
387       NEXT (IDD_CHOOSE);
388       break;
389
390     case IDCANCEL:
391       NEXT (0);
392       break;
393     }
394   return FALSE;
395 }
396
397 static BOOL CALLBACK
398 dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
399 {
400   switch (message)
401     {
402     case WM_INITDIALOG:
403       load_dialog (h);
404       return FALSE;
405     case WM_COMMAND:
406       return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd);
407     }
408   return FALSE;
409 }
410
411 void
412 do_desktop (HINSTANCE h)
413 {
414   CoInitialize (NULL);
415
416   verinfo.dwOSVersionInfoSize = sizeof (verinfo);
417   GetVersionEx (&verinfo);
418   batname = 0;
419
420   if (xemacs_package != 0 && xemacs_package->type != TY_GENERIC)
421     {
422       batname = concat (find_xemacs_exe_path (), "\\",
423                         find_xemacs_exe_name (), 0);
424       root_desktop = check_desktop ("XEmacs", batname);
425       root_menu = check_startmenu ("XEmacs", batname);
426     }
427   else
428     {
429       root_desktop = 0;
430       root_menu = 0;
431     }
432   
433   int rv = 0;
434
435   rv = DialogBox (h, MAKEINTRESOURCE (IDD_DESKTOP), 0, dialog_proc);
436   if (rv == -1)
437     fatal (IDS_DIALOG_FAILED);
438 }