cdesktopenv/cde/programs/dtappbuilder/src/libABobj/test_notify.c

1492 lines
36 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these librararies and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/*
* $XConsortium: test_notify.c /main/3 1995/11/06 18:41:12 rswiston $
*
* @(#)test_notify.c 1.16 14 Feb 1994 cde_app_builder/src/libABobj
*
* RESTRICTED CONFIDENTIAL INFORMATION:
*
* The information in this document is subject to special
* restrictions in a confidential disclosure agreement between
* HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
* document outside HP, IBM, Sun, USL, SCO, or Univel without
* Sun's specific written approval. This document and all copies
* and derivative works thereof must be returned or destroyed at
* Sun's request.
*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
*
*/
/*
* template.c - template c file.
*/
#ifdef _POSIX_SOURCE
#define _POSIX_SOURCE 1
#endif
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <ab_private/obj_notify.h>
#include <ab_private/trav.h>
typedef struct
{
int free_count;
STRING text;
} UPDATE_DATA, *UpdateData;
/*************************************************************************
** **
** Constants (#define and const) **
** **
**************************************************************************/
#define MAX_OBJECTS 1000
#define UPDATE_MSG1 (1)
#define UPDATE_MSG2 (2)
/*************************************************************************
** **
** Private Functions (C declarations and macros) **
** **
**************************************************************************/
#define check_find(obj) (check_find_impl(obj, __FILE__, __LINE__))
#define verify_tree(tree) (verify_tree_impl(tree, __FILE__, __LINE__))
#define verify_count(tree, count) \
(verify_count_impl(tree, count, __FILE__, __LINE__))
#define err_exit(str) (err_exit_impl((str), __FILE__, __LINE__))
static int err_exit_impl(STRING msg, STRING file, int line);
static int set_name(ABObj obj);
static STRING safe_obj_name(ABObj obj);
static int set_next_name_number(int number);
static ABObj create_test_project(void);
static int create_test_module(ABObj project);
static int composite_create_module(ABObj module);
static int composite_create_list(ABObj module);
static int composite_create_slider(ABObj slider);
static int check_find_impl(ABObj obj, STRING file, int line);
static int verify_count_impl(ABObj obj, int count, STRING file, int line);
static int verify_tree_impl(ABObj obj, STRING file, int line);
static int test_destroy(ABObj *treePtr, int *objCountPtr);
static int test_geometry(ABObj tree);
static int test_selection(ABObj tree);
static int test_update(ABObj tree);
static int print_selected(ABObj tree);
static int count_selected(ABObj tree);
static int free_update_data(int update_code, void *update_data);
/*************************************************************************
** **
** Data **
** **
**************************************************************************/
static char msg[1024];
static int allObjectsArrayCount= 0;
static ABObj allObjectsArray[MAX_OBJECTS];
static int renameCount= 0;
static int renameEventCount= 0;
static int reparentCount= 0;
static int reparentEventCount= 0;
static int reparentCountsDiff= 0; /* reparentCount - reparentEventCount */
static int selectCount= 0;
static int selectEventCount= 0;
static int unselectCount= 0;
static int unselectEventCount= 0;
static int destroyCount= 0;
static int destroyEventCount= 0;
static int updateCount= 0;
static int updateEventCount= 0;
static int updateTreeCount= 0;
static int updateTreeEventCount= 0;
static UPDATE_DATA update_data1;
static UPDATE_DATA update_data2;
/*************************************************************************
** **
** Function Definitions **
** **
**************************************************************************/
/*
* "mod1" module callbacks
*/
static int rename_obj_create_callback(ObjEvCreateInfo info);
static int composite_obj_create_callback(ObjEvCreateInfo info);
static int mod2_obj_create_callback(ObjEvCreateInfo info);
static int rename_callback1(ObjEvAttChangeInfo info);
static int reparent_callback1(ObjEvReparentInfo info);
static int reparent_count_callback(ObjEvReparentInfo info);
static int allow_reparent_callback1(ObjEvAllowReparentInfo info);
static int count_select_callback(ObjEvAttChangeInfo info);
static int composite_select_callback(ObjEvAttChangeInfo info);
static int exclusive_select_callback(ObjEvAttChangeInfo info);
static int grid_geometry_callback(ObjEvAttChangeInfo info);
static int symmetric_geometry_allow_callback(ObjEvAllowGeometryChangeInfo info);
static int composite_geometry_allow_callback(ObjEvAllowGeometryChangeInfo info);
static int bogus_geometry_allow_callback(ObjEvAllowGeometryChangeInfo info);
static int composite_destroy_callback(ObjEvDestroyInfo info);
static int count_destroy_callback(ObjEvDestroyInfo info);
static int composite_update_callback(ObjEvUpdateInfo info);
static int count_update_callback(ObjEvUpdateInfo info);
static int count_update_with_data_callback(ObjEvUpdateWithDataInfo info);
static int composite_update_with_data_callback(ObjEvUpdateWithDataInfo info);
int
main (int argc, char *argv[])
{
int iRC= 0; /* return code */
ABObj project= NULL;
ABObj module1= NULL;
int objCount= 0;
int fileMode= 0;
util_init(argv[0]);
/*
* Make all output unbuffered
*/
obj_add_allow_reparent_callback(
allow_reparent_callback1, "allow_reparent_callback1");
obj_add_reparent_callback(
reparent_callback1, "reparent_callback1");
obj_add_reparent_callback(
reparent_count_callback, "reparent_count_callback");
obj_add_create_callback(
rename_obj_create_callback, "rename_obj_create_callback");
obj_add_create_callback(
composite_obj_create_callback,
"composite_obj_create_callback");
obj_add_create_callback(
mod2_obj_create_callback, "mod2_obj_create_callback");
obj_add_rename_callback(
rename_callback1, "rename_callback1");
obj_add_selected_change_callback(
exclusive_select_callback, "obj_add_selected_change_callback");
obj_add_selected_change_callback(
count_select_callback, "count_select_callback");
obj_add_selected_change_callback(
composite_select_callback, "composite_select_callback");
obj_add_geometry_change_callback(
grid_geometry_callback, "grid_geometry_callback");
obj_add_allow_geometry_change_callback(
symmetric_geometry_allow_callback,
"symmetric_geometry_allow_callback");
obj_add_allow_geometry_change_callback(
composite_geometry_allow_callback,
"composite_geometry_allow_callback");
obj_add_allow_geometry_change_callback(
bogus_geometry_allow_callback,
"bogus_geometry_allow_callback");
obj_add_destroy_callback(
composite_destroy_callback,
"composite_destroy_callback");
obj_add_destroy_callback(
count_destroy_callback,
"count_destroy_callback");
obj_add_update_callback(
count_update_callback, "count_update_callback");
obj_add_update_callback(
composite_update_callback, "composite_update_callback");
obj_add_update_with_data_callback(
composite_update_with_data_callback,
"composite_update_with_data_callback");
obj_add_update_with_data_callback(
count_update_with_data_callback,
"count_update_with_data_callback");
project= create_test_project();
/* obj_print_tree(project); */
module1= obj_find_module_by_name(project, "module1");
check_find(module1);
objCount= trav_count(project, AB_TRAV_ALL);
if (objCount != allObjectsArrayCount)
{
fprintf(stderr, "Count mismatch (%d,%d) %s:%d\n",
objCount, allObjectsArrayCount, __FILE__, __LINE__);
exit(1);
}
printf("Objects in tree: %d\n", objCount);
verify_count(project, objCount);
printf("Rename events processed: %d\n", renameEventCount);
if (renameEventCount != renameCount)
{
fprintf(stderr, "ERROR: %d rename events received!\n",
renameEventCount);
}
/*
* Test reparent allow
*/
iRC= obj_unparent(module1); ++reparentCount;
printf("unparent module: %d\n", iRC);
if (iRC >= 0)
{
fprintf(stderr, "ERROR. Reparent allowed %s:%d\n", __FILE__, __LINE__);
}
reparentCountsDiff+= 1; /* this reparent ended in allow_reparent */
verify_count(project, objCount);
/*
* Test reparenting
*/
{
ABObj slider1= obj_find_by_name(project, "slider101");
ABObj container3= obj_find_by_name(project, "container103");
ABObj container5= obj_find_by_name(project, "container105");
ABObj list2= obj_find_by_name(project, "list102");
ABObj list3= obj_find_by_name(project, "list103");
check_find(slider1);
check_find(container3);
check_find(container5);
check_find(list2);
check_find(list3);
verify_count(project, objCount);
printf("test reparent\n");
obj_reparent(slider1, container3); ++reparentCount;
verify_count(project, objCount);
printf("test move_children\n");
reparentCount+= obj_get_num_children(container3);
obj_move_children(list2, container3);
verify_count(project, objCount);
/*
* Put it back the way it was!
*/
obj_reparent(slider1, container5); ++reparentCount;
obj_reparent(list3, container3); ++reparentCount;
obj_reparent(container5, container3); ++reparentCount;
verify_count(project, objCount);
}
printf("reparents - performed:%d events processed: %d\n",
reparentCount, reparentEventCount);
if ((reparentCount - reparentEventCount) != reparentCountsDiff)
{
fprintf(stderr, "ERROR: reparent counts don't match! %s:%d\n",
__FILE__, __LINE__);
exit(1);
}
verify_count(project, objCount);
test_selection(project);
verify_count(project, objCount);
test_geometry(project);
verify_count(project, objCount);
test_update(project);
verify_count(project, objCount);
test_destroy(&project, &objCount);
verify_count(project, objCount);
fflush(stdout);
fflush(stderr);
printf("\n*** TESTS COMPLETED SUCCESSFULLY ***\n\n");
exit(0);
}
static int
err_exit_impl(STRING msg, STRING file, int line)
{
if (msg != NULL)
{
fprintf(stderr, "ERROR. %s %s:%d\n", msg, file, line);
}
exit(1);
return 0;
}
static int
test_selection(ABObj tree)
{
ABObj button1= obj_find_by_name(tree, "button101");
ABObj module1= obj_find_module_by_name(tree, "module1");
ABObj list5= obj_find_by_name(tree, "list105");
ABObj container5= obj_find_by_name(tree, "container105");
check_find(button1);
check_find(module1);
check_find(list5);
check_find(container5);
obj_select(button1); selectCount+= 1;
print_selected(tree);
if (count_selected(tree) != 1)
{
fprintf(stderr, "ERROR. incorrect select count %s:%d\n",
__FILE__, __LINE__);
exit(1);
}
obj_select(module1); selectCount += 8;
print_selected(tree);
if (count_selected(tree) != 8)
{
fprintf(stderr, "ERROR. incorrect select count %s:%d\n",
__FILE__, __LINE__);
exit(1);
}
obj_unselect(module1);
print_selected(tree);
if (count_selected(tree) != 0)
{
fprintf(stderr, "ERROR: unselect failed. %s:%d\n",
__FILE__, __LINE__);
exit(1);
}
printf("selections - performed:%d events:%d\n",
selectCount, selectEventCount);
if (selectCount != selectEventCount)
{
fprintf(stderr, "ERROR: Select event count mismatch %s:%d\n",
__FILE__, __LINE__);
exit(1);
}
return OK;
}
static int
test_update(ABObj tree)
{
ABObj module1= obj_find_module_by_name(tree, "module1");
ABObj slider1= obj_find_by_name(tree, "slider101");
ABObj item2= obj_find_by_name(tree, "item102");
int numObjects= 0;
int old_verbosity= util_get_verbosity();
int data1_free_count= 0;
int data2_free_count= 0;
check_find(module1);
check_find(slider1);
check_find(item2);
printf("testing update messages\n");
update_data1.free_count= 0;
update_data1.text= "Data packet 1";
data1_free_count= 0;
update_data2.free_count= 0;
update_data2.text= "Data packet 2";
data2_free_count= 0;
updateCount= 0;
updateEventCount= 0;
updateTreeCount= 0;
updateTreeEventCount= 0;
/*
* Composite
*/
printf("updating an internal composite\n");
obj_update_clients(module1); updateCount+= 8;
if ( (updateCount != updateEventCount)
|| (updateTreeCount != updateTreeEventCount) )
{
err_exit("Update count mismatch");
}
/*
* subtree - should get one update_tree method, which will cause
* more update object messages.
*/
util_set_verbosity(4);
numObjects= trav_count(module1, AB_TRAV_ALL);
printf("updating module subtree\n");
obj_tree_update_clients(module1);
updateTreeCount+= 1; updateCount+= 7;
if ( (updateCount != updateEventCount)
|| (updateTreeCount != updateTreeEventCount) )
{
err_exit("Update count mismatch");
}
/*
* Update a composite w/data
*/
obj_update_clients_with_data(slider1,
UPDATE_MSG1, (void *)&update_data1, free_update_data);
updateCount+= 3;
++data1_free_count;
if (updateCount != updateEventCount)
{
err_exit("Bad update event count");
}
/*
* obj_tree_update_clients_with_data on large subtree
*/
printf("testing tree update clients on complex subtree\n");
numObjects= trav_count(module1, AB_TRAV_ALL);
obj_tree_update_clients_with_data(module1, UPDATE_MSG2,
(void *)&update_data2, free_update_data);
updateCount+= numObjects;
++data2_free_count;
/*
* obj_tree_update_clients on single object
*/
printf("update tree on single object\n");
obj_tree_update_clients_with_data(item2, UPDATE_MSG2,
(void *)&update_data2, free_update_data);
++updateCount;
++data2_free_count;
if (update_data1.free_count != data1_free_count)
{
err_exit("bad free count");
}
printf("data1 free count: %d (OK)\n", update_data1.free_count);
if (update_data2.free_count != data2_free_count)
{
err_exit("bad free count");
}
printf("data2 free count: %d (OK)\n", update_data2.free_count);
util_set_verbosity(old_verbosity);
return 0;
}
static int
test_geometry(ABObj tree)
{
int iRC= 0; /* return code */
ABObj list1= obj_find_by_name(tree, "list101");
ABObj container4= obj_find_by_name(tree, "container104");
ABObj slider1= obj_find_by_name(tree, "slider101");
int x, y, w, h;
check_find(list1);
check_find(container4);
check_find(slider1);
printf("Testing geometry callbacks.\n");
/*
* should be disallowed because list1 is a comp. subobj
*/
if ((iRC= obj_test_move(list1, 10, 10)) >= 0)
{
err_exit("illegal move allowed");
}
if (iRC != ERR_NOT_ALLOWED)
{
err_exit("bad error code");
}
if (obj_move(list1, 10, 10) != ERR_NOT_ALLOWED)
{
err_exit("illegal move allowed");
}
/*
* legal! (no adjustment necessary)
*/
if (obj_move(slider1, 10, 10) < 0)
{
err_exit("legal move DISallowed");
}
/*
* legal, but should get moved to 10, 10
*/
if ((iRC= obj_test_set_geometry(container4, 5, 5, 100, 100)) < 0)
{
err_exit("legal set_geo DISallowed");
}
if ((iRC= obj_set_geometry(container4, 5, 5, 100, 100)) < 0)
{
err_exit("legal set_geo DISallowed");
}
obj_get_geometry(container4, &x, &y, &w, &h);
if (! ((x==10) && (y==10) && (w==100) && (h==100)) )
{
err_exit("move not handled properly");
}
if (iRC < 0)
{
err_exit("bad error code!\n");
}
/*
* illegal - width != height
*/
if (obj_resize(container4, 55, 60) >= 0)
{
err_exit("illegal resize allowed!");
}
if (obj_resize(container4, 60, 60) < 0)
{
err_exit("legal resize DISallowed");
}
obj_get_size(container4, &w, &h);
if (! ((w == 60) && (h == 60)) )
{
err_exit("resize not handled properly!");
}
/*
* The bogus allow callback should try to move an object and
* should generate an error in the callback itself.
*/
obj_move(container4, 1000, 1000);
return 0;
}
static int
test_destroy(ABObj *treePtr, int *objCountPtr)
{
#define tree (*treePtr)
#define objCount (*objCountPtr)
int iRC= 0; /* return code */
ABObj module1= obj_find_module_by_name(tree, "module1");
ABObj button1= obj_find_by_name(tree, "button101");
ABObj slider1= obj_find_by_name(tree, "slider101");
ABObj container5= obj_find_by_name(tree, "container105");
check_find(module1);
check_find(button1);
check_find(slider1);
check_find(container5);
printf("Testing destroy callbacks\n");
/*
* atomic leaf node - should be OK
*/
printf("deleting atomic leaf node\n");
iRC= obj_destroy(button1); --objCount; ++destroyCount;
if (iRC < 0)
{
err_exit("legal destroy DISallowed");
}
printf("destroying interior atomic\n");
iRC= obj_destroy_one(container5); --objCount; ++destroyCount;
if (iRC < 0)
{
err_exit("legal destroy failed");
}
verify_count(tree, objCount);
printf("destroying interior composite\n");
iRC= obj_destroy_one(module1); objCount-= 8; destroyCount+= 8;
verify_count(tree, objCount);
printf("destroying complex subtree\n");
iRC= obj_destroy(slider1); objCount-= 4; destroyCount+= 4;
verify_count(tree, objCount);
verify_count(tree, objCount); /* be sure objCount is up-to-date */
iRC= obj_destroy(tree); destroyCount+= objCount; objCount= 0;
tree= NULL;
verify_count(tree, objCount);
if (destroyCount != destroyEventCount)
{
err_exit("mismatched destroy counts");
}
return 0;
#undef tree
#undef objCount
}
static int
check_find_impl(ABObj obj, STRING file, int line)
{
int iReturn= 0;
if (obj == NULL)
{
fprintf(stderr, "Bad find %s:%d\n", file, line);
exit(1);
}
return iReturn;
}
static int
verify_count_impl(ABObj tree, int count, STRING file, int line)
{
int localCount= 0;
if (tree != NULL)
{
if (obj_tree_verify(tree) < 0)
{
fprintf(stderr, "ERROR: corrup tree %s:%d\n", file, line);
exit(1);
}
localCount= trav_count(tree, AB_TRAV_ALL);
}
if (count != localCount)
{
fprintf(stderr, "ERROR: bad count %s:%d\n", file, line);
exit(1);
}
return 0;
}
static int
verify_tree_impl(ABObj obj, STRING file, int line)
{
if (obj_tree_verify(obj) < 0)
{
fprintf(stderr, "ERROR. corrupt tree %s:%d\n", file, line);
exit(1);
}
return 0;
}
static int
print_selected(ABObj tree)
{
AB_TRAVERSAL trav;
ABObj obj= NULL;
int selCount= 0;
printf("Selected: ");
for (trav_open(&trav, tree, AB_TRAV_ALL | AB_TRAV_MOD_PARENTS_FIRST);
(obj= trav_next(&trav)) != NULL; )
{
if (obj_is_selected(obj))
{
++selCount;
if (selCount == 1)
{
/* printf("\n"); */
}
printf("%s ", safe_obj_name(obj));
}
}
trav_close(&trav);
if (selCount == 0)
{
printf("[NONE]");
}
printf("\n");
return 0;
}
static int
count_selected(ABObj tree)
{
int selectCount= 0;
AB_TRAVERSAL trav;
ABObj obj= NULL;
for (trav_open(&trav, tree, AB_TRAV_ALL);
(obj= trav_next(&trav)) != NULL; )
{
if (obj_is_selected(obj))
{
++selectCount;
}
}
trav_close(&trav);
return selectCount;
}
static ABObj
create_test_project(void)
{
ABObj project= NULL;
ABObj module1= NULL;
ABObj module2= NULL;
ABObj module3= NULL;
ABObj obj= NULL;
ABObj button= NULL;
ABObj parent= NULL;
project= obj_create(AB_TYPE_PROJECT, NULL);
create_test_module(project);
create_test_module(project);
create_test_module(project);
module1= obj_find_module_by_name(project, "module101");
check_find(module1);
module2= obj_find_module_by_name(project, "module201");
check_find(module2);
module3= obj_find_module_by_name(project, "module301");
check_find(module3);
if (module1 != NULL)
{
obj_set_name(module1, "module1"); ++renameCount;
}
if (module2 != NULL)
{
obj_set_name(module2, "module2"); ++renameCount;
}
if (module3 != NULL)
{
obj_set_name(module3, "module3"); ++renameCount;
}
return project;
}
static int
create_test_module(ABObj project)
{
static int module_number= 0;
int baseNumber = 0;
ABObj button1= NULL;
ABObj module= NULL;
ABObj tf1= NULL;
char tf1Name[256] = "";
ABObj container3= NULL;
char container3Name[256] = "";
ABObj container5= NULL;
char container5Name[256] = "";
ABObj container6= NULL;
char container6Name[256] = "";
ABObj item3= NULL;
char item3Name[256] = "";
ABObj slider1= NULL;
char slider1Name[256] = "";
ABObj list1= NULL;
char list1Name[256] = "";
ABObj list2= NULL;
char list2Name[256] = "";
ABObj list4= NULL;
char list4Name[256] = "";
ABObj list5= NULL;
char list5Name[256] = "";
++module_number;
baseNumber = module_number * 100;
set_next_name_number(baseNumber + 1);
sprintf(tf1Name, "text-field%d", baseNumber + 1);
sprintf(container3Name, "container%d", baseNumber + 3);
sprintf(container5Name, "container%d", baseNumber + 5);
sprintf(container6Name, "container%d", baseNumber + 6);
sprintf(item3Name, "item%d", baseNumber + 3);
sprintf(slider1Name, "slider%d", baseNumber + 1);
sprintf(list1Name, "list%d", baseNumber + 1);
sprintf(list2Name, "list%d", baseNumber + 2);
sprintf(list4Name, "list%d", baseNumber + 4);
sprintf(list5Name, "list%d", baseNumber + 5);
module= obj_create(AB_TYPE_MODULE, project);
tf1= obj_find_by_name(module, tf1Name);
check_find(tf1);
obj_create(AB_TYPE_CONTAINER, tf1);
container3= obj_find_by_name(module, container3Name);
check_find(container3);
obj_create(AB_TYPE_LIST, container3);
container5= obj_create(AB_TYPE_CONTAINER, container3);
slider1= obj_create(AB_TYPE_SLIDER, container5);
list4= obj_find_by_name(slider1, list4Name);
check_find(list4);
obj_create(AB_TYPE_ITEM, list4);
list1= obj_find_by_name(module, list1Name);
check_find(list1);
obj_create(AB_TYPE_TEXT_FIELD, list1);
list2= obj_find_by_name(module, list2Name);
check_find(list2);
list5= obj_create(AB_TYPE_LIST, list2);
item3= obj_create(AB_TYPE_ITEM, list2);
container6= obj_find_by_name(list5, container6Name);
check_find(container6);
button1= obj_create(AB_TYPE_BUTTON, container6);
return 0;
}
static int typeCounts[AB_OBJECT_TYPE_NUM_VALUES];
static BOOL typeCountsInited= FALSE;
static int
set_next_name_number(int number)
{
int i;
typeCountsInited= TRUE;
for (i= 0; i < AB_OBJECT_TYPE_NUM_VALUES; ++i)
{
typeCounts[i]= number-1;
}
return 0;
}
static STRING
safe_obj_name(ABObj obj)
{
if (obj == NULL)
{
return "NULL";
}
return util_strsafe(obj_get_name(obj));
}
static int
set_name(ABObj obj)
{
char name[256];
if (!typeCountsInited)
{
int i;
typeCountsInited= TRUE;
for (i= 0; i < AB_OBJECT_TYPE_NUM_VALUES; ++i)
{
typeCounts[i]= 0;
}
}
++(typeCounts[obj->type]);
sprintf(name, "%s%d",
util_object_type_to_string(obj->type)+1, typeCounts[obj->type]);
obj_set_name(obj, name); ++renameCount;
return 0;
}
/*************************************************************************
** **
** CREATE CALLBACKS **
** **
*************************************************************************/
static int
rename_obj_create_callback(ObjEvCreateInfo info)
{
static int objNum= 0;
/* printf("rename_obj_create_callback (objNum:%d)\n", objNum); */
set_name(info->obj);
/* printf("rename_obj_create_callback (EXIT)\n"); */
return OK;
}
static int
composite_obj_create_callback(ObjEvCreateInfo info)
{
ABObj obj= info->obj;
if (obj_has_flag(obj, XmConfiguredFlag))
{
return OK;
}
if (obj_is_module(obj))
{
composite_create_module(obj);
}
else if (obj_is_list(obj))
{
composite_create_list(obj);
}
else if (obj_is_slider(obj))
{
composite_create_slider(obj);
}
obj_set_flag(obj, XmConfiguredFlag);
return OK;
}
static int
composite_create_module(ABObj module)
{
static int module_number= 0;
int iReturn= 0;
ABObj tf1= NULL;
ABObj tf2= NULL;
ABObj list1= NULL;
ABObj list2= NULL;
ABObj cont1= NULL;
ABObj cont2= NULL;
ABObj cont3= NULL;
module->part_of= module;
obj_set_flag(module, XmConfiguredFlag);
tf1= obj_create(AB_TYPE_TEXT_FIELD, module);
tf1->part_of= module;
obj_set_flag(tf1, XmConfiguredFlag);
list1= obj_create(AB_TYPE_LIST, module);
list1->part_of= module;
obj_set_flag(list1, XmConfiguredFlag);
cont1= obj_create(AB_TYPE_CONTAINER, list1);
cont1->part_of= module;
obj_set_flag(cont1, XmConfiguredFlag);
cont2= obj_create(AB_TYPE_CONTAINER, cont1);
cont2->part_of= module;
obj_set_flag(cont2, XmConfiguredFlag);
tf2= obj_create(AB_TYPE_TEXT_FIELD, cont2);
tf2->part_of= module;
obj_set_flag(tf2, XmConfiguredFlag);
cont3= obj_create(AB_TYPE_CONTAINER, list1);
cont3->part_of= module;
obj_set_flag(cont3, XmConfiguredFlag);
list2= obj_create(AB_TYPE_LIST, module);
list2->part_of= module;
obj_set_flag(list2, XmConfiguredFlag);
return iReturn;
}
static int
composite_create_list(ABObj list)
{
ABObj parent= obj_get_parent(list);
if ((parent != NULL) && obj_is_list(parent))
{
ABObj obj= NULL;
list->part_of= list; /* composite root */
obj= obj_create(AB_TYPE_CONTAINER, list);
obj->part_of= list;
}
else
{
/* atomic */
}
obj_set_flag(list, XmConfiguredFlag);
return 0;
}
static int
composite_create_slider(ABObj slider)
{
ABObj obj= NULL;
slider->part_of= slider;
obj= obj_create(AB_TYPE_LIST, slider);
obj->part_of= slider;
obj_set_flag(obj, XmConfiguredFlag);
obj= obj_create(AB_TYPE_ITEM, slider);
obj->part_of= slider;
obj_set_flag(obj, XmConfiguredFlag);
return 0;
}
/*
* "module 2" watches object creations and deletions, and keeps a list
* of all extant objects
*/
static int
mod2_obj_create_callback(ObjEvCreateInfo info)
{
/* printf("mod2_obj_create_callback\n"); */
allObjectsArray[allObjectsArrayCount]= info->obj;
++allObjectsArrayCount;
/* printf("mod2_obj_create_callback (EXIT)\n"); */
return OK;
}
/*************************************************************************
** **
** RENAME CALLBACKS **
** **
*************************************************************************/
static int
rename_callback1(ObjEvAttChangeInfo info)
{
ABObj obj= info->obj;
if (info->atts != OBJEV_ATT_NAME)
{
err_exit("bad att flag");
}
++renameEventCount;
return 0;
}
/*************************************************************************
** **
** REPARENT CALLBACKS **
** **
*************************************************************************/
/*
* Won't allow modules to be reparented
*/
static int
allow_reparent_callback1(ObjEvAllowReparentInfo info)
{
int iReturn= OK;
ABObj obj= info->obj;
if (obj_is_module(info->obj))
{
iReturn= ERR_NOT_ALLOWED;
}
/* printf("allow_reparent_callback1(%s: %s -> %s) -> %d\n",
safe_obj_name(obj),
safe_obj_name(obj->parent),
safe_obj_name(info->parent),
iReturn); */
return iReturn;
}
static int
reparent_count_callback(ObjEvReparentInfo info)
{
info->obj= info->obj;
++reparentEventCount;
return OK;
}
static int
reparent_callback1(ObjEvReparentInfo info)
{
int iReturn= 0;
ABObj obj= info->obj;
/* printf("reparent_callback1(%s: %s -> %s) -> %d\n",
safe_obj_name(obj),
safe_obj_name(info->parent),
safe_obj_name(obj->parent),
iReturn); */
return iReturn;
}
/*************************************************************************
** **
** SELECT CALLBACKS **
** **
*************************************************************************/
static int
count_select_callback(ObjEvAttChangeInfo info)
{
/* printf("count_select_callback(%s,%d)\n",
safe_obj_name(info->obj), info->obj->selected); */
if (info->atts != OBJEV_ATT_SELECTED)
{
err_exit("bad att flag");
}
++renameEventCount;
if (obj_is_selected(info->obj))
{
++selectEventCount;
}
else
{
++unselectEventCount;
}
return 0;
}
/*
* Selects all the subobjects of an object
*/
static int
composite_select_callback(ObjEvAttChangeInfo info)
{
AB_TRAVERSAL trav;
ABObj curObj= NULL;
ABObj obj= info->obj;
BOOL selected= obj_is_selected(obj);
/* printf("composite_select_callback(%s,%d)\n",
safe_obj_name(info->obj), info->obj->selected); */
if (info->atts != OBJEV_ATT_SELECTED)
{
err_exit("bad att flag");
}
for (trav_open(&trav, obj, AB_TRAV_ALL);
(curObj= trav_next(&trav)) != NULL; )
{
if (curObj->part_of == obj)
{
if (selected)
{
obj_select(curObj);
}
else
{
obj_unselect(curObj);
}
}
}
trav_close(&trav);
return 0;
}
/*
* Clears the previous selection.
* SHOULD BE THE FIRST CALLBACK!
*/
static int
exclusive_select_callback(ObjEvAttChangeInfo info)
{
static ABObj currentSelection= NULL;
AB_TRAVERSAL trav;
ABObj curObj= NULL;
ABObj obj= info->obj;
ABObj project= obj_get_project(obj);
/* printf("exclusive_select_callback(%s, %d)\n",
safe_obj_name(info->obj), info->obj->selected); */
if (info->atts != OBJEV_ATT_SELECTED)
{
err_exit("bad att flag");
}
if (!obj_is_selected(obj))
{
return OK;
}
if ((currentSelection == obj) || (currentSelection == obj->part_of))
{
return OK;
}
if (obj_is_root(obj))
{
currentSelection= obj;
}
else
{
currentSelection= obj->part_of;
}
/*
* Kill the old selection
*/
for (trav_open(&trav, project, AB_TRAV_ALL | AB_TRAV_MOD_PARENTS_FIRST);
(curObj= trav_next(&trav)) != NULL; )
{
if ((curObj != currentSelection) &&
(curObj->part_of != currentSelection))
{
obj_unselect(curObj);
}
}
trav_next(&trav);
return 0;
}
/*************************************************************************
** **
** GEOMETRY CALLBACKS **
** **
*************************************************************************/
/*
* tries to reparent an object from within an allow callback. Not allowed!
*/
static int
bogus_geometry_allow_callback(ObjEvAllowGeometryChangeInfo info)
{
if (info->new_x == 1000)
{
ABObj project= obj_get_project(info->obj);
ABObj module = obj_get_module(info->obj);
ABObj item3= obj_find_by_name(module, "item103");
ABObj module1= obj_find_module_by_name(project, "module1");
check_find(item3);
check_find(module1);
/*
* Test should be OK, actual move should cause an error
*/
if (obj_test_reparent(item3, module1) < 0)
{
err_exit("Legal reparent query DISallowed.");
}
if (obj_reparent(item3, module1) >= 0)
{
err_exit("Illegal reparent allowed");
}
printf("bogus move disallowed in allow callback (correct).\n");
}
return OK;
}
/*
* doesn't allow gemetry change for composite subobjects
*/
static int
composite_geometry_allow_callback(ObjEvAllowGeometryChangeInfo info)
{
if (obj_is_sub(info->obj))
{
return ERR_NOT_ALLOWED;
}
return OK;
}
/*
* only allows resizes where width = height
*/
static int
symmetric_geometry_allow_callback(ObjEvAllowGeometryChangeInfo info)
{
if (info->new_width != info->new_height)
{
return ERR_NOT_ALLOWED;
}
return OK;
}
/*
* Moves x,y to be multiples of 10
*/
static int
grid_geometry_callback(ObjEvAttChangeInfo info)
{
ABObj obj= info->obj;
int gridX= 0;
int gridY= 0;
if (info->atts != OBJEV_ATT_GEOMETRY)
{
err_exit("bad att flag");
}
gridX= obj->x + (obj->x % 10);
gridY= obj->x + (obj->y % 10);
return obj_move(obj, gridX, gridY);
}
/*************************************************************************
** **
** DESTROY CALLBACKS **
** **
*************************************************************************/
/*
* If the root of a composite object is destroyed, all of its composite
* subobjects are destroyed.
*/
static int
composite_destroy_callback(ObjEvDestroyInfo info)
{
ABObj obj= info->obj;
AB_TRAVERSAL trav;
ABObj subobj= NULL;
if (!obj_is_root(obj))
{
return OK;
}
for (trav_open(&trav, obj, AB_TRAV_ALL | AB_TRAV_MOD_SAFE);
(subobj= trav_next(&trav)) != NULL; )
{
if (subobj->part_of == obj)
{
obj_destroy_one(subobj);
}
}
trav_close(&trav);
return 0;
}
/*
* Just counts events...
*/
static int
count_destroy_callback(ObjEvDestroyInfo info)
{
++destroyEventCount;
return OK;
}
/*************************************************************************
** **
** UPDATE CALLBACKS **
** **
*************************************************************************/
static int
count_update_callback(ObjEvUpdateInfo info)
{
if (info->update_subtree)
{
++updateTreeEventCount;
}
else
{
++updateEventCount;
}
return OK;
}
static int
composite_update_callback(ObjEvUpdateInfo info)
{
AB_TRAVERSAL trav;
ABObj obj= info->obj;
ABObj subobj= NULL;
if (!obj_is_root(obj))
{
return OK;
}
for (trav_open(&trav, obj, AB_TRAV_ALL);
(subobj= trav_next(&trav)) != NULL; )
{
if ((subobj != obj) && (subobj->part_of == obj))
{
obj_update_clients(subobj);
}
}
trav_close(&trav);
return OK;
}
static int
count_update_with_data_callback(ObjEvUpdateWithDataInfo info)
{
++updateEventCount;
return OK;
}
static int
composite_update_with_data_callback(ObjEvUpdateWithDataInfo info)
{
ABObj obj= info->obj;
AB_TRAVERSAL trav;
ABObj subobj= NULL;
if (!obj_is_root(obj))
{
return OK;
}
for (trav_open(&trav, obj, AB_TRAV_ALL);
(subobj= trav_next(&trav)) != NULL; )
{
if ((subobj != obj) && (subobj->part_of == obj))
{
obj_update_clients_with_data(subobj,
info->update_code,
info->update_data,
info->update_data_free_func);
}
}
trav_close(&trav);
return 0;
}
static int
free_update_data(int update_code, void *void_update_data)
{
UPDATE_DATA *update_data= (UpdateData)void_update_data;
printf("freeing %s\n", update_data->text);
++(update_data->free_count);
return 0;
}