/******************************************************************************************** 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 corresponds with a CrossCallEntry generated by NewCrossCallEntry (nr,Eval). */ /* 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 corresponds with a CrossCallEntry generated by NewCrossCallEntry (nr,Eval). */ /* 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; }