01f522 BDE 1 Project:
Adding an X11 Event Logging Table Type to BDE’s Schema
Presented by: Paul Kingston
Date: December 19, 2001
Instructor: Dr. Lechner
Fall Semester 2001
Project files: /usr/proj3/case/01f522/bde1_bdeEventlog_pk
Table of Contents
Introduction 3
Project Plan 4
Implementation 7
Schema File Revisions 7
Source Code Revisions 8
Build Notes 9
Testing 9
Conclusion 9
Appendix A – Build Log 10
Appendix B – Sample Test Matrix 13
Introduction
The purpose of this project is to modify BDE to enable logging of X11 events. More specifically, the proposed modifications are to allow for the capturing of canvas drawing behavior at the state box level. This information can be useful in BDE revision testing and debugging. Furthermore, this can also be useful in distributing X11 events for a future multi-user version of BDE.
Currently the only events which need logging are button events, or events that are generated by the mouse buttons. More specifically, these include both the BUTTON_DOWN and BUTTON_UP events. In addition to the event type, the program needs to store which mouse button triggered the event (left, center, right), as well as the x and y coordinates of the mouse cursor when the event took place.
Project Plan
It is important to note at the onset that this project is not intended to perform a complete re-architecture of BDE. Such a redesign is beyond the scope of this project. Rather, the purpose of this project is to take steps in that direction by introducing logging of X11 events into the current application architecture.
The purpose of this project, as previously stated, is to "enable event logging". However this label is somewhat misleading. BDE already has a logging feature, which when configured correctly will record all table row additions to any table in its data model to a log file. This means that BDE already has the ability to generate a log file. The real purpose of this project then is to enable the creation of rows in a new "Event" table representing X11 events as they occur. This project will then let BDE’s logging features automatically output these new rows in the Event table to a log file.
The changes needed to enable X11 event logging fall into two categories: 1) update BDE’s data model to include an Event table which will store X11 events, and 2) update BDE’s source code files to capture, decode and record X11 events. The first category can be satisfied by updating BDE’s schema file, "94sbde_schema.sch" to include an EventInstance(EI) table and an EventType(ET) table, which will hold all required information about X11 events. The second category can be satisfied by introducing new code to create specific event types in the ET table, and also create new rows in the EI table when button events are encountered. These are both described in more detail below.
In an attempt to standardize data models between applications, the EventInstance(EI) and EventType(ET) tables to be included will be modeled after the tables of the same name in the JPSim project (/usr/proj3/case/01f522/lcp3/JPsim). However the use of these two tables present certain challenges, since they include foreign keys to other tables which are currently not used in BDE. Here are the JPSim ET and EI tables:
EventType ET /* EventType */
{
ETid EventTypeId c8 1 /* the primary key */
SMid EventTypesReceiver c8 1 /* the state machine which */
/* receives this event */
Label EventTypesLabel t8 0 /* the label for the event */
Descrip EventTypesDescription t80 0 /* a fuller description */
}
EventInstance EI /* An EventInstance */
{
EIid EventInstanceId c8 1 /* the primary key */
AIid1 EventInstanceGenerater c8 1 /* the active instance which */
/* generated this event */
AIid2 EventInstanceReceiver c8 1 /* the active instance which */
/* will receive this event */
ETid EventInstancesType c8 1 /* the type of this event */
Int1 EventInstanceDataInt1 i4 0 /* the first piece of int data */
Int2 EventInstanceDataInt2 i4 0 /* the second piece of int data */
Flt1 EventInstanceDataDbl1 f8 0 /* the first piece of float data */
Flt2 EventInstanceDataDbl2 f8 0 /* the second piece of float data */
Text EventInstanceDataText t80 0 /* textual data */
}
In the above implementation of the ET and EI tables, there are foreign keys to tables AI and SM. Neither of these additional tables is currently included in BDE’s schema file. To address this, the amended BDE schema file must include definitions of all tables directly or indirectly referenced by foreign keys from the ET and EI tables. However, attempting to use these additional tables properly would involve a redesign of BDE that, as mentioned above, is beyond the scope of this project. So although these additional tables will be included in BDE’s schema file, then will never actually be used. Rather, these tables will be included simply as placeholders so that that ET and EI tables can be used.
An approach that could also have been taken would be to add the ET and EI tables but omit the foreign keys to the unused tables. But for the purposes of ensuring compatibility with future versions of BDE, this is undesirable. Therefore instead of editing the ET and EI tables to remove these three foreign keys (AIid1, AIid2 and SMid), the table definition will remain unchanged but the values stored in these fields for any row entry within these tables will always be NULL. This is a valid approach since in the current version the AIid1, or ActiveInstance generator will always be the X11 subsystem, and both the AIid2 (ActiveInstance receiver) and SMid (EventTypesReceiver) will always be BDE’s dobuttonevent() function. In the future, as BDE’s architecture changes to make use of this standardized data model, the changes introduced by this project can easily be modified to correctly populate these unused fields.
The final step in preparing BDE’s data model is to determine where each piece of information extracted from X11 events will be stored in the EI and ET tables. The x and y coordinates of the mouse cursor are integers whose values will vary based on screen dimensions. But these will typically not exceed 1600 for x and 1200 for y. The logical storage place for them then is within the Int1 and Int2 fields of the EI table. The type of mouse event which occurred will take the value of either "BUTTON_UP" or "BUTTON_DOWN". Since this data represents an event type, each value will be given its own row in the ET table which can then be referenced by EI table rows. The particular mouse button which triggered the event will be a label representing "right", "left" or "middle". The logical storage place for these labels then is within the Text field of the EI table (Note: another possibility is to assign each mouse button an ascending number label from left to right and store this value in one of the integer fields in the EI table. However, the EI table has only two integer fields, and it seems more important to keep the x and y coordinate values together).
Source code changes need to be made in two locations. First, code needs to be written which creates new rows in the ET table during program initialization representing the event types which are to be logged. As mentioned in the previous section, there are two event types – BUTTON_UP and BUTTON_DOWN. Therefore two rows representing these types will need to be created.
Second, new code needs to be placed into the X11 callback function "dobuttonevent()" which is called in response to a mouse event. This code will create a new row in the EI table and within it store the required information concerning the mouse event. As mentioned in the previous section, this information will include the button which triggered the event, the x and y coordinates of the mouse cursor when the event took place and the foreign key representing the event type in the ET table. All of this information is located within the XButtonEvent structure which is passed to the dobuttonevent() function. All that’s required then is to extract the needed information from the XButtonEvent structure and create a representative new row in the EI table.
Implementation
Schema File Revisions:
The following additions were made to BDE’s schema file, 94sbde_schema.sch:
/***********BEGIN UNUSED TABLES**********************/
StateModel SM /* The State model. */
{
SMid StateModelId c8 1 /* the primary key */
Abbrev AbbreviatedName c4 0 /* the short version of the name */
Name StateModelName t80 0 /* it's name */
}
ActiveClass AC /* Table of Active Classes */
{
ACid ActiveClassId c8 1 /* the primary key */
SMid ActiveClassesStateModel c8 1 /* the state model for this class */
Name ActiveClassName t80 0 /* the name of the Active Class */
}
ActiveInstance AI /* Active Instance */
{
AIid ActiveInstanceId c8 1 /* the primary key */
ACid ActiveInstanceInThisClass c8 1 /* the active class of this AI */
State ActiveInstancesCurrentState t80 0 /* Name of current state */
Name ActiveInstanceName t80 0 /* full name - useful for debugging*/
}
/*************END UNUSED TABLES************************/
EventType ET /* EventType */
{
ETid EventTypeId c8 1 /* the primary key */
SMid EventTypesReceiver c8 1 /* NULL-SM table not yet implemented*/
Label EventTypesLabel t8 0 /* the event type name of this event */
Descrip EventTypesDescription t80 0 /* description of event's purpose and */
/* meaning */
}
EventInstance EI /* An EventInstance */
{
EIid EventInstanceId c8 1 /* the primary key */
AIid1 EventInstanceGenerater c8 1 /* NULL-AI table not yet implemented*/
AIid2 EventInstanceReceiver c8 1 /* NULL-AI table not yet implemented*/
ETid EventInstancesType c8 1 /* foreign key to EventType table */
Int1 EventInstanceDataInt1 i4 0 /* x-coordinate */
Int2 EventInstanceDataInt2 i4 0 /* y-coordinate */
Flt1 EventInstanceDataDbl1 f8 0 /* the thhird (float) argument */
Flt2 EventInstanceDataDbl2 f8 0 /* the fourth (float) argument */
Text EventInstanceDataText t80 0 /* button label */
}
Note that in order to utilize the standard JPSim-like EI and ET tables, it was necessary to add 3 other tables: StateModel(SM), ActiveClass(AC) and ActiveInstance(AI). These extra tables are required since there are foreign keys in the EI and ET tables which reference them. These extra tables will not be directly used by BDE, but are needed to avoid CHGEN errors.
Source Code Revisions:
Initialization of the ET table is performed within the bde.cc file. Within this file, the required lines of code were added in the main() function. Specifically lines 103 through 121 in the file were added. This new code adds two rows to the ET table representing the "BUTTON_DOWN" and "BUTTON_UP" events.
Logging of events as they occur is performed within the buttonevent.cc file. Within this file, the required lines were added in the dobuttonevent() function. Specifically lines 169 through 213 in the file were added. These lines parse the XButtonEvent structure passed to the function and extract data representing the button pressed, event type (BUTTON_UP, BUTTON_DOWN) and which mouse button was pressed. Then a new EI table row is created and populated with the values extracted from the XButtonEvent structure.
Build Notes
Despite repeated attempts, I was never able to successfully build even a base version of BDE. Therefore any attempt to build BDE after this projects’ changes were implemented would likewise have been unsuccessful. A complete build log showing the errors received while building a base version of BDE are listed in Appendix A.
The logic of this project’s changes is very straightforward, and the code additions are minimal. Therefore once the build errors could be taken care of and this project’s additions implemented, I am confident that after some minor debugging the resulting BDE would perform the new event logging feature as designed.
Testing
Since the build process was unsuccessful, a version was unavailable for test as of this writing. However the testing of the new event logging feature can be done manually and requires only the BDE executable. All that’s required is to run BDE and use the mouse to introduce new mouse events within the application window. The resulting log file then needs to be inspected to verify the entries represent the right values for the created rows within the EI table. A sample test matrix is given in Appendix B.
Conclusion
This project has taken the first steps in migrating BDE from its legacy data model to the more modern data model employed by JPSim. With the changes proposed within this project successfully implemented, future developers of BDE will have a new tool for debugging future revisions of BDE. Furthermore they will have a proven X11 event integration into the data model should BDE evolve into a multi-user application and require distributing mouse events.
Appendix A – Build Log
saturn.cs.uml.edu> xmkmf -a
mv -f Makefile Makefile.bak
imake -DUseInstalled -I/usr/lib/X11/config
make Makefiles
making Makefiles in pr_util...
mv -f Makefile Makefile.bak
making Makefiles in src...
mv -f Makefile Makefile.bak
make includes
including in ./pr_util...
including in ./src...
make depend
depending in ./pr_util...
makedepend -- -I/usr/include -I../include -I../pr_util -I/usr/include -I../inc
lude -DLONG_BIT=64 --
depending in ./src...
makedepend -- -I/usr/include -I../include -I../pr_util -I/usr/local/lib/g++-in
clude -I/usr/include -I../include -DLONG_BIT=64 -- bde.cc
bendpt.cc bendptops.cc buttonevent.cc
captionops.cc cursor.cc dialog.cc display
.cc draw.cc edit.cc fileio.cc
font.cc fprint.cc graphobject.cc
graphops.cc handler.cc help.cc
hlink.cc infodialog.cc infomessage.cc in
it.cc initClasses.cc leftmenu.cc leftmen
u_cb.cc linkops.cc menubar.cc menubar_cb.c
c msgBox.cc nodeops.cc select.cc
smselect.cc strdup.cc text.cc
textops.cc
"bendpt.cc":752: 0 // maushah 05/15/00
^--- expecting variable or number
"dialog.cc":7: 0 // Let's not bother with this just yet.
^--- expecting variable or number
"dialog.cc":20: 0 // Let's not bother with this just yet.
^--- expecting variable or number
"fileio.cc":2080: 0 // 99s523 rgantyal, vdhamo
da
^--- expecting variable o
r number
"select.cc":104: 0 // maushah 05/15/00
^--- expecting variable or number
"textops.cc":617: 0 // maushah 05/15/00 <--- WHY omit next 3 lines? - RJ
L 2k0901
^--- expecting variable or number
saturn.cs.uml.edu> make
making all in ./pr_util...
gcc -g -c -Wall pr_load.c pr_free.c pr_dump.c pr_delete.c
pr_log.c pr_stats.c
pr_load.c:611: warning: `/*' within comment
pr_load.c:2100: `#' operator should be followed by a macro argument name
pr_load.c:2118: `#' operator is not followed by a macro argument name
pr_load.c:2118: `#' operator is not followed by a macro argument name
pr_load.c:2118: `#' operator is not followed by a macro argument name
pr_load.c:2118: `#' operator is not followed by a macro argument name
pr_load.c:2131: `#' operator is not followed by a macro argument name
pr_load.c:2131: `#' operator is not followed by a macro argument name
In file included from pr_free.c:8:
94sbde_schema.h:292: parse error before `key_value'
94sbde_schema.h:292: warning: type defaults to `int' in declaration of `key_value'
94sbde_schema.h:292: warning: data definition has no type or storage class
94sbde_schema.h:333: undefined or invalid # directive
pr_free.c: In function `pr_free':
pr_free.c:32: warning: implicit declaration of function `logwait'
pr_free.c:33: warning: implicit declaration of function `logstr'
pr_free.c:34: warning: implicit declaration of function `free'
pr_free.c:31: warning: unused variable `rcsid'
pr_free.c: At top level:
94sbde_schema.h:1110: warning: `hcg_tbl_abbr' defined but not used
In file included from pr_dump.c:8:
94sbde_schema.h:292: parse error before `key_value'
94sbde_schema.h:292: warning: type defaults to `int' in declaration of `key_value'
94sbde_schema.h:292: warning: data definition has no type or storage class
94sbde_schema.h:333: undefined or invalid # directive
pr_dump.c: In function `pr_dump':
pr_dump.c:34: warning: implicit declaration of function `find_view_idx'
pr_dump.c:45: warning: array subscript has type `char'
pr_dump.c:47: warning: implicit declaration of function `lut_insert_element'
pr_dump.c:50: warning: implicit declaration of function `meets_view'
pr_dump.c:26: warning: unused variable `outkey'
pr_dump.c:25: warning: unused variable `rcsid'
pr_dump.c: In function `dump_row':
pr_dump.c:164: warning: implicit declaration of function `hcg_update_version'
pr_dump.c: At top level:
94sbde_schema.h:1110: warning: `hcg_tbl_abbr' defined but not used
In file included from pr_delete.c:8:
94sbde_schema.h:292: parse error before `key_value'
94sbde_schema.h:292: warning: type defaults to `int' in declaration of `key_value'
94sbde_schema.h:292: warning: data definition has no type or storage class
94sbde_schema.h:333: undefined or invalid # directive
pr_delete.c: In function `pr_del':
pr_delete.c:127: warning: implicit declaration of function `logwait'
pr_delete.c:129: warning: implicit declaration of function `lut_insert_element'
pr_delete.c:136: warning: implicit declaration of function `pr_del_bt'
pr_delete.c:136: warning: implicit declaration of function `free'
pr_delete.c:141: warning: implicit declaration of function `logstr'
pr_delete.c:123: warning: unused variable `rcsid'
pr_delete.c: At top level:
pr_delete.c:296: warning: return-type defaults to `int'
pr_delete.c: In function `pr_del_bt':
pr_delete.c:300: warning: unused variable `result'
pr_delete.c:299: warning: unused variable `finish'
pr_delete.c:307: warning: control reaches end of non-void function
pr_delete.c: At top level:
94sbde_schema.h:1110: warning: `hcg_tbl_abbr' defined but not used
pr_log.c:1758: warning: `/*' within comment
pr_log.c:1759: warning: `/*' within comment
pr_log.c:1760: warning: `/*' within comment
pr_log.c:1761: warning: `/*' within comment
In file included from pr_log.c:12:
94sbde_schema.h:292: parse error before `key_value'
94sbde_schema.h:292: warning: type defaults to `int' in declaration of `key_value'
94sbde_schema.h:292: warning: data definition has no type or storage class
94sbde_schema.h:333: undefined or invalid # directive
pr_log.c: In function `log_sleep':
pr_log.c:71: warning: implicit declaration of function `usleep'
pr_log.c:76: warning: format argument is not a pointer (arg 3)
pr_log.c:76: warning: too few arguments for format
pr_log.c: In function `timeval2millisec':
pr_log.c:311: warning: control reaches end of non-void function
pr_log.c: In function `logwait':
pr_log.c:355: warning: too few arguments for format
pr_log.c: In function `pr_startlog':
pr_log.c:398: warning: implicit declaration of function `find_view_idx'
pr_log.c:444: warning: implicit declaration of function `pr_dump'
pr_log.c:382: warning: unused variable `rcsid'
pr_log.c: In function `log_parselogdata':
pr_log.c:558: warning: implicit declaration of function `hcg_read_next'
pr_log.c:560: warning: implicit declaration of function `hcg_parse'
pr_log.c:569: warning: embedded `\0' in format
pr_log.c: In function `del_tempfiles':
pr_log.c:613: warning: implicit declaration of function `unlink'
pr_log.c: In function `log_do_add':
pr_log.c:665: warning: implicit declaration of function `find_tbl_idx'
pr_log.c:673: warning: implicit declaration of function `lut_insert_element'
pr_log.c:693: warning: implicit declaration of function `pr_add'
pr_log.c:771: warning: int format, different type arg (arg 5)
pr_log.c:773: warning: int format, different type arg (arg 5)
pr_log.c:796: warning: int format, different type arg (arg 5)
pr_log.c:798: warning: int format, different type arg (arg 5)
pr_log.c:818: warning: int format, different type arg (arg 5)
pr_log.c:820: warning: int format, different type arg (arg 5)
pr_log.c:838: warning: int format, different type arg (arg 5)
pr_log.c:861: warning: int format, different type arg (arg 5)
pr_log.c:863: warning: int format, different type arg (arg 5)
pr_log.c:910: warning: int format, different type arg (arg 5)
pr_log.c:912: warning: int format, different type arg (arg 5)
pr_log.c:642: warning: unused variable `tablename_size'
pr_log.c:641: warning: unused variable `pkey'
pr_log.c:639: warning: unused variable `status'
pr_log.c:918: warning: control reaches end of non-void function
pr_log.c: In function `convert2temp':
pr_log.c:950: warning: embedded `\0' in format
pr_log.c:956: warning: embedded `\0' in format
pr_log.c: In function `log_do_delete':
pr_log.c:992: warning: implicit declaration of function `pr_del'
pr_log.c: In function `log_do_set_int':
pr_log.c:1090: warning: unused variable `fld_encoding'
pr_log.c: In function `log_do_set_flt':
pr_log.c:1232: warning: unused variable `fld_encoding'
pr_log.c: In function `log_do_set_key':
pr_log.c:1415: warning: unused variable `fld_encoding'
pr_log.c: In function `log_do_set_str':
pr_log.c:1581: warning: unused variable `fld_encoding'
pr_log.c: In function `replay_log':
pr_log.c:1810: warning: embedded `\0' in format
pr_log.c:1814: warning: implicit declaration of function `pr_load'
pr_log.c:1865: warning: implicit declaration of function `pr_init'
pr_log.c:1935: warning: implicit declaration of function `pr_free'
pr_log.c:1953: warning: unused variable `tbl_encoding'
pr_log.c: In function `pr_replay':
pr_log.c:2046: warning: embedded `\0' in format
pr_log.c:2012: warning: unused variable `log_fp'
pr_log.c: At top level:
94sbde_schema.h:1110: warning: `hcg_tbl_abbr' defined but not used
In file included from pr_stats.c:8:
94sbde_schema.h:292: parse error before `key_value'
94sbde_schema.h:292: warning: type defaults to `int' in declaration of `key_value'
94sbde_schema.h:292: warning: data definition has no type or storage class
94sbde_schema.h:333: undefined or invalid # directive
pr_stats.c: In function `pr_stats':
pr_stats.c:35: warning: int format, different type arg (arg 4)
pr_stats.c:52: warning: int format, different type arg (arg 4)
pr_stats.c:58: warning: implicit declaration of function `lut_insert_element'
pr_stats.c:18: warning: unused variable `rcsid'
pr_stats.c: At top level:
94sbde_schema.h:1110: warning: `hcg_tbl_abbr' defined but not used
*** Exit 1
Stop.
*** Exit 1
Stop.
saturn.cs.uml.edu>
Appendix B – Sample Test Matrix
Test number Mouse position Button pressed Test Results
1 top left of BDE screen left
2 top right of BDE screen middle
3 center of BDE screen right
4 bottom left of BDE screen left
5 bottom right of BDE screen middle