344 lines
8.0 KiB
C
344 lines
8.0 KiB
C
/*-
|
|
* Copyright (c) 2017-2018 Carsten Sonne Larsen <cs@innolan.net>
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include "message.h"
|
|
#include "state.h"
|
|
#include "time.h"
|
|
#include "mem.h"
|
|
#include "win.h"
|
|
|
|
static void SettingsProc(void);
|
|
static void ProcessMsg(void);
|
|
static void HandleGadgetUp(struct Gadget *);
|
|
|
|
void ShowSettingWindow(void)
|
|
{
|
|
bool running;
|
|
|
|
Forbid();
|
|
running = Globals->Window->Task != NULL;
|
|
if (!running)
|
|
{
|
|
Globals->Window->Task = CreateNewProcTags(
|
|
NP_Entry, (IPTR)SettingsProc,
|
|
NP_Name, (IPTR)APP_SHORT_NAME " Window",
|
|
NP_StackSize, 64 * 1024,
|
|
TAG_DONE);
|
|
}
|
|
Permit();
|
|
|
|
if (running)
|
|
{
|
|
LogTrace("Setting process is already running");
|
|
return;
|
|
}
|
|
|
|
if (Globals->Window->Task != NULL)
|
|
{
|
|
LogTrace("Created setting process");
|
|
}
|
|
else
|
|
{
|
|
LogError("Failed to create setting process");
|
|
}
|
|
}
|
|
|
|
void HideSettingWindow(void)
|
|
{
|
|
Forbid();
|
|
if (Globals->Window->Task != NULL)
|
|
{
|
|
Signal((void *)Globals->Window->Task, SIGBREAKF_CTRL_C);
|
|
}
|
|
Permit();
|
|
}
|
|
|
|
bool CheckSettingWindowClosed(void)
|
|
{
|
|
return (Globals->Window->Task == NULL);
|
|
}
|
|
|
|
static bool InitWindow(void)
|
|
{
|
|
Globals->Window->Screen = LockPubScreen(NULL);
|
|
if (!Globals->Window->Screen)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Globals->Window->UserPort = CreateMsgPort();
|
|
if (Globals->Window->UserPort == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Globals->Window->VisualInfo = GetVisualInfo(Globals->Window->Screen, NULL);
|
|
if (Globals->Window->VisualInfo == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Globals->Window->PriorityText = AllocMemSafe(15);
|
|
Globals->Window->TimeZoneText = AllocMemSafe(10);
|
|
Globals->Window->ThresholdText = AllocMemSafe(MAXLONGLONGCHARSIZE);
|
|
if (Globals->Window->PriorityText == NULL ||
|
|
Globals->Window->TimeZoneText == NULL ||
|
|
Globals->Window->ThresholdText == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
LongToStr(Globals->Settings->Priority, Globals->Window->PriorityText);
|
|
LongLongToStr(Globals->Settings->Threshold, Globals->Window->ThresholdText);
|
|
GetTimeZoneText(Globals->Window->TimeZoneText);
|
|
|
|
return true;
|
|
}
|
|
|
|
static void DestroyWindow(void)
|
|
{
|
|
if (Globals->Window->SettingWindow != NULL)
|
|
{
|
|
struct Message *msg;
|
|
while ((msg = GetMsg(Globals->Window->SettingWindow->UserPort)))
|
|
ReplyMsg(msg);
|
|
|
|
CloseWindow(Globals->Window->SettingWindow);
|
|
Globals->Window->SettingWindow = NULL;
|
|
}
|
|
|
|
if (Globals->Window->GadgetList != NULL)
|
|
{
|
|
FreeGadgets(Globals->Window->GadgetList);
|
|
Globals->Window->GadgetList = NULL;
|
|
}
|
|
|
|
if (Globals->Window->VisualInfo != NULL)
|
|
{
|
|
FreeVisualInfo(Globals->Window->VisualInfo);
|
|
Globals->Window->VisualInfo = NULL;
|
|
}
|
|
|
|
if (Globals->Window->UserPort != NULL)
|
|
{
|
|
struct Message *msg;
|
|
while ((msg = GetMsg(Globals->Window->UserPort)))
|
|
ReplyMsg(msg);
|
|
|
|
DeleteMsgPort(Globals->Window->UserPort);
|
|
Globals->Window->UserPort = NULL;
|
|
}
|
|
|
|
if (Globals->Window->Screen != NULL)
|
|
{
|
|
UnlockPubScreen(NULL, Globals->Window->Screen);
|
|
Globals->Window->Screen = NULL;
|
|
}
|
|
|
|
FreeSettings(Globals->Window->Settings);
|
|
FreeMemSafe(Globals->Window->Gadgets);
|
|
FreeMemSafe(Globals->Window->PriorityText);
|
|
FreeMemSafe(Globals->Window->ThresholdText);
|
|
FreeMemSafe(Globals->Window->TimeZoneText);
|
|
Globals->Window->Gadgets = NULL;
|
|
Globals->Window->PriorityText = NULL;
|
|
Globals->Window->ThresholdText = NULL;
|
|
Globals->Window->TimeZoneText = NULL;
|
|
|
|
Forbid();
|
|
Globals->Window->Task = NULL;
|
|
Permit();
|
|
}
|
|
|
|
static bool CreateWindow(void)
|
|
{
|
|
long w = Globals->Window->Screen->WBorLeft + Globals->Window->Screen->WBorRight + Globals->Window->Width + 38; // Why is this 38?
|
|
long h = Globals->Window->Height + 8 + Globals->Window->Screen->WBorBottom;
|
|
struct Window *x = OpenWindowTags(NULL,
|
|
WA_Width, w,
|
|
WA_Height, h,
|
|
WA_Left, (Globals->Window->Screen->Width - w) / 2,
|
|
WA_Top, (Globals->Window->Screen->Height - h) / 2,
|
|
WA_PubScreen, (IPTR)Globals->Window->Screen,
|
|
WA_Title, (IPTR)APP_LONG_NAME,
|
|
WA_Flags, WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_ACTIVATE | WFLG_SIMPLE_REFRESH,
|
|
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | IDCMP_VANILLAKEY | IDCMP_GADGETUP | IDCMP_MENUPICK,
|
|
WA_Gadgets, (IPTR)Globals->Window->GadgetList,
|
|
TAG_END);
|
|
Globals->Window->SettingWindow = x;
|
|
if (!x)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static void InitWindowSettings()
|
|
{
|
|
if (Globals->Window->Settings != NULL)
|
|
{
|
|
FreeSettings(Globals->Window->Settings);
|
|
}
|
|
Globals->Window->Settings = CopySettings(Globals->Settings);
|
|
}
|
|
|
|
static void SyncExit()
|
|
{
|
|
if (!Globals->ShuttingDown)
|
|
{
|
|
struct MsgPort *replyPort = CreateMsgPort();
|
|
if (replyPort)
|
|
{
|
|
SendMessageTo(Globals->Broker->UserPort, replyPort, ATK_UNDO);
|
|
WaitPort(replyPort);
|
|
GetMsg(replyPort);
|
|
DeleteMsgPort(replyPort);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void SettingsProc(void)
|
|
{
|
|
if (!InitWindow() || !CreateGadgets() || !CreateWindow())
|
|
{
|
|
DestroyWindow();
|
|
return;
|
|
}
|
|
|
|
InitWindowSettings();
|
|
ShowLastSync();
|
|
ProcessMsg();
|
|
SyncExit();
|
|
DestroyWindow();
|
|
}
|
|
|
|
static void ProcessMsg(void)
|
|
{
|
|
bool loop = true;
|
|
|
|
GT_RefreshWindow(Globals->Window->SettingWindow, NULL);
|
|
|
|
do
|
|
{
|
|
ULONG sigrcvd = Wait(SIGBREAKF_CTRL_C |
|
|
(1 << Globals->Window->UserPort->mp_SigBit) |
|
|
(1 << Globals->Window->SettingWindow->UserPort->mp_SigBit));
|
|
|
|
if (sigrcvd & (1 << Globals->Window->SettingWindow->UserPort->mp_SigBit))
|
|
{
|
|
struct IntuiMessage *msg;
|
|
while ((msg = GT_GetIMsg(Globals->Window->SettingWindow->UserPort)))
|
|
{
|
|
switch (msg->Class)
|
|
{
|
|
case IDCMP_REFRESHWINDOW:
|
|
GT_BeginRefresh(Globals->Window->SettingWindow);
|
|
GT_EndRefresh(Globals->Window->SettingWindow, TRUE);
|
|
break;
|
|
case IDCMP_GADGETUP:
|
|
HandleGadgetUp((struct Gadget *)msg->IAddress);
|
|
break;
|
|
case IDCMP_VANILLAKEY:
|
|
if (msg->Code == 0x1b)
|
|
loop = false;
|
|
break;
|
|
case IDCMP_CLOSEWINDOW:
|
|
loop = false;
|
|
break;
|
|
}
|
|
|
|
GT_ReplyIMsg(msg);
|
|
}
|
|
}
|
|
|
|
if (sigrcvd & (1 << Globals->Window->UserPort->mp_SigBit))
|
|
{
|
|
struct AppWindowMessage *msg;
|
|
while ((msg = (struct AppWindowMessage *)GetMsg(Globals->Window->UserPort)))
|
|
{
|
|
switch (msg->Type)
|
|
{
|
|
case ATK_REFRESH:
|
|
ShowLastSync();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
ReplyMsg((struct Message *)msg);
|
|
}
|
|
}
|
|
|
|
if (sigrcvd & SIGBREAKF_CTRL_C)
|
|
{
|
|
loop = false;
|
|
}
|
|
} while (loop);
|
|
}
|
|
|
|
static void HandleGadgetUp(struct Gadget *gadget)
|
|
{
|
|
switch (gadget->GadgetID)
|
|
{
|
|
case GID_SERVER:
|
|
SetServer();
|
|
break;
|
|
case GID_PORT:
|
|
SetPort();
|
|
break;
|
|
case GID_INTERVAL:
|
|
SetInterval();
|
|
break;
|
|
case GID_TIMEOUT:
|
|
SetTimeout();
|
|
break;
|
|
case GID_THRESHOLD:
|
|
SetThreshold();
|
|
break;
|
|
case GID_VERBOSE:
|
|
SetVerbose();
|
|
break;
|
|
case GID_PRIORITY:
|
|
SetCxPriority();
|
|
break;
|
|
case GID_SAVE:
|
|
SendMessage(ATK_STORE);
|
|
break;
|
|
case GID_USE:
|
|
UseSettings();
|
|
InitWindowSettings();
|
|
SendMessage(ATK_APPLY);
|
|
break;
|
|
case GID_CANCEL:
|
|
SendMessage(ATK_UNDO);
|
|
HideSettingWindow();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|