/*
*
* ProLinga-Run
*
* Copyright (C) 2002-2009 Xobas Software.
* All rights reserved.
*
* This file is part of ProLinga-Run.
*
* ProLinga-Run 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.
*
* ProLinga-Run 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 ProLinga-Run. If not, see .
*
* More information is available at the following addresses:
*
* Website : http://www.prolinga.org
*
* Email : prolinga-list@prolinga.org
*
*
*/
#include "RunCommon.h"
#include
#include
#include
#include
#include
#include
#include "RunShare.hpp"
#include "RepositoryCommand.hpp"
#include "LogicCommands.hpp"
#include "DataRef.hpp"
#include "ScreenRef.hpp"
#include "Screen.hpp"
#include "Limits.hpp"
#include "CmdList.hpp"
extern GtkWidget *activeScreen;
extern pthread_t mainThreadId;
extern BiAppnPtr biAppnPtr;
/* Global variable (V-) */
extern VariablePtr varPtr;
/* VariableGroup (G-) */
extern VariableGroupPtr vgrpPtr;
/* Table.Record (F-) */
extern TablePtr tablePtr;
/* Pick List (P-) */
extern PickListPtr pickPtr;
/* List Store */
extern ListStorePtr listStorePtr;
/* Screens open on Desktop Ptr */
extern DesktopScreenPtr desktopScreenPtr;
/* Active Screen Dialog stack Ptr */
extern ScreenStackPtr dialogStackPtr;
extern BiQuitLastScreenPtr biQuitLastScreenPtr;
extern "C" gboolean X_HANDLER_DREF_X (GtkObject *object, gpointer user_data, int callBack);
struct widget_handler
{
char screenId[80];
char widgetType[80];
char widgetName[80];
char signalName[80];
char signalHandler[80];
};
struct screen_wdgPtr
{
char screenName[32];
GtkWidget *screenWdg;
};
struct idle_command_event
{
GtkObject *object;
char *signalData;
char *screen;
bool isMainThread;
};
gboolean ExecuteDrefEvent(GtkObject *object, char *signalData, bool isMainThread)
{
const gchar *screenObject;
const gchar *dataRef;
char dataGetPut;
char retValue[255], *retBigValue = NULL;
int i, listCount, columns, sortCol;
GtkListStore *storePtr;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
GtkTreeSelection *select;
//printf("This is object : %s\n", glade_get_widget_name(GTK_WIDGET(object)));
screenObject = G_OBJECT_TYPE_NAME(G_OBJECT(object));
//printf("Screen Object is : %s\n", screenObject);
/* Execute Command */
if (signalData == NULL)
return FALSE;
if ((signalData[0] != 'D') && (signalData[0] != 'P') && (signalData[0] != 'I'))
return FALSE;
/* PickList Rebuild/Refresh List (GtkComboBox, GtkComboBoxEntry) */
if (signalData[0] == 'P')
{
//dataGetPut = 'P';
/* Get DataRef */
dataRef = signalData+2;
if ( (strcmp(screenObject, "GtkComboBox")==0) || (strcmp(screenObject, "GtkComboBoxEntry")==0))
{
/* get GTK thread lock */
if (isMainThread == false)
gdk_threads_enter();
/* Unset active selection if applicable */
if (strcmp(screenObject, "GtkComboBox")==0)
gtk_combo_box_set_active(GTK_COMBO_BOX(object), -1);
listCount = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(gtk_combo_box_get_model(GTK_COMBO_BOX(object))), NULL);
/* Remove existing values */
for (i=(listCount-1); i>=0; i--)
gtk_combo_box_remove_text(GTK_COMBO_BOX(object),i);
/* Get number of pick list entries */
listCount = pickPtr->tableCount(&pickPtr, dataRef);
/* Add new values */
for (i=1; i<=listCount; i++)
gtk_combo_box_append_text(GTK_COMBO_BOX(object), pickPtr->getValueEntryPtr(&pickPtr, dataRef, i));
/* release GTK thread lock */
if (isMainThread == false)
{
/* Sync with X server */
gdk_flush();
/* release GTK thread lock */
gdk_threads_leave();
}
/* Return */
return FALSE;
}
else if (strcmp(screenObject, "GtkToggleButton") == 0)
{
/* get GTK thread lock */
if (isMainThread == false)
gdk_threads_enter();
/* Get number of pick list entries */
listCount = pickPtr->tableCount(&pickPtr, dataRef);
if ((gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(object)) == TRUE) && (listCount > 0))
gtk_button_set_label(GTK_BUTTON(object), pickPtr->getValueEntryPtr(&pickPtr, dataRef, 1));
else if ((gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(object)) == FALSE) && (listCount > 1))
gtk_button_set_label(GTK_BUTTON(object), pickPtr->getValueEntryPtr(&pickPtr, dataRef, 2));
else
gtk_button_set_label(GTK_BUTTON(object), "");
if (isMainThread == false)
{
/* Sync with X server */
gdk_flush();
/* release GTK thread lock */
gdk_threads_leave();
}
/* Return */
return FALSE;
}
else
/* Return */
return FALSE;
}
else if (signalData[0] == 'I')
{
dataGetPut = 'I';
/* Get DataRef */
dataRef = signalData+2;
}
else
{
if (signalData[2] == 'G')
dataGetPut = 'G';
else if (signalData[2] == 'P')
dataGetPut = 'P';
else
{
printf("ERROR -- UNKNOWN DATA MOVE\n");
printf("%s\n", signalData);
return FALSE;
}
/* Get DataRef */
dataRef = signalData+6;
}
/* Data move depending on screen object */
if ( (strcmp(screenObject, "GtkTreeView")==0) && (dataGetPut =='I'))
{
/* List Store / View */
/* Expand name */
getDataRef((char *)dataRef, isMainThread, retValue, false);
// printf("!!!%sQQQQ\n", retValue);
/* Get Store */
storePtr = listStorePtr->getStore(&listStorePtr, retValue, isMainThread);
/* Get Columns */
columns = listStorePtr->getNumberColumns(listStorePtr, retValue);
/* Get Sort Column (if set) */
sortCol = listStorePtr->getSortColumn(listStorePtr, retValue);
/* get GTK thread lock */
if (isMainThread == false)
gdk_threads_enter();
/* Link Store to view */
gtk_tree_view_set_model(GTK_TREE_VIEW(object), GTK_TREE_MODEL(storePtr));
/* Clear the view */
for (;;)
{
column = gtk_tree_view_get_column(GTK_TREE_VIEW(object), 0);
if (column == NULL)
break;
gtk_tree_view_remove_column(GTK_TREE_VIEW(object), column);
}
renderer = gtk_cell_renderer_text_new();
/* Get and present Column Data */
for (i = 1; i <= columns; i++)
{
column = gtk_tree_view_column_new_with_attributes(listStorePtr->getHeaderValue(listStorePtr, retValue, i),renderer, "text",(i-1),NULL);
if (sortCol > 0)
gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column), (i-1));
gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN (column), TRUE);
gtk_tree_view_append_column (GTK_TREE_VIEW(object), column);
}
/* Set sort order default column */
if (sortCol > 0)
{
if (listStorePtr->getSortDirection(listStorePtr, retValue) == LIST_SORTING_DESCENDING)
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(storePtr), (sortCol-1), GTK_SORT_DESCENDING);
else
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(storePtr), (sortCol-1), GTK_SORT_ASCENDING);
}
/* Set up selection handler */
select = gtk_tree_view_get_selection (GTK_TREE_VIEW (object));
gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
g_signal_connect (G_OBJECT (select), "changed", \
G_CALLBACK (tree_selection_changed_cb), \
NULL);
/* release GTK thread lock */
if (isMainThread == false)
{
/* Sync with X server */
gdk_flush();
/* release GTK thread lock */
gdk_threads_leave();
}
}
else
{
if (dataGetPut == 'G')
{
retBigValue = getDataRef((char *)dataRef, isMainThread, retBigValue, true);
//getDataRef((char *)dataRef, isMainThread, retBigValue, false);
if (retBigValue == NULL)
{
retBigValue = new char[2];
strcpy(retBigValue, "");
}
putWidgetValue(GTK_WIDGET(object), retBigValue, isMainThread);
delete retBigValue;
}
else if (dataGetPut == 'P')
{
retBigValue = getWidgetValue(GTK_WIDGET(object), isMainThread, retBigValue, true);
if (retBigValue != NULL)
{
putDataRef((char *)dataRef, (char *)retBigValue, 0, isMainThread);
delete retBigValue;
}
}
}
/* Return */
return FALSE;
}
extern "C" gboolean X_HANDLER_DREF_X (GtkObject *object, gpointer user_data, int callBack)
{
GSignalInvocationHint *ihint;
gchar signalName[255];
int i;
char sigKey[255];
char *signalData;
gboolean retStatus;
bool isMainThread;
/* Determine if call comes from main thread */
if (pthread_equal(mainThreadId, pthread_self()) == 0)
isMainThread = false;
else
isMainThread = true;
/* Determine if user event or application event */
if ( callBack == -1)
{
strcpy(signalName, (gchar *)"focus-in-event");
}
else
{
ihint = g_signal_get_invocation_hint(object);
strcpy(signalName,g_signal_name(ihint->signal_id));
}
//printf("Signal: %s Callback %d\n", signalName, callBack);
/* Replace "-" with "_" in event name */
ReplaceCharInString((char *)signalName, '-', '_');
/* Determine number of callbacks */
i = 1;
for (;;)
{
sprintf(sigKey,"%s_%d", signalName, i);
signalData = (char *)g_object_get_data(G_OBJECT(object), sigKey);
/*DISPLAY ALL triggers map_event for ever object */
if ((signalData == NULL) && (i == 1))
return FALSE;
/* Break if no more */
if (signalData == NULL)
break;
/* When refresh, map_event move only */
if ((callBack == -1) && (strcmp(signalName, "focus_in_event") != 0))
continue;
/* DEBUG */
//printf("DREF SIGNAL : %s_%d\n", signalName, i);
/* Execute Command */
retStatus = ExecuteDrefEvent(object, signalData, isMainThread);
/* Raise Counter */
i++;
}
/* Return */
return FALSE;
}
gboolean ExecuteCommandEvent(GtkObject *object, char *signalData, char *screen, bool isMainThread, bool idleEvent)
{
const char *actionCommand[255];
char actionPrefix;
/* Get action prefix */
actionPrefix = signalData[0];
actionCommand[1] = signalData+2;
if (actionPrefix == 'C')
{
CmdControl(actionCommand, 1, isMainThread, activeScreen);
}
else if (actionPrefix == 'S')
{
CmdScreen(actionCommand, 1, isMainThread, activeScreen);
}
else if (actionPrefix == 'L')
{
CmdCall(actionCommand,1, isMainThread, idleEvent);
}
else if (actionPrefix == 'X')
{
/* Special Hidden Internal Settings */
if (strcmp(actionCommand[1], "SetActiveScreen") == 0)
{
//printf("FOCUS BEFORE %s!!!!!!\n", screen);
activeScreen = LookupWidget(GTK_WIDGET(object), screen);
}
}
return FALSE;
}
gboolean IdleExecuteCommandEvent(gpointer data)
{
struct idle_command_event *ce;
/* Cast struct */
ce = (struct idle_command_event *)data;
/* Execute function */
ExecuteCommandEvent(ce->object, ce->signalData, ce->screen, ce->isMainThread, true);
/* Clean up */
delete ce;
/* Return */
return FALSE;
}
extern "C" gboolean X_HANDLER_ACTION_X (GtkObject *object, GdkEventButton *event, gpointer user_data, int callBack)
{
char *screen, *signalData;
char sigKey[80];
int i;
GtkWidget *tmpScreen = NULL;
GSignalInvocationHint *ihint;
gchar signalName[255];
gboolean retStatus;
bool isMainThread;
struct idle_command_event *ce;
/* Determine if call comes from main thread */
if (pthread_equal(mainThreadId, pthread_self()) == 0)
isMainThread = false;
else
isMainThread = true;
/* Determine if user event or application event */
if ( callBack == -1)
{
strcpy(signalName, (gchar *)"realize");
}
else
{
ihint = g_signal_get_invocation_hint(object);
strcpy(signalName,g_signal_name(ihint->signal_id));
}
//printf("signal %s - %d\n", signalName, callBack);
/* Replace "-" with "_" in event name */
ReplaceCharInString((char *)signalName, '-', '_');
/* Event button_press hard coded as double click for the time being */
/* Introduce Comm Area *BUTTONCLICK or smth similar */
if (strcmp(signalName, "button_press_event") == 0)
{
if (event->type!=GDK_2BUTTON_PRESS)
return FALSE;
}
//printf("Event is : %s\n", signalName);
// printf("This is object : %s\n", glade_get_widget_name(GTK_WIDGET(object)));
screen = (char *)g_object_get_data(G_OBJECT(object), "screenId");
// printf("Screen is : %s\n", screen);
/* FIXME: Review */
/* Container screens on multiple instance screens will generate warning */
tmpScreen = desktopScreenPtr->getOneValue(&desktopScreenPtr, screen);
if ((tmpScreen != NULL) && (desktopScreenPtr->isOnDesktop(desktopScreenPtr, screen) <= 1))
activeScreen = tmpScreen;
else
{
tmpScreen = LookupWidget(GTK_WIDGET(object), screen);
if (tmpScreen != NULL)
activeScreen = tmpScreen;
}
/* Determine number of callbacks */
i = 1;
for (;;)
{
sprintf(sigKey,"%s_%d", signalName, i);
signalData = (char *)g_object_get_data(G_OBJECT(object), sigKey);
/* new screen triggers realize event for screen */
if ((signalData == NULL) && (i == 1))
return FALSE;
/* Break if no more */
if (signalData == NULL)
break;
/* When realize, realize event only */
if ((callBack == -1) && (strcmp(signalName, "realize") != 0))
continue;
/* Execute Command */
if (strcmp(signalName, "focus_out_event") == 0)
{
/* Workaround GTK+ limitation */
/* gtk_run_dialog can not be called from
non-idle function */
ce = new idle_command_event;
ce->object = object;
ce->signalData = signalData;
ce->screen = screen;
ce->isMainThread = isMainThread;
g_idle_add(IdleExecuteCommandEvent, ce);
}
else
retStatus = ExecuteCommandEvent(object, signalData, screen, isMainThread, false);
/* Raise Counter */
i++;
}
/* Return */
return FALSE;
}
void DisplayRefresh(GtkObject *object)
{
X_HANDLER_DREF_X(object, NULL, -1);
}
void DisplayRealize(GtkObject *object)
{
X_HANDLER_ACTION_X(object, NULL, NULL, -1);
}
bool IsDialogScreen(xmlDocPtr docRes)
{
xmlXPathContextPtr ctxt;
xmlXPathObjectPtr res;
/* Init XPath */
xmlXPathInit();
/* Create XPath environment */
ctxt = xmlXPathNewContext(docRes);
/* Find out if screen is modal */
res = xmlXPathEval((const xmlChar *)"/ProLinga/Repository/Command/Object/Screen/DisplayData/glade-interface/widget/@class", ctxt);
if (strcmp((char *)xmlXPathCastToString(res), "GtkDialog") == 0)
return true;
else
return false;
}
bool AllowMultipleInstances(xmlDocPtr docRes)
{
xmlXPathContextPtr ctxt;
xmlXPathObjectPtr res;
/* Init XPath */
xmlXPathInit();
/* Create XPath environment */
ctxt = xmlXPathNewContext(docRes);
/* Find out if screen is modal */
res = xmlXPathEval((const xmlChar *)"/ProLinga/Repository/Command/Object/Screen/AllowMultipleInstances", ctxt);
if (strcmp((char *)xmlXPathCastToString(res), "True") == 0)
return true;
else
return false;
}
int SetSignalHandlers(xmlDocPtr *docRes, struct widget_handler *wh)
{
xmlNodePtr curTmp, curXPath, curBox, curLast;
xmlXPathContextPtr ctxt;
xmlXPathObjectPtr resFocus, resScreen, resSignal, resBox;
int i=0, j;
bool boxHasItems=false;
xmlChar *attributeValue;
/* Init XPath */
xmlXPathInit();
/* Create XPath environment */
ctxt = xmlXPathNewContext(*docRes);
/* Get Screen id */
resScreen = xmlXPathEval((const xmlChar *)"/ProLinga/Repository/Command/Object/Screen/DisplayData/glade-interface/widget/@id", ctxt);
/* Insert focus-in signal to keep track of active screen */
resFocus = xmlXPathEval((const xmlChar *)"/ProLinga/Repository/Command/Object/Screen/DisplayData/glade-interface/widget/child", ctxt);
curXPath = resFocus->nodesetval->nodeTab[0];
curTmp = curXPath;
curXPath = curXPath->parent;
xmlUnlinkNode(curTmp);
curXPath = xmlNewTextChild(curXPath, NULL, (const xmlChar *)"signal", (const xmlChar *)"");
xmlNewProp(curXPath, (const xmlChar *)"name", (const xmlChar *)"focus_in_event");
xmlNewProp(curXPath, (const xmlChar *)"handler", (const xmlChar *)"X-SetActiveScreen");
xmlNewProp(curXPath, (const xmlChar *)"last_modification_time", (const xmlChar *)"Wed, 01 Jan 2003 00:00:00 GMT");
xmlAddChildList(curXPath->parent, curTmp);
/* Get all signal elements */
resSignal = xmlXPathEval((const xmlChar *)"//*/signal", ctxt);
/* Process signals */
curXPath = resSignal->nodesetval->nodeTab[0];
for (i=1; i<=resSignal->nodesetval->nodeNr; i++)
{
// i++;
/* Get Widget Info */
curTmp = curXPath;
curTmp = curTmp->parent;
strcpy(wh[i].widgetType, (char *)xmlGetProp(curTmp, (const xmlChar *)"class"));
strcpy(wh[i].widgetName, (char *)xmlGetProp(curTmp, (const xmlChar *)"id"));
/* Get Screen Id and Signal */
strcpy(wh[i].screenId, (char *)xmlXPathCastToString(resScreen));
strcpy(wh[i].signalName, (char *)xmlGetProp(curXPath, (const xmlChar *)"name"));
strcpy(wh[i].signalHandler, (char *)xmlGetProp(curXPath, (const xmlChar *)"handler"));
/* Set signal handler to generic Action or Dataref function */
if ((wh[i].signalHandler[0] == 'D') || (wh[i].signalHandler[0] == 'P'))
xmlSetProp(curXPath, (const xmlChar *)"handler", (const xmlChar *)"X_HANDLER_DREF_X");
else
xmlSetProp(curXPath, (const xmlChar *)"handler", (const xmlChar *)"X_HANDLER_ACTION_X");
/* Get next signal */
curXPath = resSignal->nodesetval->nodeTab[i];
}
/* Check if all ComboBox entries have "items" property so data model gets build at screen creation time */
boxHasItems=false;
resBox = xmlXPathEval((const xmlChar *)"//*/widget[@class='GtkComboBox']|//*/widget[@class='GtkComboBoxEntry']", ctxt);
if ((resBox!=NULL) && (resBox->nodesetval->nodeNr > 0))
{
/* Found GtkComboBoxEntry */
curLast = NULL;
/* Check if it has items property */
for (j=0; jnodesetval->nodeNr; j++)
{
curBox = resBox->nodesetval->nodeTab[j];
curTmp = curBox;
curBox = curBox->xmlChildrenNode;
while (curBox != NULL)
{
if ((!xmlStrcmp(curBox->name, (const xmlChar *)"property")))
{
/* Keep pointer to last property, to insert at correct point */
curLast = curBox;
/* Check Attributes */
attributeValue = (xmlChar *)xmlGetProp(curBox, (const xmlChar *)"name");
if ((!xmlStrcmp(attributeValue, (const xmlChar *)"items")))
{
boxHasItems=true;
xmlFree(attributeValue);
break;
}
xmlFree(attributeValue);
}
curBox=curBox->next;
}
if (boxHasItems==false)
{
curBox=curTmp;
curBox=xmlNewTextChild(curBox, NULL, (const xmlChar *)"property", NULL);
if (curLast != NULL)
curBox = xmlAddNextSibling(curLast, curBox);
xmlNewProp(curBox, (const xmlChar *)"name", (const xmlChar *)"items");
xmlNewProp(curBox, (const xmlChar *)"translatable", (const xmlChar *)"yes");
}
}
}
/* Return */
return i-1;
}
void DestroyScreenName(gpointer data)
{
struct screen_wdgPtr *sw;
int numDesktop;
/* This function is only been called once when destroying any window/dialog */
/* Cast struct */
sw = (struct screen_wdgPtr *)data;
/* Remove screen from screens on desktop list */
desktopScreenPtr->deleteValue(&desktopScreenPtr, sw->screenName, sw->screenWdg);
/* Clean up */
delete sw;
numDesktop = desktopScreenPtr->numberOnDesktop(desktopScreenPtr);
if (numDesktop < 1)
{
if (biQuitLastScreenPtr->getQuitLastScreen() == 0)
{
gtk_main_quit();
return;
}
}
}
void DestroyScreen(gpointer data)
{
char *string;
// printf("NOTIFIER!!!!!\n");
string = (char *)data;
// printf("!!!%s\n", string);
delete string;
}
void CloseAllScreens(bool isMainThread)
{
GtkWidget *wdgTmp;
char *screenType, *screenName;
/* get GTK thread lock */
if (isMainThread == false)
gdk_threads_enter();
for(;;)
{
wdgTmp = desktopScreenPtr->getFirstValue(&desktopScreenPtr);
if (wdgTmp == NULL)
break;
screenType = (char *)g_object_get_data(G_OBJECT(wdgTmp), "screenType");
screenName = (char *)g_object_get_data(G_OBJECT(wdgTmp), "screenName");
if (strcmp(screenType, "DIALOG") == 0)
{
gtk_dialog_response(GTK_DIALOG(wdgTmp), GTK_RESPONSE_CLOSE);
}
else
{
desktopScreenPtr->deleteValue(&desktopScreenPtr, screenName, wdgTmp);
gtk_widget_destroy(wdgTmp);
gtk_widget_destroyed(wdgTmp, &wdgTmp);
}
}
/* release GTK thread lock */
if (isMainThread == false)
{
/* Sync with X server */
gdk_flush();
/* release GTK thread lock */
gdk_threads_leave();
}
}
void CmdScreen(const char **argList, int argHits, bool isMainThread, GtkWidget *outputScreen)
{
struct widget_handler wh[255] = {};
struct screen_wdgPtr *sw;
xmlDocPtr docRes;
xmlXPathContextPtr ctxRes;
xmlXPathObjectPtr resRes;
char *screenId, *screen, *signalHandler, returnRef[255], *screenType, *screenWidgetName;
char sigKey[80], screenName[64], *returnStatus;
char titleString[LM_TITLE_STRING_LENGTH];
const char *errorList[5];
GladeXML *xml;
GtkWidget *wdg, *wdgTmp, *dialogScreen, *wdgSrc, *wdgDest, *wdgScreen;
int i,j, numberSignals = 0;
bool isDialog = false, allowMultiple = false;
gint result;
/* Fall back */
if (outputScreen == NULL)
outputScreen = activeScreen;
if (argHits == 1)
{
/* Display New Screen */
/* Exec RC Get */
getDataRef(argList[1], isMainThread, screenName, false);
docRes = RC_Get(biAppnPtr->getAppn(), "Screen", screenName);
/* Create XPath environment */
ctxRes = xmlXPathNewContext(docRes);
/* Check status */
resRes = xmlXPathEval((const xmlChar *)"/ProLinga/Repository/Command/@Status", ctxRes);
returnStatus = (char *)xmlXPathCastToString(resRes);
if ( strcmp(returnStatus, "Ok") != 0)
{
errorList[1] = "Screen [";
errorList[2] = screenName;
errorList[3] = "] does not exist.";
CmdError(errorList, 3, isMainThread, NULL, false);
return;
}
/* Find out if Screen already on desktop */
if (desktopScreenPtr->isOnDesktop(desktopScreenPtr, screenName) != 0)
{
/* Find out if Multiple Instances are allowed */
allowMultiple = AllowMultipleInstances(docRes);
if (allowMultiple == false)
{
/* Grab Screen widget Ptr */
wdgTmp = desktopScreenPtr->getOneValue(&desktopScreenPtr, screenName);
/* get GTK thread lock */
if (isMainThread == false)
gdk_threads_enter();
/* Bring window to foreground */
gtk_window_present(GTK_WINDOW(wdgTmp));
/* release GTK thread lock */
if (isMainThread == false)
{
/* Sync with X server */
gdk_flush();
/* release GTK thread lock */
gdk_threads_leave();
}
/* Return */
return;
}
}
/* Set Signal Handlers */
numberSignals = SetSignalHandlers(&docRes, wh);
/* Find out if Modal Screen */
isDialog = IsDialogScreen(docRes);
/* Extract Glade screen from response */
screen = CreateGladeString(docRes);
/*
dump = fopen("./dump.txt", "w");
fprintf(dump,"%s",screen);
fclose(dump);
*/
/* get GTK thread lock */
if (isMainThread == false)
gdk_threads_enter();
/* Display Screen */
xml = glade_xml_new_from_buffer(screen, strlen(screen), NULL, NULL);
/* release GTK thread lock */
if (isMainThread == false)
{
/* Sync with X server */
gdk_flush();
/* release GTK thread lock */
gdk_threads_leave();
}
if (!xml)
{
g_warning("something bad happened while creating the interface");
return;
}
/* get GTK thread lock */
if (isMainThread == false)
gdk_threads_enter();
/* Set Signal Data */
for (i = 1; i <= numberSignals; i++)
{
wdg = glade_xml_get_widget(xml, wh[i].widgetName);
screenId = new char[255];
strcpy(screenId, wh[i].screenId);
/* Attach screen name to widget (only once) */
if( (char *)g_object_get_data(G_OBJECT(wdg), "screenId") == NULL)
g_object_set_data_full(G_OBJECT(wdg), "screenId", screenId, DestroyScreen);
/* Attach screen type (window or dialog) to widget (only once) */
screenType = new char[10];
if (isDialog == true)
{
if( (char *)g_object_get_data(G_OBJECT(wdg), "screenType") == NULL)
{
strcpy(screenType,"DIALOG");
g_object_set_data_full(G_OBJECT(wdg), "screenType", screenType, DestroyScreen);
}
}
else
{
if( (char *)g_object_get_data(G_OBJECT(wdg), "screenType") == NULL)
{
strcpy(screenType,"WINDOW");
g_object_set_data_full(G_OBJECT(wdg), "screenType", screenType, DestroyScreen);
}
}
/* Get signal handler data */
signalHandler = new char[255];
strcpy(signalHandler, wh[i].signalHandler);
//wdgTmp = glade_xml_get_widget(xml, screenName);
/* Set key to signalname + seq no */
j = 1;
for(;;)
{
//printf("SIGNAL %s_%d HANDLER %s\n", wh[i].signalName, j, signalHandler);
sprintf(sigKey,"%s_%d", wh[i].signalName, j);
if( (char *)g_object_get_data(G_OBJECT(wdg), sigKey) == NULL)
{
if ((strcmp(wh[i].widgetType, "GtkComboBoxEntry") == 0) && (strncmp(wh[i].signalName, "child_",6) == 0))
{
g_object_set_data_full(G_OBJECT(GTK_BIN(wdg)->child), sigKey+6, signalHandler, DestroyScreen);
/* Connect all non-clicked signals to GtkEntry part of ComboBoxEntry */
/* Future versions of Glade should split this up */
if ((wh[i].signalHandler[0] == 'D') || (wh[i].signalHandler[0] == 'P'))
g_signal_connect ((gpointer) GTK_BIN(wdg)->child, wh[i].signalName+6, G_CALLBACK (X_HANDLER_DREF_X), NULL);
else
g_signal_connect ((gpointer) GTK_BIN(wdg)->child, wh[i].signalName+6, G_CALLBACK (X_HANDLER_ACTION_X), NULL);
}
else
{
g_object_set_data_full(G_OBJECT(wdg), sigKey, signalHandler, DestroyScreen);
if ((wh[i].signalHandler[0] == 'D') || (wh[i].signalHandler[0] == 'P'))
g_signal_connect ((gpointer) G_OBJECT(wdg), wh[i].signalName, G_CALLBACK (X_HANDLER_DREF_X), NULL);
else
g_signal_connect ((gpointer) G_OBJECT(wdg), wh[i].signalName, G_CALLBACK (X_HANDLER_ACTION_X), NULL);
}
break;
}
j++;
}
}
/* Call function DestroyScreenName only once when destroyed */
// !!!!!!!
//wdg = glade_xml_get_widget(xml, screenName);
//wdgTmp = LookupWidget(GTK_WIDGET(wdg), screenName);
wdgTmp = glade_xml_get_widget(xml, screenName);
if( (char *)g_object_get_data(G_OBJECT(wdgTmp), "screenName") == NULL)
{
sw = new screen_wdgPtr;
strcpy(sw->screenName, screenName);
sw->screenWdg = wdgTmp;
g_object_set_data_full(G_OBJECT(wdgTmp), "screenName", sw, DestroyScreenName);
//g_object_set_data_full(G_OBJECT(wdgTmp), "screenName", screenName, DestroyScreenName);
/* Add screen to list 'on desktop' */
desktopScreenPtr->putValue(&desktopScreenPtr, screenName, wdgTmp);
//printf("On desktop %d times is %s\n", desktopScreenPtr->isOnDesktop(desktopScreenPtr, screenName), screenName);
}
/* Connect signals */
//glade_xml_signal_autoconnect(xml);
/* release GTK thread lock */
if (isMainThread == false)
{
/* Sync with X server */
gdk_flush();
/* release GTK thread lock */
gdk_threads_leave();
}
if (isDialog == true)
{
/* Put active screen on stack */
dialogStackPtr->push(&dialogStackPtr, activeScreen);
//tempScreen = activeScreen;
/* Block in loop */
//dialogScreen = glade_xml_get_widget(xml, screenId);
dialogScreen = glade_xml_get_widget(xml, screenName);
DisplayRealize(GTK_OBJECT(dialogScreen));
/* get GTK thread lock */
if (isMainThread == false)
gdk_threads_enter();
for (;;)
{
result = gtk_dialog_run(GTK_DIALOG(dialogScreen));
//if ((tempScreen == activeScreen) || (result == GTK_RESPONSE_CLOSE))
if (result == GTK_RESPONSE_CLOSE)
{
desktopScreenPtr->deleteValue(&desktopScreenPtr, screenName, dialogScreen);
gtk_widget_destroy(dialogScreen);
gtk_widget_destroyed(dialogScreen, &dialogScreen);
break;
}
}
/* release GTK thread lock */
if (isMainThread == false)
{
/* Sync with X server */
gdk_flush();
/* release GTK thread lock */
gdk_threads_leave();
}
/* Get active screen from stack */
dialogStackPtr->pop(&dialogStackPtr, &activeScreen);
}
else
DisplayRealize(GTK_OBJECT(wdgTmp));
/* Free object */
//g_object_unref(G_OBJECT(xml));
/*Clean up */
delete screen;
/* Cleanup */
//xmlFreeDoc(docRes);
}
else
{
/* Change Screen Property */
if (strcmp(argList[1], "CLOSE") == 0)
{
if (argHits == 1)
{
/* get GTK thread lock */
if (isMainThread == false)
gdk_threads_enter();
/* Close active screen */
screenType = (char *)g_object_get_data(G_OBJECT(outputScreen), "screenType");
if (strcmp(screenType, "DIALOG") == 0)
{
gtk_dialog_response(GTK_DIALOG(outputScreen), GTK_RESPONSE_CLOSE);
}
else
{
screenWidgetName = (char *)g_object_get_data(G_OBJECT(outputScreen), "screenName");
desktopScreenPtr->deleteValue(&desktopScreenPtr, screenWidgetName, outputScreen);
gtk_widget_destroy(outputScreen);
gtk_widget_destroyed(outputScreen, &outputScreen);
}
/* release GTK thread lock */
if (isMainThread == false)
{
/* Sync with X server */
gdk_flush();
/* release GTK thread lock */
gdk_threads_leave();
}
}
else
{
if (strcmp(argList[2], "ALL") == 0)
{
CloseAllScreens(isMainThread);
}
else
{
/* get GTK thread lock */
if (isMainThread == false)
gdk_threads_enter();
/* Get widgetptr screen */
for (;;)
{
wdgTmp = desktopScreenPtr->getOneValue(&desktopScreenPtr, argList[2]);
if (wdgTmp == NULL)
break;
screenType = (char *)g_object_get_data(G_OBJECT(wdgTmp), "screenType");
if (strcmp(screenType, "DIALOG") == 0)
{
gtk_dialog_response(GTK_DIALOG(wdgTmp), GTK_RESPONSE_CLOSE);
}
else
{
screenWidgetName = (char *)g_object_get_data(G_OBJECT(wdgTmp), "screenName");
desktopScreenPtr->deleteValue(&desktopScreenPtr, screenWidgetName, wdgTmp);
gtk_widget_destroy(wdgTmp);
gtk_widget_destroyed(wdgTmp, &wdgTmp);
}
}
/* release GTK thread lock */
if (isMainThread == false)
{
/* Sync with X server */
gdk_flush();
/* release GTK thread lock */
gdk_threads_leave();
}
}
}
}
else if (strcmp(argList[1], "TITLE") == 0)
{
/* Concatenate Title */
for (i = 2; i<= argHits; i++)
{
getDataRef(argList[i], isMainThread, returnRef, false);
if (strcmp(returnRef, "TARGET") == 0)
break;
if (i == 2)
strcpy(titleString, returnRef);
else
strcat(titleString, returnRef);
}
if (argHits == 2)
{
/* get GTK thread lock */
if (isMainThread == false)
gdk_threads_enter();
/* Set title current/active screen*/
gtk_window_set_title(GTK_WINDOW(outputScreen),(gchar *)titleString);
/* release GTK thread lock */
if (isMainThread == false)
{
/* Sync with X server */
gdk_flush();
/* release GTK thread lock */
gdk_threads_leave();
}
}
else
{
/* Get screen name */
getDataRef(argList[4], isMainThread, returnRef, false);
/* Get Pointer(s) to screens */
// for (;;)
// {
wdgTmp = desktopScreenPtr->getOneValue(&desktopScreenPtr, returnRef);
// if (wdgTmp == NULL)
// break;
/* get GTK thread lock */
if (isMainThread == false)
gdk_threads_enter();
/* Set title */
gtk_window_set_title(GTK_WINDOW(wdgTmp),(gchar *)titleString);
/* release GTK thread lock */
if (isMainThread == false)
{
/* Sync with X server */
gdk_flush();
/* release GTK thread lock */
gdk_threads_leave();
}
// }
}
}
else if (strcmp(argList[2], "CONTAINER") == 0)
{
/* Lookup container control */
wdgDest = LookupWidget(GTK_WIDGET(outputScreen), argList[3]);
if (wdgDest == NULL)
{
/*ERROR */
printf("Target container does not exist in active screen.\n");
return;
}
/* get GTK thread lock */
if (isMainThread == false)
gdk_threads_enter();
/* If bin contains child, remove it */
wdgTmp = gtk_bin_get_child(GTK_BIN(wdgDest));
if (isMainThread == false)
{
/* Sync with X server */
gdk_flush();
/* release GTK thread lock */
gdk_threads_leave();
}
if (wdgTmp != NULL)
{
/* get GTK thread lock */
if (isMainThread == false)
gdk_threads_enter();
/* remove object from container */
gtk_container_remove(GTK_CONTAINER(wdgDest), wdgTmp);
/* release GTK thread lock */
if (isMainThread == false)
{
/* Sync with X server */
gdk_flush();
/* release GTK thread lock */
gdk_threads_leave();
}
/* Destroy inclusion object */
//gtk_widget_destroy(GTK_WIDGET(wdgTmp));
}
/* Create socket and link to destination widget */
/* FUTURE ?? */
//wdgSocket = gtk_socket_new ();
//gtk_widget_show (wdgSocket);
//gtk_container_add (GTK_CONTAINER (wdgDest), wdgSocket);
/* Load inclusion screen */
getDataRef(argList[1], isMainThread, screenName, false);
docRes = RC_Get(biAppnPtr->getAppn(), "Screen", screenName);
/* Set Signal Handlers */
numberSignals = SetSignalHandlers(&docRes, wh);
/* Extract Glade screen from response */
screen = CreateGladeString(docRes);
/* get GTK thread lock */
if (isMainThread == false)
{
gdk_threads_enter();
/* FIXME: Strange timing issue */
sleep(1);
}
/* Load Screen */
xml = glade_xml_new_from_buffer(screen, strlen(screen), NULL, NULL);
if (isMainThread == false)
{
/* Sync with X server */
gdk_flush();
/* release GTK thread lock */
gdk_threads_leave();
}
if (!xml)
{
g_warning("something bad happened while creating the interface");
return;
}
/* Set Signal Data */
for (i = 1; i <= numberSignals; i++)
{
wdg = glade_xml_get_widget(xml, wh[i].widgetName);
screenId = new char[255];
strcpy(screenId, (char *)g_object_get_data(G_OBJECT(outputScreen), "screenId"));
g_object_set_data_full(G_OBJECT(wdg), "screenId", screenId, DestroyScreen);
screenType = new char[10];
strcpy(screenType, (char *)g_object_get_data(G_OBJECT(outputScreen), "screenType"));
g_object_set_data_full(G_OBJECT(wdg), "screenType", screenType, DestroyScreen);
/* Get signal handler data */
signalHandler = new char[255];
strcpy(signalHandler, wh[i].signalHandler);
/* Set key to signalname + seq no */
j = 1;
for(;;)
{
sprintf(sigKey,"%s_%d", wh[i].signalName, j);
if( (char *)g_object_get_data(G_OBJECT(wdg), sigKey) == NULL)
{
/* Connect all child signals to GtkEntry part of ComboBoxEntry */
/* Future versions of Glade should split this up */
if ((strcmp(wh[i].widgetType, "GtkComboBoxEntry") == 0) && (strncmp(wh[i].signalName, "child_",6) == 0))
{
g_object_set_data_full(G_OBJECT(GTK_BIN(wdg)->child), sigKey+6, signalHandler, DestroyScreen);
if ((wh[i].signalHandler[0] == 'D') || (wh[i].signalHandler[0] == 'P'))
g_signal_connect ((gpointer) GTK_BIN(wdg)->child, wh[i].signalName+6, G_CALLBACK (X_HANDLER_DREF_X), NULL);
else
g_signal_connect ((gpointer) GTK_BIN(wdg)->child, wh[i].signalName+6, G_CALLBACK (X_HANDLER_ACTION_X), NULL);
}
else
{
g_object_set_data_full(G_OBJECT(wdg), sigKey, signalHandler, DestroyScreen);
if ((wh[i].signalHandler[0] == 'D') || (wh[i].signalHandler[0] == 'P'))
g_signal_connect ((gpointer) G_OBJECT(wdg), wh[i].signalName, G_CALLBACK (X_HANDLER_DREF_X), NULL);
else
g_signal_connect ((gpointer) G_OBJECT(wdg), wh[i].signalName, G_CALLBACK (X_HANDLER_ACTION_X), NULL);
}
break;
}
j++;
}
}
/* Connect signals */
//glade_xml_signal_autoconnect(xml);
/* Get Source widget */
wdgScreen = glade_xml_get_widget(xml, screenName);
wdgSrc = glade_xml_get_widget(xml, argList[5]);
DisplayRealize(GTK_OBJECT(wdgScreen));
//gtk_widget_ref(wdgSrc);
/* get GTK thread lock */
if (isMainThread == false)
gdk_threads_enter();
gtk_widget_reparent(wdgSrc, wdgDest);
//gtk_container_remove(GTK_CONTAINER(wdgScreen), wdgSrc);
//gtk_widget_unparent(wdgSrc);
//gtk_container_add(GTK_CONTAINER(wdgDest), GTK_WIDGET(wdgSrc));
//gtk_widget_unref(wdgSrc);
/* Destroy source inclusion screen */
gtk_widget_destroy(wdgScreen);
/* release GTK thread lock */
if (isMainThread == false)
{
/* Sync with X server */
gdk_flush();
/* release GTK thread lock */
gdk_threads_leave();
}
/* Free */
delete screen;
/* Create "empty" plug */
//wdgPlug = gtk_plug_new (gtk_socket_get_id (GTK_SOCKET(wdgSocket)));
//gtk_widget_show (wdgPlug);
}
}
}