1 /*
2  * This file is part of libbluray
3  * Copyright (C) 2010      William Hahne
4  * Copyright (C) 2012-2019 Petri Hintukainen <phintuka@users.sourceforge.net>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library. If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
21 package org.videolan;
22 
23 import java.awt.BDFontMetrics;
24 import java.awt.BDToolkit;
25 import java.awt.event.KeyEvent;
26 import java.awt.event.MouseEvent;
27 import java.io.File;
28 import java.util.HashMap;
29 import java.util.Map;
30 import java.util.Vector;
31 
32 import javax.media.PackageManager;
33 import javax.tv.service.SIManager;
34 import javax.tv.service.SIManagerImpl;
35 import javax.tv.service.selection.ServiceContextFactory;
36 import javax.tv.service.selection.ServiceContextFactoryImpl;
37 import org.bluray.bdplus.Status;
38 import org.bluray.net.BDLocator;
39 import org.bluray.system.RegisterAccess;
40 import org.bluray.ti.DiscManager;
41 import org.bluray.ti.Title;
42 import org.bluray.ti.selection.TitleContext;
43 import org.bluray.ui.event.HRcEvent;
44 import org.dvb.event.EventManager;
45 import org.dvb.io.ixc.IxcRegistry;
46 import org.dvb.ui.FontFactory;
47 import org.videolan.bdjo.Bdjo;
48 import org.videolan.media.content.PlayerManager;
49 
50 /**
51  * This class allows BDJ to call various libbluray functions.
52  */
53 public class Libbluray {
54 
55     /* hook system properties: make "user.dir" point to current Xlet home directory */
56 
57     private static boolean booted;
58 
hookProperties()59     private static void hookProperties() {
60         java.util.Properties p = new java.util.Properties(System.getProperties()) {
61                 public String getProperty(String key) {
62                     if (key.equals("user.dir")) {
63                         BDJXletContext ctx = BDJXletContext.getCurrentContext();
64                         if (ctx != null) {
65                             return ctx.getXletHome();
66                         }
67                         if (booted) {
68                             System.err.println("getProperty(user.dir): no context !  " + Logger.dumpStack());
69                         }
70                     }
71                     return super.getProperty(key);
72                 }
73                 private static final long serialVersionUID = -6253354431747524430L;
74             };
75         System.setProperties(p);
76     }
77 
78     /*
79      * Loader hooks
80      */
81 
82     private static BDJClassLoaderAdapter classLoaderAdapter = null;
83     private static BDJLoaderAdapter      loaderAdapter = null;
84 
getClassLoaderAdapter()85     protected static BDJClassLoaderAdapter getClassLoaderAdapter() {
86         return classLoaderAdapter;
87     }
getLoaderAdapter()88     protected static BDJLoaderAdapter getLoaderAdapter() {
89         return loaderAdapter;
90     }
91 
loadAdapter(String pkg)92     private static void loadAdapter(String pkg) {
93         if (pkg == null)
94             return;
95         if (pkg.indexOf(';') > 0) {
96             pkg = pkg.substring(0, pkg.indexOf(';'));
97         }
98         try {
99             final Object obj = Class.forName("org.videolan." + pkg + ".Adapter").newInstance();
100             if (!((obj instanceof BDJClassLoaderAdapter) ||
101                   (obj instanceof BDJLoaderAdapter))) {
102                 System.err.println("Unsupported interface in " + obj);
103                 return;
104             }
105             if (obj instanceof BDJLoaderAdapter) {
106                 loaderAdapter = (BDJLoaderAdapter)obj;
107             }
108             if (obj instanceof BDJClassLoaderAdapter) {
109                 classLoaderAdapter = (BDJClassLoaderAdapter)obj;
110             }
111         } catch (ClassNotFoundException ce) {
112             System.out.println("" + ce);  /* not really an error */
113         } catch (Exception e) {
114             System.err.println("" + e);
115         }
116     }
117 
118     /*
119      *
120      */
121 
122     private static boolean initOnce = false;
initOnce()123     private static void initOnce() {
124         if (initOnce) {
125             return;
126         }
127         initOnce = true;
128 
129         /* hook system properties (provide Xlet-specific user.dir) */
130         try {
131             hookProperties();
132         } catch (Throwable t) {
133             System.err.println("hookProperties() failed: " + t);
134         }
135 
136         /* hook sockets (limit network connections) */
137         try {
138             BDJSocketFactory.init();
139         } catch (Throwable t) {
140             System.err.println("Hooking socket factory failed: " + t + "\n" + Logger.dumpStack(t));
141         }
142 
143         /* enable filesystem hooks */
144         java.io.BDFileSystem.setBooted();
145     }
146 
canonicalize(String path, boolean create)147     private static String canonicalize(String path, boolean create) {
148         try {
149             File dir = new File(path);
150             if (create && !dir.isDirectory() && !dir.mkdirs()) {
151                 System.err.println("error creating directory " + path);
152             }
153             return dir.getCanonicalPath();
154         } catch (Exception ioe) {
155             System.err.println("error canonicalizing " + path + ": " + ioe);
156         }
157         return path;
158     }
159 
removeProperty(String property)160     private static void removeProperty(String property) {
161         try {
162             System.getProperties().remove(property);
163         } catch (Exception e) {
164             System.err.println(""+ e);
165         }
166     }
167 
resetProfile()168     private static void resetProfile() {
169         removeProperty("bluray.profile.1");
170         removeProperty("bluray.p1.version.major");
171         removeProperty("bluray.p1.version.minor");
172         removeProperty("bluray.p1.version.micro");
173         removeProperty("bluray.profile.2");
174         removeProperty("bluray.p2.version.major");
175         removeProperty("bluray.p2.version.minor");
176         removeProperty("bluray.p2.version.micro");
177         removeProperty("bluray.profile.5");
178         removeProperty("bluray.p5.version.major");
179         removeProperty("bluray.p5.version.minor");
180         removeProperty("bluray.p5.version.micro");
181         removeProperty("bluray.profile.6");
182         removeProperty("bluray.p6.version.major");
183         removeProperty("bluray.p6.version.minor");
184         removeProperty("bluray.p6.version.micro");
185     }
186 
187     /* called only from native code */
init(long nativePointer, String discID, String discRoot, String persistentRoot, String budaRoot)188     private static void init(long nativePointer, String discID, String discRoot,
189                                String persistentRoot, String budaRoot) {
190 
191         initOnce();
192 
193         /* set up directories */
194 
195         try {
196             if (persistentRoot == null) {
197                 /* no persistent storage */
198                 persistentRoot = CacheDir.create("dvb.persistent.root").getPath() + File.separator;
199             }
200             if (budaRoot == null) {
201                 /* no persistent storage for BUDA */
202                 budaRoot = CacheDir.create("bluray.bindingunit.root").getPath() + File.separator;
203             }
204         } catch (java.io.IOException e) {
205             System.err.println("Cache creation failed: " + e);
206             /* not fatal with most discs */
207         }
208         if (persistentRoot != null) {
209             persistentRoot = canonicalize(persistentRoot, true);
210         }
211         if (budaRoot != null) {
212             budaRoot = canonicalize(budaRoot, true);
213         }
214 
215         System.setProperty("dvb.persistent.root", persistentRoot);
216         System.setProperty("bluray.bindingunit.root", budaRoot);
217 
218         if (discRoot != null) {
219             discRoot = canonicalize(discRoot, false);
220             System.setProperty("bluray.vfs.root", discRoot);
221         } else {
222             System.getProperties().remove("bluray.vfs.root");
223         }
224 
225         /* */
226 
227         Libbluray.nativePointer = nativePointer;
228         DiscManager.getDiscManager().setCurrentDisc(discID);
229 
230         BDJActionManager.createInstance();
231 
232         Vector prefix = new Vector();
233         prefix.add("org.videolan");
234         PackageManager.setContentPrefixList(prefix);
235         PackageManager.setProtocolPrefixList(prefix);
236         PackageManager.commitContentPrefixList();
237         PackageManager.commitProtocolPrefixList();
238 
239         try {
240             BDFontMetrics.init();
241         } catch (Throwable t) {
242         }
243 
244         byte[] type = getAacsData(4096);
245         String pkg;
246         try {
247             pkg = type != null ? new String(type, "UTF-8") : null;
248             if (pkg != null) {
249                 System.out.println("using " + pkg);
250             }
251         } catch (java.io.UnsupportedEncodingException uee) {
252             pkg = null;
253         }
254 
255         System.setProperty("mhp.profile.enhanced_broadcast", "YES");
256         System.setProperty("mhp.profile.interactive_broadcast", "YES");
257         System.setProperty("mhp.profile.internet_access", "YES");
258 
259         System.setProperty("mhp.eb.version.major", "1");
260         System.setProperty("mhp.eb.version.minor", "0");
261         System.setProperty("mhp.eb.version.micro", "3");
262         System.setProperty("mhp.ia.version.major", "1");
263         System.setProperty("mhp.ia.version.minor", "0");
264         System.setProperty("mhp.ia.version.micro", "3");
265         System.setProperty("mhp.ib.version.major", "1");
266         System.setProperty("mhp.ib.version.minor", "0");
267         System.setProperty("mhp.ib.version.micro", "3");
268 
269         System.setProperty("mhp.option.ip.multicast", "UNSUPPORTED");
270         System.setProperty("mhp.option.dsmcc.uu", "UNSUPPORTED");
271         System.setProperty("mhp.option.dvb.html", "UNSUPPORTED");
272 
273         System.setProperty("dvb.returnchannel.timeout", "30");
274 
275         /* get profile from PSR */
276         int psr31 = readPSR(RegisterAccess.PSR_PLAYER_PROFILE);
277         int version = psr31 & 0xffff;
278         int profile = psr31 >> 16;
279         boolean p11 = (profile & 0x01) != 0;
280         boolean p2  = (profile & 0x02) != 0;
281         boolean p5  = (profile & 0x10) != 0;
282         boolean p6  = ((profile & 0x1f) == 0) && (version >= 0x0300);
283 
284         resetProfile();
285         if (!p6) {
286             System.setProperty("bluray.profile.1", "YES");
287             System.setProperty("bluray.p1.version.major", "1");
288             System.setProperty("bluray.p1.version.minor", p11 ? "1" : "0");
289             System.setProperty("bluray.p1.version.micro", "0");
290 
291             System.setProperty("bluray.profile.2", p2 ? "YES" : "NO");
292             System.setProperty("bluray.p2.version.major", "1");
293             System.setProperty("bluray.p2.version.minor", "0");
294             System.setProperty("bluray.p2.version.micro", "0");
295         }
296         if (p5) {
297             System.setProperty("bluray.profile.5", "YES");
298             System.setProperty("bluray.p5.version.major", "1");
299             System.setProperty("bluray.p5.version.minor", "0");
300             System.setProperty("bluray.p5.version.micro", "0");
301         }
302         if (p6) {
303             System.setProperty("bluray.profile.6", "YES");
304             System.setProperty("bluray.p6.version.major", "1");
305             System.setProperty("bluray.p6.version.minor", "0");
306             System.setProperty("bluray.p6.version.micro", "0");
307         }
308 
309         System.setProperty("bluray.disc.avplayback.readcapability", "NO");
310 
311         System.setProperty("bluray.video.fullscreenSD", "YES");
312         System.setProperty("bluray.video.fullscreenSDPG", "YES");
313         System.setProperty("bluray.DynamicRangeConversion.Level", "0");
314 
315         System.setProperty("aacs.bluray.online.capability", "YES");
316         System.setProperty("aacs.bluray.mc.capability", "NO");
317 
318         System.setProperty("bluray.prefetchedplaylistloading", "NO");
319         System.setProperty("bluray.video.autoresume", "NO");
320 
321         System.setProperty("bluray.mediaselect", "NO");
322 
323         System.setProperty("bluray.event.extension", "YES");
324 
325         System.setProperty("bluray.jmf.subtitlestyle", "YES");
326 
327         System.setProperty("bluray.rccapability.release", "YES");
328         System.setProperty("bluray.rccapability.holdandrelease", "YES");
329         System.setProperty("bluray.rccapability.repeatonhold", "NO");
330 
331         System.setProperty("bluray.localstorage.level", "5");
332         System.setProperty("bluray.localstorage.maxlevel", "5");
333 
334         System.setProperty("bluray.localstorage.removable", "NO");
335         System.setProperty("bluray.localstorage.upgradable", "NO");
336         System.setProperty("bluray.localstorage.name", "HDD");
337 
338         System.setProperty("bluray.memory.images", "131072");
339         System.setProperty("bluray.memory.audio", "8192");
340         System.setProperty("bluray.memory.audio_plus_img", "139264");
341         System.setProperty("bluray.memory.java_heap", "32768");
342         System.setProperty("bluray.memory.font_cache", "4096");
343 
344         System.setProperty("bluray.network.connected", "YES");
345 
346         try {
347             System.setSecurityManager(new BDJSecurityManager(discRoot, persistentRoot, budaRoot));
348         } catch (Exception ex) {
349             System.err.println("System.setSecurityManager() failed: " + ex);
350             throw new SecurityException("Failed initializing SecurityManager");
351         }
352 
353         loadAdapter(System.getProperty("org.videolan.loader.adapter"));
354         loadAdapter(pkg);
355 
356         /* get title infos */
357         titleInfos = getTitleInfosN(nativePointer);
358         if (titleInfos == null) {
359             /* this is fatal */
360             throw new Error("getTitleInfos() failed");
361         }
362 
363         booted = true;
364     }
365 
366     /* called only from native code */
shutdown()367     private static void shutdown() {
368         if (nativePointer == 0) {
369             return;
370         }
371         try {
372             stopTitle(true);
373             BDJLoader.shutdown();
374             BDJActionManager.shutdown();
375 
376             /* all Xlet contexts (and threads) should be terminated now */
377             try {
378                 System.setSecurityManager(null);
379             } catch (Exception ex) {
380                 System.err.println("System.setSecurityManager(null) failed: " + ex);
381             }
382 
383             MountManager.unmountAll();
384             GUIManager.shutdown();
385             BDToolkit.shutdownDisc();
386             BDFontMetrics.shutdown();
387             SIManagerImpl.shutdown();
388             IxcRegistry.shutdown();
389             EventManager.shutdown();
390             Status.shutdown();
391             ServiceContextFactoryImpl.shutdown();
392             FontFactory.unloadDiscFonts();
393             CacheDir.remove();
394         } catch (Throwable e) {
395             System.err.println("shutdown() failed: " + e + "\n" + Logger.dumpStack(e));
396         }
397         nativePointer = 0;
398         titleInfos = null;
399         synchronized (bdjoFilesLock) {
400             bdjoFiles = null;
401         }
402         classLoaderAdapter = null;
403         loaderAdapter = null;
404         booted = false;
405     }
406 
407     /*
408      * Package private
409      */
410 
411     /* called by BDJLoader to select HDMV title */
selectHdmvTitle(int title)412     protected static boolean selectHdmvTitle(int title) {
413         return selectTitleN(nativePointer, title) == 1 ? true : false;
414     }
415 
cacheBdRomFile(String path, String cachePath)416     protected static boolean cacheBdRomFile(String path, String cachePath) {
417         return cacheBdRomFileN(nativePointer, path, cachePath) == 0;
418     }
419 
setUOMask(boolean menuCallMask, boolean titleSearchMask)420     protected static void setUOMask(boolean menuCallMask, boolean titleSearchMask) {
421         setUOMaskN(nativePointer, menuCallMask, titleSearchMask);
422     }
423 
setKeyInterest(int mask)424     protected static void setKeyInterest(int mask) {
425         setKeyInterestN(nativePointer, mask);
426     }
427 
setVirtualPackage(String vpPath, boolean initBackupRegs)428     protected static int setVirtualPackage(String vpPath, boolean initBackupRegs) {
429         return setVirtualPackageN(nativePointer, vpPath, initBackupRegs);
430     }
431 
432     /*
433      * Disc titles
434      */
435 
436     /* used by javax/tv/service/SIManagerImpl */
numTitles()437     public static int numTitles() {
438         return titleInfos.length - 2;
439     }
440 
441     /* used by org/bluray/ti/TitleImpl */
getTitleInfo(int titleNum)442     public static TitleInfo getTitleInfo(int titleNum) {
443             int numTitles = numTitles();
444             if (numTitles < 0)
445                 return null;
446 
447             if (titleNum == 0xffff) {
448                 return titleInfos[titleInfos.length - 1];
449             }
450 
451             if (titleNum < 0 || titleNum > numTitles)
452                 throw new IllegalArgumentException();
453 
454             return titleInfos[titleNum];
455     }
456 
457     /* used by org/bluray/ti/PlayListImpl */
getCurrentTitle()458     public static int getCurrentTitle() {
459         return readPSR(RegisterAccess.PSR_TITLE_NR);
460     }
461 
462 
463     /*
464      * Disc data
465      */
466 
467     /* cache parsed .bdjo files */
468     private static Map bdjoFiles = null;
469     private static Object bdjoFilesLock = new Object();
470 
getAacsData(int type)471     public static byte[] getAacsData(int type) {
472         return getAacsDataN(nativePointer, type);
473     }
474 
getPlaylistInfo(int playlist)475     public static PlaylistInfo getPlaylistInfo(int playlist) {
476         return getPlaylistInfoN(nativePointer, playlist);
477     }
478 
getBdjo(String name)479     public static Bdjo getBdjo(String name) {
480         Bdjo bdjo;
481         synchronized (bdjoFilesLock) {
482             if (bdjoFiles == null) {
483                 bdjoFiles = new HashMap();
484             } else {
485                 bdjo = (Bdjo)bdjoFiles.get(name);
486                 if (bdjo != null) {
487                     return bdjo;
488                 }
489             }
490 
491             bdjo = getBdjoN(nativePointer, name + ".bdjo");
492             if (bdjo != null) {
493                 bdjoFiles.put(name, bdjo);
494             }
495             return bdjo;
496          }
497     }
498 
listBdFiles(String path, boolean onlyBdRom)499     public static String[] listBdFiles(String path, boolean onlyBdRom) {
500         return listBdFilesN(nativePointer, path, onlyBdRom);
501     }
502 
503     /*
504      * Playback control
505      */
506 
selectPlaylist(int playlist, int playitem, int playmark, long time)507     public static boolean selectPlaylist(int playlist, int playitem, int playmark, long time) {
508         if (playlist < 0)
509             throw new IllegalArgumentException("Playlist cannot be negative");
510 
511         return selectPlaylistN(nativePointer, playlist, playitem, playmark, time) == 1 ? true : false;
512     }
513 
selectPlaylist(int playlist)514     public static boolean selectPlaylist(int playlist) {
515         return selectPlaylist(playlist, -1, -1, -1);
516     }
517 
stopPlaylist()518     public static void stopPlaylist() {
519         selectPlaylistN(nativePointer, -1, -1, -1, -1);
520     }
521 
seekTime(long tick)522     public static long seekTime(long tick) {
523         return seekN(nativePointer, -1, -1, tick);
524     }
525 
seekMark(int mark)526     public static long seekMark(int mark) {
527         if (mark < 0)
528             throw new IllegalArgumentException("Mark cannot be negative");
529 
530         long result = seekN(nativePointer, -1, mark, -1);
531         if (result == -1)
532             throw new IllegalArgumentException("Seek error");
533         return result;
534     }
535 
seekPlayItem(int clip)536     public static long seekPlayItem(int clip) {
537         if (clip < 0)
538             throw new IllegalArgumentException("Mark cannot be negative");
539 
540         long result = seekN(nativePointer, clip, -1, -1);
541         if (result == -1)
542             throw new IllegalArgumentException("Seek error");
543         return result;
544     }
545 
selectAngle(int angle)546     public static boolean selectAngle(int angle) {
547         if (angle < 1)
548             throw new IllegalArgumentException("Angle cannot be negative");
549 
550         return selectAngleN(nativePointer, angle) == 1 ? true : false;
551     }
552 
soundEffect(int id)553     public static int soundEffect(int id) {
554         return soundEffectN(nativePointer, id);
555     }
556 
getCurrentAngle()557     public static int getCurrentAngle() {
558         return readPSR(RegisterAccess.PSR_ANGLE_NR);
559     }
560 
getUOMask()561     public static long getUOMask() {
562         return getUOMaskN(nativePointer);
563     }
564 
tellTime()565     public static long tellTime() {
566         return tellTimeN(nativePointer);
567     }
568 
selectRate(float rate)569     public static boolean selectRate(float rate) {
570         return selectRateN(nativePointer, rate, 0) == 1 ? true : false;
571     }
selectRate(float rate, boolean start)572     public static boolean selectRate(float rate, boolean start) {
573         return selectRateN(nativePointer, rate, start ? 1 : 2) == 1 ? true : false;
574     }
575 
576     /*
577      * Register access
578      */
579 
writeGPR(int num, int value)580     public static void writeGPR(int num, int value) {
581         int ret = writeRegN(nativePointer, 0, num, value, 0xffffffff);
582 
583         if (ret == -1)
584             throw new IllegalArgumentException("Invalid GPR");
585     }
586 
writePSR(int num, int value)587     public static void writePSR(int num, int value) {
588         writePSR(num, value, 0xffffffff);
589     }
590 
writePSR(int num, int value, int psr_value_mask)591     public static void writePSR(int num, int value, int psr_value_mask) {
592         int ret = writeRegN(nativePointer, 1, num, value, psr_value_mask);
593 
594         if (ret == -1)
595             throw new IllegalArgumentException("Invalid PSR");
596     }
597 
readGPR(int num)598     public static int readGPR(int num) {
599         if (num < 0 || (num >= 4096))
600             throw new IllegalArgumentException("Invalid GPR");
601 
602         return readRegN(nativePointer, 0, num);
603     }
604 
readPSR(int num)605     public static int readPSR(int num) {
606         if (num < 0 || (num >= 128))
607             throw new IllegalArgumentException("Invalid PSR");
608 
609         return readRegN(nativePointer, 1, num);
610     }
611 
612     /*
613      * Graphics
614      */
615 
updateGraphic(int width, int height, int[] rgbArray)616     public static void updateGraphic(int width, int height, int[] rgbArray) {
617         updateGraphicN(nativePointer, width, height, rgbArray,
618                        0, 0, width - 1, height - 1);
619     }
620 
updateGraphic(int width, int height, int[] rgbArray, int x0, int y0, int x1, int y1)621     public static void updateGraphic(int width, int height, int[] rgbArray,
622                                      int x0, int y0, int x1, int y1) {
623         updateGraphicN(nativePointer, width, height, rgbArray,
624                        x0, y0, x1, y1);
625     }
626 
627     /*
628      * Events from native side
629      */
630 
startTitle(int titleNumber)631     private static boolean startTitle(int titleNumber) {
632         try {
633             BDLocator locator = new BDLocator(null, titleNumber, -1);
634             Title title = (Title)SIManager.createInstance().getService(locator);
635             if (title == null) {
636                 System.err.println("startTitle() failed: title " + titleNumber + " not found");
637                 return false;
638             }
639 
640             TitleContext titleContext = (TitleContext)ServiceContextFactory.getInstance().getServiceContext(null);
641             titleContext.start(title, true);
642             return true;
643 
644         } catch (Throwable e) {
645             System.err.println("startTitle() failed: " + e + "\n" + Logger.dumpStack(e));
646             return false;
647         }
648     }
649 
stopTitle(boolean shutdown)650     private static boolean stopTitle(boolean shutdown) {
651         try {
652             TitleContext titleContext = (TitleContext)ServiceContextFactory.getInstance().getServiceContext(null);
653             if (shutdown) {
654                 titleContext.destroy();
655             } else {
656                 titleContext.stop();
657             }
658             return true;
659         } catch (Throwable e) {
660             System.err.println("stopTitle() failed: " + e + "\n" + Logger.dumpStack(e));
661             return false;
662         }
663     }
664 
665     /* called only from native code */
processEventImpl(int event, int param)666     private static boolean processEventImpl(int event, int param) {
667         boolean result = true;
668         int key = 0;
669 
670         switch (event) {
671 
672         case BDJ_EVENT_START:
673             return startTitle(param);
674         case BDJ_EVENT_STOP:
675             return stopTitle(false);
676 
677         case BDJ_EVENT_CHAPTER:
678         case BDJ_EVENT_MARK:
679         case BDJ_EVENT_PLAYITEM:
680         case BDJ_EVENT_PLAYLIST:
681         case BDJ_EVENT_ANGLE:
682         case BDJ_EVENT_SUBTITLE:
683         case BDJ_EVENT_AUDIO_STREAM:
684         case BDJ_EVENT_SECONDARY_STREAM:
685         case BDJ_EVENT_END_OF_PLAYLIST:
686         case BDJ_EVENT_PTS:
687         case BDJ_EVENT_UO_MASKED:
688         case BDJ_EVENT_SEEK:
689         case BDJ_EVENT_RATE:
690             result = PlayerManager.getInstance().onEvent(event, param);
691             break;
692 
693         case BDJ_EVENT_PSR102:
694             Status.getInstance().receive(param);
695             break;
696 
697         case BDJ_EVENT_VK_KEY:
698             switch (param & 0xffff) {
699             case  0: key = KeyEvent.VK_0; break;
700             case  1: key = KeyEvent.VK_1; break;
701             case  2: key = KeyEvent.VK_2; break;
702             case  3: key = KeyEvent.VK_3; break;
703             case  4: key = KeyEvent.VK_4; break;
704             case  5: key = KeyEvent.VK_5; break;
705             case  6: key = KeyEvent.VK_6; break;
706             case  7: key = KeyEvent.VK_7; break;
707             case  8: key = KeyEvent.VK_8; break;
708             case  9: key = KeyEvent.VK_9; break;
709             case 11: key = HRcEvent.VK_POPUP_MENU; break;
710             case 12: key = KeyEvent.VK_UP; break;
711             case 13: key = KeyEvent.VK_DOWN; break;
712             case 14: key = KeyEvent.VK_LEFT; break;
713             case 15: key = KeyEvent.VK_RIGHT; break;
714             case 16: key = KeyEvent.VK_ENTER; break;
715             case 403: key = HRcEvent.VK_COLORED_KEY_0; break;
716             case 404: key = HRcEvent.VK_COLORED_KEY_1; break;
717             case 405: key = HRcEvent.VK_COLORED_KEY_2; break;
718             case 406: key = HRcEvent.VK_COLORED_KEY_3; break;
719             case 17:
720                 result = false;
721                 if ((param & 0x80000000) != 0) {
722                     result = java.awt.BDJHelper.postMouseEvent(MouseEvent.MOUSE_PRESSED) || result;
723                 }
724                 if ((param & 0x40000000) != 0) {
725                     result = java.awt.BDJHelper.postMouseEvent(MouseEvent.MOUSE_CLICKED) || result;
726                 }
727                 if ((param & 0x20000000) != 0) {
728                     result = java.awt.BDJHelper.postMouseEvent(MouseEvent.MOUSE_RELEASED) || result;
729                 }
730                 key = -1;
731                 break;
732             default:
733                 key = -1;
734                 result = false;
735                 break;
736             }
737             if (key > 0) {
738                 boolean r1 = false, r2 = false, r3 = false;
739                 if ((param & 0x80000000) != 0) {
740                     r1 = EventManager.getInstance().receiveKeyEventN(KeyEvent.KEY_PRESSED, 0, key);
741                 }
742                 if ((param & 0x40000000) != 0) {
743                     r2 = EventManager.getInstance().receiveKeyEventN(KeyEvent.KEY_TYPED, 0, key);
744                 }
745                 if ((param & 0x20000000) != 0) {
746                     r3 = EventManager.getInstance().receiveKeyEventN(KeyEvent.KEY_RELEASED, 0, key);
747                 }
748                 result = r1 || r2 || r3;
749             }
750             break;
751         case BDJ_EVENT_MOUSE:
752             result = java.awt.BDJHelper.postMouseEvent(param >> 16, param & 0xffff);
753             break;
754         default:
755             System.err.println("Unknown event " + event + "." + param);
756             result = false;
757         }
758 
759         return result;
760     }
761 
processEvent(int event, int param)762     private static boolean processEvent(int event, int param) {
763         try {
764             return processEventImpl(event, param);
765         } catch (Throwable e) {
766             System.err.println("processEvent() failed: " + e + "\n" + Logger.dumpStack(e));
767             return false;
768         }
769     }
770 
771     private static final int BDJ_EVENT_START                    = 1;
772     private static final int BDJ_EVENT_STOP                     = 2;
773     private static final int BDJ_EVENT_PSR102                   = 3;
774 
775     public  static final int BDJ_EVENT_PLAYLIST                 = 4;
776     public  static final int BDJ_EVENT_PLAYITEM                 = 5;
777     public  static final int BDJ_EVENT_CHAPTER                  = 6;
778     public  static final int BDJ_EVENT_MARK                     = 7;
779     public  static final int BDJ_EVENT_PTS                      = 8;
780     public  static final int BDJ_EVENT_END_OF_PLAYLIST          = 9;
781 
782     public  static final int BDJ_EVENT_SEEK                     = 10;
783     public  static final int BDJ_EVENT_RATE                     = 11;
784 
785     public  static final int BDJ_EVENT_ANGLE                    = 12;
786     public  static final int BDJ_EVENT_AUDIO_STREAM             = 13;
787     public  static final int BDJ_EVENT_SUBTITLE                 = 14;
788     public  static final int BDJ_EVENT_SECONDARY_STREAM         = 15;
789 
790     private static final int BDJ_EVENT_VK_KEY                   = 16;
791     public  static final int BDJ_EVENT_UO_MASKED                = 17;
792     private static final int BDJ_EVENT_MOUSE                    = 18;
793 
794     public static final int AACS_DISC_ID           = 1;
795     public static final int AACS_MEDIA_VID         = 2;
796     public static final int AACS_MEDIA_PMSN        = 3;
797     public static final int AACS_DEVICE_BINDING_ID = 4;
798     public static final int AACS_DEVICE_NONCE      = 5;
799     public static final int AACS_MEDIA_KEY         = 6;
800     public static final int AACS_CONTENT_CERT_ID   = 7;
801     public static final int AACS_BDJ_ROOT_CERT_HASH= 8;
802 
getAacsDataN(long np, int type)803     private static native byte[] getAacsDataN(long np, int type);
getTitleInfosN(long np)804     private static native TitleInfo[] getTitleInfosN(long np);
getPlaylistInfoN(long np, int playlist)805     private static native PlaylistInfo getPlaylistInfoN(long np, int playlist);
seekN(long np, int playitem, int playmark, long time)806     private static native long seekN(long np, int playitem, int playmark, long time);
selectPlaylistN(long np, int playlist, int playitem, int playmark, long time)807     private static native int selectPlaylistN(long np, int playlist, int playitem, int playmark, long time);
selectTitleN(long np, int title)808     private static native int selectTitleN(long np, int title);
selectAngleN(long np, int angle)809     private static native int selectAngleN(long np, int angle);
soundEffectN(long np, int id)810     private static native int soundEffectN(long np, int id);
getUOMaskN(long np)811     private static native long getUOMaskN(long np);
setUOMaskN(long np, boolean menuCallMask, boolean titleSearchMask)812     private static native void setUOMaskN(long np, boolean menuCallMask, boolean titleSearchMask);
setKeyInterestN(long np, int mask)813     private static native void setKeyInterestN(long np, int mask);
tellTimeN(long np)814     private static native long tellTimeN(long np);
selectRateN(long np, float rate, int reason)815     private static native int selectRateN(long np, float rate, int reason);
writeRegN(long np, int is_psr, int num, int value, int psr_value_mask)816     private static native int writeRegN(long np, int is_psr, int num, int value, int psr_value_mask);
readRegN(long np, int is_psr, int num)817     private static native int readRegN(long np, int is_psr, int num);
setVirtualPackageN(long np, String vpPath, boolean psrBackup)818     private static native int setVirtualPackageN(long np, String vpPath, boolean psrBackup);
cacheBdRomFileN(long np, String path, String cachePath)819     private static native int cacheBdRomFileN(long np, String path, String cachePath);
listBdFilesN(long np, String path, boolean onlyBdRom)820     private static native String[] listBdFilesN(long np, String path, boolean onlyBdRom);
getBdjoN(long np, String name)821     private static native Bdjo getBdjoN(long np, String name);
updateGraphicN(long np, int width, int height, int[] rgbArray, int x0, int y0, int x1, int y1)822     private static native void updateGraphicN(long np, int width, int height, int[] rgbArray,
823                                               int x0, int y0, int x1, int y1);
824 
825     private static long nativePointer = 0;
826     private static TitleInfo[] titleInfos = null;
827 }
828