-
Notifications
You must be signed in to change notification settings - Fork 1
/
XBMC-ES.usp
executable file
·864 lines (719 loc) · 32.9 KB
/
XBMC-ES.usp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
/*******************************************************************************************
SIMPL+ Module Information
(Fill in comments below)
*******************************************************************************************/
/*
Dealer Name:
System Name:
System Number:
Programmer: Neil Carthy (arduino@scpgwiki.com)
Comments:
In order for this module to work you must switch on EventServer:
Set "Allow Programs on this system to control XMBC" to ON, and
"Allow Programs on other systems to control XMBC" to ON.
In writing this module I drew heavily on the C# module written by
Peter Tribe aka EqUiNox (TeamBlackbolt).
***** License *****
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/////////////////////Compiler Directives
#SYMBOL_NAME "XBMC-ES"
#CATEGORY "41" // Remote System Interface
#HINT "Control XBMC using EventServer API"
#PRINT_TO_TRACE
#ENABLE_DYNAMIC
#DEFAULT_VOLATILE
#ENABLE_STACK_CHECKING
#ENABLE_TRACE
#OUTPUT_SHIFT 2 // Shift the outputs down 2 lines on the SIMPL window
/***** DEFINE NEW CONSTANTS *******/
//#DEFINE_CONSTANT DEBUG 1
#DEFINE_CONSTANT GATHER_TIMEOUT 15 // Timeout period to wait for response in 1/100th of second
#DEFINE_CONSTANT MAX_PACKET_SIZE 1024
#DEFINE_CONSTANT HEADER_SIZE 32
#DEFINE_CONSTANT MAX_PAYLOAD_SIZE 992 // Max payload in any one packet, equals (BUFFER_SIZE - HEADER_SIZE)
#DEFINE_CONSTANT MAJOR_VERSION 2
#DEFINE_CONSTANT MINOR_VERSION 0
#DEFINE_CONSTANT ICON_NONE 0
#DEFINE_CONSTANT ICON_JPEG 1 // Not Used
#DEFINE_CONSTANT ICON_PNG 2 // Not Used
#DEFINE_CONSTANT ICON_GIF 3 // Not Used
#DEFINE_CONSTANT BUTTON_USE_NAME 1
#DEFINE_CONSTANT BTN_DOWN 2
#DEFINE_CONSTANT BTN_UP 4
#DEFINE_CONSTANT BUTTON_USE_AMOUNT 8
#DEFINE_CONSTANT BUTTON_QUEUE 16
#DEFINE_CONSTANT BUTTON_NO_REPEAT 32
#DEFINE_CONSTANT BTN_VKEY 64
#DEFINE_CONSTANT BTN_AXIS 128
#DEFINE_CONSTANT MS_ABSOLUTE 1 // Mouse flags type
#DEFINE_CONSTANT LOGDEBUG 0
#DEFINE_CONSTANT LOGINFO 1
#DEFINE_CONSTANT LOGNOTICE 2
#DEFINE_CONSTANT LOGWARNING 3
#DEFINE_CONSTANT LOGERROR 4
#DEFINE_CONSTANT LOGSEVERE 5
#DEFINE_CONSTANT LOGFATAL 6
#DEFINE_CONSTANT LOGNONE 7
#DEFINE_CONSTANT ACTION_EXECBUILTIN 1
#DEFINE_CONSTANT ACTION_BUTTON 2
// Packet Type constants
#DEFINE_CONSTANT PT_HELO 1
#DEFINE_CONSTANT PT_BYE 2
#DEFINE_CONSTANT PT_BUTTON 3
#DEFINE_CONSTANT PT_MOUSE 4
#DEFINE_CONSTANT PT_PING 5
#DEFINE_CONSTANT PT_BROADCAST 6 //Currently not implemented
#DEFINE_CONSTANT PT_NOTIFICATION 7
#DEFINE_CONSTANT PT_BLOB 8
#DEFINE_CONSTANT PT_LOG 9
#DEFINE_CONSTANT PT_ACTION 10
#DEFINE_CONSTANT PT_DEBUG 255 //Currently not implemented
#DEFINE_CONSTANT BUTTON_UP 1
#DEFINE_CONSTANT BUTTON_DOWN 2
#DEFINE_CONSTANT BTN_LEFT 3
#DEFINE_CONSTANT BTN_RIGHT 4
#DEFINE_CONSTANT BTN_SELECT 5
#DEFINE_CONSTANT BTN_STOP 6
#DEFINE_CONSTANT BTN_PLAY 7
#DEFINE_CONSTANT BTN_PAUSE 8
#DEFINE_CONSTANT BTN_TITLE 9
#DEFINE_CONSTANT BTN_MENU 10
#DEFINE_CONSTANT BTN_INFO 11
#DEFINE_CONSTANT BTN_BACK 12
#DEFINE_CONSTANT BTN_DISPLAY 13
#DEFINE_CONSTANT BTN_POWER 14
#DEFINE_CONSTANT BTN_SKIPMINUS 15
#DEFINE_CONSTANT BTN_SKIPPLUS 16
#DEFINE_CONSTANT BTN_FORWARD 17
#DEFINE_CONSTANT BTN_MYVIDEO 18
#DEFINE_CONSTANT BTN_MYMUSIC 19
#DEFINE_CONSTANT BTN_MYPICS 20
#DEFINE_CONSTANT BTN_MYTV 21
#DEFINE_CONSTANT BTN_REVERSE 22
#DEFINE_CONSTANT BTN_ZERO 23
#DEFINE_CONSTANT BTN_ONE 24
#DEFINE_CONSTANT BTN_TWO 25
#DEFINE_CONSTANT BTN_THREE 26
#DEFINE_CONSTANT BTN_FOUR 27
#DEFINE_CONSTANT BTN_FIVE 28
#DEFINE_CONSTANT BTN_SIX 29
#DEFINE_CONSTANT BTN_SEVEN 30
#DEFINE_CONSTANT BTN_EIGHT 31
#DEFINE_CONSTANT BTN_NINE 32
#DEFINE_CONSTANT BTN_RECORD 33
#DEFINE_CONSTANT BTN_START 34
#DEFINE_CONSTANT BTN_VOLUMEPLUS 35
#DEFINE_CONSTANT BTN_VOLUMEMINUS 36
#DEFINE_CONSTANT BTN_CHANNELPLUS 37
#DEFINE_CONSTANT BTN_CHANNELMINUS 38
#DEFINE_CONSTANT BTN_PAGEPLUS 39
#DEFINE_CONSTANT BTN_MUTE 40
#DEFINE_CONSTANT BTN_RECORDED_TV 41
#DEFINE_CONSTANT BTN_GUIDE 42
#DEFINE_CONSTANT BTN_LIVE_TV 43
#DEFINE_CONSTANT BTN_STAR 44
#DEFINE_CONSTANT BTN_HASH 45
#DEFINE_CONSTANT BTN_CLEAR 46
#DEFINE_CONSTANT BTN_ENTER 47
#DEFINE_CONSTANT BTN_XBOX 48
#DEFINE_CONSTANT BTN_PAGEMINUS 49
#DEFINE_CONSTANT ACTN_REBOOT 101
#DEFINE_CONSTANT ACTN_SHUTDOWN 102
#DEFINE_CONSTANT ACTN_POWERDOWN 103
#DEFINE_CONSTANT ACTN_QUIT 104
#DEFINE_CONSTANT ACTN_HIBERNATE 105
#DEFINE_CONSTANT ACTN_SUSPEND 106
#DEFINE_CONSTANT ACTN_RESTARTAPP 107
#DEFINE_CONSTANT ACTN_MINIMIZE 108
#DEFINE_CONSTANT ACTN_CREDITS 109
#DEFINE_CONSTANT ACTN_MASTERMODE 110
#DEFINE_CONSTANT ACTN_TAKESCREENSHOT 111
#DEFINE_CONSTANT ACTN_RELOADSKIN 112
#DEFINE_CONSTANT ACTN_PLAYLISTCLEAR 113
#DEFINE_CONSTANT ACTN_EJECTTRAY 114
#DEFINE_CONSTANT ACTN_PLAYDVD 115
#DEFINE_CONSTANT ACTN_RIPCD 116
#DEFINE_CONSTANT ACTN_MUTE 117
#DEFINE_CONSTANT ACTN_SYSTEMLOGOFF 118
#DEFINE_CONSTANT ACTN_UPDATEVIDEODB 119
#DEFINE_CONSTANT ACTN_UPDATEMUSICDB 120
#DEFINE_CONSTANT ACTN_CLEANVIDEODB 121
#DEFINE_CONSTANT ACTN_CLEANMUSICDB 122
#DEFINE_CONSTANT ACTN_PAGEDOWN 123
#DEFINE_CONSTANT ACTN_PAGEUP 124
#DEFINE_CONSTANT ACTION_NEXT_LETTER 125
#DEFINE_CONSTANT ACTION_PREV_LETTER 126
#DEFINE_CONSTANT ACTION_JUMP_SMS2 127
#DEFINE_CONSTANT ACTION_JUMP_SMS3 128
#DEFINE_CONSTANT ACTION_JUMP_SMS4 129
#DEFINE_CONSTANT ACTION_JUMP_SMS5 130
#DEFINE_CONSTANT ACTION_JUMP_SMS6 131
#DEFINE_CONSTANT ACTION_JUMP_SMS7 132
#DEFINE_CONSTANT ACTION_JUMP_SMS8 133
#DEFINE_CONSTANT ACTION_JUMP_SMS9 134
#DEFINE_CONSTANT ACTION_SHOW_SUBTITLES 135
#DEFINE_CONSTANT ACTION_NEXT_SUBTITLE 136
#DEFINE_CONSTANT ACTION_SUBTITLE_DELAY_MIN 137
#DEFINE_CONSTANT ACTION_SUBTITLE_DELAY 138
#DEFINE_CONSTANT ACTION_SUBTITLE_DELAY_PLUS 139
#DEFINE_CONSTANT ACTION_SHOW_GUI 140
#DEFINE_CONSTANT ACTION_TOGGLE_FULLSCREEN 141
#DEFINE_CONSTANT ACTION_FILTER_CLEAR 142
#DEFINE_CONSTANT ACTION_FILTER_SMS2 143
#DEFINE_CONSTANT ACTION_FILTER_SMS3 144
#DEFINE_CONSTANT ACTION_FILTER_SMS4 145
#DEFINE_CONSTANT ACTION_FILTER_SMS5 146
#DEFINE_CONSTANT ACTION_FILTER_SMS6 147
#DEFINE_CONSTANT ACTION_FILTER_SMS7 148
#DEFINE_CONSTANT ACTION_FILTER_SMS8 149
#DEFINE_CONSTANT ACTION_FILTER_SMS9 150
#DEFINE_CONSTANT ACTION_FIRST_PAGE 151
#DEFINE_CONSTANT ACTION_LAST_PAGE 152
#DEFINE_CONSTANT ACTION_AUDIO_DELAY_MIN 153
#DEFINE_CONSTANT ACTION_AUDIO_DELAY 154
#DEFINE_CONSTANT ACTION_AUDIO_DELAY_PLUS 155
#DEFINE_CONSTANT ACTION_AUDIO_NEXT_LANGUAGE 156
#DEFINE_CONSTANT ACTION_TOGGLE_WATCHED 157
#DEFINE_CONSTANT ACTION_SHOW_CODEC 158
#DEFINE_CONSTANT ACTION_TAKE_SCREENSHOT 159
#DEFINE_CONSTANT ACTION_CONTEXT_MENU 160
#DEFINE_CONSTANT ACTION_SHOW_OSD 161
#DEFINE_CONSTANT ACTION_SHOW_ASPECT_RATIO 162
/*******************************************************************************************
DIGITAL, ANALOG and SERIAL INPUTS and OUTPUTS
(Uncomment and declare inputs and outputs as needed)
*******************************************************************************************/
DIGITAL_INPUT _SKIP_, _SKIP_, Connect,_SKIP_;
DIGITAL_INPUT Up, Down, Lt, Rt, _SKIP_;
// builin functions that require feedback
DIGITAL_INPUT Repeat, Shuffle, _SKIP_;
ANALOG_INPUT Command;
ANALOG_INPUT WindowName#; // Activate this window (Delta Window ID) See http://wiki.xbmc.org/index.php?title=Window_IDs
STRING_INPUT WindowName$[100];
BUFFER_INPUT _SKIP_,LogMessage$[500];
BUFFER_INPUT Notification$[500];
STRING_OUTPUT RepeatStatus$, // 'Repeat', 'RepeatOne' or 'RepeatAll' or ''
ShuffleStatus$; // 'Shuffle' or ''
///////////////////////////// Parameters
INTEGER_PARAMETER EventServer_Port#; //the port that the XBMC sends broadcast packets from
STRING_PARAMETER XBMC_IPAddr$[16]; //the ip of the XBMC server.
#BEGIN_PARAMETER_PROPERTIES XBMC_IPAddr$
propDefaultValue = "";
propShortDescription = "The IP Address of the XBMC HTTP server.";
#END_PARAMETER_PROPERTIES
#BEGIN_PARAMETER_PROPERTIES EventServer_Port#
propValidUnits = unitDecimal;
propDefaultValue = 9777d;
propShortDescription = "The port that the XBMC listens on for EventServer packets.";
#END_PARAMETER_PROPERTIES
/////////////////////////// Global variables
NONVOLATILE INTEGER RepeatCounter, ShuffleCounter; //Used to track repeat and shuffle status
/////////////////////////// Sockets
UDP_SOCKET EventServerUdp[MAX_PACKET_SIZE]; // EventServer UDP socket
/*******************************************************************************************
Global Variables
(Uncomment and declare global variables as needed)
Note: Be sure to initialize all declared STRING variables as needed
For example, in Function Main: myString = "";
*******************************************************************************************/
INTEGER UniqueToken; // Used by xbmc to identify each client, set to a random number
STRING Header$[HEADER_SIZE]; // The header that comes before the Payload of each packet
STRING Payload$[MAX_PACKET_SIZE]; // The payload buffer that is transferred to XBMC
INTEGER PayloadLength; // The actual length of the payload. (Payload$ is padded with zeros)
/*******************************************************************************************
Functions
Note: Functions must be physically placed before the location in
the code that calls them.
*******************************************************************************************/
// Insert Header details into Header$
FUNCTION GenerateHeader(INTEGER PacketType)
{
STRING HeaderStart$[6];
MAKESTRING (HeaderStart$, "XBMC%s%s", Chr(MAJOR_VERSION), Chr(MINOR_VERSION));
MAKESTRING ( Header$, "%s%s%s%s%s%s%s%s%s%s%s"
,HeaderStart$
,Chr(High(PacketType))
,Chr(Low(PacketType))
,"\x00\x00\x00\x01\x00\x00\x00\x01" // Only works for a single packet
,Chr(High(PayloadLength))
,Chr(Low(PayloadLength))
,Chr(High(HighWord(UniqueToken)))
,Chr(Low(HighWord(UniqueToken)))
,Chr(High(LowWord(UniqueToken)))
,Chr(Low(LowWord(UniqueToken)))
,"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" //Padding
);
}
FUNCTION Send(INTEGER PacketType)
{
STRING Packet$[MAX_PACKET_SIZE];
SIGNED_INTEGER Return_Value;
CALL GenerateHeader(PacketType);
IF (PayloadLength = 0)
MAKESTRING(Packet$, "%s", Header$);
ELSE
MAKESTRING(Packet$, "%s%s", Header$, LEFT(Payload$, PayloadLength));
Return_Value = SOCKETSEND(EventServerUdp, Packet$);
IF (Return_Value < 0)
{
IF (Connect = 0)
PRINT ("Not connected to Xbmc at %s. Socket Error number is %d", XBMC_IPAddr$, Return_Value);
ELSE
{
PRINT ("Error in XBMC-ES. Connect: %d", Connect);
GenerateUserError("Xbmc Eventserver error. IP Address: %s, ErrorNum: %d.", XBMC_IPAddr$, Return_Value);
}
}
}
/************************************************************************/
/* SendHelo - */
/* Payload format: */
/* %s - device name (max 128 chars) */
/* %c - icontype ( 0=>NOICON, 1=>JPEG , 2=>PNG , 3=>GIF ) */
/* %s - my port ( 0=>not listening ) */
/* %d - reserved1 ( 0 ) */
/* %d - reserved2 ( 0 ) */
/* XX - imagedata ( can span multiple packets ) */
/************************************************************************/
FUNCTION SendHelo(STRING DeviceName$)
{
PayloadLength = LEN(DeviceName$) + 12;
MAKESTRING(Payload$, "%s\x00%s\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
,DeviceName$
,Chr(ICON_NONE) //Not using Icons in this version of XBMC-ES
);
CALL Send(PT_HELO);
}
/************************************************************************/
/* SendBye - No payload */
/* A BYE packet terminates the connection to XBMC. */
/************************************************************************/
FUNCTION SendBye()
{
PayloadLength = 0;
CALL Send(PT_BYE);
}
/************************************************************************/
/* SendPing - No payload */
/* A PING packet tells XBMC that the client is still alive. All valid */
/* packets act as ping (not just this one). A client needs to ping */
/* XBMC at least once in 60 seconds or it will time out. */
/************************************************************************/
FUNCTION SendPing()
{
PayloadLength = 0;
CALL Send(PT_PING);
}
/************************************************************************/
/* SendLog - Payload format */
/* %c - log type */
/* %s - message */
/************************************************************************/
FUNCTION SendLog(INTEGER LogLevel, string Message$)
{
PayloadLength = LEN(Message$) + 2;
MAKESTRING(Payload$, "%s%s\x00"
,Chr(LogLevel)
,Message$
);
CALL Send(PT_LOG);
}
/************************************************************************/
/* SendNotification - Payload format */
/* %s - caption */
/* %s - message */
/* %c - icontype ( 0=>NOICON, 1=>JPEG , 2=>PNG , 3=>GIF ) */
/* %d - reserved ( 0 ) */
/* XX - imagedata ( can span multiple packets ) */
/************************************************************************/
FUNCTION SendNotification(string Caption$, string Message$)
{
PayloadLength = LEN(Caption$) + LEN(Message$) + 7;
MAKESTRING(Payload$, "%s\x00%s\x00%s\x00\x00\x00\x00"
,Caption$
,Message$
,Chr(ICON_NONE) //Not using Icons in this version of XBMC-ES
);
CALL Send(PT_NOTIFICATION);
}
/************************************************************************/
/* SendButton - Payload format */
/* %i - button code */
/* %i - flags 0x01 => use button map/name instead of code */
/* 0x02 => btn down */
/* 0x04 => btn up */
/* 0x08 => use amount */
/* 0x10 => queue event */
/* 0x20 => do not repeat */
/* 0x40 => virtual key */
/* 0x80 => axis key */
/* %i - amount ( 0 => 65k maps to -1 => 1 ) */
/* %s - device map (case sensitive and required if flags & 0x01) */
/* "KB" - Standard keyboard map */
/* "XG" - Xbox Gamepad */
/* "R1" - Xbox Remote */
/* "R2" - Xbox Universal Remote */
/* "LI:devicename" - valid LIRC device map where 'devicename' */
/* is the actual name of the LIRC device */
/* "JS<num>:joyname" - valid Joystick device map where */
/* 'joyname' is the name specified in */
/* the keymap. JS only supports button code */
/* and not button name currently (!0x01). */
/* %s - button name (required if flags & 0x01) */
/************************************************************************/
FUNCTION SendButton(string Button$, INTEGER ButtonCode, string DeviceMap$, INTEGER Flags, INTEGER Amount)
{
PayloadLength = LEN(Button$) + LEN(DeviceMap$) + 8;
IF (LEN(Button$) > 0)
{
IF ((Flags & BUTTON_USE_NAME) = 0)
Flags = Flags | BUTTON_USE_NAME;
ButtonCode = 0;
}
IF (Amount > 0)
{
IF ((Flags & BUTTON_USE_AMOUNT) = 0)
Flags = Flags | BUTTON_USE_AMOUNT;
}
IF (!(Flags & BTN_DOWN || Flags & BTN_UP ))
Flags = Flags | BTN_DOWN;
MAKESTRING(Payload$, "%s%s%s%s%s%s%s\x00%s\x00"
,Chr(High(ButtonCode))
,Chr(Low(ButtonCode))
,Chr(High(Flags))
,Chr(Low(Flags))
,Chr(High(Amount))
,Chr(Low(Amount))
,DeviceMap$
,Button$
);
CALL Send(PT_BUTTON);
}
/************************************************************************/
/* SendMouse - Payload format */
/* %c - flags */
/* - 0x01 absolute position */
/* %i - mousex (0-65535 => maps to screen width) */
/* %i - mousey (0-65535 => maps to screen height) */
/************************************************************************/
FUNCTION SendMouse(INTEGER X, INTEGER Y)
{
PayloadLength = 9;
MAKESTRING(Payload$, "%s%s%s%s%s\x00\x00\x00\x00"
,Chr(MS_ABSOLUTE)
,Chr(High(X))
,Chr(Low(X))
,Chr(High(Y))
,Chr(Low(Y))
);
CALL Send(PT_MOUSE);
}
/************************************************************************/
/* SendAction - Payload format */
/* %c - action type */
/* %s - action message */
/************************************************************************/
FUNCTION SendAction(INTEGER Action, string Message$)
{
PayloadLength = LEN(Message$) + 2;
MAKESTRING(Payload$, "%s%s\x00"
,Chr(Action)
,Message$
);
CALL Send(PT_ACTION);
}
/*
Raise Button-Down and Button-Up events
*/
FUNCTION ProcessButton(STRING button_name)
{
CALL SendButton(button_name,0,"R1",BTN_DOWN | BUTTON_NO_REPEAT, 0);
Delay(5);
CALL SendButton(button_name,0,"R1",BTN_UP | BUTTON_NO_REPEAT, 0);
}
/*******************************************************************************************
Event Handlers
(Uncomment and declare additional event handlers as needed)
*******************************************************************************************/
PUSH Connect
{
INTEGER LocalStatus;
LocalStatus = SocketUDP_Enable(EventServerUdp, XBMC_IPAddr$, EventServer_Port#);
IF (LocalStatus != 0)
{
#IF_DEFINED DEBUG PRINT("UDP Error: %s:%d", XBMC_IPAddr$, EventServer_Port#); #ENDIF
GenerateUserError( "(%s) %s", GetSymbolInstanceName( ), "Unable to enable EventServer Udp socket." );
}
CALL SendHelo("Crestron System");
WHILE (Connect)
{
// 30-sec wait
DELAY(3000);
// Ensure the release event is captured
PROCESSLOGIC();
// Check again just in case
IF (Connect)
CALL SendPing();
}
}
RELEASE Connect
{
INTEGER LocalStatus;
CALL SendLog(LOGNOTICE, "ES: Crestron System closed connection.");
Delay(50);
CALL SendBye();
LocalStatus = SocketUDP_Disable(EventServerUdp);
IF (LocalStatus != 0)
{
GenerateUserError( "(%s) %s", GetSymbolInstanceName( ), "Unable to DISable EventServer Udp socket." );
}
}
/* Up/Down/Left/Right are special cases... repeat is allowed */
PUSH Up
{
// Keyboard Button names are CButtonTranslator::TranslateKeyboardString
// in XBMC source code
CALL SendButton("up",0,"R1",BTN_DOWN, 0);
}
PUSH Down
{
CALL SendButton("down",0,"R1",BTN_DOWN, 0);
}
PUSH Lt
{
CALL SendButton("left",0,"R1",BTN_DOWN, 0);
}
PUSH Rt
{
CALL SendButton("right",0,"R1",BTN_DOWN, 0);
}
RELEASE Up
{
CALL SendButton("up",0,"R1",BTN_UP, 0);
}
RELEASE Down
{
CALL SendButton("down",0,"R1",BTN_UP, 0);
}
RELEASE Lt
{
CALL SendButton("left",0,"R1",BTN_UP, 0);
}
RELEASE Rt
{
CALL SendButton("right",0,"R1",BTN_UP, 0);
}
CHANGE Command
{
Switch (Command)
{
Case (BUTTON_UP) : { ProcessButton("up"); }
Case (BUTTON_DOWN) : { ProcessButton("down"); }
Case (BTN_LEFT) : { ProcessButton("left"); }
Case (BTN_RIGHT) : { ProcessButton("right"); }
Case (BTN_SELECT) : { ProcessButton("select");}
Case (BTN_STOP) : { ProcessButton("stop"); }
Case (BTN_PLAY) : { ProcessButton("play"); }
Case (BTN_PAUSE) : { ProcessButton("pause"); }
Case (BTN_RECORD) : { ProcessButton("record"); }
Case (BTN_START) : { ProcessButton("start"); }
Case (BTN_TITLE) : { ProcessButton("title"); }
Case (BTN_MENU) : { ProcessButton("menu"); }
Case (BTN_INFO) : { ProcessButton("info"); }
Case (BTN_BACK) : { ProcessButton("back"); }
Case (BTN_DISPLAY) : { ProcessButton("display");}
Case (BTN_POWER) : { ProcessButton("power"); }
Case (BTN_SKIPMINUS) : { ProcessButton("skipminus");}
Case (BTN_SKIPPLUS) : { ProcessButton("skipplus");}
Case (BTN_FORWARD) : { ProcessButton("forward");}
Case (BTN_REVERSE) : { ProcessButton("reverse");}
Case (BTN_MYVIDEO) : { ProcessButton("myvideo");}
Case (BTN_MYMUSIC) : { ProcessButton("mymusic");}
Case (BTN_MYPICS) : { ProcessButton("mypictures");}
Case (BTN_MYTV) : { ProcessButton("mytv");}
Case (BTN_ZERO) : { ProcessButton("zero"); }
Case (BTN_ONE) : { ProcessButton("one"); }
Case (BTN_TWO) : { ProcessButton("two");}
Case (BTN_THREE) : { ProcessButton("three");}
Case (BTN_FOUR) : { ProcessButton("four");}
Case (BTN_FIVE) : { ProcessButton("five");}
Case (BTN_SIX) : { ProcessButton("six");}
Case (BTN_SEVEN) : { ProcessButton("seven");}
Case (BTN_EIGHT) : { ProcessButton("eight");}
Case (BTN_NINE) : { ProcessButton("nine");}
Case (BTN_VOLUMEPLUS) : { ProcessButton("volumeplus");}
Case (BTN_VOLUMEMINUS) : { ProcessButton("volumeminus");}
Case (BTN_MUTE) : { ProcessButton("mute");}
Case (BTN_CHANNELPLUS) : { ProcessButton("channelplus");}
Case (BTN_CHANNELMINUS) : { ProcessButton("channelminus");}
Case (BTN_PAGEPLUS) : { ProcessButton("pageplus");}
Case (BTN_PAGEMINUS) : { ProcessButton("pageminus");}
Case (BTN_RECORDED_TV) : { ProcessButton("recordedtv");}
Case (BTN_GUIDE) : { ProcessButton("guide"); }
Case (BTN_LIVE_TV) : { ProcessButton("livetv");}
Case (BTN_STAR) : { ProcessButton("star"); }
Case (BTN_HASH) : { ProcessButton("hash"); }
Case (BTN_CLEAR) : { ProcessButton("clear"); }
Case (BTN_ENTER) : { ProcessButton("enter"); }
Case (BTN_XBOX) : { ProcessButton("xbox"); }
Case (ACTN_REBOOT) : { SendAction(ACTION_EXECBUILTIN, "Reboot" ); }
Case (ACTN_SHUTDOWN) : { SendAction(ACTION_EXECBUILTIN, "ShutDown" ); }
Case (ACTN_POWERDOWN) : { SendAction(ACTION_EXECBUILTIN, "Powerdown"); }
Case (ACTN_QUIT) : { SendAction(ACTION_EXECBUILTIN, "Quit"); }
Case (ACTN_HIBERNATE) : { SendAction(ACTION_EXECBUILTIN, "Hibernate"); }
Case (ACTN_SUSPEND) : { SendAction(ACTION_EXECBUILTIN, "Suspend"); }
Case (ACTN_RESTARTAPP) : { SendAction(ACTION_EXECBUILTIN, "RestartApp"); }
Case (ACTN_SYSTEMLOGOFF) : { SendAction(ACTION_EXECBUILTIN, "System.LogOff"); }
Case (ACTN_CREDITS) : { SendAction(ACTION_EXECBUILTIN, "Credits"); }
Case (ACTN_MASTERMODE) : { SendAction(ACTION_EXECBUILTIN, "Mastermode"); }
Case (ACTN_TAKESCREENSHOT) : { SendAction(ACTION_EXECBUILTIN, "TakeScreenshot"); }
Case (ACTN_RELOADSKIN) : { SendAction(ACTION_EXECBUILTIN, "ReloadSkin()"); }
Case (ACTN_MUTE) : { SendAction(ACTION_EXECBUILTIN, "Mute"); }
Case (ACTN_PLAYLISTCLEAR) : { SendAction(ACTION_EXECBUILTIN, "Playlist.Clear"); }
Case (ACTN_EJECTTRAY) : { SendAction(ACTION_EXECBUILTIN, "EjectTray()"); }
Case (ACTN_PLAYDVD) : { SendAction(ACTION_EXECBUILTIN, "PlayDVD"); }
Case (ACTN_RIPCD) : { SendAction(ACTION_EXECBUILTIN, "RipCD"); }
Case (ACTN_UPDATEVIDEODB) : { SendAction(ACTION_EXECBUILTIN, "UpdateLibrary(video)"); }
Case (ACTN_UPDATEMUSICDB) : { SendAction(ACTION_EXECBUILTIN, "UpdateLibrary(music)"); }
Case (ACTN_CLEANVIDEODB) : { SendAction(ACTION_EXECBUILTIN, "CleanLibrary(video)"); }
Case (ACTN_CLEANMUSICDB) : { SendAction(ACTION_EXECBUILTIN, "CleanLibrary(music)"); }
Case (ACTN_PAGEDOWN) : { SendAction(ACTION_EXECBUILTIN, "PageDown"); }
Case (ACTN_PAGEUP) : { SendAction(ACTION_EXECBUILTIN, "PageUp"); }
Case (ACTION_FIRST_PAGE) : { SendAction(ACTION_BUTTON, "firstpage"); }
Case (ACTION_LAST_PAGE) : { SendAction(ACTION_BUTTON, "lastpage"); }
Case (ACTION_SHOW_GUI) : { SendAction(ACTION_BUTTON, "fullscreen"); }
Case (ACTION_TOGGLE_FULLSCREEN) : { SendAction(ACTION_BUTTON, "togglefullscreen"); }
Case (ACTN_MINIMIZE) : { SendAction(ACTION_EXECBUILTIN, "Minimize"); }
Case (ACTION_NEXT_LETTER) : { SendAction(ACTION_BUTTON, "nextletter"); }
Case (ACTION_PREV_LETTER) : { SendAction(ACTION_BUTTON, "prevletter"); }
Case (ACTION_JUMP_SMS2) : { SendAction(ACTION_BUTTON, "jumpsms2"); }
Case (ACTION_JUMP_SMS3) : { SendAction(ACTION_BUTTON, "jumpsms3"); }
Case (ACTION_JUMP_SMS4) : { SendAction(ACTION_BUTTON, "jumpsms4"); }
Case (ACTION_JUMP_SMS5) : { SendAction(ACTION_BUTTON, "jumpsms5"); }
Case (ACTION_JUMP_SMS6) : { SendAction(ACTION_BUTTON, "jumpsms6"); }
Case (ACTION_JUMP_SMS7) : { SendAction(ACTION_BUTTON, "jumpsms7"); }
Case (ACTION_JUMP_SMS8) : { SendAction(ACTION_BUTTON, "jumpsms8"); }
Case (ACTION_JUMP_SMS9) : { SendAction(ACTION_BUTTON, "jumpsms9"); }
Case (ACTION_FILTER_CLEAR) : { SendAction(ACTION_BUTTON, "filterclear"); }
Case (ACTION_FILTER_SMS2) : { SendAction(ACTION_BUTTON, "filtersms2"); }
Case (ACTION_FILTER_SMS3) : { SendAction(ACTION_BUTTON, "filtersms3"); }
Case (ACTION_FILTER_SMS4) : { SendAction(ACTION_BUTTON, "filtersms4"); }
Case (ACTION_FILTER_SMS5) : { SendAction(ACTION_BUTTON, "filtersms5"); }
Case (ACTION_FILTER_SMS6) : { SendAction(ACTION_BUTTON, "filtersms6"); }
Case (ACTION_FILTER_SMS7) : { SendAction(ACTION_BUTTON, "filtersms7"); }
Case (ACTION_FILTER_SMS8) : { SendAction(ACTION_BUTTON, "filtersms8"); }
Case (ACTION_FILTER_SMS9) : { SendAction(ACTION_BUTTON, "filtersms9"); }
Case (ACTION_SHOW_SUBTITLES) : { SendAction(ACTION_BUTTON, "showsubtitles"); }
Case (ACTION_NEXT_SUBTITLE) : { SendAction(ACTION_BUTTON, "nextsubtitle"); }
Case (ACTION_SUBTITLE_DELAY_MIN) : { SendAction(ACTION_BUTTON, "subtitledelayminus"); }
Case (ACTION_SUBTITLE_DELAY) : { SendAction(ACTION_BUTTON, "subtitledelay"); }
Case (ACTION_SUBTITLE_DELAY_PLUS) : { SendAction(ACTION_BUTTON, "subtitledelayplus"); }
Case (ACTION_AUDIO_DELAY_MIN) : { SendAction(ACTION_BUTTON, "audiodelayminus"); }
Case (ACTION_AUDIO_DELAY) : { SendAction(ACTION_BUTTON, "audiodelay"); }
Case (ACTION_AUDIO_DELAY_PLUS) : { SendAction(ACTION_BUTTON, "audiodelayplus"); }
Case (ACTION_AUDIO_NEXT_LANGUAGE) : { SendAction(ACTION_BUTTON, "audionextlanguage"); }
Case (ACTION_TOGGLE_WATCHED) : { SendAction(ACTION_BUTTON, "togglewatched"); }
Case (ACTION_SHOW_CODEC) : { SendAction(ACTION_BUTTON, "codecinfo"); }
Case (ACTION_CONTEXT_MENU) : { SendAction(ACTION_BUTTON, "contextmenu"); }
Case (ACTION_SHOW_OSD) : { SendAction(ACTION_BUTTON, "osd"); }
Case (ACTION_SHOW_ASPECT_RATIO) : { SendAction(ACTION_BUTTON, "aspectratio"); }
}
}
push Repeat
{
IF ( RepeatCounter MOD 4 = 1)
{
CALL SendAction(ACTION_EXECBUILTIN, "PlayerControl(Repeat)");
RepeatStatus$ = "Repeat On";
}
ELSE IF ( RepeatCounter MOD 4 = 2)
{
CALL SendAction(ACTION_EXECBUILTIN, "PlayerControl(RepeatOne)");
RepeatStatus$ = "Repeat One";
}
ELSE IF ( RepeatCounter MOD 4 = 3)
{
CALL SendAction(ACTION_EXECBUILTIN, "PlayerControl(RepeatAll)");
RepeatStatus$ = "Repeat All";
}
ELSE {
CALL SendAction(ACTION_EXECBUILTIN, "PlayerControl(RepeatOff)");
RepeatStatus$ = "";
}
RepeatCounter = (RepeatCounter + 1) MOD 4;
}
push Shuffle
{
IF ( ShuffleCounter MOD 2)
{
// OFF
CALL SendAction(ACTION_EXECBUILTIN, "PlayerControl(RandomOff)");
ShuffleStatus$ = "";
}
ELSE
{
// ON
CALL SendAction(ACTION_EXECBUILTIN, "PlayerControl(RandomOn)");
ShuffleStatus$ = "Shuffle";
}
ShuffleCounter = (ShuffleCounter + 1) MOD 2;
}
CHANGE LogMessage$
{
String responseLine$[ 500 ];
responseLine$ = Gather( "\n", LogMessage$, GATHER_TIMEOUT );
IF (LEN(responseLine$) = 0)
MAKESTRING(responseLine$, "%s", LogMessage$);
CLEARBUFFER(LogMessage$);
CALL SendLog(LOGNOTICE, responseLine$);
}
CHANGE Notification$
{
String responseLine$[ 500 ];
responseLine$ = Gather( "\n", Notification$, GATHER_TIMEOUT );
IF (LEN(responseLine$) = 0)
MAKESTRING(responseLine$, "%s", Notification$);
CLEARBUFFER(Notification$);
CALL SendNotification("Crestron System says:", responseLine$);
}
CHANGE WindowName#
{
// ActivateWindow parameters: http://wiki.xbmc.org/index.php?title=Opening_Windows_and_Dialogs
// and http://wiki.xbmc.org/index.php?title=Window_IDs
String Command$[ 100 ];
MAKESTRING(Command$, "ActivateWindow(%d)", WindowName#);
SendAction(ACTION_EXECBUILTIN, Command$);
}
CHANGE WindowName$
{
// ActivateWindow parameters: http://wiki.xbmc.org/index.php?title=Opening_Windows_and_Dialogs
// and http://wiki.xbmc.org/index.php?title=Window_IDs
String Command$[ 100 ];
MAKESTRING(Command$, "ActivateWindow(%s)", WindowName$);
SendAction(ACTION_EXECBUILTIN, Command$);
}
/*******************************************************************************************
Main()
Uncomment and place one-time startup code here
(This code will get called when the system starts up)
*******************************************************************************************/
Function Main()
{
WaitForInitializationComplete();
// If you are reading any Input or Output variables, uncomment
// the WaitForInitializationComplete statement above and read
// them afterwards. Input/Output variables will not have
// their correct values set until after the logic processor
// runs and propagates the values to them.
UniqueToken = GetTicks();
}