Commit daecaf1e003d0a78e4148f02ce648fc7a4c68144
1 parent
c252e4b4
Exists in
master
and in
3 other branches
Adding support for insert/remove of toggle listeners.
Showing
8 changed files
with
128 additions
and
35 deletions
Show diff stats
lib3270.cbp
... | ... | @@ -243,7 +243,6 @@ |
243 | 243 | <Unit filename="src/lib3270++/windows/resources.rc"> |
244 | 244 | <Option compilerVar="WINDRES" /> |
245 | 245 | </Unit> |
246 | - <Unit filename="src/lib3270/private.h" /> | |
247 | 246 | <Unit filename="src/lib3270/windows/resources.rc"> |
248 | 247 | <Option compilerVar="WINDRES" /> |
249 | 248 | </Unit> | ... | ... |
src/core/host.c
... | ... | @@ -189,12 +189,12 @@ LIB3270_EXPORT const void * lib3270_register_schange(H3270 *hSession, LIB3270_ST |
189 | 189 | st->func = func; |
190 | 190 | st->data = data; |
191 | 191 | |
192 | - if (hSession->st.last[tx]) | |
193 | - hSession->st.last[tx]->next = st; | |
192 | + if (hSession->listeners.state.last[tx]) | |
193 | + hSession->listeners.state.last[tx]->next = st; | |
194 | 194 | else |
195 | - hSession->st.callbacks[tx] = st; | |
195 | + hSession->listeners.state.callbacks[tx] = st; | |
196 | 196 | |
197 | - hSession->st.last[tx] = st; | |
197 | + hSession->listeners.state.last[tx] = st; | |
198 | 198 | |
199 | 199 | return (void *) st; |
200 | 200 | |
... | ... | @@ -207,16 +207,16 @@ LIB3270_EXPORT int lib3270_unregister_schange(H3270 *hSession, LIB3270_STATE tx, |
207 | 207 | |
208 | 208 | #ifdef DEBUG |
209 | 209 | { |
210 | - debug("Before remove of %p (last=%p):",id,hSession->st.last[tx]); | |
210 | + debug("Before remove of %p (last=%p):",id,hSession->listeners.state.last[tx]); | |
211 | 211 | |
212 | - for (st = hSession->st.callbacks[tx]; st != (struct lib3270_state_callback *) NULL; st = (struct lib3270_state_callback *) st->next) | |
212 | + for (st = hSession->listeners.state.callbacks[tx]; st != (struct lib3270_state_callback *) NULL; st = (struct lib3270_state_callback *) st->next) | |
213 | 213 | { |
214 | 214 | debug("%p",st); |
215 | 215 | } |
216 | 216 | } |
217 | 217 | #endif // DEBUG |
218 | 218 | |
219 | - for (st = hSession->st.callbacks[tx]; st != (struct lib3270_state_callback *) NULL; st = (struct lib3270_state_callback *) st->next) | |
219 | + for (st = hSession->listeners.state.callbacks[tx]; st != (struct lib3270_state_callback *) NULL; st = (struct lib3270_state_callback *) st->next) | |
220 | 220 | { |
221 | 221 | if (st == (struct lib3270_state_callback *)id) |
222 | 222 | break; |
... | ... | @@ -233,18 +233,18 @@ LIB3270_EXPORT int lib3270_unregister_schange(H3270 *hSession, LIB3270_STATE tx, |
233 | 233 | if (prev != (struct lib3270_state_callback *) NULL) |
234 | 234 | prev->next = st->next; |
235 | 235 | else |
236 | - hSession->st.callbacks[tx] = (struct lib3270_state_callback *) st->next; | |
236 | + hSession->listeners.state.callbacks[tx] = (struct lib3270_state_callback *) st->next; | |
237 | 237 | |
238 | - for(st = hSession->st.callbacks[tx]; st != (struct lib3270_state_callback *) NULL; st = (struct lib3270_state_callback *) st->next) | |
239 | - hSession->st.last[tx] = st; | |
238 | + for(st = hSession->listeners.state.callbacks[tx]; st != (struct lib3270_state_callback *) NULL; st = (struct lib3270_state_callback *) st->next) | |
239 | + hSession->listeners.state.last[tx] = st; | |
240 | 240 | |
241 | 241 | lib3270_free((void *) id); |
242 | 242 | |
243 | 243 | #ifdef DEBUG |
244 | 244 | { |
245 | - debug("After Remove of %p (last=%p):",id,hSession->st.last[tx]); | |
245 | + debug("After Remove of %p (last=%p):",id,hSession->listeners.state.last[tx]); | |
246 | 246 | |
247 | - for (st = hSession->st.callbacks[tx]; st != (struct lib3270_state_callback *) NULL; st = (struct lib3270_state_callback *) st->next) | |
247 | + for (st = hSession->listeners.state.callbacks[tx]; st != (struct lib3270_state_callback *) NULL; st = (struct lib3270_state_callback *) st->next) | |
248 | 248 | { |
249 | 249 | debug("%p",st); |
250 | 250 | } |
... | ... | @@ -282,7 +282,7 @@ void lib3270_st_changed(H3270 *h, LIB3270_STATE tx, int mode) |
282 | 282 | |
283 | 283 | trace("%s is %d on session %p",state_name[tx],mode,h); |
284 | 284 | |
285 | - for(st = h->st.callbacks[tx];st;st = st->next) | |
285 | + for(st = h->listeners.state.callbacks[tx];st;st = st->next) | |
286 | 286 | { |
287 | 287 | st->func(h,mode,st->data); |
288 | 288 | } | ... | ... |
src/core/linux/connect.c
src/core/session.c
... | ... | @@ -92,11 +92,22 @@ void lib3270_session_free(H3270 *h) |
92 | 92 | // Release state change callbacks |
93 | 93 | for(f=0;f<LIB3270_STATE_USER;f++) |
94 | 94 | { |
95 | - while(h->st.callbacks[f]) | |
95 | + while(h->listeners.state.callbacks[f]) | |
96 | 96 | { |
97 | - struct lib3270_state_callback *next = h->st.callbacks[f]->next; | |
98 | - lib3270_free(h->st.callbacks[f]); | |
99 | - h->st.callbacks[f] = next; | |
97 | + struct lib3270_state_callback *next = h->listeners.state.callbacks[f]->next; | |
98 | + lib3270_free(h->listeners.state.callbacks[f]); | |
99 | + h->listeners.state.callbacks[f] = next; | |
100 | + } | |
101 | + } | |
102 | + | |
103 | + // Release toggle change listeners. | |
104 | + for(f=0;f<LIB3270_TOGGLE_COUNT;f++) | |
105 | + { | |
106 | + while(h->listeners.toggle.callbacks[f]) | |
107 | + { | |
108 | + struct lib3270_toggle_callback *next = h->listeners.toggle.callbacks[f]->next; | |
109 | + lib3270_free(h->listeners.toggle.callbacks[f]); | |
110 | + h->listeners.toggle.callbacks[f] = next; | |
100 | 111 | } |
101 | 112 | } |
102 | 113 | ... | ... |
src/core/toggles.c
... | ... | @@ -24,9 +24,6 @@ |
24 | 24 | * |
25 | 25 | * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) |
26 | 26 | * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) |
27 | - * licinio@bb.com.br (Licínio Luis Branco) | |
28 | - * kraucer@bb.com.br (Kraucer Fernandes Mazuco) | |
29 | - * macmiranda@bb.com.br (Marco Aurélio Caldas Miranda) | |
30 | 27 | * |
31 | 28 | */ |
32 | 29 | |
... | ... | @@ -244,17 +241,24 @@ LIB3270_EXPORT unsigned char lib3270_get_toggle(H3270 *session, LIB3270_TOGGLE i |
244 | 241 | return session->toggle[ix].value != 0; |
245 | 242 | } |
246 | 243 | |
247 | -/* | |
248 | - * Call the internal update routine | |
244 | +/** | |
245 | + * @brief Call the internal update routine and listeners. | |
249 | 246 | */ |
250 | 247 | static void toggle_notify(H3270 *session, struct lib3270_toggle *t, LIB3270_TOGGLE ix) |
251 | 248 | { |
249 | + struct lib3270_toggle_callback * st; | |
250 | + | |
252 | 251 | trace("%s: ix=%d upcall=%p",__FUNCTION__,ix,t->upcall); |
253 | 252 | t->upcall(session, t, LIB3270_TOGGLE_TYPE_INTERACTIVE); |
254 | 253 | |
255 | 254 | if(session->cbk.update_toggle) |
256 | 255 | session->cbk.update_toggle(session,ix,t->value,LIB3270_TOGGLE_TYPE_INTERACTIVE,toggle_info[ix].name); |
257 | 256 | |
257 | + for(st = session->listeners.toggle.callbacks[ix]; st != (struct lib3270_toggle_callback *) NULL; st = (struct lib3270_toggle_callback *) st->next) | |
258 | + { | |
259 | + st->func(session, ix, st->data); | |
260 | + } | |
261 | + | |
258 | 262 | } |
259 | 263 | |
260 | 264 | /** |
... | ... | @@ -315,8 +319,8 @@ static void toggle_redraw(H3270 *session, struct lib3270_toggle GNUC_UNUSED(*t), |
315 | 319 | session->cbk.display(session); |
316 | 320 | } |
317 | 321 | |
318 | -/* | |
319 | - * No-op toggle. | |
322 | +/** | |
323 | + * @brief No-op toggle. | |
320 | 324 | */ |
321 | 325 | static void toggle_nop(H3270 GNUC_UNUSED(*session), struct lib3270_toggle GNUC_UNUSED(*t), LIB3270_TOGGLE_TYPE GNUC_UNUSED(tt)) |
322 | 326 | { |
... | ... | @@ -356,7 +360,6 @@ void initialize_toggles(H3270 *session) |
356 | 360 | session->toggle[LIB3270_TOGGLE_UNDERLINE].upcall = toggle_redraw; |
357 | 361 | session->toggle[LIB3270_TOGGLE_ALTSCREEN].upcall = toggle_altscreen; |
358 | 362 | session->toggle[LIB3270_TOGGLE_KEEP_ALIVE].upcall = toggle_keepalive; |
359 | -// session->toggle[LIB3270_TOGGLE_RECONNECT].upcall = toggle_reconnect; | |
360 | 363 | |
361 | 364 | for(f=0;f<LIB3270_TOGGLE_COUNT;f++) |
362 | 365 | { |
... | ... | @@ -418,3 +421,56 @@ LIB3270_EXPORT LIB3270_TOGGLE lib3270_get_toggle_id(const char *name) |
418 | 421 | return -1; |
419 | 422 | } |
420 | 423 | |
424 | +LIB3270_EXPORT const void * lib3270_register_toggle_listener(H3270 *hSession, LIB3270_TOGGLE tx, void (*func)(H3270 *, LIB3270_TOGGLE, void *),void *data) | |
425 | +{ | |
426 | + struct lib3270_toggle_callback *st; | |
427 | + | |
428 | + CHECK_SESSION_HANDLE(hSession); | |
429 | + | |
430 | + st = (struct lib3270_toggle_callback *) lib3270_malloc(sizeof(struct lib3270_toggle_callback)); | |
431 | + st->func = func; | |
432 | + st->data = data; | |
433 | + | |
434 | + if (hSession->listeners.toggle.last[tx]) | |
435 | + hSession->listeners.toggle.last[tx]->next = st; | |
436 | + else | |
437 | + hSession->listeners.toggle.callbacks[tx] = st; | |
438 | + | |
439 | + hSession->listeners.toggle.last[tx] = st; | |
440 | + | |
441 | + return (void *) st; | |
442 | + | |
443 | +} | |
444 | + | |
445 | +LIB3270_EXPORT int lib3270_unregister_toggle_listener(H3270 *hSession, LIB3270_TOGGLE tx, const void *id) | |
446 | +{ | |
447 | + struct lib3270_toggle_callback *st; | |
448 | + struct lib3270_toggle_callback *prev = (struct lib3270_toggle_callback *) NULL; | |
449 | + | |
450 | + for (st = hSession->listeners.toggle.callbacks[tx]; st != (struct lib3270_toggle_callback *) NULL; st = (struct lib3270_toggle_callback *) st->next) | |
451 | + { | |
452 | + if (st == (struct lib3270_toggle_callback *)id) | |
453 | + break; | |
454 | + | |
455 | + prev = st; | |
456 | + } | |
457 | + | |
458 | + if (st == (struct lib3270_toggle_callback *)NULL) | |
459 | + { | |
460 | + lib3270_write_log(hSession,"lib3270","Invalid call to (%s): %p wasnt found in the list",__FUNCTION__,id); | |
461 | + return errno = ENOENT; | |
462 | + } | |
463 | + | |
464 | + if (prev != (struct lib3270_toggle_callback *) NULL) | |
465 | + prev->next = st->next; | |
466 | + else | |
467 | + hSession->listeners.toggle.callbacks[tx] = (struct lib3270_toggle_callback *) st->next; | |
468 | + | |
469 | + for(st = hSession->listeners.toggle.callbacks[tx]; st != (struct lib3270_toggle_callback *) NULL; st = (struct lib3270_toggle_callback *) st->next) | |
470 | + hSession->listeners.toggle.last[tx] = st; | |
471 | + | |
472 | + lib3270_free((void *) id); | |
473 | + | |
474 | + return 0; | |
475 | + | |
476 | +} | ... | ... |
src/include/lib3270-internals.h
... | ... | @@ -323,9 +323,16 @@ typedef struct _input_t |
323 | 323 | |
324 | 324 | struct lib3270_state_callback |
325 | 325 | { |
326 | - struct lib3270_state_callback * next; /**< Next callback in chain */ | |
327 | - void * data; /**< User data */ | |
328 | - void (*func)(H3270 *, int, void *); /**< Function to call */ | |
326 | + struct lib3270_state_callback * next; /**< @brief Next callback in chain */ | |
327 | + void * data; /**< @brief User data */ | |
328 | + void (*func)(H3270 *, int, void *); /**< @brief Function to call */ | |
329 | +}; | |
330 | + | |
331 | +struct lib3270_toggle_callback | |
332 | +{ | |
333 | + struct lib3270_toggle_callback * next; /**< @brief Next callback in chain */ | |
334 | + void * data; /**< @brief User data */ | |
335 | + void (*func)(H3270 *, LIB3270_TOGGLE, void *); /**< @brief Function to call */ | |
329 | 336 | }; |
330 | 337 | |
331 | 338 | /** |
... | ... | @@ -663,16 +670,31 @@ struct _h3270 |
663 | 670 | int inputs_changed : 1; |
664 | 671 | |
665 | 672 | // Trace methods. |
666 | - struct { | |
673 | + struct | |
674 | + { | |
667 | 675 | void (*handler)(H3270 *session, void *userdata, const char *fmt, va_list args); |
668 | 676 | void *userdata; |
669 | 677 | } trace; |
670 | 678 | |
671 | - // State change listeners. | |
672 | - struct { | |
673 | - struct lib3270_state_callback * callbacks[LIB3270_STATE_USER]; | |
674 | - struct lib3270_state_callback * last[LIB3270_STATE_USER]; | |
675 | - } st; | |
679 | + // Listeners. | |
680 | + struct | |
681 | + { | |
682 | + // State. | |
683 | + struct | |
684 | + { | |
685 | + struct lib3270_state_callback * callbacks[LIB3270_STATE_USER]; | |
686 | + struct lib3270_state_callback * last[LIB3270_STATE_USER]; | |
687 | + } state; | |
688 | + | |
689 | + // Toggle change listeners | |
690 | + struct | |
691 | + { | |
692 | + struct lib3270_toggle_callback * callbacks[LIB3270_TOGGLE_COUNT]; | |
693 | + struct lib3270_toggle_callback * last[LIB3270_TOGGLE_COUNT]; | |
694 | + } toggle; | |
695 | + | |
696 | + } listeners; | |
697 | + | |
676 | 698 | |
677 | 699 | }; |
678 | 700 | ... | ... |
src/include/lib3270/toggle.h
... | ... | @@ -104,4 +104,7 @@ |
104 | 104 | LIB3270_EXPORT void lib3270_set_session_id(H3270 *hSession, char id); |
105 | 105 | LIB3270_EXPORT char lib3270_get_session_id(H3270 *hSession); |
106 | 106 | |
107 | + LIB3270_EXPORT const void * lib3270_register_toggle_listener(H3270 *hSession, LIB3270_TOGGLE tx, void (*func)(H3270 *, LIB3270_TOGGLE, void *),void *data); | |
108 | + LIB3270_EXPORT int lib3270_unregister_toggle_listener(H3270 *hSession, LIB3270_TOGGLE tx, const void *id); | |
109 | + | |
107 | 110 | #endif /* LIB3270_TOGGLE_H_INCLUDED */ | ... | ... |