00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <qvaluevector.h>
00023 #include <qregexp.h>
00024
00025 #include "Engine.h"
00026 #include "ParseNode.h"
00027 #include "ParseBinary.h"
00028 #include "ParseText.h"
00029 #include "Root.h"
00030 #include "Groups.h"
00031 #include "ASN1Codes.h"
00032 #include "Logging.h"
00033 #include "freemheg.h"
00034 #include "Visible.h"
00035
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <stdarg.h>
00039
00040
00041 MHEG *MHCreateEngine(MHContext *context)
00042 {
00043 return new MHEngine(context);
00044 }
00045
00046 MHEngine::MHEngine(MHContext *context): m_Context(context)
00047 {
00048 m_fInTransition = false;
00049 m_ApplicationStack.setAutoDelete(true);
00050 m_EventQueue.setAutoDelete(true);
00051 m_ExternContentTable.setAutoDelete(true);
00052
00053 m_fBooting = true;
00054 m_Interacting = 0;
00055 }
00056
00057 MHEngine::~MHEngine()
00058 {
00059 }
00060
00061
00062 #define CONTENT_CHECK_TIME 2000
00063
00064
00065 int MHEngine::RunAll()
00066 {
00067
00068 if (m_fBooting) {
00069
00070 m_ApplicationStack.clear();
00071 m_EventQueue.clear();
00072 m_ExternContentTable.clear();
00073 m_LinkTable.clear();
00074
00075
00076
00077 MHObjectRef startObj;
00078 startObj.m_nObjectNo = 0;
00079 startObj.m_GroupId.Copy(MHOctetString("~//a"));
00080
00081
00082
00083
00084 if (! Launch(startObj))
00085 {
00086 startObj.m_GroupId.Copy(MHOctetString("~//startup"));
00087 if (! Launch(startObj))
00088 return -1;
00089 }
00090 m_fBooting = false;
00091 }
00092
00093 int nNextTime = 0;
00094 do {
00095
00096 if (m_Context->CheckStop()) return 0;
00097
00098
00099 RunActions();
00100
00101
00102
00103
00104
00105 CheckContentRequests();
00106
00107
00108 if (CurrentScene()) {
00109 int next = CurrentScene()->CheckTimers(this);
00110 if (nNextTime == 0 || nNextTime > next) nNextTime = next;
00111 }
00112 if (CurrentApp()) {
00113
00114 int nAppTime = CurrentApp()->CheckTimers(this);
00115 if (nAppTime != 0 && (nNextTime == 0 || nAppTime < nNextTime)) nNextTime = nAppTime;
00116 }
00117 if (! m_ExternContentTable.isEmpty()) {
00118
00119 if (nNextTime == 0 || nNextTime > CONTENT_CHECK_TIME) nNextTime = CONTENT_CHECK_TIME;
00120 }
00121
00122 if (! m_EventQueue.isEmpty()) {
00123 MHAsynchEvent *pEvent = m_EventQueue.first();
00124 MHLOG(MHLogLinks, QString("Asynchronous event dequeued - %1 from %2")
00125 .arg(MHLink::EventTypeToString(pEvent->eventType))
00126 .arg(pEvent->pEventSource->m_ObjectReference.Printable()));
00127 CheckLinks(pEvent->pEventSource->m_ObjectReference, pEvent->eventType, pEvent->eventData);
00128 m_EventQueue.removeFirst();
00129 }
00130 } while (! m_EventQueue.isEmpty() || ! m_ActionStack.isEmpty());
00131
00132
00133 if (! m_redrawRegion.isEmpty()) {
00134 m_Context->RequireRedraw(m_redrawRegion);
00135 m_redrawRegion = QRegion();
00136 }
00137
00138 return nNextTime;
00139 }
00140
00141
00142
00143 MHGroup *MHEngine::ParseProgram(QByteArray &text)
00144 {
00145 if (text.size() == 0) return NULL;
00146
00147
00148
00149
00150 unsigned char ch = text[0];
00151 MHParseBase *parser = NULL;
00152 MHParseNode *pTree = NULL;
00153 MHGroup *pRes = NULL;
00154 if (ch >= 128) parser = new MHParseBinary(text);
00155 else parser = new MHParseText(text);
00156
00157 try {
00158
00159 pTree = parser->Parse();
00160
00161 switch (pTree->GetTagNo()) {
00162 case C_APPLICATION: pRes = new MHApplication; break;
00163 case C_SCENE: pRes = new MHScene; break;
00164 default: pTree->Failure("Expected Application or Scene");
00165 }
00166 pRes->Initialise(pTree, this);
00167 delete(pTree);
00168 delete(parser);
00169 }
00170 catch (...) {
00171 delete(parser);
00172 delete(pTree);
00173 delete(pRes);
00174 throw;
00175 }
00176 return pRes;
00177 }
00178
00179
00180 bool MHEngine::Launch(const MHObjectRef &target, bool fIsSpawn)
00181 {
00182 QString csPath = GetPathName(target.m_GroupId);
00183 if (csPath.length() == 0) return false;
00184 if (m_fInTransition) {
00185 MHLOG(MHLogWarning, "Launch during transition - ignoring");
00186 return false;
00187 }
00188 QByteArray text;
00189
00190
00191 if (! m_Context->GetCarouselData(csPath, text)) return false;
00192
00193 m_fInTransition = true;
00194 try {
00195 if (CurrentApp()) {
00196 if (fIsSpawn) {
00197 AddActions(CurrentApp()->m_CloseDown);
00198 RunActions();
00199 }
00200 if (CurrentScene()) CurrentScene()->Destruction(this);
00201 CurrentApp()->Destruction(this);
00202 if (! fIsSpawn) m_ApplicationStack.remove();
00203 }
00204
00205 MHApplication *pProgram = (MHApplication*)ParseProgram(text);
00206
00207 if ((__mhlogoptions & MHLogScenes) && __mhlogStream != 0) {
00208 pProgram->PrintMe(__mhlogStream, 0);
00209 }
00210
00211 if (! pProgram->m_fIsApp) MHERROR("Expected an application");
00212
00213
00214 pProgram->m_Path = csPath;
00215 int nPos = pProgram->m_Path.findRev('/');
00216 if (nPos < 0) pProgram->m_Path = "";
00217 else pProgram->m_Path = pProgram->m_Path.left(nPos);
00218
00219 m_ApplicationStack.push(pProgram);
00220
00221
00222
00223 m_EventQueue.clear();
00224
00225
00226 CurrentApp()->Activation(this);
00227 m_fInTransition = false;
00228 return true;
00229 }
00230 catch (...) {
00231 m_fInTransition = false;
00232 return false;
00233 }
00234 }
00235
00236 void MHEngine::Quit()
00237 {
00238 if (m_fInTransition) {
00239 MHLOG(MHLogWarning, "Quit during transition - ignoring");
00240 return;
00241 }
00242 m_fInTransition = true;
00243 if (CurrentScene()) CurrentScene()->Destruction(this);
00244 CurrentApp()->Destruction(this);
00245
00246
00247 m_EventQueue.clear();
00248
00249 m_ApplicationStack.remove();
00250
00251 if (m_ApplicationStack.isEmpty())
00252 m_fBooting = true;
00253 else {
00254 CurrentApp()->m_fRestarting = true;
00255 CurrentApp()->Activation(this);
00256
00257 }
00258 m_fInTransition = false;
00259 }
00260
00261 void MHEngine::TransitionToScene(const MHObjectRef &target)
00262 {
00263 int i;
00264 if (m_fInTransition) {
00265
00266 MHLOG(MHLogWarning, "TransitionTo during transition - ignoring");
00267 return;
00268 }
00269 if (target.m_GroupId.Size() == 0) return;
00270 QString csPath = GetPathName(target.m_GroupId);
00271 QByteArray text;
00272
00273 if (! m_Context->GetCarouselData(csPath, text)) return;
00274
00275
00276 MHGroup *pProgram = ParseProgram(text);
00277 if (pProgram->m_fIsApp) MHERROR("Expected a scene");
00278
00279 m_ActionStack.clear();
00280
00281
00282
00283 MHApplication *pApp = CurrentApp();
00284 for (i = pApp->m_Items.Size(); i > 0; i--) {
00285 MHIngredient *pItem = pApp->m_Items.GetAt(i-1);
00286 if (! pItem->IsShared()) pItem->Deactivation(this);
00287 }
00288 m_fInTransition = true;
00289 if (pApp->m_pCurrentScene) {
00290 pApp->m_pCurrentScene->Deactivation(this);
00291 pApp->m_pCurrentScene->Destruction(this);
00292 }
00293
00294
00295
00296
00297
00298
00299
00300 MHAsynchEvent *pEvent;
00301 for (pEvent = m_EventQueue.first(); pEvent != 0; ) {
00302 if (pEvent->pEventSource->IsShared()) pEvent = m_EventQueue.next();
00303 else { m_EventQueue.remove(); pEvent = m_EventQueue.current(); }
00304 }
00305
00306
00307 if (pApp->m_pCurrentScene) {
00308 delete(pApp->m_pCurrentScene);
00309 pApp->m_pCurrentScene = NULL;
00310 }
00311
00312 m_Interacting = 0;
00313
00314
00315 CurrentApp()->m_pCurrentScene = (MHScene*) pProgram;
00316 SetInputRegister(CurrentScene()->m_nEventReg);
00317 m_redrawRegion = QRegion(0, 0, CurrentScene()->m_nSceneCoordX, CurrentScene()->m_nSceneCoordY);
00318
00319 if ((__mhlogoptions & MHLogScenes) && __mhlogStream != 0) {
00320 pProgram->PrintMe(__mhlogStream, 0);
00321 }
00322 pProgram->Preparation(this);
00323 pProgram->Activation(this);
00324 m_fInTransition = false;
00325 }
00326
00327 void MHEngine::SetInputRegister(int nReg)
00328 {
00329 m_Context->SetInputRegister(nReg);
00330 }
00331
00332
00333 QString MHEngine::GetPathName(const MHOctetString &str)
00334 {
00335 QString csPath;
00336 if (str.Size() != 0) csPath = QString::fromUtf8((const char *)str.Bytes(), str.Size());
00337 if (csPath.left(4) == "DSM:") csPath = csPath.mid(4);
00338
00339 int firstColon = csPath.find(':'), firstSlash = csPath.find('/');
00340 if (firstColon > 0 && firstSlash > 0 && firstColon < firstSlash)
00341 return QString();
00342
00343 if (csPath.left(1) == "~") csPath = csPath.mid(1);
00344
00345 if (csPath.left(2) != "//") {
00346
00347 if (CurrentApp()) csPath = CurrentApp()->m_Path + csPath;
00348 }
00349
00350 int nPos;
00351 while ((nPos = csPath.find("/../")) >= 0) {
00352 int nEnd = nPos+4;
00353 while (nPos >= 1 && csPath[nPos-1] != '/') nPos--;
00354 csPath = csPath.left(nPos) + csPath.mid(nEnd);
00355 }
00356 return csPath;
00357 }
00358
00359
00360 MHRoot *MHEngine::FindObject(const MHObjectRef &oRef, bool failOnNotFound)
00361 {
00362
00363 MHGroup *pSearch = NULL;
00364 MHGroup *pScene = CurrentScene(), *pApp = CurrentApp();
00365 if (pScene && GetPathName(pScene->m_ObjectReference.m_GroupId) == GetPathName(oRef.m_GroupId)) pSearch = pScene;
00366 else if (pApp && GetPathName(pApp->m_ObjectReference.m_GroupId) == GetPathName(oRef.m_GroupId)) pSearch = pApp;
00367 if (pSearch) {
00368 MHRoot *pItem = pSearch->FindByObjectNo(oRef.m_nObjectNo);
00369 if (pItem) return pItem;
00370 }
00371 if (failOnNotFound) {
00372
00373
00374
00375
00376 MHLOG(MHLogWarning, QString("Reference %1 not found").arg(oRef.m_nObjectNo));
00377 throw "FindObject failed";
00378 }
00379 return NULL;
00380 }
00381
00382
00383 void MHEngine::RunActions()
00384 {
00385 while (! m_ActionStack.isEmpty()) {
00386
00387 MHElemAction *pAction = m_ActionStack.pop();
00388
00389 try {
00390 if ((__mhlogoptions & MHLogActions) && __mhlogStream != 0) {
00391 fprintf(__mhlogStream, "Action - "); pAction->PrintMe(__mhlogStream, 0); fflush(__mhlogStream);
00392 }
00393 pAction->Perform(this);
00394 }
00395 catch (char const *) {
00396 }
00397 }
00398 }
00399
00400
00401 void MHEngine::EventTriggered(MHRoot *pSource, enum EventType ev, const MHUnion &evData)
00402 {
00403 MHLOG(MHLogLinks, QString("Event - %1 from %2")
00404 .arg(MHLink::EventTypeToString(ev)).arg(pSource->m_ObjectReference.Printable()));
00405
00406 switch (ev) {
00407 case EventFirstItemPresented:
00408 case EventHeadItems:
00409 case EventHighlightOff:
00410 case EventHighlightOn:
00411 case EventIsAvailable:
00412 case EventIsDeleted:
00413 case EventIsDeselected:
00414 case EventIsRunning:
00415 case EventIsSelected:
00416 case EventIsStopped:
00417 case EventItemDeselected:
00418 case EventItemSelected:
00419 case EventLastItemPresented:
00420 case EventTailItems:
00421 case EventTestEvent:
00422 case EventTokenMovedFrom:
00423 case EventTokenMovedTo:
00424
00425
00426
00427
00428
00429 CheckLinks(pSource->m_ObjectReference, ev, evData);
00430 break;
00431 case EventAnchorFired:
00432 case EventAsyncStopped:
00433 case EventContentAvailable:
00434 case EventCounterTrigger:
00435 case EventCursorEnter:
00436 case EventCursorLeave:
00437 case EventEngineEvent:
00438 case EventEntryFieldFull:
00439 case EventInteractionCompleted:
00440 case EventStreamEvent:
00441 case EventStreamPlaying:
00442 case EventStreamStopped:
00443 case EventTimerFired:
00444 case EventUserInput:
00445 case EventFocusMoved:
00446 case EventSliderValueChanged:
00447 {
00448
00449 MHAsynchEvent *pEvent = new MHAsynchEvent;
00450 pEvent->pEventSource = pSource;
00451 pEvent->eventType = ev;
00452 pEvent->eventData = evData;
00453 m_EventQueue.append(pEvent);
00454 }
00455 }
00456 }
00457
00458
00459
00460
00461
00462
00463
00464 void MHEngine::CheckLinks(const MHObjectRef &sourceRef, enum EventType ev, const MHUnion &un)
00465 {
00466 for (int i = 0; i < (int)m_LinkTable.count(); i++)
00467 m_LinkTable.at(i)->MatchEvent(sourceRef, ev, un, this);
00468 }
00469
00470
00471 void MHEngine::AddLink(MHLink *pLink)
00472 {
00473 m_LinkTable.append(pLink);
00474 }
00475
00476 void MHEngine::RemoveLink(MHLink *pLink)
00477 {
00478 (void)m_LinkTable.removeRef(pLink);
00479 }
00480
00481
00482 void MHEngine::AddActions(const MHActionSequence &actions)
00483 {
00484
00485 for (int i = actions.Size(); i > 0; i--) m_ActionStack.push(actions.GetAt(i-1));
00486 }
00487
00488
00489 void MHEngine::AddToDisplayStack(MHVisible *pVis)
00490 {
00491 if (CurrentApp()->FindOnStack(pVis) != -1) return;
00492 CurrentApp()->m_DisplayStack.Append(pVis);
00493 Redraw(pVis->GetVisibleArea());
00494 }
00495
00496
00497 void MHEngine::RemoveFromDisplayStack(MHVisible *pVis)
00498 {
00499 int nPos = CurrentApp()->FindOnStack(pVis);
00500 if (nPos == -1) return;
00501 CurrentApp()->m_DisplayStack.RemoveAt(nPos);
00502 Redraw(pVis->GetVisibleArea());
00503 }
00504
00505
00506 void MHEngine::BringToFront(const MHRoot *p)
00507 {
00508 int nPos = CurrentApp()->FindOnStack(p);
00509 if (nPos == -1) return;
00510 MHVisible *pVis = (MHVisible*)p;
00511 CurrentApp()->m_DisplayStack.RemoveAt(nPos);
00512 CurrentApp()->m_DisplayStack.Append((MHVisible*)pVis);
00513 Redraw(pVis->GetVisibleArea());
00514 }
00515
00516 void MHEngine::SendToBack(const MHRoot *p)
00517 {
00518 int nPos = CurrentApp()->FindOnStack(p);
00519 if (nPos == -1) return;
00520 MHVisible *pVis = (MHVisible*)p;
00521 CurrentApp()->m_DisplayStack.RemoveAt(nPos);
00522 CurrentApp()->m_DisplayStack.InsertAt(pVis, 0);
00523 Redraw(pVis->GetVisibleArea());
00524 }
00525
00526 void MHEngine::PutBefore(const MHRoot *p, const MHRoot *pRef)
00527 {
00528 int nPos = CurrentApp()->FindOnStack(p);
00529 if (nPos == -1) return;
00530 MHVisible *pVis = (MHVisible*)p;
00531 int nRef = CurrentApp()->FindOnStack(pRef);
00532 if (nRef == -1) return;
00533 CurrentApp()->m_DisplayStack.RemoveAt(nPos);
00534 if (nRef >= nPos) nRef--;
00535 CurrentApp()->m_DisplayStack.InsertAt(pVis, nRef+1);
00536
00537
00538
00539 Redraw(pVis->GetVisibleArea());
00540 }
00541
00542 void MHEngine::PutBehind(const MHRoot *p, const MHRoot *pRef)
00543 {
00544 int nPos = CurrentApp()->FindOnStack(p);
00545 if (nPos == -1) return;
00546 int nRef = CurrentApp()->FindOnStack(pRef);
00547 if (nRef == -1) return;
00548 MHVisible *pVis = (MHVisible*)p;
00549 CurrentApp()->m_DisplayStack.RemoveAt(nPos);
00550 if (nRef >= nPos) nRef--;
00551 CurrentApp()->m_DisplayStack.InsertAt((MHVisible*)pVis, nRef);
00552 Redraw(pVis->GetVisibleArea());
00553 }
00554
00555
00556
00557
00558 void MHEngine::DrawRegion(QRegion toDraw, int nStackPos)
00559 {
00560 if (toDraw.isEmpty()) return;
00561
00562 while (nStackPos >= 0) {
00563 MHVisible *pItem = CurrentApp()->m_DisplayStack.GetAt(nStackPos);
00564
00565
00566 QRegion drawArea = pItem->GetVisibleArea() & toDraw;
00567 if (! drawArea.isEmpty()) {
00568
00569
00570 QRegion newDraw = toDraw - pItem->GetOpaqueArea();
00571 DrawRegion(newDraw, nStackPos-1);
00572
00573 pItem->Display(this);
00574 return;
00575 }
00576 nStackPos--;
00577 }
00578
00579
00580 m_Context->DrawBackground(toDraw);
00581 }
00582
00583
00584 void MHEngine::DrawDisplay(QRegion toDraw)
00585 {
00586 if (m_fBooting) return;
00587 int nTopStack = CurrentApp() == NULL ? -1 : CurrentApp()->m_DisplayStack.Size()-1;
00588 DrawRegion(toDraw, nTopStack);
00589 }
00590
00591
00592
00593 void MHEngine::Redraw(QRegion region)
00594 {
00595 m_redrawRegion += region;
00596 }
00597
00598
00599 void MHEngine::UnlockScreen()
00600 {
00601 if (CurrentApp()->m_nLockCount > 0) CurrentApp()->m_nLockCount--;
00602 }
00603
00604
00605
00606 void MHEngine::GenerateUserAction(int nCode)
00607 {
00608 MHScene *pScene = CurrentScene();
00609 if (! pScene) return;
00610
00611
00612
00613 switch (nCode)
00614 {
00615 case 104:
00616 case 105:
00617 EventTriggered(pScene, EventEngineEvent, 4);
00618 break;
00619 case 16:
00620 case 100:
00621 case 101:
00622 case 102:
00623 case 103:
00624 EventTriggered(pScene, EventEngineEvent, nCode);
00625 break;
00626 }
00627
00628
00629
00630 if (m_Interacting)
00631 m_Interacting->KeyEvent(this, nCode);
00632 else EventTriggered(pScene, EventUserInput, nCode);
00633 }
00634
00635
00636 void MHEngine::RequestExternalContent(MHIngredient *pRequester)
00637 {
00638
00639
00640 if (! pRequester->m_ContentRef.IsSet()) return;
00641
00642 CancelExternalContentRequest(pRequester);
00643 QString csPath = GetPathName(pRequester->m_ContentRef.m_ContentRef);
00644
00645
00646 if (csPath.isEmpty())
00647 return;
00648 QByteArray text;
00649 if (m_Context->CheckCarouselObject(csPath) && m_Context->GetCarouselData(csPath, text)) {
00650
00651 pRequester->ContentArrived((const unsigned char *)text.data(), text.size(), this);
00652 }
00653 else {
00654
00655 MHExternContent *pContent = new MHExternContent;
00656 pContent->m_FileName = csPath;
00657 pContent->m_pRequester = pRequester;
00658 m_ExternContentTable.append(pContent);
00659 }
00660 }
00661
00662
00663 void MHEngine::CancelExternalContentRequest(MHIngredient *pRequester)
00664 {
00665 for (MHExternContent *pContent = m_ExternContentTable.first(); pContent; pContent = m_ExternContentTable.next()) {
00666 if (pContent->m_pRequester == pRequester) {
00667 m_ExternContentTable.remove();
00668 return;
00669 }
00670 }
00671 }
00672
00673
00674 void MHEngine::CheckContentRequests()
00675 {
00676 for (MHExternContent *pContent = m_ExternContentTable.first(); pContent;) {
00677 QByteArray text;
00678 if (m_Context->CheckCarouselObject(pContent->m_FileName) && m_Context->GetCarouselData(pContent->m_FileName, text)) {
00679 pContent->m_pRequester->ContentArrived((const unsigned char *)text.data(), text.size(), this);
00680
00681 m_ExternContentTable.remove();
00682 pContent = m_ExternContentTable.current();
00683 }
00684 else pContent = m_ExternContentTable.next();
00685 }
00686 }
00687
00688 bool MHEngine::LoadStorePersistent(bool fIsLoad, const MHOctetString &fileName, const MHSequence<MHObjectRef *> &variables)
00689 {
00690
00691 MHPSEntry *pEntry = NULL;
00692 int i;
00693 for (i = 0; i < m_PersistentStore.Size(); i++) {
00694 pEntry = m_PersistentStore.GetAt(i);
00695 if (pEntry->m_FileName.Equal(fileName)) break;
00696 }
00697 if (i == m_PersistentStore.Size()) {
00698
00699 if (fIsLoad) return false;
00700
00701 pEntry = new MHPSEntry;
00702 pEntry->m_FileName.Copy(fileName);
00703 m_PersistentStore.Append(pEntry);
00704 }
00705 if (fIsLoad) {
00706
00707 if (pEntry->m_Data.Size() < variables.Size()) return false;
00708
00709 for (i = 0; i < variables.Size(); i++) {
00710 FindObject(*(variables.GetAt(i)))->SetVariableValue(*(pEntry->m_Data.GetAt(i)));
00711 }
00712 }
00713
00714 else {
00715
00716 while (pEntry->m_Data.Size() != 0) pEntry->m_Data.RemoveAt(0);
00717
00718 for (i = 0; i < variables.Size(); i++) {
00719 MHUnion *pValue = new MHUnion;
00720 pEntry->m_Data.Append(pValue);
00721 FindObject(*(variables.GetAt(i)))->GetVariableValue(*pValue, this);
00722 }
00723 }
00724 return true;
00725 }
00726
00727
00728 bool MHEngine::GetEngineSupport(const MHOctetString &feature)
00729 {
00730 QString csFeat = QString::fromUtf8((const char *)feature.Bytes(), feature.Size());
00731 QStringList strings = QStringList::split(QRegExp("[\\(\\,\\)]"), csFeat);
00732
00733 if (strings[0] == "ApplicationStacking" || strings[0] == "ASt") return true;
00734
00735 if (strings[0] == "Cloning" || strings[0] == "Clo") return true;
00736 if (strings[0] == "SceneCoordinateSystem" || strings[0] == "SCS") {
00737 if (strings.count() >= 3 && strings[1] == "720" && strings[2] == "576")
00738 return true;
00739 else return false;
00740
00741 }
00742 if (strings[0] == "MultipleAudioStreams" || strings[0] == "MAS") {
00743 if (strings.count() >= 2 && (strings[1] == "0" || strings[1] == "1"))
00744 return true;
00745 else return false;
00746 }
00747 if (strings[0] == "MultipleVideoStreams" || strings[0] == "MVS") {
00748 if (strings.count() >= 2 && (strings[1] == "0" || strings[1] == "1"))
00749 return true;
00750 else return false;
00751 }
00752
00753 if (strings[0] == "OverlappingVisibles" || strings[0] == "OvV") return true;
00754
00755 if (strings[0] == "SceneAspectRatio" || strings[0] == "SAR") {
00756 if (strings.count() < 3) return false;
00757 else if ((strings[1] == "4" && strings[2] == "3") || (strings[1] == "16" && strings[2] == "9"))
00758 return true;
00759 else return false;
00760 }
00761
00762
00763 if (strings[0] == "VideoScaling" || strings[0] == "VSc") {
00764 if (strings.count() < 4 || strings[1] != "10") return false;
00765 else if ((strings[2] == "720" && strings[3] == "576") || (strings[2] == "360" && strings[3] == "288"))
00766 return true;
00767 else return false;
00768 }
00769 if (strings[0] == "BitmapScaling" || strings[0] == "BSc") {
00770 if (strings.count() < 4 || strings[1] != 2) return false;
00771 else if ((strings[2] == "720" && strings[3] == "576") || (strings[2] == "360" && strings[3] == "288"))
00772 return true;
00773 else return false;
00774 }
00775
00776
00777 if (strings[0] == "VideoDecodeOffset" || strings[0] == "VDO") {
00778 if (strings.count() >= 3 && strings[1] == 10 && strings[1] == 0) return true;
00779 else return false;
00780 }
00781
00782 if (strings[0] == "BitmapDecodeOffset" || strings[0] == "BDO") {
00783 if (strings.count() >= 3 && strings[1] == "10" && (strings[2] == "0" || strings[2] == "1"))
00784 return true;
00785 else return false;
00786 }
00787
00788 if (strings[0] == "UKEngineProfile" || strings[0] == "UEP") {
00789 if (strings.count() < 2) return false;
00790 if (strings[1] == MHEGEngineProviderIdString)
00791 return true;
00792 if (strings[1] == m_Context->GetReceiverId())
00793 return true;
00794 if (strings[1] == m_Context->GetDSMCCId())
00795 return true;
00796
00797
00798 if (strings[1] == "2")
00799 return true;
00800 else return false;
00801 }
00802
00803
00804 return false;
00805 }
00806
00807
00808 int MHEngine::GetDefaultCharSet()
00809 {
00810 MHApplication *pApp = CurrentApp();
00811 if (pApp && pApp->m_nCharSet > 0) return pApp->m_nCharSet;
00812 else return 10;
00813 }
00814
00815 void MHEngine::GetDefaultBGColour(MHColour &colour)
00816 {
00817 MHApplication *pApp = CurrentApp();
00818 if (pApp && pApp->m_BGColour.IsSet()) colour.Copy(pApp->m_BGColour);
00819 else colour.SetFromString("\000\000\000\377", 4);
00820 }
00821
00822 void MHEngine::GetDefaultTextColour(MHColour &colour)
00823 {
00824 MHApplication *pApp = CurrentApp();
00825 if (pApp && pApp->m_TextColour.IsSet()) colour.Copy(pApp->m_TextColour);
00826 else colour.SetFromString("\377\377\377\000", 4);
00827 }
00828
00829 void MHEngine::GetDefaultButtonRefColour(MHColour &colour)
00830 {
00831 MHApplication *pApp = CurrentApp();
00832 if (pApp && pApp->m_ButtonRefColour.IsSet()) colour.Copy(pApp->m_ButtonRefColour);
00833 else colour.SetFromString("\377\377\377\000", 4);
00834 }
00835
00836 void MHEngine::GetDefaultHighlightRefColour(MHColour &colour)
00837 {
00838 MHApplication *pApp = CurrentApp();
00839 if (pApp && pApp->m_HighlightRefColour.IsSet()) colour.Copy(pApp->m_HighlightRefColour);
00840 else colour.SetFromString("\377\377\377\000", 4);
00841 }
00842
00843 void MHEngine::GetDefaultSliderRefColour(MHColour &colour)
00844 {
00845 MHApplication *pApp = CurrentApp();
00846 if (pApp && pApp->m_SliderRefColour.IsSet()) colour.Copy(pApp->m_SliderRefColour);
00847 else colour.SetFromString("\377\377\377\000", 4);
00848 }
00849
00850 int MHEngine::GetDefaultTextCHook()
00851 {
00852 MHApplication *pApp = CurrentApp();
00853 if (pApp && pApp->m_nTextCHook > 0) return pApp->m_nTextCHook;
00854 else return 10;
00855 }
00856
00857 int MHEngine::GetDefaultStreamCHook()
00858 {
00859 MHApplication *pApp = CurrentApp();
00860 if (pApp && pApp->m_nStrCHook > 0) return pApp->m_nStrCHook;
00861 else return 10;
00862 }
00863
00864 int MHEngine::GetDefaultBitmapCHook()
00865 {
00866 MHApplication *pApp = CurrentApp();
00867 if (pApp && pApp->m_nBitmapCHook > 0) return pApp->m_nBitmapCHook;
00868 else return 4;
00869 }
00870
00871 void MHEngine::GetDefaultFontAttrs(MHOctetString &str)
00872 {
00873 MHApplication *pApp = CurrentApp();
00874 if (pApp && pApp->m_FontAttrs.Size() > 0) str.Copy(pApp->m_FontAttrs);
00875 else str.Copy("plain.24.24.0");
00876 }
00877
00878
00879 const char *MHEngine::MHEGEngineProviderIdString = "MHGGNU001";
00880
00881
00882 int __mhlogoptions = MHLogError;
00883
00884 FILE *__mhlogStream = NULL;
00885
00886
00887 void __mhlog(QString logtext)
00888 {
00889 fprintf(__mhlogStream, "%s\n", logtext.ascii());
00890 }
00891
00892
00893 void MHSetLogging(FILE *logStream, unsigned int logLevel)
00894 {
00895 __mhlogStream = logStream;
00896 __mhlogoptions = logLevel;
00897 }