/* mswindows GUI code. (menubars, scrollbars, toolbars, dialogs)
Copyright (C) 1998 Andy Piper.
Copyright (C) 2002 Ben Wing.
This file is part of XEmacs.
XEmacs is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
XEmacs is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with XEmacs. If not, see . */
/* Synched up with: Not in FSF. */
/* This file essentially Mule-ized (except perhaps some Unicode splitting).
5-2000. */
#include
#include "lisp.h"
#include "console-msw-impl.h"
#include "redisplay.h"
#include "gui.h"
#include "glyphs.h"
#include "frame-impl.h"
#include "elhash.h"
#include "events.h"
#include "buffer.h"
/*
* Return value is Qt if we have dispatched the command,
* or Qnil if id has not been mapped to a callback.
* Window procedure may try other targets to route the
* command if we return nil
*/
Lisp_Object
mswindows_handle_gui_wm_command (struct frame *f, HWND UNUSED (ctrl),
LPARAM id)
{
/* Try to map the command id through the proper hash table */
Lisp_Object callback, callback_ex, image_instance, frame, event;
frame = wrap_frame (f);
image_instance = Fgethash (make_fixnum_verify (id),
FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f), Qnil);
/* It is possible for a widget action to cause it to get out of sync
with its instantiator. Thus it is necessary to signal this
possibility. */
if (IMAGE_INSTANCEP (image_instance))
XIMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (image_instance) = 1;
callback = Fgethash (make_fixnum (id),
FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f), Qnil);
callback_ex = Fgethash (make_fixnum (id),
FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f), Qnil);
if (!NILP (callback_ex) && !UNBOUNDP (callback_ex))
{
event = Fmake_event (Qnil, Qnil);
XSET_EVENT_TYPE (event, misc_user_event);
XSET_EVENT_CHANNEL (event, frame);
XSET_EVENT_TIMESTAMP (event, GetTickCount());
XSET_EVENT_MISC_USER_FUNCTION (event, Qeval);
XSET_EVENT_MISC_USER_OBJECT (event,
list4 (Qfuncall, callback_ex, image_instance, event));
}
else if (NILP (callback) || UNBOUNDP (callback))
return Qnil;
else
{
Lisp_Object fn, arg;
event = Fmake_event (Qnil, Qnil);
get_gui_callback (callback, &fn, &arg);
XSET_EVENT_TYPE (event, misc_user_event);
XSET_EVENT_CHANNEL (event, frame);
XSET_EVENT_TIMESTAMP (event, GetTickCount());
XSET_EVENT_MISC_USER_FUNCTION (event, fn);
XSET_EVENT_MISC_USER_OBJECT (event, arg);
}
mswindows_enqueue_dispatch_event (event);
/* The result of this evaluation could cause other instances to change so
enqueue an update callback to check this. */
enqueue_magic_eval_event (update_widget_instances, frame);
return Qt;
}
/*
* Translate X accelerator syntax to win32 accelerator syntax.
* accel = (Ichar*) to receive the accelerator character
* or NULL to suppress accelerators in the menu or dialog item.
*
* %% is replaced with %
* if accel is NULL:
* %_ is removed.
* if accel is non-NULL:
* %_ is replaced with &.
* The accelerator character is passed back in *accel.
* (If there is no accelerator, it will be added on the first character.)
*
*/
Lisp_Object
mswindows_translate_menu_or_dialog_item (Lisp_Object item, Ichar *accel)
{
Bytecount len = XSTRING_LENGTH (item);
Ibyte *it = alloca_ibytes (2 * len + 42), *ptr = it;
memcpy (ptr, XSTRING_DATA (item), len + 1);
if (accel)
*accel = '\0';
/* Escape '&' as '&&' */
while ((ptr = (Ibyte *) memchr (ptr, '&', len - (ptr - it))) != NULL)
{
memmove (ptr + 1, ptr, (len - (ptr - it)) + 1);
len++;
ptr += 2;
}
/* Replace XEmacs accelerator '%_' with Windows accelerator '&'
and `%%' with `%'. */
ptr = it;
while ((ptr = (Ibyte *) memchr (ptr, '%', len - (ptr - it))) != NULL)
{
if (*(ptr + 1) == '_')
{
if (accel)
{
*ptr = '&';
if (!*accel)
*accel = DOWNCASE (0, itext_ichar (ptr + 2));
memmove (ptr + 1, ptr + 2, len - (ptr - it + 2) + 1);
len--;
}
else /* Skip accelerator */
{
memmove (ptr, ptr + 2, len - (ptr - it + 2) + 1);
len -= 2;
}
}
else if (*(ptr + 1) == '%')
{
memmove (ptr + 1, ptr + 2, len - (ptr - it + 2) + 1);
len--;
ptr++;
}
else /* % on its own - shouldn't happen */
ptr++;
}
if (accel && !*accel)
{
/* Force a default accelerator */
ptr = it;
memmove (ptr + 1, ptr, len + 1);
*accel = DOWNCASE (0, itext_ichar (ptr + 1));
*ptr = '&';
len++;
}
return make_string (it, len);
}
void
syms_of_gui_mswindows (void)
{
}