Commit f60ae425 authored by Ben Key's avatar Ben Key

Added a partial implementation of play-sound-internal for Windows. Fixed the...

Added a partial implementation of play-sound-internal for Windows.  Fixed the following entry in etc/PROBLEMS: Emacs built on Windows 9x/ME crashes at startup on Windows XP, or Emacs built on XP crashes at startup on Windows 9x/ME.
parent 87a609d3
2002-11-17 Ben Key <BKey1@tampabay.rr.com>
* nmake.defs: Made changes so that Emacs would link with
WinMM.lib. This change was required for my addition of a Windows
compatible implementation of play-sound-internal.
* gmake.defs: Made changes so that Emacs would link with
WinMM.lib. This change was required for my addition of a Windows
compatible implementation of play-sound-internal.
2002-09-03 Juanma Barranquero <lektu@terra.es> (tiny change) 2002-09-03 Juanma Barranquero <lektu@terra.es> (tiny change)
* emacs.rc: Version updated to 21.3.50. From Peter Runestig * emacs.rc: Version updated to 21.3.50. From Peter Runestig
......
...@@ -166,6 +166,7 @@ MPR = -lmpr ...@@ -166,6 +166,7 @@ MPR = -lmpr
SHELL32 = -lshell32 SHELL32 = -lshell32
USER32 = -luser32 USER32 = -luser32
WSOCK32 = -lwsock32 WSOCK32 = -lwsock32
WINMM = -lwinmm
ifdef NOOPT ifdef NOOPT
DEBUG_CFLAGS = -DEMACSDEBUG DEBUG_CFLAGS = -DEMACSDEBUG
......
...@@ -123,6 +123,7 @@ MPR = mpr.lib ...@@ -123,6 +123,7 @@ MPR = mpr.lib
SHELL32 = shell32.lib SHELL32 = shell32.lib
USER32 = user32.lib USER32 = user32.lib
WSOCK32 = wsock32.lib WSOCK32 = wsock32.lib
WINMM = winmm.lib
!ifdef NOOPT !ifdef NOOPT
DEBUG_CFLAGS = -DEMACSDEBUG DEBUG_CFLAGS = -DEMACSDEBUG
......
2002-11-17 Ben Key <BKey1@tampabay.rr.com>
* w32.c: Added wrapper functions around the win32 API functions
OpenProcessToken, GetTokenInformation, LookupAccountSid, and
GetSidIdentifierAuthority. These wrapper functions serve two
purposes:
1. They ensure that the wrapped function can never be called
when Emacs is running on an operating system on which they are
not supported (Microsoft Windows 95 / 98 / ME).
2. They call the wrapped functions via function pointers rather
than calling them directly. This avoids taking advantage of the
undocumented fact that although these functions are not supported
in the 9x branch of Microsoft Windows, the functions do exist in
the version of advapi32.dll that is found in the 9x branch of
Microsoft Windows.
This change is part of my fix for the following entry in
etc/PROBLEMS: "Emacs built on Windows 9x/ME crashes at startup on
Windows XP, or Emacs built on XP crashes at startup on Windows
9x/ME."
* w32.c (init_user_info): Replaced the calls to the win32 API
functions OpenProcessToken, GetTokenInformation, LookupAccountSid,
and GetSidIdentifierAuthority with calls to the newly added
wrapper functions.
This change is part of my fix for the following entry in
etc/PROBLEMS: "Emacs built on Windows 9x/ME crashes at startup on
Windows XP, or Emacs built on XP crashes at startup on Windows
9x/ME."
* w32.h: Added extern declarations for the following functions:
syms_of_w32term, syms_of_w32fns, syms_of_w32select,
syms_of_w32menu, and void syms_of_fontset.
This change is part of my fix for the following entry in
etc/PROBLEMS: "Emacs built on Windows 9x/ME crashes at startup on
Windows XP, or Emacs built on XP crashes at startup on Windows
9x/ME."
* w32fns.c (w32_wnd_proc): Added code to reinitialize the
function pointer track_mouse_event_fn in the handler for the
WM_SETFOCUS message.
This change is part of my fix for the following entry in
etc/PROBLEMS: "Emacs built on Windows 9x/ME crashes at startup on
Windows XP, or Emacs built on XP crashes at startup on Windows
9x/ME."
* w32menu.c (initialize_frame_menubar): Added code to
reinitialize the function pointers set_menu_item_info and
get_menu_item_info.
This change is part of my fix for the following entry in
etc/PROBLEMS: "Emacs built on Windows 9x/ME crashes at startup on
Windows XP, or Emacs built on XP crashes at startup on Windows
9x/ME."
* sound.c: Added a partial implementation of play-sound-internal
for Microsoft Windows. Added various #ifdef / #else / #endif
code blocks to separate the code that will compile under
Microsoft Windows from the code that is specific to Gnu/Linux.
Moved several blocks of code around to make this separation of
code into Windows compatible and Gnu/Linux compatible code blocks
easier.
* makefile.w32-in: Made modifications so that sound.c would be
included in the Windows port of Emacs and that it would link with
WinMM.lib.
* s/ms-w32.h: Defined the symbol HAVE_SOUND so that the newly
added support for play-sound-internal under Windows would be
included in the build of Emacs.
2002-11-16 Jason Rumney <jasonr@gnu.org> 2002-11-16 Jason Rumney <jasonr@gnu.org>
* w32fns.c (w32_load_system_font): Don't disable Cleartype. * w32fns.c (w32_load_system_font): Don't disable Cleartype.
......
...@@ -94,6 +94,7 @@ OBJ1 = $(BLD)/abbrev.$(O) \ ...@@ -94,6 +94,7 @@ OBJ1 = $(BLD)/abbrev.$(O) \
$(BLD)/regex.$(O) \ $(BLD)/regex.$(O) \
$(BLD)/scroll.$(O) \ $(BLD)/scroll.$(O) \
$(BLD)/search.$(O) \ $(BLD)/search.$(O) \
$(BLD)/sound.$(O) \
$(BLD)/syntax.$(O) \ $(BLD)/syntax.$(O) \
$(BLD)/sysdep.$(O) \ $(BLD)/sysdep.$(O) \
$(BLD)/term.$(O) \ $(BLD)/term.$(O) \
...@@ -133,6 +134,7 @@ LIBS = $(TLIB0) \ ...@@ -133,6 +134,7 @@ LIBS = $(TLIB0) \
$(TLIB1) \ $(TLIB1) \
$(TLIBW32) \ $(TLIBW32) \
$(TLASTLIB) \ $(TLASTLIB) \
$(WINMM) \
$(ADVAPI32) \ $(ADVAPI32) \
$(GDI32) \ $(GDI32) \
$(COMDLG32) \ $(COMDLG32) \
...@@ -1094,6 +1096,13 @@ $(BLD)/search.$(O) : \ ...@@ -1094,6 +1096,13 @@ $(BLD)/search.$(O) : \
$(SRC)/w32bdf.h \ $(SRC)/w32bdf.h \
$(SRC)/w32gui.h $(SRC)/w32gui.h
$(BLD)/sound.$(O) : \
$(SRC)/sound.c \
$(SRC)/lisp.h \
$(SRC)/dispextern.h \
$(SRC)/atimer.h \
$(SRC)/syssignal.h
$(BLD)/strftime.$(O) : \ $(BLD)/strftime.$(O) : \
$(SRC)/strftime.c \ $(SRC)/strftime.c \
$(EMACS_ROOT)/src/s/ms-w32.h \ $(EMACS_ROOT)/src/s/ms-w32.h \
......
...@@ -217,6 +217,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -217,6 +217,7 @@ Boston, MA 02111-1307, USA. */
#define MAXPATHLEN _MAX_PATH #define MAXPATHLEN _MAX_PATH
#endif #endif
#define HAVE_SOUND 1
#define LISP_FLOAT_TYPE 1 #define LISP_FLOAT_TYPE 1
#undef HAVE_SYS_SELECT_H #undef HAVE_SYS_SELECT_H
......
This diff is collapsed.
...@@ -104,6 +104,171 @@ extern Lisp_Object Vw32_generate_fake_inodes; ...@@ -104,6 +104,171 @@ extern Lisp_Object Vw32_generate_fake_inodes;
extern Lisp_Object Vw32_get_true_file_attributes; extern Lisp_Object Vw32_get_true_file_attributes;
extern Lisp_Object Vw32_num_mouse_buttons; extern Lisp_Object Vw32_num_mouse_buttons;
/*
BEGIN: Wrapper functions around OpenProcessToken
and other functions in advapi32.dll that are only
supported in Windows NT / 2k / XP
*/
/* ** Function pointer typedefs ** */
typedef BOOL (WINAPI * OpenProcessToken_Proc) (
HANDLE ProcessHandle,
DWORD DesiredAccess,
PHANDLE TokenHandle);
typedef BOOL (WINAPI * GetTokenInformation_Proc) (
HANDLE TokenHandle,
TOKEN_INFORMATION_CLASS TokenInformationClass,
LPVOID TokenInformation,
DWORD TokenInformationLength,
PDWORD ReturnLength);
#ifdef _UNICODE
const char * const LookupAccountSid_Name = "LookupAccountSidW";
#else
const char * const LookupAccountSid_Name = "LookupAccountSidA";
#endif
typedef BOOL (WINAPI * LookupAccountSid_Proc) (
LPCTSTR lpSystemName,
PSID Sid,
LPTSTR Name,
LPDWORD cbName,
LPTSTR DomainName,
LPDWORD cbDomainName,
PSID_NAME_USE peUse);
typedef PSID_IDENTIFIER_AUTHORITY (WINAPI * GetSidIdentifierAuthority_Proc) (
PSID pSid);
/* ** A utility function ** */
static BOOL is_windows_9x ()
{
BOOL b_ret=0;
OSVERSIONINFO os_ver;
ZeroMemory(&os_ver, sizeof(OSVERSIONINFO));
os_ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx (&os_ver))
{
b_ret = (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
}
return b_ret;
}
/* ** The wrapper functions ** */
BOOL WINAPI open_process_token (
HANDLE ProcessHandle,
DWORD DesiredAccess,
PHANDLE TokenHandle)
{
OpenProcessToken_Proc pfn_Open_Process_Token = NULL;
HMODULE hm_advapi32 = NULL;
if (is_windows_9x () == TRUE)
{
return FALSE;
}
hm_advapi32 = LoadLibrary ("Advapi32.dll");
pfn_Open_Process_Token =
(OpenProcessToken_Proc) GetProcAddress (hm_advapi32, "OpenProcessToken");
if (pfn_Open_Process_Token == NULL)
{
return FALSE;
}
return (
pfn_Open_Process_Token (
ProcessHandle,
DesiredAccess,
TokenHandle)
);
}
BOOL WINAPI get_token_information (
HANDLE TokenHandle,
TOKEN_INFORMATION_CLASS TokenInformationClass,
LPVOID TokenInformation,
DWORD TokenInformationLength,
PDWORD ReturnLength)
{
GetTokenInformation_Proc pfn_Get_Token_Information = NULL;
HMODULE hm_advapi32 = NULL;
if (is_windows_9x () == TRUE)
{
return FALSE;
}
hm_advapi32 = LoadLibrary ("Advapi32.dll");
pfn_Get_Token_Information =
(GetTokenInformation_Proc) GetProcAddress (hm_advapi32, "GetTokenInformation");
if (pfn_Get_Token_Information == NULL)
{
return FALSE;
}
return (
pfn_Get_Token_Information (
TokenHandle,
TokenInformationClass,
TokenInformation,
TokenInformationLength,
ReturnLength)
);
}
BOOL WINAPI lookup_account_sid (
LPCTSTR lpSystemName,
PSID Sid,
LPTSTR Name,
LPDWORD cbName,
LPTSTR DomainName,
LPDWORD cbDomainName,
PSID_NAME_USE peUse)
{
LookupAccountSid_Proc pfn_Lookup_Account_Sid = NULL;
HMODULE hm_advapi32 = NULL;
if (is_windows_9x () == TRUE)
{
return FALSE;
}
hm_advapi32 = LoadLibrary ("Advapi32.dll");
pfn_Lookup_Account_Sid =
(LookupAccountSid_Proc) GetProcAddress (hm_advapi32, LookupAccountSid_Name);
if (pfn_Lookup_Account_Sid == NULL)
{
return FALSE;
}
return (
pfn_Lookup_Account_Sid (
lpSystemName,
Sid,
Name,
cbName,
DomainName,
cbDomainName,
peUse)
);
}
PSID_IDENTIFIER_AUTHORITY WINAPI get_sid_identifier_authority (
PSID pSid)
{
GetSidIdentifierAuthority_Proc pfn_Get_Sid_Identifier_Authority = NULL;
HMODULE hm_advapi32 = NULL;
if (is_windows_9x () == TRUE)
{
return NULL;
}
hm_advapi32 = LoadLibrary ("Advapi32.dll");
pfn_Get_Sid_Identifier_Authority =
(GetSidIdentifierAuthority_Proc) GetProcAddress (
hm_advapi32, "GetSidIdentifierAuthority");
if (pfn_Get_Sid_Identifier_Authority == NULL)
{
return NULL;
}
return (pfn_Get_Sid_Identifier_Authority (pSid));
}
/*
END: Wrapper functions around OpenProcessToken
and other functions in advapi32.dll that are only
supported in Windows NT / 2k / XP
*/
/* Equivalent of strerror for W32 error codes. */ /* Equivalent of strerror for W32 error codes. */
char * char *
...@@ -254,11 +419,15 @@ init_user_info () ...@@ -254,11 +419,15 @@ init_user_info ()
HANDLE token = NULL; HANDLE token = NULL;
SID_NAME_USE user_type; SID_NAME_USE user_type;
if (OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &token) if (
&& GetTokenInformation (token, TokenUser, open_process_token (GetCurrentProcess (), TOKEN_QUERY, &token)
&& get_token_information (
token, TokenUser,
(PVOID) user_sid, sizeof (user_sid), &trash) (PVOID) user_sid, sizeof (user_sid), &trash)
&& LookupAccountSid (NULL, *((PSID *) user_sid), name, &length, && lookup_account_sid (
domain, &dlength, &user_type)) NULL, *((PSID *) user_sid), name, &length,
domain, &dlength, &user_type)
)
{ {
strcpy (the_passwd.pw_name, name); strcpy (the_passwd.pw_name, name);
/* Determine a reasonable uid value. */ /* Determine a reasonable uid value. */
...@@ -271,7 +440,7 @@ init_user_info () ...@@ -271,7 +440,7 @@ init_user_info ()
{ {
SID_IDENTIFIER_AUTHORITY * pSIA; SID_IDENTIFIER_AUTHORITY * pSIA;
pSIA = GetSidIdentifierAuthority (*((PSID *) user_sid)); pSIA = get_sid_identifier_authority (*((PSID *) user_sid));
/* I believe the relative portion is the last 4 bytes (of 6) /* I believe the relative portion is the last 4 bytes (of 6)
with msb first. */ with msb first. */
the_passwd.pw_uid = ((pSIA->Value[2] << 24) + the_passwd.pw_uid = ((pSIA->Value[2] << 24) +
...@@ -282,12 +451,12 @@ init_user_info () ...@@ -282,12 +451,12 @@ init_user_info ()
the_passwd.pw_uid = the_passwd.pw_uid % 60001; the_passwd.pw_uid = the_passwd.pw_uid % 60001;
/* Get group id */ /* Get group id */
if (GetTokenInformation (token, TokenPrimaryGroup, if (get_token_information (token, TokenPrimaryGroup,
(PVOID) user_sid, sizeof (user_sid), &trash)) (PVOID) user_sid, sizeof (user_sid), &trash))
{ {
SID_IDENTIFIER_AUTHORITY * pSIA; SID_IDENTIFIER_AUTHORITY * pSIA;
pSIA = GetSidIdentifierAuthority (*((PSID *) user_sid)); pSIA = get_sid_identifier_authority (*((PSID *) user_sid));
the_passwd.pw_gid = ((pSIA->Value[2] << 24) + the_passwd.pw_gid = ((pSIA->Value[2] << 24) +
(pSIA->Value[3] << 16) + (pSIA->Value[3] << 16) +
(pSIA->Value[4] << 8) + (pSIA->Value[4] << 8) +
......
...@@ -124,5 +124,10 @@ extern LPBYTE w32_get_resource (char * key, LPDWORD type); ...@@ -124,5 +124,10 @@ extern LPBYTE w32_get_resource (char * key, LPDWORD type);
extern void init_ntproc (); extern void init_ntproc ();
extern void term_ntproc (); extern void term_ntproc ();
extern void syms_of_w32term ();
extern void syms_of_w32fns ();
extern void syms_of_w32select ();
extern void syms_of_w32menu ();
extern void syms_of_fontset ();
#endif /* EMACS_W32_H */ #endif /* EMACS_W32_H */
...@@ -283,7 +283,12 @@ static unsigned mouse_move_timer = 0; ...@@ -283,7 +283,12 @@ static unsigned mouse_move_timer = 0;
/* Window that is tracking the mouse. */ /* Window that is tracking the mouse. */
static HWND track_mouse_window; static HWND track_mouse_window;
FARPROC track_mouse_event_fn;
typedef BOOL (WINAPI * TrackMouseEvent_Proc) (
IN OUT LPTRACKMOUSEEVENT lpEventTrack
);
TrackMouseEvent_Proc track_mouse_event_fn=NULL;
/* W95 mousewheel handler */ /* W95 mousewheel handler */
unsigned int msh_mousewheel = 0; unsigned int msh_mousewheel = 0;
...@@ -4929,6 +4934,30 @@ w32_wnd_proc (hwnd, msg, wParam, lParam) ...@@ -4929,6 +4934,30 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
goto dflt; goto dflt;
case WM_SETFOCUS: case WM_SETFOCUS:
/*
Reinitialize the function pointer track_mouse_event_fn here.
This is required even though it is initialized in syms_of_w32fns
which is called in main (emacs.c).
Reinitialize the function pointer track_mouse_event_fn here.
Even though this function pointer is initialized in
syms_of_w32fns which is called from main (emacs.c),
we need to initialize it again here in order to prevent
a crash that occurs in Windows 9x (possibly only when Emacs
was built on Windows NT / 2000 / XP?) when handling the
WM_MOUSEMOVE message.
The crash occurs when attempting to call the Win32 API
function TrackMouseEvent through the function pointer.
It appears as if the function pointer that is obtained when
syms_of_w32fns is called from main is no longer valid
(possibly due to DLL relocation?).
To resolve this issue, I have placed a call to reinitialize
this function pointer here because this message gets received
when the Emacs window gains focus.
*/
track_mouse_event_fn =
(TrackMouseEvent_Proc) GetProcAddress (
GetModuleHandle ("user32.dll"),
"TrackMouseEvent");
dpyinfo->faked_key = 0; dpyinfo->faked_key = 0;
reset_modifiers (); reset_modifiers ();
register_hot_keys (hwnd); register_hot_keys (hwnd);
...@@ -14843,7 +14872,7 @@ syms_of_w32fns () ...@@ -14843,7 +14872,7 @@ syms_of_w32fns ()
/* TrackMouseEvent not available in all versions of Windows, so must load /* TrackMouseEvent not available in all versions of Windows, so must load
it dynamically. Do it once, here, instead of every time it is used. */ it dynamically. Do it once, here, instead of every time it is used. */
track_mouse_event_fn = GetProcAddress (user32_lib, "TrackMouseEvent"); track_mouse_event_fn = (TrackMouseEvent_Proc) GetProcAddress (user32_lib, "TrackMouseEvent");
track_mouse_window = NULL; track_mouse_window = NULL;
w32_visible_system_caret_hwnd = NULL; w32_visible_system_caret_hwnd = NULL;
......
...@@ -129,8 +129,23 @@ typedef struct _widget_value ...@@ -129,8 +129,23 @@ typedef struct _widget_value
static HMENU current_popup_menu; static HMENU current_popup_menu;
FARPROC get_menu_item_info; void syms_of_w32menu ();
FARPROC set_menu_item_info;
typedef BOOL (WINAPI * GetMenuItemInfoA_Proc) (
IN HMENU,
IN UINT,
IN BOOL,
IN OUT LPMENUITEMINFOA
);
typedef BOOL (WINAPI * SetMenuItemInfoA_Proc) (
IN HMENU,
IN UINT,
IN BOOL,
IN LPCMENUITEMINFOA
);
GetMenuItemInfoA_Proc get_menu_item_info=NULL;
SetMenuItemInfoA_Proc set_menu_item_info=NULL;
Lisp_Object Vmenu_updating_frame; Lisp_Object Vmenu_updating_frame;
...@@ -1591,6 +1606,26 @@ void ...@@ -1591,6 +1606,26 @@ void
initialize_frame_menubar (f) initialize_frame_menubar (f)
FRAME_PTR f; FRAME_PTR f;
{ {
HMODULE user32 = GetModuleHandle ("user32.dll");
/*
Reinitialize the function pointers set_menu_item_info and
get_menu_item_info here.
Even though these function pointers are initialized in
syms_of_w32menu which is called from main (emacs.c),
we need to initialize them again here in order to prevent
a crash that occurs in Windows 9x (possibly only when Emacs
was built on Windows NT / 2000 / XP?) in add_menu_item.
The crash occurs when attempting to call the Win32 API
function SetMenuItemInfo through the function pointer.
It appears as if the function pointer that is obtained when
syms_of_w32menu is called from main is no longer valid
(possibly due to DLL relocation?).
To resolve this issue, I have placed calls to reinitialize
these function pointers here because this function is the
entry point for menu creation.
*/
get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA");
set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA");
/* This function is called before the first chance to redisplay /* This function is called before the first chance to redisplay
the frame. It has to be, so the frame will have the right size. */ the frame. It has to be, so the frame will have the right size. */
FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f)); FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
...@@ -2355,13 +2390,12 @@ w32_free_menu_strings (hwnd) ...@@ -2355,13 +2390,12 @@ w32_free_menu_strings (hwnd)
#endif /* HAVE_MENUS */ #endif /* HAVE_MENUS */
void syms_of_w32menu ()
syms_of_w32menu ()
{ {
/* See if Get/SetMenuItemInfo functions are available. */ /* See if Get/SetMenuItemInfo functions are available. */
HMODULE user32 = GetModuleHandle ("user32.dll"); HMODULE user32 = GetModuleHandle ("user32.dll");
get_menu_item_info = GetProcAddress (user32, "GetMenuItemInfoA"); get_menu_item_info = (GetMenuItemInfoA_Proc) GetProcAddress (user32, "GetMenuItemInfoA");
set_menu_item_info = GetProcAddress (user32, "SetMenuItemInfoA"); set_menu_item_info = (SetMenuItemInfoA_Proc) GetProcAddress (user32, "SetMenuItemInfoA");
staticpro (&menu_items); staticpro (&menu_items);
menu_items = Qnil; menu_items = Qnil;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment