Well, its been a while since my last message (I just recently checked and I see
that the message window overlap that I reported (long ago) has been fixed.
THANKS !). I've been busy doing other projects and I'm just now getting back
to this one. This is actually the last problem I encountered before stopping
work on this project and I first noticed it in OTK 0.75. I just rechecked it
and I am seeing the problem in 0.87. I'm getting segmentation faults when
using the close "X" on the message window with a registered kill window
callback function when the pointer parameter I pass to it is dereferenced as
shown in the print out and code below. I could have multiple message windows
open (some without user intervention) so I use the MessageWindow structure to
store information that allows the code that opened the window to see if any
push button action has taken place, and for the push button callback handlers
or the code that opened the window to close the correct window when needed. It
is also used to prevent the same message window from being opened more than
once. I've traced around to see what was happening and this is what happens
when I run it and use the window close "X":
As you can see, everything looks good until it enters the kill window callback
handler and then the MessageWindow pointer is different. I might be missing
something, but I don't think so.
Once again, if you could look into this it will be greatly appreciated. Thanks.
// *****************************************************************************
// *
// * Structure used to pass information between the message window handler and
// * the function that opened the window.
// *
// *****************************************************************************
struct MessageWindow
{
bool wait_flag ; // Wait for a message window push button press flag
int pb_pressed ; // Which push button was pressed in the message window
OtkWidget OtkW_window ; // Otk widget for opened message window
} ;
typedef struct MessageWindow *MesgWin ;
// *****************************************************************************
// *
// * Description: Message window close "X" pushed handler
// *
// * Parameters: mw_p - pointer to MessageWindow structure for window with
// *
// *
// * Notes:
// *
// *****************************************************************************
if (mesg_win_p != NULL)
{
mesg_win_p->wait_flag = false ; // Clear wait for button push flag
mesg_win_p->pb_pressed = KILL_PB ; // Kill window button pushed
mesg_win_p->OtkW_window = NULL ; // Window no longer in use
}
}
// *****************************************************************************
// *
// * Description: This opens a message window on top of all existing windows
// * an prints the selected message.
// *
// * Parameters: mesg_class - selects which class of messages the message
// * belongs to
// * mesg_number - selects which message in the message class to
// * print
// * param_1 - pointer to first data to display when needed
// * param_2 - pointer to second data to display when needed
// *
// * Returns: pointer to MessageWindow structure for opened window
// *
// *****************************************************************************
P.S. FYI, I am developing a fairly sophisticated demonstration program for some
hardware that I designed that communicates over a USB "serial interface"
or regular serial port. This involves low level I/O so I am doing a good
deal of error checking during debugging and this can open error message
windows. The hardware uses a simple protocol of sending a command, and
waiting for a response (or timeout) with data that will be displayed
using one of the OTK gadgets and text for multiple sensors each with
their own window that is updated at a maximum rate of once per second.
A higher level protocol automatically retries on non-critical errors.
Either of these can open protocol error messages. Plus, there are several
main window pull down menu bars that can generate commands and responses
to display/modify hardware options and display hardware status. Eventually
I intend to block all but the critical error messages unless a debug mode
is enabled.
P.S.P.S On the main page of your on-line documentation this line:
The following are related functions: <a name="#anch7a">
works a lot better if it is changed to:
The following are related functions: <a name="anch7a">
I maintain an offline version of the on-line documentation if you or
anybody else is interested.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Well, its been a while since my last message (I just recently checked and I see
that the message window overlap that I reported (long ago) has been fixed.
THANKS !). I've been busy doing other projects and I'm just now getting back
to this one. This is actually the last problem I encountered before stopping
work on this project and I first noticed it in OTK 0.75. I just rechecked it
and I am seeing the problem in 0.87. I'm getting segmentation faults when
using the close "X" on the message window with a registered kill window
callback function when the pointer parameter I pass to it is dereferenced as
shown in the print out and code below. I could have multiple message windows
open (some without user intervention) so I use the MessageWindow structure to
store information that allows the code that opened the window to see if any
push button action has taken place, and for the push button callback handlers
or the code that opened the window to close the correct window when needed. It
is also used to prevent the same message window from being opened more than
once. I've traced around to see what was happening and this is what happens
when I run it and use the window close "X":
[gdstew@localhost PCTM_demo]$ ./PCTM_demo
Using OTK - V0.87
open_message_window() OtkWidget: 0x840ef68
Otk_RegisterWindowKillEventFunction() OtkWidget: 0x840ef68
Otk_RegisterWindowKillEventFunction() callback param: (nil)
open_message_window() OtkWidget: 0x83dcbe0
Otk_RegisterWindowKillEventFunction() OtkWidget: 0x83dcbe0
Otk_RegisterWindowKillEventFunction() callback param: 0x80774d0
display_command_err_message() MesgWin: 0x80774d0
display_command_err_message() OtkWidget: 0x83dcbe0
open_message_window(), command error MesgWin: 0x80774d0
kill_mesg_window() MesgWin: 0x804d170
kill_mesg_window() OtkWidget: 0x4c7085d
Segmentation fault
As you can see, everything looks good until it enters the kill window callback
handler and then the MessageWindow pointer is different. I might be missing
something, but I don't think so.
Once again, if you could look into this it will be greatly appreciated. Thanks.
// *****************************************************************************
// *
// * Structure used to pass information between the message window handler and
// * the function that opened the window.
// *
// *****************************************************************************
struct MessageWindow
{
bool wait_flag ; // Wait for a message window push button press flag
int pb_pressed ; // Which push button was pressed in the message window
OtkWidget OtkW_window ; // Otk widget for opened message window
} ;
typedef struct MessageWindow *MesgWin ;
// *****************************************************************************
// *
// * Description: Message window close "X" pushed handler
// *
// * Parameters: mw_p - pointer to MessageWindow structure for window with
// *
// *
// * Notes:
// *
// *****************************************************************************
static void kill_mesg_window(void *mw_p)
{
MesgWin mesg_win_p ;
mesg_win_p = (MesgWin) mw_p ;
#ifdef SEGFAULT_PROB
printf("\nkill_mesg_window() MesgWin: %p\n", mesg_win_p) ;
printf("kill_mesg_window() OtkWidget: %p\n\n", mesg_win_p->OtkW_window) ;
#endif // SEGFAULT_PROB
if (mesg_win_p != NULL)
{
mesg_win_p->wait_flag = false ; // Clear wait for button push flag
mesg_win_p->pb_pressed = KILL_PB ; // Kill window button pushed
mesg_win_p->OtkW_window = NULL ; // Window no longer in use
}
}
// *****************************************************************************
// *
// * Description: This opens a message window on top of all existing windows
// * an prints the selected message.
// *
// * Parameters: mesg_class - selects which class of messages the message
// * belongs to
// * mesg_number - selects which message in the message class to
// * print
// * param_1 - pointer to first data to display when needed
// * param_2 - pointer to second data to display when needed
// *
// * Returns: pointer to MessageWindow structure for opened window
// *
// *****************************************************************************
MesgWin open_message_window (int_32 mesg_class, int_32 mesg_number, void *param_1, void *param_2)
{
float y = 5.0 ;
OtkWidget mesg_win ;
static struct MessageWindow m_win ;
MesgWin mesg_win_p ;
mesg_win = OtkMakeWindow(Otk_Recessed, Otk_Blue, Otk_LightGray, 10.0, 10.0, 70.0, 85.0) ;
#ifdef SEGFAULT_PROB
printf("open_message_window() OtkWidget: %p\n", mesg_win) ;
#endif // SEGFAULT_PROB
Otk_Set_Text_Aspect(0.4);
switch (mesg_class)
{
case USAGE_MESG:
mesg_win_p = display_usage_message(mesg_win) ;
break ;
case DEVICE_INIT_MESG:
mesg_win_p = display_dev_init_err_message(mesg_win, mesg_number, (bool) param_1) ;
break ;
case DEVICE_IO_ERROR_MESG:
mesg_win_p = display_dev_io_err_message(mesg_win, mesg_number) ;
break ;
case COMMAND_ERROR_MESG:
mesg_win_p = display_command_err_message(mesg_win, mesg_number) ;
#ifdef SEGFAULT_PROB
printf("open_message_window(), command error MesgWin: %p\n", mesg_win_p) ;
#endif // SEGFAULT_PROB
break ;
case RESPONSE_ERROR_MESG:
mesg_win_p = display_response_err_message(mesg_win, mesg_number) ;
break ;
... More case statements and default
}
Otk_Set_Text_Aspect(1.0) ;
return (mesg_win_p) ;
}
// *****************************************************************************
// *
// * Description: Displays protocol level send command error messages
// *
// * Parameters: mw - pointer to OTK widget for this window
// * message_number - Selects which send command error message to
// * display
// *
// * Returns: pointer to MessageWindow structure for opened window
// *
// *****************************************************************************
static MesgWin display_command_err_message(OtkWidget mw, int_32 message_number)
{
float y = 5.0, dy = 12.0, dy1_5 = 15.0 ;
OtkWidget ok_pb1, ok_pb2, exit_pb ;
static struct MessageWindow m_win1, m_win2, m_win3, m_win4, m_win5 ;
switch (message_number)
{
case Q_FULL:
if (m_win1.OtkW_window == NULL)
{
m_win1.wait_flag = true ;
m_win1.pb_pressed = NO_PB ;
m_win1.OtkW_window = mw ;
Otk_RegisterWindowKillEventFunction(mw, kill_mesg_window, (void *) &m_win1) ;
}
else
{
Otk_RemoveObject(mw) ; // Free the unused message window Otk widget
return (NULL) ;
}
OtkMakeTextLabel(mw, "Command queue is full", Otk_Black, 3.0, 1.0, 4.0, y) ;
ok_pb1 = OtkMakeButton(mw, 40.0, 75.0, 20.0, 15.0, "", ok_pb_cb, (void *) &m_win1) ;
OtkMakeTextLabel(ok_pb1, "OK", Otk_Black, 3.0, 1.0, 30.0, 15.0) ;
return (&m_win1) ;
break ;
... More case statements
case PCTM_DISCONNECTED:
if (m_win4.OtkW_window == NULL)
{
m_win4.wait_flag = true ;
m_win4.pb_pressed = NO_PB ;
m_win4.OtkW_window = mw ;
Otk_RegisterWindowKillEventFunction(mw, kill_mesg_window, (void *) &m_win4) ;
}
else
{
Otk_RemoveObject(mw) ; // Free the unused message window Otk widget
return (NULL) ;
}
#ifdef SEGFAULT_PROB
printf("display_command_err_message() MesgWin: %p\n", &m_win4) ;
printf("display_command_err_message() OtkWidget: %p\n\n", mw) ;
#endif // SEGFAULT_PROB
OtkMakeTextLabel(mw, "Attempting to connect to the", Otk_Black, 3.0, 1.0, 4.0, y) ;
y = y + dy ;
OtkMakeTextLabel(mw, " PCTM", Otk_Black, 3.0, 1.0, 4.0, y) ;
exit_pb = OtkMakeButton(mw, 40.0, 75.0, 20.0, 15.0, "", exit_werr_pb_cb, (void *) &m_win4) ;
OtkMakeTextLabel(exit_pb, "Exit", Otk_Black, 3.0, 1.0, 25.0, 15.0) ;
return (&m_win4) ;
break ;
... More case statements and default
}
}
// *****************************************************************************
// *
// * otk_lib.c slightly modified to print pointers of interest
// *
// *****************************************************************************
void Otk_RegisterWindowKillEventFunction( OtkWidget topobj, void (*callback)(void *x), void *parameter )
{
printf("\nOtk_RegisterWindowKillEventFunction() OtkWidget: %p\n", topobj) ;
printf("Otk_RegisterWindowKillEventFunction() callback param: %p\n\n", parameter) ;
if ((topobj->parent != 0) && (topobj->superclass == Otk_SC_WindowPane)) topobj = topobj->parent;
topobj->callback = callback;
topobj->callback_param = parameter;
}
P.S. FYI, I am developing a fairly sophisticated demonstration program for some
hardware that I designed that communicates over a USB "serial interface"
or regular serial port. This involves low level I/O so I am doing a good
deal of error checking during debugging and this can open error message
windows. The hardware uses a simple protocol of sending a command, and
waiting for a response (or timeout) with data that will be displayed
using one of the OTK gadgets and text for multiple sensors each with
their own window that is updated at a maximum rate of once per second.
A higher level protocol automatically retries on non-critical errors.
Either of these can open protocol error messages. Plus, there are several
main window pull down menu bars that can generate commands and responses
to display/modify hardware options and display hardware status. Eventually
I intend to block all but the critical error messages unless a debug mode
is enabled.
P.S.P.S On the main page of your on-line documentation this line:
The following are related functions: <a name="#anch7a">
works a lot better if it is changed to:
The following are related functions: <a name="anch7a">
I maintain an offline version of the on-line documentation if you or
anybody else is interested.