365 lines
8.9 KiB
C++
365 lines
8.9 KiB
C++
|
|
// ------------------------------------------------------------------
|
|
// GoldED+
|
|
// Copyright (C) 1990-1999 Odinn Sorensen
|
|
// Copyright (C) 1999-2000 Alexander S. Aganichev
|
|
// ------------------------------------------------------------------
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License as
|
|
// published by the Free Software Foundation; either version 2 of the
|
|
// License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
// MA 02111-1307 USA
|
|
// ------------------------------------------------------------------
|
|
// $Id$
|
|
// ------------------------------------------------------------------
|
|
// Global utility functions.
|
|
// ------------------------------------------------------------------
|
|
|
|
#include <golded.h>
|
|
#include <gwinput.h>
|
|
|
|
extern bool akamatchreply;
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
int edit_string(char* buf, int buf_size, char* title, int helpcat) {
|
|
|
|
gwindow window;
|
|
|
|
window.openxy(inforow,((MAXCOL-63)/2)-1,3,63,W_BASK,C_ASKB,C_ASKW);
|
|
window.title(title, C_ASKT);
|
|
if(CFG->switches.get(screenshadows))
|
|
window.shadow(C_SHADOW);
|
|
|
|
gwinput2 iform(window);
|
|
|
|
std::string buf2 = buf;
|
|
iform.setup(C_ASKW, C_ASKW, C_ASKQ, _box_table(W_BASK, 13), true);
|
|
iform.add_field(0, 0, 1, 59, buf2, buf_size, gwinput::cvt_none, fieldupd);
|
|
vcurshow();
|
|
iform.run(helpcat);
|
|
vcurhide();
|
|
|
|
window.close();
|
|
|
|
if(iform.dropped)
|
|
return false;
|
|
|
|
size_t len = buf2.length();
|
|
while(len and ('!' > buf2[--len]))
|
|
buf2.erase(len, 1);
|
|
strcpy(buf, buf2.c_str());
|
|
return make_bool(*buf);
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
bool edit_pathname(char* buf, int buf_size, char* title, int helpcat) {
|
|
|
|
if(not edit_string(buf, buf_size, title, helpcat))
|
|
return false;
|
|
|
|
std::vector<FileAlias>::iterator z;
|
|
for(z = CFG->filealias.begin(); z != CFG->filealias.end(); z++) {
|
|
if(strieql(buf, z->alias)) {
|
|
strcpy(buf, z->file);
|
|
break;
|
|
}
|
|
}
|
|
|
|
strschg_environ(buf);
|
|
return true;
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
bool PopupLocked(long tries, int isopen, const char* file) {
|
|
|
|
// Close popup window if requested
|
|
if(tries == 0) {
|
|
w_info(NULL);
|
|
return true;
|
|
}
|
|
|
|
// Tell the world
|
|
char buf[200];
|
|
if((uint) strlen(file) > (uint) (MAXCOL-25))
|
|
sprintf(buf, "[..]%*.*s", MAXCOL-30, MAXCOL-30, file);
|
|
else
|
|
strcpy(buf, file);
|
|
w_infof(LNG->WaitLocked, buf);
|
|
update_statuslinef(LNG->RetryOrESC, "ST_RETRYORESC", isopen ? LNG->RetryLock : LNG->RetryOpen , tries);
|
|
|
|
// Check for keypress
|
|
if(kbxhit()) {
|
|
|
|
// Return fail value if Escape was pressed
|
|
gkey keyval = kbxget();
|
|
if(keyval == Key_Esc) {
|
|
GMenuLockLoop MenuLockLoop;
|
|
if(MenuLockLoop.Run()) {
|
|
w_info(NULL);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Pause approx 1 second before trying again
|
|
#ifndef __BEOS__
|
|
usleep(1000);
|
|
#else
|
|
sleep(1);
|
|
#endif
|
|
// Try again
|
|
return true;
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
// Build zonegate address from orig/dest address
|
|
|
|
void ZonegateIt(ftn_addr& gate, ftn_addr& orig, ftn_addr& dest) {
|
|
|
|
gate.zone = orig.zone; // Send to the local zoneGate
|
|
gate.net = orig.zone;
|
|
gate.node = dest.zone;
|
|
gate.point = 0;
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
int GetAkaNo(const ftn_addr& aka) {
|
|
|
|
int akano = 0;
|
|
while(akano < CFG->aka.size()) {
|
|
if(CFG->aka[akano].addr.equals(aka))
|
|
return akano;
|
|
akano++;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
void doinvalidate(char* text, const char* find, const char* replace, bool is_tearline) {
|
|
|
|
int n = strlen(find);
|
|
if(strnieql(text, find, n) and (not is_tearline or (text[n] == NUL) or isspace(text[n]))) {
|
|
char buf[256];
|
|
|
|
strcpy(buf, text);
|
|
strcpy(stpcpy(text, replace), &buf[n]);
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
int AkaMatchOne(const ftn_addr* mask, const ftn_addr* addr) {
|
|
|
|
int match = 0;
|
|
|
|
// Count matching parts
|
|
if((mask->zone == 0) or (addr->zone == 0) or (mask->zone == GFTN_ALL) or (mask->zone == addr->zone)) {
|
|
match++;
|
|
if((mask->net == GFTN_ALL) or (mask->net == addr->net)) {
|
|
match++;
|
|
if((mask->node == GFTN_ALL) or (mask->node == addr->node)) {
|
|
match++;
|
|
if((mask->point == GFTN_ALL) or (mask->point == addr->point)) {
|
|
match++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return match;
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
int AkaMatch(ftn_addr* match, const ftn_addr* addr) {
|
|
|
|
int aka;
|
|
std::vector<AkaMatchG>::iterator am;
|
|
|
|
for(am = CFG->akamatch.begin(), aka=0; am != CFG->akamatch.end(); am++, aka++) {
|
|
if(addr->match(am->mask)) {
|
|
int akano = GetAkaNo(am->aka);
|
|
if(akano != -1) {
|
|
*match = CFG->aka[akano].addr;
|
|
return akano;
|
|
}
|
|
}
|
|
}
|
|
|
|
int bestaka = -1;
|
|
int bestmatch = 0;
|
|
int matchaka = 0;
|
|
std::vector<gaka>::iterator a;
|
|
|
|
for(a = CFG->aka.begin(), aka = 0; a != CFG->aka.end(); aka++, a++) {
|
|
|
|
if(match->equals(a->addr))
|
|
{
|
|
if (CFG->akamatchfromto && akamatchreply)
|
|
return aka;
|
|
else
|
|
matchaka = aka;
|
|
}
|
|
|
|
// Ignore fakenet addresses
|
|
if(a->addr.net != a->pointnet) {
|
|
|
|
int match = AkaMatchOne(&a->addr, addr);
|
|
|
|
// Note if we found a better match
|
|
if(match > bestmatch) {
|
|
bestmatch = match;
|
|
bestaka = aka;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If there was no matching aka, use the aka
|
|
if(bestaka == -1)
|
|
bestaka = matchaka;
|
|
else {
|
|
// If the current address matches at least as good as the best match, don't change it
|
|
if(bestmatch <= AkaMatchOne(match, addr)) {
|
|
int akano = GetAkaNo(*match);
|
|
if(akano != -1)
|
|
return akano;
|
|
}
|
|
}
|
|
|
|
*match = CFG->aka[bestaka].addr;
|
|
return bestaka;
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
void ScreenBlankIdle() {
|
|
|
|
static int whb = -1;
|
|
static int whh = -1;
|
|
static int wascurhid = false;
|
|
static Clock lastmoved = 0;
|
|
int windowheight = 4;
|
|
|
|
IdleCheckSemaphores();
|
|
|
|
char blankmsg1[80];
|
|
char blankmsg2[80];
|
|
|
|
time32_t t = gtime(NULL);
|
|
struct tm tm; glocaltime(&tm, &t);
|
|
sprintf(blankmsg1, " %s %s %s ", __gver_longpid__, __gver_ver__, strftimei(blankmsg2, 40, LNG->StatusLineTimeFmt, &tm));
|
|
sprintf(blankmsg2, " %s ", LNG->BlankMsg);
|
|
|
|
if (strblank(blankmsg2))
|
|
{
|
|
*blankmsg2 = NUL;
|
|
windowheight--;
|
|
}
|
|
|
|
int b1 = strlen(blankmsg1);
|
|
int b2 = strlen(blankmsg2);
|
|
int blankmsglen = MaxV(b1,b2);
|
|
int ry = rand() % (MAXROW-windowheight);
|
|
int rx = rand() % ((MAXCOL-blankmsglen)-2);
|
|
|
|
if(blanked and (whb == -1)) {
|
|
wascurhid = vcurhidden();
|
|
vcurhide();
|
|
if (C_BACKB != (BLACK_|_BLACK))
|
|
gvid->setoverscan(BLACK_|_BLACK);
|
|
whb = wopen(0,0,MAXROW-1,MAXCOL-1, 5, LGREY_|_BLACK, LGREY_|_BLACK);
|
|
if(CFG->screenblankertype == BLANK_SLIDEWIN)
|
|
whh = wopen_(ry, rx, windowheight, blankmsglen+2, W_BINFO, C_INFOB, C_INFOW);
|
|
lastmoved = gkbd.tickvalue;
|
|
}
|
|
|
|
if(not blanked and (whb != -1)) {
|
|
if(CFG->screenblankertype == BLANK_SLIDEWIN) {
|
|
wactiv_(whh);
|
|
wclose();
|
|
whh = -1;
|
|
}
|
|
wactiv_(whb);
|
|
wclose();
|
|
whb = -1;
|
|
if (C_BACKB != (BLACK_|_BLACK))
|
|
gvid->setoverscan(C_BACKB);
|
|
if(wascurhid)
|
|
vcurhide();
|
|
else
|
|
vcurshow();
|
|
return;
|
|
}
|
|
|
|
if(gkbd.tickvalue > (lastmoved+50L)) {
|
|
lastmoved = gkbd.tickvalue;
|
|
if(CFG->screenblankertype == BLANK_SLIDEWIN)
|
|
wslide(ry, rx);
|
|
}
|
|
|
|
if(CFG->screenblankertype == BLANK_SLIDEWIN) {
|
|
wcenters(0, C_INFOW, blankmsg1);
|
|
if(*blankmsg2)
|
|
wcenters(1, C_INFOW, blankmsg2);
|
|
}
|
|
|
|
// If timed out, exit screenblanker
|
|
if (CFG->timeout)
|
|
{
|
|
if (gkbd.tickvalue < gkbd.tickpress)
|
|
gkbd.tickpress = gkbd.tickvalue;
|
|
if (gkbd.tickvalue >= (gkbd.tickpress+(CFG->timeout*10L)))
|
|
kbput(Key_Tick);
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
vattr GetColorName(const char *name, Addr &addr, vattr color)
|
|
{
|
|
bool addr_valid = addr.valid();
|
|
bool name_valid = (name != NULL);
|
|
|
|
if (!addr_valid && !name_valid)
|
|
return color;
|
|
|
|
std::vector< std::pair<Node, vattr> >::iterator it;
|
|
for (it = CFG->colorname.begin(); it != CFG->colorname.end(); it++)
|
|
{
|
|
if (addr_valid && addr.match(it->first.addr))
|
|
return it->second;
|
|
if (name_valid && gwildmat(name, it->first.name))
|
|
return it->second;
|
|
}
|
|
|
|
return color;
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|