/********************************************************************************************
Clean OS Windows library module version 1.2.1.
This module is part of the Clean Object I/O library, version 1.2.1,
for the Windows platform.
********************************************************************************************/
/********************************************************************************************
About this module:
Routines related to menu handling.
********************************************************************************************/
#include "cCrossCallMenus_121.h"
#include "cCrossCall_121.h"
/* Cross call procedure implementations.
Eval<nr> corresponds with a CrossCallEntry generated by NewCrossCallEntry (nr,Eval<nr>).
*/
/* Remove a shortkey from a framewindow shortkey table. */
static gboolean dummy_find_accel(GtkAccelKey *key, GClosure *closure, gpointer data)
{
printf("dummy_find_accel\n");
return gtk_true();
}
void EvalCcRqREMOVEMENUSHORTKEY (CrossCallInfo *pcci) /* frameptr, cmd; no result. */
{
GtkWidget *frame;
GtkWidget *box;
GtkWidget *menu_item;
GtkAccelGroup *accel_group;
printf("EvalCcRqREMOVEMENUSHORTKEY\n");
frame = GTK_WIDGET(pcci->p1);
menu_item = GTK_WIDGET(pcci->p2);
accel_group = ((GtkAccelGroup*)gtk_accel_groups_from_object(G_OBJECT(frame))->data);
for (;;)
{
GtkAccelKey *key = gtk_accel_group_find(accel_group, dummy_find_accel, NULL);
if (!key) break;
gtk_widget_remove_accelerator(menu_item,
accel_group,
key->accel_key,
key->accel_mods);
}
MakeReturn0Cci (pcci);
}
void EvalCcRqMODIFYMENUITEM (CrossCallInfo *pcci) /* hitem, hmenu, textptr; no result. */
{
GtkWidget *menu, *menu_item, *label;
gchar *title;
printf("EvalCcRqMODIFYMENUITEM\n");
title = createMnemonicString((gchar *) pcci->p3);
menu = GTK_WIDGET(pcci->p2);
menu_item = GTK_WIDGET(pcci->p1);
label = gtk_bin_get_child(GTK_BIN(menu_item));
gtk_label_set_text_with_mnemonic(GTK_LABEL(label), title);
rfree(title);
MakeReturn0Cci (pcci);
}
static int in_handler_flag = 0;
static void menuitem_activate_handler(GtkMenuItem *menu_item)
{
printf("menuitem_activate_handler\n");
if (in_handler_flag == 0)
{
in_handler_flag = 1;
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), !(GTK_CHECK_MENU_ITEM(menu_item)->active));
SendMessage2ToClean (CcWmCOMMAND, GTK_WIDGET(menu_item), GetModifiers ());
in_handler_flag = 0;
}
}
void EvalCcRqINSERTMENUITEM (CrossCallInfo *pcci)
{
gchar *title;
GtkWidget *menu, *menu_item, *label;
GtkAccelGroup *accel_group;
guint graystate, checkstate;
printf("EvalCcRqINSERTMENUITEM\n");
printf("Inserting item with position %d and name %s\n", pcci->p5, (char*)pcci->p3);
printf("Checking graystate: ");
if (pcci->p1)
{
graystate = 1; // MF_ENABLED
} else {
graystate = 0; // MF_GRAYED;
}
printf("%s\n", (graystate ? "enabled" : "grayed"));
printf("Checking checkstate: ");
if (pcci->p4)
{
checkstate = 1; // MF_CHECKED
} else {
checkstate = 0; // MF_UNCHECKED
}
printf("%s\n", (checkstate ? "checked" : "unchecked"));
printf("Calling Make Mnemonic string with: %s\n", (gchar*)pcci->p3);
title = createMnemonicString((gchar *) pcci->p3);
printf("Got title: %s\n", title);
menu = GTK_WIDGET(pcci->p2);
printf("Menu widget: %s\n", gtk_menu_get_title(GTK_MENU(menu)));
printf("Creating new menu item\n");
menu_item = gtk_menu_item_new_with_mnemonic(title);
gtk_menu_shell_insert( GTK_MENU_SHELL (menu), menu_item, (gint) pcci->p5);
//gtk_accel_label_set_accel_widget(GTK_ACCEL_LABEL(label), menu_item);
//gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), ((pcci->p1 & 1) != 0));
//gtk_widget_set_sensitive(menu_item, ((pcci->p1 & 2) != 0));
gtk_signal_connect_object (GTK_OBJECT (menu_item), "activate",
GTK_SIGNAL_FUNC (menuitem_activate_handler), menu_item);
gtk_widget_show(menu_item);
printf("About to free title: %s\n", title);
rfree(title);
printf("Freed title\n");
/* if (key != 0)
{
printf("Creating accellerators\n");
accel_group = ((GtkAccelGroup *) gtk_accel_groups_from_object (G_OBJECT(frame))->data);
gtk_widget_add_accelerator(menu_item, "activate",
accel_group,
key,
GDK_CONTROL_MASK,
GTK_ACCEL_VISIBLE);
gtk_widget_add_accelerator(menu_item, "activate",
accel_group,
key,
GDK_CONTROL_MASK | GDK_SHIFT_MASK,
0);
gtk_widget_add_accelerator(menu_item, "activate",
accel_group,
key,
GDK_CONTROL_MASK | GDK_MOD1_MASK,
0);
gtk_widget_add_accelerator(menu_item, "activate",
accel_group,
key,
GDK_CONTROL_MASK | GDK_MOD1_MASK | GDK_SHIFT_MASK,
0);
}
*/
printf("Creating return Cci\n");
MakeReturn1Cci (pcci, (int64_t) menu_item);
}
/* Cross call procedure implementations.
Eval<nr> corresponds with a CrossCallEntry generated by NewCrossCallEntry (nr,Eval<nr>).
*/
/* Add a shortkey to a framewindow shortkey table. */
void EvalCcRqADDMENUSHORTKEY (CrossCallInfo *pcci) /* frameptr, cmd, key; no result. */
{
/* ProcessShortcutTable table;
HWND frameptr;
int cmd, key;
frameptr = (HWND) pcci->p1;
cmd = pcci->p2;
key = pcci->p3;
table = (ProcessShortcutTable) GetWindowLong (frameptr,0);
table = AddProcessShortcut (key, cmd, table);
SetWindowLong (frameptr, 0, (long)table);
if (gAcceleratorTableIsUpToDate)
gAcceleratorTableIsUpToDate = !(ghActiveFrameWindow==frameptr);
}
*/
printf("EvalCcRqADDMENUSHORTKEY\n");
MakeReturn0Cci (pcci);
}
static void find_item_callback(GtkWidget *menu_item, gpointer data)
{
printf("find_item_callback\n");
if (GTK_IS_MENU_ITEM(menu_item) && GTK_MENU_ITEM (menu_item)->submenu == ((GtkWidget *) data))
*((GtkWidget **) data) = menu_item;
}
void EvalCcRqITEMENABLE (CrossCallInfo *pcci) /* parent, HITEM, onoff; no result. */
{
GtkWidget *menu, *menu_item;
printf("EvalCcRqITEMENABLE\n");
menu = GTK_WIDGET(pcci->p1);
menu_item = GTK_WIDGET(pcci->p2);
printf("Menu widget: %s\n", gtk_menu_get_title((GtkMenu*)menu));
printf("EvalCcRqITEMENABLE\n");
gtk_widget_set_sensitive(menu_item, (gboolean) pcci->p3);
MakeReturn0Cci (pcci);
}
/* Destroy a menu 'physically' */
void EvalCcRqDESTROYMENU (CrossCallInfo *pcci) /* HMENU; no result. */
{
printf("EvalCcRqDESTROYMENU\n");
/*
* This is handled behind-the-scenes by GTK
*/
MakeReturn0Cci (pcci);
}
/* Remove a menu logically */
void EvalCcRqDELETEMENU (CrossCallInfo *pcci) /* HMENU, HITEM; no result. */
{
GtkWidget *menu, *menu_item;
printf("EvalCcRqDELETEMENU\n");
menu = GTK_WIDGET(pcci->p1);
menu_item = GTK_WIDGET(pcci->p2);
gtk_container_foreach(GTK_CONTAINER(menu), find_item_callback, (gpointer) &menu_item);
if (menu_item != GTK_WIDGET(pcci->p2))
{
gtk_menu_item_remove_submenu(GTK_MENU_ITEM(menu_item));
gtk_widget_destroy(menu_item);
}
MakeReturn0Cci (pcci);
}
void EvalCcRqREMOVEMENUITEM (CrossCallInfo *pcci) /* menu, HITEM; no result. */
{
GtkWidget *menu, *menu_item;
printf("EvalCcRqREMOVEMENUITEM\n");
menu = GTK_WIDGET(pcci->p1);
menu_item = GTK_WIDGET(pcci->p2);
gtk_menu_item_remove_submenu(GTK_MENU_ITEM(menu_item));
gtk_widget_destroy(menu_item);
MakeReturn0Cci (pcci);
}
void EvalCcRqINSERTSEPARATOR (CrossCallInfo *pcci) /* hmenu, pos no result. */
{
GtkWidget *menu, *menu_item;
printf("EvalCcRqINSERTSEPARATOR\n");
menu = GTK_WIDGET(pcci->p1);
menu_item = gtk_menu_item_new();
gtk_menu_insert(GTK_MENU(menu), menu_item, (gint) pcci->p2);
gtk_widget_show_all(menu_item);
MakeReturn1Cci (pcci, (int64_t) menu_item);
}
void EvalCcRqMODIFYMENU (CrossCallInfo *pcci) /* hitem, hmenu, textptr; no result. */
{
gint i;
GtkWidget *menu, *menu_item, *label;
gchar *title;
printf("EvalCcRqMODIFYMENU\n");
title = createMnemonicString((gchar *) pcci->p3);
menu = GTK_WIDGET(pcci->p2);
menu_item = GTK_WIDGET(pcci->p1);
label = gtk_bin_get_child(GTK_BIN(menu_item));
gtk_label_set_text_with_mnemonic(GTK_LABEL(label), title);
rfree(title);
MakeReturn0Cci (pcci);
}
/* Insert a menu into the menu bar. */
void EvalCcRqINSERTMENU (CrossCallInfo *pcci)
{
gint i;
gchar *title;
GtkWidget *parent_menu, *root_menu, *sub_menu;
GtkAccelGroup *accel_group;
printf("EvalCcRqINSERTMENU\n");
title = createMnemonicString((gchar *) pcci->p3);
parent_menu = GTK_WIDGET(pcci->p2);
sub_menu = GTK_WIDGET(pcci->p4);
if (GTK_IS_MENU_BAR(parent_menu))
{
printf("Adding to a menu bar.\n");
printf("Menu Bar Name: %s\n", gtk_menu_get_title((GtkMenu*)parent_menu));
GtkWidget *frame = gtk_widget_get_parent(gtk_widget_get_parent(parent_menu));
accel_group = ((GtkAccelGroup*)gtk_accel_groups_from_object (G_OBJECT(frame))->data);
}
else
{
printf("We're not adding to a menu bar!?!\n");
printf("Parent Menu widget: %s\n", gtk_menu_get_title((GtkMenu*)parent_menu));
accel_group = gtk_menu_get_accel_group (GTK_MENU(parent_menu));
}
gtk_menu_set_accel_group (GTK_MENU(sub_menu), accel_group);
root_menu = gtk_menu_item_new_with_mnemonic(title);
gtk_widget_set_sensitive(root_menu, (gboolean) pcci->p1);
gtk_widget_show_all (root_menu);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (root_menu), sub_menu);
printf("Inserting menu called %s at position %d (%s)\n",
gtk_menu_get_title(GTK_MENU(root_menu)), (gint) pcci->p5, title);
if (GTK_IS_MENU_BAR(parent_menu))
{
gtk_menu_shell_insert(GTK_MENU_SHELL(parent_menu), root_menu, (gint) pcci->p5);
} else {
gtk_menu_insert(GTK_MENU(parent_menu), root_menu, (gint) pcci->p5);
}
rfree(title);
printf("New menu is called: %s\n", gtk_menu_get_title((GtkMenu*)root_menu));
MakeReturn1Cci (pcci, (int64_t) sub_menu);
}
static void enable_menu_callback(GtkWidget *menu_item, gpointer data)
{
printf("enable_menu_callback\n");
gint *val = (gint*) data;
printf("Checking: %d\n", *val);
if (GTK_IS_MENU_ITEM(menu_item)
&& (*val == 0))
{
gtk_widget_set_sensitive(menu_item, gtk_true());
}
else
{
*val = *val - 1;
}
}
static void disable_menu_callback(GtkWidget *menu_item, gpointer data)
{
printf("disable_menu_callback\n");
gint *val = (gint*) data;
printf("Checking: %d\n", *val);
if (GTK_IS_MENU_ITEM(menu_item)
&& (*val == 0))
{
gtk_widget_set_sensitive(menu_item, gtk_false());
}
else
{
*val = *val - 1;
}
}
void EvalCcRqMENUENABLE (CrossCallInfo *pcci) /* parent, zero based position of menu, onoff; no result. */
{
GtkWidget *parent_menu, *sub_menu;
printf("EvalCcRqMENUENABLE\n");
gint index = pcci->p2;
if (pcci->p1 && GTK_IS_CONTAINER(pcci->p1))
{
printf("We have a container. Checking the widget.\n");
parent_menu = GTK_WIDGET(pcci->p1);
printf("Parent Menu widget: %s\n",
gtk_menu_get_title(GTK_MENU(parent_menu)));
gtk_container_foreach(GTK_CONTAINER(parent_menu), pcci->p3 ?
enable_menu_callback : disable_menu_callback,
(gpointer) (&index));
}
MakeReturn0Cci (pcci);
}
void EvalCcRqDRAWMBAR (CrossCallInfo *pcci) /* framePtr, clientPtr; no result. */
{
printf("EvalCcRqDRAWMBAR\n");
MakeReturn0Cci (pcci);
}
/* Track pop up menu. */
void EvalCcRqTRACKPOPMENU (CrossCallInfo *pcci) /* popupmenu,framePtr; BOOL result. */
{
printf("EvalCcRqTRACKPOPMENU\n");
if (GTK_IS_MENU(pcci->p1))
{
GtkWidget *popup_menu = GTK_WIDGET(pcci->p1);
GtkWidget *frame = GTK_WIDGET(pcci->p2);
GdkEvent *event = gtk_get_current_event();
gtk_menu_popup(GTK_MENU(popup_menu),NULL,NULL,NULL,NULL,
(event->type == GDK_BUTTON_PRESS) ?
((GdkEventButton *) event)->button : 0,
gdk_event_get_time(event));
}
MakeReturn1Cci (pcci,(int64_t)gtk_true());
}
void EvalCcRqCREATEPOPMENU (CrossCallInfo *pcci) /* no params; MENU result. */
{
/*
* Establish a new meta-menu that will be used to hold the individual
* menu entries later.
*
* This menu should be added to a menu bar.
*/
printf("EvalCcRqCREATEPOPMENU\n");
MakeReturn1Cci (pcci, (int64_t) gtk_menu_new());
}
void EvalCcRqCHECKMENUITEM (CrossCallInfo *pcci) /* menu, HITEM, on/off; no result. */
{
printf("EvalCcRqCHECKMENUITEM\n");
if (GTK_IS_MENU(pcci->p1))
{
GtkWidget *menu = GTK_WIDGET(pcci->p1);
GtkWidget *menu_item = GTK_WIDGET(pcci->p2);
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item),
(gboolean) pcci->p3);
}
MakeReturn0Cci (pcci);
}
/* Install the cross call procedures in the gCrossCallProcedureTable of cCrossCall_121.
*/
OS InstallCrossCallMenus (OS ios)
{
CrossCallProcedureTable newTable;
printf("InstallCrossCallMenus\n");
newTable = EmptyCrossCallProcedureTable ();
AddCrossCallEntry (newTable, CcRqADDMENUSHORTKEY, EvalCcRqADDMENUSHORTKEY);
AddCrossCallEntry (newTable, CcRqREMOVEMENUSHORTKEY, EvalCcRqREMOVEMENUSHORTKEY);
AddCrossCallEntry (newTable, CcRqMODIFYMENUITEM, EvalCcRqMODIFYMENUITEM);
AddCrossCallEntry (newTable, CcRqINSERTMENUITEM, EvalCcRqINSERTMENUITEM);
AddCrossCallEntry (newTable, CcRqITEMENABLE, EvalCcRqITEMENABLE);
AddCrossCallEntry (newTable, CcRqDELETEMENU, EvalCcRqDELETEMENU);
AddCrossCallEntry (newTable, CcRqDESTROYMENU, EvalCcRqDESTROYMENU);
AddCrossCallEntry (newTable, CcRqREMOVEMENUITEM, EvalCcRqREMOVEMENUITEM);
AddCrossCallEntry (newTable, CcRqINSERTSEPARATOR, EvalCcRqINSERTSEPARATOR);
AddCrossCallEntry (newTable, CcRqMODIFYMENU, EvalCcRqMODIFYMENU);
AddCrossCallEntry (newTable, CcRqINSERTMENU, EvalCcRqINSERTMENU);
AddCrossCallEntry (newTable, CcRqMENUENABLE, EvalCcRqMENUENABLE);
AddCrossCallEntry (newTable, CcRqDRAWMBAR, EvalCcRqDRAWMBAR);
AddCrossCallEntry (newTable, CcRqTRACKPOPMENU, EvalCcRqTRACKPOPMENU);
AddCrossCallEntry (newTable, CcRqCREATEPOPMENU, EvalCcRqCREATEPOPMENU);
AddCrossCallEntry (newTable, CcRqCHECKMENUITEM, EvalCcRqCHECKMENUITEM);
AddCrossCallEntries (gCrossCallProcedureTable, newTable);
return ios;
}