Release 980726
Sat Jul 25 19:45:45 1998 Juergen Schmied <juergen.schmied@metronet.de>
* [include/shlobj.h][misc/shell.c][misc/shellord.c][ole/folders.c]
[shell32.spec]
Added SHFILEOPSTRUCT32[A|W] and constants, prototypes.
Implemented SHGetSpecialFolderLocation, SHGetPathFromIDList32[A].
Many IShellFolder, pidl, shell -related changes.
SHChangeNotifyRegister, SHChangeNotifyDeregister,
SHShellFolderView_Message, SHMapPIDLToSystemImageListIndex,
SHAddToRecentDocs32, SHFileOperation, SHChangeNotify,
SHCreateShellFolderViewEx stubs.
Sat Jul 25 17:16:25 1998 Huw D M Davies <daviesh@abacus.physics.ox.ac.uk>
* [files/profile.c]
Fix return value of PROFILE_GetSection().
Fri Jul 24 22:45:19 1998 Ove Kaaven <ovek@isflak.arcticnet.no>
* [controls/edit.c]
Killed the modified flag on WM_SETTEXT. Eudora should no longer
bother asking whether you want to save an unchanged message.
Fri Jul 24 21:21:35 1998 Andreas Mohr <100.30936@germany.net>
* [controls/menu.c]
Fixed bug in GetMenuState32.
Doesn't fix Free Agent 32 :((
* [documentation/debugging]
Hints added.
* [files/dos_fs.c] [include/msdos.h] [msdos/int21.c]
Enhanced DOS device support.
* [if1632/Makefile.in] [if1632/builtin.c] [if1632/rasapi16.spec]
[relay32/Makefile.in] [relay32/builtin32.c] [relay32/rasapi32.spec]
Added RASAPI16/32.DLL.
* [misc/aspi.c] [relay32/wnaspi32.spec]
Implemented GetASPI32SupportInfo.
* [multimedia/mmsystem.c]
Implemented mmTaskCreate.
Fri Jul 24 20:55:31 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
* [controls/toolbar.c]
Fixed some bugs and added new features.
* [controls/tooltips.c][include/tooltips.h]
Added more messages and started display code.
* [misc/shell.c][misc/shellord.c][relay32/shell.spec]
Fixed StrToOleStrN (SHELL32_79) and added OleStrToStrN (SHELL32_78).
Added some new stubs.
* [objects/cursoricon.c][misc/imagelist.c][include/windows.h]
Fixed GetIconInfo and removed the GetIconInfo hack from the
image list code.
* [controls/pager.c][include/pager.h][controls/treeview.c]
[include/treeview.h]
Added some messages.
* [misc/tweak.c][winows/nonclient.c][documentation/win95look]
Removed unused tweak variables.
* [documentation/common_controls]
Updated.
Fri Jul 24 18:36:32 1998 James Moody <013263m@dragon.acadiau.ca>
* [objects/font.c]
Fixed a bug in GetTextFace.
Fri Jul 24 17:09:33 1998 Marcus Meissner <marcus@jet.franken.de>
* [misc/commdlg.c]
Fixed stacksmashing bug due to invalid specified function
pointers.
* [files/dos_fs.c]
Small change in case handling... be able to create files with
uppercase in them (like Program Files/).
* [graphics/ddraw.c]
XF86DGA support made threadsafe, added more Xlib dependent stuff
(create Window using CreateWindow(), draw into it). xlib support
is not satisfying.
* [scheduler/critsection.c]
Don't recurse on HeapLock with semaphore id 0.
* [win32/user32.c][windows/message.c][windows/event.c]
Moved win32 *Message functions where they belong.
Removed some potential races between XPending and XNextEvent by
a bit more locking.
Fri Jul 24 13:58:19 1998 Alexandre Julliard <julliard@lrc.epfl.ch>
* [loader/pe_image.c] [loader/ne/segment.c]
Use bogus pointer value instead of NULL for unresolved externals.
* [memory/selector.c]
Clear saved_fs on selector free.
* [msdos/cdrom.c] [configure.in]
Added check for linux/ucdrom.h.
* [scheduler/client.c] [server/socket.c]
Fix for missing struct cmsghdr.
Attempt to support msg_accrights fd passing (completely untested).
* [windows/event.c]
Do not grab the pointer in SetCapture (Win32 behavior).
Tue Jul 21 22:28:13 1998 James Juran <jrj120@psu.edu>
* [Make.rules.in]
Changed $(MKDIR) macro to use -p option (make parent directories
if they don't already exist. This fixes an error in 'make install'
if /usr/local/include doesn't already exist.
Tue Jul 21 13:37:04 Rein Klazes <rklazes@casema.net>
* [include/heap.h]
Replaced macro SEGPTR_GET by inline function to avoid *lots*
of wrong use of this macro.
* [relay32/comdlg32.spec]
Corrected GetSaveFileNameW entry.
* [relay32/advapi32.spec] [win32/advapi.c]
[relay32/ole32.spec] [ ole/moniker.c]
Added stubs for SetFileSecurity[AW] and CreateFileMoniker32
* [graphics/x11drv/graphics.c]
Finished implementation of bezier drawing code.
Tue Jul 21 11:00:51 1998 Claus Fischer <cfischer@td2cad.intel.com>
* [files/drive.c]
Remove label trailing blanks in GetVolumeInformation32A.
* [documentation/cdrom-labels]
Added documentation on how to find out a CD-ROM label.
Sun Jul 19 23:16:41 1998 Pascal Cuoq <pcuoq@ens-lyon.fr>
* [include/windows.h]
Added some DM_* and DISP_CHANGE_* flags.
* [relay32/user32.spec] [windows/user.c]
Added stub for ChangeDisplaySettingA.
* [ole/ole2nls.c]
is_punctuation: reuse information from another table.
Sun Jul 19 22:04:46 1998 Douglas Ridgway <ridgway@winehq.com>
* [Make.rules.in]
Updated automatic documentation rules.
* [graphics/path.c] [misc/aspi.c] [misc/ntdll.c] [misc/winsock_dns.c]
[ole/ole2dsp.c] [relay32/user32.spec]
Comment format futzing to keep c2man happy.
* [documentation/README.documentation]
Updated description of automatic documentation.
Wed Jul 15 19:10:09 1998 Andrew M. Bishop <amb@gedanken.demon.co.uk>
* [files/profile.c]
Cache the 10 most recently used .ini files.
Tue May 20 19:20:23 1997 Pablo Saratxaga <srtxg@chanae.alphanet.ch>
* [misc/commdlg.c]
Makes PrintDlg32A() return TRUE even if it is an empty
stub, so most programs are happy and run anyway instead of
aborting at startup.
* [graphics/x11drv/xfont.c]
Increased the maximum font families as (X11) font aliases
eated up a lot of families causing wine to stop reading fonts.
diff --git a/files/profile.c b/files/profile.c
index 4110e71..c1f0daf 100644
--- a/files/profile.c
+++ b/files/profile.c
@@ -9,6 +9,8 @@
#include <stdlib.h>
#include <string.h>
+#include <sys/stat.h>
+
#include "windows.h"
#include "file.h"
#include "heap.h"
@@ -36,11 +38,16 @@
char *dos_name;
char *unix_name;
char *filename;
+ time_t mtime;
} PROFILE;
-/* Cached profile file */
-static PROFILE CurProfile = { FALSE, NULL, NULL };
+#define N_CACHED_PROFILES 10
+
+/* Cached profile files */
+static PROFILE *MRUProfile[N_CACHED_PROFILES]={NULL};
+
+#define CurProfile (MRUProfile[0])
/* wine.ini profile content */
static PROFILESECTION *WineProfile;
@@ -205,17 +212,22 @@
next_section = §ion->next;
next_key = §ion->key;
prev_key = NULL;
+
+ TRACE(profile, "New section: '%s'\n",section->name);
+
continue;
}
}
+
+ p2=p+strlen(p) - 1;
+ while ((p2 > p) && ((*p2 == '\n') || PROFILE_isspace(*p2))) *p2--='\0';
+
if ((p2 = strchr( p, '=' )) != NULL)
{
char *p3 = p2 - 1;
while ((p3 > p) && PROFILE_isspace(*p3)) *p3-- = '\0';
*p2++ = '\0';
while (*p2 && PROFILE_isspace(*p2)) p2++;
- p3 = p2 + strlen(p2) - 1;
- while ((p3 > p2) && ((*p3 == '\n') || PROFILE_isspace(*p3))) *p3--='\0';
}
if(*p || !prev_key || *prev_key->name)
@@ -341,9 +353,16 @@
char *p, buffer[MAX_PATHNAME_LEN];
const char *unix_name;
FILE *file = NULL;
+ struct stat buf;
- if (!CurProfile.changed || !CurProfile.dos_name) return TRUE;
- if (!(unix_name = CurProfile.unix_name) || !(file = fopen(unix_name, "w")))
+ if(!CurProfile)
+ {
+ WARN(profile, "No current profile!\n");
+ return FALSE;
+ }
+
+ if (!CurProfile->changed || !CurProfile->dos_name) return TRUE;
+ if (!(unix_name = CurProfile->unix_name) || !(file = fopen(unix_name, "w")))
{
/* Try to create it in $HOME/.wine */
/* FIXME: this will need a more general solution */
@@ -352,7 +371,7 @@
strcpy( buffer, p );
strcat( buffer, "/.wine/" );
p = buffer + strlen(buffer);
- strcpy( p, strrchr( CurProfile.dos_name, '\\' ) + 1 );
+ strcpy( p, strrchr( CurProfile->dos_name, '\\' ) + 1 );
CharLower32A( p );
file = fopen( buffer, "w" );
unix_name = buffer;
@@ -361,14 +380,16 @@
if (!file)
{
- WARN(profile, "could not save profile file %s\n", CurProfile.dos_name);
+ WARN(profile, "could not save profile file %s\n", CurProfile->dos_name);
return FALSE;
}
- TRACE(profile, "Saving '%s' into '%s'\n", CurProfile.dos_name, unix_name );
- PROFILE_Save( file, CurProfile.section );
+ TRACE(profile, "Saving '%s' into '%s'\n", CurProfile->dos_name, unix_name );
+ PROFILE_Save( file, CurProfile->section );
fclose( file );
- CurProfile.changed = FALSE;
+ CurProfile->changed = FALSE;
+ if(!stat(unix_name,&buf))
+ CurProfile->mtime=buf.st_mtime;
return TRUE;
}
@@ -384,13 +405,25 @@
char buffer[MAX_PATHNAME_LEN];
char *newdos_name, *p;
FILE *file = NULL;
+ int i,j;
+ struct stat buf;
+ PROFILE *tempProfile;
- if (CurProfile.filename && !strcmp( filename, CurProfile.filename ))
- {
- TRACE(profile, "(%s): already opened\n",
- filename );
- return TRUE;
- }
+ /* First time around */
+
+ if(!CurProfile)
+ for(i=0;i<N_CACHED_PROFILES;i++)
+ {
+ MRUProfile[i]=HEAP_xalloc( SystemHeap, 0, sizeof(PROFILE) );
+ MRUProfile[i]->changed=FALSE;
+ MRUProfile[i]->section=NULL;
+ MRUProfile[i]->dos_name=NULL;
+ MRUProfile[i]->unix_name=NULL;
+ MRUProfile[i]->filename=NULL;
+ MRUProfile[i]->mtime=0;
+ }
+
+ /* Check for a match */
if (strchr( filename, '/' ) || strchr( filename, '\\' ) ||
strchr( filename, ':' ))
@@ -404,25 +437,61 @@
strcat( buffer, filename );
if (!DOSFS_GetFullName( buffer, FALSE, &full_name )) return FALSE;
}
- if (CurProfile.dos_name &&
- !strcmp( full_name.short_name, CurProfile.dos_name ))
- {
- TRACE(profile, "(%s): already opened\n",
- filename );
- return TRUE;
- }
- /* Flush the previous profile */
+ for(i=0;i<N_CACHED_PROFILES;i++)
+ {
+ if ((MRUProfile[i]->filename && !strcmp( filename, MRUProfile[i]->filename )) ||
+ (MRUProfile[i]->dos_name && !strcmp( full_name.short_name, MRUProfile[i]->dos_name )))
+ {
+ if(i)
+ {
+ PROFILE_FlushFile();
+ tempProfile=MRUProfile[i];
+ for(j=i;j>0;j--)
+ MRUProfile[j]=MRUProfile[j-1];
+ CurProfile=tempProfile;
+ }
+ if(!stat(CurProfile->unix_name,&buf) && CurProfile->mtime==buf.st_mtime)
+ {
+ TRACE(profile, "(%s): already opened (mru=%d)\n",
+ filename, i );
+ return TRUE;
+ }
+ TRACE(profile, "(%s): already opened, needs refreshing (mru=%d)\n",
+ filename, i );
+ }
+ }
+
+ /* Rotate the oldest to the top to be replaced */
+
+ if(i==N_CACHED_PROFILES)
+ {
+ tempProfile=MRUProfile[N_CACHED_PROFILES-1];
+ for(i=N_CACHED_PROFILES-1;i>0;i--)
+ MRUProfile[i]=MRUProfile[i-1];
+ CurProfile=tempProfile;
+ }
+
+ /* Flush the profile */
+
+ if(CurProfile->filename)
+ {
+ PROFILE_FlushFile();
+ PROFILE_Free( CurProfile->section );
+ if (CurProfile->dos_name) HeapFree( SystemHeap, 0, CurProfile->dos_name );
+ if (CurProfile->unix_name) HeapFree( SystemHeap, 0, CurProfile->unix_name );
+ if (CurProfile->filename) HeapFree( SystemHeap, 0, CurProfile->filename );
+ CurProfile->changed=FALSE;
+ CurProfile->section=NULL;
+ CurProfile->dos_name=NULL;
+ CurProfile->unix_name=NULL;
+ CurProfile->filename=NULL;
+ CurProfile->mtime=0;
+ }
newdos_name = HEAP_strdupA( SystemHeap, 0, full_name.short_name );
- PROFILE_FlushFile();
- PROFILE_Free( CurProfile.section );
- if (CurProfile.dos_name) HeapFree( SystemHeap, 0, CurProfile.dos_name );
- if (CurProfile.unix_name) HeapFree( SystemHeap, 0, CurProfile.unix_name );
- if (CurProfile.filename) HeapFree( SystemHeap, 0, CurProfile.filename );
- CurProfile.section = NULL;
- CurProfile.dos_name = newdos_name;
- CurProfile.filename = HEAP_strdupA( SystemHeap, 0, filename );
+ CurProfile->dos_name = newdos_name;
+ CurProfile->filename = HEAP_strdupA( SystemHeap, 0, filename );
/* Try to open the profile file, first in $HOME/.wine */
@@ -438,13 +507,13 @@
{
TRACE(profile, "(%s): found it in %s\n",
filename, buffer );
- CurProfile.unix_name = HEAP_strdupA( SystemHeap, 0, buffer );
+ CurProfile->unix_name = HEAP_strdupA( SystemHeap, 0, buffer );
}
}
if (!file)
{
- CurProfile.unix_name = HEAP_strdupA( SystemHeap, 0,
+ CurProfile->unix_name = HEAP_strdupA( SystemHeap, 0,
full_name.long_name );
if ((file = fopen( full_name.long_name, "r" )))
TRACE(profile, "(%s): found it in %s\n",
@@ -453,8 +522,10 @@
if (file)
{
- CurProfile.section = PROFILE_Load( file );
+ CurProfile->section = PROFILE_Load( file );
fclose( file );
+ if(!stat(CurProfile->unix_name,&buf))
+ CurProfile->mtime=buf.st_mtime;
}
else
{
@@ -481,7 +552,7 @@
if (section->name && !strcasecmp( section->name, section_name ))
{
UINT32 oldlen = len;
- for (key = section->key; key; key = key->next)
+ for (key = section->key; key && *(key->name); key = key->next)
{
if (len <= 2) break;
if (IS_ENTRY_COMMENT(key->name)) continue; /* Skip comments */
@@ -507,7 +578,7 @@
buffer[-1] = '\0';
return oldlen - 2;
}
- return oldlen - len + 1;
+ return oldlen - len;
}
section = section->next;
}
@@ -529,14 +600,14 @@
if (!def_val) def_val = "";
if (key_name && key_name[0])
{
- key = PROFILE_Find( &CurProfile.section, section, key_name, FALSE );
+ key = PROFILE_Find( &CurProfile->section, section, key_name, FALSE );
PROFILE_CopyEntry( buffer, (key && key->value) ? key->value : def_val,
len, FALSE );
TRACE(profile, "('%s','%s','%s'): returning '%s'\n",
section, key_name, def_val, buffer );
return strlen( buffer );
}
- return PROFILE_GetSection(CurProfile.section, section, buffer, len,
+ return PROFILE_GetSection(CurProfile->section, section, buffer, len,
FALSE, FALSE);
}
@@ -552,8 +623,8 @@
if (!key_name) /* Delete a whole section */
{
TRACE(profile, "('%s')\n", section_name);
- CurProfile.changed |= PROFILE_DeleteSection( &CurProfile.section,
- section_name );
+ CurProfile->changed |= PROFILE_DeleteSection( &CurProfile->section,
+ section_name );
return TRUE; /* Even if PROFILE_DeleteSection() has failed,
this is not an error on application's level.*/
}
@@ -561,13 +632,13 @@
{
TRACE(profile, "('%s','%s')\n",
section_name, key_name );
- CurProfile.changed |= PROFILE_DeleteKey( &CurProfile.section,
- section_name, key_name );
+ CurProfile->changed |= PROFILE_DeleteKey( &CurProfile->section,
+ section_name, key_name );
return TRUE; /* same error handling as above */
}
else /* Set the key value */
{
- PROFILEKEY *key = PROFILE_Find( &CurProfile.section, section_name,
+ PROFILEKEY *key = PROFILE_Find( &CurProfile->section, section_name,
key_name, TRUE );
TRACE(profile, "('%s','%s','%s'): \n",
section_name, key_name, value );
@@ -584,7 +655,7 @@
}
else TRACE(profile, " creating key\n" );
key->value = HEAP_strdupA( SystemHeap, 0, value );
- CurProfile.changed = TRUE;
+ CurProfile->changed = TRUE;
}
return TRUE;
}
@@ -1013,7 +1084,7 @@
UINT32 len, LPCSTR filename )
{
if (PROFILE_Open( filename ))
- return PROFILE_GetSection(CurProfile.section, section, buffer, len,
+ return PROFILE_GetSection(CurProfile->section, section, buffer, len,
FALSE, TRUE);
return 0;
@@ -1092,7 +1163,7 @@
if (PROFILE_Open( filename )) {
buf=buffer;
cursize=0;
- section=CurProfile.section;
+ section=CurProfile->section;
for ( ; section; section = section->next)
if (section->name) {
l=strlen (section->name);
@@ -1122,7 +1193,7 @@
PROFILEKEY *k;
if (PROFILE_Open( filename )) {
- k=PROFILE_Find ( &CurProfile.section, section, key, FALSE);
+ k=PROFILE_Find ( &CurProfile->section, section, key, FALSE);
if (!k) return FALSE;
lstrcpyn32A( buf, k->value, strlen(k->value));
return TRUE;