File indexing completed on 2024-03-24 04:05:23
0001 // 0002 // C++ Implementation: cmxpmanager 0003 // 0004 // Description: 0005 // 0006 /* 0007 Copyright 2004-2011 Tomas Mecir <kmuddy@kmuddy.com> 0008 0009 This program is free software; you can redistribute it and/or 0010 modify it under the terms of the GNU General Public License as 0011 published by the Free Software Foundation; either version 2 of 0012 the License, or (at your option) any later version. 0013 0014 This program is distributed in the hope that it will be useful, 0015 but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0017 GNU General Public License for more details. 0018 0019 You should have received a copy of the GNU General Public License 0020 along with this program. If not, see <http://www.gnu.org/licenses/>. 0021 */ 0022 0023 #include "cmxpmanager.h" 0024 0025 #ifdef HAVE_MXP 0026 0027 #include "cgaugelist.h" 0028 #include "cglobalsettings.h" 0029 #include "cprofilesettings.h" 0030 #include "cstatusvarlist.h" 0031 #include "ctelnet.h" 0032 #include "cvariablelist.h" 0033 #include "kmuddy-version.h" 0034 #include "cmxpconsole.h" 0035 0036 #include <KLocalizedString> 0037 0038 // from ctextchunk.h 0039 #define ATTRIB_BOLD 1 0040 #define ATTRIB_ITALIC 2 0041 #define ATTRIB_UNDERLINE 4 0042 #define ATTRIB_STRIKEOUT 8 0043 0044 #endif 0045 0046 cMXPManager::cMXPManager (int sess) : cActionBase ("mxpmanager", sess) 0047 { 0048 #ifdef HAVE_MXP 0049 havehandler = false; 0050 reset (); 0051 addEventHandler ("connected", 100, PT_NOTHING); 0052 addGlobalEventHandler ("global-settings-changed", 50, PT_NOTHING); 0053 #endif 0054 } 0055 0056 cMXPManager::~cMXPManager () 0057 { 0058 #ifdef HAVE_MXP 0059 removeEventHandler ("connected"); 0060 removeGlobalEventHandler ("global-settings-changed"); 0061 0062 if (havehandler) 0063 mxpDestroyHandler (h); 0064 havehandler = false; 0065 #endif 0066 } 0067 0068 #ifdef HAVE_MXP 0069 0070 void cMXPManager::eventNothingHandler (QString event, int) 0071 { 0072 if (event == "connected") 0073 reset (); 0074 if (event == "global-settings-changed") { 0075 cGlobalSettings *gs = cGlobalSettings::self(); 0076 setDefaultFont (gs->getFont ("console-font"), 0077 gs->getColor ("color-" + QString::number(gs->getInt ("fg-color"))), 0078 gs->getColor ("color-" + QString::number(gs->getInt ("bg-color")))); 0079 } 0080 } 0081 0082 QString cMXPManager::actionIntHandler (QString action, int, int par1, int /*par2*/) 0083 { 0084 if (action == "set-active") { 0085 setMXPActive (par1 != 0); 0086 } 0087 return QString(); 0088 } 0089 0090 QString cMXPManager::actionNothingHandler (QString action, int) 0091 { 0092 if (action == "switch-open") switchToOpenMode (); 0093 return QString(); 0094 } 0095 0096 void cMXPManager::setMXPActive (bool active) 0097 { 0098 if (active == mxpactive) 0099 return; //nothing to do 0100 0101 if (active) 0102 { 0103 if (!havehandler) 0104 initLibrary (); 0105 } 0106 0107 mxpactive = active; 0108 } 0109 0110 void cMXPManager::processText (const QString &text) 0111 { 0112 if (!havehandler) 0113 return; 0114 0115 //give the text to the library 0116 mxpProcessText (h, text.toLocal8Bit().data()); 0117 0118 //process each result 0119 while (mxpHasResults (h)) { 0120 mxpResult *res = mxpNextResult (h); 0121 if (res->type >= 2) //got some MXP stuff... 0122 mxpinuse = true; 0123 processResult (res); 0124 }; 0125 } 0126 0127 void cMXPManager::switchToOpenMode () 0128 { 0129 if (!havehandler) 0130 return; 0131 mxpSwitchToOpen (h); 0132 } 0133 0134 void cMXPManager::setDefaultFont (QFont font, QColor fg, QColor bg) 0135 { 0136 deffont = font; 0137 deffg = fg; 0138 defbg = bg; 0139 //send font info to the lib, if we have a handler 0140 if (havehandler) 0141 sendDefaultFont (); 0142 } 0143 0144 void cMXPManager::processResult (mxpResult *res) 0145 { 0146 switch (res->type) { 0147 case 0: { /* NOTHING */ } 0148 break; 0149 case 1: { //text or newline or SBR 0150 char *s = (char *) res->data; 0151 if (s && (strcmp (s, "\r\n") == 0)) //newlines are always sent separately 0152 emit gotNewLine (); 0153 else 0154 if (s && ((s[0] == 0x1f) && (s[1] == '\0'))) 0155 //<SBR> tag - ignored - converted into a space 0156 emit gotNewText (QString (" ")); 0157 else 0158 emit gotNewText (s ? QString::fromLocal8Bit (s) : QString ("")); 0159 } 0160 break; 0161 case 3: { 0162 // NOTHING HERE YET 0163 } 0164 break; 0165 case 4: { //variable 0166 varStruct *vs = (varStruct *) res->data; 0167 char *n = vs->name; 0168 char *v = vs->value; 0169 cVariableList *vl = dynamic_cast<cVariableList *>(object ("variables")); 0170 cProfileSettings *sett = settings(); 0171 if (sett && n) //we need a profile and a variable name 0172 { 0173 QString prefix = sett->getString ("mxp-variable-prefix"); 0174 if (vs->erase) 0175 //erase that variable 0176 vl->unset (prefix + QString(n)); 0177 else 0178 //set that variable 0179 vl->set (prefix+QString(n), v ? QString::fromLocal8Bit(v) : QString()); 0180 } 0181 } 0182 break; 0183 case 5: { //formatting 0184 formatStruct *fs = (formatStruct *) res->data; 0185 unsigned char mask = fs->usemask; 0186 0187 //colors 0188 if (mask & USE_FG) 0189 emit gotFgColor (toColor (fs->fg)); 0190 if (mask & USE_BG) 0191 emit gotBgColor (toColor (fs->bg)); 0192 0193 //font and font size: IGNORED 0194 0195 //attributes 0196 int oldattrib = curattrib; 0197 if (mask & USE_BOLD) 0198 curattrib = (fs->attributes & Bold) ? (curattrib | ATTRIB_BOLD) : 0199 (curattrib & ~ATTRIB_BOLD); 0200 if (mask & USE_ITALICS) 0201 curattrib = (fs->attributes & Italic) ? (curattrib | ATTRIB_ITALIC) : 0202 (curattrib & ~ATTRIB_ITALIC); 0203 if (mask & USE_UNDERLINE) 0204 curattrib = (fs->attributes & Underline) ? (curattrib | ATTRIB_UNDERLINE) : 0205 (curattrib & ~ATTRIB_UNDERLINE); 0206 if (mask & USE_STRIKEOUT) 0207 curattrib = (fs->attributes & Strikeout) ? (curattrib | ATTRIB_STRIKEOUT) : 0208 (curattrib & ~ATTRIB_STRIKEOUT); 0209 if (curattrib != oldattrib) //attributes have changed somehow 0210 emit gotAttrib (curattrib); 0211 } 0212 break; 0213 case 6: { //A-link 0214 linkStruct *ls = (linkStruct *) res->data; 0215 QString name = ls->name ? QString::fromLocal8Bit (ls->name) : QString(); 0216 QString url = ls->url ? QString::fromLocal8Bit (ls->url) : QString(); 0217 QString text = ls->text ? QString::fromLocal8Bit (ls->text) : QString(); 0218 QString hint = ls->hint ? QString::fromLocal8Bit (ls->hint) : QString(); 0219 emit gotALink (name, url, text, hint); 0220 } 0221 break; 0222 case 7: { //SEND-link 0223 sendStruct *ss = (sendStruct *) res->data; 0224 QString name = ss->name ? QString::fromLocal8Bit (ss->name) : QString(); 0225 QString command = ss->command ? QString::fromLocal8Bit (ss->command) : QString(); 0226 QString text = ss->text ? QString::fromLocal8Bit (ss->text) : QString(); 0227 QString hint = ss->hint ? QString::fromLocal8Bit (ss->hint) : QString(); 0228 emit gotSENDLink (name, command, text, hint, ss->toprompt, ss->ismenu); 0229 } 0230 break; 0231 case 8: { //expire link 0232 char *name = (char *) res->data; 0233 if (name) 0234 emit gotExpire (QString (name)); 0235 else 0236 emit gotExpire (QString()); 0237 } 0238 break; 0239 case 9: { //send this 0240 char *s = (char *) res->data; 0241 cTelnet *telnet = dynamic_cast<cTelnet *>(object ("telnet")); 0242 telnet->sendData (s); 0243 } 0244 break; 0245 case 11: { //sound/music 0246 soundStruct *ss = (soundStruct *) res->data; 0247 QString fName = ss->fname ? QString (ss->fname) : QString(); 0248 QString url = ss->url ? QString (ss->url) : QString(); 0249 QString type = ss->type ? QString (ss->type) : QString(); 0250 int priority = ss->isSOUND ? ss->priority : (ss->continuemusic ? 1 : 0); 0251 0252 cTelnet *telnet = dynamic_cast<cTelnet *>(object ("telnet")); 0253 telnet->processSoundRequest (ss->isSOUND, fName, ss->vol, ss->repeats, 0254 priority, type, url); 0255 } 0256 break; 0257 case 22: { //gauge 0258 /* 0259 // TODO We need to re-enable the MXP gauges ! 0260 gaugeStruct *gs = (gaugeStruct *) res->data; 0261 QString var = gs->variable ? QString (gs->variable) : QString(); 0262 QString maxvar = gs->maxvariable ? QString (gs->maxvariable) : QString(); 0263 QString caption = gs->caption ? QString::fromLocal8Bit (gs->caption) : QString(); 0264 QColor color = toColor (gs->color); 0265 0266 cGaugeList *gl = dynamic_cast<cGaugeList *>(object ("gaugelist")); 0267 if (gl && (!var.isEmpty())) 0268 gl->requestGauge (var, maxvar, caption, color, false); 0269 */ 0270 } 0271 break; 0272 case 23: { //status bar 0273 /* 0274 // TODO We need to re-enable the MXP status variables ! 0275 statStruct *ss = (statStruct *) res->data; 0276 QString var = ss->variable ? QString (ss->variable) : QString(); 0277 QString maxvar = ss->maxvariable ? QString (ss->maxvariable) : QString(); 0278 QString caption = ss->caption ? QString::fromLocal8Bit (ss->caption) : QString(); 0279 0280 cStatusVarList *svl = dynamic_cast<cStatusVarList *>(object ("statusvarlist")); 0281 if (svl && (!var.isEmpty())) 0282 svl->requestStatusVar (var, maxvar, caption, false, false); 0283 */ 0284 } 0285 break; 0286 case -1: { //error 0287 char *s = (char *) res->data; 0288 cMXPConsole::self()->addError (sess(), QString::fromLocal8Bit (s)); 0289 } 0290 break; 0291 case -2: { //warning 0292 char *s = (char *) res->data; 0293 cMXPConsole::self()->addWarning (sess(), QString::fromLocal8Bit (s)); 0294 } 0295 break; 0296 default: { 0297 QString reqName; 0298 switch (res->type) { 0299 case 2: reqName = i18n ("line tag"); break; 0300 case 8: reqName = i18n ("expire link"); break; 0301 case 10: reqName = i18n ("horizontal line"); break; 0302 case 12: reqName = i18n ("create window"); break; 0303 case 13: reqName = i18n ("create internal window"); break; 0304 case 14: reqName = i18n ("close window"); break; 0305 case 15: reqName = i18n ("set active window"); break; 0306 case 16: reqName = i18n ("move cursor"); break; 0307 case 17: reqName = i18n ("erase text"); break; 0308 case 18: reqName = i18n ("relocate"); break; 0309 case 19: reqName = i18n ("send username/password"); break; 0310 case 20: reqName = i18n ("image"); break; 0311 case 21: reqName = i18n ("image map"); break; 0312 default: reqName = i18n ("unknown"); break; 0313 }; 0314 cMXPConsole::self()->addWarning (sess(), i18n ("Ignoring unsupported MXP request (%1)", reqName)); 0315 } 0316 break; 0317 }; 0318 } 0319 0320 QColor cMXPManager::toColor (RGB mxpColor) 0321 { 0322 return QColor (mxpColor.r, mxpColor.g, mxpColor.b); 0323 } 0324 0325 void cMXPManager::sendDefaultFont () 0326 { 0327 const char *name = deffont.family ().toLatin1().data(); 0328 int size = deffont.pointSize (); 0329 bool bold = deffont.bold (); 0330 bool italics = deffont.italic (); 0331 bool underline = deffont.underline (); 0332 bool strikeout = deffont.strikeOut (); 0333 RGB fg, bg; 0334 fg.r = deffg.red (); 0335 fg.g = deffg.green (); 0336 fg.b = deffg.blue (); 0337 bg.r = defbg.red (); 0338 bg.g = defbg.green (); 0339 bg.b = defbg.blue (); 0340 0341 //remember current attributes 0342 curattrib = ATTRIB_BOLD * (bold?1:0) + ATTRIB_ITALIC * (italics?1:0) + 0343 ATTRIB_UNDERLINE * (underline?1:0) + ATTRIB_STRIKEOUT * (strikeout?1:0); 0344 0345 mxpSetDefaultText (h, name, size, bold, italics, underline, strikeout, fg, bg); 0346 mxpSetNonProportFont (h, name); 0347 //header params... most of these aren't used anyway ;) 0348 mxpSetHeaderParams (h, 1, name, size * 3, true, false, true, false, fg, bg); 0349 mxpSetHeaderParams (h, 2, name, size * 2, true, false, false, false, fg, bg); 0350 mxpSetHeaderParams (h, 3, name, size * 3 / 2, true, false, false, false, fg, bg); 0351 mxpSetHeaderParams (h, 4, name, size * 4 / 3, true, false, false, false, fg, bg); 0352 mxpSetHeaderParams (h, 5, name, size + 2, true, false, false, false, fg, bg); 0353 mxpSetHeaderParams (h, 6, name, size, true, false, false, false, fg, bg); 0354 } 0355 0356 void cMXPManager::initLibrary () 0357 { 0358 h = mxpCreateHandler (); 0359 0360 mxpSetClient (h, PACKAGE, VERSION); 0361 sendDefaultFont (); 0362 0363 //set supported features... 0364 mxpSupportsLink (h, true); 0365 mxpSupportsGauge (h, true); 0366 mxpSupportsStatus (h, true); 0367 mxpSupportsSound (h, true); 0368 mxpSupportsFrame (h, false); 0369 mxpSupportsImage (h, false); 0370 mxpSupportsRelocate (h, false); 0371 0372 //mxpSetScreenProps is not issued, because we don't need it yet 0373 0374 havehandler = true; 0375 } 0376 0377 #endif 0378 0379 //slot - must always exist 0380 void cMXPManager::reset () 0381 { 0382 #ifdef HAVE_MXP 0383 0384 if (havehandler) 0385 mxpDestroyHandler (h); 0386 havehandler = false; 0387 mxpactive = false; 0388 mxpinuse = false; 0389 deffont.setFamily ("fixed"); //some default font, will be changed when settings are loaded 0390 deffg = Qt::lightGray; 0391 defbg = Qt::black; 0392 curattrib = 0; 0393 0394 #endif //HAVE_MXP 0395 } 0396 0397 #include "moc_cmxpmanager.cpp"