AmiTimeKeeper/win_main.c

344 lines
8.0 KiB
C

/*-
* Copyright (c) 2017-2019 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;
}
}