Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: jreceiver/client/rio/servlet/RioHostLayout.java


1   /* $Header: /cvsroot/jreceiver/jreceiver/src/jreceiver/client/rio/servlet/RioHostLayout.java,v 1.4 2002/12/29 00:44:07 reedesau Exp $ */
2   
3   package jreceiver.client.rio.servlet;
4   
5   import java.io.IOException;
6   import javax.servlet.*;
7   import javax.servlet.http.*;
8   
9   
10  import jreceiver.client.common.servlet.*;
11  import jreceiver.common.rpc.RpcException;
12  
13  /**
14   * Servlet answering 'layout' requests from Rio Server.
15   * <p>
16   * I18N this class
17   * <p>
18   * Return localized text strings describing what to
19   * put on the Rio Receiver display.
20   * <p>
21   * The URL looks like this
22   *    http://.../layout/en_UK/index
23   * <p>
24   * where en_UK is the locale for which strings are requested.
25   * <p>
26   * The response looks like this:
27   * <p>
28   *     /layout/en_UK/all_info=All Info           *SUPPORTED*
29   *     /layout/en_UK/remaining=Remaining Time
30   *     /layout/en_UK/scope=Scope View
31   *     /layout/en_UK/inverse_scope=Inverse Scope
32   *     /layout/en_UK/big_title=Big Title
33   *
34   * @author Reed Esau
35   * @version $Revision: 1.4 $ $Date: 2002/12/29 00:44:07 $
36   */
37  public class RioHostLayout extends RioHostBase {
38  
39      /**
40       */
41      protected void handleRequest(HttpServletRequest req,
42                                   HttpServletResponse resp,
43                                   int src_id)
44      throws ServletException, IOException, RpcException {
45  
46          long []layoutData = null;
47          String pathinfo = req.getPathInfo();  // extra path after servlet name
48  
49          if (pathinfo == null) {
50              log.warn("no locale was specified");
51              return;
52          }
53  
54  
55          BaseResponseWriter writer = null;
56  
57          try {
58              if (pathinfo.startsWith("/en_UK/index")) {
59                  log.debug("localized message strings requested");
60                  writer = new ResponseWriter();
61                  writer.write("/layout/en_UK/all_info=All Info\r\n");
62                  writer.write("/layout/en_UK/remaining=Remaining Time\r\n");
63                  writer.write("/layout/en_UK/big_title=Big Title\r\n");
64                  writer.write("/layout/en_UK/scope=Scope\r\n");
65                  writer.write("/layout/en_UK/inverse_scope=Inverse Scope\r\n");
66                  writer.write("/layout/en_UK/with_volume=All, With Volume\r\n");
67                  writer.write("/layout/en_UK/test=Test\r\n");
68              }
69  /*            else if (pathinfo.startsWith("/en_UK/all_info")) {
70                  log.debug("the 'all_info' layout requested");
71                  writer = new ResponseStreamWriter();
72                  for (int i = 0; i < layout_data.length; i++) {
73                      // store id as a little endian dword
74                      writer.write4( (int)layout_data[i], false);
75                  }
76              } */
77  /*
78              else if (pathinfo.startsWith("/en_UK/with_volume")) {
79                  log.debug("the most excellent 'with_volume' layout requested");
80                  writer = new ResponseStreamWriter();
81                  for (int i = 0; i < layout_with_volume.length; i++) {
82                      // store id as a little endian dword
83                      writer.write4( (int)layout_with_volume[i], false);
84                  }
85              }
86              else if (pathinfo.startsWith("/en_UK/all_info")) {
87                  log.debug("the 'all_info' layout requested");
88                  writer = new ResponseStreamWriter();
89                  for (int i = 0; i < layout_all_info.length; i++) {
90                      // store id as a little endian dword
91                      writer.write4( (int)layout_all_info[i], false);
92                  }
93              }
94              else if (pathinfo.startsWith("/en_UK/remaining")) {
95                  log.debug("the 'remaining' layout requested");
96                  writer = new ResponseStreamWriter();
97                  for (int i = 0; i < layout_remaining.length; i++) {
98                      // store id as a little endian dword
99                      writer.write4( (int)layout_remaining[i], false);
100                 }
101             }
102             else if (pathinfo.startsWith("/en_UK/big_title")) {
103                 log.debug("the 'big_title' layout requested");
104                 writer = new ResponseStreamWriter();
105                 for (int i = 0; i < layout_big_title.length; i++) {
106                     // store id as a little endian dword
107                     writer.write4( (int)layout_big_title[i], false);
108                 }
109             }
110             else if (pathinfo.startsWith("/en_UK/scope")) {
111                 log.debug("the 'scope' layout requested");
112                 writer = new ResponseStreamWriter();
113                 for (int i = 0; i < layout_scope.length; i++) {
114                     // store id as a little endian dword
115                     writer.write4( (int)layout_scope[i], false);
116                 }
117             }
118             else if (pathinfo.startsWith("/en_UK/inverse_scope")) {
119                 log.debug("the 'inverse_scope' layout requested");
120                 writer = new ResponseStreamWriter();
121                 for (int i = 0; i < layout_inverse_scope.length; i++) {
122                     // store id as a little endian dword
123                     writer.write4( (int)layout_inverse_scope[i], false);
124                 }
125             } */
126             else if (pathinfo.startsWith("/en_UK/with_volume")) {
127                 layoutData = layout_with_volume;
128             }
129             else if (pathinfo.startsWith("/en_UK/all_info")) {
130                 layoutData = layout_all_info;
131             }
132             else if (pathinfo.startsWith("/en_UK/remaining")) {
133                 layoutData = layout_remaining;
134             }
135             else if (pathinfo.startsWith("/en_UK/big_title")) {
136                 layoutData = layout_big_title;
137             }
138             else if (pathinfo.startsWith("/en_UK/scope")) {
139                 layoutData = layout_scope;
140             }
141             else if (pathinfo.startsWith("/en_UK/inverse_scope")) {
142                 layoutData = layout_inverse_scope;
143             }
144             else if (pathinfo.startsWith("/en_UK/test")) {
145                 layoutData = layout_test;
146             }
147             else
148                 throw new ServletException("query not supported just yet");
149 
150             if (layoutData != null) {
151                 writer = new ResponseStreamWriter();
152                 for (int i = 0; i < layoutData.length; i++) {
153                     // store id as a little endian dword
154                     writer.write4( (int)layoutData[i], false);
155                 }
156             }
157 
158             writer.respond(resp);
159         }
160 
161         finally {
162             if (writer != null)
163                 writer.close();
164         }
165 
166     }
167 
168     /**
169      * DON'T implicitly fail if no src_id is provided in the * query
170      */
171     protected boolean requireMfileId() {
172         return false;
173     }
174 
175 
176     // Unknown format for the layouts.  Data extracted from
177     // /layout/en_UK/all_info request.  Only 'en_UK/all_info'
178     // supported in alpha release.  More to come.
179     //layout_data =
180     protected static long []layout_data =
181     {
182         // the mysterious /en_UK/all_info (a bitmap?)
183         0x00000002, 0x0000000C, 0x00000000, 0x00000080,
184         0x00000009, 0x00000004, 0x06000002, 0x00000002,
185         0x00000000, 0x00000009, 0x00000080, 0x00000014,
186         0x00000004, 0x00000000, 0x00000006, 0x00000000,
187         0x00000013, 0x00000080, 0x00000014, 0x00000008,
188         0x00000000, 0x0000000F, 0x00000002, 0x00000000,
189         0x00000015, 0x00000080, 0x00000020, 0x00000004,
190         0x01000000, 0x00000002, 0x00000000, 0x00000020,
191         0x00000080, 0x0000002A, 0x00000004, 0x03000000,
192         0x00000003, 0x0000003E, 0x0000002A, 0x00000080,
193         0x00000040, 0x00000004, 0x00030002, 0x00000009,
194         0x00000000, 0x00000033, 0x0000003E, 0x0000003B,
195         0x00000004, 0x00000000, 0x00000002, 0x00000000,
196         0x0000003B, 0x0000003E, 0x00000040, 0x00000004,
197         0x05010000, 0x00000009, 0x00000026, 0x00000031,
198         0x0000003E, 0x00000040, 0x00000004, 0x00010000,
199         0x00000009, 0x00000026, 0x0000003B, 0x00000040,
200         0x00000040, 0x00000004, 0x00020000, 0x00000004,
201         0x00000000, 0x00000000, 0x0000000C, 0x00000008,
202         0x00000004, 0x00020000
203     };
204 
205 // with-volume layout  (david schuetz, 29 dec 2001)
206     protected static long []layout_with_volume =
207     {
208       0x02, 0x0c, 0x00, 0x80, 0x09, 0x04, 0x06000002, // Playlist Name
209       0x02, 0x00, 0x09, 0x80, 0x34, 0x04, 0x00000000, // Track Name
210       0x06, 0x00, 0x13, 0x80, 0x14, 0x08, 0x00, 0x0f, // Horizontal Bar
211       0x02, 0x00, 0x15, 0x80, 0x20, 0x04, 0x01000000, // Artist Name
212       0x02, 0x00, 0x20, 0x80, 0x2a, 0x04, 0x03000000, // Album Name
213       0x03, 0x3e, 0x2a, 0x80, 0x40, 0x04, 0x00030002, // Big Time Display
214       0x07, 0x00, 0x33, 0x40, 0x40, 0x04, 0x00000000, // Volume Indicator
215 //    0x02, 0x00, 0x33, 0x3e, 0x3b, 0x04, 0x05010000, // File Type (bit, codec)
216       0x09, 0x1f, 0x29, 0x3e, 0x31, 0x04, 0x00010000, // Repeat indicator
217       0x09, 0x00, 0x2b, 0x1a, 0x31, 0x04, 0x00020000, // Shuffle indicator
218       0x04, 0x00, 0x00, 0x0c, 0x08, 0x04, 0x00020000  // Play Status Icon
219     };
220 
221 // standard Rio layouts (auto-decoded, hopefully they're labelled right!)
222 // all_info layout
223     protected static long []layout_all_info =
224     {
225       0x02, 0x0c, 0x00, 0x80, 0x09, 0x04, 0x06000002,  // Playlist name
226       0x02, 0x00, 0x09, 0x80, 0x14, 0x04, 0x00000000,  // Track name
227       0x06, 0x00, 0x13, 0x80, 0x14, 0x08, 0x00, 0x0f,  // Box or Bar
228       0x02, 0x00, 0x15, 0x80, 0x20, 0x04, 0x01000000,  // Artist name
229       0x02, 0x00, 0x20, 0x80, 0x2a, 0x04, 0x03000000,  // Album name
230       0x03, 0x3e, 0x2a, 0x80, 0x40, 0x04, 0x00030002,  // Time display
231       0x09, 0x00, 0x33, 0x3e, 0x3b, 0x04, 0x00000000,  // Mute indicator
232       0x02, 0x00, 0x3b, 0x3e, 0x40, 0x04, 0x05010000,  // File Type (bit, codec)
233       0x09, 0x26, 0x31, 0x3e, 0x40, 0x04, 0x00010000,  // Repeat indicator
234       0x09, 0x26, 0x3b, 0x50, 0x40, 0x04, 0x00020000,  // Shuffle indicator
235       0x04, 0x00, 0x00, 0x0c, 0x08, 0x04, 0x00020000   // Play Status icon
236     };
237 
238 // remaining layout
239     protected static long []layout_remaining =
240     {
241       0x02, 0x0c, 0x00, 0x80, 0x09, 0x04, 0x06000002,  // Playlist name
242       0x02, 0x00, 0x09, 0x80, 0x14, 0x04, 0x00000000,  // Track name
243       0x06, 0x00, 0x13, 0x80, 0x14, 0x08, 0x00, 0x0f,  // Box or Bar
244       0x02, 0x00, 0x15, 0x80, 0x20, 0x04, 0x01000000,  // Artist name
245       0x02, 0x00, 0x20, 0x80, 0x2a, 0x04, 0x03000000,  // Album name
246       0x03, 0x40, 0x2a, 0x80, 0x40, 0x04, 0x01030002,  // Time display
247       0x09, 0x00, 0x33, 0x40, 0x3b, 0x04, 0x00000000,  // Mute indicator
248       0x02, 0x00, 0x3b, 0x40, 0x40, 0x04, 0x05010000,  // File Type (bit, codec)
249       0x09, 0x30, 0x31, 0x40, 0x40, 0x04, 0x00010000,  // Repeat indicator
250       0x09, 0x30, 0x3b, 0x50, 0x40, 0x04, 0x00020000,  // Shuffle indicator
251       0x04, 0x00, 0x00, 0x0c, 0x08, 0x04, 0x00020000   // Play Status icon
252     };
253 
254 // big_title layout
255     protected static long []layout_big_title =
256     {
257       0x02, 0x00, 0x00, 0x80, 0x12, 0x04, 0x00040000,  // Track name
258       0x02, 0x00, 0x14, 0x80, 0x1f, 0x04, 0x01000000,  // Artist name
259       0x03, 0x20, 0x2a, 0x60, 0x40, 0x04, 0x00030002,  // Time display
260       0x09, 0x00, 0x28, 0x20, 0x31, 0x04, 0x00000000,  // Mute indicator
261       0x09, 0x70, 0x31, 0x80, 0x40, 0x04, 0x00010002,  // Repeat indicator
262       0x09, 0x60, 0x28, 0x80, 0x31, 0x04, 0x00020002,  // Shuffle indicator
263       0x04, 0x00, 0x38, 0x0c, 0x40, 0x04, 0x00020000   // Play Status icon
264     };
265 
266 // scope layout
267     protected static long []layout_scope =
268     {
269       0x02, 0x00, 0x00, 0x80, 0x0b, 0x04, 0x00000000,  // Track name
270       0x02, 0x00, 0x0b, 0x80, 0x16, 0x04, 0x01000000,  // Artist name
271       0x02, 0x00, 0x16, 0x80, 0x20, 0x04, 0x03000000,  // Album name
272       0x03, 0x40, 0x2a, 0x80, 0x40, 0x04, 0x00030002,  // Time display
273       0x09, 0x71, 0x20, 0x80, 0x29, 0x04, 0x00010000,  // Repeat indicator
274       0x08, 0x00, 0x20, 0x40, 0x40, 0x00               // 'scope Display
275     };
276 
277 // inverse_scope layout
278     protected static long []layout_inverse_scope =
279     {
280       0x02, 0x01, 0x01, 0x7f, 0x0c, 0x04, 0x00000000,  // Track name
281       0x02, 0x01, 0x0c, 0x7f, 0x17, 0x04, 0x01000000,  // Artist name
282       0x02, 0x01, 0x17, 0x7f, 0x21, 0x04, 0x03000000,  // Album name
283       0x03, 0x40, 0x2a, 0x7f, 0x3f, 0x04, 0x00030002,  // Time display
284       0x09, 0x71, 0x20, 0x80, 0x29, 0x04, 0x00010000,  // Repeat indicator
285       0x08, 0x01, 0x21, 0x40, 0x3f, 0x00,              // 'scope Display
286       0x06, 0x00, 0x00, 0x80, 0x40, 0x08, 0x02, 0x00   // Box or Bar
287     };
288 
289 // test layout
290     protected static long []layout_test =
291     {
292 
293       0x02, 0x00, 0x00, 0x3f, 0x07, 0x04, 0x00010000,  // Track name
294       0x02, 0x40, 0x00, 0x80, 0x07, 0x04, 0x01010002,  // Artist name
295       0x02, 0x00, 0x08, 0x80, 0x0f, 0x04, 0x02010000,  // Album name
296       0x02, 0x40, 0x08, 0x80, 0x0f, 0x04, 0x03010002,  // Album name
297       0x02, 0x00, 0x10, 0x3f, 0x17, 0x04, 0x04010000,  // Year
298       0x02, 0x40, 0x10, 0x80, 0x17, 0x04, 0x05010002,  // File Type (bit, codec)
299       0x02, 0x00, 0x18, 0x3f, 0x1f, 0x04, 0x06010000,  // Playlist name
300       0x02, 0x40, 0x18, 0x80, 0x1f, 0x04, 0x07010002,  // (unknown - tag 7)
301       0x02, 0x00, 0x20, 0x3f, 0x27, 0x04, 0x08010000,  // (unknown - tag 8)
302       0x02, 0x40, 0x20, 0x80, 0x27, 0x04, 0x09010002,  // (unknown - tag 9)
303       0x03, 0x00, 0x30, 0x1f, 0x37, 0x04, 0x00010000,  // Time display
304       0x04, 0x20, 0x30, 0x2f, 0x37, 0x04, 0x00020000,  // Play Status icon
305       0x09, 0x40, 0x30, 0x5f, 0x37, 0x04, 0x00010000,  // Repeat indicator
306       0x09, 0x60, 0x30, 0x80, 0x37, 0x04, 0x00020000,  // Shuffle indicator
307       0x07, 0x00, 0x38, 0x1f, 0x40, 0x04, 0x00000000,  // Volume indicator
308       0x08, 0x20, 0x38, 0x80, 0x40, 0x04, 0x00000000   // 'scope Display
309     };
310 
311 }
312 
313 
314 
315 /***
316 
317   ** David Schuetz
318   ** 29 December 2001
319 
320 
321 Layout format:
322 
323 A series of field definitions applied, in order, to the Rio screen.
324 
325 Each definition includes:
326   * Field Type
327   * Field Location (left, top, right, and bottom edges)
328   * Contents and Formatting Information
329 
330   Each piece of data is a single double-word (4 bytes), though the
331   formatting information for a box-type requires two double-words, while
332   tag selection, fonts, and field justification are all contained within
333   a single dword.
334 
335 Fields:
336   Type, Left, Top, Right, Bottom, Content-Length, Content-Information
337 
338 
339 Type:
340   0x00 - blank
341   0x01 - blank (shows a shaded square when used in the top-right of
342                 the playlist field on the "all info" type layout.
343                 Haven't quite figured this one out yet.)
344   0x02 - tag display (selected in the Content-Information field)
345   0x03 - time display of current location within track
346   0x04 - player status (play, pause, etc.) - uses font 2
347   0x05 - garbage (shows some sort of diagonally repeating and progressing
348                   bit-junk.  looks a lot like it's a bitmap, or maybe
349                   the content-information is supposed to contain a bitmap,
350                   or maybe an arbitrary string, but I haven't gotten this
351                   to work yet, either.)
352   0x06 - draw box (see Content-Information for type, color, and border)
353   0x07 - volume display (diagonal wedge)
354   0x08 - scope display
355   0x09 - Mute indicator (when font=0), repeat icons (font=1) or
356          shuffle setting (font=2)
357 
358 
359 Position Information:
360   0x00 - 0x40 - vertical offset from top edge of screen to designated
361                 (top, bottom) edge of field
362   0x00 - 0x80 - horizontal offset from left edge of screen
363 
364   (for example, (0x00, 0x00, 0x80, 0x10) defines a 128x16 pixel rectangle
365    that starts in the top left corner of the screen and stretches to the
366    right edge of the screen, 16 pixels down from the top)
367 
368 Content-Length:
369   Indicates the number of bytes to skip over to get to the next field.
370   In most cases, this is 0x04, 'cause the Content-Information is a single
371   double-word of four bytes.  in the case of a box, this is 0x08, because
372   we need two dwords to describe the box.  it's possible that we might
373   have an entire string in here, if need be, though it'd be limited to
374   0xffffffff bytes (which, it seems to me, oughta be enough for anybody).
375 
376 
377 Content-Information:
378   For most fields, this breaks down as 0xTgFt--Jj:
379 
380   Tg (Tag information):
381     Fills the field with information from the designated tag, as returned
382     by the /tags HTTP call.  Doesn't quite match up with the codes in the
383     call, unfortunately, and I couldn't find a way to get many of the tags
384     displayed.  Also, in testing, the year ended up attached to the end of
385     album titles.  Dunno.
386 
387     00 - track name
388     01 - artist name (when used with the Time Display type, changes to a
389                       remaining time display)
390     02 - album name
391     03 - album name, with year appended
392     04 - year
393     05 - file type (bitrate, codec, like "128k mp3")
394     06 - current playlist name
395     07 - "mp3" (?)
396     08 - "mp3" (?)
397 
398   Ft (Font information)
399     00 - default (medium.bf)
400     01 - small (small.bf)
401     02 - icons (graphics.bf)
402     03 - timecode (timecode.bf) (big, bold, monospace font)
403     04 - large (large.bf)
404   Note that 05 and 06 crashed the receiver in testing.
405 
406   Jj (Field Justification)
407     00 - align text with the left edge of the field
408     01 - center text in the field
409     02 - align right
410 
411   When drawing a box (Type Code 6 - used for the horizontal lines), this
412   field takes on a different meaning:
413     00 - fill solid (color in next field)
414     01 - fill with grey (x-windows stippled pattern)
415     02 - invert all pixels within box
416     03 - draw only border (color in next field)
417   An extra double word is used to define a color:
418     00 - "white" (pixels of)
419     anything else - "black" (pixels on).  I saw 0x0f used in the
420                     "inverse scope" default layout
421 
422 
423 Notes:
424   Layout order doesn't really matter, until one thing overwrites another.
425   It's actually possible to fill the screen with a 'scope visualization,
426     then overlay track and time information on top of it.
427   If the field sizes don't make sense (like, say, if the right edge is
428     left of the left edge), you can crash the receiver.  If the bug is
429     in the first layout to be listed in the /layout/index call, then
430     you'll get stuck in a reboot loop.
431   I've seen the volume control in a Rio mockup image, along with some kind
432     of bargraph spectrum analyer sort of thing.  However, the fonts in that
433     picture were all very different from what finally shipped, so I'm not
434     convinced that there are other visualizations hidden somewhere in the
435     player.  Of course, you never know...
436 
437 ***/
438 
439 
440 
441 
442 
443 
444 
445 /*
446 JRECEIVER MODIFIED BSD LICENSE
447 
448 Copyright (c) 2001-2002, Reed Esau (reed.esau@pobox.com) All rights reserved.
449 
450 Redistribution and use in source and binary forms, with or without
451 modification, are permitted provided that the following conditions are
452 met:
453 
454 Redistributions of source code must retain the above copyright notice,
455 this list of conditions and the following disclaimer.
456 
457 Redistributions in binary form must reproduce the above copyright notice,
458 this list of conditions and the following disclaimer in the documentation
459 and/or other materials provided with the distribution.
460 
461 Neither the name of the JReceiver Project
462 (http://jreceiver.sourceforge.net) nor the names of its contributors may
463 be used to endorse or promote products derived from this software without
464 specific prior written permission.
465 
466 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
467 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
468 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
469 PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
470 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
471 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
472 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
473 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
474 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
475 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
476 POSSIBILITY OF SUCH DAMAGE.
477 */
478