PEBL 2.2
Psychology Experiment Building Language - Cross-platform psychological experiment development system
PEBLEnvironment.cpp
Go to the documentation of this file.
1//* -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*- */
3// Name: src/libs/PEBLEnvironment.cpp
4// Purpose: General Environment Function Library for PEBL
5// Author: Shane T. Mueller, Ph.D.
6// Copyright: (c) 2003-2026 Shane T. Mueller <smueller@obereed.net>
7// License: GPL 2
8//
9//
10//
11// This file is part of the PEBL project.
12//
13// PEBL is free software; you can redistribute it and/or modify
14// it under the terms of the GNU General Public License as published by
15// the Free Software Foundation; either version 2 of the License, or
16// (at your option) any later version.
17//
18// PEBL is distributed in the hope that it will be useful,
19// but WITHOUT ANY WARRANTY; without even the implied warranty of
20// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21// GNU General Public License for more details.
22//
23// You should have received a copy of the GNU General Public License
24// along with PEBL; if not, write to the Free Software
25// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
28#ifdef PEBL_WINDOWS
29#include <Windows.h>
30#undef GetObject
31#undef DeleteFile
32#endif
33
34#include "PEBLEnvironment.h"
35#include "PEBLObjects.h"
36
37#include "../base/Variant.h"
38#include "../base/PList.h"
39#include "../base/PComplexData.h"
40#include "../base/PNode.h"
41#include "../base/grammar.tab.hpp"
42
43#ifdef PEBL_ITERATIVE_EVAL
44#include "../base/Evaluator-es.h"
45#include "../devices/PEventLoop-es.h"
46#else
47#include "../base/Evaluator.h"
48#include "../devices/PEventLoop.h"
49#endif
50
51#include "../utility/PError.h"
52#include "../utility/PEBLUtility.h"
53#include "../utility/rc_ptrs.h"
54
55#include "../devices/PTimer.h"
56#include "../devices/DeviceState.h"
57
58
59#include "../objects/PTextBox.h"
60
61#ifdef PEBL_VALIDATOR
62#include "../platforms/validator/PlatformTimer.h"
63#include "../platforms/validator/PlatformKeyboard.h"
64#include "../platforms/validator/PlatformTextBox.h"
65#include "../platforms/validator/PlatformEventQueue.h"
66#else
67#include "../platforms/sdl/PlatformTimer.h"
68#include "../platforms/sdl/PlatformKeyboard.h"
69#include "../platforms/sdl/PlatformTextBox.h"
70#include "../platforms/sdl/PlatformEventQueue.h"
71#ifdef PEBL_MOVIES
72#include "../platforms/sdl/PlatformMovie.h"
73#endif
74#endif
75
76
77#include <ctime>
78#include <string>
79
80#if defined(PEBL_WIN32)
81//#include <shellapi.h>
82#include <winsock2.h> //avoid collision
83#include <windows.h>
84// Undefine Windows macros that conflict with PEBL methods
85#undef GetObject
86#undef DeleteFile
87#endif
88
89#if defined(PEBL_UNIX)
90#include <unistd.h> // for fork(), execl()
91#include <sys/types.h> // for pid_t
92#include <sys/wait.h> // for waitpid()
93#endif
94
95
96using std::string;
97using std::endl;
98using std::cout;
99
101namespace PEBLEnvironment
102{
105}
106
109
112{
113 //v should have no parameters
114
115 //get the time from timer object.
116 return Variant(myTimer.GetTime());
117}
118
120{
121#ifdef PEBL_VALIDATOR
122 // Validator mode: return dummy value
123 return Variant((pDouble)0.0);
124#else
126#endif
127}
128
129//gettimeofday() gives you microsecond resolution...the comment about not
130//being able to work in units smaller than 10 milliseconds is bunk, and
131//has to do with the Linux 2.4 scheduler not letting you sleep less than
132//10ms...but even there, within your timeslice, you can get microsecond
133//timing. Linux 2.6 fixed the scheduler resolution, too.
134
136{
137 long unsigned int secs;
138 long unsigned int msecs;
139 myTimer.GetTimeOfDay(secs,msecs);
140
141 return Variant(secs);
142}
143
144
146{
147
148 PList * plist = v.GetComplexData()->GetList();
149
150 Variant obj = plist->First();
151
152 return Variant(obj.GetCreationTime());
153}
154
156{
157
158 //cout << "Internal wait\n";
159 //v[1] should have the parameter
160 PList * plist = v.GetComplexData()->GetList();
161
162 PError::AssertType(plist->First(), PEAT_NUMBER, "Argument error in function [Wait(<number>)]: ");
163 int delay = plist->First();// plist->PopFront();
164 delay += myTimer.GetTime();
165 //Create a timer test correspending to keydown.
166 //1 is the value (down), DT_GREATER_THAN is the test, key is the interface (e.g., the 'A' key)
167 PDevice * device = new PlatformTimer(myTimer);
168 ValueState * state = new ValueState(delay, DT_GREATER_THAN_OR_EQUAL, 1,device, PDT_TIMER);
169 //NULL,NULL will terminate the looping
170 string funcname = "";
171
172 Evaluator::mEventLoop->RegisterState(state, funcname, Variant(0));
173 PEvent returnval = Evaluator::mEventLoop->Loop();
174 //Now, clear the event loop tests
176
177
178 delete device;
179
180 return Variant(returnval.GetDummyEvent().value);
181}
182
183
185{
186 //v[1] should have the parameter-a letter
187 PList * plist = v.GetComplexData()->GetList();
188 PError::AssertType(plist->First(), PEAT_STRING, "Argument error in function [IsKeyDown(<string>)]: ");
189
190 std::string mystring = plist->First();// plist->PopFront();
192
193 return Variant(myKeyboard.IsKeyDown(key));
194}
195
196
197
198
200{
201 PList * plist = v.GetComplexData()->GetList();
202 //v[1] should have the parameter-a letter
203
204 PError::AssertType(plist->First(), PEAT_STRING, "Argument error in function [IsKeyUp(<string>)]: ");
205
206 string mystring = plist->First();// plist->PopFront();
208
209 return Variant(myKeyboard.IsKeyUp(key));
210}
211
212
213
215{
216 //This shouldn't receive any arguments
218
219 // cout<< "isanykeydown key:" << key << endl;
220 if(key==PEBL_KEYCODE_NOTHING)
221 {
222 return Variant(0);
223 }else
224 {
226 }
227}
228
230{
231 PList * plist = v.GetComplexData()->GetList();
232 PError::AssertType(plist->First(), PEAT_INTEGER, "Argument error in function [ShowCursor(<bool>)]: ");
233 int val = plist->First();
234 return Variant(myEnv->ShowCursor(val));
235}
236
237
238// /// This function uses the event loop to schedule a single
239// /// device-test, which checks for the selected key.
240// Variant PEBLEnvironment::WaitForMouseOverRegion(Variant v)
241// {
242// //v[1-4] should specify a rectangle
243// PList * plist = v.GetComplexData()->GetList();
244
245// PError::AssertType(plist->First(), PEAT_STRING, "Argument error in function [WaitForKeyPress(<string>)]: ");
246
247// string mystring = plist->First(); plist->PopFront();
248// PEBLKey key = PEBLUtility::TranslateString(mystring);
249
250
251
252// RegionState * state = new RegionState(10,100,10,100, DT_INSIDE, , gEventQueue, PDT_MOUSEMOTION);
253
254// //NULL,NULL will terminate the looping
255// string funcname = "";
256// PList* params = NULL;
257// Evaluator::mEventLoop.RegisterEvent(state,funcname, params);
258// PEvent returnval = Evaluator::mEventLoop.Loop();
259
260// //Now, clear the event loop tests
261// Evaluator::mEventLoop.Clear();
262
263// return Variant(PEBLUtility::TranslateKeyCode(returnval.GetKeyboardEvent().key,0));
264// }
265
266
267
271{
272
273 //v[1] should have the parameter-a letter
274 PList * plist = v.GetComplexData()->GetList();
275
276 PError::AssertType(plist->First(), PEAT_STRING, "Argument error in function [WaitForKeyDown(<string>)]: ");
277
278 string mystring = plist->First();// plist->PopFront();
280
281
282 //Create a keyboard test correspending to keydown.
283 //1 is the value (down), DT_EQUAL is the test, key is the interface (e.g., the 'A' key)
284 PDevice * device = new PlatformKeyboard(myKeyboard);
285 ValueState * state = new ValueState(1, DT_EQUAL, key, device, PDT_KEYBOARD);
286
287 //NULL,NULL will terminate the looping
288 string funcname = "";
289
290
291 Evaluator::mEventLoop->RegisterState(state,funcname, Variant(0));
292 PEvent returnval = Evaluator::mEventLoop->Loop();
293
294 //Now, clear the event loop tests
296 gEventQueue->Clear(); //clear the event queue so the editing events don't bleed over.
297
298 return Variant(returnval.GetDummyEvent().value);
299}
300
301
302
304{
305
306 //v[1] should have the parameter-a letter
307 PList * plist = v.GetComplexData()->GetList();
308
309 PError::AssertType(plist->First(), PEAT_STRING, "Argument error in function [WaitForKeyUp(<string>)]: ");
310
311 string mystring = plist->First(); //plist->PopFront();
313
314
315 //Create a keyboard test correspending to keydown.
316 //1 is the value (down), DT_NOT_EQUAL is the test, key is the interface (e.g., the 'A' key)
317 PDevice * device = new PlatformKeyboard(myKeyboard);
318 ValueState * state = new ValueState(1, DT_NOT_EQUAL, key, device, PDT_KEYBOARD);
319
320 //NULL,NULL will terminate the looping
321 string funcname = "";
322 Evaluator::mEventLoop->RegisterState(state, funcname, Variant(0));
323 PEvent returnval = Evaluator::mEventLoop->Loop();
324
325 //Now, clear the event loop tests (this is now done in-loop).
327
328 return Variant(returnval.GetDummyEvent().value);
329
330}
331
332
333
334
338{
339
341
342 //Create a keyboard test correspending to keydown.
343 //1 is the value (down), DT_EQUAL is the test, key is the interface (normally an actual key, here the "ANYKEY")
344 PDevice * device = new PlatformKeyboard(myKeyboard);
345 ValueState * state = new ValueState(1, DT_EQUAL, key, device,PDT_KEYBOARD);
346
347 //NULL,NULL will terminate the looping
348 string funcname = "";
349
350 Evaluator::mEventLoop->RegisterState(state, funcname, Variant(0));
351 PEvent returnval = Evaluator::mEventLoop->Loop();
352
353 //Now, clear the event loop tests
355 gEventQueue->Clear(); //clear the event queue so the editing events don't bleed over.
356
357 return Variant(returnval.GetDummyEvent().value);
358}
359
360
361
362
366{
367
368
369 //v[1] should have the parameter-a letter
370 PList * plist = v.GetComplexData()->GetList();
371
372 PError::AssertType(plist->First(), PEAT_STRING, "Argument error in function [WaitForKeyPress(<string>)]: ");
373
374 string mystring = plist->First();// plist->PopFront();
375
376
377
379
380
381 //Create a keyboard test correspending to keydown.
382 //1 is the value (down), DT_EQUAL is the test, key is the interface (e.g., the 'A' key)
383
386
387
388
389 //NULL,NULL will terminate the looping
390 string funcname = "";
391
392 Evaluator::mEventLoop->RegisterEvent(state,funcname, Variant(0));
393 PEvent returnval = Evaluator::mEventLoop->Loop();
394
395 state =NULL;
396
397
398 //Now, clear the event loop tests
400 gEventQueue->Clear(); //clear the event queue so the editing events don't bleed over.
401
402 //return returnval.GetKeyboardEvent().key;
404}
405
406
407
409{
410
411 //v[1] should have the parameter-a letter
412 PList * plist = v.GetComplexData()->GetList();
413
414 PError::AssertType(plist->First(), PEAT_STRING, "Argument error in function [WaitForKeyRelease(<string>)]: ");
415
416 string mystring = plist->First();// plist->PopFront();
418
419
420 //Create a keyboard test correspending to keydown.
421 //1 is the value (down), DT_NOT_EQUAL is the test, key is the interface (e.g., the 'A' key)
422
423 ValueState * state = new ValueState(PEBL_RELEASED,
424 DT_EQUAL, key,
427
428 //NULL,NULL will terminate the looping
429 string funcname = "";
430
431 Evaluator::mEventLoop->RegisterEvent(state, funcname, Variant(0));
432 PEvent returnval = Evaluator::mEventLoop->Loop();
433
434 //Now, clear the event loop tests
436
437
439
440}
441
442
443
444
448{
449
451
452 //Create a keyboard test correspending to keydown.
454
455 //NULL,NULL will terminate the looping
456 string funcname = "";
457
458 Evaluator::mEventLoop->RegisterEvent(state, funcname, Variant(0));
459 PEvent returnval = Evaluator::mEventLoop->Loop();
460
461 //cout <<" inhere:" <<returnval.GetEventTime() << endl;
462 //Now, clear the event loop tests
464 gEventQueue->Clear(); //clear the event queue so the editing events don't bleed over.
465
466 //cout << "KEY:!" << returnval.GetKeyboardEvent().key << endl;
468 out.SetCreationTime(returnval.GetEventTime());
469 //cout <<"out:" << out.GetCreationTime() << endl;
470
471 return out;
472
473}
474
475
476
478{
479
481
482
483 //Create a keyboard test correspending to keydown.
484 //1 is the value (down), DT_EQUAL is the test, key is the interface (e.g., the 'A' key)
485 PDevice * device = new PlatformKeyboard(myKeyboard);
486 ValueState * state = new ValueState(1, DT_NOT_EQUAL, key, device, PDT_KEYBOARD);
487
488 //NULL,NULL will terminate the looping
489 string funcname = "";
490 Evaluator::mEventLoop->RegisterState(state,funcname, Variant(0));
491 PEvent returnval = Evaluator::mEventLoop->Loop();
492
493 //Now, clear the event loop tests
495
496
497 return Variant(returnval.GetDummyEvent().value);
498}
499
500
502{
503
504 //v[1] should have the parameter: a time to wait.
505 PList * plist = v.GetComplexData()->GetList();
506
507 PError::AssertType(plist->First(), PEAT_NUMBER, "Argument error in function [WaitForAnyKeyDownWithTimeout(<number>)]: ");
508
509 int delay = plist->First(); //plist->PopFront();
510 delay += myTimer.GetTime();
511
512 //Create a timer test correspending to keydown.
513 //1 is the value (down), DT_GREATERTHAN is the test, key is the interface (e.g., the 'A' key)
514 PDevice * timer = new PlatformTimer(myTimer);
515 ValueState * timestate = new ValueState(delay, DT_GREATER_THAN_OR_EQUAL, 1, timer, PDT_TIMER);
516
517
519 //Create a keyboard test correspending to keydown.
520 //1 is the value (down), DT_EQUAL is the test, key is the interface (e.g., the 'A' key)
521
522 PDevice * device = new PlatformKeyboard(myKeyboard);
523 ValueState * state = new ValueState(1, DT_EQUAL, key, device,PDT_KEYBOARD);
524
525 //NULL,NULL will terminate the looping
526 string funcname = "";
527 Evaluator::mEventLoop->RegisterState(state,funcname, Variant(0));
528 Evaluator::mEventLoop->RegisterState(timestate, funcname, Variant(0));
529 PEvent returnval = Evaluator::mEventLoop->Loop();
530
531 //Now, clear the event loop tests
533 gEventQueue->Clear(); //clear the event queue so the editing events don't bleed over.
534
535 //std::cout << "Returnval for gadpwto: "<<returnval.GetDummyEvent().value<< std::endl;
536
537 //Now, clear the event loop tests
538
539
540 int retkey =returnval.GetDummyEvent().value;
541 if(retkey==PEBL_KEYCODE_UNKNOWN)
542 {
543 //cout << "Returning timeout value\n";
544 return Variant("<timeout>");
545 }else{
546
548 }
549
550 return Variant(returnval.GetDummyEvent().value);
551
552}
553
554// This returns the key pressed, or <timeout> if there is a timeout
555
556
558{
559
560 //v[1] should have the parameter: a time to wait.
561 PList * plist = v.GetComplexData()->GetList();
562
563 PError::AssertType(plist->First(), PEAT_NUMBER, "Argument error in function [WaitForAnyKeyPressWithTimeout(<number>)]: ");
564
565 int delay = plist->First(); //plist->PopFront();
566 delay += myTimer.GetTime();
567
568 //Create a timer test correspending to keydown.
569 //1 is the value (down), DT_GREATERTHAN is the test, key is
570 // the interface (e.g., the 'A' key)
571 PDevice * timer = new PlatformTimer(myTimer);
572 ValueState * timestate = new ValueState(delay, DT_GREATER_THAN_OR_EQUAL, 1, timer, PDT_TIMER);
573
574
575
576 //Create a keyboard test correspending to keydown.
577 //1 is the value (down), DT_EQUAL is the test, key is the interface (e.g., the 'A' key)
579 //PDevice * device = new PlatformKeyboard(myKeyboard);
580 //ValueState * state = new ValueState(1, DT_EQUAL, key, device, PDT_KEYBOARD);
582
583
584 string funcname = "";
585 Evaluator::mEventLoop->RegisterEvent(state, funcname, Variant(0));
586
587
588 Evaluator::mEventLoop->RegisterState(timestate, funcname, Variant(0));
589 PEvent returnval = Evaluator::mEventLoop->Loop();
590
591
592 //std::cout << "Returnval for gakpwto: "<<returnval.GetKeyboardEvent().key<< std::endl;
593 //std::cout << PEBL_KEYCODE_UNKNOWN << endl;
594 //Now, clear the event loop tests
596 gEventQueue->Clear(); //clear the event queue so the editing events don't bleed over.
597
598 // return Variant(returnval.GetDummyEvent().value);
599
600 PEBL_Keycode retkey =returnval.GetKeyboardEvent().key;
601 if(retkey==PEBL_KEYCODE_UNKNOWN)
602 {
603 //cout << "Returning timeout value\n";
604 return Variant("<timeout>");
605 }else{
606
607 return Variant(PEBLUtility::TranslateKeycode(retkey,0));
608 }
609}
610
611
612
613// The scheme below is unused.--the third parameter does not work.
614// on timeout, <timeout> is returned.
615//
616// Planned functionality of third parameter (unimplemented)
617//This takes a list of keys, a timeout duration, and an integer specifying
618// the style:
619// 1 == return after whichever happens first
620// 2 == return only after timeout occurs
621// 3 == return after both occur (response and min duration necessary)
622// In all cases, the key pressed is returned.
623//If a key has not been pressed,
624// the empty string "" is returned.
625
627{
628
629 PList * plist = v.GetComplexData()->GetList();
630 Variant v1 = plist->First(); //plist->PopFront();
631 PError::AssertType(v1, PEAT_LIST, "Argument error in first parameter of function [WaitForListKeyPressWithTimeout(<list-of-keys>,<timeout>,<style>)]: ");
632
633
634 //Use plist to get the actual list of items.
635 PList * keylist = (PList*)((v1.GetComplexData())->GetObject().get());
636
637 PError::AssertType(plist->Nth(2), PEAT_NUMBER, "Argument error in second parameter of function [WaitForListKeyPressWithTimeout(<list-of-keys>,<timeout>,<style>)]: ");
638 int delay = plist->Nth(2);// plist->PopFront();
639 delay += myTimer.GetTime();
640
641 //this is unused.
642 // PError::AssertType(plist->Nth(3), PEAT_INTEGER, "Argument error in third parameter of function [WaitForListKeyPressWithTimeout(<list-of-keys>,<timeout>,<style>)]: ");
643 // Variant v3 = plist->Nth(3);// plist->PopFront();
644
645
646
647
648
649 std::vector<Variant>::iterator p = keylist->Begin();
650 std::vector<Variant>::iterator end = keylist->End();
651
652 ValueState * state;
653 string funcname = "";
654
655 PEBL_Keycode key;
656
657 while(p != end)
658 {
659 //Create a keyboard tests correspending to each item in v1.
660 //1 is the value (down), DT_EQUAL is the test, key is the interface (e.g., the 'A' key)
663 //NULL,NULL will terminate the looping
664 Evaluator::mEventLoop->RegisterEvent(state,funcname, Variant(0));
665 p++;
666 }
667
668
669
670 //Create a timer test correspending to keydown.
671 //1 is the value (down), DT_GREATERTHAN is the test, key is the interface (e.g., the 'A' key)
672 PDevice * timer = new PlatformTimer(myTimer);
673 ValueState * timestate = new ValueState(delay, DT_GREATER_THAN_OR_EQUAL, 1, timer, PDT_TIMER);
674
675
676 //NULL,NULL will terminate the looping
677 Evaluator::mEventLoop->RegisterState(timestate, funcname, Variant(0));
678 PEvent returnval = Evaluator::mEventLoop->Loop();
679
680 //Now, clear the event loop tests
682 gEventQueue->Clear(); //clear the event queue so the editing events don't bleed over.
683
684 // return Variant(PEBLUtility::TranslateKeyCode(returnval.GetKeyboardEvent().key,0));
685 Variant ret;
686 // std::cout<<"Type:" << returnval.GetType() <<std::endl;
687
688 if(returnval.GetType() == PDT_KEYBOARD)
689 {
690
692 }
693 else
694 {
695
696 //PList *newlist = new PList();
697 //newlist->PushBack(Variant("<timeout>"));
698 //counted_ptr<PEBLObjectBase>newlist2 = counted_ptr<PEBLObjectBase>(newlist);
699 //PComplexData * pcd = new PComplexData(newlist2);
700
701 ret = Variant("<timeout>");
702 }
703
704 return ret;
705
706}
707
708
709//This function will block until one of the keys listed in the argument is depressed,
710//and then return the value of the key that was hit.
712{
713
714 //v[1] should have the parameter: a list of keys to wait for.
715 PList * plist = v.GetComplexData()->GetList();
716 Variant v1 = plist->First(); //plist->PopFront();
717 PError::AssertType(v1, PEAT_LIST, "Argument error in function [WaitForKeyListDown(<list>)]: ");
718
719 //Use plist to get the actual list of items.
720 PList * keylist = (PList*)((v1.GetComplexData())->GetObject().get());
721
722 std::vector<Variant>::iterator p = keylist->Begin();
723 std::vector<Variant>::iterator end = keylist->End();
724
725 PDevice * device = new PlatformKeyboard(myKeyboard);
726 ValueState * state;
727 string funcname = "";
728
729 PEBL_Keycode key;
730
731
732 while(p != end)
733 {
734 //Create a keyboard tests correspending to each item in v1.
735 //1 is the value (down), DT_EQUAL is the test, key is the interface (e.g., the 'A' key)
737 state = new ValueState(1, DT_EQUAL, key, device, PDT_KEYBOARD);
738 //NULL,NULL will terminate the looping
739 Evaluator::mEventLoop->RegisterState(state,funcname, Variant(0));
740 p++;
741 }
742
743
744 //Start the event loop.
745 PEvent returnval = Evaluator::mEventLoop->Loop();
746
747
749
750
751 Variant ret;
752 if(returnval.GetType() == PDT_KEYBOARD)
753 {
754
755 ret = Variant(returnval.GetDummyEvent().value);
756 }
757 else
758 {
759 // cout <<"======="<< returnval.GetDummyEvent().value << std::endl;
760
761 //PList *newlist = new PList();
762 //newlist->PushBack(Variant("<timeout>"));
763 //counted_ptr<PEBLObjectBase>newlist2 = counted_ptr<PEBLObjectBase>(newlist);
764 //PComplexData * pcd = new PComplexData(newlist2);
765 // ret = Variant(pcd);
766
767
768 //ret = Variant(returnval.GetDummyEvent().value);
770
771 }
772
773 return ret;
774}
775
776
777//This function will block until one of the keys listed in
778// the argument is depressed,
779//and then return the value of the key that was hit.
781{
782
783 //v[1] should have the parameter: a list of keys to wait for.
784 PList * plist = v.GetComplexData()->GetList();
785
786 Variant v1 = plist->First(); //plist->PopFront();
787 PError::AssertType(v1, PEAT_LIST, "Argument error in function [WaitForKeyListPress(<list>)]: ");
788
789 //Use plist to get the actual list of items.
790 PList * keylist = (PList*)((v1.GetComplexData())->GetObject().get());
791
792 std::vector<Variant>::iterator p = keylist->Begin();
793 std::vector<Variant>::iterator end = keylist->End();
794
795 ValueState * state;
796 string funcname = "";
797
798 PEBL_Keycode key;
799
800 while(p != end)
801 {
802 //Create a keyboard tests correspending to each item in v1.
803 //1 is the value (down), DT_EQUAL is the test, key is the interface (e.g., the 'A' key)
804
805
807 //std::cout<< "Key:" << *p << "|"<<key<< std::endl;
809 //NULL,NULL will terminate the looping
810 Evaluator::mEventLoop->RegisterEvent(state,funcname, Variant(0));
811 p++;
812 }
813
814
815 //Start the event loop.
816 PEvent returnval = Evaluator::mEventLoop->Loop();
818 gEventQueue->Clear(); //clear the event queue so the editing events don't bleed over.
819
821}
822
823
830
831
835
837{
838
839 // cout << "GetInput0:\n";
840 PList * plist = v.GetComplexData()->GetList();
841 //The first argument should be a textbox.
842 PError::AssertType(plist->First(), PEAT_TEXTBOX, "Argument error in function [GetInput(<textbox>,<key-string>)]: ");
843 PlatformTextBox * textbox = dynamic_cast<PlatformTextBox*>(plist->First().GetComplexData()->GetObject().get());
844
845 //The next argument should be the 'escape' key, or a list of 'escape' keys.
846 // l.GetType() << std::endl;
847 //type = plist->First()->GetType();
848
849 PError::AssertType(plist->Nth(2), PEAT_STRING, "Argument error in function [GetInput(<textbox>,<key-string>)]: ");
850 string exitString = plist->Nth(2); //plist->PopFront();
851
852
853 //Create a keyboard test correspending to escape keydown.
854 //1 is the value (down), DT_EQUAL is the test, key is the interface (e.g., the 'A' key)
855
856
857
858
859 //NULL,NULL will terminate the looping
860 string funcname = "";
861 ValueState * keypressstate =NULL;
862 ValueState * texteditstate =NULL;
863
864 //Make the textbox editable.
865 textbox->SetEditable(true);
866 myEnv->SetKeyRepeat(true);
867 myEnv->Draw();
868
870
871 //This is the main mini-event loop for getinput.
872 bool cont = true;
873
874 while(cont)
875 {
876
877
878 //First, program the event loop triggers:
879
880 //This adds anykey press to process.
881 keypressstate = new ValueState(PEBL_PRESSED, DT_EQUAL,
883
884 Evaluator::mEventLoop->RegisterEvent(keypressstate, funcname, Variant(0));
885 keypressstate = NULL;
886
887
888
889 //This handles text editing events
890 texteditstate = new ValueState(PEBL_PRESSED, DT_TRUE, 1, gEventQueue, PDT_TEXT_INPUT);
891 Evaluator::mEventLoop->RegisterEvent(texteditstate, funcname, Variant(0));
892 texteditstate = NULL;
893
894 //Evaluate the last list item, if it exists.
895 //This is the optional command that specifies mouse click events.
896 //cout << "Testing length:" << plist->Length() << endl;
897 if(plist->Length() > 2)
898 {
899
900 //cout << "Optinoal arguments:\n";
901 Variant tmp = plist->Nth(3); //nth(3) is the 3rd element
902 //cout << "tmp:["<<plist->Nth(2)<<"]\n";
903 //cout << "tmp:["<<tmp<<"]\n";
904
905 if(tmp)
906 {
907 //cout << "tmp was not null\n";
908 //add a mouse click as an exit too.
910 Evaluator::mEventLoop->RegisterEvent(state2,funcname, Variant(0));
911 state2 = NULL;
912 }
913
914
915 //right-click is button 3 (interface 3rd argument):
917 Evaluator::mEventLoop->RegisterEvent(state2,"HANDLETEXTBOXRIGHTCLICK", v);
918 state2 = NULL;
919 //cout << "handletextboxrightclick will be called with : " << v << endl;
920
921 }
922 else
923 {
924
925 //Otherwise, add mouse click event but use it in a specific way.
926 //add a mouse click as an exit too.
927
929 Evaluator::mEventLoop->RegisterEvent(state2,"SETTEXTBOXCURSORFROMCLICK", v);
930 state2 = NULL;
931
932 //right-click is button 3:
934 Evaluator::mEventLoop->RegisterEvent(state2,"HANDLETEXTBOXRIGHTCLICK", v);
935 state2 = NULL;
936
937
938
939 // ValueState * state2 = new ValueState(PEBL_PRESSED, DT_TRUE, 1, gEventQueue, PDT_MOUSE_BUTTON);
940 // Evaluator::mEventLoop->RegisterEvent(state2,funcname, Variant(0));
941 //state2 = NULL;
942 }
943
944
945 bool ignore = false;
946
947 //Now, the event(s) we are catching have been programmed. Turn
948 //on the loop until it catches something:
949 //This gets the first click/keypress:
950
952 //Evaluator::mEventLoop->Clear();
953 //handle special if it is a mouse click:
954 //cout << "********************************************\n--------------EVENt"<< evt.GetType() << endl;
955
956 if(evt.GetType()==PDT_MOUSE_BUTTON )
957 {
959 {
960
961 textbox->SetEditable(false);
963 return Variant(textbox->GetText());
964 } else {
965
966 //We just ignore the keypress in this case.
967 ignore = true;
968 }
969 }
970
971 //Keyboard event is ONLY used for checking exit condition.
972 //otherwise, the text should be taken from the TEXT_EDITING
973 //or TEXT_INPUT event.
974
975 else if(evt.GetType()==PDT_KEYBOARD)
976 {
977
978
980
981 //cout << "Keystring: " <<PEBLUtility::TranslateKeycode(pke.key, pke.modkeys);
982 //cout << " Exitstring: " << PEBLUtility::ToLower(exitString) << endl;
984 {
985
986 textbox->SetEditable(false);
987 cont = false;
988 //Exit the loop here; we have matched the exit condition.
989 }
990 else
991 {
992 //This should handle keypresses for limited keystrokes:
993 textbox->HandleKeyPress(pke.key, pke.modkeys, 0);
994 ignore = true;
995 if(myEnv) myEnv->Draw();
996 }
997
998 }
999 else if(evt.GetType()==PDT_TEXT_INPUT)
1000 {
1002
1003 if(!ignore)
1004 {
1005 textbox->HandleTextInput(std::string(event.text));
1006 }
1007
1008 if(myEnv)
1009 {
1010
1011 myEnv->Draw();
1012 }
1013
1014
1015 //return to top of loop to program events and await for the next keystroke..
1016 }
1017
1019 }
1020
1021
1022
1023
1024 textbox->SetEditable(false);
1025
1026 myEnv->SetKeyRepeat(false);
1027 return Variant(textbox->GetText());
1028}
1029
1030
1031
1032
1033
1034
1036{
1037
1038 PList * plist = v.GetComplexData()->GetList();
1039 //The first argument should be a textbox.
1040 PError::AssertType(plist->First(), PEAT_TEXTBOX, "Argument error in function [SetTextBoxCursorFromClick(<textbox>,<x>,<y>)]: ");
1041 PlatformTextBox * textbox = dynamic_cast<PlatformTextBox*>(plist->First().GetComplexData()->GetObject().get());
1042
1043
1044 PError::AssertType(plist->Nth(2), PEAT_NUMBER, "Argument error in first argument of function [SetTextBoxCursorFromClick(<textbox>,<x>,<y>)]: ");
1045 int x = plist->Nth(2);
1046
1047
1048 PError::AssertType(plist->Nth(3), PEAT_NUMBER, "Argument error in second argumeent of function [SetTextBoxCursorFromClick(<textbox>,<x>,<y>)]: ");
1049
1050 int y = plist->Nth(3);
1051
1052
1053 // int relx <- x - (textbox->GetX() - textbox->GetWidth()/2)
1054 // int rely <- y - (textbox->GetY() - textbox->GetHeight()/2)
1055
1056 return textbox->FindCursorPosition(x,y);
1057
1058}
1059
1060
1065{
1066 //Create a mouse test
1067 //1 is the value (down), DT_EQUAL is the test, 1 is the interface (e.g., the 'A' key)
1068
1069 //Add normal mouse buttons:
1070 ValueState * state = NULL;
1072 //cout << "Registering in: " << *(Evaluator::mEventLoop) << endl;
1073 //NULL,NULL will terminate the looping
1074 string funcname = "";
1075 Evaluator::mEventLoop->RegisterEvent(state,funcname, Variant(0));
1076
1077
1078 //add scrolling button movement.
1079 //interface=1 is x, interface 2 = 5
1081 Evaluator::mEventLoop->RegisterEvent(state,funcname, Variant(0));
1082
1083
1084
1085
1086 PEvent returnval = Evaluator::mEventLoop->Loop();
1087
1088
1089
1090 //Now, clear the event loop tests
1092
1093
1094 PList * newlist = new PList();
1095
1096 if( returnval.GetType()==PDT_MOUSE_BUTTON)
1097 {
1098 int x =returnval.GetMouseButtonEvent().x;
1099 int y =returnval.GetMouseButtonEvent().y;
1100 newlist->PushBack(Variant(x));
1101 newlist->PushBack(Variant(y));
1102 int btn = returnval.GetMouseButtonEvent().button;
1103 Variant button = Variant(btn);
1104 newlist ->PushBack(button);
1105
1106 Variant buttonstate = "";
1107 int upstate = returnval.GetMouseButtonEvent().state;
1108 if(upstate == PEBL_PRESSED)
1109 {
1110 buttonstate = Variant("<pressed>");
1111 }
1112 else
1113 {
1114 buttonstate = Variant("<released>");
1115 }
1116 newlist->PushBack(buttonstate);
1117
1118 }else if(returnval.GetType()==PDT_MOUSE_WHEEL)
1119 {
1120
1121 unsigned long int x =returnval.GetMouseWheelEvent().x;
1122 unsigned long int y =returnval.GetMouseWheelEvent().y;
1123 newlist->PushBack(Variant(x));
1124 newlist->PushBack(Variant(y));
1125
1126 long int deltax = returnval.GetMouseWheelEvent().deltax;
1127 long int deltay = returnval.GetMouseWheelEvent().deltay;
1128
1129
1130 Variant button = 0; //keep button code here for consistency.
1131 newlist ->PushBack(button);
1132
1133 Variant buttonstate = "<wheel>";
1134 newlist->PushBack(buttonstate);
1135
1136 Variant buttonstatex = (pInt)deltax;
1137 Variant buttonstatey = (pInt)(deltay*returnval.GetMouseWheelEvent().direction);
1138
1139 newlist->PushBack(buttonstatex);
1140 newlist->PushBack(buttonstatey);
1141
1142 }
1143
1145 PComplexData * pcd = new PComplexData(newlist2);
1146 newlist = NULL;
1147
1148 return Variant(pcd);
1149}
1150
1155{
1156
1157
1158
1159 //v[1] should have the parameter: a time to wait.
1160 PList * plist = v.GetComplexData()->GetList();
1161
1162 PError::AssertType(plist->First(), PEAT_NUMBER, "Argument error in function [WaitForMouseButtonWithTimeout(<number>)]: ");
1163
1164 //set the timeout
1165 int delay = plist->First(); //plist->PopFront();
1166 delay += myTimer.GetTime();
1167
1168
1169 //Create a timer test
1170 //1 is the value (down), DT_GREATERTHAN is the test, key is
1171 // the interface (e.g., the 'A' key)
1172 PDevice * timer = new PlatformTimer(myTimer);
1173 ValueState * timestate = new ValueState(delay, DT_GREATER_THAN_OR_EQUAL, PDT_TIMER, timer, PDT_TIMER);
1174
1175
1176
1178 //Create a mouse test
1179 //1 is the value (down), DT_EQUAL is the test, 1 is the interface (e.g., the 'A' key)
1180
1182
1183
1185
1186
1187
1188 //NULL,NULL will terminate the looping
1189 string funcname = "";
1190 Evaluator::mEventLoop->RegisterEvent(state,funcname, Variant(0));
1191 Evaluator::mEventLoop->RegisterEvent(state2,funcname, Variant(0));
1192 Evaluator::mEventLoop->RegisterState(timestate, funcname, Variant(0));
1193
1194 PEvent returnval = Evaluator::mEventLoop->Loop();
1195
1196
1197 //Now, clear the event loop tests
1199
1200
1201 PList *newlist = new PList();
1202
1203 if(returnval.GetType()== PDT_MOUSE_BUTTON)
1204 {
1205
1206
1207 int x =returnval.GetMouseButtonEvent().x;
1208 int y =returnval.GetMouseButtonEvent().y;
1209 newlist->PushBack(Variant(x));
1210 newlist->PushBack(Variant(y));
1211 int btn = returnval.GetMouseButtonEvent().button;
1212 Variant button = Variant(btn);
1213 newlist ->PushBack(button);
1214
1215 Variant buttonstate = "";
1216 int upstate = returnval.GetMouseButtonEvent().state;
1217 if(upstate == PEBL_PRESSED)
1218 {
1219 buttonstate = Variant("<pressed>");
1220 } else {
1221 buttonstate = Variant("<released>");
1222 }
1223 newlist->PushBack(buttonstate);
1224
1225 }else if(returnval.GetType()==PDT_MOUSE_WHEEL)
1226 {
1227
1228 unsigned long int x =returnval.GetMouseWheelEvent().x;
1229 unsigned long int y =returnval.GetMouseWheelEvent().y;
1230 newlist->PushBack(Variant(x));
1231 newlist->PushBack(Variant(y));
1232
1233 long int deltax = returnval.GetMouseWheelEvent().deltax;
1234 long int deltay = returnval.GetMouseWheelEvent().deltay;
1235
1236
1237 Variant button = 0; //keep button code here for consistency.
1238 newlist ->PushBack(button);
1239
1240 Variant buttonstate = "<wheel>";
1241 newlist->PushBack(buttonstate);
1242
1243 Variant buttonstatex = (pInt)deltax;
1244 Variant buttonstatey = (pInt)(deltay*returnval.GetMouseWheelEvent().direction);
1245
1246 newlist->PushBack(buttonstatex);
1247 newlist->PushBack(buttonstatey);
1248
1249 } else //PCD_TIMER
1250 {
1251
1252 return Variant("<timeout>");
1253
1254 }
1255
1257 PComplexData * pcd = new PComplexData(newlist2);
1258 return Variant(pcd);
1259}
1260
1261
1262
1263
1270
1271
1272
1273
1276{
1277 PList * plist = v.GetComplexData()->GetList();
1278 //The first argument should be a textbox.
1279 PError::AssertType(plist->First(), PEAT_NUMBER, "Argument error in first argument of function [SetCursorPosition(<x>,<y>)]: ");
1280 int x = plist->First();
1281 //plist->PopFront();
1282
1283 PError::AssertType(plist->Nth(2), PEAT_NUMBER, "Argument error in second argument of function [SetCursorPosition(<x>,<y>)]: ");
1284
1285 int y =plist->Nth(2);
1286 // plist->PopFront();
1287
1289 return Variant(1);
1290}
1291
1297
1298 //basic joystick stuff
1303
1304//This returns a joystic to use, based on its name.
1306{
1307
1308 PList * plist = v.GetComplexData()->GetList();
1309 //The first argument should be an integer specifying the joystick index
1310 PError::AssertType(plist->First(), PEAT_INTEGER, "Argument error in argument of function [GetJoystick(<int>)]: ");
1311 int id = plist->First();
1312 //plist->PopFront();
1313
1314
1315 PlatformJoystick * js = new PlatformJoystick(id);
1317 PComplexData * pcd = new PComplexData(joy);
1318 return Variant(pcd);
1319
1320}
1321
1323{
1324
1325 PList * plist = v.GetComplexData()->GetList();
1326 //The first argument should be a joystick
1327 PError::AssertType(plist->First(), PEAT_JOYSTICK, "Argument error in argument of function [GetNumJoystickAxes(<joystick>)]: ");
1328
1329 PlatformJoystick * joystick = dynamic_cast<PlatformJoystick*>(plist->First().GetComplexData()->GetObject().get());
1330
1331 return Variant(joystick->GetNumAxes());
1332}
1333
1334
1336{
1337 PList * plist = v.GetComplexData()->GetList();
1338 //The first argument should be a joystick
1339 PError::AssertType(plist->First(), PEAT_JOYSTICK, "Argument error in argument of function [GetNumJoystickBalls(<joystick>)]: ");
1340
1341 PlatformJoystick * joystick = dynamic_cast<PlatformJoystick*>(plist->First().GetComplexData()->GetObject().get());
1342
1343
1344 return Variant(joystick->GetNumBalls());
1345
1346}
1348{
1349 PList * plist = v.GetComplexData()->GetList();
1350 //The first argument should be a joystick
1351 PError::AssertType(plist->First(), PEAT_JOYSTICK, "Argument error in argument of function [GetNumJoystickButtons(<joystick>)]: ");
1352 PlatformJoystick * joystick = dynamic_cast<PlatformJoystick*>(plist->First().GetComplexData()->GetObject().get());
1353
1354
1355
1356 return Variant(joystick->GetNumButtons());
1357
1358}
1360{
1361 PList * plist = v.GetComplexData()->GetList();
1362 //The first argument should be a joystick
1363 PError::AssertType(plist->First(), PEAT_JOYSTICK, "Argument error in argument of function [GetNumJoystickHats(<joystick>)]: ");
1364 PlatformJoystick * joystick = dynamic_cast<PlatformJoystick*>(plist->First().GetComplexData()->GetObject().get());
1365
1366
1367 return Variant(joystick->GetNumHats());
1368
1369}
1370
1371
1373{
1374 PList * plist = v.GetComplexData()->GetList();
1375 //The first argument should be a joystick
1376 PError::AssertType(plist->First(), PEAT_JOYSTICK, "Argument error in first argument of function [GetJoystickButtonState(<joystick>,<button>)]: ");
1377 PlatformJoystick * joystick = dynamic_cast<PlatformJoystick*>(plist->First().GetComplexData()->GetObject().get());
1378 // plist->PopFront();
1379
1380 PError::AssertType(plist->Nth(2), PEAT_INTEGER, "Argument error in second argument of function [GetJoystickButtonState(<joystick>,<button>)]: ");
1381 unsigned int button = (unsigned int)(int)(plist->Nth(2));
1382
1383
1384 return joystick->GetButtonState(button);
1385}
1386
1388{
1389
1390 PList * plist = v.GetComplexData()->GetList();
1391 //The first argument should be a joystick
1392 PError::AssertType(plist->First(), PEAT_JOYSTICK, "Argument error in first argument of function [GetJoystickAxisState(<joystick>,<axis>)]: ");
1393 PlatformJoystick * joystick = dynamic_cast<PlatformJoystick*>(plist->First().GetComplexData()->GetObject().get());
1394 //plist->PopFront();
1395
1396 PError::AssertType(plist->Nth(2), PEAT_INTEGER, "Argument error in second argument of function [GetJoystickAxisState(<joystick>,<axis>)]: ");
1397
1398 unsigned int axis = (unsigned int)(int)(plist->Nth(2));
1399
1400 return joystick->GetAxisState(axis);
1401
1402}
1403
1404
1406{
1407 PList * plist = v.GetComplexData()->GetList();
1408 //The first argument should be a joystick
1409 PError::AssertType(plist->First(), PEAT_JOYSTICK, "Argument error in first argument of function [GetJoystickHatState(<joystick>,<hat>)]: ");
1410 PlatformJoystick * joystick = dynamic_cast<PlatformJoystick*>(plist->First().GetComplexData()->GetObject().get());
1411 // plist->PopFront();
1412
1413 PError::AssertType(plist->Nth(2), PEAT_INTEGER, "Argument error in second argument of function [GetJoystickHatState(<joystick>,<hat>)]: ");
1414
1415 unsigned int hat = (unsigned int)(int)(plist->First());
1416
1417 return joystick->GetHatState(hat);
1418
1419}
1420
1421
1423{
1424 PList * plist = v.GetComplexData()->GetList();
1425 //The first argument should be a joystick
1426 PError::AssertType(plist->First(), PEAT_JOYSTICK, "Argument error in first argument of function [GetJoystickBallState(<joystick>,<button>)]: ");
1427 PlatformJoystick * joystick = dynamic_cast<PlatformJoystick*>(plist->First().GetComplexData()->GetObject().get());
1428 // plist->PopFront();
1429
1430 PError::AssertType(plist->Nth(2), PEAT_INTEGER, "Argument error in second argument of function [GetJoystickBallState(<joystick>,<button>)]: ");
1431 unsigned int button = (unsigned int)(int)(plist->Nth(2));
1432
1433
1434 return joystick->GetBallState(button);
1435
1436
1437}
1438
1439
1440// This takes an event definition, and function,
1441//
1442//
1443// First parameter is device as a <string> should take Device as a
1444//Complex eventloop construction.
1445// arguments are:
1446//
1447// device
1448// intface
1449// comparison
1450// function name
1451// parameters???
1452//
1453//
1454//
1455//
1457{
1458
1459 //v[1] should have the parameter-a letter
1460 PList * plist = v.GetComplexData()->GetList();
1461
1462
1463 //arguments are:
1464 //1: event type as a string
1465 //2: interface (key, etc), dummy value of 1 for timer
1466 //3: state (pressed/released)
1467 //4: logical test
1468 //5: called function ("" for no function call)
1469 //6: function arguments
1470
1471 PError::AssertType(plist->First(), PEAT_STRING, "Argument error in function [RegisterEvent(<string>)]: ");
1472 string mystring = PEBLUtility::ToUpper(plist->First());
1473
1474 PDevice * device = NULL;
1475
1476 enum PEBL_DEVICE_TYPE devicetype = PDT_DUMMY;
1477 int type = PEBL_UNKNOWN;
1478
1479
1480 if(mystring == "<KEY_PRESS>")
1481 {
1482 type=PEBL_PRESSED;
1483 device = gEventQueue;
1484 devicetype = PDT_KEYBOARD;
1485 }
1486 else if(mystring == "<KEY_RELEASE>")
1487 {
1488 type=PEBL_RELEASED;
1489 device = gEventQueue;
1490 devicetype = PDT_KEYBOARD;
1491
1492
1493 }else if(mystring == "<TEXT_INPUT>")
1494 {
1495 type=PEBL_TEXT_INPUT;
1496 device = gEventQueue;
1497 devicetype = PDT_TEXT_INPUT;
1498
1499
1500 }else if(mystring == "<MOUSE_MOVEMENT>")
1501 {
1502 type = PEBL_MOVEMENT;
1503 device = gEventQueue;
1504 devicetype = PDT_MOUSE_MOVEMENT;
1505
1506
1507 }else if(mystring == "<MOUSE_BUTTON>")
1508 {
1509
1510 //this is sort of broken--keeping it around because
1511 //it used to work ok in 1.0, but now we should use
1512 //mouse_button_press and mouse_button_release
1513 type = PEBL_PRESSED;
1514 device = gEventQueue;
1515 devicetype = PDT_MOUSE_BUTTON;
1516
1517
1518 }else if(mystring == "<MOUSE_BUTTON_PRESS>")
1519 {
1520 type = PEBL_PRESSED;
1521 device = gEventQueue;
1522 devicetype = PDT_MOUSE_BUTTON;
1523
1524 }else if(mystring == "<MOUSE_BUTTON_RELEASE>")
1525 {
1526 type = PEBL_RELEASED;
1527 device = gEventQueue;
1528 devicetype = PDT_MOUSE_BUTTON;
1529
1530 } else if(mystring== "<TIMER>")
1531 {
1532
1533
1534 type = PEBL_TIMEOUT;
1535 //This has the potential to leak:
1536 device = new PlatformTimer(myTimer);
1537 devicetype = PDT_TIMER;
1538
1539 //this will be a state, not an event.
1540
1541 }else if(mystring == "<WINDOW_RESIZE>")
1542 {
1543 type = PEBL_WINDOWWIDTH;
1544 device = gEventQueue;
1545 devicetype = PDT_WINDOW_RESIZE;
1546
1547 //cout << "Creating window resize:" << PDT_WINDOW_RESIZE << endl;
1548 }else if (mystring == "<JOYSTICK_BUTTON>")
1549 {
1550 type = PEBL_PRESSED;
1551 device = gEventQueue;
1552 devicetype = PDT_JOYSTICK_BUTTON;
1553
1554 }else if (mystring == "<JOYSTICK_HAT>")
1555 {
1556 type = PEBL_PRESSED;
1557 device = gEventQueue;
1558 devicetype = PDT_JOYSTICK_HAT;
1559
1560
1561 }else if (mystring == "<JOYSTICK_AXIS>")
1562 {
1563 type = PEBL_PRESSED;
1564 device = gEventQueue;
1565 devicetype = PDT_JOYSTICK_HAT;
1566
1567 }else if (mystring == "<JOYSTICK_BALL>")
1568 {
1569 type = PEBL_PRESSED;
1570 device = gEventQueue;
1571 devicetype = PDT_JOYSTICK_HAT;
1572 }else
1573 {
1574 //Note: PDT_stream, PDTevent_queue, and PDT_audio_out
1575 //not handled.
1576
1577 PError::SignalFatalError("Unknown Device\n");
1578 }
1579
1580
1584
1585 //Next argument is a value or range
1586 //It should be either a number,
1587 // or a list of 2 or 4 items.
1588 //For keyboard events, this can be anything, because it should be
1589 //overridden by whether it is key_press or key_release.
1590
1591 Variant v1,v2,v11,v12,v21,v22;
1592 enum DeviceTestType testtype;
1593
1594 Variant p = plist->Nth(3);//plist->PopFront();
1595 if(devicetype== PDT_KEYBOARD |
1596 devicetype == PDT_MOUSE_BUTTON)
1597 {
1598 p =type;
1599 testtype =DTT_VALUESTATE;
1600 } else {
1601
1602
1603
1604
1605
1606
1607 if(p.IsNumber())
1608 {
1609
1610
1611 testtype =DTT_VALUESTATE;
1612 PError::AssertType(p, PEAT_INTEGER, "In RegisterEvent, test bounds not a number:");
1613 //valuestate
1614 // this will crash!!! }else if (p.IsList())
1615
1616 }else
1617 {
1618
1619
1620
1621 PList * myList = (PList*)(p.GetComplexData()->GetObject().get());
1622 // This will be either intervalstate or regionstate
1623 // if it is an intervalstate, the list well have two numbers inside it
1624 // for a regionstate, the list will have two sublists.
1625
1626 v1 = myList->First();//myList->PopFront();
1627 v2 = myList->Nth(2);//First();myList->PopFront();
1628
1629 if(/* DISABLES CODE */ (0))//v1.IsList())
1630 {
1631
1632 //regionstate;
1633 testtype =DTT_REGIONSTATE;
1634
1635 PList * sublist1 = (PList*)(v1.GetComplexData()->GetObject().get());
1636 PList * sublist2 = (PList*)(v2.GetComplexData()->GetObject().get());
1637
1638 //Could this end up destroying a global list???
1639 v11 = sublist1->First();// sublist1->PopFront();
1640 v12 = sublist1->Nth(2);
1641 v21 = sublist2->First(); //sublist1->PopFront();
1642 v22 = sublist2->Nth(2);//First();
1643
1644 }
1645 else
1646 {
1647
1648 testtype = DTT_INTERVALSTATE;
1649 PError::AssertType(v1, PEAT_NUMBER, "In RegisterEvent, test bounds not a number:");
1650 PError::AssertType(v2, PEAT_NUMBER, "In RegisterEvent, test bounds not a number:");
1651 //intervalstate
1652 //ValueState * state = new ValueState(1, DT_EQUAL, key, device, PDT_KEYBOARD);
1653
1654
1655 }
1656
1657
1658 }
1659 }
1660
1661
1662
1663
1664 //Next argument is the interface
1665 //for mouse/keyboard, this is the button
1666 //for textinput, it doesn't matter.
1667
1668 Variant intface =(plist->Nth(2));// plist->PopFront();
1669
1670 if(devicetype == PDT_KEYBOARD)
1671 {
1672 //cout<<"Translating interface/keycode"<<intface << "==";
1673 // PEBL_Keycode key = PEBLUtility::TranslateString(intface);
1674 intface = PEBLUtility::TranslateString(intface);
1675 //cout << intface << endl;
1676
1677 }
1678
1679
1680
1681
1682
1683
1684 //1 is the value (down), DT_EQUAL is the test, key is the interface (e.g., the 'A' key)
1685
1686 // intervalstate or
1687 // regionstate:
1688 // inside
1689 // not_outside
1690 // outside
1691 // note_inside
1692 // on_edge
1693
1694 // other:
1695 // TRUE
1696 // FALSE
1697
1698
1700 "Error in 4th argument of function [RegisterEvent(<device>,<interface>,valuerange,comparison,<function>,<fval>)]: ");
1701
1702
1703 std::string test = PEBLUtility::ToUpper(plist->Nth(4)); //plist->PopFront();
1704 enum DeviceTest dtype=DT_TRUE;
1705
1706 switch(testtype)
1707 {
1708 case DTT_VALUESTATE:
1709
1710 if(test == "<NOTEQUAL>")
1711 {
1712 dtype = DT_NOT_EQUAL;
1713 }
1714 else if(test == "<EQUAL>")
1715 {
1716 dtype = DT_EQUAL;
1717 }
1718 else if(test == "<LESSTHAN>")
1719 {
1720 dtype = DT_LESS_THAN;
1721 }
1722 else if(test == "<GREATERTHAN>")
1723 {
1724 dtype = DT_GREATER_THAN;
1725 }
1726 else if(test =="<LEQ>")
1727 {
1728 dtype = DT_LESS_THAN_OR_EQUAL;
1729 }
1730 else if( test == "<GEQ>")
1731 {
1733 }
1734 else if(test == "<TRUE>")
1735 {
1736 dtype = DT_TRUE;
1737 }
1738 else if(test == "<FALSE>")
1739 {
1740 dtype = DT_FALSE;
1741 }else{
1742
1743 PError::SignalFatalError("test type not available for value comparisons");
1744 }
1745
1746 break;
1747
1748 //The same test types are available
1749 //for intervals and regions.
1750 case DTT_INTERVALSTATE:
1751 case DTT_REGIONSTATE:
1752
1753 if(test =="<INSIDE>")
1754 {
1755 dtype = DT_INSIDE;
1756 }
1757 else if(test == "<OUTSIDE>")
1758 {
1759 dtype = DT_OUTSIDE;
1760 }
1761 else if (test == "<TRUE>")
1762 {
1763 dtype = DT_TRUE;
1764 }
1765 else if (test == "<FALSE>")
1766 {
1767 dtype = DT_FALSE;
1768 }
1769 else if( test == "<ON_EDGE>")
1770 {
1771 dtype = DT_ON_EDGE;
1772 }
1773 else if(test =="<NOT_INSIDE>")
1774 {
1775 dtype = DT_NOT_INSIDE;
1776 }
1777 else if(test == "<NOT_OUTSIDE>")
1778 {
1779 dtype = DT_OUTSIDE;
1780 }else
1781 {
1782 PError::SignalFatalError("Test type not available for region or interval test");
1783 }
1784
1785 }
1786
1787
1788
1789
1790 PError::AssertType(plist->Nth(5), PEAT_STRING, "Error in parameter of function [RegisterEvent(<device>,<xxx>,<functionname>)]: ");
1791 string funcname = PEBLUtility::ToUpper(plist->Nth(5));// plist->PopFront();
1792 //Can we check to see if funcname exists in the functionmap?
1793
1794
1795
1796 DeviceState * state = NULL;
1797
1798 switch(testtype)
1799 {
1800 case DTT_VALUESTATE:
1801
1802
1803
1804 state = new ValueState((int)p,
1805 dtype,
1806 (int)intface,
1807 device, devicetype);
1808
1809
1810
1811 break;
1812 case DTT_INTERVALSTATE:
1813 //This might not work right now.
1814 state = new IntervalState((int)v1,(int)v2, dtype, (int)intface, device, devicetype);
1815 break;
1816 case DTT_REGIONSTATE:
1817 //This might not work right now.
1818 state = new RegionState((int)v11, (int)v12, (int)v21, (int)v22, dtype, (int)intface, device, devicetype);
1819 break;
1820 }
1821
1822
1823
1824 //get the parameter to pass to the callback function.
1825
1826 Variant parameters = plist->Nth(6);//; plist->PopFront();
1827
1828 if(parameters.IsStackSignal())
1829 parameters = Variant(0);
1830
1831 if(devicetype == PDT_TIMER)
1832 {
1833 Evaluator::mEventLoop->RegisterState(state,funcname,
1834 parameters);
1835
1836 //cout<<">>>>>>>>>>Timer" << *Evaluator::mEventLoop << endl;
1837 }
1838 else
1839 {
1840
1841 Evaluator::mEventLoop->RegisterEvent(state,funcname, parameters);
1842 //cout<<">>>>>>>>>>>>nonTimer" << *Evaluator::mEventLoop << endl;
1843 }
1844
1845
1846
1847 return Variant(0);
1848}
1849
1850
1852{
1853
1854
1855 PEvent returnval = Evaluator::mEventLoop->Loop();
1856
1857
1858
1859 /*
1860 returnval could take on any one of the folloing event types:
1861 we need to make as many of them interpretable as possible.
1862 it should return, in each case, the same thing returned by the custom
1863 compiled library function; i.e., the key name, mouse position, etc.
1864
1865
1866 PDT_UNKNOWN = 0,
1867 PDT_KEYBOARD,
1868 PDT_TEXT_INPUT,
1869 PDT_TEXT_EDITING,
1870 PDT_MOUSE_MOVEMENT,
1871 PDT_MOUSE_BUTTON,
1872 PDT_MOUSE_WHEEL,
1873 PDT_TIMER,
1874 PDT_STREAM,
1875 PDT_EVENT_QUEUE,
1876 PDT_AUDIO_OUT,
1877 PDT_JOYSTICK_AXIS,
1878 PDT_JOYSTICK_BALL,
1879 PDT_JOYSTICK_BUTTON,
1880 PDT_JOYSTICK_HAT,
1881 PDT_PORT,
1882 PDT_MOVIE_REFRESH,
1883 PDT_MOVIE_END,
1884 PDT_WINDOW_RESIZE,
1885 PDT_DUMMY
1886 */
1887 Variant ret = Variant(-999);
1888 // cout << "returntype:" << returnval.GetType() <<endl;
1889
1890
1891 switch(returnval.GetType())
1892 {
1893
1894 case PDT_KEYBOARD:
1895 //cout << "Keyborad event\n";
1896
1898
1899 break;
1900
1901
1902 case PDT_MOUSE_MOVEMENT:
1903 case PDT_MOUSE_BUTTON:
1904 {
1905 //cout << "Mouse button/move case\n";
1906 PList * newlist = new PList();
1907 int x =returnval.GetMouseButtonEvent().x;
1908 int y =returnval.GetMouseButtonEvent().y;
1909 newlist->PushBack(Variant(x));
1910 newlist->PushBack(Variant(y));
1911 int btn = returnval.GetMouseButtonEvent().button;
1912 Variant button = Variant(btn);
1913 newlist ->PushBack(button);
1914
1915 Variant buttonstate = "";
1916 int upstate = returnval.GetMouseButtonEvent().state;
1917 if(upstate == PEBL_PRESSED)
1918 {
1919 buttonstate = Variant("<pressed>");
1920 }
1921 else
1922 {
1923 buttonstate = Variant("<released>");
1924 }
1925 newlist->PushBack(buttonstate);
1927 PComplexData * pcd = new PComplexData(newlist2);
1928 newlist = NULL;
1929
1930 ret = Variant(pcd);
1931
1932 }
1933 break;
1934
1935 case PDT_MOUSE_WHEEL:
1936 {
1937
1938 //cout << "Mouse wheel case\n";
1939
1940 PList * newlist = new PList();
1941 unsigned long int x =returnval.GetMouseWheelEvent().x;
1942 unsigned long int y =returnval.GetMouseWheelEvent().y;
1943 newlist->PushBack(Variant(x));
1944 newlist->PushBack(Variant(y));
1945
1946 long int deltax = returnval.GetMouseWheelEvent().deltax;
1947 long int deltay = returnval.GetMouseWheelEvent().deltay;
1948
1949
1950 Variant button = 0; //keep button code here for consistency.
1951 newlist ->PushBack(button);
1952
1953 Variant buttonstate = "<wheel>";
1954 newlist->PushBack(buttonstate);
1955
1956 Variant buttonstatex = (pInt)deltax;
1957 Variant buttonstatey = (pInt)(deltay*returnval.GetMouseWheelEvent().direction);
1958
1959 newlist->PushBack(buttonstatex);
1960 newlist->PushBack(buttonstatey);
1961
1963 PComplexData * pcd = new PComplexData(newlist2);
1964 newlist = NULL;
1965
1966 ret = Variant(pcd);
1967
1968 //should return a list of mouse
1969 break;
1970 }
1971
1972 case PDT_TIMER:
1973 //cout << "TIMEOUT case\n";
1974 ret = Variant("<timeout>");
1975 break;
1976 default:
1977 //cout << "UNKNOWN\n";
1978 ret = Variant("<unknown>");
1979 }
1980
1981
1982 return ret;
1983}
1984
1985
1987{
1988
1989
1991
1992 return Variant(0);
1993}
1994
1995
1996//Calls a function with the specified parameters
1998{
1999
2000 //v[1] should have the key
2001 PList * plist = v.GetComplexData()->GetList();
2002
2004 "Argument error in first argument of function [CallFunction(<fname>,[<paramlist>])]: ");
2005 PError::AssertType(plist->Nth(2), PEAT_LIST,
2006 "Argument error in second argument of function [CallFunction(<fname>,[<paramlist>])]: ");
2007
2008 Variant fname = plist->First();
2009 Variant args = plist->Nth(2);
2010
2011
2012 //we need to create a 'varlist' tree, which
2013 //is a set of opnode(varlist) nodes with the variable on
2014 // the left and another opnode on the right.
2015
2016 PList * arglist = args.GetComplexData()->GetList();
2017
2018
2019 std::vector<Variant>::iterator a = arglist->End();
2020 PNode * rest = NULL;
2021 while(a != arglist->Begin())
2022 {
2023 a--;
2024
2025
2026 Variant value = *a;
2027 DataNode * valuenode = new DataNode(value,"<CALLBACK>",0);
2028 rest = new OpNode(PEBL_VARLIST,valuenode,rest, "<CALLBACK>",0);
2029
2030 }
2031
2032 //now, rest is equal to the argument list.
2033
2034 Variant fname2 = Variant(fname.GetString().c_str(), P_DATA_FUNCTION);
2035 DataNode * namenode = new DataNode(fname2,"<CALLBACK>",-1);
2036
2037
2038 OpNode * node = (OpNode*)Evaluator::mFunctionMap.GetFunction(fname);
2039
2040 Variant retval;
2041 if(node->GetOp()==PEBL_LAMBDAFUNCTION)
2042 {
2043 //For a lambda function, the left node is
2044 //a varlist, the right node is
2045 // the function block.
2046
2047
2048 PNode * arglistnode = ((OpNode*)node)->GetLeft();
2049
2050
2051#ifdef PEBL_ITERATIVE_EVAL
2052 //For iterative evaluator, schedule the function call and execute until complete
2053
2054 //Create a DataNode containing the actual parameter values
2055 DataNode * argsDataNode = new DataNode(args, "user-generated", -1);
2056
2057 //Create the PEBL_FUNCTION node with the parameter values
2058 OpNode * fnode = new OpNode(PEBL_FUNCTION, namenode, (PNode*)argsDataNode, "user-generated", -1);
2059
2060 //Save the current node stack size to know when the function completes
2061 size_t nodeStackSizeBefore = myEval->GetNodeStackDepth();
2062
2063 //Schedule the PEBL_FUNCTION node on myEval's node stack
2064 //PEBL_FUNCTION will evaluate argsDataNode which pushes the parameter list onto the stack
2065 myEval->NodeStackPush(fnode);
2066
2067 //Execute nodes until the function completes
2068 //The function is complete when the node stack is back to its original size
2069 while(myEval->GetNodeStackDepth() > (int)nodeStackSizeBefore)
2070 {
2071 myEval->Evaluate1();
2072 }
2073
2074 //The function's return value should now be on top of the data stack
2075 //Pop it to return to the caller
2076 if(myEval->GetStackDepth() >= 1)
2077 {
2078 retval = myEval->Pop();
2079 }
2080 else
2081 {
2082 retval = Variant(0); //Default return value if stack is empty
2083 }
2084
2085 //Clean up the allocated nodes to prevent memory leaks
2086 //The nodes have been processed and the values are on the stack,
2087 //so we can safely delete them now
2088 delete argsDataNode;
2089 delete fnode;
2090#else
2091 //For recursive evaluator, create a new evaluator as before
2092 OpNode * fnode = new OpNode(PEBL_FUNCTION, namenode, arglistnode, "user-generated", -1);
2093
2094 Evaluator * eval = new Evaluator();
2095
2096 eval->Push(args);//add the parameter node
2097
2098
2099 eval->CallFunction(fnode);
2100
2101 if(eval->GetStackDepth()<1)
2102 {
2103 retval = Variant(0);
2104 }
2105 else{
2106
2107 retval = eval->Pop();
2108 }
2109
2110
2111
2112 delete eval;
2113#endif
2114 //Maybe this argument structure should be cleaned up?
2115 rest->DestroyChildren();
2116 delete rest;
2117
2118
2119
2120 }
2121 else if(node->GetOp()==PEBL_LIBRARYFUNCTION)
2122 {
2123 //For a library function, the left node is an AND with min/max arguments
2124 //the right node has the function pointer.
2125
2126 //PNod * tmpNode = new DataNode(
2127
2128#if 0
2129 //THis is not used--not sure why it was created; mayb redundant with tmpNode above?
2130
2131 Variant fname2 = Variant(fname.GetString().c_str(), P_DATA_FUNCTION);
2132 PNode * tmpNode = new DataNode(fname2, "USER-GENERATED",-1);
2133
2134 PNode * arglistnode = ((OpNode*)node)->GetLeft();
2135
2136 OpNode * fnode = new OpNode(PEBL_FUNCTION, tmpNode, arglistnode, "user-generated", -1);
2137
2138#endif
2139
2140
2141 Evaluator * eval = new Evaluator();
2142
2143
2144
2145 eval->Push(args);//add the parameter node
2146
2147#ifdef PEBL_ITERATIVE_EVAL
2148 eval->Evaluate1(node);
2149 eval->Evaluate1();
2150#else
2151 eval->Evaluate(node);
2152#endif
2153
2154 if(eval->GetStackDepth()<1)
2155 {
2156 retval = Variant(0);
2157 }
2158 else
2159 {
2160
2161 retval = eval->Pop();
2162 }
2163
2164
2165
2166 delete eval;
2167 //Maybe this argument structure should be cleaned up?
2168 rest->DestroyChildren();
2169 delete rest;
2170
2171
2172 }
2173 else
2174 {
2175 //Unknown type
2176 }
2177
2178 return retval;
2179}
2180
2181
2183{
2184 //Signal a fatal error with the message inside v
2185 PList * plist = v.GetComplexData()->GetList();
2186 std::string message = plist->First().GetString();
2187
2188 PError::SignalFatalError(message);
2189 return Variant(false);
2190}
2191
2192
2194{
2195 //Exit quietly with optional exit code
2196 //First parameter is message, optional second parameter is exit code (default 0)
2197 PList * plist = v.GetComplexData()->GetList();
2198 std::string message = plist->First().GetString();
2199
2200 int exitCode = 0; // Default exit code
2201 if(plist->Length() >= 2)
2202 {
2203 exitCode = plist->Nth(2).GetInteger();
2204 }
2205
2206 PError::ExitQuietly(message, exitCode);
2207 return Variant(false);
2208}
2209
2210
2215{
2216
2217 //v[1] should have the key
2218 PList * plist = v.GetComplexData()->GetList();
2219
2220 PError::AssertType(plist->First(), PEAT_INTEGER, "Argument error in function [TranslateKeyCode(<integer>)]: ");
2221
2222 int key = (int)(plist->First());// plist->PopFront();
2223
2224 std::string retval = PEBLUtility::TranslateKeycode((PEBL_Keycode)key, PEBLMOD_NONE);
2225 return Variant(retval);
2226
2227}
2228
2233{
2234
2235
2236 PList * plist = v.GetComplexData()->GetList();
2237 //v[1] should have the parameter-a letter
2238
2239 PError::AssertType(plist->First(), PEAT_STRING, "Argument error in function [TranslateString(<string>)]: ");
2240
2241 string mystring = plist->First();// plist->PopFront();
2243
2244 return Variant(key);
2245
2246}
2247
2248
2249
2250
2252{
2253
2254 time_t rawtime;
2255 rawtime = time(NULL);
2256 char* timestring = ctime(&rawtime);
2257
2258
2259 //timestring now ends with a carriage return. So fix it.
2260
2261 int pos =0;
2262 while( timestring[pos] != '\n' && timestring[pos] != '\0')
2263 {
2264 pos++;
2265 }
2266 timestring[pos] = '\0';
2267 Variant ret = Variant(timestring);
2268
2269 return ret;
2270}
2271
2272
2274{
2275#ifdef PEBL_VALIDATOR
2276 // Validator mode: return dummy resolution
2277 PList * list = new PList();
2278 list->PushBack(Variant(1920));
2279 list->PushBack(Variant(1080));
2281 PComplexData * pcd = new PComplexData(tmp);
2282 Variant ret = Variant(pcd);
2283 delete pcd;
2284 return ret;
2285#else
2287#endif
2288}
2289
2290
2292{
2293#ifdef PEBL_VALIDATOR
2294 // Validator mode: return empty list
2295 PList * list = new PList();
2297 PComplexData * pcd = new PComplexData(tmp);
2298 Variant ret = Variant(pcd);
2299 delete pcd;
2300 return ret;
2301#else
2302 return SDLUtility::GetDriverList(false);
2303#endif
2304}
2305
2307{
2308
2309 int screen = 0;
2310 if(v.IsStackSignal())
2311 {
2312 screen = 0;
2313 }
2314 else
2315 {
2316 PList * plist = v.GetComplexData()->GetList();
2317 screen = plist->First();
2318 }
2319
2320 return myEnv->GetScreenModes(screen);
2321
2322}
2323
2325{
2326
2327 return Variant("PEBL Version " PEBL_VERSION);
2328}
2329
2330
2332{
2333#if defined(PEBL_EMSCRIPTEN)
2334 Variant type = "EMSCRIPTEN";
2335#elif defined(PEBL_OSX)
2336 Variant type = "OSX";
2337#elif defined (PEBL_UNIX)
2338 Variant type = "LINUX";
2339#else
2340 Variant type = "WINDOWS";
2341#endif
2342 return type;
2343}
2344
2346{
2347 SignalFatalError("Use gExecutableName");
2348 //THis should access a global variable that is set up on startup
2349 //that keeps track of the executable name.
2350 //return myEnv->GetExecutableName();
2351 return Variant(0);
2352}
2353
2354
2355
2356
2358{
2359 PList * plist = v.GetComplexData()->GetList();
2360 std::string file = plist->First().GetString();
2361
2362
2363 Variant success = PEBLUtility::LaunchFile(file.c_str());
2364 return success;
2365}
2366
2368{
2369
2370 PList * plist = v.GetComplexData()->GetList();
2371 std::string call = plist->First().GetString();
2372
2373
2374 std::string args;
2375
2376 if(plist->Length()>=2)
2377 {
2378 args = plist->Nth(2).GetString();
2379 }
2380 else
2381 {
2382 args = "";
2383 }
2384
2385
2386 Variant x =PEBLUtility::SystemCall(call.c_str(),args.c_str());
2387
2388
2389 return x;
2390
2391}
2392#ifdef PEBL_WINDOWS
2393
2395{
2396
2397 PList * plist = v.GetComplexData()->GetList();
2398
2399 std::string call = plist->Nth(1).GetString();
2400 std::string args;
2401
2402 if(plist->Length()>=2)
2403 {
2404 args = plist->Nth(2).GetString();
2405 }
2406 else
2407 {
2408 args = "";
2409 }
2410
2411
2412 PROCESS_INFORMATION pi =PEBLUtility::SystemCallAndReturn(call.c_str(),args.c_str());
2413
2414 //Now, we should call wait and draw repeatedly.
2415 DWORD out = WAIT_TIMEOUT;
2416 while(out == WAIT_TIMEOUT)
2417 {
2418 out= ::WaitForSingleObject(pi.hProcess, 10);
2419#if 0
2420 cout << "WAIT_ABANDONED: " << (out == WAIT_ABANDONED) << endl;
2421 cout << "WAIT_OBJECT_0: " << (out == WAIT_OBJECT_0) << endl;
2422 cout << "WAIT_TIMEOUT: " << (out == WAIT_TIMEOUT) << endl;
2423 cout <<"WAIT_FAILED: "<< (out == WAIT_FAILED) << endl;
2424#endif
2425
2426 myEnv->Draw();
2427 }
2428
2429 ::CloseHandle(pi.hProcess);
2430 ::CloseHandle(pi.hThread);
2431
2432 return Variant(true);
2433
2434}
2435#else
2436
2437// Unix/Linux implementation - fork and return PID
2439{
2440#if defined(PEBL_UNIX)
2441 PList * plist = v.GetComplexData()->GetList();
2442
2443 std::string call = plist->Nth(1).GetString();
2444 std::string args;
2445
2446 if(plist->Length()>=2)
2447 {
2448 args = plist->Nth(2).GetString();
2449 }
2450 else
2451 {
2452 args = "";
2453 }
2454
2455 // Combine command and args for shell execution
2456 std::string fullcmd = call + " " + args;
2457
2458 // Fork a child process
2459 pid_t pid = fork();
2460
2461 if (pid < 0) {
2462 // Fork failed
2463 PError::SignalWarning("SystemCallUpdate: fork() failed");
2464 return Variant(-1);
2465 }
2466 else if (pid == 0) {
2467 // Child process - execute the command
2468 execl("/bin/sh", "sh", "-c", fullcmd.c_str(), (char *)NULL);
2469 // If execl returns, it failed
2470 _exit(127);
2471 }
2472 else {
2473 // Parent process - return the child PID
2474 return Variant((pInt)pid);
2475 }
2476#else
2477 // Fallback for non-Unix platforms
2478 return SystemCall(v);
2479#endif
2480}
2481#endif
2482
2483
2484// Check process status - returns 0 if finished, 1 if running, -1 if error
2486{
2487 PList * plist = v.GetComplexData()->GetList();
2488 PError::AssertType(plist->First(), PEAT_INTEGER, "Argument error in function [CheckProcessStatus(<pid>)]: ");
2489
2490#if defined(PEBL_UNIX)
2491 pid_t pid = (pid_t)(plist->First().GetInteger());
2492
2493 int status;
2494 pid_t result = waitpid(pid, &status, WNOHANG);
2495
2496 if (result == 0) {
2497 // Process still running
2498 return Variant(1);
2499 }
2500 else if (result == pid) {
2501 // Process has finished
2502 return Variant(0);
2503 }
2504 else {
2505 // Error or already reaped
2506 return Variant(-1);
2507 }
2508#elif defined(PEBL_WIN32)
2509 DWORD pid = (DWORD)(plist->First().GetInteger());
2510
2511 HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
2512 if (hProcess == NULL) {
2513 // Process doesn't exist or already finished
2514 return Variant(0);
2515 }
2516
2517 DWORD exitCode;
2518 if (GetExitCodeProcess(hProcess, &exitCode)) {
2519 CloseHandle(hProcess);
2520 if (exitCode == STILL_ACTIVE) {
2521 // Process still running
2522 return Variant(1);
2523 } else {
2524 // Process has finished
2525 return Variant(0);
2526 }
2527 } else {
2528 // Error querying process
2529 CloseHandle(hProcess);
2530 return Variant(-1);
2531 }
2532#else
2533 // Not supported on other platforms
2534 PError::SignalWarning("CheckProcessStatus not supported on this platform");
2535 return Variant(-1);
2536#endif
2537}
2538
2539
2541{
2542 PList * plist = v.GetComplexData()->GetList();
2543
2544 PError::AssertType(plist->First(), PEAT_STRING, "Argument error in function [IsDirectory(<pathname>)]: ");
2545
2546 Variant out = PEBLUtility::IsDirectory(plist->First());
2547 return out;
2548}
2549
2550
2552{
2553 PList * plist = v.GetComplexData()->GetList();
2554
2555 PError::AssertType(plist->First(), PEAT_STRING, "Argument error in function [GetDirectoryListing(<pathname>)]: ");
2556
2558 return out;
2559}
2560
2561
2562
2564{
2565 PList * plist = v.GetComplexData()->GetList();
2566
2567 PError::AssertType(plist->First(), PEAT_STRING, "Argument error in function [FileExists(<filename>)]: ");
2568
2569 Variant out = PEBLUtility::FileExists(plist->First());
2570 //cout << "Fileexists:" << out << endl;
2571 return out;
2572}
2573
2574
2575
2577{
2578 PList * plist = v.GetComplexData()->GetList();
2579
2580 PError::AssertType(plist->First(), PEAT_STRING, "Argument error in function [MakeDirectory(<dirname>)]: ");
2581 //cout << "Making directory in penviremnt" << plist->First()<<std::endl;
2582// (std::string)(plist->First()
2584 return out;
2585}
2586
2588{
2589
2590 PList * plist = v.GetComplexData()->GetList();
2591
2592 PError::AssertType(plist->First(), PEAT_STRING, "Argument error in function [DeleteFile(<filename>)]: ");
2593 //cout << "Making directory in penviremnt" << plist->First()<<std::endl;
2594 Variant out = PEBLUtility::DeleteMyFile((plist->First()));
2595 return out;
2596
2597
2598}
2599
2606
2607
2608
2615
2616
2618{
2619 PList * plist = v.GetComplexData()->GetList();
2620
2621 PError::AssertType(plist->First(), PEAT_STRING, "Argument error in function [SetWorkingDirectory(<pathname>)]: ");
2622
2624 return out;
2625}
2626
2627
2629{
2630 PList * plist = v.GetComplexData()->GetList();
2631 Variant x = plist->First();
2632 PError::AssertType(x,PEAT_STRING,"Argument error in function [CopyToClipboard]: ");
2633
2634#ifdef PEBL_VALIDATOR
2635 // Validator mode: no-op
2636#else
2638#endif
2639 return x; //return whatever we copied here.
2640}
2641
2643{
2644#ifdef PEBL_VALIDATOR
2645 // Validator mode: return empty string
2646 return Variant("");
2647#else
2649#endif
2650}
2651
2652
2653
2654// This does not currently work.
2655//
2657{
2658 PList * plist = v.GetComplexData()->GetList();
2659 Variant x = plist->First();
2660 //return Variant(true);//
2661 return Variant(myEval->IsVariableName(x));
2662
2663}
2664
2665
2666
2668{
2669 PList * plist = v.GetComplexData()->GetList();
2670
2671 return plist->First().IsString();
2672}
2673
2674
2676{
2677 PList * plist = v.GetComplexData()->GetList();
2678
2679 return plist->First().IsNumber();
2680}
2681
2682
2684{
2685 PList * plist = v.GetComplexData()->GetList();
2686
2687 return plist->First().IsInteger();
2688}
2689
2690
2692{
2693 PList * plist = v.GetComplexData()->GetList();
2694
2695 return plist->First().IsFloat();
2696}
2697
2698
2699
2701{
2702 PList * plist = v.GetComplexData()->GetList();
2703 return plist->First().IsString();
2704}
2705
2706
2708{
2709 PList * plist = v.GetComplexData()->GetList();
2710
2711 Variant v1 = plist->First();
2712 if (v1.IsComplexData())
2713 {
2714 if((v1.GetComplexData())->IsList())
2715 {
2716 return Variant(true);
2717 }
2718 }
2719 return Variant(false);
2720}
2721
2722
2724{
2725 PList * plist = v.GetComplexData()->GetList();
2726
2727 Variant v1 = plist->First();
2728 if (v1.IsComplexData())
2729 {
2730 if((v1.GetComplexData())->IsTextBox())
2731 {
2732 return Variant(true);
2733 }
2734 }
2735 return Variant(false);
2736}
2737
2738
2739
2741{
2742 PList * plist = v.GetComplexData()->GetList();
2743
2744 Variant v1 = plist->First();
2745 if (v1.IsComplexData())
2746 {
2747 if((v1.GetComplexData())->IsJoystick())
2748 {
2749 return Variant(true);
2750 }
2751 }
2752 return Variant(false);
2753}
2754
2755
2756
2757
2759{
2760 PList * plist = v.GetComplexData()->GetList();
2761 Variant v1 = plist->First();
2762 if (v1.IsComplexData())
2763 {
2764 if((v1.GetComplexData())->IsCanvas())
2765 {
2766 return Variant(true);
2767 }
2768 }
2769 return Variant(false);
2770}
2771
2772
2774{
2775 PList * plist = v.GetComplexData()->GetList();
2776 Variant v1 = plist->First();
2777 if (v1.IsComplexData())
2778 {
2779 if((v1.GetComplexData())->IsImageBox())
2780 {
2781 return Variant(true);
2782 }
2783 }
2784 return Variant(false);
2785}
2786
2787
2788
2790{
2791 PList * plist = v.GetComplexData()->GetList();
2792 Variant v1 = plist->First();
2793 if (v1.IsComplexData())
2794 {
2795 if((v1.GetComplexData())->IsLabel())
2796 {
2797 return Variant(true);
2798 }
2799 }
2800 return Variant(false);
2801}
2802
2803
2804
2806{
2807 PList * plist = v.GetComplexData()->GetList();
2808
2809 Variant v1 = plist->First();
2810 if (v1.IsComplexData())
2811 {
2812 if((v1.GetComplexData())->IsAudioOut())
2813 {
2814 return Variant(true);
2815 }
2816 }
2817 return Variant(false);
2818}
2819
2820
2821
2823{
2824 PList * plist = v.GetComplexData()->GetList();
2825
2826 Variant v1 = plist->First();
2827 if (v1.IsComplexData())
2828 {
2829 if((v1.GetComplexData())->IsFont())
2830 {
2831 return Variant(true);
2832 }
2833 }
2834 return Variant(false);
2835}
2836
2837
2838
2840{
2841 PList * plist = v.GetComplexData()->GetList();
2842
2843 Variant v1 = plist->First();
2844 if (v1.IsComplexData())
2845 {
2846 if((v1.GetComplexData())->IsColor())
2847 {
2848 return Variant(true);
2849 }
2850 }
2851 return Variant(false);
2852}
2853
2854
2856{
2857 PList * plist = v.GetComplexData()->GetList();
2858 Variant v1 = plist->First();
2859 if (v1.IsComplexData())
2860 {
2861 if((v1.GetComplexData())->IsFileStream())
2862 {
2863 return Variant(true);
2864 }
2865 }
2866 return Variant(false);
2867}
2868
2870{
2871
2872 PList * plist = v.GetComplexData()->GetList();
2873 Variant v1 = plist->First();
2874 if (v1.IsComplexData())
2875 {
2876 if((v1.GetComplexData())->IsWidget())
2877 {
2878 return Variant(true);
2879 }
2880 }
2881 return Variant(false);
2882}
2883
2885{
2886
2887 PList * plist = v.GetComplexData()->GetList();
2888 Variant v1 = plist->First();
2889 if (v1.IsComplexData())
2890 {
2891 if((v1.GetComplexData())->IsWindow())
2892 {
2893 return Variant(true);
2894 }
2895 }
2896 return Variant(false);
2897}
2898
2899
2901{
2902
2903 PList * plist = v.GetComplexData()->GetList();
2904 Variant v1 = plist->First();
2905 if (v1.IsComplexData())
2906 {
2907 if((v1.GetComplexData())->IsDrawObject())
2908 {
2909 return Variant(true);
2910 }
2911 }
2912 return Variant(false);
2913}
2914
2915
2916
2918{
2919
2920 PList * plist = v.GetComplexData()->GetList();
2921 Variant v1 = plist->First();
2922 if (v1.IsComplexData())
2923 {
2924 if((v1.GetComplexData())->IsCustomObject())
2925 {
2926 return Variant(true);
2927 }
2928 }
2929 return Variant(false);
2930}
2931
2932// Check if value is a PEBL object with properties (font, color, widget, custom object, etc.)
2933// Returns true for anything that has properties via GetPropertyList()
2934// Excludes lists (which are ComplexData but have no properties)
2936{
2937 PList * plist = v.GetComplexData()->GetList();
2938 Variant v1 = plist->First();
2939
2940 // Must be ComplexData (excludes simple types like numbers/strings)
2941 // But must NOT be a list (lists have no properties)
2942 if (v1.IsComplexData() && !(v1.GetComplexData()->IsList()))
2943 {
2944 return Variant(true);
2945 }
2946
2947 return Variant(false);
2948}
2949
2950
2951
2952
2954{
2955#ifdef PEBL_MOVIES
2956 PList * plist = v.GetComplexData()->GetList();
2957
2958 PError::AssertType(plist->First(), PEAT_MOVIE, "Argument error in first parameter of function [PlayMovie(<movie>)]: ");
2959
2960
2961 Variant v1 = plist->First();
2962 PlatformMovie * myMovie = dynamic_cast<PlatformMovie*>(v1.GetComplexData()->GetObject().get());
2963
2964 //the endmovie event seems to be a bit buggy; so we need to get the actual duration and add a 'kill' event a bit after that.
2965 long int movietime = myMovie->GetLength();
2966
2967
2968 movietime += PEBLEnvironment::myTimer.GetTime()+100;
2970 ValueState * timestate = new ValueState(movietime, DT_GREATER_THAN_OR_EQUAL, 1, timer, PDT_TIMER);
2971 string funcname = "";
2972 Evaluator::mEventLoop->RegisterState(timestate, funcname, Variant(0));
2973 ValueState * state = new ValueState(1, DT_EQUAL, true, myMovie, PDT_MOVIE_END);
2974 //NULL,NULL will terminate the looping
2975
2976
2977 //Loop (play movie) until you get the end-of-movie event.
2978 Evaluator::mEventLoop->RegisterEvent(state, funcname, Variant(0));
2979
2980 myMovie->StartPlayback();
2981 PEvent returnval = Evaluator::mEventLoop->Loop();
2982
2983
2984 //Now, clear the event loop tests
2986
2987
2988 return Variant(returnval.GetDummyEvent().value);
2989#else
2990 PError::SignalFatalError("Movie playing capabilities not supported in this version.");
2991 return Variant(0);
2992#endif
2993
2994}
#define NULL
Definition BinReloc.cpp:317
#define pInt
Definition Defs.h:8
#define pDouble
Definition Defs.h:7
DeviceTestType
Definition DeviceState.h:59
@ DTT_REGIONSTATE
Definition DeviceState.h:62
@ DTT_INTERVALSTATE
Definition DeviceState.h:61
@ DTT_VALUESTATE
Definition DeviceState.h:60
DeviceTest
Definition DeviceState.h:41
@ DT_INSIDE
Definition DeviceState.h:48
@ DT_NOT_EQUAL
Definition DeviceState.h:42
@ DT_ON_EDGE
Definition DeviceState.h:52
@ DT_LESS_THAN_OR_EQUAL
Definition DeviceState.h:45
@ DT_TRUE
Definition DeviceState.h:53
@ DT_LESS_THAN
Definition DeviceState.h:44
@ DT_OUTSIDE
Definition DeviceState.h:50
@ DT_FALSE
Definition DeviceState.h:54
@ DT_GREATER_THAN_OR_EQUAL
Definition DeviceState.h:47
@ DT_NOT_INSIDE
Definition DeviceState.h:51
@ DT_EQUAL
Definition DeviceState.h:43
@ DT_GREATER_THAN
Definition DeviceState.h:46
Evaluator * myEval
Definition PEBL.cpp:188
#define PEBL_VERSION
PEBL_DEVICE_TYPE
Definition PDevice.h:40
@ PDT_MOUSE_WHEEL
Definition PDevice.h:47
@ PDT_MOVIE_END
Definition PDevice.h:58
@ PDT_TEXT_INPUT
Definition PDevice.h:43
@ PDT_MOUSE_MOVEMENT
Definition PDevice.h:45
@ PDT_DUMMY
Definition PDevice.h:60
@ PDT_JOYSTICK_BUTTON
Definition PDevice.h:54
@ PDT_MOUSE_BUTTON
Definition PDevice.h:46
@ PDT_KEYBOARD
Definition PDevice.h:42
@ PDT_WINDOW_RESIZE
Definition PDevice.h:59
@ PDT_TIMER
Definition PDevice.h:48
@ PDT_JOYSTICK_HAT
Definition PDevice.h:55
PlatformEnvironment * myEnv
Definition PEBL.cpp:189
PlatformEventQueue * gEventQueue
@ PEAT_JOYSTICK
Definition PError.h:59
@ PEAT_LIST
Definition PError.h:61
@ PEAT_TEXTBOX
Definition PError.h:67
@ PEAT_INTEGER
Definition PError.h:44
@ PEAT_STRING
Definition PError.h:46
@ PEAT_NUMBER
Definition PError.h:43
@ PEAT_MOVIE
Definition PError.h:71
@ PEBL_TIMEOUT
Definition PEvent.h:48
@ PEBL_RELEASED
Definition PEvent.h:46
@ PEBL_PRESSED
Definition PEvent.h:45
@ PEBL_WINDOWWIDTH
Definition PEvent.h:51
@ PEBL_MOVEMENT
Definition PEvent.h:47
@ PEBL_UNKNOWN
Definition PEvent.h:40
@ PEBL_TEXT_INPUT
Definition PEvent.h:53
PEBL_Keycode
Definition PKeyboard.h:78
@ PEBL_KEYCODE_UNKNOWN
Definition PKeyboard.h:79
@ PEBL_KEYCODE_ANYKEY
Definition PKeyboard.h:329
@ PEBL_KEYCODE_NOTHING
Definition PKeyboard.h:331
@ PEBLMOD_NONE
Definition PKeyboard.h:50
@ P_DATA_FUNCTION
Definition Variant.h:43
This class has got everything you need to evaluate stuff.
bool Evaluate(const PNode *node)
void NodeStackPush(const PNode *node)
bool Evaluate1()
void Push(Variant v)
static PEventLoop * mEventLoop
int GetNodeStackDepth()
bool IsVariableName(Variant v)
Variant Pop()
static FunctionMap mFunctionMap
Initiate some static member data.
void CallFunction(const OpNode *node)
int GetStackDepth()
int GetOp() const
Definition PNode.h:111
counted_ptr< PEBLObjectBase > GetObject() const
PList * GetList() const
bool IsList() const
PEvent Loop()
Initiates the looping tests.
void RegisterEvent(DeviceState *state, const std::string &function, Variant parameters)
void RegisterState(DeviceState *state, const std::string &function, Variant parameters)
virtual void Clear()
virtual void PushEvent(PEvent &evt)
PEBL_DEVICE_TYPE GetType() const
Definition PEvent.h:167
PEBL_TextInputEvent GetTextInputEvent() const
Definition PEvent.cpp:324
unsigned long int GetEventTime() const
Definition PEvent.h:183
PEBL_MouseButtonEvent GetMouseButtonEvent() const
Definition PEvent.cpp:357
PEBL_MouseWheelEvent GetMouseWheelEvent() const
Definition PEvent.cpp:372
PEBL_KeyboardEvent GetKeyboardEvent() const
Definition PEvent.cpp:294
PEBL_DummyEvent GetDummyEvent() const
Definition PEvent.cpp:414
int GetNumButtons()
Definition PJoystick.h:55
int GetNumHats()
Definition PJoystick.h:52
int GetNumBalls()
Definition PJoystick.h:53
int GetNumAxes()
Definition PJoystick.h:54
Definition PList.h:45
std::vector< Variant >::const_iterator End() const
Definition PList.cpp:132
std::vector< Variant >::const_iterator Begin() const
Definition PList.cpp:127
Variant Nth(unsigned int n)
Definition PList.cpp:181
unsigned long Length() const
Definition PList.h:89
void PushBack(const Variant &v)
Definition PList.cpp:149
Variant First()
Definition PList.cpp:169
Definition PNode.h:45
virtual void DestroyChildren()
Definition PNode.cpp:112
virtual std::string GetText() const
Definition PTextObject.h:56
virtual int SetCursorPosition(int x, int y)
virtual void SetKeyRepeat(bool onoff)
Variant GetScreenModes(int screen=-1)
virtual int ShowCursor(int val)
virtual Variant GetCursorPosition()
virtual signed int GetButtonState(unsigned int button)
virtual Variant GetBallState(unsigned int ball)
virtual signed int GetHatState(unsigned int hat)
virtual signed int GetAxisState(unsigned int axis)
virtual bool IsKeyUp(PEBL_Keycode key) const
virtual PEBL_Keycode IsKeyDown(PEBL_Keycode key) const
Primitive key event poller.
Validator platform textbox - no rendering, used only for compilation.
virtual int FindCursorPosition(long int x, long int y)
virtual void HandleKeyPress(int keycode, int modkeys, Uint16 unicode)
virtual void HandleTextInput(std::string input)
virtual void SetEditable(bool val)
virtual void GetTimeOfDay(unsigned long &secs, unsigned long &msecs)
virtual unsigned long int GetTime() const
bool IsComplexData() const
Definition Variant.cpp:984
pInt GetInteger() const
Definition Variant.cpp:997
void SetCreationTime(long unsigned int time)
Definition Variant.h:184
long unsigned int GetCreationTime() const
Definition Variant.h:185
bool IsString() const
Definition Variant.cpp:948
bool IsStackSignal() const
Definition Variant.cpp:989
bool IsFloat() const
Definition Variant.cpp:937
std::string GetString() const
Definition Variant.cpp:1056
bool IsInteger() const
Definition Variant.cpp:942
PComplexData * GetComplexData() const
Definition Variant.cpp:1299
bool IsNumber() const
This tests whether the Variant is a number (i.e., a float or an integer.)
Definition Variant.cpp:930
X * get() const
Definition rc_ptrs.h:110
The following initiates classes used by functions in the Environment library.
Definition Functions.h:295
Variant GetDrivers(Variant v)
Variant WaitForAnyKeyDown(Variant v)
Variant GetNumJoystickAxes(Variant v)
Variant GetNumJoystickButtons(Variant v)
Variant WaitForKeyRelease(Variant v)
Variant GetDirectoryListing(Variant v)
Variant RegisterEvent(Variant v)
Variant GetPEBLVersion(Variant v)
Variant IsFileStream(Variant v)
Variant Wait(Variant v)
PlatformKeyboard myKeyboard
Variant IsString(Variant v)
Variant MakeDirectory(Variant v)
Variant WaitForKeyDown(Variant v)
Variant IsInteger(Variant v)
Variant WaitForAllKeysUp(Variant v)
Variant StartEventLoop(Variant v)
Variant WaitForListKeyPressWithTimeout(Variant v)
Variant DeleteFile(Variant v)
Variant WaitForAnyKeyPressWithTimeout(Variant v)
Variant GetJoystickButtonState(Variant v)
Variant ShowCursor(Variant v)
Variant FileExists(Variant v)
Variant IsImage(Variant v)
Variant WaitForKeyListDown(Variant v)
Variant IsWidget(Variant v)
Variant IsNumber(Variant v)
Variant GetJoystickHatState(Variant v)
Variant CopyFromClipboard(Variant v)
Variant GetJoystick(Variant v)
Variant IsJoystick(Variant v)
Variant IsList(Variant v)
Variant SystemCallUpdate(Variant v)
Variant IsAudioOut(Variant v)
Variant WaitForKeyUp(Variant v)
Variant GetCursorPosition(Variant v)
Variant SystemCall(Variant v)
Variant IsFont(Variant v)
Variant IsShape(Variant v)
Variant ClearEventLoop(Variant v)
Variant SignalFatalError(Variant v)
Variant GetCurrentScreenResolution(Variant v)
Variant ExitQuietly(Variant v)
Variant GetNumJoystickHats(Variant v)
Variant TimeStamp(Variant v)
Variant WaitForAnyKeyDownWithTimeout(Variant v)
Variant LaunchFile(Variant v)
Variant GetMouseState(Variant v)
Variant TranslateKeyCode(Variant v)
Variant GetTime(Variant v)
This function moves a widget to a new location.
Variant GetTextBoxCursorFromClick(Variant v)
Variant WaitForMouseButtonWithTimeout(Variant v)
Variant IsDirectory(Variant v)
Variant GetWorkingDirectory(Variant v)
Variant CopyToClipboard(Variant v)
Variant WaitForKeyPress(Variant v)
Variant GetNumJoysticks(Variant v)
Variant GetTimeOfDay(Variant v)
Variant WaitForAnyKeyPress(Variant v)
Variant IsLabel(Variant v)
Variant CallFunction(Variant v)
Variant PlayMovie(Variant v)
Variant GetJoystickAxisState(Variant v)
Variant SetWorkingDirectory(Variant v)
PlatformTimer myTimer
Variant SetCursorPosition(Variant v)
This sets the mouse to a new position.
Variant IsFloat(Variant v)
Variant WaitForListKeyPress(Variant v)
Variant GetJoystickBallState(Variant v)
Variant GetVideoModes(Variant v)
Variant IsAnyKeyDown(Variant v)
Variant IsCustomObject(Variant v)
Variant IsColor(Variant v)
Variant IsCanvas(Variant v)
Variant CheckProcessStatus(Variant v)
Variant IsKeyDown(Variant v)
Variant IsWindow(Variant v)
Variant IsKeyUp(Variant v)
Variant VariableExists(Variant v)
Variant GetObjectTime(Variant v)
Variant GetExecutableName(Variant v)
Variant GetInput0(Variant v)
Variant IsPEBLObject(Variant v)
Variant TranslateString(Variant v)
Variant IsText(Variant v)
Variant GetTimeHP(Variant v)
Variant GetHomeDirectory(Variant v)
Variant WaitForMouseButton(Variant v)
Variant IsTextBox(Variant v)
Variant GetNumJoystickBalls(Variant v)
Variant GetSystemType(Variant v)
Variant SystemCall(std::string path, std::string args)
Variant LaunchFile(std::string file)
Variant GetHomeDirectory()
PEBL_Keycode TranslateString(const std::string &letters)
std::string TranslateKeycode(const PEBL_Keycode key, int modkeys)
std::string ToUpper(const std::string &text)
Variant SetWorkingDirectory(std::string path)
Variant DeleteMyFile(std::string path)
Variant FileExists(std::string path)
Variant GetDirectoryListing(std::string path)
Variant GetWorkingDirectory()
Variant MakeDirectory(std::string path)
std::string ToLower(const std::string &text)
Variant IsDirectory(std::string path)
void ExitQuietly(const std::string &message, int exitCode=0)
Definition PError.cpp:126
void SignalWarning(const std::string &message)
Definition PError.cpp:119
void AssertType(Variant v, int type, const std::string &outsidemessage)
void SignalFatalError(const std::string &message)
Variant GetDriverList(bool printout=true)
Variant CopyFromClipboard()
void CopyToClipboard(std::string text)
Variant GetCurrentScreenResolution()
long double GetTimeHP()
PEBL_Keycode key
Definition PEvent.h:66
unsigned int x
Definition PEvent.h:105
unsigned int y
Definition PEvent.h:105
long unsigned int x
Definition PEvent.h:115
long unsigned int y
Definition PEvent.h:115