diff --git a/src/frame.c b/src/frame.c index 32e607d16..c10ce98b5 100644 --- a/src/frame.c +++ b/src/frame.c @@ -35,6 +35,16 @@ struct _MetaFrameActionGrab int start_button; }; +/* This lacks ButtonReleaseMask to avoid the auto-grab + * since it breaks our popup menu + */ +#define EVENT_MASK (StructureNotifyMask | SubstructureNotifyMask | \ + ExposureMask | \ + ButtonPressMask | ButtonReleaseMask | \ + PointerMotionMask | PointerMotionHintMask | \ + EnterWindowMask | LeaveWindowMask) + + static void clear_tip (MetaFrame *frame); static void @@ -244,14 +254,7 @@ meta_window_ensure_frame (MetaWindow *window) window->size_hints.win_gravity); attrs.background_pixel = frame->bg_pixel; - attrs.event_mask = - StructureNotifyMask | SubstructureNotifyMask | ExposureMask | - /* We need OwnerGrabButtonMask because during a button - * press we may need to transfer control to the UI slave. - */ - ButtonPressMask | ButtonReleaseMask | OwnerGrabButtonMask | - PointerMotionMask | PointerMotionHintMask | - EnterWindowMask | LeaveWindowMask; + attrs.event_mask = EVENT_MASK; frame->xwindow = XCreateWindow (window->display->xdisplay, window->screen->xroot, @@ -804,6 +807,38 @@ meta_frame_event (MetaFrame *frame, frame->grab->start_window_y = frame->window->rect.height; frame->grab->start_button = event->xbutton.button; } + else if (control == META_FRAME_CONTROL_MENU && + event->xbutton.button == 1) + { + int x, y, width, height; + MetaFrameInfo info; + + meta_verbose ("Menu control clicked on %s\n", + frame->window->desc); + + meta_frame_init_info (frame, &info); + frame->window->screen->engine->get_control_rect (&info, + META_FRAME_CONTROL_MENU, + &x, &y, &width, &height, + frame->theme_data); + + /* Let the menu get a grab. The user could release button + * before the menu gets the grab, in which case the + * menu gets somewhat confused, but it's not that + * disastrous. + */ + XUngrabPointer (frame->window->display->xdisplay, + event->xbutton.time); + + meta_ui_slave_show_window_menu (frame->window->screen->uislave, + frame->window, + frame->rect.x + x, + frame->rect.y + y + height, + event->xbutton.button, + META_MESSAGE_MENU_ALL, + META_MESSAGE_MENU_MINIMIZE, + event->xbutton.time); + } } break; case ButtonRelease: diff --git a/src/keybindings.c b/src/keybindings.c index 56ab3646a..38ad32e10 100644 --- a/src/keybindings.c +++ b/src/keybindings.c @@ -52,7 +52,17 @@ struct _MetaKeyBinding static MetaKeyBinding bindings[] = { { XK_F1, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (0), 0 }, - { XK_F2, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (1), 0 } + { XK_F2, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (1), 0 }, + { XK_F3, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (2), 0 }, + { XK_F4, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (3), 0 }, + { XK_F5, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (4), 0 }, + { XK_F6, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (5), 0 }, + { XK_1, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (0), 0 }, + { XK_2, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (1), 0 }, + { XK_3, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (2), 0 }, + { XK_4, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (3), 0 }, + { XK_5, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (4), 0 }, + { XK_6, Mod1Mask, handle_activate_workspace, GINT_TO_POINTER (5), 0 } }; void diff --git a/src/menu.c b/src/menu.c new file mode 100644 index 000000000..292e99484 --- /dev/null +++ b/src/menu.c @@ -0,0 +1,190 @@ +/* Metacity window menu */ + +/* + * Copyright (C) 2001 Havoc Pennington + * + * This program 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 2 of the + * License, or (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "menu.h" +#include "main.h" +#include + +typedef struct _MenuItem MenuItem; +typedef struct _MenuData MenuData; + +struct _MenuItem +{ + MetaMessageWindowMenuOps op; + const char *stock_id; + const char *label; +}; + + +struct _MenuData +{ + GdkWindow *window; + MetaMessageWindowMenuOps op; +}; + +static void activate_cb (GtkWidget *menuitem, gpointer data); + +static GtkWidget *menu = NULL; +static MenuItem menuitems[] = { + { META_MESSAGE_MENU_DELETE, GTK_STOCK_CLOSE, N_("Close") }, + { META_MESSAGE_MENU_MINIMIZE, NULL, N_("Minimize") }, + { META_MESSAGE_MENU_MAXIMIZE, NULL, N_("Maximize") } +}; + +static void +popup_position_func (GtkMenu *menu, + gint *x, + gint *y, + gboolean *push_in, + gpointer user_data) +{ + GtkRequisition req; + GdkPoint *pos; + + pos = user_data; + + gtk_widget_size_request (GTK_WIDGET (menu), &req); + + *x = pos->x; + *y = pos->y; + + /* Ensure onscreen */ + *x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width)); + *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height)); +} + +void +meta_window_menu_show (gulong xwindow, + int root_x, int root_y, + int button, + MetaMessageWindowMenuOps ops, + MetaMessageWindowMenuOps insensitive, + guint32 timestamp) +{ + int i; + GdkWindow *window; + GdkPoint *pt; + + if (menu) + gtk_widget_destroy (menu); + + window = gdk_xid_table_lookup (xwindow); + if (window) + g_object_ref (G_OBJECT (window)); + else + window = gdk_window_foreign_new (xwindow); + + /* X error creating the foreign window means NULL here */ + if (window == NULL) + return; + + menu = gtk_menu_new (); + + i = 0; + while (i < G_N_ELEMENTS (menuitems)) + { + if (ops & menuitems[i].op) + { + GtkWidget *mi; + MenuData *md; + + if (menuitems[i].stock_id) + { + GtkWidget *image; + + mi = gtk_image_menu_item_new_with_label (menuitems[i].label); + image = gtk_image_new_from_stock (menuitems[i].stock_id, + GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), + image); + gtk_widget_show (image); + } + else + { + mi = gtk_menu_item_new_with_label (menuitems[i].label); + } + + if (insensitive & menuitems[i].op) + gtk_widget_set_sensitive (mi, FALSE); + + md = g_new (MenuData, 1); + + md->window = window; + md->op = menuitems[i].op; + + gtk_signal_connect (GTK_OBJECT (mi), + "activate", + GTK_SIGNAL_FUNC (activate_cb), + md); + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), + mi); + + gtk_widget_show (mi); + } + ++i; + } + + gtk_signal_connect (GTK_OBJECT (menu), + "destroy", + GTK_SIGNAL_FUNC (gtk_widget_destroyed), + &menu); + + pt = g_new (GdkPoint, 1); + + g_object_set_data_full (G_OBJECT (menu), + "destroy-point", + pt, + g_free); + + pt->x = root_x; + pt->y = root_y; + + gtk_menu_popup (GTK_MENU (menu), + NULL, NULL, + popup_position_func, pt, + button, + timestamp); + + if (!GTK_MENU_SHELL (menu)->have_xgrab) + meta_ui_warning ("GtkMenu failed to grab the pointer\n"); +} + +void +meta_window_menu_hide (void) +{ + if (menu) + gtk_widget_destroy (menu); +} + +static void +activate_cb (GtkWidget *menuitem, gpointer data) +{ + MenuData *md; + + md = data; + + meta_ui_warning ("Activated menuitem\n"); + + gtk_widget_destroy (menu); + g_object_unref (G_OBJECT (md->window)); + g_free (md); +} diff --git a/src/menu.h b/src/menu.h new file mode 100644 index 000000000..8a667781c --- /dev/null +++ b/src/menu.h @@ -0,0 +1,39 @@ +/* Metacity window menu */ + +/* + * Copyright (C) 2001 Havoc Pennington + * + * This program 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 2 of the + * License, or (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_MENU_H +#define META_MENU_H + +#include +#include "messages.h" +void meta_window_menu_show (gulong xwindow, + int root_x, + int root_y, + int button, + MetaMessageWindowMenuOps ops, + MetaMessageWindowMenuOps insensitive, + guint32 timestamp); +void meta_window_menu_hide (void); + + + + +#endif diff --git a/src/screen.c b/src/screen.c index b79b44b29..1c262cd58 100644 --- a/src/screen.c +++ b/src/screen.c @@ -108,7 +108,11 @@ meta_screen_new (MetaDisplay *display, * so create that required workspace. */ screen->active_workspace = meta_workspace_new (screen); - /* FIXME, for debugging create another one. */ + /* FIXME, for now there are always 6 workspaces... */ + meta_workspace_new (screen); + meta_workspace_new (screen); + meta_workspace_new (screen); + meta_workspace_new (screen); meta_workspace_new (screen); meta_screen_init_visual_info (screen); diff --git a/src/screen.h b/src/screen.h index 93de5bc22..50647915e 100644 --- a/src/screen.h +++ b/src/screen.h @@ -71,12 +71,10 @@ void meta_screen_foreach_window (MetaScreen *scree MetaScreenWindowFunc func, gpointer data); void meta_screen_queue_frame_redraws (MetaScreen *screen); - void meta_screen_show_tip (MetaScreen *screen, int root_x, int root_y, const char *markup); - void meta_screen_hide_tip (MetaScreen *screen); #endif diff --git a/src/uislave.c b/src/uislave.c index 680bb1027..023b82599 100644 --- a/src/uislave.c +++ b/src/uislave.c @@ -20,6 +20,7 @@ */ #include "uislave.h" +#include "window.h" #include #include #include @@ -317,3 +318,42 @@ meta_ui_slave_hide_tip (MetaUISlave *uislave) send_message (uislave, (MetaMessage*)&hidetip); } + +void +meta_ui_slave_show_window_menu (MetaUISlave *uislave, + MetaWindow *window, + int root_x, + int root_y, + int button, + MetaMessageWindowMenuOps ops, + MetaMessageWindowMenuOps insensitive, + Time timestamp) +{ + MetaMessageShowWindowMenu showmenu; + + memset (&showmenu, 0, META_MESSAGE_LENGTH (MetaMessageShowWindowMenu)); + showmenu.header.message_code = MetaMessageShowWindowMenuCode; + showmenu.header.length = META_MESSAGE_LENGTH (MetaMessageShowWindowMenu); + + showmenu.window = window->xwindow; + showmenu.root_x = root_x; + showmenu.root_y = root_y; + showmenu.button = button; + showmenu.ops = ops; + showmenu.insensitive = insensitive; + showmenu.timestamp = timestamp; + + send_message (uislave, (MetaMessage*)&showmenu); +} + +void +meta_ui_slave_hide_window_menu (MetaUISlave *uislave) +{ + MetaMessageHideWindowMenu hidemenu; + + memset (&hidemenu, 0, META_MESSAGE_LENGTH (MetaMessageHideWindowMenu)); + hidemenu.header.message_code = MetaMessageHideWindowMenuCode; + hidemenu.header.length = META_MESSAGE_LENGTH (MetaMessageHideWindowMenu); + + send_message (uislave, (MetaMessage*)&hidemenu); +} diff --git a/src/uislave.h b/src/uislave.h index 673901b0f..c5852925c 100644 --- a/src/uislave.h +++ b/src/uislave.h @@ -64,4 +64,15 @@ void meta_ui_slave_show_tip (MetaUISlave *uislave, const char *markup_text); void meta_ui_slave_hide_tip (MetaUISlave *uislave); +void meta_ui_slave_show_window_menu (MetaUISlave *uislave, + MetaWindow *window, + int root_x, + int root_y, + int button, + MetaMessageWindowMenuOps ops, + MetaMessageWindowMenuOps insensitive, + Time timestamp); +void meta_ui_slave_hide_window_menu (MetaUISlave *uislave); + #endif + diff --git a/src/uislave/Makefile.am b/src/uislave/Makefile.am index b70f94635..1f93d1aab 100644 --- a/src/uislave/Makefile.am +++ b/src/uislave/Makefile.am @@ -5,6 +5,8 @@ metacity_uislave_SOURCES = \ fixedtip.h \ fixedtip.c \ main.c \ + menu.c \ + menu.h \ messages.c \ messages.h \ messagequeue.c \ diff --git a/src/uislave/main.c b/src/uislave/main.c index 284fbd214..f419f3402 100644 --- a/src/uislave/main.c +++ b/src/uislave/main.c @@ -23,6 +23,7 @@ #include "messagequeue.h" #include "fixedtip.h" #include "main.h" +#include "menu.h" #include #include @@ -67,6 +68,20 @@ message_callback (MetaMessageQueue *mq, case MetaMessageHideTipCode: meta_fixed_tip_hide (); break; + + case MetaMessageShowWindowMenuCode: + meta_window_menu_show (message->show_menu.window, + message->show_menu.root_x, + message->show_menu.root_y, + message->show_menu.button, + message->show_menu.ops, + message->show_menu.insensitive, + message->show_menu.timestamp); + break; + + case MetaMessageHideWindowMenuCode: + meta_window_menu_hide (); + break; default: meta_ui_warning ("Unhandled message code %d\n", @@ -88,6 +103,7 @@ meta_ui_warning (const char *format, ...) va_end (args); fputs (str, stderr); + fflush (stderr); /* though stderr is unbuffered right */ g_free (str); } diff --git a/src/uislave/main.h b/src/uislave/main.h index bc58d458d..1c21a253a 100644 --- a/src/uislave/main.h +++ b/src/uislave/main.h @@ -26,6 +26,7 @@ void meta_ui_warning (const char *format, ...); /* FIXME */ #define _(x) x +#define N_(x) x #endif diff --git a/src/uislave/menu.c b/src/uislave/menu.c new file mode 100644 index 000000000..292e99484 --- /dev/null +++ b/src/uislave/menu.c @@ -0,0 +1,190 @@ +/* Metacity window menu */ + +/* + * Copyright (C) 2001 Havoc Pennington + * + * This program 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 2 of the + * License, or (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "menu.h" +#include "main.h" +#include + +typedef struct _MenuItem MenuItem; +typedef struct _MenuData MenuData; + +struct _MenuItem +{ + MetaMessageWindowMenuOps op; + const char *stock_id; + const char *label; +}; + + +struct _MenuData +{ + GdkWindow *window; + MetaMessageWindowMenuOps op; +}; + +static void activate_cb (GtkWidget *menuitem, gpointer data); + +static GtkWidget *menu = NULL; +static MenuItem menuitems[] = { + { META_MESSAGE_MENU_DELETE, GTK_STOCK_CLOSE, N_("Close") }, + { META_MESSAGE_MENU_MINIMIZE, NULL, N_("Minimize") }, + { META_MESSAGE_MENU_MAXIMIZE, NULL, N_("Maximize") } +}; + +static void +popup_position_func (GtkMenu *menu, + gint *x, + gint *y, + gboolean *push_in, + gpointer user_data) +{ + GtkRequisition req; + GdkPoint *pos; + + pos = user_data; + + gtk_widget_size_request (GTK_WIDGET (menu), &req); + + *x = pos->x; + *y = pos->y; + + /* Ensure onscreen */ + *x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width)); + *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height)); +} + +void +meta_window_menu_show (gulong xwindow, + int root_x, int root_y, + int button, + MetaMessageWindowMenuOps ops, + MetaMessageWindowMenuOps insensitive, + guint32 timestamp) +{ + int i; + GdkWindow *window; + GdkPoint *pt; + + if (menu) + gtk_widget_destroy (menu); + + window = gdk_xid_table_lookup (xwindow); + if (window) + g_object_ref (G_OBJECT (window)); + else + window = gdk_window_foreign_new (xwindow); + + /* X error creating the foreign window means NULL here */ + if (window == NULL) + return; + + menu = gtk_menu_new (); + + i = 0; + while (i < G_N_ELEMENTS (menuitems)) + { + if (ops & menuitems[i].op) + { + GtkWidget *mi; + MenuData *md; + + if (menuitems[i].stock_id) + { + GtkWidget *image; + + mi = gtk_image_menu_item_new_with_label (menuitems[i].label); + image = gtk_image_new_from_stock (menuitems[i].stock_id, + GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), + image); + gtk_widget_show (image); + } + else + { + mi = gtk_menu_item_new_with_label (menuitems[i].label); + } + + if (insensitive & menuitems[i].op) + gtk_widget_set_sensitive (mi, FALSE); + + md = g_new (MenuData, 1); + + md->window = window; + md->op = menuitems[i].op; + + gtk_signal_connect (GTK_OBJECT (mi), + "activate", + GTK_SIGNAL_FUNC (activate_cb), + md); + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), + mi); + + gtk_widget_show (mi); + } + ++i; + } + + gtk_signal_connect (GTK_OBJECT (menu), + "destroy", + GTK_SIGNAL_FUNC (gtk_widget_destroyed), + &menu); + + pt = g_new (GdkPoint, 1); + + g_object_set_data_full (G_OBJECT (menu), + "destroy-point", + pt, + g_free); + + pt->x = root_x; + pt->y = root_y; + + gtk_menu_popup (GTK_MENU (menu), + NULL, NULL, + popup_position_func, pt, + button, + timestamp); + + if (!GTK_MENU_SHELL (menu)->have_xgrab) + meta_ui_warning ("GtkMenu failed to grab the pointer\n"); +} + +void +meta_window_menu_hide (void) +{ + if (menu) + gtk_widget_destroy (menu); +} + +static void +activate_cb (GtkWidget *menuitem, gpointer data) +{ + MenuData *md; + + md = data; + + meta_ui_warning ("Activated menuitem\n"); + + gtk_widget_destroy (menu); + g_object_unref (G_OBJECT (md->window)); + g_free (md); +} diff --git a/src/uislave/menu.h b/src/uislave/menu.h new file mode 100644 index 000000000..8a667781c --- /dev/null +++ b/src/uislave/menu.h @@ -0,0 +1,39 @@ +/* Metacity window menu */ + +/* + * Copyright (C) 2001 Havoc Pennington + * + * This program 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 2 of the + * License, or (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_MENU_H +#define META_MENU_H + +#include +#include "messages.h" +void meta_window_menu_show (gulong xwindow, + int root_x, + int root_y, + int button, + MetaMessageWindowMenuOps ops, + MetaMessageWindowMenuOps insensitive, + guint32 timestamp); +void meta_window_menu_hide (void); + + + + +#endif diff --git a/src/uislave/messages.h b/src/uislave/messages.h index c4fadd21e..4e083042c 100644 --- a/src/uislave/messages.h +++ b/src/uislave/messages.h @@ -60,12 +60,14 @@ #define META_MESSAGE_MAX_HOST_ALIAS_LEN 50 #define META_MESSAGE_MAX_TIP_LEN 128 -typedef union _MetaMessage MetaMessage; -typedef struct _MetaMessageHeader MetaMessageHeader; -typedef struct _MetaMessageFooter MetaMessageFooter; -typedef struct _MetaMessageCheck MetaMessageCheck; -typedef struct _MetaMessageShowTip MetaMessageShowTip; -typedef struct _MetaMessageHideTip MetaMessageHideTip; +typedef union _MetaMessage MetaMessage; +typedef struct _MetaMessageHeader MetaMessageHeader; +typedef struct _MetaMessageFooter MetaMessageFooter; +typedef struct _MetaMessageCheck MetaMessageCheck; +typedef struct _MetaMessageShowTip MetaMessageShowTip; +typedef struct _MetaMessageHideTip MetaMessageHideTip; +typedef struct _MetaMessageShowWindowMenu MetaMessageShowWindowMenu; +typedef struct _MetaMessageHideWindowMenu MetaMessageHideWindowMenu; typedef enum { @@ -75,7 +77,9 @@ typedef enum MetaMessageNullCode, MetaMessageCheckCode, MetaMessageShowTipCode, - MetaMessageHideTipCode + MetaMessageHideTipCode, + MetaMessageShowWindowMenuCode, + MetaMessageHideWindowMenuCode } MetaMessageCode; struct _MetaMessageHeader @@ -124,12 +128,42 @@ struct _MetaMessageHideTip MetaMessageFooter footer; }; +typedef enum +{ + META_MESSAGE_MENU_DELETE = 1 << 0, + META_MESSAGE_MENU_MINIMIZE = 1 << 1, + META_MESSAGE_MENU_MAXIMIZE = 1 << 2, + META_MESSAGE_MENU_ALL = META_MESSAGE_MENU_DELETE | META_MESSAGE_MENU_MINIMIZE | META_MESSAGE_MENU_MAXIMIZE +} MetaMessageWindowMenuOps; + +struct _MetaMessageShowWindowMenu +{ + MetaMessageHeader header; + MetaMessageWindowMenuOps ops; + MetaMessageWindowMenuOps insensitive; + gulong window; + int root_x; + int root_y; + guint32 timestamp; + int button; + MetaMessageFooter footer; +}; + +struct _MetaMessageHideWindowMenu +{ + MetaMessageHeader header; + + MetaMessageFooter footer; +}; + union _MetaMessage { MetaMessageHeader header; MetaMessageCheck check; MetaMessageShowTip show_tip; MetaMessageShowTip hide_tip; + MetaMessageShowWindowMenu show_menu; + MetaMessageHideWindowMenu hide_menu; }; /* Slave-side message send/read code */