Browse Source

Intercept management callbacks for better control of the UI

- Dialog windows of connections can popup at any time due to
  restarts not in user's control. Avoid this by marking current
  current profile being connected, and intercepting dialogs for
  other profiles.

  This is implemented by hooking into management callbacks such as
  OnPassword, OnNeedOk etc.

Signed-off-by: Selva Nair <selva.nair@gmail.com>
pull/529/head
Selva Nair 2 years ago
parent
commit
e64b18074f
  1. 3
      plap/plap_connection.c
  2. 135
      plap/ui_glue.c
  3. 6
      plap/ui_glue.h

3
plap/plap_connection.c

@ -540,6 +540,8 @@ Connect(ICCPC *this, IQueryContinueWithStatus *qc)
NotifyEvents(oc, L"");
oc->connect_cancelled = FALSE;
SetActiveProfile(oc->c);
ConnectHelper(oc->c);
Sleep(100);
@ -570,6 +572,7 @@ Connect(ICCPC *this, IQueryContinueWithStatus *qc)
ShowStatusWindow(oc->c, FALSE);
oc->qc = NULL;
SetActiveProfile(NULL);
dmsg (L"Exit with: <%ls>", ISCONNECTED(oc->c) ? L"success" : L"error/cancel");

135
plap/ui_glue.c

@ -42,9 +42,121 @@
/* Global options structure */
options_t o;
int state_connected = connected, state_disconnected = disconnected,
state_onhold = onhold;
static connection_t *active_profile;
/* Override management handlers that generate user dialogs
* and pass them on only for currently active profile.
* Also ensure no unwanted popus are generated.
*/
static void
OnStop_(connection_t *c, UNUSED char *msg)
{
dmsg(L"profile: %ls with state = %d", c->config_name, c->state);
/* do not show any popup error messages */
c->state = disconnected;
SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_DISCONNECTED));
SetStatusWinIcon(c->hwndStatus, ID_ICO_DISCONNECTED);
SendMessage(c->hwndStatus, WM_CLOSE, 0, 0);
}
/* Override OnInfoMsg: We filter out anything other
* than CR_TEXT: In particular, OPEN_URL is not supported
* in PLAP context.
*/
static void
OnInfoMsg_(connection_t* c, char* msg)
{
if (strbegins(msg, "CR_TEXT:"))
{
if (c == active_profile)
{
OnInfoMsg(c, msg);
}
else
{
DetachOpenVPN(c); /* next attach will handle it */
}
}
}
static void
OnNeedOk_(connection_t *c, char *msg)
{
if (c == active_profile)
{
OnNeedOk(c, msg);
}
else
{
DetachOpenVPN(c); /* next attach will handle it */
}
}
static void
OnNeedStr_(connection_t *c, char *msg)
{
if (c == active_profile)
{
OnNeedStr(c, msg);
}
else
{
DetachOpenVPN(c); /* next attach will handle it */
}
}
static void
OnPassword_(connection_t *c, char *msg)
{
if (c == active_profile)
{
OnPassword(c, msg);
}
else
{
DetachOpenVPN(c); /* next attach will handle it */
}
}
static void
OnProxy_(connection_t *c, char *msg)
{
if (c == active_profile)
{
OnProxy(c, msg);
}
else
{
DetachOpenVPN(c); /* next attach will handle it */
}
}
/* Intercept state change. Keep track of previous state and handle
* cases like user wants to disconnect but connection completed in
* the meantime.
*/
void
OnStateChange_(connection_t *c, char *msg)
{
int state_prev = c->state;
OnStateChange(c, msg);
if (c->state == connected && state_prev == disconnecting)
{
/* connection completed while user clicked disconnect,
* let disconnect process continue. This is required to
* retain the hold state after SIGHUP restart.
*/
c->state = disconnecting;
}
}
/* Initialize GUI data structures. Returns 0 on success */
DWORD
InitializeUI(HINSTANCE hinstance)
@ -90,15 +202,15 @@ InitializeUI(HINSTANCE hinstance)
{ ready_, OnReady },
{ hold_, OnHold },
{ log_, OnLogLine },
{ state_, OnStateChange },
{ password_, OnPassword },
{ proxy_, OnProxy },
{ stop_, OnStop },
{ needok_, OnNeedOk },
{ needstr_, OnNeedStr },
{ state_, OnStateChange_ },
{ password_, OnPassword_ },
{ proxy_, OnProxy_ },
{ stop_, OnStop_ },
{ needok_, OnNeedOk_ },
{ needstr_, OnNeedStr_ },
{ echo_, OnEcho },
{ bytecount_,OnByteCount },
{ infomsg_, OnInfoMsg },
{ infomsg_, OnInfoMsg_ },
{ timeout_, OnTimeout },
{ 0, NULL}
};
@ -356,3 +468,12 @@ DisconnectHelper(connection_t *c)
dmsg(L"profile: %ls state = %d", c->config_name, c->state);
}
/* Set the currently active profile in Connect() operation -- pass NULL to unset.
* We allow UI dialogs only on the current profile.
*/
void
SetActiveProfile(connection_t *c)
{
active_profile = c;
}

6
plap/ui_glue.h

@ -101,6 +101,12 @@ void ConnectHelper(connection_t *c);
*/
void DisconnectHelper(connection_t *c);
/**
* Set c as the currently active profile selected for user interaction
* UI dialogs are suppressed for non-active profiles
*/
void SetActiveProfile(connection_t *c);
#ifdef __cplusplus
}
#endif

Loading…
Cancel
Save