AmiTimeKeeper/win_main.c

370 lines
8.7 KiB
C
Raw Permalink Normal View History

2018-11-24 21:39:18 +00:00
/*-
2021-01-12 22:16:18 +00:00
* Copyright (c) 2017-2021 Carsten Sonne Larsen <cs@innolan.net>
2018-11-24 21:39:18 +00:00
* 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.
2021-01-12 22:00:49 +00:00
*
2018-11-24 21:39:18 +00:00
*/
#include "config.h"
2021-01-12 22:02:29 +00:00
#include "global.h"
2018-11-24 21:39:18 +00:00
#include "message.h"
2021-01-12 22:02:29 +00:00
#include "setting.h"
#include "timer.h"
2021-01-12 22:16:18 +00:00
#include "conv.h"
2021-01-12 22:02:29 +00:00
#include "sync.h"
2021-01-12 22:16:18 +00:00
#include "text.h"
2018-11-24 21:39:18 +00:00
#include "mem.h"
#include "win.h"
2021-01-12 22:02:29 +00:00
#include "logmod.h"
2021-01-12 22:16:18 +00:00
#undef MODULENAME
2021-01-12 22:02:29 +00:00
#define MODULENAME "Window"
#define WINPROCNAME APP_SHORT_NAME " Window"
2021-01-12 22:16:18 +00:00
#ifndef GADTOOLSNAME
#define GADTOOLSNAME "gadtools.library"
#endif
2018-11-24 21:39:18 +00:00
static void SettingsProc(void);
2021-01-12 22:02:29 +00:00
static void MsgLoop(void);
2018-11-24 21:39:18 +00:00
static void HandleGadgetUp(struct Gadget *);
2021-01-12 22:02:29 +00:00
volatile bool WindowProcRunning = false;
struct AppSettings *WindowSettings = NULL;
struct AppSettingWindow SettingWindow;
2021-01-31 19:10:59 +00:00
static APTR OrgWindowPtr = NULL;
2018-11-24 21:39:18 +00:00
void ShowSettingWindow(void)
{
bool running;
2021-01-31 19:10:59 +00:00
struct Task *task = NULL;
2018-11-24 21:39:18 +00:00
2021-01-12 22:16:18 +00:00
if (GadToolsBase == NULL)
{
LogWarn(GADTOOLSNAME " is not present");
LogNotice("Settings window cannot open");
return;
}
#if defined(AROS)
LogWarn("Settings window dos not work in AROS with " APP_TITLE_VERSION);
return;
#endif
2018-11-24 21:39:18 +00:00
Forbid();
2021-01-12 22:02:29 +00:00
running = WindowProcRunning;
if (!WindowProcRunning)
2018-11-24 21:39:18 +00:00
{
2021-01-12 22:02:29 +00:00
task = (struct Task *)CreateNewProcTags(
2018-11-24 21:39:18 +00:00
NP_Entry, (IPTR)SettingsProc,
2021-01-12 22:02:29 +00:00
NP_Name, (IPTR)WINPROCNAME,
2018-11-24 21:39:18 +00:00
NP_StackSize, 64 * 1024,
TAG_DONE);
2021-01-12 22:02:29 +00:00
WindowProcRunning = (task != NULL);
2018-11-24 21:39:18 +00:00
}
Permit();
if (running)
{
2021-01-31 19:10:59 +00:00
LogDebug(Text2P, "Setting process", TextAlreadyRunning);
2021-01-12 22:16:18 +00:00
SendWindowMessage(ATK_SHOW);
2018-11-24 21:39:18 +00:00
}
2021-01-12 22:02:29 +00:00
else if (task != NULL)
2018-11-24 21:39:18 +00:00
{
2021-01-12 22:02:29 +00:00
LogDebug("Created setting process");
2018-11-24 21:39:18 +00:00
}
else
{
LogError("Failed to create setting process");
}
}
static bool InitWindow(void)
{
2021-01-12 22:16:18 +00:00
bool success;
LogInfo(TextInitComponent, "settings window");
2021-01-12 22:02:29 +00:00
SettingWindow.Screen = NULL;
SettingWindow.Window = NULL;
SettingWindow.GadgetList = NULL;
SettingWindow.VisualInfo = NULL;
SettingWindow.PriorityText = NULL;
SettingWindow.ThresholdText = NULL;
SettingWindow.TimezoneText = NULL;
SettingWindow.Width = 0;
SettingWindow.Height = 0;
SettingWindow.Gadgets = NULL;
2021-01-12 22:16:18 +00:00
success = CreateMessagePort(MSGPORT_WINDOW);
if (!success)
2018-11-24 21:39:18 +00:00
{
return false;
}
2021-01-12 22:02:29 +00:00
SettingWindow.Screen = LockPubScreen(NULL);
if (!SettingWindow.Screen)
2018-11-24 21:39:18 +00:00
{
return false;
}
2021-01-12 22:02:29 +00:00
SettingWindow.VisualInfo = GetVisualInfo(SettingWindow.Screen, NULL);
if (SettingWindow.VisualInfo == NULL)
2018-11-24 21:39:18 +00:00
{
return false;
}
2021-01-12 22:02:29 +00:00
SettingWindow.PriorityText = AllocStringSafe(15);
SettingWindow.TimezoneText = AllocStringSafe(TIMEZONE_TEXT_LEN);
SettingWindow.ThresholdText = AllocStringSafe(MAXLONGLONGCHARSIZE);
if (SettingWindow.PriorityText == NULL ||
SettingWindow.TimezoneText == NULL ||
SettingWindow.ThresholdText == NULL)
2018-11-24 21:39:18 +00:00
{
return false;
}
2021-01-12 22:02:29 +00:00
LongToStr(Settings->Priority, SettingWindow.PriorityText);
LongLongToStr(Settings->Threshold, SettingWindow.ThresholdText);
2021-01-31 19:10:59 +00:00
GetTimezoneText(SettingWindow.TimezoneText, Settings->TimeZoneDisplay);
2018-11-24 21:39:18 +00:00
return true;
}
static void DestroyWindow(void)
{
2021-01-12 22:16:18 +00:00
LogTrace("Clean up");
DestroyMessagePort(MSGPORT_WINDOW);
2021-01-12 22:02:29 +00:00
if (SettingWindow.Window != NULL)
2018-11-24 21:39:18 +00:00
{
struct Message *msg;
2021-01-12 22:02:29 +00:00
while ((msg = GetMsg(SettingWindow.Window->UserPort)))
2018-11-24 21:39:18 +00:00
ReplyMsg(msg);
2021-01-31 19:10:59 +00:00
Forbid();
struct Process *proc = (struct Process *)FindTask(NULL);
proc->pr_WindowPtr = OrgWindowPtr;
Permit();
2021-01-12 22:02:29 +00:00
CloseWindow(SettingWindow.Window);
SettingWindow.Window = NULL;
2018-11-24 21:39:18 +00:00
}
2021-01-12 22:02:29 +00:00
if (SettingWindow.GadgetList != NULL)
2018-11-24 21:39:18 +00:00
{
2021-01-12 22:02:29 +00:00
FreeGadgets(SettingWindow.GadgetList);
SettingWindow.GadgetList = NULL;
2018-11-24 21:39:18 +00:00
}
2021-01-12 22:02:29 +00:00
if (SettingWindow.VisualInfo != NULL)
2018-11-24 21:39:18 +00:00
{
2021-01-12 22:02:29 +00:00
FreeVisualInfo(SettingWindow.VisualInfo);
SettingWindow.VisualInfo = NULL;
2018-11-24 21:39:18 +00:00
}
2021-01-12 22:02:29 +00:00
if (SettingWindow.Screen != NULL)
2018-11-24 21:39:18 +00:00
{
2021-01-12 22:02:29 +00:00
UnlockPubScreen(NULL, SettingWindow.Screen);
SettingWindow.Screen = NULL;
2018-11-24 21:39:18 +00:00
}
2021-01-12 22:02:29 +00:00
FreeSettings(WindowSettings);
WindowSettings = NULL;
FreeMemSafe(SettingWindow.Gadgets);
FreeMemSafe(SettingWindow.PriorityText);
FreeMemSafe(SettingWindow.ThresholdText);
FreeMemSafe(SettingWindow.TimezoneText);
SettingWindow.Gadgets = NULL;
SettingWindow.PriorityText = NULL;
SettingWindow.ThresholdText = NULL;
SettingWindow.TimezoneText = NULL;
2018-11-24 21:39:18 +00:00
}
static bool CreateWindow(void)
{
2021-01-12 22:02:29 +00:00
long w = SettingWindow.Screen->WBorLeft + SettingWindow.Screen->WBorRight + SettingWindow.Width + 38; // Why is this 38?
long h = SettingWindow.Height + 8 + SettingWindow.Screen->WBorBottom;
2018-11-24 21:39:18 +00:00
struct Window *x = OpenWindowTags(NULL,
WA_Width, w,
WA_Height, h,
2021-01-12 22:02:29 +00:00
WA_Left, (SettingWindow.Screen->Width - w) / 2,
WA_Top, (SettingWindow.Screen->Height - h) / 2,
WA_PubScreen, (IPTR)SettingWindow.Screen,
2018-11-24 21:39:18 +00:00
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,
2021-01-12 22:02:29 +00:00
WA_Gadgets, (IPTR)SettingWindow.GadgetList,
2018-11-24 21:39:18 +00:00
TAG_END);
2021-01-12 22:02:29 +00:00
SettingWindow.Window = x;
2018-11-24 21:39:18 +00:00
if (!x)
{
return false;
}
2021-01-31 19:10:59 +00:00
Forbid();
struct Process *proc = (struct Process *)FindTask(NULL);
OrgWindowPtr = proc->pr_WindowPtr;
proc->pr_WindowPtr = x;
Permit();
2018-11-24 21:39:18 +00:00
return true;
}
static void InitWindowSettings()
{
2021-01-12 22:02:29 +00:00
if (WindowSettings != NULL)
2018-11-24 21:39:18 +00:00
{
2021-01-12 22:02:29 +00:00
FreeSettings(WindowSettings);
2018-11-24 21:39:18 +00:00
}
2021-01-12 22:02:29 +00:00
WindowSettings = CopySettings(Settings);
2018-11-24 21:39:18 +00:00
}
static void SettingsProc(void)
{
if (!InitWindow() || !CreateGadgets() || !CreateWindow())
{
DestroyWindow();
2021-01-12 22:02:29 +00:00
WindowProcRunning = false;
2018-11-24 21:39:18 +00:00
return;
}
InitWindowSettings();
2021-01-12 22:02:29 +00:00
ShowLastSync((struct timeval *)&LastSync);
MsgLoop();
2021-01-12 22:16:18 +00:00
SendMessageWait(MSGPORT_BROKER, ATK_UNDO);
2018-11-24 21:39:18 +00:00
DestroyWindow();
2021-01-12 22:02:29 +00:00
WindowProcRunning = false;
2018-11-24 21:39:18 +00:00
}
2021-01-12 22:02:29 +00:00
static void MsgLoop(void)
2018-11-24 21:39:18 +00:00
{
bool loop = true;
2021-01-12 22:16:18 +00:00
ULONG procPortSigMask = GetPortSignalMask(MSGPORT_WINDOW);
2021-01-12 22:02:29 +00:00
ULONG windowSigMask = (1 << SettingWindow.Window->UserPort->mp_SigBit);
2021-01-12 22:16:18 +00:00
ULONG sigMask = procPortSigMask | windowSigMask;
2018-11-24 21:39:18 +00:00
2021-01-12 22:02:29 +00:00
GT_RefreshWindow(SettingWindow.Window, NULL);
2018-11-24 21:39:18 +00:00
do
{
2021-01-12 22:02:29 +00:00
ULONG sigrcvd = Wait(sigMask);
if (sigrcvd & windowSigMask)
2018-11-24 21:39:18 +00:00
{
struct IntuiMessage *msg;
2021-01-12 22:02:29 +00:00
while ((msg = GT_GetIMsg(SettingWindow.Window->UserPort)))
2018-11-24 21:39:18 +00:00
{
switch (msg->Class)
{
case IDCMP_REFRESHWINDOW:
2021-01-12 22:02:29 +00:00
GT_BeginRefresh(SettingWindow.Window);
GT_EndRefresh(SettingWindow.Window, TRUE);
2018-11-24 21:39:18 +00:00
break;
case IDCMP_GADGETUP:
HandleGadgetUp((struct Gadget *)msg->IAddress);
break;
case IDCMP_VANILLAKEY:
if (msg->Code == 0x1b)
2021-01-12 22:02:29 +00:00
{
2018-11-24 21:39:18 +00:00
loop = false;
2021-01-12 22:02:29 +00:00
}
2018-11-24 21:39:18 +00:00
break;
case IDCMP_CLOSEWINDOW:
loop = false;
break;
}
GT_ReplyIMsg(msg);
}
}
2021-01-12 22:16:18 +00:00
if (sigrcvd & procPortSigMask)
2018-11-24 21:39:18 +00:00
{
2021-01-12 22:02:29 +00:00
struct ApplicationMesage *msg;
2021-01-12 22:16:18 +00:00
while ((msg = (struct ApplicationMesage *)GetNewMessage(MSGPORT_WINDOW)))
2018-11-24 21:39:18 +00:00
{
2021-01-12 22:02:29 +00:00
long msgId = msg->MsgId;
2018-11-24 21:39:18 +00:00
ReplyMsg((struct Message *)msg);
2021-01-12 22:16:18 +00:00
switch (msgId)
2021-01-12 22:02:29 +00:00
{
2021-01-12 22:16:18 +00:00
case ATK_SHUTDOWN:
loop = false;
break;
case ATK_LASTSYNC:
ShowLastSync((struct timeval *)&LastSync);
break;
case ATK_TZ_CHANGED:
ShowNewTimezone();
break;
case ATK_SHOW:
WindowToFront(SettingWindow.Window);
break;
default:
break;
2021-01-12 22:02:29 +00:00
}
}
2018-11-24 21:39:18 +00:00
}
} while (loop);
}
static void HandleGadgetUp(struct Gadget *gadget)
{
switch (gadget->GadgetID)
{
case GID_SERVER:
2021-01-12 22:16:18 +00:00
ReadUiServer();
2018-11-24 21:39:18 +00:00
break;
case GID_PORT:
2021-01-12 22:16:18 +00:00
ReadUiPort();
2018-11-24 21:39:18 +00:00
break;
case GID_INTERVAL:
2021-01-12 22:16:18 +00:00
ReadUiInterval();
2018-11-24 21:39:18 +00:00
break;
case GID_TIMEOUT:
2021-01-12 22:16:18 +00:00
ReadUiTimeout();
2018-11-24 21:39:18 +00:00
break;
case GID_THRESHOLD:
2021-01-12 22:16:18 +00:00
ReadUiThreshold();
2018-11-24 21:39:18 +00:00
break;
case GID_PRIORITY:
2021-01-12 22:16:18 +00:00
ReadUiCxPriority();
2018-11-24 21:39:18 +00:00
break;
case GID_SAVE:
2021-01-12 22:02:29 +00:00
UseSettings();
InitWindowSettings();
2021-01-12 22:16:18 +00:00
SendBrokerMessage(ATK_STORE);
2018-11-24 21:39:18 +00:00
break;
case GID_USE:
UseSettings();
InitWindowSettings();
2021-01-12 22:16:18 +00:00
SendBrokerMessage(ATK_APPLY);
2018-11-24 21:39:18 +00:00
break;
case GID_CANCEL:
2021-01-12 22:16:18 +00:00
SendBrokerMessage(ATK_UNDO);
2018-11-24 21:39:18 +00:00
break;
default:
break;
}
}