3 //=============================================================================
5 * @file XtMotifReactor_Test.cpp
7 * This is a simple test that illustrates the possibility to integrate
8 * ACE to the X Main Loop. This program uses ACE_XtReactor class to
9 * schedule three additional event sources:
10 * 1. Events from button "Stop Test" (registed with XtAddCallback)
11 * 2. Events from button "Press Me" (registed with XtAddCallback)
12 * 3. Events from X timer (registed with XtAppAddTimeOut)
13 * 4. Events from ACE timer (registed with ACE_XtReactor::schedule_timer)
14 * 5. Events from the TCP/IP channel using ACE_Acceptor
15 * No command line arguments are needed to run the test.
16 * The program needs Motif or lestiff to be compiled and run.
18 * @author Kirill Rybaltchenko <Kirill.Rybaltchenko@cern.ch>
20 //=============================================================================
23 #include "test_config.h"
25 #include "ace/XtReactor/XtReactor.h"
26 #include "ace/Event_Handler.h"
27 #include "ace/Acceptor.h"
28 #include "ace/SOCK_Acceptor.h"
29 #include "ace/SOCK_Connector.h"
30 #include "ace/Service_Config.h"
31 #include "ace/Thread_Manager.h"
33 #include "ace/OS_NS_unistd.h"
35 #include /**/ <X11/Intrinsic.h>
36 #include /**/ <X11/Xatom.h>
37 #include /**/ <X11/Shell.h>
39 #include /**/ <Xm/Xm.h>
40 #include /**/ <Xm/Label.h>
41 #include /**/ <Xm/PushB.h>
42 #include /**/ <Xm/RowColumn.h>
44 static void set_label(Widget w
, const char *p
)
48 XmStringCreateLocalized( (char*) p
),
49 static_cast<void *>(0));
51 #define LABEL_WIDGET xmLabelWidgetClass
52 #define BUTTON_WIDGET xmPushButtonWidgetClass
53 #define PRESS_ME_CALLBACK XmNactivateCallback
54 static Widget
create_box(Widget parent
, const char *name
)
58 XtSetArg (al
[ac
], XmNnumColumns
, 3); ac
++;
59 XtSetArg (al
[ac
], XmNpacking
, XmPACK_COLUMN
); ac
++;
60 XtSetArg (al
[ac
], XmNentryAlignment
, XmALIGNMENT_CENTER
); ac
++;
61 return XmCreateRowColumn (parent
, (char *) name
, al
, ac
);
65 static const u_short SERV_TCP_PORT
= 6670;
67 // counter for events from "Press Me" button.
68 static int count1
= 0;
70 // counter for events from X Timer.
71 static int count2
= 0;
73 // counter for events from ACE Timer.
74 static int count3
= 0;
76 // Callback for "Stop Test" buton - quit the program.
78 Quit (Widget
, XtPointer
, XtPointer
)
91 " (%P) Client: Starting...\n"));
93 ACE_SOCK_Stream stream
;
94 ACE_SOCK_Connector connector
;
95 ACE_OS::snprintf (buf
, 100, "Client: the life was good!");
97 mes_len
= (int) htonl (ACE_OS::strlen (buf
) + 1);
99 if (connector
.connect (stream
,
100 ACE_INET_Addr (SERV_TCP_PORT
,
101 ACE_DEFAULT_SERVER_HOST
)) == -1)
102 ACE_ERROR ((LM_ERROR
,
110 ACE_OS::strlen (buf
) + 1) == -1)
112 ACE_ERROR ((LM_ERROR
,
116 if (stream
.close () == -1)
117 ACE_ERROR ((LM_ERROR
,
121 ACE_DEBUG ((LM_DEBUG
,
122 "(%P) Client: Message has been sent, about to exit...\n"));
126 // Callback for "Press Me" button.
129 inc_count (Widget
, XtPointer client_data
, XtPointer
)
133 ACE_OS::snprintf (new_string
, 80, "Events: [%d] [%d] [%d]",
134 count1
++, count2
, count3
);
136 set_label((Widget
) client_data
, new_string
);
139 // Callback for X Timer.
142 inc_tmo (void *w
, XtIntervalId
*)
148 ACE_OS::snprintf (new_string
, 80, "Events: [%d] [%d] [%d]",
149 count1
, count2
++, count3
);
151 set_label((Widget
) w
, new_string
);
153 (void) XtAppAddTimeOut (XtWidgetToApplicationContext ((Widget
) w
),
159 class EV_handler
: public ACE_Event_Handler
162 virtual int handle_timeout (const ACE_Time_Value
&,
166 ACE_OS::snprintf (new_string
, 80, "Events: [%d] [%d] [%d]",
167 count1
, count2
, count3
++);
168 set_label((Widget
) arg
, new_string
);
173 class Connection_Handler
: public ACE_Svc_Handler
<ACE_SOCK_STREAM
, ACE_NULL_SYNCH
>
176 //FUZZ: disable check_for_lack_ACE_OS
177 virtual int open (void *)
179 //FUZZ: enable check_for_lack_ACE_OS
182 ssize_t ret
= this->peer ().recv_n ((char *) &head
,
184 if (ret
!= sizeof (int))
185 ACE_ERROR_RETURN ((LM_ERROR
,
190 ret
= this->peer ().recv_n (buf
,
193 if (ret
!= (int) ntohl (head
))
194 ACE_ERROR_RETURN ((LM_ERROR
,
198 ACE_DEBUG ((LM_DEBUG
,
199 " (%P)Server (ACE_SOCKET channel message): [%s]\n",
205 #if defined (HummingBird_X)
206 extern "C" void HCLXmInit ();
207 #endif /* HummingBird_X */
210 run_main (int argc
, ACE_TCHAR
*argv
[])
212 ACE_START_TEST (ACE_TEXT ("XtMotifReactor_Test"));
214 XtAppContext app_context
;
215 Widget topLevel
, goodbye
, PressMe
, lbl
, digits_rc
;
218 #if defined (HummingBird_X)
220 #endif /* HummingBird_X */
221 topLevel
= XtVaAppInitialize (&app_context
,
228 static_cast<void *>(0));
230 digits_rc
= create_box(topLevel
, "digits_rc");
232 //"Stop Test" button.
233 goodbye
= XtCreateWidget ( (char *) "goodbye",
238 set_label(goodbye
, "Stop Test");
241 PressMe
= XtCreateWidget ((char *) "PressMe",
247 //Display for event counter
248 lbl
= XtCreateWidget ((char *) "label_for_event_one",
253 set_label(lbl
, "label_for_all_events");
255 children
[ac
++] = goodbye
;
256 children
[ac
++] = PressMe
;
257 children
[ac
++] = lbl
;
258 XtManageChildren (children
, ac
);
259 XtManageChild (digits_rc
);
261 //Register callback for "Stop Test" button
262 XtAddCallback (goodbye
, PRESS_ME_CALLBACK
, Quit
, 0);
264 //Register callback for "Press Me" button
265 XtAddCallback (PressMe
,
270 // Register callback for X Timer
271 (void) XtAppAddTimeOut (app_context
,
276 XtRealizeWidget (topLevel
);
278 // It will perform X Main Loop
279 ACE_XtReactor
reactor (app_context
);
281 ACE_Reactor
r (&reactor
);
283 //Event Handler for ACE Timer.
286 ACE_Acceptor
<Connection_Handler
, ACE_SOCK_ACCEPTOR
> acceptor
;
288 if (acceptor
.open (ACE_INET_Addr ((u_short
) SERV_TCP_PORT
),
290 ACE_ERROR_RETURN ((LM_ERROR
,
295 if (reactor
.schedule_timer (&evh
,
298 ACE_Time_Value (2))==-1)
299 ACE_ERROR_RETURN ((LM_ERROR
,
300 " (%P|%t) can't register with reactor\n"),
303 ACE_Thread_Manager::instance ()->spawn ((ACE_THR_FUNC
) client
,
305 THR_NEW_LWP
| THR_DETACHED
);
307 XtAppMainLoop (XtWidgetToApplicationContext (topLevel
));