Release 960302
Sat Mar 2 18:19:06 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [controls/scroll.c]
Fixed SCROLL_THUMB painting fixes from Alex Korobka to store the
current tracking window.
* [files/file.c]
Fixed two file descriptor leaks in FILE_OpenFile().
* [if1632/relay32.c] [loader/module.c] [loader/pe_image.c]
[tools/build.c]
Replaced LOADEDFILEINFO structure by OFSTRUCT.
* [memory/atom.c]
Reload the pointer to the atom table in ATOM_GetTable() and
ATOM_AddAtom() in case the LOCAL_Alloc() calls caused the table to
move in linear memory.
Fri Mar 1 11:57:13 1996 Frans van Dorsselaer <dorssel@rulhm1.leidenuniv.nl>
* [include/callback.h]
Added support for CallWordBreakProc().
* [controls/edit.c]
New caret handling (really efficient / fast).
Implemented EM_SETWORDBREAKPROC and EM_GETWORDBREAKPROC.
Fixed EM_SETFONT so it now also creates a proper new caret.
Wed Feb 28 22:03:34 1996 Daniel Schepler <daniel@frobnitz.wustl.edu>
* [controls/desktop.c] [misc/main.c] [windows/event.c] [windows/win.c]
Added WM_DELETE protocol to top-level windows.
* [controls/scroll.c]
Fixed a problem which caused slow scrolling to continue uncontrollably.
* [misc/exec.c]
Implemented ExitWindows().
* [windows/win.c]
Set top-level owned windows to be transient.
Wed Feb 28 19:13:22 1996 Ulrich Schmid <uschmid@mail.hh.provi.de>
* [programs/progman/*]
Added a program manager.
Wed Feb 28 18:38:01 1996 Duncan C Thomson <duncan@spd.eee.strath.ac.uk>
* [resources/sysres_Eo.c]
Added support for Esperanto [Eo] language.
Wed Feb 28 00:23:00 1996 Thomas Sandford <t.d.g.sandford@prds-grn.demon.co.uk>
* [if1632/user32.spec]
Added EndDialog, GetDlgItem, GetDlgItemInt, SetDlgItemInt,
* [win32/init.c]
Added task.h to includes. GetModuleHandleA() - return hInstance
if called with NULL parameter. Freecell needs this. NOTE this
may indicate a problem with differentiation between hModule and
hInstance within Wine.
* [win32/resource.c]
FindResource32() and LoadResource32() - Removed #if 0's around
conversion from hInstance to hModule. See remarks above.
* [win32/string32.c]
WIN32_UniLen() - removed stray semicolon.
Tue Feb 27 21:05:18 1996 Jim Peterson <jspeter@birch.ee.vt.edu>
* [windows/caret.c]
Set blink rate with call to GetProfileInt().
* [rc/winerc.c]
In new_style(), made initial flag settings WS_CHILD | WS_VISIBLE
instead of 0. This seems to correspond to Borland's defaults, and
the flags can be unset by using the (rather obtuse) "| NOT WS_CHILD"
or "| NOT WS_VISIBLE" technique in the *.rc file.
* [win32/time.c]
In GetLocalTime() and GetSystemTime(), used tv_sec field of result
returned by gettimeofday() instead of making second call to
time(). This eliminates clock jitter if the seconds change
between the two calls (rare, but possible).
* [include/wintypes.h]
Added "#define _far" and "#define _pascal".
* [windows/win.c]
Added function GetDesktopHwnd().
* [include/xmalloc.h]
Removed the '#ifdef HAVE_STDLIB_H' structure, since it seemed to
have been removed from 'configure', and was causing redefinition
warnings.
Tue Feb 27 19:31:11 1996 Albrecht Kleine <kleine@ak.sax.de>
* [windows/winpos.c]
Added RDW_ALLCHILDREN flag in SetWindowPos (handling SWP_FRAMECHANGED)
to force a repaint when setting menu bars with different rows.
Sun Feb 25 21:15:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu>
* [windows/syscolors.c] [controls/scroll.c]
Fixed DrawFocusRect pen and SCROLL_THUMB painting.
diff --git a/ANNOUNCE b/ANNOUNCE
index 8ba1e3b..662f7c4 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,15 +1,15 @@
-This is release 960225 of Wine the MS Windows emulator. This is still a
+This is release 960302 of Wine the MS Windows emulator. This is still a
developer's only release. There are many bugs and many unimplemented API
features. Most applications still do not work.
Patches should be submitted to "julliard@lrc.epfl.ch". Please don't
forget to include a ChangeLog entry.
-WHAT'S NEW with Wine-960225: (see ChangeLog for details)
- - Many caret fixes.
- - New -mode option to replace -enhanced.
- - Many listboxes improvements.
- - Find and Replace dialogs in built-in COMMDLG fixed.
+WHAT'S NEW with Wine-960302: (see ChangeLog for details)
+ - Program manager clone using Winelib.
+ - Support for Esperanto language.
+ - Some scrollbar fixes.
+ - Edit control improvements.
- Lots of bug fixes.
See the README file in the distribution for installation instructions.
@@ -18,10 +18,10 @@
the release is available at the ftp sites. The sources will be available
from the following locations:
- sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960225.tar.gz
- tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960225.tar.gz
- ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960225.tar.gz
- aris.com:/pub/linux/ALPHA/Wine/development/Wine-960225.tar.gz
+ sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960302.tar.gz
+ tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960302.tar.gz
+ ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960302.tar.gz
+ aris.com:/pub/linux/ALPHA/Wine/development/Wine-960302.tar.gz
It should also be available from any site that mirrors tsx-11 or sunsite.
diff --git a/ChangeLog b/ChangeLog
index 42953b0..3ab435b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,114 @@
----------------------------------------------------------------------
+Sat Mar 2 18:19:06 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
+
+ * [controls/scroll.c]
+ Fixed SCROLL_THUMB painting fixes from Alex Korobka to store the
+ current tracking window.
+
+ * [files/file.c]
+ Fixed two file descriptor leaks in FILE_OpenFile().
+
+ * [if1632/relay32.c] [loader/module.c] [loader/pe_image.c]
+ [tools/build.c]
+ Replaced LOADEDFILEINFO structure by OFSTRUCT.
+
+ * [memory/atom.c]
+ Reload the pointer to the atom table in ATOM_GetTable() and
+ ATOM_AddAtom() in case the LOCAL_Alloc() calls caused the table to
+ move in linear memory.
+
+Fri Mar 1 11:57:13 1996 Frans van Dorsselaer <dorssel@rulhm1.leidenuniv.nl>
+
+ * [include/callback.h]
+ Added support for CallWordBreakProc().
+
+ * [controls/edit.c]
+ New caret handling (really efficient / fast).
+ Implemented EM_SETWORDBREAKPROC and EM_GETWORDBREAKPROC.
+ Fixed EM_SETFONT so it now also creates a proper new caret.
+
+Wed Feb 28 22:03:34 1996 Daniel Schepler <daniel@frobnitz.wustl.edu>
+
+ * [controls/desktop.c] [misc/main.c] [windows/event.c] [windows/win.c]
+ Added WM_DELETE protocol to top-level windows.
+
+ * [controls/scroll.c]
+ Fixed a problem which caused slow scrolling to continue uncontrollably.
+
+ * [misc/exec.c]
+ Implemented ExitWindows().
+
+ * [windows/win.c]
+ Set top-level owned windows to be transient.
+
+Wed Feb 28 19:13:22 1996 Ulrich Schmid <uschmid@mail.hh.provi.de>
+
+ * [programs/progman/*]
+ Added a program manager.
+
+Wed Feb 28 18:38:01 1996 Duncan C Thomson <duncan@spd.eee.strath.ac.uk>
+
+ * [resources/sysres_Eo.c]
+ Added support for Esperanto [Eo] language.
+
+Wed Feb 28 00:23:00 1996 Thomas Sandford <t.d.g.sandford@prds-grn.demon.co.uk>
+
+ * [if1632/user32.spec]
+ Added EndDialog, GetDlgItem, GetDlgItemInt, SetDlgItemInt,
+
+ * [win32/init.c]
+ Added task.h to includes. GetModuleHandleA() - return hInstance
+ if called with NULL parameter. Freecell needs this. NOTE this
+ may indicate a problem with differentiation between hModule and
+ hInstance within Wine.
+
+ * [win32/resource.c]
+ FindResource32() and LoadResource32() - Removed #if 0's around
+ conversion from hInstance to hModule. See remarks above.
+
+ * [win32/string32.c]
+ WIN32_UniLen() - removed stray semicolon.
+
+Tue Feb 27 21:05:18 1996 Jim Peterson <jspeter@birch.ee.vt.edu>
+
+ * [windows/caret.c]
+ Set blink rate with call to GetProfileInt().
+
+ * [rc/winerc.c]
+ In new_style(), made initial flag settings WS_CHILD | WS_VISIBLE
+ instead of 0. This seems to correspond to Borland's defaults, and
+ the flags can be unset by using the (rather obtuse) "| NOT WS_CHILD"
+ or "| NOT WS_VISIBLE" technique in the *.rc file.
+
+ * [win32/time.c]
+ In GetLocalTime() and GetSystemTime(), used tv_sec field of result
+ returned by gettimeofday() instead of making second call to
+ time(). This eliminates clock jitter if the seconds change
+ between the two calls (rare, but possible).
+
+ * [include/wintypes.h]
+ Added "#define _far" and "#define _pascal".
+
+ * [windows/win.c]
+ Added function GetDesktopHwnd().
+
+ * [include/xmalloc.h]
+ Removed the '#ifdef HAVE_STDLIB_H' structure, since it seemed to
+ have been removed from 'configure', and was causing redefinition
+ warnings.
+
+Tue Feb 27 19:31:11 1996 Albrecht Kleine <kleine@ak.sax.de>
+
+ * [windows/winpos.c]
+ Added RDW_ALLCHILDREN flag in SetWindowPos (handling SWP_FRAMECHANGED)
+ to force a repaint when setting menu bars with different rows.
+
+Sun Feb 25 21:15:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu>
+
+ * [windows/syscolors.c] [controls/scroll.c]
+ Fixed DrawFocusRect pen and SCROLL_THUMB painting.
+
+----------------------------------------------------------------------
Sat Feb 24 16:17:05 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [files/profile.c]
diff --git a/Make.rules.in b/Make.rules.in
index d871a6f..3ae1d05 100644
--- a/Make.rules.in
+++ b/Make.rules.in
@@ -42,7 +42,7 @@
echo "#include \"windows.h\"" >winerctmp.c
echo WINDOWS_H_ENDS_HERE >>winerctmp.c
cat $< >>winerctmp.c
- $(CPP) $(DEFS) $(DIVINCL) -P winerctmp.c | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | $(WINERC) -c -o $* -p $*
+ $(CPP) $(DEFS) $(DIVINCL) -DRC_INVOKED -P winerctmp.c | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | $(WINERC) -c -o $* -p $*
$(RM) winerctmp.c
.rc.h:
diff --git a/Makefile.in b/Makefile.in
index dbbe50e..42f935e 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -69,7 +69,9 @@
LIBSUBDIRS = library
-ALLSUBDIRS = $(COMMONSUBDIRS) $(EMUSUBDIRS) $(LIBSUBDIRS) libtest
+PROGSUBDIRS = libtest programs
+
+ALLSUBDIRS = $(COMMONSUBDIRS) $(EMUSUBDIRS) $(LIBSUBDIRS) $(PROGSUBDIRS)
COMMONOBJS = \
controls/controls.o \
diff --git a/configure b/configure
index ba6c93e..df78b45 100755
--- a/configure
+++ b/configure
@@ -1962,6 +1962,8 @@
miscemu/Makefile
multimedia/Makefile
objects/Makefile
+programs/Makefile
+programs/progman/Makefile
rc/Makefile
resources/Makefile
tools/Makefile
@@ -2034,6 +2036,8 @@
miscemu/Makefile
multimedia/Makefile
objects/Makefile
+programs/Makefile
+programs/progman/Makefile
rc/Makefile
resources/Makefile
tools/Makefile
diff --git a/configure.in b/configure.in
index 9fbbd12..ff6531b 100644
--- a/configure.in
+++ b/configure.in
@@ -97,6 +97,8 @@
miscemu/Makefile
multimedia/Makefile
objects/Makefile
+programs/Makefile
+programs/progman/Makefile
rc/Makefile
resources/Makefile
tools/Makefile
diff --git a/controls/desktop.c b/controls/desktop.c
index 77faca7..c0d48fb 100644
--- a/controls/desktop.c
+++ b/controls/desktop.c
@@ -149,6 +149,10 @@
case WM_ERASEBKGND:
if (rootWindow == DefaultRootWindow(display)) return 1;
return DESKTOP_DoEraseBkgnd( hwnd, (HDC)wParam, infoPtr );
+
+ case WM_SYSCOMMAND:
+ if ((wParam & 0xfff0) != SC_CLOSE) return 0;
+ ExitWindows( 0, 0 );
}
return 0;
diff --git a/controls/edit.c b/controls/edit.c
index 73ce404..e952589 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -19,7 +19,7 @@
#include "stddebug.h"
#include "debug.h"
#include "xmalloc.h"
-
+#include "callback.h"
#ifdef WINELIB32
#define NOTIFY_PARENT(hWndCntrl, wNotifyCode) \
@@ -71,8 +71,15 @@
int ClientWidth; /* computed from the window's ClientRect */
int ClientHeight; /* ditto */
char PasswordChar; /* The password character */
+ EDITWORDBREAKPROC WordBreakProc;
+ BOOL WeOwnCaret; /* Do we own the caret ? */
+ int CaretPrepareCount; /* Did we already prepare the caret ? */
+ BOOL CaretHidden; /* Did we hide the caret during painting ? */
+ int oldWndCol; /* WndCol before we started painting */
+ int oldWndRow; /* ditto for WndRow */
} EDITSTATE;
+
#define EditBufStartLen(hwnd) (GetWindowLong(hwnd,GWL_STYLE) & ES_MULTILINE \
? EDITLEN : ENTRYLEN)
#define CurrChar (EDIT_TextLine(hwnd, es->CurrLine) + es->CurrCol)
@@ -98,6 +105,7 @@
#define SWAP_INT(x,y) do { int temp = (x); (x) = (y); (y) = temp; } while(0)
+
/*********************************************************************
* EDIT_HeapAlloc
*
@@ -197,6 +205,105 @@
}
/*********************************************************************
+ * EDIT_CaretPrepare
+ *
+ * Save the caret state before any painting is done.
+ */
+static void EDIT_CaretPrepare(HWND hwnd)
+{
+ EDITSTATE *es = EDIT_GetEditState(hwnd);
+
+ if (!es) return;
+
+ if (!es->CaretPrepareCount)
+ {
+ es->CaretHidden = FALSE;
+ es->oldWndCol = es->WndCol;
+ es->oldWndRow = es->WndRow;
+ }
+
+ es->CaretPrepareCount++;
+}
+
+/*********************************************************************
+ * EDIT_CaretHide
+ *
+ * Called before some painting is done.
+ */
+static void EDIT_CaretHide(HWND hwnd)
+{
+ EDITSTATE *es = EDIT_GetEditState(hwnd);
+
+ if (!es) return;
+ if (!es->WeOwnCaret) return;
+ if (!es->CaretPrepareCount) return;
+
+ if (!es->CaretHidden)
+ {
+ HideCaret(hwnd);
+ es->CaretHidden = TRUE;
+ }
+}
+
+/*********************************************************************
+ * EDIT_CaretUpdate
+ *
+ * Called after all painting is done.
+ */
+static void EDIT_CaretUpdate(HWND hwnd)
+{
+ EDITSTATE *es = EDIT_GetEditState(hwnd);
+
+ if (!es) return;
+ if (!es->CaretPrepareCount) return;
+
+ es->CaretPrepareCount--;
+
+ if (es->CaretPrepareCount) return;
+ if (!es->WeOwnCaret) return;
+
+ if ((es->WndCol != es->oldWndCol) || (es->WndRow != es->oldWndRow))
+ SetCaretPos(es->WndCol, es->WndRow * es->txtht);
+
+ if (es->CaretHidden)
+ {
+ ShowCaret(hwnd);
+ es->CaretHidden = FALSE;
+ }
+}
+
+/*********************************************************************
+ * EDIT_WordBreakProc
+ *
+ * Find the beginning of words.
+ */
+static int CALLBACK EDIT_WordBreakProc(char * pch, int ichCurrent,
+ int cch, int code)
+{
+ dprintf_edit(stddeb, "EDIT_WordBreakProc: pch=%p, ichCurrent=%d"
+ ", cch=%d, code=%d\n", pch, ichCurrent, cch, code);
+
+ dprintf_edit(stddeb, "string=%s\n", pch);
+ return 0;
+}
+
+/*********************************************************************
+ * EDIT_CallWordBreakProc
+ *
+ * Call appropriate WordBreakProc (internal or external).
+ */
+static int CALLBACK EDIT_CallWordBreakProc(HWND hwnd, char *pch,
+ int ichCurrent, int cch, int code)
+{
+ EDITSTATE *es = EDIT_GetEditState(hwnd);
+
+ if (es->WordBreakProc) {
+ /* FIXME: do some stuff to make pch a SEGPTR */
+ return CallWordBreakProc((FARPROC)es->WordBreakProc, (LONG)pch, ichCurrent, cch, code);
+ } else return EDIT_WordBreakProc(pch, ichCurrent, cch, code);
+}
+
+/*********************************************************************
* EDIT_GetNextTabStop
*
* Return the next tab stop beyond _pcol_.
@@ -466,6 +573,8 @@
dprintf_edit(stddeb,"EDIT_WriteText lp=%s, off=%d, len=%d, row=%d, col=%d, reverse=%d\n", lp, off, len, row, col, reverse);
+ EDIT_CaretHide(hwnd);
+
if( off < 0 ) {
len += off;
col -= off;
@@ -832,6 +941,8 @@
if (IsWindowVisible(hwnd))
{
+ EDIT_CaretHide(hwnd);
+
/* adjust client bottom to nearest whole line */
GetClientRect(hwnd, &rc);
rc.bottom = (rc.bottom / es->txtht) * es->txtht;
@@ -1196,6 +1307,8 @@
if (IsWindowVisible(hwnd))
{
+ EDIT_CaretHide(hwnd);
+
/* adjust client bottom to nearest whole line */
GetClientRect(hwnd, &rc);
rc.bottom = (rc.bottom / es->txtht) * es->txtht;
@@ -1747,7 +1860,6 @@
NOTIFY_PARENT(hwnd, EN_UPDATE);
/* re-adjust textwidth, if necessary, and redraw line */
- HideCaret(hwnd);
if (IsMultiLine(hwnd) && es->wlines > 1)
{
es->textwidth = MAX(es->textwidth,
@@ -1775,8 +1887,6 @@
rc.top = es->WndRow * es->txtht;
InvalidateRect(hwnd, &rc, FALSE);
- SetCaretPos(es->WndCol, es->WndRow * es->txtht);
- ShowCaret(hwnd);
UpdateWindow(hwnd);
NOTIFY_PARENT(hwnd, EN_CHANGE);
return;
@@ -1795,8 +1905,6 @@
es->CurrCol++;
EDIT_SetAnchor(hwnd, es->CurrLine, es->CurrCol);
EDIT_WriteTextLine(hwnd, NULL, es->wtop + es->WndRow);
- SetCaretPos(es->WndCol, es->WndRow * es->txtht);
- ShowCaret(hwnd);
NOTIFY_PARENT(hwnd, EN_CHANGE);
dprintf_edit(stddeb,"KeyTyped O.K.\n");
}
@@ -2150,6 +2258,14 @@
es->PaintBkgd = TRUE;
if (lParam) UpdateWindow(hwnd);
EDIT_RecalcSize(hwnd,es);
+
+ if (es->WeOwnCaret)
+ {
+ EDIT_CaretHide(hwnd);
+ DestroyCaret();
+ CreateCaret(hwnd, 0, 2, es->txtht);
+ SetCaretPos(es->WndCol, es->WndRow * es->txtht);
+ }
}
/*********************************************************************
@@ -2186,6 +2302,8 @@
RECT rc;
EDITSTATE *es = EDIT_GetEditState(hwnd);
+ EDIT_CaretHide(hwnd);
+
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rc);
IntersectClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom);
@@ -2237,6 +2355,13 @@
/* --- text buffer */
es->MaxTextLen = MAXTEXTLEN + 1;
es->PasswordChar = '*';
+
+ es->WordBreakProc = NULL;
+
+ /* Caret stuff */
+ es->CaretPrepareCount = 1;
+ es->CaretHidden = FALSE;
+ es->WeOwnCaret = FALSE;
/*
* Hack - If there is no local heap then hwnd should be a globalHeap block
* and the local heap needs to be initilised to the same size(minus something)
@@ -2384,12 +2509,11 @@
*/
static void EDIT_WM_VScroll(HWND hwnd, WORD wParam, LONG lParam)
{
- EDITSTATE *es = EDIT_GetEditState(hwnd);
-
+/*
+ * EDITSTATE *es = EDIT_GetEditState(hwnd);
+ */
if (IsMultiLine(hwnd))
{
- HideCaret(hwnd);
-
switch (wParam)
{
case SB_LINEUP:
@@ -2403,9 +2527,6 @@
break;
}
}
-
- SetCaretPos(es->WndCol, es->WndRow);
- ShowCaret(hwnd);
}
/*********************************************************************
@@ -2413,16 +2534,13 @@
*/
static void EDIT_WM_HScroll(HWND hwnd, WORD wParam, LONG lParam)
{
- EDITSTATE *es = EDIT_GetEditState(hwnd);
-
+/*
+ * EDITSTATE *es = EDIT_GetEditState(hwnd);
+ */
switch (wParam)
{
case SB_LINEUP:
case SB_LINEDOWN:
- HideCaret(hwnd);
-
- SetCaretPos(es->WndCol, es->WndRow * es->txtht);
- ShowCaret(hwnd);
break;
}
}
@@ -2489,11 +2607,11 @@
*/
static void EDIT_WM_MouseMove(HWND hwnd, WORD wParam, LONG lParam)
{
- EDITSTATE *es = EDIT_GetEditState(hwnd);
-
+/*
+ * EDITSTATE *es = EDIT_GetEditState(hwnd);
+ */
if (!(wParam & MK_LBUTTON)) return;
- HideCaret(hwnd);
if (ButtonDown)
{
TextMarking = TRUE;
@@ -2501,11 +2619,7 @@
}
if (TextMarking)
- {
EDIT_ExtendSel(hwnd, LOWORD(lParam), HIWORD(lParam));
- SetCaretPos(es->WndCol, es->WndRow * es->txtht);
- }
- ShowCaret(hwnd);
}
/*********************************************************************
@@ -2548,7 +2662,6 @@
dprintf_edit(stddeb,"EDIT_WM_KeyDown: key=%x\n", wParam);
- HideCaret(hwnd);
switch (wParam)
{
case VK_UP:
@@ -2627,7 +2740,6 @@
break;
default:
- ShowCaret(hwnd);
return;
}
@@ -2641,8 +2753,6 @@
} else {
EDIT_SetAnchor(hwnd, es->CurrLine, es->CurrCol);
}
- SetCaretPos(es->WndCol, es->WndRow * es->txtht);
- ShowCaret(hwnd);
}
/*********************************************************************
@@ -2689,6 +2799,8 @@
int len;
EDITSTATE *es = EDIT_GetEditState(hwnd);
+ EDIT_CaretPrepare(hwnd);
+
switch (uMsg) {
case EM_CANUNDO:
lResult = (LONG)es->hDeletedText;
@@ -2733,7 +2845,6 @@
break;
case EM_GETPASSWORDCHAR:
- /* FIXME: is this the right place to return the character? */
lResult = es->PasswordChar;
break;
@@ -2746,7 +2857,8 @@
break;
case EM_GETWORDBREAKPROC:
- fprintf(stdnimp,"edit: cannot process EM_GETWORDBREAKPROC message\n");
+ dprintf_edit(stddeb, "EM_GETWORDBREAKPROC\n");
+ lResult = (LONG)es->WordBreakProc;
break;
case EM_LIMITTEXT:
@@ -2778,18 +2890,12 @@
break;
case EM_REPLACESEL:
- HideCaret(hwnd);
EDIT_ReplaceSel(hwnd, lParam);
- SetCaretPos(es->WndCol, es->WndRow * es->txtht);
- ShowCaret(hwnd);
break;
case EM_SETHANDLE:
- HideCaret(hwnd);
EDIT_ClearDeletedText(hwnd);
EDIT_SetHandleMsg(hwnd, wParam);
- SetCaretPos(es->WndCol, es->WndRow * es->txtht);
- ShowCaret(hwnd);
break;
case EM_SETMODIFY:
@@ -2810,10 +2916,7 @@
break;
case EM_SETSEL:
- HideCaret(hwnd);
EDIT_SetSelMsg(hwnd, wParam, lParam);
- SetCaretPos(es->WndCol, es->WndRow * es->txtht);
- ShowCaret(hwnd);
break;
case EM_SETTABSTOPS:
@@ -2821,18 +2924,18 @@
break;
case EM_SETWORDBREAKPROC:
- fprintf(stdnimp,"edit: cannot process EM_SETWORDBREAKPROC message\n");
+ dprintf_edit(stddeb, "EM_SETWORDBREAKPROC, lParam=%08lx\n",
+ (DWORD)lParam);
+ es->WordBreakProc = (EDITWORDBREAKPROC)lParam;
break;
case EM_UNDO:
- HideCaret(hwnd);
lResult = EDIT_UndoMsg(hwnd);
- SetCaretPos(es->WndCol, es->WndRow * es->txtht);
- ShowCaret(hwnd);
break;
case WM_GETDLGCODE:
- return DLGC_HASSETSEL | DLGC_WANTCHARS | DLGC_WANTARROWS;
+ lResult = DLGC_HASSETSEL | DLGC_WANTCHARS | DLGC_WANTARROWS;
+ break;
case WM_CHAR:
EDIT_WM_Char(hwnd, wParam);
@@ -2895,6 +2998,7 @@
dprintf_edit(stddeb, "WM_KILLFOCUS\n");
es->HaveFocus = FALSE;
DestroyCaret();
+ es->WeOwnCaret = FALSE;
if (SelMarked(es))
if(GetWindowLong(hwnd,GWL_STYLE) & ES_NOHIDESEL)
EDIT_UpdateSel(hwnd);
@@ -2904,12 +3008,9 @@
break;
case WM_LBUTTONDOWN:
- HideCaret(hwnd);
SetFocus(hwnd);
SetCapture(hwnd);
EDIT_WM_LButtonDown(hwnd, wParam, lParam);
- SetCaretPos(es->WndCol, es->WndRow * es->txtht);
- ShowCaret(hwnd);
break;
case WM_LBUTTONUP:
@@ -2945,16 +3046,14 @@
es->HaveFocus = TRUE;
if (SelMarked(es)) EDIT_UpdateSel(hwnd);
CreateCaret(hwnd, 0, 2, es->txtht);
+ es->WeOwnCaret = TRUE;
SetCaretPos(es->WndCol, es->WndRow * es->txtht);
- ShowCaret(hwnd);
+ es->CaretHidden = TRUE;
NOTIFY_PARENT(hwnd, EN_SETFOCUS);
break;
case WM_SETFONT:
- HideCaret(hwnd);
EDIT_WM_SetFont(hwnd, wParam, lParam);
- SetCaretPos(es->WndCol, es->WndRow * es->txtht);
- ShowCaret(hwnd);
break;
#if 0
case WM_SETREDRAW:
@@ -2988,6 +3087,8 @@
break;
}
+ EDIT_CaretUpdate(hwnd);
+
return lResult;
}
diff --git a/controls/listbox.c b/controls/listbox.c
index 3d24874..3365cde 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -2096,16 +2096,8 @@
if (!filespec[0]) strcpy( mask, "*.*" );
else
{
- const char *ptr;
- BYTE attr;
- if (((ptr = DOSFS_GetUnixFileName( filespec, TRUE )) != NULL) &&
- FILE_Stat( ptr, &attr, NULL, NULL, NULL ) &&
- (attr & FA_DIRECTORY))
- {
- /* If the path exists and is a directory, chdir to it */
- if (!DRIVE_Chdir( drive, filespec )) return FALSE;
- strcpy( mask, "*.*" );
- }
+ /* If the path exists and is a directory, chdir to it */
+ if (DRIVE_Chdir( drive, filespec )) strcpy( mask, "*.*" );
else
{
char *p, *p2;
diff --git a/controls/scroll.c b/controls/scroll.c
index aac0ecf..e746ec5 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -70,6 +70,10 @@
SCROLL_BOTTOM_ARROW /* Bottom or right arrow */
};
+ /* Thumb-tracking info */
+static HWND hwndTracking = 0;
+static int nBarTracking = 0;
+static UINT uTrackingPos = 0;
/***********************************************************************
* SCROLL_LoadBitmaps
@@ -430,6 +434,8 @@
Rectangle( hdc, r.left, r.top, r.right, r.bottom );
InflateRect( &r, -1, -1 );
GRAPH_DrawReliefRect( hdc, &r, 1, 2, FALSE );
+ if ((hwndTracking == hwnd) && (nBarTracking == nBar))
+ SCROLL_DrawMovingThumb( hdc, &rect, vertical, arrowSize, uTrackingPos);
}
@@ -607,9 +613,6 @@
{
if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
{
- SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
- SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
- (FARPROC)0 );
#ifdef WINELIB32
SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
(WPARAM)SB_LINEUP, (LPARAM)hwndCtl );
@@ -617,6 +620,9 @@
SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
SB_LINEUP, MAKELONG( 0, hwndCtl ));
#endif
+ SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
+ SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
+ (FARPROC)0 );
}
}
else KillSystemTimer( hwnd, SCROLL_TIMER );
@@ -630,9 +636,6 @@
{
if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
{
- SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
- SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
- (FARPROC)0 );
#ifdef WINELIB32
SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
(WPARAM)SB_PAGEUP, (LPARAM)hwndCtl );
@@ -640,6 +643,9 @@
SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
SB_PAGEUP, MAKELONG( 0, hwndCtl ));
#endif
+ SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
+ SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
+ (FARPROC)0 );
}
}
else KillSystemTimer( hwnd, SCROLL_TIMER );
@@ -647,11 +653,18 @@
case SCROLL_THUMB:
if (msg == WM_LBUTTONDOWN)
+ {
SCROLL_DrawMovingThumb( hdc, &rect, vertical, arrowSize,
trackThumbPos + lastMousePos - lastClickPos );
+ hwndTracking = hwnd;
+ nBarTracking = nBar;
+ }
else if (msg == WM_LBUTTONUP)
+ {
+ hwndTracking = 0;
SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbPos,
infoPtr->flags, vertical, FALSE, FALSE );
+ }
else /* WM_MOUSEMOVE */
{
UINT pos, val;
@@ -662,11 +675,11 @@
{
SCROLL_DrawMovingThumb( hdc, &rect, vertical, arrowSize,
trackThumbPos + lastMousePos - lastClickPos );
- SCROLL_DrawMovingThumb( hdc, &rect, vertical, arrowSize,
- trackThumbPos + pos - lastClickPos );
lastMousePos = pos;
val = SCROLL_GetThumbVal( infoPtr, &rect, vertical,
trackThumbPos + lastMousePos - lastClickPos );
+ /* Save tracking info */
+ uTrackingPos = trackThumbPos + pos - lastClickPos;
#ifdef WINELIB32
SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
MAKEWPARAM(SB_THUMBTRACK,val), (LPARAM)hwndCtl );
@@ -674,6 +687,8 @@
SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
SB_THUMBTRACK, MAKELONG( val, hwndCtl ));
#endif
+ SCROLL_DrawMovingThumb( hdc, &rect, vertical,
+ arrowSize, uTrackingPos );
}
}
break;
@@ -686,9 +701,6 @@
{
if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
{
- SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
- SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
- (FARPROC)0 );
#ifdef WINELIB32
SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
(WPARAM)SB_PAGEDOWN, (LPARAM)hwndCtl );
@@ -696,6 +708,9 @@
SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
SB_PAGEDOWN, MAKELONG( 0, hwndCtl ));
#endif
+ SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
+ SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
+ (FARPROC)0 );
}
}
else KillSystemTimer( hwnd, SCROLL_TIMER );
@@ -708,9 +723,6 @@
{
if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
{
- SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
- SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
- (FARPROC)0 );
#ifdef WINELIB32
SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
(WPARAM)SB_LINEDOWN, (LPARAM)hwndCtl );
@@ -718,6 +730,9 @@
SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
SB_LINEDOWN, MAKELONG( 0, hwndCtl ));
#endif
+ SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
+ SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
+ (FARPROC)0 );
}
}
else KillSystemTimer( hwnd, SCROLL_TIMER );
diff --git a/files/file.c b/files/file.c
index 0ba36fd..8ea3d1e 100644
--- a/files/file.c
+++ b/files/file.c
@@ -657,11 +657,6 @@
lstrcpyn( ofs->szPathName, DOSFS_GetDosTrueName( ofs->szPathName, FALSE ),
sizeof(ofs->szPathName) );
- if (mode & OF_PARSE)
- {
- dprintf_file( stddeb, "FILE_Openfile: %s return = 0\n", name);
- return 0;
- }
if (mode & OF_DELETE)
{
if (unlink( unixName ) == -1) goto not_found;
@@ -690,13 +685,18 @@
if (memcmp( ofs->reserved, &st.st_mtime, sizeof(ofs->reserved) ))
{
dprintf_file( stddeb, "FILE_Openfile: %s return = -1\n", name);
+ close( handle );
return -1;
}
}
memcpy( ofs->reserved, &st.st_mtime, sizeof(ofs->reserved) );
}
- if (mode & OF_EXIST) close( handle );
+ if (mode & OF_EXIST)
+ {
+ close( handle );
+ return 0;
+ }
dprintf_file( stddeb, "FILE_Openfile: %s return = %d\n", name,handle);
return handle;
diff --git a/files/profile.c b/files/profile.c
index 9516811..9932328 100644
--- a/files/profile.c
+++ b/files/profile.c
@@ -7,6 +7,7 @@
#include <ctype.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "dos_fs.h"
diff --git a/if1632/relay32.c b/if1632/relay32.c
index 54c1898..a104958 100644
--- a/if1632/relay32.c
+++ b/if1632/relay32.c
@@ -142,7 +142,7 @@
struct w_files *wpnt;
int size;
HMODULE hModule;
- LOADEDFILEINFO *pFileInfo;
+ OFSTRUCT *pFileInfo;
char *pStr;
wpnt=xmalloc(sizeof(struct w_files));
wpnt->hinstance=0;
@@ -151,7 +151,8 @@
wpnt->mz_header=wpnt->pe=0;
size=sizeof(NE_MODULE) +
/* loaded file info */
- sizeof(LOADEDFILEINFO) + strlen(dll->name) +
+ sizeof(*pFileInfo) - sizeof(pFileInfo->szPathName) +
+ strlen(dll->name) + 1 +
/* name table */
12 +
/* several empty tables */
@@ -177,10 +178,11 @@
pModule->fileinfo=sizeof(NE_MODULE);
pModule->os_flags=NE_OSFLAGS_WINDOWS;
pModule->expected_version=0x30A;
- pFileInfo=(LOADEDFILEINFO *)(pModule + 1);
- pFileInfo->length = sizeof(LOADEDFILEINFO)+strlen(dll->name)-1;
- strcpy(pFileInfo->filename,dll->name);
- pStr = ((char*)pFileInfo+pFileInfo->length+1);
+ pFileInfo=(OFSTRUCT *)(pModule + 1);
+ pFileInfo->cBytes = sizeof(*pFileInfo) - sizeof(pFileInfo->szPathName)
+ + strlen(dll->name);
+ strcpy( pFileInfo->szPathName, dll->name );
+ pStr = ((char*)pFileInfo) + pFileInfo->cBytes + 1;
pModule->name_table=(int)pStr-(int)pModule;
*pStr=strlen(dll->name);
strcpy(pStr+1,dll->name);
diff --git a/if1632/user.spec b/if1632/user.spec
index 9d4f57b..4df1c0f 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -280,7 +280,7 @@
275 stub RepaintScreen
276 stub LockMyTask
277 pascal16 GetDlgCtrlID(word) GetDlgCtrlID
-278 pascal16 GetDeskTopHwnd() GetDesktopWindow
+278 pascal16 GetDesktopHwnd() GetDesktopHwnd
279 stub OldSetDeskPattern
280 stub SetSystemMenu
281 pascal16 GetSysColorBrush(word) GetSysColorBrush
diff --git a/if1632/user32.spec b/if1632/user32.spec
index bb36b0b..763352f 100644
--- a/if1632/user32.spec
+++ b/if1632/user32.spec
@@ -181,7 +181,7 @@
0170 stdcall EnableScrollBar(long long long) EnableScrollBar
0171 stdcall EnableWindow(long long) EnableWindow
0172 stub EndDeferWindowPos
-0173 stub EndDialog
+0173 stdcall EndDialog(long long) EndDialog
0174 stub EndMenu
0175 stdcall EndPaint(long ptr) USER32_EndPaint
0176 stub EndTask
@@ -242,8 +242,8 @@
0231 stub GetDesktopWindow
0232 stub GetDialogBaseUnits
0233 stub GetDlgCtrlID
-0234 stub GetDlgItem
-0235 stub GetDlgItemInt
+0234 stdcall GetDlgItem(long long) GetDlgItem
+0235 stdcall GetDlgItemInt(long long long long) GetDlgItemInt
0236 stub GetDlgItemTextA
0237 stub GetDlgItemTextW
0238 stub GetDoubleClickTime
@@ -485,7 +485,7 @@
0473 stub SetCursorPos
0474 stub SetDebugErrorLevel
0475 stub SetDeskWallpaper
-0476 stub SetDlgItemInt
+0476 stdcall SetDlgItemInt(long long long long) SetDlgItemInt
0477 stub SetDlgItemTextA
0478 stub SetDlgItemTextW
0479 stub SetDoubleClickTime
diff --git a/include/callback.h b/include/callback.h
index 1e5649c..4f8b6dd 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -32,6 +32,7 @@
extern LONG CallTo16_long_wwl ( FARPROC, WORD, WORD, WORD, LONG );
extern WORD CallTo16_word_llwl ( FARPROC, WORD, LONG, LONG, WORD, LONG );
extern LONG CallTo16_long_wwwl ( FARPROC, WORD, WORD, WORD, WORD, LONG );
+extern WORD CallTo16_word_lwww ( FARPROC, WORD, LONG, WORD, WORD, WORD );
extern WORD CallTo16_word_wllwl( FARPROC, WORD, WORD, LONG, LONG, WORD, LONG );
extern WORD CallTo16_word_wwlll( FARPROC, WORD, WORD, WORD, LONG, LONG, LONG );
@@ -64,6 +65,8 @@
CallTo16_word_wwlll( func, CURRENT_DS, id, msg, dwUser, dw1, dw2 )
#define CallWndProc( func, ds, hwnd, msg, wParam, lParam ) \
CallTo16_long_wwwl( func, ds, hwnd, msg, wParam, lParam )
+#define CallWordBreakProc( func, lpch, ichCurrent, cch, code ) \
+ CallTo16_word_lwww( func, CURRENT_DS, lpch, ichCurrent, cch, code )
#else /* WINELIB */
@@ -93,6 +96,8 @@
(*func)( id, msg, dwUser, dw1, dw2 )
#define CallWndProc( func, ds, hwnd, msg, wParam, lParam ) \
(*func)( hwnd, msg, wParam, lParam )
+#define CallWordBreakProc( func, lpch, ichCurrent, cch, code ) \
+ (*func)( lpch, ichCurrent, cch, code )
#endif /* WINELIB */
diff --git a/include/module.h b/include/module.h
index 1641754..c19f764 100644
--- a/include/module.h
+++ b/include/module.h
@@ -21,7 +21,7 @@
WORD entry_table; /* Near ptr to entry table */
HMODULE next; /* Selector to next module */
WORD dgroup_entry; /* Near ptr to segment entry for DGROUP */
- WORD fileinfo; /* Near ptr to file info (LOADEDFILEINFO) */
+ WORD fileinfo; /* Near ptr to file info (OFSTRUCT) */
WORD flags; /* Module flags */
WORD dgroup; /* Logical segment for DGROUP */
WORD heap_size; /* Initial heap size */
@@ -51,17 +51,6 @@
WORD self_loading_sel; /* Selector used for self-loading apps. procs */
} NE_MODULE;
- /* Loaded file info */
-typedef struct
-{
- BYTE length; /* Length of the structure, not counting this byte */
- BYTE fixed_media; /* File is on removable media */
- WORD error; /* Error code (?) */
- WORD date; /* File date in MS-DOS format */
- WORD time; /* File time in MS-DOS format */
- char filename[1]; /* File name */
-} LOADEDFILEINFO;
-
/* In-memory segment table */
typedef struct
{
@@ -105,6 +94,9 @@
#define NE_MODULE_TABLE(pModule) \
((WORD *)((char *)(pModule) + (pModule)->modref_table))
+#define NE_MODULE_NAME(pModule) \
+ (((OFSTRUCT *)((char*)(pModule) + (pModule)->fileinfo))->szPathName)
+
#ifndef WINELIB
#pragma pack(4)
#endif
diff --git a/include/options.h b/include/options.h
index 9c89b37..1513a3a 100644
--- a/include/options.h
+++ b/include/options.h
@@ -17,7 +17,8 @@
LANG_Fr, /* French */
LANG_Fi, /* Finnish */
LANG_Da, /* Danish */
- LANG_Cz /* Czech */
+ LANG_Cz, /* Czech */
+ LANG_Eo /* Esperanto */
} WINE_LANGUAGE;
/* Supported modes */
diff --git a/include/wintypes.h b/include/wintypes.h
index 77b33fe..3884f3b 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -138,9 +138,11 @@
#define FALSE 0
#define CW_USEDEFAULT ((INT)0x8000)
#define FAR
+#define _far
#define NEAR
#define _near
#define PASCAL
+#define _pascal
#define VOID void
#define WINAPI PASCAL
#define CALLBACK PASCAL
diff --git a/include/xmalloc.h b/include/xmalloc.h
index 396fde0..f054edd 100644
--- a/include/xmalloc.h
+++ b/include/xmalloc.h
@@ -1,14 +1,8 @@
#ifndef __WINE_XMALLOC_H
#define __WINE_XMALLOC_H
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#else
-#define size_t unsigned int
-#endif
-
-void *xmalloc (size_t);
-void *xrealloc (void *, size_t);
-char *xstrdup( const char * );
+void *xmalloc( int size );
+void *xrealloc( void *ptr, int size );
+char *xstrdup( const char *str );
#endif /* __WINE_XMALLOC_H */
diff --git a/loader/module.c b/loader/module.c
index e97c806..f9dd6fe 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -27,6 +27,8 @@
#include "callback.h"
#include "wine.h"
+extern HINSTANCE PE_LoadModule( int fd, OFSTRUCT *ofs, LOADPARAMS* params );
+
static HMODULE hFirstModule = 0;
static HMODULE hCachedModule = 0; /* Module cached by MODULE_OpenFile */
@@ -145,8 +147,7 @@
/* Dump the file info */
- printf( "Filename: '%s'\n",
- ((LOADEDFILEINFO *)((BYTE *)pModule + pModule->fileinfo))->filename );
+ printf( "Filename: '%s'\n", NE_MODULE_NAME(pModule) );
/* Dump the segment table */
@@ -269,7 +270,7 @@
if (hCachedModule == hModule) return cachedfd;
close( cachedfd );
hCachedModule = hModule;
- name = ((LOADEDFILEINFO*)((char*)pModule + pModule->fileinfo))->filename;
+ name = NE_MODULE_NAME( pModule );
if (!(unixName = DOSFS_GetUnixFileName( name, TRUE )) ||
(cachedfd = open( unixName, O_RDONLY )) == -1)
fprintf( stderr, "MODULE_OpenFile: can't open file '%s' for module "NPFMT"\n",
@@ -444,7 +445,7 @@
size = sizeof(NE_MODULE) +
/* loaded file info */
- sizeof(LOADEDFILEINFO) + strlen(ofs->szPathName) +
+ sizeof(OFSTRUCT)-sizeof(ofs->szPathName)+strlen(ofs->szPathName)+1+
/* segment table */
ne_header.n_segment_tab * sizeof(SEGTABLEENTRY) +
/* resource table */
@@ -488,13 +489,10 @@
/* Store the filename information */
pModule->fileinfo = (int)pData - (int)pModule;
- ((LOADEDFILEINFO*)pData)->length = sizeof(LOADEDFILEINFO)+strlen(ofs->szPathName);
- ((LOADEDFILEINFO*)pData)->fixed_media = TRUE;
- ((LOADEDFILEINFO*)pData)->error = 0;
- ((LOADEDFILEINFO*)pData)->date = 0;
- ((LOADEDFILEINFO*)pData)->time = 0;
- strcpy( ((LOADEDFILEINFO*)pData)->filename, ofs->szPathName );
- pData += ((LOADEDFILEINFO*)pData)->length--;
+ size = sizeof(OFSTRUCT)-sizeof(ofs->szPathName)+strlen(ofs->szPathName)+1;
+ memcpy( pData, ofs, size );
+ ((OFSTRUCT *)pData)->cBytes = size - 1;
+ pData += size;
/* Get the segment table */
@@ -845,7 +843,7 @@
{
NE_MODULE *pModule = (NE_MODULE *)GlobalLock( hModule );
if (!pModule) break;
- modulepath = ((LOADEDFILEINFO*)((char*)pModule + pModule->fileinfo))->filename;
+ modulepath = NE_MODULE_NAME(pModule);
if (!(modulename = strrchr( modulepath, '\\' )))
modulename = modulepath;
else modulename++;
@@ -916,8 +914,6 @@
}
-HINSTANCE PE_LoadModule(int fd, OFSTRUCT *ofs, LOADPARAMS* params);
-
/**********************************************************************
* LoadModule (KERNEL.45)
*/
@@ -1194,12 +1190,10 @@
int GetModuleFileName( HANDLE hModule, LPSTR lpFileName, short nSize )
{
NE_MODULE *pModule;
- char *name;
hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
- name = ((LOADEDFILEINFO*)((char*)pModule + pModule->fileinfo))->filename;
- lstrcpyn( lpFileName, name, nSize );
+ lstrcpyn( lpFileName, NE_MODULE_NAME(pModule), nSize );
dprintf_module( stddeb, "GetModuleFilename: %s\n", lpFileName );
return strlen(lpFileName);
}
@@ -1405,9 +1399,7 @@
lpme->szModule[MAX_MODULE_NAME] = '\0';
lpme->hModule = lpme->wNext;
lpme->wcUsage = pModule->count;
- strncpy( lpme->szExePath,
- ((LOADEDFILEINFO*)((char*)pModule + pModule->fileinfo))->filename,
- MAX_PATH );
+ strncpy( lpme->szExePath, NE_MODULE_NAME(pModule), MAX_PATH );
lpme->szExePath[MAX_PATH] = '\0';
lpme->wNext = pModule->next;
return TRUE;
diff --git a/loader/ne_resource.c b/loader/ne_resource.c
index 5eee682..add76cf 100644
--- a/loader/ne_resource.c
+++ b/loader/ne_resource.c
@@ -240,7 +240,6 @@
{
NE_MODULE *pModule;
NE_NAMEINFO *pNameInfo=NULL;
- char *name;
int fd;
pModule = (NE_MODULE *)GlobalLock( hModule );
@@ -249,8 +248,7 @@
pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc);
#endif
- name = ((LOADEDFILEINFO*)((char*)pModule + pModule->fileinfo))->filename;
- if ((fd = _lopen( name, OF_READ )) != -1)
+ if ((fd = _lopen( NE_MODULE_NAME(pModule), OF_READ )) != -1)
{
WORD sizeShift = *(WORD *)((char *)pModule + pModule->res_table);
_llseek( fd, (int)pNameInfo->offset << sizeShift, SEEK_SET );
diff --git a/loader/pe_image.c b/loader/pe_image.c
index 5abdeae..9d68504 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -536,12 +536,11 @@
HINSTANCE MODULE_CreateInstance(HMODULE hModule,LOADPARAMS *params);
void InitTask(struct sigcontext_struct context);
-HINSTANCE PE_LoadModule(int fd, OFSTRUCT *ofs, LOADPARAMS* params)
+HINSTANCE PE_LoadModule( int fd, OFSTRUCT *ofs, LOADPARAMS* params )
{
struct w_files *wpnt;
- int size;
+ int size, of_size;
NE_MODULE *pModule;
- LOADEDFILEINFO *pFileInfo;
SEGTABLEENTRY *pSegment;
char *pStr;
DWORD cts;
@@ -561,15 +560,17 @@
wpnt->mz_header=xmalloc(sizeof(struct mz_header_s));
read(fd,wpnt->mz_header,sizeof(struct mz_header_s));
- size=sizeof(NE_MODULE) +
- /* loaded file info */
- sizeof(LOADEDFILEINFO) + strlen(ofs->szPathName) +
- /* segment table: DS,CS */
- 2 * sizeof(SEGTABLEENTRY) +
- /* name table */
- 9 +
- /* several empty tables */
- 8;
+ of_size = sizeof(OFSTRUCT) - sizeof(ofs->szPathName)
+ + strlen(ofs->szPathName) + 1;
+ size = sizeof(NE_MODULE) +
+ /* loaded file info */
+ of_size +
+ /* segment table: DS,CS */
+ 2 * sizeof(SEGTABLEENTRY) +
+ /* name table */
+ 9 +
+ /* several empty tables */
+ 8;
hModule = GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, size );
wpnt->hModule=hModule;
@@ -593,17 +594,16 @@
pModule->seg_count=1;
pModule->modref_count=0;
pModule->nrname_size=0;
- pModule->seg_table=sizeof(NE_MODULE)+
- sizeof(LOADEDFILEINFO)+strlen(ofs->szPathName);
+ pModule->seg_table=sizeof(NE_MODULE) + of_size;
pModule->fileinfo=sizeof(NE_MODULE);
pModule->os_flags=NE_OSFLAGS_WINDOWS;
pModule->expected_version=0x30A;
- pFileInfo=(LOADEDFILEINFO *)(pModule + 1);
- pFileInfo->length = sizeof(LOADEDFILEINFO)+strlen(ofs->szPathName)-1;
- strcpy(pFileInfo->filename,ofs->szPathName);
+ /* Set loaded file information */
+ memcpy( pModule + 1, ofs, of_size );
+ ((OFSTRUCT *)(pModule+1))->cBytes = of_size - 1;
- pSegment=(SEGTABLEENTRY*)((char*)pFileInfo+pFileInfo->length+1);
+ pSegment=(SEGTABLEENTRY*)((char*)(pModule + 1) + of_size);
pModule->dgroup_entry=(int)pSegment-(int)pModule;
pSegment->size=0;
pSegment->flags=NE_SEGFLAGS_DATA;
diff --git a/loader/task.c b/loader/task.c
index 08d730c..e721cf1 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -611,6 +611,8 @@
*/
void TASK_KillCurrentTask( int exitCode )
{
+ extern void EXEC_ExitWindows( int retCode );
+
if (hTaskToKill && (hTaskToKill != hCurrentTask))
{
/* If another task is already marked for destruction, */
@@ -621,7 +623,7 @@
if (nTaskCount <= 1)
{
dprintf_task( stddeb, "Killing the last task, exiting\n" );
- ExitWindows( 0, 0 );
+ EXEC_ExitWindows( 0 );
}
/* Remove the task from the list to be sure we never switch back to it */
diff --git a/memory/atom.c b/memory/atom.c
index 0e42c92..fe807cd 100644
--- a/memory/atom.c
+++ b/memory/atom.c
@@ -92,6 +92,8 @@
{
if (!create) return NULL;
if (!ATOM_InitTable( selector, DEFAULT_ATOMTABLE_SIZE )) return NULL;
+ /* Reload ptr in case it moved in linear memory */
+ ptr = (INSTANCEDATA *)PTR_SEG_OFF_TO_LIN( selector, 0 );
}
return (ATOMTABLE *)((char *)ptr + ptr->atomtable);
}
@@ -156,6 +158,8 @@
entry = LOCAL_Alloc( selector, LMEM_FIXED, sizeof(ATOMENTRY)+len-1 );
if (!entry) return 0;
+ /* Reload the table ptr in case it moved in linear memory */
+ table = ATOM_GetTable( selector, FALSE );
entryPtr = ATOM_MakePtr( selector, entry );
entryPtr->next = table->entries[hash];
entryPtr->refCount = 1;
diff --git a/misc/exec.c b/misc/exec.c
index 6cc85b3..6def5ad 100644
--- a/misc/exec.c
+++ b/misc/exec.c
@@ -14,6 +14,7 @@
#include "callback.h"
#include "stddebug.h"
#include "debug.h"
+#include "win.h"
#define HELP_CONTEXT 0x0001
#define HELP_QUIT 0x0002
@@ -31,23 +32,82 @@
#define HELP_SETWINPOS 0x0203
-/**********************************************************************
- * ExitWindows [USER.7]
+/***********************************************************************
+ * EXEC_ExitWindows
+ *
+ * Clean-up everything and exit the Wine process.
+ * This is the back-end of ExitWindows(), called when all windows
+ * have agreed to be terminated.
*/
-BOOL ExitWindows(DWORD dwReturnCode, WORD wReserved)
+void EXEC_ExitWindows( int retCode )
{
- api_assert("ExitWindows", wReserved == 0);
- api_assert("ExitWindows", HIWORD(dwReturnCode) == 0);
-
- dprintf_exec( stdnimp,"PARTIAL STUB ExitWindows(%08lX, %04X)\n",
- dwReturnCode, wReserved);
-
/* Do the clean-up stuff */
WriteOutProfiles();
SHELL_SaveRegistry();
- exit( LOWORD(dwReturnCode) );
+ exit( retCode );
+}
+
+
+/***********************************************************************
+ * ExitWindows (USER.7)
+ */
+BOOL ExitWindows( DWORD dwReturnCode, WORD wReserved )
+{
+ HWND hwnd, hwndDesktop;
+ WND *wndPtr;
+ HWND *list, *pWnd;
+ int count, i;
+ BOOL result;
+
+ api_assert("ExitWindows", wReserved == 0);
+ api_assert("ExitWindows", HIWORD(dwReturnCode) == 0);
+
+ /* We have to build a list of all windows first, as in EnumWindows */
+
+ /* First count the windows */
+
+ hwndDesktop = GetDesktopWindow();
+ count = 0;
+ for (hwnd = GetTopWindow(hwndDesktop); hwnd != 0; hwnd = wndPtr->hwndNext)
+ {
+ if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
+ count++;
+ }
+ if (!count) /* No windows, we can exit at once */
+ EXEC_ExitWindows( LOWORD(dwReturnCode) );
+
+ /* Now build the list of all windows */
+
+ if (!(list = (HWND *)malloc( sizeof(HWND) * count ))) return FALSE;
+ for (hwnd = GetTopWindow(hwndDesktop), pWnd = list; hwnd != 0; hwnd = wndPtr->hwndNext)
+ {
+ wndPtr = WIN_FindWndPtr( hwnd );
+ *pWnd++ = hwnd;
+ }
+
+ /* Now send a WM_QUERYENDSESSION message to every window */
+
+ for (pWnd = list, i = 0; i < count; i++, pWnd++)
+ {
+ /* Make sure that window still exists */
+ if (!IsWindow(*pWnd)) continue;
+ if (!SendMessage( *pWnd, WM_QUERYENDSESSION, 0, 0 )) break;
+ }
+ result = (i == count);
+
+ /* Now notify all windows that got a WM_QUERYENDSESSION of the result */
+
+ for (pWnd = list; i > 0; i--, pWnd++)
+ {
+ if (!IsWindow(*pWnd)) continue;
+ SendMessage( *pWnd, WM_ENDSESSION, result, 0 );
+ }
+ free( list );
+
+ if (result) EXEC_ExitWindows( LOWORD(dwReturnCode) );
+ return FALSE;
}
diff --git a/misc/main.c b/misc/main.c
index c7a6afa..eb19885 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -56,6 +56,7 @@
"Fi", /* LANG_Fi */
"Da", /* LANG_Da */
"Cz", /* LANG_Cz */
+ "Eo", /* LANG_Eo */
NULL
};
@@ -138,7 +139,7 @@
" -fixedmap Use a \"standard\" color map\n" \
" -iconic Start as an icon\n" \
" -ipc Enable IPC facilities\n" \
- " -language xx Set the language (one of En,Es,De,No,Fr,Fi,Da,Cz)\n" \
+ " -language xx Set the language (one of En,Es,De,No,Fr,Fi,Da,Cz,Eo)\n" \
" -managed Allow the window manager to manage created windows\n" \
" -mode mode Start Wine in a particular mode (standard or enhanced)\n" \
" -name name Set the application name\n" \
@@ -460,6 +461,7 @@
XClassHint *class_hints;
XSetWindowAttributes win_attr;
XTextProperty window_name;
+ Atom XA_WM_DELETE_WINDOW;
flags = XParseGeometry( Options.desktopGeometry,
&desktopX, &desktopY, &width, &height );
@@ -505,6 +507,8 @@
XStringListToTextProperty( &name, 1, &window_name );
XSetWMProperties( display, rootWindow, &window_name, &window_name,
argv, argc, size_hints, wm_hints, class_hints );
+ XA_WM_DELETE_WINDOW = XInternAtom( display, "WM_DELETE_WINDOW", False );
+ XSetWMProtocols( display, rootWindow, &XA_WM_DELETE_WINDOW, 1 );
XFree( size_hints );
XFree( wm_hints );
XFree( class_hints );
diff --git a/misc/ole2nls.c b/misc/ole2nls.c
index 500a3f2..51cd354 100644
--- a/misc/ole2nls.c
+++ b/misc/ole2nls.c
@@ -31,6 +31,7 @@
case LANG_Fi:
case LANG_Da:
case LANG_Cz:
+ case LANG_Eo:
default:
return 0; /* Neutral language */
}
@@ -421,6 +422,108 @@
/* LOCVAL(LOCALE_INEGSEPBYSPACE) */
break; /* LANG(Da) */
+ case LANG_Eo:
+/* LOCVAL(LOCALE_ILANGUAGE,"9") ISO numerical ID for language TODO */
+LOCVAL(LOCALE_SLANGUAGE,"Esperanto")
+LOCVAL(LOCALE_SENGLANGUAGE,"Esperanto")
+/* LOCVAL(LOCALE_SABBREVLANGNAME,"deu") */
+LOCVAL(LOCALE_SNATIVELANGNAME,"Esperanto")
+/* LOCVAL(LOCALE_ICOUNTRY,"49") not official in any one country */
+/* LOCVAL(LOCALE_SCOUNTRY,"Deutschland") */
+/* LOCVAL(LOCALE_SENGCOUNTRY,"Germany") */
+/* LOCVAL(LOCALE_SABBREVCTRYNAME,"De") */
+/* LOCVAL(LOCALE_SNATIVECTRYNAME,"Deutschland") */
+/* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"9") ISO ID of lang TODO */
+/* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"49") */
+LOCVAL(LOCALE_IDEFAULTCODEPAGE,3) /* is this right? TODO */
+LOCVAL(LOCALE_IDEFAULTANSICODEPAGE,3) /* is this right? TODO */
+LOCVAL(LOCALE_SLIST,";")
+LOCVAL(LOCALE_IMEASURE,"0")
+LOCVAL(LOCALE_SDECIMAL,",")
+LOCVAL(LOCALE_STHOUSAND,".")
+/* LOCVAL(LOCALE_SGROUPING) */
+LOCVAL(LOCALE_IDIGITS,"2")
+LOCVAL(LOCALE_ILZERO,"1")
+/* LOCVAL(LOCALE_INEGNUMBER) */
+/* LOCVAL(LOCALE_SNATIVEDIGITS) */
+LOCVAL(LOCALE_SCURRENCY,"NLG") /* accounting currency of UEA */
+/* LOCVAL(LOCALE_SINTLSYMBOL) */
+/* LOCVAL(LOCALE_SMONDECIMALSEP) */
+/* LOCVAL(LOCALE_SMONTHOUSANDSEP) */
+/* LOCVAL(LOCALE_SMONGROUPING) */
+/* LOCVAL(LOCALE_ICURRDIGITS,"2") */
+/* LOCVAL(LOCALE_IINTLCURRDIGITS) */
+LOCVAL(LOCALE_ICURRENCY,"3")
+LOCVAL(LOCALE_INEGCURR,"8")
+LOCVAL(LOCALE_SDATE,".")
+LOCVAL(LOCALE_STIME,":")
+LOCVAL(LOCALE_SSHORTDATE,"yyyy.mm.dd")
+LOCVAL(LOCALE_SLONGDATE,"ddd, d. MMMM yyyy")
+/* LOCVAL(LOCALE_STIMEFORMAT) */
+LOCVAL(LOCALE_IDATE,"1")
+/* LOCVAL(LOCALE_ILDATE) */
+LOCVAL(LOCALE_ITIME,"1")
+/* LOCVAL(LOCALE_ITIMEMARKPOSN) */
+/* LOCVAL(LOCALE_ICENTURY) */
+LOCVAL(LOCALE_ITLZERO,"1")
+/* LOCVAL(LOCALE_IDAYLZERO) */
+/* LOCVAL(LOCALE_IMONLZERO) */
+/* LOCVAL(LOCALE_S1159) */
+/* LOCVAL(LOCALE_S2359) */
+/* LOCVAL(LOCALE_ICALENDARTYPE) */
+/* LOCVAL(LOCALE_IOPTIONALCALENDAR) */
+/* LOCVAL(LOCALE_IFIRSTDAYOFWEEK) */
+/* LOCVAL(LOCALE_IFIRSTWEEKOFYEAR) */
+LOCVAL(LOCALE_SDAYNAME1,"lundo")
+LOCVAL(LOCALE_SDAYNAME2,"mardo")
+LOCVAL(LOCALE_SDAYNAME3,"merkredo")
+LOCVAL(LOCALE_SDAYNAME4,"¼aýdo")
+LOCVAL(LOCALE_SDAYNAME5,"vendredo")
+LOCVAL(LOCALE_SDAYNAME6,"sabato")
+LOCVAL(LOCALE_SDAYNAME7,"dimanæo")
+LOCVAL(LOCALE_SABBREVDAYNAME1,"lu")
+LOCVAL(LOCALE_SABBREVDAYNAME2,"ma")
+LOCVAL(LOCALE_SABBREVDAYNAME3,"me")
+LOCVAL(LOCALE_SABBREVDAYNAME4,"¼a")
+LOCVAL(LOCALE_SABBREVDAYNAME5,"ve")
+LOCVAL(LOCALE_SABBREVDAYNAME6,"sa")
+LOCVAL(LOCALE_SABBREVDAYNAME7,"di")
+LOCVAL(LOCALE_SMONTHNAME1,"januaro")
+LOCVAL(LOCALE_SMONTHNAME2,"februaro")
+LOCVAL(LOCALE_SMONTHNAME3,"marto")
+LOCVAL(LOCALE_SMONTHNAME4,"aprilo")
+LOCVAL(LOCALE_SMONTHNAME5,"majo")
+LOCVAL(LOCALE_SMONTHNAME6,"junio")
+LOCVAL(LOCALE_SMONTHNAME7,"julio")
+LOCVAL(LOCALE_SMONTHNAME8,"aýgusto")
+LOCVAL(LOCALE_SMONTHNAME9,"septembro")
+LOCVAL(LOCALE_SMONTHNAME10,"oktobro")
+LOCVAL(LOCALE_SMONTHNAME11,"novembro")
+LOCVAL(LOCALE_SMONTHNAME12,"decembro")
+LOCVAL(LOCALE_SMONTHNAME13,"")
+LOCVAL(LOCALE_SABBREVMONTHNAME1,"jan")
+LOCVAL(LOCALE_SABBREVMONTHNAME2,"feb")
+LOCVAL(LOCALE_SABBREVMONTHNAME3,"mar")
+LOCVAL(LOCALE_SABBREVMONTHNAME4,"apr")
+LOCVAL(LOCALE_SABBREVMONTHNAME5,"maj")
+LOCVAL(LOCALE_SABBREVMONTHNAME6,"jun")
+LOCVAL(LOCALE_SABBREVMONTHNAME7,"jul")
+LOCVAL(LOCALE_SABBREVMONTHNAME8,"aýg")
+LOCVAL(LOCALE_SABBREVMONTHNAME9,"sep")
+LOCVAL(LOCALE_SABBREVMONTHNAME10,"okt")
+LOCVAL(LOCALE_SABBREVMONTHNAME11,"nov")
+LOCVAL(LOCALE_SABBREVMONTHNAME12,"dec")
+LOCVAL(LOCALE_SABBREVMONTHNAME13,"")
+/* LOCVAL(LOCALE_SPOSITIVESIGN) */
+/* LOCVAL(LOCALE_SNEGATIVESIGN) */
+/* LOCVAL(LOCALE_IPOSSIGNPOSN) */
+/* LOCVAL(LOCALE_INEGSIGNPOSN) */
+/* LOCVAL(LOCALE_IPOSSYMPRECEDES) */
+/* LOCVAL(LOCALE_IPOSSEPBYSPACE) */
+/* LOCVAL(LOCALE_INEGSYMPRECEDES) */
+/* LOCVAL(LOCALE_INEGSEPBYSPACE) */
+ break; /* LANG(Eo) */
+
/*Insert other languages here*/
default:
diff --git a/misc/xmalloc.c b/misc/xmalloc.c
index d79bd20..0765edf 100644
--- a/misc/xmalloc.c
+++ b/misc/xmalloc.c
@@ -14,11 +14,11 @@
*/
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "xmalloc.h"
-void *
-xmalloc (size_t size)
+void *xmalloc( int size )
{
void *res;
@@ -32,8 +32,7 @@
}
-void *
-xrealloc (void *ptr, size_t size)
+void *xrealloc( void *ptr, int size )
{
void *res = realloc (ptr, size);
if (res == NULL)
diff --git a/programs/Makefile.in b/programs/Makefile.in
new file mode 100644
index 0000000..a954a5f
--- /dev/null
+++ b/programs/Makefile.in
@@ -0,0 +1,14 @@
+SUBDIRS = progman
+
+all: $(SUBDIRS)
+
+$(SUBDIRS): dummy
+ @cd $@; $(MAKE)
+
+depend:
+ for i in $(SUBDIRS); do (cd $$i; $(MAKE) depend); done
+
+clean:
+ for i in $(SUBDIRS); do (cd $$i; $(MAKE) clean); done
+
+dummy:
diff --git a/programs/progman/ChangeLog b/programs/progman/ChangeLog
new file mode 100644
index 0000000..7a14e2d
--- /dev/null
+++ b/programs/progman/ChangeLog
@@ -0,0 +1,6 @@
+Wed Feb 28 19:21:55 1996 Ulrich Schmid <uschmid@mail.hh.provi.de>
+
+ * [progman.h] [main.c] [group.c] [program.c] [dialog.c]
+ [grpfile.c] [string.c] [winexec.c] [license.h] [license.c] [Xx.rc]
+ [accel.rc] [En.rc] [Strings_En.c] [License_En.c] [De.rc]
+ [Strings_De.c] Original by Ulrich Schmid
diff --git a/programs/progman/De.rc b/programs/progman/De.rc
new file mode 100644
index 0000000..9284517
--- /dev/null
+++ b/programs/progman/De.rc
@@ -0,0 +1,93 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+/* Menu */
+
+#define MENU_Xx MENU_De
+
+#define MENU_FILE "&Datei"
+#define MENU_FILE_NEW "&Neu..."
+#define MENU_FILE_OPEN "Ö&ffnen\tEingabetaste"
+#define MENU_FILE_MOVE "&Verschieben...\tF7"
+#define MENU_FILE_COPY "&Kopieren...\tF8"
+#define MENU_FILE_DELETE "&Löschen\tEntf"
+#define MENU_FILE_ATTRIBUTES "&Eigenschaften...\tAlt+Eingabetaste"
+#define MENU_FILE_EXECUTE "&Ausführen..."
+#define MENU_FILE_EXIT "&Programm-Manager &beenden..."
+
+#define MENU_OPTIONS "&Optionen"
+#define MENU_OPTIONS_AUTO_ARRANGE "&Automatisch anordnen"
+#define MENU_OPTIONS_MIN_ON_RUN "&Symbol nach Programmstart"
+#define MENU_OPTIONS_SAVE_SETTINGS "&Einstellungen beim Beenden speichern"
+
+#define MENU_WINDOWS "&Fenster"
+#define MENU_WINDOWS_OVERLAP "Über&lappend\tUmschalt+F5"
+#define MENU_WINDOWS_SIDE_BY_SIDE "&Nebeneinander\tUmschalt+F4"
+#define MENU_WINDOWS_ARRANGE "&Symbole anordnen"
+
+#define MENU_LANGUAGE "&Sprache"
+
+#define MENU_HELP "&Hilfe"
+#define MENU_HELP_CONTENTS "&Inhalt"
+#define MENU_HELP_SEARCH "&Suchen..."
+#define MENU_HELP_HELP_ON_HELP "&Hilfe benutzen"
+#define MENU_HELP_TUTORIAL "&Lernprogramm"
+
+#define MENU_INFO "Inf&o..."
+#define MENU_INFO_LICENSE "&Lizenz"
+#define MENU_INFO_NO_WARRANTY "&KEINE GARANTIE"
+#define MENU_INFO_ABOUT_WINE "&Über WINE"
+
+/* Dialogs */
+
+#define DIALOG_OK "OK"
+#define DIALOG_CANCEL "Abbrechen"
+#define DIALOG_BROWSE "&Durchsuchen..."
+#define DIALOG_HELP "&Hilfe"
+
+#define DIALOG_NEW_Xx DIALOG_NEW_De
+#define DIALOG_NEW_CAPTION "Neues Programmobject"
+#define DIALOG_NEW_NEW "Neu"
+#define DIALOG_NEW_GROUP "Programmgrupp&e"
+#define DIALOG_NEW_PROGRAM "&Programm"
+
+#define DIALOG_MOVE_Xx DIALOG_MOVE_De
+#define DIALOG_MOVE_CAPTION "Programm verschieben"
+#define DIALOG_MOVE_PROGRAM "Verschiebe Programm:"
+#define DIALOG_MOVE_FROM_GROUP "Von Programmgruppe:"
+#define DIALOG_MOVE_TO_GROUP "&In Gruppe:"
+
+#define DIALOG_COPY_Xx DIALOG_COPY_De
+#define DIALOG_COPY_CAPTION "Programm kopieren"
+#define DIALOG_COPY_PROGRAM "Kopiere Programm:"
+#define DIALOG_COPY_FROM_GROUP DIALOG_MOVE_FROM_GROUP
+#define DIALOG_COPY_TO_GROUP DIALOG_MOVE_TO_GROUP
+
+#define DIALOG_GROUP_Xx DIALOG_GROUP_De
+#define DIALOG_GROUP_CAPTION "Programmgruppeneigenschaften"
+#define DIALOG_GROUP_DESCRIPTION "&Beschreibung:"
+#define DIALOG_GROUP_FILE "&Gruppendatei:"
+
+#define DIALOG_PROGRAM_Xx DIALOG_PROGRAM_De
+#define DIALOG_PROGRAM_CAPTION "Programmeigenschaften"
+#define DIALOG_PROGRAM_DESCRIPTION DIALOG_GROUP_DESCRIPTION
+#define DIALOG_PROGRAM_COMMAND_LINE "Befehls&zeile:"
+#define DIALOG_PROGRAM_DIRECTORY "&Arbeitsverzeichnis:"
+#define DIALOG_PROGRAM_HOT_KEY "&Tastenkombination:"
+#define DIALOG_PROGRAM_SYMBOL "Als Sy&mbol"
+#define DIALOG_PROGRAM_OTHER_SYMBOL "Anderes &Symbol..."
+
+#define DIALOG_SYMBOL_Xx DIALOG_SYMBOL_De
+#define DIALOG_SYMBOL_CAPTION "Symbol auswählen"
+#define DIALOG_SYMBOL_FILE "Datei&name:"
+#define DIALOG_SYMBOL_CURRENT "&Aktuelles Symbol:"
+
+#define DIALOG_EXECUTE_Xx DIALOG_EXECUTE_De
+#define DIALOG_EXECUTE_CAPTION "Programm Ausführen"
+#define DIALOG_EXECUTE_COMMAND_LINE DIALOG_PROGRAM_COMMAND_LINE
+#define DIALOG_EXECUTE_SYMBOL DIALOG_PROGRAM_SYMBOL
+
+#include "Xx.rc"
diff --git a/programs/progman/En.rc b/programs/progman/En.rc
new file mode 100644
index 0000000..97fb14b
--- /dev/null
+++ b/programs/progman/En.rc
@@ -0,0 +1,93 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+/* Menu */
+
+#define MENU_Xx MENU_En
+
+#define MENU_FILE "&File"
+#define MENU_FILE_NEW "&New..."
+#define MENU_FILE_OPEN "O&pen\tEnter"
+#define MENU_FILE_MOVE "&Move...\tF7"
+#define MENU_FILE_COPY "&Copy...\tF8"
+#define MENU_FILE_DELETE "&Delete\tEntf"
+#define MENU_FILE_ATTRIBUTES "&Attributes...\tAlt+Enter"
+#define MENU_FILE_EXECUTE "&Execute..."
+#define MENU_FILE_EXIT "E&xit Windows..."
+
+#define MENU_OPTIONS "&Options"
+#define MENU_OPTIONS_AUTO_ARRANGE "&Arrange automatically"
+#define MENU_OPTIONS_MIN_ON_RUN "&Minimize on run"
+#define MENU_OPTIONS_SAVE_SETTINGS "&Save settings on exit"
+
+#define MENU_WINDOWS "&Windows"
+#define MENU_WINDOWS_OVERLAP "&Overlapped\tShift+F5"
+#define MENU_WINDOWS_SIDE_BY_SIDE "&Side by side\tShift+F4"
+#define MENU_WINDOWS_ARRANGE "&Arrange Symbols"
+
+#define MENU_LANGUAGE "&Language"
+
+#define MENU_HELP "&Help"
+#define MENU_HELP_CONTENTS "&Contents"
+#define MENU_HELP_SEARCH "&Search..."
+#define MENU_HELP_HELP_ON_HELP "&Help on Help"
+#define MENU_HELP_TUTORIAL "&Tutorial"
+
+#define MENU_INFO "&Info..."
+#define MENU_INFO_LICENSE "&License"
+#define MENU_INFO_NO_WARRANTY "&NO WARRANTY"
+#define MENU_INFO_ABOUT_WINE "&About WINE"
+
+/* Dialogs */
+
+#define DIALOG_OK "OK"
+#define DIALOG_CANCEL "Cancel"
+#define DIALOG_BROWSE "&Browse"
+#define DIALOG_HELP "&Help"
+
+#define DIALOG_NEW_Xx DIALOG_NEW_En
+#define DIALOG_NEW_CAPTION "New Program Object"
+#define DIALOG_NEW_NEW "New"
+#define DIALOG_NEW_GROUP "Program &group"
+#define DIALOG_NEW_PROGRAM "&Program"
+
+#define DIALOG_MOVE_Xx DIALOG_MOVE_En
+#define DIALOG_MOVE_CAPTION "Move Program"
+#define DIALOG_MOVE_PROGRAM "Move program:"
+#define DIALOG_MOVE_FROM_GROUP "From group:"
+#define DIALOG_MOVE_TO_GROUP "&To group:"
+
+#define DIALOG_COPY_Xx DIALOG_COPY_En
+#define DIALOG_COPY_CAPTION "Copy Program"
+#define DIALOG_COPY_PROGRAM "Copy program:"
+#define DIALOG_COPY_FROM_GROUP DIALOG_MOVE_FROM_GROUP
+#define DIALOG_COPY_TO_GROUP DIALOG_MOVE_TO_GROUP
+
+#define DIALOG_GROUP_Xx DIALOG_GROUP_En
+#define DIALOG_GROUP_CAPTION "Program Group Attributes"
+#define DIALOG_GROUP_DESCRIPTION "&Description:"
+#define DIALOG_GROUP_FILE "&Group file:"
+
+#define DIALOG_PROGRAM_Xx DIALOG_PROGRAM_En
+#define DIALOG_PROGRAM_CAPTION "Program Attributes"
+#define DIALOG_PROGRAM_DESCRIPTION DIALOG_GROUP_DESCRIPTION
+#define DIALOG_PROGRAM_COMMAND_LINE "&Command line:"
+#define DIALOG_PROGRAM_DIRECTORY "&Working directory:"
+#define DIALOG_PROGRAM_HOT_KEY "&Key combination:"
+#define DIALOG_PROGRAM_SYMBOL "As &Symbol"
+#define DIALOG_PROGRAM_OTHER_SYMBOL "&Other Symbol..."
+
+#define DIALOG_SYMBOL_Xx DIALOG_SYMBOL_En
+#define DIALOG_SYMBOL_CAPTION "Select Symbol"
+#define DIALOG_SYMBOL_FILE "&Filename:"
+#define DIALOG_SYMBOL_CURRENT "&Current Symbol:"
+
+#define DIALOG_EXECUTE_Xx DIALOG_EXECUTE_En
+#define DIALOG_EXECUTE_CAPTION "Execute Program"
+#define DIALOG_EXECUTE_COMMAND_LINE DIALOG_PROGRAM_COMMAND_LINE
+#define DIALOG_EXECUTE_SYMBOL DIALOG_PROGRAM_SYMBOL
+
+#include "Xx.rc"
diff --git a/programs/progman/License_En.c b/programs/progman/License_En.c
new file mode 100644
index 0000000..efe3437
--- /dev/null
+++ b/programs/progman/License_En.c
@@ -0,0 +1,47 @@
+#include <windows.h>
+#include "license.h"
+
+static CHAR LicenseCaption_En[] = "LICENSE";
+static CHAR License_En[] = "\
+You may without charge, royalty or other payment, copy and\
+ distribute copies of this work and derivative works of this work\
+ in source or binary form provided that: (1)\
+ you appropriately publish on each copy an appropriate copyright\
+ notice; (2) faithfully reproduce all prior copyright notices\
+ included in the original work (you may also add your own\
+ copyright notice); and (3) agree to indemnify and hold all prior\
+ authors, copyright holders and licensors of the work harmless\
+ from and against all damages arising from use of the work.\
+\n\
+You may distribute sources of derivative works of the work\
+ provided that (1) (a) all source files of the original work that\
+ have been modified, (b) all source files of the derivative work\
+ that contain any party of the original work, and (c) all source\
+ files of the derivative work that are necessary to compile, link\
+ and run the derivative work without unresolved external calls and\
+ with the same functionality of the original work (\"Necessary\
+ Sources\") carry a prominent notice explaining the nature and date\
+ of the modification and/or creation. You are encouraged to make\
+ the Necessary Sources available under this license in order to\
+ further the development and acceptance of the work.\
+\n\
+EXCEPT AS OTHERWISE RESTRICTED BY LAW, THIS WORK IS PROVIDED\
+ WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND, INCLUDING\
+ BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF FITNESS FOR A\
+ PARTICULAR PURPOSE, MERCHANTABILITY OR TITLE. EXCEPT AS\
+ OTHERWISE PROVIDED BY LAW, NO AUTHOR, COPYRIGHT HOLDER OR\
+ LICENSOR SHALL BE LIABLE TO YOU FOR DAMAGES OF ANY KIND, EVEN IF\
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.";
+
+static CHAR NoWarrantyCaption_En[] = "NO WARRANTY";
+static CHAR NoWarranty_En[] = "\
+EXCEPT AS OTHERWISE RESTRICTED BY LAW, THIS WORK IS PROVIDED\
+ WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND, INCLUDING\
+ BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF FITNESS FOR A\
+ PARTICULAR PURPOSE, MERCHANTABILITY OR TITLE. EXCEPT AS\
+ OTHERWISE PROVIDED BY LAW, NO AUTHOR, COPYRIGHT HOLDER OR\
+ LICENSOR SHALL BE LIABLE TO YOU FOR DAMAGES OF ANY KIND, EVEN IF\
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.";
+
+LICENSE WineLicense_En = {License_En, LicenseCaption_En,
+ NoWarranty_En, NoWarrantyCaption_En};
diff --git a/programs/progman/Makefile.in b/programs/progman/Makefile.in
new file mode 100644
index 0000000..32f4a44
--- /dev/null
+++ b/programs/progman/Makefile.in
@@ -0,0 +1,41 @@
+TOPSRC = @top_srcdir@
+MODULE = none
+PROGRAMS = progman
+ALL_LIBS = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS)
+
+LANGUAGES = En De
+LICENSELANG = En
+
+MOSTOBJS = \
+ dialog.o \
+ group.o \
+ grpfile.o \
+ license.o \
+ main.o \
+ program.o \
+ winexec.o
+
+STRINGOBJS = \
+ accel.o \
+ string.o \
+ $(LANGUAGES:%=%.o) \
+ $(LICENSELANG:%=License_%.o) \
+ $(LANGUAGES:%=Strings_%.o)
+
+C_SRCS = $(MOSTOBJS:.o=.c) $(STRINGOBJS:.o=.c)
+
+all: check_winerc $(PROGRAMS)
+
+@MAKE_RULES@
+
+# Some strings need addresses >= 0x10000
+progman: $(MOSTOBJS) $(STRINGOBJS)
+ $(CC) -o progman $(MOSTOBJS) $(LDOPTIONS) $(ALL_LIBS) $(STRINGOBJS)
+
+clean::
+ $(RM) accel.c accel.h $(LANGUAGES:%=%.c) $(LANGUAGES:%=%.h) progman
+
+accel.c accel.h: $(WINERC) Xx.rc
+$(LANGUAGES:%=%.c) $(LANGUAGES:%=%.h): $(WINERC) Xx.rc
+
+### Dependencies:
diff --git a/programs/progman/README b/programs/progman/README
new file mode 100644
index 0000000..b145c28
--- /dev/null
+++ b/programs/progman/README
@@ -0,0 +1,16 @@
+This is a Program Manager for WINE.
+
+There is a checksum in the Microsoft `*.grp' files. I don't know how
+to calculate it. Therefore the group files written by this Program Manager
+cannot be used with the Microsoft Program Manager!!
+
+To prevent overwriting original files:
+If there is an existing `*.grp' file this program uses the extension
+`.gr' instead.
+
+It's possible to use an alternate `progman.ini' file by adding to
+`wine.conf' something like:
+[progman]
+progman.ini=/my/wine/path/progman.ini
+
+It's possible to start both Windows and UNIX programs.
diff --git a/programs/progman/Strings_De.c b/programs/progman/Strings_De.c
new file mode 100644
index 0000000..de3d369
--- /dev/null
+++ b/programs/progman/Strings_De.c
@@ -0,0 +1,34 @@
+#include <windows.h>
+#include "progman.h"
+
+LPCSTR StringTableDe[NUMBER_OF_STRINGS] =
+{
+ "Programm-Manager",
+ "FEHLER",
+ "Information",
+ "Löschen",
+ "Lösche Programmgruppe `%s' ?",
+ "Lösche Programm `%s' ?",
+ "Nicht implementiert",
+ "Fehler beim Lesen von `%s'",
+ "Fehler beim Schreiben von `%s'",
+
+ "Die Programmgruppendatei `%s' kann nicht geöffnet werden.\n"
+ "Soll weiterhin versucht werden, diese Datei zu laden?",
+
+ "Zu wenig Hauptspeicher",
+ "Keine Hilfe verfügbar",
+ "Unbekannte Eigenschaft der `.grp' Datei",
+ "Datei `%s' existiert. Sie wird nicht überschrieben.",
+ "Die Programmgruppe wird als `%s' gesichert um das Überschreiben der Originaldatei zu verhindern.",
+ "Keine",
+
+ "Alle Dateien (*.*)\0" "*.*\0"
+ "Programme\0" "*.exe;*.pif;*.com;*.bat\0",
+
+ "Alle Dateien (*.*)\0" "*.*\0"
+ "Bibliotheken (*.dll)\0" "*.dll\0"
+ "Programme\0" "*.exe\0"
+ "Symboldateien\0" "*.ico;*.exe;*.dll\0"
+ "Symbole (*.ico)\0" "*.ico\0"
+};
diff --git a/programs/progman/Strings_En.c b/programs/progman/Strings_En.c
new file mode 100644
index 0000000..da3f19d
--- /dev/null
+++ b/programs/progman/Strings_En.c
@@ -0,0 +1,34 @@
+#include <windows.h>
+#include "progman.h"
+
+LPCSTR StringTableEn[NUMBER_OF_STRINGS] =
+{
+ "Program Manager",
+ "ERROR",
+ "Information",
+ "Delete",
+ "Delete group `%s' ?",
+ "Delete program `%s' ?",
+ "Not implemented",
+ "Error reading `%s'",
+ "Error writeing `%s'",
+
+ "The group file `%s' cannot be opened.\n"
+ "Should it be tried further on?",
+
+ "Out of memory",
+ "Help not available",
+ "Unknown feature in `.grp' file",
+ "File `%s' exists. Not overwritten.",
+ "Save group as `%s' to prevent overwriting original files",
+ "None",
+
+ "All files (*.*)\0" "*.*\0"
+ "Programs\0" "*.exe;*.pif;*.com;*.bat\0",
+
+ "All files (*.*)\0" "*.*\0"
+ "Libraries (*.dll)\0" "*.dll\0"
+ "Programs\0" "*.exe\0"
+ "Symbol files\0" "*.ico;*.exe;*.dll\0"
+ "Symbols (*.ico)\0" "*.ico\0"
+};
diff --git a/programs/progman/TODO b/programs/progman/TODO
new file mode 100644
index 0000000..c3685a2
--- /dev/null
+++ b/programs/progman/TODO
@@ -0,0 +1,6 @@
+* Microsoft `*.grp' files use a checksum.
+ Find out how to calculate it.
+
+* Accelerators
+
+* Create some icons
diff --git a/programs/progman/Xx.rc b/programs/progman/Xx.rc
new file mode 100644
index 0000000..44d7991
--- /dev/null
+++ b/programs/progman/Xx.rc
@@ -0,0 +1,174 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+#include "progman.h"
+
+/* Menu */
+
+MENU_Xx MENU
+{
+ POPUP MENU_FILE {
+ MENUITEM MENU_FILE_NEW, PM_NEW
+ MENUITEM MENU_FILE_OPEN, PM_OPEN
+ MENUITEM MENU_FILE_MOVE, PM_MOVE, GRAYED
+ MENUITEM MENU_FILE_COPY, PM_COPY, GRAYED
+ MENUITEM MENU_FILE_DELETE, PM_DELETE
+ MENUITEM MENU_FILE_ATTRIBUTES, PM_ATTRIBUTES
+ MENUITEM SEPARATOR
+ MENUITEM MENU_FILE_EXECUTE, PM_EXECUTE
+ MENUITEM SEPARATOR
+ MENUITEM MENU_FILE_EXIT, PM_EXIT
+ }
+ POPUP MENU_OPTIONS {
+ MENUITEM MENU_OPTIONS_AUTO_ARRANGE, PM_AUTO_ARRANGE
+ MENUITEM MENU_OPTIONS_MIN_ON_RUN, PM_MIN_ON_RUN
+ MENUITEM MENU_OPTIONS_SAVE_SETTINGS, PM_SAVE_SETTINGS
+ }
+ POPUP MENU_WINDOWS {
+ MENUITEM MENU_WINDOWS_OVERLAP, PM_OVERLAP
+ MENUITEM MENU_WINDOWS_SIDE_BY_SIDE, PM_SIDE_BY_SIDE
+ MENUITEM MENU_WINDOWS_ARRANGE, PM_ARRANGE
+ }
+ POPUP MENU_LANGUAGE {
+ MENUITEM "&English", PM_En
+ MENUITEM "&Deutsch", PM_De
+ }
+ POPUP MENU_HELP {
+ MENUITEM MENU_HELP_CONTENTS, PM_CONTENTS
+ MENUITEM MENU_HELP_SEARCH, PM_SEARCH
+ MENUITEM SEPARATOR
+ MENUITEM MENU_HELP_HELP_ON_HELP, PM_HELPONHELP
+ MENUITEM MENU_HELP_TUTORIAL, PM_TUTORIAL
+ MENUITEM SEPARATOR
+
+ POPUP MENU_INFO {
+ MENUITEM MENU_INFO_LICENSE, PM_LICENSE
+ MENUITEM MENU_INFO_NO_WARRANTY, PM_NO_WARRANTY
+ MENUITEM MENU_INFO_ABOUT_WINE, PM_ABOUT_WINE
+ }
+ }
+}
+
+/* Dialog `New' */
+
+DIALOG_NEW_Xx DIALOG 0, 0, 170, 65
+STYLE DS_MODALFRAME
+CAPTION DIALOG_NEW_CAPTION
+{
+RADIOBUTTON "", PM_NEW_GROUP, 10, 15, 10, 15
+LTEXT DIALOG_NEW_GROUP, PM_NEW_GROUP, 20, 18, 80, 15
+RADIOBUTTON "", PM_NEW_PROGRAM, 10, 35, 10, 15
+LTEXT DIALOG_NEW_PROGRAM, PM_NEW_PROGRAM, 20, 38, 80, 15
+DEFPUSHBUTTON DIALOG_OK, IDOK, 105, 5, 60, 15
+PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 105, 25, 60, 15
+PUSHBUTTON DIALOG_HELP, PM_HELP, 105, 45, 60, 15
+}
+
+/* Dialog `Move' */
+
+DIALOG_MOVE_Xx DIALOG 0, 0, 250, 65
+STYLE DS_MODALFRAME
+CAPTION DIALOG_MOVE_CAPTION
+{
+LTEXT DIALOG_MOVE_PROGRAM, IDIGNORE, 5, 5, 90, 15
+LTEXT "", PM_PROGRAM, 95, 5, 90, 15
+LTEXT DIALOG_MOVE_FROM_GROUP, IDIGNORE, 5, 13, 90, 15
+LTEXT "", PM_FROM_GROUP, 95, 13, 90, 15
+LTEXT DIALOG_MOVE_TO_GROUP, PM_TO_GROUP_TXT, 5, 28, 140, 15
+COMBOBOX PM_TO_GROUP, 5, 38, 140, 50, CBS_DROPDOWNLIST
+DEFPUSHBUTTON DIALOG_OK, IDOK, 185, 5, 60, 15
+PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 185, 25, 60, 15
+PUSHBUTTON DIALOG_HELP, PM_HELP, 185, 45, 60, 15
+}
+
+/* Dialog `Copy' */
+
+DIALOG_COPY_Xx DIALOG 0, 0, 250, 65
+STYLE DS_MODALFRAME
+CAPTION DIALOG_COPY_CAPTION
+{
+LTEXT DIALOG_COPY_PROGRAM, IDIGNORE, 5, 5, 90, 15
+LTEXT "", PM_PROGRAM, 95, 5, 90, 15
+LTEXT DIALOG_COPY_FROM_GROUP, IDIGNORE, 5, 13, 90, 15
+LTEXT "", PM_FROM_GROUP, 95, 13, 90, 15
+LTEXT DIALOG_COPY_TO_GROUP, PM_TO_GROUP_TXT, 5, 28, 140, 15
+COMBOBOX PM_TO_GROUP, 5, 38, 140, 50, CBS_DROPDOWNLIST
+DEFPUSHBUTTON DIALOG_OK, IDOK, 185, 5, 60, 15
+PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 185, 25, 60, 15
+PUSHBUTTON DIALOG_HELP, PM_HELP, 185, 45, 60, 15
+}
+
+/* Dialog `Group attributes' */
+
+DIALOG_GROUP_Xx DIALOG 0, 0, 230, 65
+STYLE DS_MODALFRAME
+CAPTION DIALOG_GROUP_CAPTION
+{
+LTEXT DIALOG_GROUP_DESCRIPTION, PM_DESCRIPTION_TXT, 05, 18, 50, 10
+EDITTEXT PM_DESCRIPTION, 60, 18, 90, 15
+LTEXT DIALOG_GROUP_FILE, PM_FILE_TXT, 05, 38, 50, 10
+EDITTEXT PM_FILE, 60, 38, 90, 15
+DEFPUSHBUTTON DIALOG_OK, IDOK, 155, 5, 60, 15
+PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 155, 25, 60, 15
+PUSHBUTTON DIALOG_HELP, PM_HELP, 155, 45, 60, 15
+}
+
+/* Dialog `Program attributes' */
+
+DIALOG_PROGRAM_Xx DIALOG 0, 0, 250, 105
+STYLE DS_MODALFRAME
+CAPTION DIALOG_PROGRAM_CAPTION
+{
+LTEXT DIALOG_PROGRAM_DESCRIPTION, PM_DESCRIPTION_TXT, 05, 10, 60, 10
+EDITTEXT PM_DESCRIPTION, 80, 10, 90, 15
+LTEXT DIALOG_PROGRAM_COMMAND_LINE, PM_COMMAND_LINE_TXT, 05, 25, 60, 10
+EDITTEXT PM_COMMAND_LINE, 80, 25, 90, 15
+LTEXT DIALOG_PROGRAM_DIRECTORY, PM_DIRECTORY_TXT, 05, 40, 60, 10
+EDITTEXT PM_DIRECTORY, 80, 40, 90, 15
+LTEXT DIALOG_PROGRAM_HOT_KEY, PM_HOT_KEY_TXT, 05, 55, 60, 10
+EDITTEXT PM_HOT_KEY, 80, 55, 90, 15
+ICON "", PM_ICON, 20, 70
+CHECKBOX "", PM_SYMBOL, 80, 75, 10, 10
+LTEXT DIALOG_PROGRAM_SYMBOL, IDIGNORE, 95, 75, 75, 10
+DEFPUSHBUTTON DIALOG_OK, IDOK, 185, 5, 60, 15
+PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 185, 25, 60, 15
+PUSHBUTTON DIALOG_BROWSE, PM_BROWSE, 185, 45, 60, 15
+PUSHBUTTON DIALOG_PROGRAM_OTHER_SYMBOL, PM_OTHER_SYMBOL, 185, 65, 60, 15
+PUSHBUTTON DIALOG_HELP, PM_HELP, 185, 85, 60, 15
+}
+
+/* Dialog `Symbol' */
+
+DIALOG_SYMBOL_Xx DIALOG 0, 0, 200, 85
+STYLE DS_MODALFRAME
+CAPTION DIALOG_SYMBOL_CAPTION
+{
+LTEXT DIALOG_SYMBOL_FILE, PM_ICON_FILE_TXT, 5, 15, 40, 10
+EDITTEXT PM_ICON_FILE, 45, 15, 85, 15
+LTEXT DIALOG_SYMBOL_CURRENT, PM_SYMBOL_LIST_TXT, 5, 30, 125, 10
+COMBOBOX PM_SYMBOL_LIST, 5, 40, 125, 50,
+ CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_OWNERDRAWFIXED
+DEFPUSHBUTTON DIALOG_OK, IDOK, 135, 5, 60, 15
+PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 135, 25, 60, 15
+PUSHBUTTON DIALOG_BROWSE , PM_BROWSE, 135, 45, 60, 15
+PUSHBUTTON DIALOG_HELP, PM_HELP, 135, 65, 60, 15
+}
+
+/* Dialog `Execute' */
+
+DIALOG_EXECUTE_Xx DIALOG 0, 0, 200, 85
+STYLE DS_MODALFRAME
+CAPTION DIALOG_EXECUTE_CAPTION
+{
+LTEXT DIALOG_EXECUTE_COMMAND_LINE, IDIGNORE, 05, 15, 120, 10
+EDITTEXT PM_COMMAND, 05, 25, 120, 15
+CHECKBOX "", PM_SYMBOL, 05, 45, 10, 10
+LTEXT DIALOG_EXECUTE_SYMBOL, IDIGNORE, 20, 45, 120, 10
+DEFPUSHBUTTON DIALOG_OK, IDOK, 135, 5, 60, 15
+PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 135, 25, 60, 15
+PUSHBUTTON DIALOG_BROWSE , PM_BROWSE, 135, 45, 60, 15
+PUSHBUTTON DIALOG_HELP, PM_HELP, 135, 65, 60, 15
+}
diff --git a/programs/progman/accel.rc b/programs/progman/accel.rc
new file mode 100644
index 0000000..3409682
--- /dev/null
+++ b/programs/progman/accel.rc
@@ -0,0 +1,6 @@
+#include "progman.h"
+
+ACCEL ACCELERATORS
+{
+VK_RETURN, PM_EXECUTE, VIRTKEY, ALT
+}
diff --git a/programs/progman/dialog.c b/programs/progman/dialog.c
new file mode 100644
index 0000000..c19ca83
--- /dev/null
+++ b/programs/progman/dialog.c
@@ -0,0 +1,569 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+#include <windows.h>
+#include <commdlg.h>
+#include "progman.h"
+
+static BOOL DIALOG_Browse(HWND, LPCSTR, LPSTR, INT);
+static LRESULT DIALOG_NEW_DlgProc(HWND, UINT, WPARAM, LPARAM);
+static LRESULT DIALOG_COPY_MOVE_DlgProc(HWND, UINT, WPARAM, LPARAM);
+static LRESULT DIALOG_GROUP_DlgProc(HWND, UINT, WPARAM, LPARAM);
+static LRESULT DIALOG_PROGRAM_DlgProc(HWND, UINT, WPARAM, LPARAM);
+static LRESULT DIALOG_SYMBOL_DlgProc(HWND, UINT, WPARAM, LPARAM);
+static LRESULT DIALOG_EXECUTE_DlgProc(HWND, UINT, WPARAM, LPARAM);
+
+/***********************************************************************
+ *
+ * DIALOG_New
+ */
+
+static struct
+{
+ INT nDefault;
+} New;
+
+INT DIALOG_New(INT nDefault)
+{
+ WNDPROC lpfnDlg = MakeProcInstance(DIALOG_NEW_DlgProc, Globals.hInstance);
+ INT ret;
+
+ New.nDefault = nDefault;
+
+ ret = DialogBox(Globals.hInstance, STRING_NEW_Xx,
+ Globals.hMainWnd, lpfnDlg);
+ FreeProcInstance(lpfnDlg);
+ return ret;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * DIALOG_NEW_DlgProc
+ */
+
+static LRESULT DIALOG_NEW_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ CheckRadioButton(hDlg, PM_NEW_GROUP, PM_NEW_PROGRAM, New.nDefault);
+ break;
+
+ case WM_COMMAND:
+ switch (wParam)
+ {
+ case PM_NEW_GROUP:
+ case PM_NEW_PROGRAM:
+ CheckRadioButton(hDlg, PM_NEW_GROUP, PM_NEW_PROGRAM, wParam);
+ return TRUE;
+
+ case IDOK:
+ EndDialog(hDlg, IsDlgButtonChecked(hDlg, PM_NEW_GROUP) ?
+ PM_NEW_GROUP : PM_NEW_PROGRAM);
+ return TRUE;
+
+ case IDCANCEL:
+ EndDialog(hDlg, IDCANCEL);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/***********************************************************************
+ *
+ * DIALOG_CopyMove
+ */
+
+static struct
+{
+ LPCSTR lpszProgramName, lpszFromGroupName;
+ HLOCAL hToGroup;
+} CopyMove;
+
+HLOCAL DIALOG_CopyMove(LPCSTR lpszProgramName, LPCSTR lpszFromGroupName,
+ BOOL bMove)
+{
+ WNDPROC lpfnDlg = MakeProcInstance(DIALOG_COPY_MOVE_DlgProc, Globals.hInstance);
+ INT ret;
+
+ CopyMove.lpszProgramName = lpszProgramName;
+ CopyMove.lpszFromGroupName = lpszFromGroupName;
+ CopyMove.hToGroup = 0;
+
+ ret = DialogBox(Globals.hInstance,
+ bMove ? STRING_MOVE_Xx : STRING_COPY_Xx,
+ Globals.hMainWnd, lpfnDlg);
+ FreeProcInstance(lpfnDlg);
+
+ return((ret == IDOK) ? CopyMove.hToGroup : 0);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * DIALOG_COPY_MOVE_DlgProc
+ */
+
+static LRESULT DIALOG_COPY_MOVE_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ HLOCAL hGroup;
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ /* List all group names */
+ for (hGroup = GROUP_FirstGroup(); hGroup; hGroup = GROUP_NextGroup(hGroup))
+ SendDlgItemMessage(hDlg, PM_TO_GROUP, CB_ADDSTRING, 0,
+ (LPARAM) GROUP_GroupName(hGroup));
+
+ SetDlgItemText(hDlg, PM_PROGRAM, (LPSTR)CopyMove.lpszProgramName);
+ SetDlgItemText(hDlg, PM_FROM_GROUP, (LPSTR)CopyMove.lpszFromGroupName);
+ break;
+
+ case WM_COMMAND:
+ switch (wParam)
+ {
+ case IDOK:
+ {
+ /* Get selected group */
+ INT nCurSel = SendDlgItemMessage(hDlg, PM_TO_GROUP, CB_GETCURSEL, 0, 0);
+ INT nLen = SendDlgItemMessage(hDlg, PM_TO_GROUP, CB_GETLBTEXTLEN, nCurSel, 0);
+ HLOCAL hBuffer = LocalAlloc(LMEM_FIXED, nLen + 1);
+ LPSTR buffer = LocalLock(hBuffer);
+
+ SendDlgItemMessage(hDlg, PM_TO_GROUP, CB_GETLBTEXT, nCurSel, (LPARAM)buffer);
+ for (hGroup = GROUP_FirstGroup(); hGroup; hGroup = GROUP_NextGroup(hGroup))
+ if (!lstrcmp(buffer, GROUP_GroupName(hGroup))) break;
+ LocalFree(hBuffer);
+
+ CopyMove.hToGroup = hGroup;
+ EndDialog(hDlg, IDOK);
+ return TRUE;
+ }
+
+ case IDCANCEL:
+ EndDialog(hDlg, IDCANCEL);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/***********************************************************************
+ *
+ * DIALOG_Delete
+ */
+
+BOOL DIALOG_Delete(LPCSTR lpszFormat_s, LPCSTR lpszName)
+{
+ CHAR msg[1000];
+ if (sizeof(msg) <= lstrlen(lpszFormat_s) + lstrlen(lpszName)) return FALSE;
+ wsprintf(msg, (LPSTR)lpszFormat_s, lpszName);
+ return (IDYES == MessageBox(Globals.hMainWnd, msg, STRING_DELETE,
+ MB_YESNO | MB_DEFBUTTON2));
+}
+
+
+/***********************************************************************
+ *
+ * DIALOG_GroupAttributes
+ */
+
+static struct
+{
+ LPSTR lpszTitle, lpszGrpFile;
+ INT nSize;
+} GroupAttributes;
+
+BOOL DIALOG_GroupAttributes(LPSTR lpszTitle, LPSTR lpszGrpFile, INT nSize)
+{
+ WNDPROC lpfnDlg = MakeProcInstance(DIALOG_GROUP_DlgProc, Globals.hInstance);
+ INT ret;
+
+ GroupAttributes.nSize = nSize;
+ GroupAttributes.lpszTitle = lpszTitle;
+ GroupAttributes.lpszGrpFile = lpszGrpFile;
+
+ ret = DialogBox(Globals.hInstance, STRING_GROUP_Xx,
+ Globals.hMainWnd, lpfnDlg);
+ FreeProcInstance(lpfnDlg);
+ return(ret == IDOK);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * DIALOG_GROUP_DlgProc
+ */
+
+static LRESULT DIALOG_GROUP_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ SetDlgItemText(hDlg, PM_DESCRIPTION, GroupAttributes.lpszTitle);
+ SetDlgItemText(hDlg, PM_FILE, GroupAttributes.lpszGrpFile);
+ break;
+
+ case WM_COMMAND:
+ switch (wParam)
+ {
+ case IDOK:
+ GetDlgItemText(hDlg, PM_DESCRIPTION, GroupAttributes.lpszTitle,
+ GroupAttributes.nSize);
+ GetDlgItemText(hDlg, PM_FILE, GroupAttributes.lpszGrpFile,
+ GroupAttributes.nSize);
+ EndDialog(hDlg, IDOK);
+ return TRUE;
+
+ case IDCANCEL:
+ EndDialog(hDlg, IDCANCEL);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/***********************************************************************
+ *
+ * DIALOG_ProgramAttributes
+ */
+
+static struct
+{
+ LPSTR lpszTitle, lpszCmdLine, lpszWorkDir, lpszIconFile, lpszTmpIconFile;
+ INT nSize;
+ INT *lpnCmdShow;
+ INT *lpnHotKey;
+ HWND hSelGroupWnd;
+ HICON *lphIcon, hTmpIcon;
+ INT *lpnIconIndex, nTmpIconIndex;
+} ProgramAttributes;
+
+BOOL DIALOG_ProgramAttributes(LPSTR lpszTitle, LPSTR lpszCmdLine,
+ LPSTR lpszWorkDir, LPSTR lpszIconFile,
+ HICON *lphIcon, INT *lpnIconIndex,
+ INT *lpnHotKey, INT *lpnCmdShow, INT nSize)
+{
+ CHAR szTmpIconFile[MAX_PATHNAME_LEN];
+ WNDPROC lpfnDlg = MakeProcInstance(DIALOG_PROGRAM_DlgProc, Globals.hInstance);
+ INT ret;
+
+ ProgramAttributes.nSize = nSize;
+ ProgramAttributes.lpszTitle = lpszTitle;
+ ProgramAttributes.lpszCmdLine = lpszCmdLine;
+ ProgramAttributes.lpszWorkDir = lpszWorkDir;
+ ProgramAttributes.lpszIconFile = lpszIconFile;
+ ProgramAttributes.lpnCmdShow = lpnCmdShow;
+ ProgramAttributes.lpnHotKey = lpnHotKey;
+ ProgramAttributes.lphIcon = lphIcon;
+ ProgramAttributes.lpnIconIndex = lpnIconIndex;
+
+#if 0
+ ProgramAttributes.hTmpIcon = 0;
+#else
+ ProgramAttributes.hTmpIcon = *lphIcon;
+#endif
+ ProgramAttributes.nTmpIconIndex = *lpnIconIndex;
+ ProgramAttributes.lpszTmpIconFile = szTmpIconFile;
+ lstrcpyn(ProgramAttributes.lpszTmpIconFile, lpszIconFile, MAX_PATHNAME_LEN);
+
+ ret = DialogBox(Globals.hInstance, STRING_PROGRAM_Xx,
+ Globals.hMainWnd, lpfnDlg);
+ FreeProcInstance(lpfnDlg);
+
+ return(ret == IDOK);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * DIALOG_PROGRAM_DlgProc
+ */
+
+static LRESULT DIALOG_PROGRAM_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ SetDlgItemText(hDlg, PM_DESCRIPTION, ProgramAttributes.lpszTitle);
+ SetDlgItemText(hDlg, PM_COMMAND_LINE, ProgramAttributes.lpszCmdLine);
+ SetDlgItemText(hDlg, PM_DIRECTORY, ProgramAttributes.lpszWorkDir);
+ if (!*ProgramAttributes.lpnHotKey)
+ SetDlgItemText(hDlg, PM_HOT_KEY, (LPSTR)STRING_NO_HOT_KEY);
+
+ CheckDlgButton(hDlg, PM_SYMBOL,
+ (*ProgramAttributes.lpnCmdShow == SW_SHOWMINIMIZED));
+ SendDlgItemMessage(hDlg, PM_ICON, STM_SETICON,
+ (WPARAM) ProgramAttributes.hTmpIcon, 0);
+ break;
+
+ case WM_COMMAND:
+ switch (wParam)
+ {
+ case PM_SYMBOL:
+ CheckDlgButton(hDlg, PM_SYMBOL, !IsDlgButtonChecked(hDlg, PM_SYMBOL));
+ return TRUE;
+
+ case PM_BROWSE:
+ {
+ CHAR filename[MAX_PATHNAME_LEN];
+ if (DIALOG_Browse(hDlg, STRING_BROWSE_EXE_FILTER,
+ filename, sizeof(filename)))
+ SetDlgItemText(hDlg, PM_COMMAND_LINE, filename);
+ return TRUE;
+ }
+
+ case PM_OTHER_SYMBOL:
+ {
+ DIALOG_Symbol(&ProgramAttributes.hTmpIcon,
+ ProgramAttributes.lpszTmpIconFile,
+ &ProgramAttributes.nTmpIconIndex,
+ MAX_PATHNAME_LEN);
+
+ SendDlgItemMessage(hDlg, PM_ICON, STM_SETICON,
+ (WPARAM) ProgramAttributes.hTmpIcon, 0);
+ return TRUE;
+ }
+
+ case IDOK:
+ GetDlgItemText(hDlg, PM_DESCRIPTION,
+ ProgramAttributes.lpszTitle,
+ ProgramAttributes.nSize);
+ GetDlgItemText(hDlg, PM_COMMAND_LINE,
+ ProgramAttributes.lpszCmdLine,
+ ProgramAttributes.nSize);
+ GetDlgItemText(hDlg, PM_DIRECTORY,
+ ProgramAttributes.lpszWorkDir,
+ ProgramAttributes.nSize);
+
+ if (ProgramAttributes.hTmpIcon)
+ {
+#if 0
+ if (*ProgramAttributes.lphIcon)
+ DestroyIcon(*ProgramAttributes.lphIcon);
+#endif
+ *ProgramAttributes.lphIcon = ProgramAttributes.hTmpIcon;
+ *ProgramAttributes.lpnIconIndex = ProgramAttributes.nTmpIconIndex;
+ lstrcpyn(ProgramAttributes.lpszIconFile,
+ ProgramAttributes.lpszTmpIconFile,
+ ProgramAttributes.nSize);
+ }
+
+ *ProgramAttributes.lpnCmdShow =
+ IsDlgButtonChecked(hDlg, PM_SYMBOL) ?
+ SW_SHOWMINIMIZED : SW_SHOWNORMAL;
+ EndDialog(hDlg, IDOK);
+ return TRUE;
+
+ case IDCANCEL:
+ EndDialog(hDlg, IDCANCEL);
+ return TRUE;
+ }
+ return FALSE;
+ }
+ return FALSE;
+}
+
+/***********************************************************************
+ *
+ * DIALOG_Symbol
+ */
+
+static struct
+{
+ LPSTR lpszIconFile;
+ INT nSize;
+ HICON *lphIcon;
+ INT *lpnIconIndex;
+} Symbol;
+
+VOID DIALOG_Symbol(HICON *lphIcon, LPSTR lpszIconFile,
+ INT *lpnIconIndex, INT nSize)
+{
+ WNDPROC lpfnDlg = MakeProcInstance(DIALOG_SYMBOL_DlgProc, Globals.hInstance);
+
+ Symbol.nSize = nSize;
+ Symbol.lpszIconFile = lpszIconFile;
+ Symbol.lphIcon = lphIcon;
+ Symbol.lpnIconIndex = lpnIconIndex;
+
+ DialogBox(Globals.hInstance, STRING_SYMBOL_Xx,
+ Globals.hMainWnd, lpfnDlg);
+ FreeProcInstance(lpfnDlg);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * DIALOG_SYMBOL_DlgProc
+ */
+
+static LRESULT DIALOG_SYMBOL_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ SetDlgItemText(hDlg, PM_ICON_FILE, Symbol.lpszIconFile);
+ SendDlgItemMessage(hDlg, PM_SYMBOL_LIST, CB_SETITEMHEIGHT, 0, (LPARAM) 32);
+ SendDlgItemMessage(hDlg, PM_SYMBOL_LIST, CB_ADDSTRING, 0, (LPARAM)*Symbol.lphIcon);
+ SendDlgItemMessage(hDlg, PM_SYMBOL_LIST, CB_ADDSTRING, 0, (LPARAM)Globals.hDefaultIcon);
+ SendDlgItemMessage(hDlg, PM_SYMBOL_LIST, CB_SETCURSEL, 0, 0);
+ return TRUE;
+
+ case WM_MEASUREITEM:
+ {
+ PMEASUREITEMSTRUCT measure = (PMEASUREITEMSTRUCT) lParam;
+ measure->itemWidth = 32;
+ measure->itemHeight = 32;
+ return TRUE;
+ }
+
+ case WM_DRAWITEM:
+ {
+ PDRAWITEMSTRUCT dis = (PDRAWITEMSTRUCT) lParam;
+ DrawIcon(dis->hDC, dis->rcItem.left, dis->rcItem.top, (HICON)dis->itemData);
+ return TRUE;
+ }
+
+ case WM_COMMAND:
+ switch (wParam)
+ {
+ case PM_BROWSE:
+ {
+ CHAR filename[MAX_PATHNAME_LEN];
+ if (DIALOG_Browse(hDlg, STRING_BROWSE_ICO_FILTER,
+ filename, sizeof(filename)))
+ SetDlgItemText(hDlg, PM_ICON_FILE, filename);
+ return TRUE;
+ }
+
+ case PM_HELP:
+ MAIN_NotImplementedError();
+ return TRUE;
+
+ case IDOK:
+ {
+ INT nCurSel = SendDlgItemMessage(hDlg, PM_SYMBOL_LIST, CB_GETCURSEL, 0, 0);
+
+ GetDlgItemText(hDlg, PM_ICON_FILE, Symbol.lpszIconFile, Symbol.nSize);
+
+ *Symbol.lphIcon = (HICON)SendDlgItemMessage(hDlg, PM_SYMBOL_LIST,
+ CB_GETITEMDATA,
+ (WPARAM) nCurSel, 0);
+#if 0
+ *Symbol.lphIcon = CopyIcon(*Symbol.lphIcon);
+#endif
+
+ EndDialog(hDlg, IDOK);
+ return TRUE;
+ }
+
+ case IDCANCEL:
+ EndDialog(hDlg, IDCANCEL);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/***********************************************************************
+ *
+ * DIALOG_Execute
+ */
+
+VOID DIALOG_Execute()
+{
+ WNDPROC lpfnDlg = MakeProcInstance(DIALOG_EXECUTE_DlgProc, Globals.hInstance);
+ DialogBox(Globals.hInstance, STRING_EXECUTE_Xx,
+ Globals.hMainWnd, lpfnDlg);
+ FreeProcInstance(lpfnDlg);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * DIALOG_EXECUTE_DlgProc
+ */
+
+static LRESULT DIALOG_EXECUTE_DlgProc(HWND hDlg, UINT msg,
+ WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_COMMAND:
+ switch (wParam)
+ {
+ case PM_SYMBOL:
+ CheckDlgButton(hDlg, PM_SYMBOL, !IsDlgButtonChecked(hDlg, PM_SYMBOL));
+ return TRUE;
+
+ case PM_BROWSE:
+ {
+ CHAR filename[MAX_PATHNAME_LEN];
+ if (DIALOG_Browse(hDlg, STRING_BROWSE_EXE_FILTER,
+ filename, sizeof(filename)))
+ SetDlgItemText(hDlg, PM_COMMAND, filename);
+ return TRUE;
+ }
+
+ case PM_HELP:
+ MAIN_NotImplementedError();
+ return TRUE;
+
+ case IDOK:
+ {
+ CHAR cmdline[MAX_PATHNAME_LEN];
+ GetDlgItemText(hDlg, PM_COMMAND, cmdline, sizeof(cmdline));
+
+ WinExec(cmdline, IsDlgButtonChecked(hDlg, PM_SYMBOL) ?
+ SW_SHOWMINIMIZED : SW_SHOWNORMAL);
+ if (Globals.bMinOnRun) CloseWindow(Globals.hMainWnd);
+
+ EndDialog(hDlg, IDOK);
+ return TRUE;
+ }
+
+ case IDCANCEL:
+ EndDialog(hDlg, IDCANCEL);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/***********************************************************************
+ *
+ * DIALOG_Browse
+ */
+
+/* FIXME is this correct ? */
+static BOOL DIALOG_Browse(HWND hDlg, LPCSTR lpcstrFilter,
+ LPSTR lpstrFile, INT nMaxFile)
+{
+ OPENFILENAME openfilename;
+ openfilename.lStructSize = 0;
+ openfilename.hwndOwner = hDlg;
+ openfilename.hInstance = Globals.hInstance;
+ openfilename.lpstrFilter = (LPSTR)lpcstrFilter;
+ openfilename.lpstrCustomFilter = 0;
+ openfilename.nMaxCustFilter = 0;
+ openfilename.nFilterIndex = 0;
+ openfilename.lpstrFile = lpstrFile;
+ openfilename.nMaxFile = sizeof(lpstrFile);
+ openfilename.lpstrFileTitle = 0;
+ openfilename.nMaxFileTitle = 0;
+ openfilename.lpstrInitialDir = 0;
+ openfilename.lpstrTitle = 0;
+ openfilename.Flags = 0;
+ openfilename.nFileOffset = 0;
+ openfilename.nFileExtension = 0;
+ openfilename.lpstrDefExt = 0;
+ openfilename.lCustData = 0;
+ openfilename.lpfnHook = 0;
+ openfilename.lpTemplateName = 0;
+ return GetOpenFileName(&openfilename);
+}
+
+/* Local Variables: */
+/* c-file-style: "GNU" */
+/* End: */
diff --git a/programs/progman/group.c b/programs/progman/group.c
new file mode 100644
index 0000000..0646f8f
--- /dev/null
+++ b/programs/progman/group.c
@@ -0,0 +1,313 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+#include <stdio.h>
+#include <windows.h>
+#include "progman.h"
+
+/***********************************************************************
+ *
+ * GROUP_GroupWndProc
+ */
+
+static LRESULT GROUP_GroupWndProc (HWND hWnd, UINT msg,
+ WPARAM wParam, LPARAM lParam)
+{
+#if 0
+ printf("G %4.4x %4.4x\n", msg, wParam);
+#endif
+ switch (msg)
+ {
+ case WM_SYSCOMMAND:
+ if (wParam == SC_CLOSE) wParam = SC_MINIMIZE;
+ break;
+
+ case WM_CHILDACTIVATE:
+ case WM_NCLBUTTONDOWN:
+ Globals.hActiveGroup = (HLOCAL) GetWindowLong(hWnd, 0);
+ EnableMenuItem(Globals.hFileMenu, PM_MOVE , MF_GRAYED);
+ EnableMenuItem(Globals.hFileMenu, PM_COPY , MF_GRAYED);
+ break;
+ }
+ return(DefMDIChildProc(hWnd, msg, wParam, lParam));
+}
+
+/***********************************************************************
+ *
+ * GROUP_RegisterGroupWinClass
+ */
+
+ATOM GROUP_RegisterGroupWinClass()
+{
+ WNDCLASS class;
+
+ class.style = CS_HREDRAW | CS_VREDRAW;
+ class.lpfnWndProc = GROUP_GroupWndProc;
+ class.cbClsExtra = 0;
+ class.cbWndExtra = sizeof(LONG);
+ class.hInstance = Globals.hInstance;
+ class.hIcon = LoadIcon (0, MAKEINTRESOURCE(OIC_WINEICON));
+ class.hCursor = LoadCursor (0, IDC_ARROW);
+ class.hbrBackground = GetStockObject (WHITE_BRUSH);
+ class.lpszMenuName = 0;
+ class.lpszClassName = STRING_GROUP_WIN_CLASS_NAME;
+
+ return RegisterClass(&class);
+}
+
+/***********************************************************************
+ *
+ * GROUP_NewGroup
+ */
+
+VOID GROUP_NewGroup()
+{
+ CHAR szName[MAX_PATHNAME_LEN] = "";
+ CHAR szFile[MAX_PATHNAME_LEN] = "";
+ OFSTRUCT dummy;
+
+ if (!DIALOG_GroupAttributes(szName, szFile, MAX_PATHNAME_LEN)) return;
+
+ if (OpenFile(szFile, &dummy, OF_EXIST) == HFILE_ERROR)
+ {
+ /* File doesn't exist */
+ HLOCAL hGroup =
+ GROUP_AddGroup(szName, szFile, SW_SHOWNORMAL,
+ DEF_GROUP_WIN_XPOS, DEF_GROUP_WIN_YPOS,
+ DEF_GROUP_WIN_WIDTH, DEF_GROUP_WIN_HEIGHT, 0, 0,
+ FALSE, FALSE, FALSE);
+ if (!hGroup) return;
+ GRPFILE_WriteGroupFile(hGroup);
+ }
+ else /* File exist */
+ GRPFILE_ReadGroupFile(szFile);
+
+ /* FIXME Update progman.ini */
+}
+
+/***********************************************************************
+ *
+ * GROUP_AddGroup
+ */
+
+HLOCAL GROUP_AddGroup(LPCSTR lpszName, LPCSTR lpszGrpFile, INT nCmdShow,
+ INT x, INT y, INT width, INT height,
+ INT iconx, INT icony,
+ BOOL bFileNameModified, BOOL bOverwriteFileOk,
+ /* FIXME shouldn't be necessary */
+ BOOL bSuppressShowWindow)
+{
+ GROUP *group, *prior;
+ MDICREATESTRUCT cs;
+ INT seqnum;
+ HLOCAL hPrior, *p;
+ HLOCAL hGroup = LocalAlloc(LMEM_FIXED, sizeof(GROUP));
+ HLOCAL hName = LocalAlloc(LMEM_FIXED, 1 + lstrlen(lpszName));
+ HLOCAL hGrpFile = LocalAlloc(LMEM_FIXED, 1 + lstrlen(lpszGrpFile));
+ if (!hGroup || !hName || !hGrpFile)
+ {
+ MessageBox(Globals.hMainWnd, "out of memory", lpszName, MB_OK);
+ if (hGroup) LocalFree(hGroup);
+ if (hName) LocalFree(hName);
+ if (hGrpFile) LocalFree(hGrpFile);
+ return(0);
+ }
+ hmemcpy(LocalLock(hName), lpszName, 1 + lstrlen(lpszName));
+ hmemcpy(LocalLock(hGrpFile), lpszGrpFile, 1 + lstrlen(lpszGrpFile));
+
+ Globals.hActiveGroup = hGroup;
+
+ seqnum = 1;
+ hPrior = 0;
+ p = &Globals.hGroups;
+ while (*p)
+ {
+ hPrior = *p;
+ prior = LocalLock(hPrior);
+ p = &prior->hNext;
+ if (prior->seqnum >= seqnum)
+ seqnum = prior->seqnum + 1;
+ }
+ *p = hGroup;
+
+ group = LocalLock(hGroup);
+ group->hPrior = hPrior;
+ group->hNext = 0;
+ group->hName = hName;
+ group->hGrpFile = hGrpFile;
+ group->bFileNameModified = bFileNameModified;
+ group->bOverwriteFileOk = bOverwriteFileOk;
+ group->seqnum = seqnum;
+ group->nCmdShow = nCmdShow;
+ group->x = x;
+ group->y = y;
+ group->width = width;
+ group->height = height;
+ group->iconx = iconx;
+ group->icony = icony;
+ group->hPrograms = 0;
+ group->hActiveProgram = 0;
+
+ cs.szClass = STRING_GROUP_WIN_CLASS_NAME;
+ cs.szTitle = (LPSTR)lpszName;
+ cs.hOwner = 0;
+ cs.x = x;
+ cs.y = y;
+ cs.cx = width;
+ cs.cy = height;
+ cs.style = 0;
+ cs.lParam = 0;
+
+ group->hWnd = (HWND)SendMessage(Globals.hMDIWnd, WM_MDICREATE, 0, (LPARAM)&cs);
+
+ SetWindowLong(group->hWnd, 0, (LONG) hGroup);
+
+#if 1
+ if (!bSuppressShowWindow) /* FIXME shouldn't be necessary */
+#endif
+ {
+ ShowWindow (group->hWnd, nCmdShow);
+ UpdateWindow (group->hWnd);
+ }
+
+ return(hGroup);
+}
+
+/***********************************************************************
+ *
+ * GROUP_ModifyGroup
+ */
+
+VOID GROUP_ModifyGroup(HLOCAL hGroup)
+{
+ GROUP *group = LocalLock(hGroup);
+ CHAR szName[MAX_PATHNAME_LEN];
+ CHAR szFile[MAX_PATHNAME_LEN];
+ lstrcpyn(szName, LocalLock(group->hName), MAX_PATHNAME_LEN);
+ lstrcpyn(szFile, LocalLock(group->hGrpFile), MAX_PATHNAME_LEN);
+
+ if (!DIALOG_GroupAttributes(szName, szFile, MAX_PATHNAME_LEN)) return;
+
+ if (strcmp(szFile, LocalLock(group->hGrpFile)))
+ group->bOverwriteFileOk = FALSE;
+
+ MAIN_ReplaceString(&group->hName, szName);
+ MAIN_ReplaceString(&group->hGrpFile, szFile);
+
+ GRPFILE_WriteGroupFile(hGroup);
+
+ /* FIXME Delete old GrpFile if GrpFile changed */
+
+ /* FIXME Update progman.ini */
+
+ SetWindowText(group->hWnd, szName);
+}
+
+/***********************************************************************
+ *
+ * GROUP_ShowGroupWindow
+ */
+
+/* FIXME shouldn't be necessary */
+VOID GROUP_ShowGroupWindow(HLOCAL hGroup)
+{
+ GROUP *group = LocalLock(hGroup);
+ ShowWindow (group->hWnd, group->nCmdShow);
+ UpdateWindow (group->hWnd);
+}
+
+/***********************************************************************
+ *
+ * GROUP_DeleteGroup
+ */
+
+VOID GROUP_DeleteGroup(HLOCAL hGroup)
+{
+ GROUP *group = LocalLock(hGroup);
+
+ Globals.hActiveGroup = 0;
+
+ if (group->hPrior)
+ ((GROUP*)LocalLock(group->hPrior))->hNext = group->hNext;
+ else Globals.hGroups = group->hNext;
+
+ if (group->hNext)
+ ((GROUP*)LocalLock(group->hNext))->hPrior = group->hPrior;
+
+ while (group->hPrograms)
+ PROGRAM_DeleteProgram(group->hPrograms, FALSE);
+
+ /* FIXME Update progman.ini */
+
+ SendMessage(Globals.hMDIWnd, WM_MDIDESTROY, (WPARAM)group->hWnd, 0);
+
+ LocalFree(group->hName);
+ LocalFree(group->hGrpFile);
+ LocalFree(hGroup);
+}
+
+/***********************************************************************
+ *
+ * GROUP_FirstGroup
+ */
+
+HLOCAL GROUP_FirstGroup()
+{
+ return(Globals.hGroups);
+}
+
+/***********************************************************************
+ *
+ * GROUP_NextGroup
+ */
+
+HLOCAL GROUP_NextGroup(HLOCAL hGroup)
+{
+ GROUP *group;
+ if (!hGroup) return(0);
+ group = LocalLock(hGroup);
+ return(group->hNext);
+}
+
+/***********************************************************************
+ *
+ * GROUP_ActiveGroup
+ */
+
+HLOCAL GROUP_ActiveGroup()
+{
+ return(Globals.hActiveGroup);
+}
+
+/***********************************************************************
+ *
+ * GROUP_GroupWnd
+ */
+
+HWND GROUP_GroupWnd(HLOCAL hGroup)
+{
+ GROUP *group;
+ if (!hGroup) return(0);
+ group = LocalLock(hGroup);
+ return(group->hWnd);
+}
+
+/***********************************************************************
+ *
+ * GROUP_GroupName
+ */
+
+LPCSTR GROUP_GroupName(HLOCAL hGroup)
+{
+ GROUP *group;
+ if (!hGroup) return(0);
+ group = LocalLock(hGroup);
+ return(LocalLock(group->hName));
+}
+
+/* Local Variables: */
+/* c-file-style: "GNU" */
+/* End: */
diff --git a/programs/progman/grpfile.c b/programs/progman/grpfile.c
new file mode 100644
index 0000000..50e99ec
--- /dev/null
+++ b/programs/progman/grpfile.c
@@ -0,0 +1,645 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+#include <windows.h>
+#include "progman.h"
+
+#define MALLOCHUNK 1000
+
+#define GET_USHORT(buffer, i)\
+ (((BYTE)((buffer)[(i)]) + 0x100 * (BYTE)((buffer)[(i)+1])))
+#define GET_SHORT(buffer, i)\
+ (((BYTE)((buffer)[(i)]) + 0x100 * (signed char)((buffer)[(i)+1])))
+#define PUT_SHORT(buffer, i, s)\
+ (((buffer)[(i)] = (s) & 0xff, (buffer)[(i)+1] = ((s) >> 8) & 0xff))
+
+static BOOL GRPFILE_ReadFileToBuffer(LPCSTR, HLOCAL*, INT*);
+static HLOCAL GRPFILE_ScanGroup(LPCSTR, INT, LPCSTR, BOOL);
+static HLOCAL GRPFILE_ScanProgram(LPCSTR, INT, LPCSTR, INT,
+ LPCSTR, HLOCAL,LPCSTR);
+static BOOL GRPFILE_DoWriteGroupFile(HFILE file, GROUP *group);
+
+/***********************************************************************
+ *
+ * GRPFILE_ModifyFileName
+ *
+ * Change extension `.grp' to `.gr'
+ */
+
+static VOID GRPFILE_ModifyFileName(LPSTR lpszNewName, LPCSTR lpszOrigName,
+ INT nSize, BOOL bModify)
+{
+ lstrcpyn(lpszNewName, lpszOrigName, nSize);
+ lpszNewName[nSize-1] = '\0';
+ if (!bModify) return;
+ if (!lstrcmpi(lpszNewName + strlen(lpszNewName) - 4, ".grp"))
+ lpszNewName[strlen(lpszNewName) - 1] = '\0';
+}
+
+/***********************************************************************
+ *
+ * GRPFILE_ReadGroupFile
+ */
+
+HLOCAL GRPFILE_ReadGroupFile(LPCSTR lpszPath)
+{
+ CHAR szPath_gr[MAX_PATHNAME_LEN];
+ BOOL bFileNameModified = FALSE;
+ OFSTRUCT dummy;
+ HLOCAL hBuffer, hGroup;
+ INT size;
+
+ /* if `.gr' file exists use that */
+ GRPFILE_ModifyFileName(szPath_gr, lpszPath, MAX_PATHNAME_LEN, TRUE);
+ if (OpenFile(szPath_gr, &dummy, OF_EXIST) != HFILE_ERROR)
+ {
+ lpszPath = szPath_gr;
+ bFileNameModified = TRUE;
+ }
+
+ /* Read the whole file into a buffer */
+ if (!GRPFILE_ReadFileToBuffer(lpszPath, &hBuffer, &size))
+ {
+ MAIN_GrpFileReadError(lpszPath);
+ return(0);
+ }
+
+ /* Interpret buffer */
+ hGroup = GRPFILE_ScanGroup(LocalLock(hBuffer), size,
+ lpszPath, bFileNameModified);
+ if (!hGroup) MAIN_GrpFileReadError(lpszPath);
+
+ LocalFree(hBuffer);
+
+ return(hGroup);
+}
+
+/***********************************************************************
+ *
+ * GRPFILE_ReadFileToBuffer
+ */
+
+static BOOL GRPFILE_ReadFileToBuffer(LPCSTR path, HLOCAL *phBuffer,
+ INT *piSize)
+{
+ INT len, size;
+ LPSTR buffer;
+ HLOCAL hBuffer, hNewBuffer;
+ HFILE file;
+
+ file=_lopen(path, OF_READ);
+ if (file == HFILE_ERROR) return FALSE;
+
+ size = 0;
+ hBuffer = LocalAlloc(LMEM_FIXED, size + MALLOCHUNK + 1);
+ if (!hBuffer) return FALSE;
+ buffer = LocalLock(hBuffer);
+
+ while ((len = _lread(file, buffer + size, MALLOCHUNK))
+ == MALLOCHUNK)
+ {
+ size += len;
+ hNewBuffer = LocalReAlloc(hBuffer, size + MALLOCHUNK + 1,
+ LMEM_FIXED);
+ if (!hNewBuffer)
+ {
+ LocalFree(hBuffer);
+ return FALSE;
+ }
+ hBuffer = hNewBuffer;
+ buffer = LocalLock(hBuffer);
+ }
+
+ _lclose(file);
+
+ if (len == HFILE_ERROR)
+ {
+ LocalFree(hBuffer);
+ return FALSE;
+ }
+
+ size += len;
+ buffer[size] = 0;
+
+ *phBuffer = hBuffer;
+ *piSize = size;
+ return TRUE;
+}
+
+/***********************************************************************
+ * GRPFILE_ScanGroup
+ */
+
+static HLOCAL GRPFILE_ScanGroup(LPCSTR buffer, INT size,
+ LPCSTR lpszGrpFile,
+ BOOL bModifiedFileName)
+{
+ HLOCAL hGroup;
+ INT i, seqnum;
+ LPCSTR extension;
+ LPCSTR lpszName;
+ INT x, y, width, height, iconx, icony, nCmdShow;
+ INT number_of_programs;
+ BOOL bOverwriteFileOk;
+
+ if (buffer[0] != 'P' || buffer[1] != 'M') return(0);
+ if (buffer[2] == 'C' && buffer[3] == 'C')
+ /* original with checksum */
+ bOverwriteFileOk = FALSE;
+ else if (buffer[2] == 'X' && buffer[3] == 'X')
+ /* modified without checksum */
+ bOverwriteFileOk = TRUE;
+ else return(0);
+
+ /* checksum = GET_USHORT(buffer, 4) (ignored) */
+
+ extension = buffer + GET_USHORT(buffer, 6);
+ if (extension == buffer + size) extension = 0;
+ else if (extension + 6 > buffer + size) return(0);
+
+ nCmdShow = GET_USHORT(buffer, 8);
+ x = GET_SHORT(buffer, 10);
+ y = GET_SHORT(buffer, 12);
+ width = GET_USHORT(buffer, 14);
+ height = GET_USHORT(buffer, 16);
+ iconx = GET_SHORT(buffer, 18);
+ icony = GET_SHORT(buffer, 20);
+ lpszName = buffer + GET_USHORT(buffer, 22);
+ if (lpszName >= buffer + size) return(0);
+
+ /* unknown bytes 24 - 31 ignored */
+
+ hGroup = GROUP_AddGroup(lpszName, lpszGrpFile, nCmdShow, x, y,
+ width, height, iconx, icony,
+ bModifiedFileName, bOverwriteFileOk,
+ TRUE);
+ if (!hGroup) return(0);
+
+ number_of_programs = GET_USHORT(buffer, 32);
+ if (2 * number_of_programs + 34 > size) return(0);
+ for (i=0, seqnum=0; i < number_of_programs; i++, seqnum++)
+ {
+ LPCSTR program_ptr = buffer + GET_USHORT(buffer, 34 + 2*i);
+ if (program_ptr + 24 > buffer + size) return(0);
+ if (!GET_USHORT(buffer, 34 + 2*i)) continue;
+ if (!GRPFILE_ScanProgram(buffer, size, program_ptr, seqnum,
+ extension, hGroup, lpszGrpFile))
+ {
+ GROUP_DeleteGroup(hGroup);
+ return(0);
+ }
+ }
+
+ /* FIXME shouldn't be necessary */
+ GROUP_ShowGroupWindow(hGroup);
+
+ return hGroup;
+}
+
+/***********************************************************************
+ * GRPFILE_ScanProgram
+ */
+
+static HLOCAL GRPFILE_ScanProgram(LPCSTR buffer, INT size,
+ LPCSTR program_ptr, INT seqnum,
+ LPCSTR extension, HLOCAL hGroup,
+ LPCSTR lpszGrpFile)
+{
+ INT icontype;
+ HICON hIcon;
+ LPCSTR lpszName, lpszCmdLine, lpszIconFile, lpszWorkDir;
+ LPCSTR iconinfo_ptr, iconANDbits_ptr, iconXORbits_ptr;
+ INT x, y, nIconIndex, iconANDsize, iconXORsize;
+ INT nHotKey, nCmdShow;
+ CURSORICONINFO iconinfo;
+
+ x = GET_SHORT(program_ptr, 0);
+ y = GET_SHORT(program_ptr, 2);
+ nIconIndex = GET_USHORT(program_ptr, 4);
+
+ /* FIXME is this correct ?? */
+ icontype = GET_USHORT(program_ptr, 6);
+ switch (icontype)
+ {
+ default:
+ MessageBox(Globals.hMainWnd, STRING_UNKNOWN_FEATURE_IN_GRPFILE,
+ lpszGrpFile, MB_OK);
+ case 0x048c:
+ iconXORsize = GET_USHORT(program_ptr, 8);
+ iconANDsize = GET_USHORT(program_ptr, 10) / 8;
+ iconinfo_ptr = buffer + GET_USHORT(program_ptr, 12);
+ iconXORbits_ptr = buffer + GET_USHORT(program_ptr, 14);
+ iconANDbits_ptr = buffer + GET_USHORT(program_ptr, 16);
+ iconinfo.ptHotSpot.x = GET_USHORT(iconinfo_ptr, 0);
+ iconinfo.ptHotSpot.y = GET_USHORT(iconinfo_ptr, 2);
+ iconinfo.nWidth = GET_USHORT(iconinfo_ptr, 4);
+ iconinfo.nHeight = GET_USHORT(iconinfo_ptr, 6);
+ iconinfo.nWidthBytes = GET_USHORT(iconinfo_ptr, 8);
+ iconinfo.bPlanes = GET_USHORT(iconinfo_ptr, 10);
+ iconinfo.bBitsPerPixel = GET_USHORT(iconinfo_ptr, 11);
+ break;
+ case 0x000c:
+ iconANDsize = GET_USHORT(program_ptr, 8);
+ iconXORsize = GET_USHORT(program_ptr, 10);
+ iconinfo_ptr = buffer + GET_USHORT(program_ptr, 12);
+ iconANDbits_ptr = buffer + GET_USHORT(program_ptr, 14);
+ iconXORbits_ptr = buffer + GET_USHORT(program_ptr, 16);
+ iconinfo.ptHotSpot.x = GET_USHORT(iconinfo_ptr, 0);
+ iconinfo.ptHotSpot.y = GET_USHORT(iconinfo_ptr, 2);
+ iconinfo.nWidth = GET_USHORT(iconinfo_ptr, 4);
+ iconinfo.nHeight = GET_USHORT(iconinfo_ptr, 6);
+ iconinfo.nWidthBytes = GET_USHORT(iconinfo_ptr, 8) * 8;
+ iconinfo.bPlanes = GET_USHORT(iconinfo_ptr, 10);
+ iconinfo.bBitsPerPixel = GET_USHORT(iconinfo_ptr, 11);
+ }
+
+ if (iconANDbits_ptr + iconANDsize > buffer + size ||
+ iconXORbits_ptr + iconXORsize > buffer + size) return(0);
+
+ hIcon = CreateCursorIconIndirect(Globals.hInstance, &iconinfo,
+ (LPSTR)iconANDbits_ptr,
+ (LPSTR)iconXORbits_ptr);
+
+ lpszName = buffer + GET_USHORT(program_ptr, 18);
+ lpszCmdLine = buffer + GET_USHORT(program_ptr, 20);
+ lpszIconFile = buffer + GET_USHORT(program_ptr, 22);
+ if (iconinfo_ptr + 6 > buffer + size ||
+ lpszName > buffer + size ||
+ lpszCmdLine > buffer + size ||
+ lpszIconFile > buffer + size) return(0);
+
+ /* Scan Extensions */
+ lpszWorkDir = "";
+ nHotKey = 0;
+ nCmdShow = SW_SHOWNORMAL;
+ if (extension)
+ {
+ LPCSTR ptr = extension;
+ while (ptr + 6 <= buffer + size)
+ {
+ UINT type = GET_USHORT(ptr, 0);
+ UINT number = GET_USHORT(ptr, 2);
+ UINT skip = GET_USHORT(ptr, 4);
+
+ if (number == seqnum)
+ {
+ switch (type)
+ {
+ case 0x8000:
+ if (ptr + 10 > buffer + size) return(0);
+ if (ptr[6] != 'P' || ptr[7] != 'M' ||
+ ptr[8] != 'C' || ptr[9] != 'C') return(0);
+ break;
+ case 0x8101:
+ lpszWorkDir = ptr + 6;
+ break;
+ case 0x8102:
+ if (ptr + 8 > buffer + size) return(0);
+ nHotKey = GET_USHORT(ptr, 6);
+ break;
+ case 0x8103:
+ if (ptr + 8 > buffer + size) return(0);
+ nCmdShow = GET_USHORT(ptr, 6);
+ break;
+ default:
+ MessageBox(Globals.hMainWnd,
+ STRING_UNKNOWN_FEATURE_IN_GRPFILE,
+ lpszGrpFile, MB_OK);
+ }
+ }
+ if (!skip) break;
+ ptr += skip;
+ }
+ }
+
+ return (PROGRAM_AddProgram(hGroup, hIcon, lpszName, x, y,
+ lpszCmdLine, lpszIconFile,
+ nIconIndex, lpszWorkDir,
+ nHotKey, nCmdShow));
+}
+
+/***********************************************************************
+ *
+ * GRPFILE_WriteGroupFile
+ */
+
+BOOL GRPFILE_WriteGroupFile(HLOCAL hGroup)
+{
+ CHAR szPath[MAX_PATHNAME_LEN];
+ GROUP *group = LocalLock(hGroup);
+ OFSTRUCT dummy;
+ HFILE file;
+ BOOL ret;
+
+ GRPFILE_ModifyFileName(szPath, LocalLock(group->hGrpFile),
+ MAX_PATHNAME_LEN,
+ group->bFileNameModified);
+
+ /* Try not to overwrite original files */
+
+ /* group->bOverwriteFileOk == TRUE only if a file has the modified format */
+ if (!group->bOverwriteFileOk &&
+ OpenFile(szPath, &dummy, OF_EXIST) != HFILE_ERROR)
+ {
+ CHAR msg[MAX_PATHNAME_LEN + 1000];
+
+ /* Original file exists, try `.gr' extension */
+ GRPFILE_ModifyFileName(szPath, LocalLock(group->hGrpFile),
+ MAX_PATHNAME_LEN, TRUE);
+ if (OpenFile(szPath, &dummy, OF_EXIST) != HFILE_ERROR)
+ {
+ /* File exists. Do not overwrite */
+ if (sizeof(msg) <= lstrlen(STRING_FILE_NOT_OVERWRITTEN_s) + lstrlen(szPath))
+ return FALSE;
+ wsprintf(msg, (LPSTR)STRING_FILE_NOT_OVERWRITTEN_s, szPath);
+ MessageBox(Globals.hMainWnd, msg, STRING_ERROR, MB_OK);
+ return FALSE;
+ }
+ /* Inform about the modified file name */
+ if (sizeof(msg) <= lstrlen(STRING_SAVE_GROUP_AS_s) + lstrlen(szPath))
+ return FALSE;
+ wsprintf(msg, (LPSTR)STRING_SAVE_GROUP_AS_s, szPath);
+ if (IDCANCEL == MessageBox(Globals.hMainWnd, msg, STRING_INFO,
+ MB_OKCANCEL | MB_ICONINFORMATION))
+ return FALSE;
+ }
+
+ {
+ /* Warn about the incompatibility */
+ CHAR msg[MAX_PATHNAME_LEN + 200];
+ wsprintf(msg,
+ "Group files written by this DRAFT Program Manager "
+ "cannot be read by the Microsoft Program Manager!!\n"
+ "Are you sure to write %s?", szPath);
+ if (IDOK != MessageBox(Globals.hMainWnd, msg, "WARNING",
+ MB_OKCANCEL | MB_DEFBUTTON2)) return FALSE;
+ }
+
+ /* FIXME */
+ if (OpenFile(szPath, &dummy, OF_EXIST) == HFILE_ERROR)
+ {
+ CHAR msg[MAX_PATHNAME_LEN + 200];
+ wsprintf(msg, "Cause of a bug you must now touch the file %s\n", szPath);
+ MessageBox(Globals.hMainWnd, msg, "", MB_OK);
+ }
+
+ /* Open file */
+ file = _lopen(szPath, OF_WRITE);
+ if (file != HFILE_ERROR)
+ {
+ ret = GRPFILE_DoWriteGroupFile(file, group);
+ _lclose(file);
+ }
+ else ret = FALSE;
+
+ if (!ret) MAIN_FileWriteError(szPath);
+
+ return(ret);
+}
+
+/***********************************************************************
+ *
+ * GRPFILE_CalculateSizes
+ */
+
+static VOID GRPFILE_CalculateSizes(PROGRAM *program,
+ INT *Progs, INT *Icons)
+{
+ CURSORICONINFO *iconinfo = LocalLock(program->hIcon);
+ INT sizeXor = iconinfo->nHeight * iconinfo->nWidthBytes;
+ INT sizeAnd = iconinfo->nHeight * ((iconinfo->nWidth + 15) / 16 * 2);
+
+ *Progs += 24;
+ *Progs += lstrlen(LocalLock(program->hName)) + 1;
+ *Progs += lstrlen(LocalLock(program->hCmdLine)) + 1;
+ *Progs += lstrlen(LocalLock(program->hIconFile)) + 1;
+
+ *Icons += 12; /* IconInfo */
+ *Icons += sizeAnd;
+ *Icons += sizeXor;
+}
+
+/***********************************************************************
+ *
+ * GRPFILE_DoWriteGroupFile
+ */
+
+static BOOL GRPFILE_DoWriteGroupFile(HFILE file, GROUP *group)
+{
+ BYTE buffer[34];
+ HLOCAL hProgram;
+ INT NumProg, Title, Progs, Icons, Extension;
+ INT CurrProg, CurrIcon, nCmdShow, ptr, seqnum;
+ BOOL need_extension;
+ LPCSTR lpszTitle = LocalLock(group->hName);
+
+ /* Calculate offsets */
+ NumProg = 0;
+ Icons = 0;
+ Extension = 0;
+ need_extension = FALSE;
+ hProgram = group->hPrograms;
+ while(hProgram)
+ {
+ PROGRAM *program = LocalLock(hProgram);
+ LPCSTR lpszWorkDir = LocalLock(program->hWorkDir);
+
+ NumProg++;
+ GRPFILE_CalculateSizes(program, &Icons, &Extension);
+
+ /* Set a flag if an extension is needed */
+ if (lpszWorkDir[0] || program->nHotKey ||
+ program->nCmdShow != SW_SHOWNORMAL) need_extension = TRUE;
+
+ hProgram = program->hNext;
+ }
+ Title = 34 + NumProg * 2;
+ Progs = Title + lstrlen(lpszTitle) + 1;
+ Icons += Progs;
+ Extension += Icons;
+
+ /* Header */
+ buffer[0] = 'P';
+ buffer[1] = 'M';
+#if 0
+ buffer[2] = 'C'; /* Original magic number */
+ buffer[3] = 'C';
+#else
+ buffer[2] = 'X'; /* Modified magic number: no checksum */
+ buffer[3] = 'X';
+#endif
+ PUT_SHORT(buffer, 4, 0); /* Checksum ignored */
+ PUT_SHORT(buffer, 6, Extension);
+ /* Update group->nCmdShow */
+ if (IsIconic(group->hWnd)) nCmdShow = SW_SHOWMINIMIZED;
+ else if (IsZoomed(group->hWnd)) nCmdShow = SW_SHOWMAXIMIZED;
+ else nCmdShow = SW_SHOWNORMAL;
+ PUT_SHORT(buffer, 8, nCmdShow);
+ PUT_SHORT(buffer, 10, group->x);
+ PUT_SHORT(buffer, 12, group->y);
+ PUT_SHORT(buffer, 14, group->width);
+ PUT_SHORT(buffer, 16, group->height);
+ PUT_SHORT(buffer, 18, group->iconx);
+ PUT_SHORT(buffer, 20, group->icony);
+ PUT_SHORT(buffer, 22, Title);
+ PUT_SHORT(buffer, 24, 0x0020); /* unknown */
+ PUT_SHORT(buffer, 26, 0x0020); /* unknown */
+ PUT_SHORT(buffer, 28, 0x0108); /* unknown */
+ PUT_SHORT(buffer, 30, 0x0000); /* unknown */
+ PUT_SHORT(buffer, 32, NumProg);
+
+ if (HFILE_ERROR == _lwrite(file, buffer, 34)) return FALSE;
+
+ /* Program table */
+ CurrProg = Progs;
+ CurrIcon = Icons;
+ hProgram = group->hPrograms;
+ while(hProgram)
+ {
+ PROGRAM *program = LocalLock(hProgram);
+
+ PUT_SHORT(buffer, 0, CurrProg);
+ if (HFILE_ERROR == _lwrite(file, buffer, 2)) return FALSE;
+
+ GRPFILE_CalculateSizes(program, &CurrProg, &CurrIcon);
+ hProgram = program->hNext;
+ }
+
+ /* Title */
+ if (HFILE_ERROR == _lwrite(file, lpszTitle, lstrlen(lpszTitle) + 1))
+ return FALSE;
+
+ /* Program entries */
+ CurrProg = Progs;
+ CurrIcon = Icons;
+ hProgram = group->hPrograms;
+ while(hProgram)
+ {
+ PROGRAM *program = LocalLock(hProgram);
+ CURSORICONINFO *iconinfo = LocalLock(program->hIcon);
+ LPCSTR Name = LocalLock(program->hName);
+ LPCSTR CmdLine = LocalLock(program->hCmdLine);
+ LPCSTR IconFile = LocalLock(program->hIconFile);
+ INT sizeXor = iconinfo->nHeight * iconinfo->nWidthBytes;
+ INT sizeAnd = iconinfo->nHeight * ((iconinfo->nWidth + 15) / 16 * 2);
+
+ PUT_SHORT(buffer, 0, program->x);
+ PUT_SHORT(buffer, 2, program->y);
+ PUT_SHORT(buffer, 4, program->nIconIndex);
+ PUT_SHORT(buffer, 6, 0x048c); /* unknown */
+ PUT_SHORT(buffer, 8, sizeXor);
+ PUT_SHORT(buffer, 10, sizeAnd * 8);
+ PUT_SHORT(buffer, 12, CurrIcon);
+ PUT_SHORT(buffer, 14, CurrIcon + 12 + sizeAnd);
+ PUT_SHORT(buffer, 16, CurrIcon + 12);
+ ptr = CurrProg + 24;
+ PUT_SHORT(buffer, 18, ptr);
+ ptr += lstrlen(Name) + 1;
+ PUT_SHORT(buffer, 20, ptr);
+ ptr += lstrlen(CmdLine) + 1;
+ PUT_SHORT(buffer, 22, ptr);
+
+ if (HFILE_ERROR == _lwrite(file, buffer, 24) ||
+ HFILE_ERROR == _lwrite(file, Name, lstrlen(Name) + 1) ||
+ HFILE_ERROR == _lwrite(file, CmdLine, lstrlen(CmdLine) + 1) ||
+ HFILE_ERROR == _lwrite(file, IconFile, lstrlen(IconFile) + 1))
+ return FALSE;
+
+ GRPFILE_CalculateSizes(program, &CurrProg, &CurrIcon);
+ hProgram = program->hNext;
+ }
+
+ /* Icons */
+ hProgram = group->hPrograms;
+ while(hProgram)
+ {
+ PROGRAM *program = LocalLock(hProgram);
+ CURSORICONINFO *iconinfo = LocalLock(program->hIcon);
+ SEGPTR XorBits, AndBits;
+ INT sizeXor = iconinfo->nHeight * iconinfo->nWidthBytes;
+ INT sizeAnd = iconinfo->nHeight * ((iconinfo->nWidth + 15) / 16 * 2);
+ DumpIcon(LocalLock(program->hIcon), 0, &XorBits, &AndBits);
+
+ PUT_SHORT(buffer, 0, iconinfo->ptHotSpot.x);
+ PUT_SHORT(buffer, 2, iconinfo->ptHotSpot.y);
+ PUT_SHORT(buffer, 4, iconinfo->nWidth);
+ PUT_SHORT(buffer, 6, iconinfo->nHeight);
+ PUT_SHORT(buffer, 8, iconinfo->nWidthBytes);
+ buffer[10] = iconinfo->bPlanes;
+ buffer[11] = iconinfo->bBitsPerPixel;
+
+ if (HFILE_ERROR == _lwrite(file, buffer, 12) ||
+ HFILE_ERROR == _lwrite(file, AndBits, sizeAnd) ||
+ HFILE_ERROR == _lwrite(file, XorBits, sizeXor)) return FALSE;
+
+ hProgram = program->hNext;
+ }
+
+ if (need_extension)
+ {
+ /* write `PMCC' extension */
+ PUT_SHORT(buffer, 0, 0x8000);
+ PUT_SHORT(buffer, 2, 0xffff);
+ PUT_SHORT(buffer, 4, 0x000a);
+ buffer[6] = 'P', buffer[7] = 'M';
+ buffer[8] = 'C', buffer[9] = 'C';
+ if (HFILE_ERROR == _lwrite(file, buffer, 10)) return FALSE;
+
+ seqnum = 0;
+ hProgram = group->hPrograms;
+ while(hProgram)
+ {
+ PROGRAM *program = LocalLock(hProgram);
+ LPCSTR lpszWorkDir = LocalLock(program->hWorkDir);
+
+ /* Working directory */
+ if (lpszWorkDir[0])
+ {
+ PUT_SHORT(buffer, 0, 0x8101);
+ PUT_SHORT(buffer, 2, seqnum);
+ PUT_SHORT(buffer, 4, 7 + lstrlen(lpszWorkDir));
+ if (HFILE_ERROR == _lwrite(file, buffer, 6) ||
+ HFILE_ERROR == _lwrite(file, lpszWorkDir, lstrlen(lpszWorkDir) + 1))
+ return FALSE;
+ }
+
+ /* Hot key */
+ if (program->nHotKey)
+ {
+ PUT_SHORT(buffer, 0, 0x8102);
+ PUT_SHORT(buffer, 2, seqnum);
+ PUT_SHORT(buffer, 4, 8);
+ PUT_SHORT(buffer, 6, program->nHotKey);
+ if (HFILE_ERROR == _lwrite(file, buffer, 8)) return FALSE;
+ }
+
+ /* Show command */
+ if (program->nCmdShow)
+ {
+ PUT_SHORT(buffer, 0, 0x8103);
+ PUT_SHORT(buffer, 2, seqnum);
+ PUT_SHORT(buffer, 4, 8);
+ PUT_SHORT(buffer, 6, program->nCmdShow);
+ if (HFILE_ERROR == _lwrite(file, buffer, 8)) return FALSE;
+ }
+
+ seqnum++;
+ hProgram = program->hNext;
+ }
+
+ /* Write `End' extension */
+ PUT_SHORT(buffer, 0, 0xffff);
+ PUT_SHORT(buffer, 2, 0xffff);
+ PUT_SHORT(buffer, 4, 0x0000);
+ if (HFILE_ERROR == _lwrite(file, buffer, 6)) return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Local Variables: */
+/* c-file-style: "GNU" */
+/* End: */
diff --git a/programs/progman/license.c b/programs/progman/license.c
new file mode 100644
index 0000000..14308cd
--- /dev/null
+++ b/programs/progman/license.c
@@ -0,0 +1,32 @@
+#include <windows.h>
+#include "license.h"
+
+static LICENSE* SelectLanguage(LPCSTR Language)
+{
+#if 0
+ if (!lstrcmp(Language, "Da")) return(&WineLicense_Cz);
+ if (!lstrcmp(Language, "Da")) return(&WineLicense_Da);
+ if (!lstrcmp(Language, "De")) return(&WineLicense_De);
+ if (!lstrcmp(Language, "Es")) return(&WineLicense_Es);
+ if (!lstrcmp(Language, "Fi")) return(&WineLicense_Fi);
+ if (!lstrcmp(Language, "Fr")) return(&WineLicense_Fr);
+ if (!lstrcmp(Language, "No")) return(&WineLicense_No);
+#endif
+ return(&WineLicense_En);
+}
+
+VOID WineLicense(HWND Wnd, LPCSTR Language)
+{
+ LICENSE *License = SelectLanguage(Language);
+
+ MessageBox(Wnd, License->License, License->LicenseCaption,
+ MB_ICONINFORMATION | MB_OK);
+}
+
+VOID WineWarranty(HWND Wnd, LPCSTR Language)
+{
+ LICENSE *License = SelectLanguage(Language);
+
+ MessageBox(Wnd, License->Warranty, License->WarrantyCaption,
+ MB_ICONEXCLAMATION | MB_OK);
+}
diff --git a/programs/progman/license.h b/programs/progman/license.h
new file mode 100644
index 0000000..97fa9ba
--- /dev/null
+++ b/programs/progman/license.h
@@ -0,0 +1,11 @@
+VOID WineLicense(HWND hWnd, LPCSTR lpszLanguage);
+VOID WineWarranty(HWND hWnd, LPCSTR language);
+
+typedef struct
+{
+ LPCSTR License, LicenseCaption;
+ LPCSTR Warranty, WarrantyCaption;
+} LICENSE;
+
+extern LICENSE WineLicense_Cz, WineLicense_Da, WineLicense_De, WineLicense_En;
+extern LICENSE WineLicense_Es, WineLicense_Fi, WineLicense_Fr, WineLicense_No;
diff --git a/programs/progman/main.c b/programs/progman/main.c
new file mode 100644
index 0000000..f6173e2
--- /dev/null
+++ b/programs/progman/main.c
@@ -0,0 +1,553 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid <uschmid@mail.hh.provi.de>
+ */
+
+#include <stdio.h>
+#include <windows.h>
+#include "license.h"
+#include "progman.h"
+#ifdef WINELIB
+#include <options.h>
+#include <shell.h>
+#endif
+
+GLOBALS Globals;
+
+static VOID MAIN_CreateGroups(void);
+static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
+static ATOM MAIN_RegisterMainWinClass(void);
+static VOID MAIN_CreateMainWindow(void);
+static VOID MAIN_CreateMDIWindow(void);
+static VOID MAIN_AutoStart(void);
+
+#define BUFFER_SIZE 1000
+
+/***********************************************************************
+ *
+ * WinMain
+ */
+
+int PASCAL WinMain (HANDLE hInstance, HANDLE prev, LPSTR cmdline, int show)
+{
+ MSG msg;
+
+#ifndef WINELIB
+ Globals.lpszIniFile = "progman.ini";
+ Globals.lpszIcoFile = "progman.ico";
+#else /* Configuration in `wine.ini' */
+ {
+ CHAR buffer[MAX_PATHNAME_LEN], *p;
+
+ /* Redirect `progman.ini' */
+ PROFILE_GetWineIniString("progman", "progman.ini", "progman.ini",
+ buffer, sizeof(buffer));
+ Globals.lpszIniFile = p = LocalLock(LocalAlloc(LMEM_FIXED, lstrlen(buffer)));
+ hmemcpy(p, buffer, 1 + lstrlen(buffer));
+
+ /* Redirect `progman.ico' */
+ PROFILE_GetWineIniString("progman", "progman.ico", "progman.ico",
+ buffer, sizeof(buffer));
+ Globals.lpszIcoFile = p = LocalLock(LocalAlloc(LMEM_FIXED, lstrlen(buffer)));
+ hmemcpy(p, buffer, 1 + lstrlen(buffer));
+ }
+#endif
+
+ /* Select Language */
+ Globals.lpszLanguage = "En";
+#ifdef WINELIB
+ if (Options.language == LANG_Cz) Globals.lpszLanguage = "Cz";
+ if (Options.language == LANG_Da) Globals.lpszLanguage = "Da";
+ if (Options.language == LANG_De) Globals.lpszLanguage = "De";
+ if (Options.language == LANG_Es) Globals.lpszLanguage = "Es";
+ if (Options.language == LANG_Fi) Globals.lpszLanguage = "Fi";
+ if (Options.language == LANG_Fr) Globals.lpszLanguage = "Fr";
+ if (Options.language == LANG_No) Globals.lpszLanguage = "No";
+#ifndef HAVE_WINE_CONSTRUCTOR
+ /* Register resources */
+ LIBWINE_Register_accel();
+ LIBWINE_Register_De();
+ LIBWINE_Register_En();
+#endif
+#endif
+
+ Globals.hInstance = hInstance;
+ Globals.hGroups = 0;
+
+ /* FIXME should use MDI */
+ Globals.hActiveGroup = 0;
+
+ /* Read Options from `progman.ini' */
+ Globals.bAutoArrange =
+ GetPrivateProfileInt("Settings", "AutoArrange", 0, Globals.lpszIniFile);
+ Globals.bMinOnRun =
+ GetPrivateProfileInt("Settings", "MinOnRun", 0, Globals.lpszIniFile);
+ Globals.bSaveSettings =
+ GetPrivateProfileInt("Settings", "SaveSettings", 0, Globals.lpszIniFile);
+
+ /* Load default icons */
+ Globals.hMainIcon = ExtractIcon(Globals.hInstance, Globals.lpszIcoFile, 0);
+ Globals.hGroupIcon = ExtractIcon(Globals.hInstance, Globals.lpszIcoFile, 0);
+ Globals.hDefaultIcon = ExtractIcon(Globals.hInstance, Globals.lpszIcoFile, 0);
+ if (!Globals.hMainIcon) Globals.hMainIcon = LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON));
+ if (!Globals.hGroupIcon) Globals.hGroupIcon = LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON));
+ if (!Globals.hDefaultIcon) Globals.hDefaultIcon = LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON));
+
+ /* Register classes */
+ if (!prev)
+ {
+ if (!MAIN_RegisterMainWinClass()) return(FALSE);
+ if (!GROUP_RegisterGroupWinClass()) return(FALSE);
+ if (!PROGRAM_RegisterProgramWinClass()) return(FALSE);
+ }
+
+ /* Create main window */
+ MAIN_CreateMainWindow();
+ Globals.hAccel = LoadAccelerators(Globals.hInstance, STRING_ACCEL);
+
+ /* Setup menu, stringtable and resourcenames */
+ STRING_SelectLanguage(Globals.lpszLanguage);
+
+ MAIN_CreateMDIWindow();
+
+ /* Initialize groups */
+ MAIN_CreateGroups();
+
+ /* Start initial applications */
+ MAIN_AutoStart();
+
+ /* Message loop */
+ while (GetMessage (&msg, 0, 0, 0))
+ if (!TranslateAccelerator(Globals.hMainWnd, Globals.hAccel, &msg))
+ {
+ TranslateMessage (&msg);
+ DispatchMessage (&msg);
+ }
+ return 0;
+}
+
+/***********************************************************************
+ *
+ * MAIN_CreateGroups
+ */
+
+static VOID MAIN_CreateGroups()
+{
+ CHAR buffer[BUFFER_SIZE];
+ CHAR szPath[MAX_PATHNAME_LEN];
+ CHAR key[20], *ptr;
+
+ /* Initialize groups according the `Order' entry of `progman.ini' */
+ GetPrivateProfileString("Settings", "Order", "", buffer, sizeof(buffer), Globals.lpszIniFile);
+ ptr = buffer;
+ while (ptr < buffer + sizeof(buffer))
+ {
+ int num, skip, ret;
+ ret = sscanf(ptr, "%d%n", &num, &skip);
+ if (ret == 0) MAIN_FileReadError(Globals.lpszIniFile);
+ if (ret != 1) break;
+
+ sprintf(key, "Group%d", num);
+ GetPrivateProfileString("Groups", key, "", szPath,
+ sizeof(szPath), Globals.lpszIniFile);
+ if (!szPath[0]) continue;
+
+ GRPFILE_ReadGroupFile(szPath);
+
+ ptr += skip;
+ }
+ /* FIXME initialize other groups, not enumerated by `Order' */
+}
+
+/***********************************************************************
+ *
+ * MAIN_AutoStart
+ */
+
+VOID MAIN_AutoStart()
+{
+ CHAR buffer[BUFFER_SIZE];
+ HLOCAL hGroup, hProgram;
+
+ GetPrivateProfileString("Settings", "AutoStart", "Autostart", buffer,
+ sizeof(buffer), Globals.lpszIniFile);
+
+ for (hGroup = GROUP_FirstGroup(); hGroup; hGroup = GROUP_NextGroup(hGroup))
+ if (!lstrcmp(buffer, GROUP_GroupName(hGroup)))
+ for (hProgram = PROGRAM_FirstProgram(hGroup); hProgram;
+ hProgram = PROGRAM_NextProgram(hProgram))
+ PROGRAM_ExecuteProgram(hProgram);
+}
+
+/***********************************************************************
+ *
+ * MAIN_MainWndProc
+ */
+
+static LRESULT MAIN_MainWndProc (HWND hWnd, UINT msg,
+ WPARAM wParam, LPARAM lParam)
+{
+#if 0
+ printf("M %4.4x %4.4x\n", msg, wParam);
+#endif
+ switch (msg)
+ {
+ case WM_INITMENU:
+ CheckMenuItem(Globals.hOptionMenu, PM_AUTO_ARRANGE,
+ MF_BYCOMMAND | (Globals.bAutoArrange ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(Globals.hOptionMenu, PM_MIN_ON_RUN,
+ MF_BYCOMMAND | (Globals.bMinOnRun ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(Globals.hOptionMenu, PM_SAVE_SETTINGS,
+ MF_BYCOMMAND | (Globals.bSaveSettings ? MF_CHECKED : MF_UNCHECKED));
+ break;
+
+ case WM_COMMAND:
+ if (wParam < PM_FIRST_CHILD)
+ MAIN_MenuCommand(hWnd, wParam, lParam);
+ break;
+
+ case WM_DESTROY:
+ PostQuitMessage (0);
+ break;
+ }
+ return(DefFrameProc(hWnd, Globals.hMDIWnd, msg, wParam, lParam));
+}
+
+/***********************************************************************
+ *
+ * MAIN_MenuCommand
+ */
+
+static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+ HLOCAL hActiveGroup = GROUP_ActiveGroup();
+ HLOCAL hActiveProgram = PROGRAM_ActiveProgram(hActiveGroup);
+ HWND hActiveGroupWnd = GROUP_GroupWnd(hActiveGroup);
+
+ switch(wParam)
+ {
+ /* Menu File */
+ case PM_NEW:
+ switch (DIALOG_New((hActiveGroupWnd && !IsIconic(hActiveGroupWnd)) ?
+ PM_NEW_PROGRAM : PM_NEW_GROUP))
+ {
+ case PM_NEW_PROGRAM:
+ if (hActiveGroup) PROGRAM_NewProgram(hActiveGroup);
+ break;
+
+ case PM_NEW_GROUP:
+ GROUP_NewGroup();
+ break;
+ }
+ break;
+
+ case PM_OPEN:
+ if (hActiveProgram)
+ PROGRAM_ExecuteProgram(hActiveProgram);
+ else if (hActiveGroupWnd)
+ OpenIcon(hActiveGroupWnd);
+ break;
+
+ case PM_MOVE:
+ case PM_COPY:
+ if (hActiveProgram)
+ PROGRAM_CopyMoveProgram(hActiveProgram, wParam == PM_MOVE);
+ break;
+
+ case PM_DELETE:
+ if (hActiveProgram)
+ {
+ if (DIALOG_Delete(STRING_DELETE_PROGRAM_s, PROGRAM_ProgramName(hActiveProgram)))
+ PROGRAM_DeleteProgram(hActiveProgram, TRUE);
+ }
+ else if (hActiveGroup)
+ {
+ if (DIALOG_Delete(STRING_DELETE_GROUP_s, GROUP_GroupName(hActiveGroup)))
+ GROUP_DeleteGroup(hActiveGroup);
+ }
+ break;
+
+ case PM_ATTRIBUTES:
+ if (hActiveProgram)
+ PROGRAM_ModifyProgram(hActiveProgram);
+ else if (hActiveGroup)
+ GROUP_ModifyGroup(hActiveGroup);
+ break;
+
+ case PM_EXECUTE:
+ DIALOG_Execute();
+ break;
+
+ case PM_EXIT:
+ PostQuitMessage(0);
+ break;
+
+ /* Menu Options */
+ case PM_AUTO_ARRANGE:
+ Globals.bAutoArrange = !Globals.bAutoArrange;
+ CheckMenuItem(Globals.hOptionMenu, PM_AUTO_ARRANGE,
+ MF_BYCOMMAND | (Globals.bAutoArrange ?
+ MF_CHECKED : MF_UNCHECKED));
+ WritePrivateProfileString("Settings", "AutoArrange",
+ Globals.bAutoArrange ? "1" : "0",
+ Globals.lpszIniFile);
+ WriteOutProfiles();
+ break;
+
+ case PM_MIN_ON_RUN:
+ Globals.bMinOnRun = !Globals.bMinOnRun;
+ CheckMenuItem(Globals.hOptionMenu, PM_MIN_ON_RUN,
+ MF_BYCOMMAND | (Globals.bMinOnRun ?
+ MF_CHECKED : MF_UNCHECKED));
+ WritePrivateProfileString("Settings", "MinOnRun",
+ Globals.bMinOnRun ? "1" : "0",
+ Globals.lpszIniFile);
+ WriteOutProfiles();
+ break;
+
+ case PM_SAVE_SETTINGS:
+ Globals.bSaveSettings = !Globals.bSaveSettings;
+ CheckMenuItem(Globals.hOptionMenu, PM_SAVE_SETTINGS,
+ MF_BYCOMMAND | (Globals.bSaveSettings ?
+ MF_CHECKED : MF_UNCHECKED));
+ WritePrivateProfileString("Settings", "SaveSettings",
+ Globals.bSaveSettings ? "1" : "0",
+ Globals.lpszIniFile);
+ WriteOutProfiles();
+ break;
+
+ /* Menu Windows */
+ case PM_ARRANGE:
+ SendMessage(Globals.hMDIWnd, WM_MDIICONARRANGE, 0, 0);
+ break;
+
+ /* Menu Language */
+ case PM_Da: STRING_SelectLanguage("Da"); break;
+ case PM_De: STRING_SelectLanguage("De"); break;
+ case PM_En: STRING_SelectLanguage("En"); break;
+ case PM_Es: STRING_SelectLanguage("Es"); break;
+ case PM_Fi: STRING_SelectLanguage("Fi"); break;
+ case PM_Fr: STRING_SelectLanguage("Fr"); break;
+ case PM_No: STRING_SelectLanguage("No"); break;
+
+ /* Menu Help */
+ case PM_CONTENTS:
+ if (!WinHelp(Globals.hMainWnd, "progman.hlp", HELP_INDEX, 0))
+ MAIN_WinHelpError();
+ break;
+
+ case PM_HELPONHELP:
+ if (!WinHelp(Globals.hMainWnd, "progman.hlp", HELP_HELPONHELP, 0))
+ MAIN_WinHelpError();
+ break;
+
+ case PM_TUTORIAL:
+ WinExec("wintutor.exe", SW_SHOWNORMAL);
+ break;
+
+ case PM_LICENSE:
+ WineLicense(Globals.hMainWnd, Globals.lpszLanguage);
+ break;
+
+ case PM_NO_WARRANTY:
+ WineWarranty(Globals.hMainWnd, Globals.lpszLanguage);
+ break;
+
+#ifdef WINELIB
+ case PM_ABOUT_WINE:
+ {
+ extern const char people[];
+ ShellAbout(hWnd, "WINE", people, 0);
+ }
+ break;
+#endif
+
+ default:
+ MAIN_NotImplementedError();
+ break;
+ }
+}
+
+/***********************************************************************
+ *
+ * MAIN_RegisterMainWinClass
+ */
+
+static ATOM MAIN_RegisterMainWinClass()
+{
+ WNDCLASS class;
+
+ class.style = CS_HREDRAW | CS_VREDRAW;
+ class.lpfnWndProc = MAIN_MainWndProc;
+ class.cbClsExtra = 0;
+ class.cbWndExtra = 0;
+ class.hInstance = Globals.hInstance;
+ class.hIcon = Globals.hMainIcon;
+ class.hCursor = LoadCursor (0, IDC_ARROW);
+ class.hbrBackground = GetStockObject (NULL_BRUSH);
+ class.lpszMenuName = 0;
+ class.lpszClassName = STRING_MAIN_WIN_CLASS_NAME;
+
+ return RegisterClass(&class);
+}
+
+/***********************************************************************
+ *
+ * MAIN_CreateMainWindow
+ */
+
+static VOID MAIN_CreateMainWindow()
+{
+ INT left , top, right, bottom, width, height, show;
+ CHAR buffer[100];
+
+ Globals.hMDIWnd = 0;
+ Globals.hMainMenu = 0;
+
+ /* Get the geometry of the main window */
+ GetPrivateProfileString("Settings", "Window", "",
+ buffer, sizeof(buffer), Globals.lpszIniFile);
+ if (5 == sscanf(buffer, "%d %d %d %d %d", &left, &top, &right, &bottom, &show))
+ {
+ width = right - left;
+ height = bottom - top;
+ }
+ else
+ {
+ left = top = width = height = CW_USEDEFAULT;
+ show = SW_SHOWNORMAL;
+ }
+
+ /* Create main Window */
+ Globals.hMainWnd =
+ CreateWindow (STRING_MAIN_WIN_CLASS_NAME, "",
+ WS_OVERLAPPEDWINDOW, left, top, width, height,
+ 0, 0, Globals.hInstance, 0);
+
+ ShowWindow (Globals.hMainWnd, show);
+ UpdateWindow (Globals.hMainWnd);
+}
+
+/***********************************************************************
+ *
+ * MAIN_CreateMDIWindow
+ */
+
+static VOID MAIN_CreateMDIWindow()
+{
+ CLIENTCREATESTRUCT ccs;
+ RECT rect;
+
+ /* Get the geometry of the MDI window */
+ GetClientRect(Globals.hMainWnd, &rect);
+
+ ccs.hWindowMenu = Globals.hWindowsMenu;
+ ccs.idFirstChild = PM_FIRST_CHILD;
+
+ /* Create MDI Window */
+ Globals.hMDIWnd =
+ CreateWindow (STRING_MDI_WIN_CLASS_NAME, "",
+ WS_CHILD, rect.left, rect.top,
+ rect.right - rect.left, rect.bottom - rect.top,
+ Globals.hMainWnd, 0,
+ Globals.hInstance, &ccs);
+
+ ShowWindow (Globals.hMDIWnd, SW_SHOW);
+ UpdateWindow (Globals.hMDIWnd);
+}
+
+/**********************************************************************/
+/***********************************************************************
+ *
+ * MAIN_ReplaceString
+ */
+
+VOID MAIN_ReplaceString(HLOCAL *handle, LPSTR replace)
+{
+ HLOCAL newhandle = LocalAlloc(LMEM_FIXED, strlen(replace) + 1);
+ if (newhandle)
+ {
+ LPSTR newstring = LocalLock(newhandle);
+ lstrcpy(newstring, replace);
+ LocalFree(*handle);
+ *handle = newhandle;
+ }
+ else MAIN_OutOfMemoryError();
+}
+
+/***********************************************************************
+ *
+ * MAIN_NotImplementedError
+ */
+
+VOID MAIN_NotImplementedError()
+{
+ MessageBox(Globals.hMainWnd,
+ STRING_NOT_IMPLEMENTED, STRING_ERROR, MB_OK);
+}
+
+/***********************************************************************
+ *
+ * MAIN_OutOfMemoryError
+ */
+
+VOID MAIN_OutOfMemoryError()
+{
+ MessageBox(Globals.hMainWnd,
+ STRING_OUT_OF_MEMORY, STRING_ERROR, MB_OK);
+}
+
+/***********************************************************************
+ *
+ * MAIN_WinHelpError
+ */
+
+VOID MAIN_WinHelpError()
+{
+ MessageBox(Globals.hMainWnd,
+ STRING_WINHELP_ERROR, STRING_ERROR, MB_OK);
+}
+
+/***********************************************************************
+ *
+ * MAIN_FileReadError
+ */
+
+VOID MAIN_FileReadError(LPCSTR lpszPath)
+{
+ CHAR msg[MAX_PATHNAME_LEN + 1000];
+ if (sizeof(msg) <= strlen(STRING_FILE_READ_ERROR_s) + strlen(lpszPath)) return;
+ wsprintf(msg, (LPSTR)STRING_FILE_READ_ERROR_s, lpszPath);
+ MessageBox(Globals.hMainWnd, msg, STRING_ERROR, MB_OK);
+}
+
+/***********************************************************************
+ *
+ * MAIN_FileWriteError
+ */
+
+VOID MAIN_FileWriteError(LPCSTR lpszPath)
+{
+ CHAR msg[MAX_PATHNAME_LEN + 1000];
+ if (sizeof(msg) <= strlen(STRING_FILE_WRITE_ERROR_s) + strlen(lpszPath)) return;
+ wsprintf(msg, (LPSTR)STRING_FILE_WRITE_ERROR_s, lpszPath);
+ MessageBox(Globals.hMainWnd, msg, STRING_ERROR, MB_OK);
+}
+
+/***********************************************************************
+ *
+ * MAIN_GrpFileReadError
+ */
+
+VOID MAIN_GrpFileReadError(LPCSTR lpszPath)
+{
+ CHAR msg[MAX_PATHNAME_LEN + 1000];
+ if (sizeof(msg) <= strlen(STRING_GRPFILE_READ_ERROR_s) + strlen(lpszPath)) return;
+ wsprintf(msg, (LPSTR)STRING_GRPFILE_READ_ERROR_s, lpszPath);
+ MessageBox(Globals.hMainWnd, msg, STRING_ERROR, MB_YESNO);
+}
+
+/* Local Variables: */
+/* c-file-style: "GNU" */
+/* End: */
diff --git a/programs/progman/progman.h b/programs/progman/progman.h
new file mode 100644
index 0000000..5d72ed9
--- /dev/null
+++ b/programs/progman/progman.h
@@ -0,0 +1,347 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+#ifndef PROGMAN_H
+#define PROGMAN_H
+
+#ifndef RC_INVOKED
+
+#include "windows.h"
+
+/* FIXME should use WinExec from -lwine */
+#ifdef WINELIB
+#define WinExec ProgmanWinExec
+#define WinHelp ProgmanWinHelp
+HANDLE ProgmanWinExec(LPSTR,WORD);
+BOOL ProgmanWinHelp(HWND,LPSTR,WORD,DWORD);
+#endif
+
+#define MAX_PATHNAME_LEN 1024
+
+/* Fallback icon */
+#ifdef WINELIB
+#define DEFAULTICON OIC_WINEICON
+#else
+#define DEFAULTICON OIC_LANDSCAPE
+#endif
+
+/* Icon index in M$ Window's progman.exe */
+#define PROGMAN_ICON_INDEX 0
+#define GROUP_ICON_INDEX 6
+#define DEFAULT_ICON_INDEX 7
+
+#define DEF_GROUP_WIN_XPOS 100
+#define DEF_GROUP_WIN_YPOS 100
+#define DEF_GROUP_WIN_WIDTH 300
+#define DEF_GROUP_WIN_HEIGHT 200
+
+typedef struct
+{
+ HLOCAL hGroup;
+ HLOCAL hPrior;
+ HLOCAL hNext;
+ HWND hWnd;
+ /**/ /* Numbers are byte indexes in *.grp */
+
+ /**/ /* Program entry */
+ INT x, y; /* 0 - 3 */
+ INT nIconIndex; /* 4 - 5 */
+ HICON hIcon;
+ /* icon flags ??? */ /* 6 - 7 */
+ /* iconANDsize */ /* 8 - 9 */
+ /* iconXORsize */ /* 10 - 11 */
+ /* pointer to IconInfo */ /* 12 - 13 */
+ /* pointer to iconXORbits */ /* 14 - 15 */ /* sometimes iconANDbits ?! */
+ /* pointer to iconANDbits */ /* 16 - 17 */ /* sometimes iconXORbits ?! */
+ HLOCAL hName; /* 18 - 19 */
+ HLOCAL hCmdLine; /* 20 - 21 */
+ HLOCAL hIconFile; /* 22 - 23 */
+ HLOCAL hWorkDir; /* Extension 0x8101 */
+ INT nHotKey; /* Extension 0x8102 */
+ /* Modifier: bit 8... */
+ INT nCmdShow; /* Extension 0x8103 */
+
+ /**/ /* IconInfo */
+ /* HotSpot x ??? */ /* 0 - 1 */
+ /* HotSpot y ??? */ /* 2 - 3 */
+ /* Width */ /* 4 - 5 */
+ /* Height */ /* 6 - 7 */
+ /* WidthBytes ??? */ /* 8 - 9 */
+ /* Planes */ /* 10 - 10 */
+ /* BitsPerPixel */ /* 11 - 11 */
+} PROGRAM;
+
+typedef struct
+{
+ HLOCAL hPrior;
+ HLOCAL hNext;
+ HWND hWnd;
+ HLOCAL hGrpFile;
+ HLOCAL hActiveProgram;
+ BOOL bFileNameModified;
+ BOOL bOverwriteFileOk;
+ INT seqnum;
+
+ /**/ /* Absolute */
+ /* magic `PMCC' */ /* 0 - 3 */
+ /* checksum */ /* 4 - 5 */
+ /* Extension ptr */ /* 6 - 7 */
+ INT nCmdShow; /* 8 - 9 */
+ INT x, y; /* 10 - 13 */
+ INT width, height; /* 14 - 17 */
+ INT iconx, icony; /* 18 - 21 */
+ HLOCAL hName; /* 22 - 23 */
+ /* unknown */ /* 24 - 31 */
+ /* number of programs */ /* 32 - 33 */
+ HLOCAL hPrograms; /* 34 ... */
+
+ /**/ /* Extensions */
+ /* Extension type */ /* 0 - 1 */
+ /* Program number */ /* 2 - 3 */
+ /* Size of entry */ /* 4 - 5 */
+ /* Data */ /* 6 ... */
+
+ /* magic `PMCC' */ /* Extension 0x8000 */
+ /* End of Extensions */ /* Extension 0xffff */
+} GROUP;
+
+typedef struct
+{
+ HANDLE hInstance;
+ HANDLE hAccel;
+ HWND hMainWnd;
+ HWND hMDIWnd;
+ HICON hMainIcon;
+ HICON hGroupIcon;
+ HICON hDefaultIcon;
+ HMENU hMainMenu;
+ HMENU hFileMenu;
+ HMENU hOptionMenu;
+ HMENU hWindowsMenu;
+ LPCSTR lpszIniFile;
+ LPCSTR lpszIcoFile;
+ BOOL bAutoArrange;
+ BOOL bSaveSettings;
+ BOOL bMinOnRun;
+ HLOCAL hGroups;
+ LPCSTR lpszLanguage;
+ LPCSTR *StringTable;
+ /* FIXME should use MDI */
+ HLOCAL hActiveGroup;
+} GLOBALS;
+
+extern GLOBALS Globals;
+
+VOID MAIN_ReplaceString(HLOCAL *handle, LPSTR replacestring);
+VOID MAIN_NotImplementedError(void);
+VOID MAIN_FileReadError(LPCSTR lpszPath);
+VOID MAIN_FileWriteError(LPCSTR lpszPath);
+VOID MAIN_GrpFileReadError(LPCSTR lpszPath);
+VOID MAIN_OutOfMemoryError(void);
+VOID MAIN_WinHelpError(void);
+
+HLOCAL GRPFILE_ReadGroupFile(const char* path);
+BOOL GRPFILE_WriteGroupFile(HLOCAL hGroup);
+
+ATOM GROUP_RegisterGroupWinClass(void);
+HLOCAL GROUP_AddGroup(LPCSTR lpszName, LPCSTR lpszGrpFile, INT showcmd,
+ INT x, INT y, INT width, INT heiht,
+ INT iconx, INT icony,
+ BOOL bModifiedFileName, BOOL bOverwriteFileOk,
+ /* FIXME shouldn't be necessary */
+ BOOL bSuppressShowWindow);
+VOID GROUP_NewGroup(void);
+VOID GROUP_ModifyGroup(HLOCAL hGroup);
+VOID GROUP_DeleteGroup(HLOCAL hGroup);
+/* FIXME shouldn't be necessary */
+VOID GROUP_ShowGroupWindow(HLOCAL hGroup);
+HLOCAL GROUP_FirstGroup(void);
+HLOCAL GROUP_NextGroup(HLOCAL hGroup);
+HLOCAL GROUP_ActiveGroup(void);
+HWND GROUP_GroupWnd(HLOCAL hGroup);
+LPCSTR GROUP_GroupName(HLOCAL hGroup);
+
+ATOM PROGRAM_RegisterProgramWinClass(void);
+HLOCAL PROGRAM_AddProgram(HLOCAL hGroup, HICON hIcon, LPCSTR lpszName,
+ INT x, INT y, LPCSTR lpszCmdLine,
+ LPCSTR lpszIconFile, INT nIconIndex,
+ LPCSTR lpszWorkDir, INT nHotKey, INT nCmdShow);
+VOID PROGRAM_NewProgram(HLOCAL hGroup);
+VOID PROGRAM_ModifyProgram(HLOCAL hProgram);
+VOID PROGRAM_CopyMoveProgram(HLOCAL hProgram, BOOL bMove);
+VOID PROGRAM_DeleteProgram(HLOCAL hProgram, BOOL BUpdateGrpFile);
+HLOCAL PROGRAM_FirstProgram(HLOCAL hGroup);
+HLOCAL PROGRAM_NextProgram(HLOCAL hProgram);
+HLOCAL PROGRAM_ActiveProgram(HLOCAL hGroup);
+LPCSTR PROGRAM_ProgramName(HLOCAL hProgram);
+VOID PROGRAM_ExecuteProgram(HLOCAL hLocal);
+
+INT DIALOG_New(INT nDefault);
+HLOCAL DIALOG_CopyMove(LPCSTR lpszProgramName, LPCSTR lpszGroupName, BOOL bMove);
+BOOL DIALOG_Delete(LPCSTR lpszFormat, LPCSTR lpszName);
+BOOL DIALOG_GroupAttributes(LPSTR lpszTitle, LPSTR lpszPath, INT nSize);
+BOOL DIALOG_ProgramAttributes(LPSTR lpszTitle, LPSTR lpszCmdLine,
+ LPSTR lpszWorkDir, LPSTR lpszIconFile,
+ HICON *lphIcon, INT *nIconIndex,
+ INT *lpnHotKey, INT *lpnCmdShow, INT nSize);
+VOID DIALOG_Symbol(HICON *lphIcon, LPSTR lpszIconFile,
+ INT *lpnIconIndex, INT nSize);
+VOID DIALOG_Execute(void);
+
+VOID STRING_SelectLanguage(LPCSTR lang);
+
+/* Class names */
+extern CHAR STRING_MAIN_WIN_CLASS_NAME[];
+extern CHAR STRING_MDI_WIN_CLASS_NAME[];
+extern CHAR STRING_GROUP_WIN_CLASS_NAME[];
+extern CHAR STRING_PROGRAM_WIN_CLASS_NAME[];
+
+/* Resource names */
+extern CHAR STRING_ACCEL[];
+extern CHAR STRING_MAIN_Xx[];
+extern CHAR STRING_NEW_Xx[];
+extern CHAR STRING_OPEN_Xx[];
+extern CHAR STRING_MOVE_Xx[];
+extern CHAR STRING_COPY_Xx[];
+extern CHAR STRING_DELETE_Xx[];
+extern CHAR STRING_GROUP_Xx[];
+extern CHAR STRING_PROGRAM_Xx[];
+extern CHAR STRING_SYMBOL_Xx[];
+extern CHAR STRING_EXECUTE_Xx[];
+
+/* Strings */
+#define STRING_PROGRAM_MANAGER Globals.StringTable[ 0]
+#define STRING_ERROR Globals.StringTable[ 1]
+#define STRING_INFO Globals.StringTable[ 2]
+#define STRING_DELETE Globals.StringTable[ 3]
+#define STRING_DELETE_GROUP_s Globals.StringTable[ 4]
+#define STRING_DELETE_PROGRAM_s Globals.StringTable[ 5]
+#define STRING_NOT_IMPLEMENTED Globals.StringTable[ 6]
+#define STRING_FILE_READ_ERROR_s Globals.StringTable[ 7]
+#define STRING_FILE_WRITE_ERROR_s Globals.StringTable[ 8]
+#define STRING_GRPFILE_READ_ERROR_s Globals.StringTable[ 9]
+#define STRING_OUT_OF_MEMORY Globals.StringTable[10]
+#define STRING_WINHELP_ERROR Globals.StringTable[11]
+#define STRING_UNKNOWN_FEATURE_IN_GRPFILE Globals.StringTable[12]
+#define STRING_FILE_NOT_OVERWRITTEN_s Globals.StringTable[13]
+#define STRING_SAVE_GROUP_AS_s Globals.StringTable[14]
+#define STRING_NO_HOT_KEY Globals.StringTable[15]
+#define STRING_BROWSE_EXE_FILTER Globals.StringTable[16]
+#define STRING_BROWSE_ICO_FILTER Globals.StringTable[17]
+#define NUMBER_OF_STRINGS 18
+
+extern LPCSTR StringTableCz[];
+extern LPCSTR StringTableDa[];
+extern LPCSTR StringTableDe[];
+extern LPCSTR StringTableEn[];
+extern LPCSTR StringTableEs[];
+extern LPCSTR StringTableFi[];
+extern LPCSTR StringTableFr[];
+extern LPCSTR StringTableNo[];
+
+#if defined(WINELIB) && !defined(HAVE_WINE_CONSTRUCTOR)
+ VOID LIBWINE_Register_accel(void);
+ VOID LIBWINE_Register_Cz(void);
+ VOID LIBWINE_Register_Da(void);
+ VOID LIBWINE_Register_De(void);
+ VOID LIBWINE_Register_Es(void);
+ VOID LIBWINE_Register_En(void);
+ VOID LIBWINE_Register_Fi(void);
+ VOID LIBWINE_Register_Fr(void);
+ VOID LIBWINE_Register_No(void);
+#endif
+
+#endif /* !RC_INVOKED */
+
+/* Menu */
+
+#define PM_NEW 100
+#define PM_OPEN 101
+#define PM_MOVE 102
+#define PM_COPY 103
+#define PM_DELETE 104
+#define PM_ATTRIBUTES 105
+#define PM_EXECUTE 107
+#define PM_EXIT 108
+
+#define PM_AUTO_ARRANGE 200
+#define PM_MIN_ON_RUN 201
+#define PM_SAVE_SETTINGS 203
+
+#define PM_OVERLAP 300
+#define PM_SIDE_BY_SIDE 301
+#define PM_ARRANGE 302
+#define PM_FIRST_CHILD 3030
+
+#define PM_En 400
+#define PM_Es 401
+#define PM_De 402
+#define PM_No 403
+#define PM_Fr 404
+#define PM_Fi 405
+#define PM_Da 406
+#define PM_Cz 407
+
+#define PM_CONTENTS 501
+#define PM_SEARCH 502
+#define PM_HELPONHELP 503
+#define PM_TUTORIAL 504
+
+#define PM_LICENSE 510
+#define PM_NO_WARRANTY 511
+#define PM_ABOUT_WINE 512
+
+/* Dialog `New' */
+
+/* RADIOBUTTON: The next two must be in sequence */
+#define PM_NEW_GROUP 1000
+#define PM_NEW_PROGRAM 1001
+#define PM_NEW_GROUP_TXT 1002
+#define PM_NEW_PROGRAM_TXT 1003
+
+/* Dialogs `Copy', `Move' */
+
+#define PM_PROGRAM 1200
+#define PM_FROM_GROUP 1201
+#define PM_TO_GROUP 1202
+#define PM_TO_GROUP_TXT 1203
+
+/* Dialogs `Group attributes' */
+
+#define PM_DESCRIPTION 1500
+#define PM_DESCRIPTION_TXT 1501
+#define PM_FILE 1502
+#define PM_FILE_TXT 1503
+
+/* Dialogs `Program attributes' */
+#define PM_COMMAND_LINE 1510
+#define PM_COMMAND_LINE_TXT 1511
+#define PM_DIRECTORY 1512
+#define PM_DIRECTORY_TXT 1513
+#define PM_HOT_KEY 1514
+#define PM_HOT_KEY_TXT 1515
+#define PM_ICON 1516
+#define PM_OTHER_SYMBOL 1517
+
+/* Dialog `Symbol' */
+
+#define PM_ICON_FILE 1520
+#define PM_ICON_FILE_TXT 1521
+#define PM_SYMBOL_LIST 1522
+#define PM_SYMBOL_LIST_TXT 1523
+
+/* Dialog `Execute' */
+
+#define PM_COMMAND 1600
+#define PM_SYMBOL 1601
+#define PM_BROWSE 1602
+#define PM_HELP 1603
+
+#endif /* PROGMAN_H */
+
+/* Local Variables: */
+/* c-file-style: "GNU" */
+/* End: */
diff --git a/programs/progman/program.c b/programs/progman/program.c
new file mode 100644
index 0000000..adf30ed
--- /dev/null
+++ b/programs/progman/program.c
@@ -0,0 +1,356 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+#include <windows.h>
+#include "progman.h"
+
+/***********************************************************************
+ *
+ * PROGRAM_ProgramWndProc
+ */
+
+static LRESULT PROGRAM_ProgramWndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_NCLBUTTONDOWN:
+ {
+ HLOCAL hProgram = (HLOCAL) GetWindowLong(hWnd, 0);
+ PROGRAM *program = LocalLock(hProgram);
+ GROUP *group = LocalLock(program->hGroup);
+ group->hActiveProgram = hProgram;
+ EnableMenuItem(Globals.hFileMenu, PM_MOVE , MF_ENABLED);
+ EnableMenuItem(Globals.hFileMenu, PM_COPY , MF_ENABLED);
+ break;
+ }
+ case WM_NCLBUTTONDBLCLK:
+ {
+ PROGRAM_ExecuteProgram((HLOCAL) GetWindowLong(hWnd, 0));
+ return(0);
+ }
+
+ case WM_PAINT:
+ {
+ PROGRAM *program;
+ PAINTSTRUCT ps;
+ HDC hdc;
+ hdc = BeginPaint(hWnd,&ps);
+ program = LocalLock((HLOCAL) GetWindowLong(hWnd, 0));
+ if (program->hIcon)
+ DrawIcon(hdc, 0, 0, program->hIcon);
+ EndPaint(hWnd,&ps);
+ break;
+ }
+ }
+ return(DefWindowProc(hWnd, msg, wParam, lParam));
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_RegisterProgramWinClass
+ */
+
+ATOM PROGRAM_RegisterProgramWinClass()
+{
+ WNDCLASS class;
+
+ class.style = CS_HREDRAW | CS_VREDRAW;
+ class.lpfnWndProc = PROGRAM_ProgramWndProc;
+ class.cbClsExtra = 0;
+ class.cbWndExtra = sizeof(LONG);
+ class.hInstance = Globals.hInstance;
+ class.hIcon = 0;
+ class.hCursor = LoadCursor (0, IDC_ARROW);
+ class.hbrBackground = GetStockObject (WHITE_BRUSH);
+ class.lpszMenuName = 0;
+ class.lpszClassName = STRING_PROGRAM_WIN_CLASS_NAME;
+
+ return RegisterClass(&class);
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_NewProgram
+ */
+
+VOID PROGRAM_NewProgram(HLOCAL hGroup)
+{
+ INT nCmdShow = SW_SHOWNORMAL;
+ INT nHotKey = 0;
+ INT nIconIndex = 0;
+ CHAR szName[MAX_PATHNAME_LEN] = "";
+ CHAR szCmdLine[MAX_PATHNAME_LEN] = "";
+ CHAR szIconFile[MAX_PATHNAME_LEN] = "";
+ CHAR szWorkDir[MAX_PATHNAME_LEN] = "";
+ HICON hIcon = 0;
+
+ if (!DIALOG_ProgramAttributes(szName, szCmdLine, szWorkDir, szIconFile,
+ &hIcon, &nIconIndex, &nHotKey,
+ &nCmdShow, MAX_PATHNAME_LEN))
+ return;
+
+ if (!hIcon) hIcon = LoadIcon(0, MAKEINTRESOURCE(OIC_WINEICON));
+
+
+ if (!PROGRAM_AddProgram(hGroup, hIcon, szName, 0, 0, szCmdLine, szIconFile,
+ nIconIndex, szWorkDir, nHotKey, nCmdShow))
+ return;
+
+ GRPFILE_WriteGroupFile(hGroup);
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_ModifyProgram
+ */
+
+VOID PROGRAM_ModifyProgram(HLOCAL hProgram)
+{
+ PROGRAM *program = LocalLock(hProgram);
+ CHAR szName[MAX_PATHNAME_LEN];
+ CHAR szCmdLine[MAX_PATHNAME_LEN];
+ CHAR szIconFile[MAX_PATHNAME_LEN];
+ CHAR szWorkDir[MAX_PATHNAME_LEN];
+
+ lstrcpyn(szName, LocalLock(program->hName), MAX_PATHNAME_LEN);
+ lstrcpyn(szCmdLine, LocalLock(program->hCmdLine), MAX_PATHNAME_LEN);
+ lstrcpyn(szIconFile, LocalLock(program->hIconFile), MAX_PATHNAME_LEN);
+ lstrcpyn(szWorkDir, LocalLock(program->hWorkDir), MAX_PATHNAME_LEN);
+
+ if (!DIALOG_ProgramAttributes(szName, szCmdLine, szWorkDir, szIconFile,
+ &program->hIcon, &program->nIconIndex,
+ &program->nHotKey, &program->nCmdShow,
+ MAX_PATHNAME_LEN))
+ return;
+
+ MAIN_ReplaceString(&program->hName, szName);
+ MAIN_ReplaceString(&program->hCmdLine, szCmdLine);
+ MAIN_ReplaceString(&program->hIconFile, szIconFile);
+ MAIN_ReplaceString(&program->hWorkDir, szWorkDir);
+
+ SetWindowText(program->hWnd, szName);
+ UpdateWindow(program->hWnd);
+
+ GRPFILE_WriteGroupFile(program->hGroup);
+
+ return;
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_AddProgram
+ */
+
+HLOCAL PROGRAM_AddProgram(HLOCAL hGroup, HICON hIcon, LPCSTR lpszName,
+ INT x, INT y, LPCSTR lpszCmdLine,
+ LPCSTR lpszIconFile, INT nIconIndex,
+ LPCSTR lpszWorkDir, INT nHotKey, INT nCmdShow)
+{
+ GROUP *group = LocalLock(hGroup);
+ PROGRAM *program;
+ HLOCAL hPrior, *p;
+ HLOCAL hProgram = LocalAlloc(LMEM_FIXED, sizeof(PROGRAM));
+ HLOCAL hName = LocalAlloc(LMEM_FIXED, 1 + lstrlen(lpszName));
+ HLOCAL hCmdLine = LocalAlloc(LMEM_FIXED, 1 + lstrlen(lpszCmdLine));
+ HLOCAL hIconFile = LocalAlloc(LMEM_FIXED, 1 + lstrlen(lpszIconFile));
+ HLOCAL hWorkDir = LocalAlloc(LMEM_FIXED, 1 + lstrlen(lpszWorkDir));
+ if (!hProgram || !hName || !hCmdLine || !hIconFile || !hWorkDir)
+ {
+ MAIN_OutOfMemoryError();
+ if (hProgram) LocalFree(hProgram);
+ if (hName) LocalFree(hName);
+ if (hCmdLine) LocalFree(hCmdLine);
+ if (hIconFile) LocalFree(hIconFile);
+ if (hWorkDir) LocalFree(hWorkDir);
+ return(0);
+ }
+ hmemcpy(LocalLock(hName), lpszName, 1 + lstrlen(lpszName));
+ hmemcpy(LocalLock(hCmdLine), lpszCmdLine, 1 + lstrlen(lpszCmdLine));
+ hmemcpy(LocalLock(hIconFile), lpszIconFile, 1 + lstrlen(lpszIconFile));
+ hmemcpy(LocalLock(hWorkDir), lpszWorkDir, 1 + lstrlen(lpszWorkDir));
+
+ group->hActiveProgram = hProgram;
+
+ hPrior = 0;
+ p = &group->hPrograms;
+ while (*p)
+ {
+ hPrior = *p;
+ p = &((PROGRAM*)LocalLock(hPrior))->hNext;
+ }
+ *p = hProgram;
+
+ program = LocalLock(hProgram);
+ program->hGroup = hGroup;
+ program->hPrior = hPrior;
+ program->hNext = 0;
+ program->hName = hName;
+ program->hCmdLine = hCmdLine;
+ program->hIconFile = hIconFile;
+ program->nIconIndex = nIconIndex;
+ program->hWorkDir = hWorkDir;
+ program->hIcon = hIcon;
+ program->nCmdShow = nCmdShow;
+ program->nHotKey = nHotKey;
+
+ program->hWnd =
+ CreateWindow (STRING_PROGRAM_WIN_CLASS_NAME, (LPSTR)lpszName,
+ WS_CHILD | WS_OVERLAPPEDWINDOW,
+ x, y, CW_USEDEFAULT, CW_USEDEFAULT,
+ group->hWnd, 0, Globals.hInstance, 0);
+
+ SetWindowLong(program->hWnd, 0, (LONG) hProgram);
+
+ ShowWindow (program->hWnd, SW_SHOWMINIMIZED);
+ UpdateWindow (program->hWnd);
+
+ return hProgram;
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_CopyMoveProgram
+ */
+
+VOID PROGRAM_CopyMoveProgram(HLOCAL hProgram, BOOL bMove)
+{
+ PROGRAM *program = LocalLock(hProgram);
+ GROUP *fromgroup = LocalLock(program->hGroup);
+ HLOCAL hGroup = DIALOG_CopyMove(LocalLock(program->hName),
+ LocalLock(fromgroup->hName), bMove);
+ if (!hGroup) return;
+
+ /* FIXME shouldn't be necessary */
+ OpenIcon(((GROUP*)LocalLock(hGroup))->hWnd);
+
+ if (!PROGRAM_AddProgram(hGroup,
+#if 0
+ CopyIcon(program->hIcon),
+#else
+ program->hIcon,
+#endif
+ LocalLock(program->hName),
+ program->x, program->y,
+ LocalLock(program->hCmdLine),
+ LocalLock(program->hIconFile),
+ program->nIconIndex,
+ LocalLock(program->hWorkDir),
+ program->nHotKey, program->nCmdShow)) return;
+ GRPFILE_WriteGroupFile(hGroup);
+
+ if (bMove) PROGRAM_DeleteProgram(hProgram, TRUE);
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_ExecuteProgram
+ */
+
+VOID PROGRAM_ExecuteProgram(HLOCAL hProgram)
+{
+ PROGRAM *program = LocalLock(hProgram);
+ LPSTR lpszCmdLine = LocalLock(program->hCmdLine);
+ LPSTR lpszWorkDir = LocalLock(program->hWorkDir);
+
+ /* FIXME set working direktory */
+ lpszWorkDir = lpszWorkDir;
+
+ WinExec(lpszCmdLine, program->nCmdShow);
+ if (Globals.bMinOnRun) CloseWindow(Globals.hMainWnd);
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_DeleteProgram
+ */
+
+VOID PROGRAM_DeleteProgram(HLOCAL hProgram, BOOL bUpdateGrpFile)
+{
+ PROGRAM *program = LocalLock(hProgram);
+ GROUP *group = LocalLock(program->hGroup);
+
+ group->hActiveProgram = 0;
+
+ if (program->hPrior)
+ ((PROGRAM*)LocalLock(program->hPrior))->hNext = program->hNext;
+ else
+ ((GROUP*)LocalLock(program->hGroup))->hPrograms = program->hNext;
+
+ if (program->hNext)
+ ((PROGRAM*)LocalLock(program->hNext))->hPrior = program->hPrior;
+
+ if (bUpdateGrpFile)
+ GRPFILE_WriteGroupFile(program->hGroup);
+
+ DestroyWindow(program->hWnd);
+#if 0
+ if (program->hIcon)
+ DestroyIcon(program->hIcon);
+#endif
+ LocalFree(program->hName);
+ LocalFree(program->hCmdLine);
+ LocalFree(program->hIconFile);
+ LocalFree(program->hWorkDir);
+ LocalFree(hProgram);
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_FirstProgram
+ */
+
+HLOCAL PROGRAM_FirstProgram(HLOCAL hGroup)
+{
+ GROUP *group;
+ if (!hGroup) return(0);
+ group = LocalLock(hGroup);
+ return(group->hPrograms);
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_NextProgram
+ */
+
+HLOCAL PROGRAM_NextProgram(HLOCAL hProgram)
+{
+ PROGRAM *program;
+ if (!hProgram) return(0);
+ program = LocalLock(hProgram);
+ return(program->hNext);
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_ActiveProgram
+ */
+
+HLOCAL PROGRAM_ActiveProgram(HLOCAL hGroup)
+{
+ GROUP *group;
+ if (!hGroup) return(0);
+ group = LocalLock(hGroup);
+ if (IsIconic(group->hWnd)) return(0);
+
+ return(group->hActiveProgram);
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_ProgramName
+ */
+
+LPCSTR PROGRAM_ProgramName(HLOCAL hProgram)
+{
+ PROGRAM *program;
+ if (!hProgram) return(0);
+ program = LocalLock(hProgram);
+ return(LocalLock(program->hName));
+}
+
+/* Local Variables: */
+/* c-file-style: "GNU" */
+/* End: */
diff --git a/programs/progman/string.c b/programs/progman/string.c
new file mode 100644
index 0000000..a040855
--- /dev/null
+++ b/programs/progman/string.c
@@ -0,0 +1,92 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+#include <windows.h>
+#include "progman.h"
+
+/* Class names */
+
+CHAR STRING_MAIN_WIN_CLASS_NAME[] = "PMMain";
+CHAR STRING_MDI_WIN_CLASS_NAME[] = "MDICLIENT";
+CHAR STRING_GROUP_WIN_CLASS_NAME[] = "PMGroup";
+CHAR STRING_PROGRAM_WIN_CLASS_NAME[] = "PMProgram";
+
+/* Resource names */
+/* Xx will be overwritten with En, ... */
+CHAR STRING_ACCEL[] = "ACCEL";
+CHAR STRING_MAIN_Xx[] = "MENU_Xx";
+CHAR STRING_NEW_Xx[] = "DIALOG_NEW_Xx";
+CHAR STRING_OPEN_Xx[] = "DIALOG_OPEN_Xx";
+CHAR STRING_MOVE_Xx[] = "DIALOG_MOVE_Xx";
+CHAR STRING_COPY_Xx[] = "DIALOG_COPY_Xx";
+CHAR STRING_DELETE_Xx[] = "DIALOG_DELETE_Xx";
+CHAR STRING_GROUP_Xx[] = "DIALOG_GROUP_Xx";
+CHAR STRING_PROGRAM_Xx[] = "DIALOG_PROGRAM_Xx";
+CHAR STRING_SYMBOL_Xx[] = "DIALOG_SYMBOL_Xx";
+CHAR STRING_EXECUTE_Xx[] = "DIALOG_EXECUTE_Xx";
+
+static LPCSTR StringTableEn[];
+static LPCSTR StringTableDe[];
+
+VOID STRING_SelectLanguage(LPCSTR lang)
+{
+ /* Change string table */
+ Globals.StringTable = StringTableEn;
+ if (!lstrcmp(lang, "De")) Globals.StringTable = StringTableDe;
+
+ SetWindowText(Globals.hMainWnd, STRING_PROGRAM_MANAGER);
+
+ /* Change Resource names */
+ lstrcpyn(STRING_MAIN_Xx + sizeof(STRING_MAIN_Xx) - 3, lang, 3);
+ lstrcpyn(STRING_NEW_Xx + sizeof(STRING_NEW_Xx) - 3, lang, 3);
+ lstrcpyn(STRING_OPEN_Xx + sizeof(STRING_OPEN_Xx) - 3, lang, 3);
+ lstrcpyn(STRING_MOVE_Xx + sizeof(STRING_MOVE_Xx) - 3, lang, 3);
+ lstrcpyn(STRING_COPY_Xx + sizeof(STRING_COPY_Xx) - 3, lang, 3);
+ lstrcpyn(STRING_DELETE_Xx + sizeof(STRING_DELETE_Xx) - 3, lang, 3);
+ lstrcpyn(STRING_GROUP_Xx + sizeof(STRING_GROUP_Xx) - 3, lang, 3);
+ lstrcpyn(STRING_PROGRAM_Xx + sizeof(STRING_PROGRAM_Xx) - 3, lang, 3);
+ lstrcpyn(STRING_SYMBOL_Xx + sizeof(STRING_SYMBOL_Xx) - 3, lang, 3);
+ lstrcpyn(STRING_EXECUTE_Xx + sizeof(STRING_EXECUTE_Xx) - 3, lang, 3);
+
+ /* Destroy old menu */
+ if (Globals.hMainMenu)
+ {
+ SendMessage(Globals.hMDIWnd, WM_MDISETMENU, (WPARAM) NULL, (LPARAM) NULL);
+#if 0 /* FIXME when MDISetMenu is complete */
+ DestroyMenu(Globals.hMainMenu);
+#endif
+ }
+
+ /* Create new menu */
+ Globals.hMainMenu = LoadMenu(Globals.hInstance, STRING_MAIN_Xx);
+ if (Globals.hMainMenu)
+ {
+ Globals.hFileMenu = GetSubMenu(Globals.hMainMenu, 0);
+ Globals.hOptionMenu = GetSubMenu(Globals.hMainMenu, 1);
+ Globals.hWindowsMenu = GetSubMenu(Globals.hMainMenu, 2);
+
+ if (Globals.hMDIWnd)
+ SendMessage(Globals.hMDIWnd, WM_MDISETMENU,
+ (WPARAM) Globals.hMainMenu,
+ (LPARAM) Globals.hWindowsMenu);
+ else SetMenu(Globals.hMainWnd, Globals.hMainMenu);
+ }
+ /* Unsupported language */
+ else if(lstrcmp(lang, "En")) STRING_SelectLanguage("En");
+ else
+ {
+ MessageBox(Globals.hMainWnd, "No language found", "FATAL ERROR", MB_OK);
+ PostQuitMessage(1);
+ }
+
+ /* have to be last because of
+ * the possible recursion */
+ Globals.lpszLanguage = lang;
+}
+
+/* Local Variables: */
+/* c-file-style: "GNU" */
+/* End: */
diff --git a/programs/progman/winexec.c b/programs/progman/winexec.c
new file mode 100644
index 0000000..722576c
--- /dev/null
+++ b/programs/progman/winexec.c
@@ -0,0 +1,91 @@
+#ifdef WINELIB
+#include <unistd.h>
+#include <string.h>
+#include "windows.h"
+#include "winbase.h"
+#include "options.h"
+#include "dos_fs.h"
+#include "debug.h"
+#include "progman.h"
+
+#define MAX_CMDLINE_SIZE 256
+
+/* FIXME should use WinExec from -lwine */
+
+HANDLE ProgmanWinExec( LPSTR lpCmdLine, WORD nCmdShow )
+{
+ char wine[MAX_CMDLINE_SIZE];
+ char filename[MAX_CMDLINE_SIZE], *p;
+ char cmdline[MAX_CMDLINE_SIZE];
+ const char *argv[10], **argptr;
+ const char *unixfilename;
+ int simplename = 1;
+
+ if (fork()) return(INVALID_HANDLE_VALUE);
+
+ strncpy( filename, lpCmdLine, MAX_CMDLINE_SIZE );
+ filename[MAX_CMDLINE_SIZE-1] = '\0';
+ for (p = filename; *p && (*p != ' ') && (*p != '\t'); p++)
+ if ((*p == ':') || (*p == ':') || (*p == '/')) simplename = 0;
+ if (*p)
+ {
+ strncpy( cmdline, p + 1, 128 );
+ cmdline[127] = '\0';
+ }
+ else cmdline[0] = '\0';
+ *p = '\0';
+
+ if (simplename) unixfilename = filename;
+ else unixfilename = DOSFS_GetUnixFileName(filename, 0);
+
+ argptr = argv;
+ *argptr++ = unixfilename;
+ if (nCmdShow == SW_SHOWMINIMIZED) *argptr++ = "-iconic";
+ if (cmdline[0]) *argptr++ = cmdline;
+ *argptr++ = 0;
+ execvp(argv[0], (char**)argv);
+
+ PROFILE_GetWineIniString("progman", "wine", "wine",
+ wine, sizeof(wine));
+ argptr = argv;
+ *argptr++ = wine;
+ *argptr++ = "-language";
+ *argptr++ = Globals.lpszLanguage;
+ if (nCmdShow == SW_SHOWMINIMIZED) *argptr++ = "-iconic";
+ *argptr++ = lpCmdLine;
+ *argptr++ = 0;
+ execvp(argv[0] , (char**)argv);
+
+ printf("Cannot exec `%s %s %s%s %s'\n",
+ wine, "-language", Globals.lpszLanguage,
+ nCmdShow == SW_SHOWMINIMIZED ? " -iconic" : "",
+ lpCmdLine);
+ exit(1);
+}
+
+BOOL ProgmanWinHelp(HWND hWnd, LPSTR lpHelpFile, WORD wCommand, DWORD dwData)
+{
+ char str[256];
+ dprintf_exec(stddeb,"WinHelp(%s, %u, %lu)\n",
+ lpHelpFile, wCommand, dwData);
+ switch(wCommand) {
+ case 0:
+ case HELP_HELPONHELP:
+ GetWindowsDirectory(str, sizeof(str));
+ strcat(str, "\\winhelp.exe winhelp.hlp");
+ dprintf_exec(stddeb,"'%s'\n", str);
+ break;
+ case HELP_INDEX:
+ GetWindowsDirectory(str, sizeof(str));
+ strcat(str, "\\winhelp.exe ");
+ strcat(str, lpHelpFile);
+ dprintf_exec(stddeb,"'%s'\n", str);
+ break;
+ default:
+ return FALSE;
+ }
+ WinExec(str, SW_SHOWNORMAL);
+ return(TRUE);
+}
+
+#endif
diff --git a/rc/winerc.c b/rc/winerc.c
index 7642ff2..494ab10 100644
--- a/rc/winerc.c
+++ b/rc/winerc.c
@@ -212,7 +212,7 @@
/*initially, no bits have to be reset*/
ret->and=-1;
/*initially, no bits are set*/
- ret->or=0;
+ ret->or=WS_CHILD | WS_VISIBLE;
return ret;
}
diff --git a/resources/Makefile.in b/resources/Makefile.in
index 3bcc5ef..7cb7871 100644
--- a/resources/Makefile.in
+++ b/resources/Makefile.in
@@ -2,7 +2,7 @@
MODULE = resources
-LANGUAGES = En Es De No Fr Fi Da Cz
+LANGUAGES = En Es De No Fr Fi Da Cz Eo
SYSRES_SRCS = $(LANGUAGES:%=sysres_%.c)
diff --git a/resources/sysres.c b/resources/sysres.c
index 4dac4bf..ae1cbd0 100644
--- a/resources/sysres.c
+++ b/resources/sysres.c
@@ -17,6 +17,7 @@
#include "sysres_Fi.h"
#include "sysres_Da.h"
#include "sysres_Cz.h"
+#include "sysres_Eo.h"
static const struct resource * const * SYSRES_Resources[] =
@@ -28,7 +29,8 @@
sysres_Fr_Table, /* LANG_Fr */
sysres_Fi_Table, /* LANG_Fi */
sysres_Da_Table, /* LANG_Da */
- sysres_Cz_Table /* LANG_Cz */
+ sysres_Cz_Table, /* LANG_Cz */
+ sysres_Eo_Table /* LANG_Eo */
};
diff --git a/resources/sysres_Eo.rc b/resources/sysres_Eo.rc
new file mode 100644
index 0000000..09b3a93
--- /dev/null
+++ b/resources/sysres_Eo.rc
@@ -0,0 +1,201 @@
+SYSMENU MENU LOADONCALL MOVEABLE DISCARDABLE
+{
+ MENUITEM "&Renormaligu", 61728
+ MENUITEM "&Movi", 61456
+ MENUITEM "&Grando", 61440
+ MENUITEM "E&tigu", 61472
+ MENUITEM "&Egigu", 61488
+ MENUITEM SEPARATOR
+ MENUITEM "&Fermu\tAlt-F4", 61536
+ MENUITEM SEPARATOR
+ MENUITEM "&Alia tasko ...\tCtrl-Esc", 61744
+ MENUITEM SEPARATOR
+ MENUITEM "&Pri WINE ...", 61761
+}
+
+MSGBOX DIALOG 100, 80, 216, 168
+STYLE DS_SYSMODAL | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+BEGIN
+ ICON "", 1088, 8, 20, 16, 16, WS_CHILD | WS_VISIBLE
+ LTEXT "", 100, 32, 4, 176, 48, WS_CHILD | WS_VISIBLE | WS_GROUP
+ PUSHBUTTON "En&orde", 1, 16, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ PUSHBUTTON "&Nuligu", 2, 64, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ PUSHBUTTON "Æe&su", 3, 112, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ PUSHBUTTON "&Reprovu", 4, 160, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ PUSHBUTTON "&Ignoru", 5, 208, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ PUSHBUTTON "&Jes", 6, 256, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ PUSHBUTTON "N&e", 7, 304, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+END
+
+SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 50, 44, 223, 200
+STYLE DS_LOCALEDIT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Pri %s"
+FONT 10, "System"
+{
+ DEFPUSHBUTTON "Enorde", 1, 91, 180, 40, 14
+ CONTROL "", -1, "STATIC", SS_BLACKFRAME | WS_CHILD | WS_VISIBLE | WS_DISABLED, 4, 35, 215, 140
+ LTEXT "Text", 100, 11, 40, 200, 130, SS_NOPREFIX | WS_GROUP
+ ICON "", 1088, 195, 10, 18, 20
+}
+
+
+OPEN_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Malfermu dosieron"
+FONT 8, "Helv"
+{
+ LTEXT "Dosier&nomo:", 1090, 6, 6, 76, 9
+ EDITTEXT 1152, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP
+ LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
+ LTEXT "Dosier&ujo:", -1, 110, 6, 92, 9
+ LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP
+ LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
+ LTEXT "Dosier&speco:", 1089, 6, 104, 90, 9
+ COMBOBOX 1136, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Disk&ilo:", 1091, 110, 104, 92, 9
+ COMBOBOX 1137, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "Malfermu", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Nuligu", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Helpu", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ CHECKBOX "Nur &legebla", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+}
+
+
+SAVE_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Sekurigu dosieron"
+FONT 8, "Helv"
+{
+ LTEXT "Dosier&nomo:", 1090, 6, 6, 76, 9
+ EDITTEXT 1152, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP
+ LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
+ LTEXT "Dosier&ujo:", -1, 110, 6, 92, 9
+ LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP
+ LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
+ LTEXT "Dosier&speco:", 1089, 6, 104, 90, 9
+ COMBOBOX 1136, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Disk&ilo:", 1091, 110, 104, 92, 9
+ COMBOBOX 1137, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "Sekurigu", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Nuligu", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Helpu", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ CHECKBOX "Nur &legebla", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+}
+
+
+PRINT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Presu"
+FONT 8, "Helv"
+{
+ LTEXT "Presilo:", 1088, 6, 6, 40, 9
+ LTEXT "", 1089, 60, 6, 150, 9
+ GROUPBOX "Etendiøon", 1072, 6, 30, 160, 65, BS_GROUPBOX
+ RADIOBUTTON "æ&iujn", 1056, 16, 45, 60, 12
+ RADIOBUTTON "&elekton", 1057, 16, 60, 60, 12
+ RADIOBUTTON "&paøojn", 1058, 16, 75, 60, 12
+ DEFPUSHBUTTON "Presu", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Nuligu", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Aranøu", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ LTEXT "de:", 1090, 60, 80, 30, 9
+ LTEXT "øis:", 1091, 120, 80, 30, 9
+ LTEXT "&Kvalito:", 1092, 6, 100, 76, 9
+ COMBOBOX 1136, 80, 100, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ CHECKBOX "Presu &dosieren", 1040, 20, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "Mallarøtipe", 1041, 160, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+}
+
+
+PRINT_SETUP DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Presada Aranøo"
+FONT 8, "Helv"
+{
+ GROUPBOX "Presilo", 1072, 6, 10, 180, 65, BS_GROUPBOX
+ RADIOBUTTON "&Implicita Presilo", 1056, 16, 20, 80, 12
+ LTEXT "[none]", 1088, 35, 35, 120, 9
+ RADIOBUTTON "&Specifa Presilo", 1057, 16, 50, 80, 12
+ COMBOBOX 1136, 35, 65, 149, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "Enorde", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Nuligu", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Agordo", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ GROUPBOX "Formato", 1073, 6, 85, 100, 50, BS_GROUPBOX
+ RADIOBUTTON "&Vertikala", 1058, 50, 100, 40, 12
+ RADIOBUTTON "&Horizontala", 1059, 50, 115, 40, 12
+ ICON "LANDSCAP", 1097, 10, 95, 32, 32
+ ICON "PORTRAIT", 1098, 10, 95, 32, 32
+ GROUPBOX "Papero", 1074, 120, 85, 180, 50, BS_GROUPBOX
+ LTEXT "&Grando", 1089, 130, 95, 30, 9
+ LTEXT "&Fonto", 1090, 130, 110, 30, 9
+ COMBOBOX 1137, 155, 95, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX 1138, 155, 110, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+}
+
+
+CHOOSE_FONT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Tiparo"
+FONT 8, "Helv"
+{
+ LTEXT "Tiparo:", 1088, 6, 6, 40, 9
+ LTEXT "", 1089, 60, 6, 150, 9
+ DEFPUSHBUTTON "Enorde", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Nuligu", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
+}
+
+
+CHOOSE_COLOR DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 200
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Koloro"
+FONT 8, "Helv"
+{
+ LTEXT "&Normala koloraro:", 1088, 6, 6, 40, 9
+ LTEXT "&Persona koloraro:", 1089, 6, 126, 40, 9
+ LTEXT "Color|Sol&id", 1090, 100, 146, 40, 9
+ LTEXT "&Farbo:", 1091, 150, 126, 40, 9
+ LTEXT "&Saturo:", 1092, 150, 146, 40, 9
+ LTEXT "&Helo:", 1093, 150, 166, 40, 9
+ LTEXT "&Ruøo:", 1094, 150, 126, 40, 9
+ LTEXT "&Verda:", 1095, 150, 146, 40, 9
+ LTEXT "&Bluo:", 1096, 150, 166, 40, 9
+ DEFPUSHBUTTON "Enorde", 1, 6, 182, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Aldonu al persona koloraro", 1024, 120, 182, 100, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Forv&iþu personan koloraron", 1025, 6, 164, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Nuligu", 2, 76, 182, 56, 14, WS_GROUP | WS_TABSTOP
+}
+
+
+FIND_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 84
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Seræu"
+FONT 8, "Helv"
+{
+ LTEXT "&Seræu:", 1088, 6, 6, 40, 9
+ LTEXT "", 1089, 60, 6, 150, 9
+ CHECKBOX "Nur tutan &vorton", 1040, 20, 30, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "Atentu &Usklecon", 1041, 20, 50, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ GROUPBOX "Direkto", 1072, 90, 40, 80, 40, BS_GROUPBOX
+ RADIOBUTTON "&Retro", 1056, 100, 50, 50, 12
+ RADIOBUTTON "&Antaýen", 1057, 150, 50, 50, 12
+ DEFPUSHBUTTON "&Pluseræu", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Nuligu", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
+}
+
+
+REPLACE_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 114
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Anstataýigu"
+FONT 8, "Helv"
+{
+ LTEXT "Anstataýigu:", 1088, 6, 6, 40, 9
+ LTEXT "", 1089, 60, 6, 150, 9
+ LTEXT "&per:", 1090, 6, 26, 40, 9
+ LTEXT "", 1091, 60, 26, 150, 9
+ CHECKBOX "Nur tutan &vorton", 1040, 20, 40, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "Atentu &Usklecon", 1041, 20, 60, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ DEFPUSHBUTTON "Plu&seræu", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Anstataýigu", 1024, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Anstataýigu æ&iujn", 1025, 206, 44, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Nuligu", 2, 206, 64, 56, 14, WS_GROUP | WS_TABSTOP
+}
+
diff --git a/tools/build.c b/tools/build.c
index 13d2913..938f99f 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -11,6 +11,7 @@
#include "wine.h"
#include "module.h"
#include "neexe.h"
+#include "windows.h"
/* ELF symbols do not have an underscore in front */
#if defined (__ELF__) || defined (__svr4__)
@@ -560,13 +561,13 @@
char *buffer;
NE_MODULE *pModule;
SEGTABLEENTRY *pSegment;
- LOADEDFILEINFO *pFileInfo;
+ OFSTRUCT *pFileInfo;
BYTE *pstr, *bundle;
WORD *pword;
/* Module layout:
* NE_MODULE Module
- * LOADEDFILEINFO File information
+ * OFSTRUCT File information
* SEGTABLEENTRY Segment 1 (code)
* SEGTABLEENTRY Segment 2 (data)
* WORD[2] Resource table (empty)
@@ -606,15 +607,13 @@
/* File information */
- pFileInfo = (LOADEDFILEINFO *)(pModule + 1);
+ pFileInfo = (OFSTRUCT *)(pModule + 1);
pModule->fileinfo = (int)pFileInfo - (int)pModule;
- pFileInfo->length = sizeof(LOADEDFILEINFO) + strlen(UpperDLLName) + 3;
- pFileInfo->fixed_media = 0;
- pFileInfo->error = 0;
- pFileInfo->date = 0;
- pFileInfo->time = 0;
- sprintf( pFileInfo->filename, "%s.DLL", UpperDLLName );
- pstr = (char *)pFileInfo + pFileInfo->length + 1;
+ memset( pFileInfo, 0, sizeof(*pFileInfo) - sizeof(pFileInfo->szPathName) );
+ pFileInfo->cBytes = sizeof(*pFileInfo) - sizeof(pFileInfo->szPathName)
+ + strlen(UpperDLLName) + 4;
+ sprintf( pFileInfo->szPathName, "%s.DLL", UpperDLLName );
+ pstr = (char *)pFileInfo + pFileInfo->cBytes + 1;
/* Segment table */
diff --git a/win32/init.c b/win32/init.c
index 2081fe1..fa923b2 100644
--- a/win32/init.c
+++ b/win32/init.c
@@ -12,6 +12,7 @@
#include "kernel32.h"
#include "handle32.h"
#include "pe_image.h"
+#include "task.h"
#include "stddebug.h"
#define DEBUG_WIN32
#include "debug.h"
@@ -76,8 +77,13 @@
HMODULE hModule;
dprintf_win32(stddeb, "GetModuleHandle: %s\n", module ? module : "NULL");
- if (module == NULL) hModule = GetExePtr( GetCurrentTask() );
- else hModule = GetModuleHandle(module);
+/* Freecell uses the result of GetModuleHandleA(0) as the hInstance in
+all calls to e.g. CreateWindowEx. */
+ if (module == NULL) {
+ TDB *pTask = (TDB *)GlobalLock( GetCurrentTask() );
+ hModule = pTask->hInstance;
+ } else
+ hModule = GetModuleHandle(module);
dprintf_win32(stddeb, "GetModuleHandle: returning %d\n", hModule );
return hModule;
}
diff --git a/win32/resource.c b/win32/resource.c
index b2f055b..ed81d60 100644
--- a/win32/resource.c
+++ b/win32/resource.c
@@ -97,9 +97,7 @@
DWORD root;
HANDLE32 result;
-#if 0
hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
-#endif
dprintf_resource(stddeb, "FindResource: module=%08x type=", hModule );
PrintId( type );
dprintf_resource( stddeb, " name=" );
@@ -133,9 +131,7 @@
#ifndef WINELIB
struct w_files *wptr = wine_files;
-#if 0
hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
-#endif
dprintf_resource(stddeb, "LoadResource: module="NPFMT" res="NPFMT"\n",
hModule, hRsrc );
if (!hRsrc) return 0;
diff --git a/win32/string32.c b/win32/string32.c
index 1ae569b..e09042a 100644
--- a/win32/string32.c
+++ b/win32/string32.c
@@ -17,7 +17,7 @@
int STRING32_UniLen(LPWSTR s)
{
int i;
- for(i=0;*s;s++);
+ for(i=0;*s;s++)
i++;
return i;
}
diff --git a/win32/time.c b/win32/time.c
index 24be6a3..8dd88fc 100644
--- a/win32/time.c
+++ b/win32/time.c
@@ -23,9 +23,9 @@
struct tm *local_tm;
struct timeval tv;
- time(&local_time);
- local_tm = localtime(&local_time);
gettimeofday(&tv, NULL);
+ local_time = tv.tv_sec;
+ local_tm = localtime(&local_time);
systime->wYear = local_tm->tm_year + 1900;
systime->wMonth = local_tm->tm_mon + 1;
@@ -46,9 +46,9 @@
struct tm *local_tm;
struct timeval tv;
- time(&local_time);
- local_tm = gmtime(&local_time);
gettimeofday(&tv, NULL);
+ local_time = tv.tv_sec;
+ local_tm = gmtime(&local_time);
systime->wYear = local_tm->tm_year + 1900;
systime->wMonth = local_tm->tm_mon + 1;
diff --git a/windows/caret.c b/windows/caret.c
index 863a75c..268b937 100644
--- a/windows/caret.c
+++ b/windows/caret.c
@@ -155,7 +155,6 @@
/*****************************************************************
* CreateCaret (USER.163)
*/
-
BOOL CreateCaret(HWND hwnd, HBITMAP bitmap, INT width, INT height)
{
dprintf_caret(stddeb,"CreateCaret: hwnd="NPFMT"\n", hwnd);
@@ -186,7 +185,7 @@
Caret.color = GetSysColor(COLOR_GRAYTEXT);
else
Caret.color = GetSysColor(COLOR_WINDOW);
- Caret.timeout = 750;
+ Caret.timeout = GetProfileInt( "windows", "CursorBlinkRate", 750 );
CARET_Initialize();
@@ -220,6 +219,7 @@
void SetCaretPos(short x, short y)
{
if (!Caret.hwnd) return;
+ if ((x == Caret.x) && (y == Caret.y)) return;
dprintf_caret(stddeb,"SetCaretPos: x=%d, y=%d\n", x, y);
diff --git a/windows/event.c b/windows/event.c
index 780cc31..7ab8e42 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -145,6 +145,7 @@
static void EVENT_SelectionRequest( HWND hwnd, XSelectionRequestEvent *event);
static void EVENT_SelectionNotify( HWND hwnd, XSelectionEvent *event);
static void EVENT_SelectionClear( HWND hwnd, XSelectionClearEvent *event);
+static void EVENT_ClientMessage( HWND hwnd, XClientMessageEvent *event );
/***********************************************************************
@@ -220,6 +221,10 @@
EVENT_SelectionClear( hwnd, (XSelectionClearEvent*) event );
break;
+ case ClientMessage:
+ EVENT_ClientMessage( hwnd, (XClientMessageEvent *) event );
+ break;
+
default:
dprintf_event(stddeb, "Unprocessed event %s for hwnd "NPFMT"\n",
event_names[event->type], hwnd );
@@ -616,6 +621,30 @@
CLIPBOARD_ReleaseSelection(hwnd);
}
+
+/**********************************************************************
+ * EVENT_ClientMessage
+ */
+static void EVENT_ClientMessage (HWND hwnd, XClientMessageEvent *event )
+{
+ static Atom wmProtocols = None;
+ static Atom wmDeleteWindow = None;
+
+ if (wmProtocols == None)
+ wmProtocols = XInternAtom( display, "WM_PROTOCOLS", True );
+ if (wmDeleteWindow == None)
+ wmDeleteWindow = XInternAtom( display, "WM_DELETE_WINDOW", True );
+
+ if ((event->format != 32) || (event->message_type != wmProtocols) ||
+ (((Atom) event->data.l[0]) != wmDeleteWindow))
+ {
+ dprintf_event( stddeb, "unrecognized ClientMessage\n" );
+ return;
+ }
+ SendMessage( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
+}
+
+
/**********************************************************************
* SetCapture (USER.18)
*/
diff --git a/windows/syscolor.c b/windows/syscolor.c
index 066eb24..4e5bc07 100644
--- a/windows/syscolor.c
+++ b/windows/syscolor.c
@@ -86,7 +86,7 @@
break;
case COLOR_WINDOWTEXT:
DeleteObject( sysColorObjects.hpenWindowText );
- sysColorObjects.hpenWindowText = CreatePen( PS_SOLID, 1, color );
+ sysColorObjects.hpenWindowText = CreatePen( PS_DOT, 1, color );
break;
case COLOR_CAPTIONTEXT:
break;
diff --git a/windows/win.c b/windows/win.c
index 81133a4..697bef1 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -306,11 +306,12 @@
{
HANDLE class, hwnd;
CLASS *classPtr;
- WND *wndPtr;
+ WND *wndPtr, *parentWndPtr;
POINT maxSize, maxPos, minTrack, maxTrack;
CREATESTRUCT createStruct;
int wmcreate;
XSetWindowAttributes win_attr;
+ Atom XA_WM_DELETE_WINDOW;
/* FIXME: windowName and className should be SEGPTRs */
@@ -473,6 +474,15 @@
CWColormap | CWCursor | CWSaveUnder |
CWBackingStore, &win_attr );
XStoreName( display, wndPtr->window, PTR_SEG_TO_LIN(windowName) );
+ XA_WM_DELETE_WINDOW = XInternAtom( display, "WM_DELETE_WINDOW",
+ False );
+ XSetWMProtocols( display, wndPtr->window, &XA_WM_DELETE_WINDOW, 1 );
+ if (parent) /* Get window owner */
+ {
+ Window win = WIN_GetXWindow( parent );
+ if (win) XSetTransientForHint( display, wndPtr->window, win );
+ }
+
EVENT_RegisterWindow( wndPtr->window, hwnd );
}
@@ -663,8 +673,7 @@
/**********************************************************************
- * GetDesktopWindow (USER.286)
- * GetDeskTopHwnd (USER.278)
+ * GetDesktopWindow (USER.286)
*/
HWND GetDesktopWindow(void)
{
@@ -672,6 +681,18 @@
}
+/**********************************************************************
+ * GetDesktopHwnd (USER.278)
+ *
+ * Exactly the same thing as GetDesktopWindow(), but not documented.
+ * Don't ask me why...
+ */
+HWND GetDesktopHwnd(void)
+{
+ return hwndDesktop;
+}
+
+
/*******************************************************************
* EnableWindow (USER.34)
*/
diff --git a/windows/winpos.c b/windows/winpos.c
index 683bde0..40929f4 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -1219,6 +1219,7 @@
if ((flags & SWP_FRAMECHANGED) && !(flags & SWP_NOREDRAW))
RedrawWindow( winpos.hwnd, NULL, 0,
+ RDW_ALLCHILDREN | /*FIXME: this should not be necessary*/
RDW_INVALIDATE | RDW_FRAME | RDW_ERASE );
if (!(flags & SWP_DEFERERASE))
RedrawWindow( wndPtr->hwndParent, NULL, 0,
diff --git a/wine.man b/wine.man
index 5e79214..2f3f6c5 100644
--- a/wine.man
+++ b/wine.man
@@ -104,7 +104,7 @@
.I -language xx
Set the language to
.I xx
-(one of En, Es, De, No, Fr, Fi, Da, Cz)
+(one of En, Es, De, No, Fr, Fi, Da, Cz, Eo)
.TP
.I -managed
Create each top-level window as a properly managed X window