trunk 20080912
[gitenigma.git] / src / rds_text.cpp
blob73d77c75cc26403a9c0aa7731305d2c3a29b31bd
1 #include <src/rds_text.h>
3 #include <stdio.h>
4 #include <fcntl.h>
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <string.h>
8 #include <dirent.h>
10 #include <src/enigma.h>
11 #include <lib/dvb/decoder.h>
12 #include <lib/driver/streamwd.h>
14 #include <errno.h>
16 #define SWAP(x) ((x<<8)|(x>>8))
17 #define LO(x) (x&0xFF)
19 static inline unsigned short crc_ccitt_byte( unsigned short crc, unsigned char c )
21 crc = SWAP(crc) ^ c;
22 crc = crc ^ (LO(crc) >> 4);
23 crc = crc ^ (SWAP(LO(crc)) << 4) ^ (LO(crc) << 5);
24 return crc;
27 RDSTextDecoder::RDSTextDecoder()
28 : m_interactive(0), wasVisible(0), bytesread(0), ptr(0), p1(-1), p2(-1), qdar_pos(0), rass_imode_active(0), leninfo(0), text_len(0), m_ptr(0), state(0)
29 , is_sync(0), paket_size(0), sync_try(0), sn(0), rass_logo( eZap::getInstance()->getDesktop( eZap::desktopFB )), qdarmvi_show(-1)
31 int fd=open("/dev/dvb/card0/ancillary0", O_RDONLY|O_NONBLOCK );
32 if ( fd < 0 )
33 eDebug("open /dev/dvb/card0/ancillary0 failed(%m)");
34 else
36 sn = new eSocketNotifier(eApp, fd, eSocketNotifier::Read);
37 CONNECT(sn->activated, RDSTextDecoder::process_data);
40 memset(rtp_item, 0, sizeof(rtp_item));
42 int x = eSkin::getActive()->queryValue("rds.pos.x", 0);
43 int y = eSkin::getActive()->queryValue("rds.pos.y", 0);
44 int width = eSkin::getActive()->queryValue("rds.pos.width", 0);
45 int height = eSkin::getActive()->queryValue("rds.pos.height", 0);
46 gFont rds_font = eSkin::getActive()->queryFont("rds");
48 // OSD Radiotext
49 rds_text = new eLabel( eZap::getInstance()->getDesktop( eZap::desktopFB ) );
50 rds_text->move(ePoint(x, y));
51 rds_text->resize(eSize(width, height));
52 rds_text->setFont(rds_font);
53 rds_text->setProperty("align","left");
54 rds_text->setProperty("backgroundColor","rds_bg");
55 rds_text->setProperty("foregroundColor","rds_fg");
56 rds_text->hide();
58 x = eSkin::getActive()->queryValue("rds_plus.pos.x", 0);
59 y = eSkin::getActive()->queryValue("rds_plus.pos.y", 0);
60 width = eSkin::getActive()->queryValue("rds_plus.pos.width", 0);
61 height = eSkin::getActive()->queryValue("rds_plus.pos.height", 0);
63 // OSD RTPlus Text
64 rtp_text = new eLabel( eZap::getInstance()->getDesktop( eZap::desktopFB ) );
65 rtp_text->move(ePoint(x, y));
66 rtp_text->resize(eSize(width, height));
67 rtp_text->setFont(rds_font);
68 rtp_text->setProperty("align","right");
69 rtp_text->setProperty("backgroundColor","rds_bg");
70 rtp_text->setProperty("foregroundColor","rds_fg");
71 rtp_text->hide();
73 x = eSkin::getActive()->queryValue("rass_logo.pos.x", 0);
74 y = eSkin::getActive()->queryValue("rass_logo.pos.y", 0);
76 // Rass Logo
77 gPixmap *pm = eSkin::getActive()->queryImage("rass_logo");
78 rass_logo.setPixmap(pm);
79 rass_logo.move( ePoint(x, y) );
80 rass_logo.resize( eSize(50, 21) );
81 rass_logo.pixmap_position = ePoint(0,0);
82 rass_logo.hide();
83 CONNECT(eWidget::globalFocusChanged, RDSTextDecoder::globalFocusHasChanged);
86 RDSTextDecoder::~RDSTextDecoder()
88 int fd = sn ? sn->getFD() : -1;
89 if ( fd != -1 )
91 delete sn;
92 close(fd);
96 void RDSTextDecoder::clear_service()
98 is_sync=0;paket_size=0;sync_try=0;
99 state=bytesread=ptr=0;
100 p1=p2=-1;
101 message[0]=lastmessage[0]=0;
103 int tmp=0;
104 while(tmp++ < 64)
105 rtp_item[tmp][0]=0;
107 qdarmvi_show=interactive_avail=0;
108 rds_text->hide();
109 rtp_text->hide();
110 rass_logo.hide();
111 wasVisible &= ~(1|2|4);
113 // delete cached rass slides
114 DIR *tmp_directory;
115 struct dirent *filename;
116 char tmp_filename[128];
118 tmp_directory = opendir("/tmp");
119 while ((filename = readdir(tmp_directory)) != NULL)
121 if (strstr(filename->d_name,"Rass") && strstr(filename->d_name,".mvi"))
123 sprintf(tmp_filename,"/tmp/%s",filename->d_name);
124 remove(tmp_filename);
127 closedir(tmp_directory);
130 void RDSTextDecoder::process_qdar(unsigned char *buf)
132 if (buf[0] == 0x40 && buf[1] == 0xDA)
134 int item,cnt,ctrl,item_type;
135 long item_length,id,item_no,ptr,tmp;
136 unsigned short crc_qdar,crc_read;
137 char fname[50];
138 ptr=4;cnt=0;
139 item=buf[2]<<8; // Number of Items
140 item|=buf[3];
142 while ( cnt++ < item ) //read in items
144 id=buf[ptr++]<<8; //QDarID
145 id|=buf[ptr++];
147 item_no=buf[ptr++]<<8; // Item Number
148 item_no|=buf[ptr++];
150 ctrl=buf[ptr++]; //controlbyte
151 item_type=buf[ptr++]; //item type
153 item_length=buf[ptr++]<<24; // Item length
154 item_length|=buf[ptr++]<<16;
155 item_length|=buf[ptr++]<<8;
156 item_length|=buf[ptr++];
158 ptr=ptr+4; // rfu Bytes ... not used
159 tmp=ptr; // calc crc
160 crc_qdar=0xFFFF;
161 while (tmp < ptr+item_length)
162 crc_qdar = crc_ccitt_byte(crc_qdar, buf[tmp++]);
164 crc_read=buf[ptr+item_length]<<8;
165 crc_read|=buf[ptr+item_length+1];
166 //eDebug("[RDS/Rass] CRC read: %04X calculated: %04X",crc_read,crc_qdar^0xFFFF);
168 if (crc_read == (crc_qdar^0xFFFF)) // process item
170 switch(item_type)
172 case 0x01: //Stillframe
173 if (ctrl&0x01) // display slide
175 if (!qdarmvi_show)
176 eStreamWatchdog::getInstance()->reloadSettings(3); // set mpeg decoder to 16:9
177 qdarmvi_show=1;
178 if (rass_imode_active != 1)
179 Decoder::displayIFrame((const char*)buf+ptr,item_length-2);
180 // save as last slide, used for leaving interactive mode
181 sprintf(fname,"/tmp/RassLast.mvi");
182 FILE *fh=fopen(fname,"wb");
183 fwrite(buf+ptr,1,item_length-2,fh);
184 fclose(fh);
186 if (ctrl&0x02) // save slide for interactive mode
188 sprintf(fname,"/tmp/Rass%04d.mvi",(int)id);
189 FILE *fh=fopen(fname,"wb");
190 fwrite(buf+ptr,1,item_length-2,fh);
191 fclose(fh);
192 if (id == 0 && interactive_avail == 0)
194 interactive_avail=1;
195 if (wasVisible & 8) // another widget/window visible
196 wasVisible |= 4;
197 else
198 rass_logo.show();
200 if (m_interactive && id != 0)
201 m_interactive->update_avail((int)(id/1000));
203 if (ctrl&0x04) // display slide if nothing had been displayed yet
205 if (qdarmvi_show != 1)
207 eStreamWatchdog::getInstance()->reloadSettings(3); // set mpeg decoder to 16:9
208 qdarmvi_show=1;
209 if (rass_imode_active != 1)
210 Decoder::displayIFrame((const char*)buf+ptr,item_length-2);
211 // save as last slide, used for leaving interactive mode
212 sprintf(fname,"/tmp/RassLast.mvi");
213 FILE *fh=fopen(fname,"wb");
214 fwrite(buf+ptr,1,item_length-2,fh);
215 fclose(fh);
218 if (ctrl&0x08) // delete slide
220 sprintf(fname,"/tmp/Rass%04d.mvi",(int)id);
221 remove(fname);
223 break;
224 default: //nothing more yet defined
225 break;
228 else
230 eDebug("[RDS/Rass] CRC error, skip Rass-Qdar-Item");
233 ptr=+item_length;
236 else
238 eDebug("[RDS/Rass] No Rass-QDAR archive (%02X %02X) so skipping !\n",buf[0],buf[1]);
242 void RDSTextDecoder::process_data(int what)
244 int rd=read(sn->getFD(), buf+bytesread, 263-bytesread);
245 if ( rd >= 0 )
247 bytesread+=rd;
248 if ( bytesread == 263 )
250 while(ptr<263)
252 // sync ancillary stream
253 if (sync_try > 99) // sync failed after 100 tries ? give up and spend the cpu time for something useful ;)
255 eDebug("[RDS/Rass] ancillary sync not found (%d) ... give up",sync_try);
256 bytesread=0;ptr=0;
257 return;
259 if (is_sync < 5) // try to get paket_length for sync ancillary stream
261 if ( buf[ptr] == 0xFD && ptr > p1 )
263 if ( sync_try < 15 || buf[ptr-1] > 0x02 )
265 if (p1 == -1)
266 p1=ptr;
267 else
268 p2=ptr;
271 if ( p1 != -1 && p2 != -1 )
273 ++sync_try;
274 if ((paket_size == p2-p1) || (paket_size == (p2-p1)+2) || (paket_size == (p2-p1)-2))
275 ++is_sync;
276 else
278 paket_size=p2-p1;
279 is_sync=0;
281 if (is_sync < 5)
283 p1=ptr;
284 p2=-1;
286 else
287 eDebug("[RDS/Rass] ancillary sync found (%d/%d) ...",paket_size,sync_try);
291 // get endpoint if in sync to reverse paket, we need to handle some special cases here
292 // and search -2 to +4 from theoretical position
293 if (is_sync == 5 && ptr == (p1+paket_size+4))
295 ptr-=6;
296 int tmp_pos=0xFF;
297 int tmp_l=-1;
299 int tmp_step=-2;
301 while (tmp_step <= 4)
303 if ( buf[p1+paket_size+tmp_step] == 0xFD &&
304 tmp_l < buf[p1+paket_size+tmp_step-1] &&
305 buf[p1+paket_size+tmp_step-1] < paket_size )
307 tmp_l=buf[p1+paket_size+tmp_step-1];
308 tmp_pos=tmp_step;
310 tmp_step+=2;
312 if (tmp_pos == 0xFF || tmp_l==-1 )
314 eDebug("[RDS/Rass] ancillary sync lost ... try to resync");
315 is_sync=0;
316 p1=p2=-1;
317 sync_try=0;
318 paket_size=0;
320 else
322 p2=p1+paket_size+tmp_pos;
323 ptr=ptr+tmp_pos+2;
327 // process UECP data
328 if ( p1 != -1 && p2 != -1 )
330 int cnt=buf[--p2];
331 while ( cnt-- > 0 )
333 unsigned char c = buf[--p2];
335 if (bsflag == 1) // byte stuffing
337 bsflag=2;
338 switch (c)
340 case 0x00: c=0xFD; break;
341 case 0x01: c=0xFE; break;
342 case 0x02: c=0xFF; break;
346 if (c == 0xFD && bsflag ==0)
347 bsflag=1;
348 else
349 bsflag=0;
352 if (bsflag == 0)
355 if ( state == 1 )
356 crc=0xFFFF;
357 if (( state >= 1 && state < 11 ) || ( state >=26 && state < 36 ))
358 crc = crc_ccitt_byte(crc, c);
360 switch (state)
362 case 0:
363 if ( c==0xFE ) // Start
364 state=1;
365 break;
366 case 1: // 10bit Site Address + 6bit Encoder Address
367 case 2:
368 case 3: // Sequence Counter
369 ++state;
370 break;
371 case 4:
372 leninfo=c;
373 ++state;
374 break;
375 case 5:
376 switch (c)
378 case 0x0A: // Radiotext
379 ++state;
380 break;
381 case 0x46: // Radiotext Plus tags
382 state=38;
383 break;
384 case 0xDA: // Rass
385 state=26;
386 break;
387 default: // reset to state 0
388 state=0;
390 break;
392 // process Radiotext
393 case 6: // Data Set Number ... ignore
394 case 7: // Program Service Number ... ignore
395 ++state;
396 break;
397 case 8: // Message Element Length
398 text_len=c;
399 if ( !text_len || text_len > 65 || text_len > leninfo-4)
400 state=0;
401 else
403 ++state;
404 text_len-=2;
405 m_ptr=0;
407 break;
408 case 9: // Radio Text Status bit:
409 // 0 = AB-flagcontrol
410 // 1-4 = Transmission-Number
411 // 5-6 = Buffer-Config
412 ++state; // ignore ...
413 break;
414 case 10:
415 // TODO build a complete radiotext charcode to UTF8 conversion table for all character > 0x80
416 switch (c)
418 case 0 ... 0x7f: break;
420 case 0x8d: c='ß'; break;
421 case 0x91: c='ä'; break;
422 case 0xd1: c='Ä'; break;
423 case 0x97: c='ö'; break;
424 case 0xd7: c='Ö'; break;
425 case 0x99: c='ü'; break;
426 case 0xd9: c='Ü'; break;
427 default: c=' '; break; // convert all unknown to space
429 message[m_ptr++]=c;
430 if(text_len)
431 --text_len;
432 else
433 ++state;
434 break;
435 case 11:
436 crc16=c<<8;
437 ++state;
438 break;
439 case 12:
440 crc16|=c;
441 message[m_ptr--]=0;
442 while(message[m_ptr] == ' ' && m_ptr > 0)
443 message[m_ptr--] = 0;
444 if ( crc16 == (crc^0xFFFF) )
446 rds_text->setText((const char*)message);
447 /*emit*/ textReady((const char*)message);
448 if (lastmessage[0]==0 && rass_imode_active != 1)
450 if (wasVisible & 8)
451 wasVisible |= 1;
452 else
453 rds_text->show();
455 memcpy(lastmessage,message,66);
457 else
458 eDebug("[RDS/Rass] invalid rdstext crc (%s)", message);
459 state=0;
460 break;
462 // process Rass
463 case 26: //MEL
464 text_len = c;
465 text_len2 = c;
466 ++state;
467 text_len-=9;
468 text_len2-=9;
469 t_ptr=0;
470 break;
471 case 27: // SID not used atm
472 ++state;
473 break;
474 case 28: // SID not used atm
476 ++state;
477 break;
478 case 29: // PNR packet number
479 part=c<<16;
480 ++state;
481 break;
482 case 30: // PNR packet number
483 part|=c<<8;
484 ++state;
485 break;
486 case 31: // PNR packet number
487 part|=c;
488 ++state;
489 break;
490 case 32: // NOP number of packets
491 parts=c<<16;
492 ++state;
493 break;
494 case 33: // NOP number of packets
495 parts|=c<<8;
496 ++state;
497 break;
498 case 34: // NOP number of packets
499 parts|=c;
500 ++state;
501 break;
502 case 35:
503 datamessage[t_ptr++]=c;
504 if(text_len)
505 --text_len;
506 else
507 ++state;
508 break;
509 case 36:
510 crc16=c<<8;
511 ++state;
512 break;
513 case 37:
514 crc16|=c;
515 //eDebug("[RDS/Rass] CRC read: %04X CRC calculated: %04X",crc16,crc^0xFFFF);
516 state=0;
517 if ( crc16 == (crc^0xFFFF) )
519 if (partcnt == -1)
520 partcnt=1;
521 if (partcnt == part)
523 memcpy(qdar+qdar_pos,datamessage,text_len2+1);
524 qdar_pos=qdar_pos+text_len2+1;
525 if (partcnt == parts)
527 process_qdar(qdar); // decode qdar archive
528 qdar_pos=0;
529 partcnt=-1;
531 else
532 ++partcnt;
534 else
536 qdar_pos=0;
537 partcnt=-1;
540 else
542 eDebug("[RDS/Rass] CRC error, skip Rass-Qdar-Packet");
543 partcnt=-1;
545 state=0;
546 break;
548 // process RT plus tags ...
549 case 38: // Message Element Length
550 text_len=c;
551 ++state;
552 break;
553 case 39: // Application ID
554 case 40: // always 0x4BD7 so we ignore it ;)
555 case 41: // Applicationgroup Typecode/PTY ... ignore
556 ++state;
557 break;
558 case 42:
559 rtp_buf[0]=c;
560 ++state;
561 break;
562 case 43:
563 rtp_buf[1]=c;
564 ++state;
565 break;
566 case 44:
567 rtp_buf[2]=c;
568 ++state;
569 break;
570 case 45:
571 rtp_buf[3]=c;
572 ++state;
573 break;
574 case 46: // bit 10#4 = Item Togglebit
575 // bit 10#3 = Item Runningbit
576 // Tag1: bit 10#2..11#5 = Contenttype, 11#4..12#7 = Startmarker, 12#6..12#1 = Length
577 rtp_buf[4]=c;
578 if (lastmessage[0] == 0) // no rds message till now ? quit ...
579 break;
580 int rtp_typ[2],rtp_start[2],rtp_len[2];
581 rtp_typ[0] = (0x38 & rtp_buf[0]<<3) | rtp_buf[1]>>5;
582 rtp_start[0] = (0x3e & rtp_buf[1]<<1) | rtp_buf[2]>>7;
583 rtp_len[0] = 0x3f & rtp_buf[2]>>1;
584 // Tag2: bit 12#0..13#3 = Contenttype, 13#2..14#5 = Startmarker, 14#4..14#0 = Length(5bit)
585 rtp_typ[1] = (0x20 & rtp_buf[2]<<5) | rtp_buf[3]>>3;
586 rtp_start[1] = (0x38 & rtp_buf[3]<<3) | rtp_buf[4]>>5;
587 rtp_len[1] = 0x1f & rtp_buf[4];
589 unsigned char rtplus_osd_tmp[64];
591 if (rtp_start[0] < 66 && (rtp_len[0]+rtp_start[0]) < 66)
593 memcpy(rtp_item[rtp_typ[0]],lastmessage+rtp_start[0],rtp_len[0]+1);
594 rtp_item[rtp_typ[0]][rtp_len[0]+1]=0;
597 if (rtp_typ[0] != rtp_typ[1])
599 if (rtp_start[1] < 66 && (rtp_len[1]+rtp_start[1]) < 66)
601 memcpy(rtp_item[rtp_typ[1]],lastmessage+rtp_start[1],rtp_len[1]+1);
602 rtp_item[rtp_typ[1]][rtp_len[1]+1]=0;
606 // main RTPlus item_types used by the radio stations:
607 // 1 title
608 // 4 artist
609 // 24 info.date_time
610 // 31 stationname
611 // 32 program.now
612 // 39 homepage
613 // 41 phone.hotline
614 // 46 email.hotline
615 // todo: make a window to display all saved items ...
617 //create RTPlus OSD for title/artist
618 rtplus_osd[0]=0;
620 if ( rtp_item[4][0] != 0 )//artist
621 sprintf((char*)rtplus_osd_tmp," (%s)",rtp_item[4]);
623 if ( rtp_item[1][0] != 0 )//title
624 sprintf((char*)rtplus_osd,"%s%s",rtp_item[1],rtplus_osd_tmp);
626 if ( rtplus_osd[0] != 0 )
628 rtp_text->setText((const char*)rtplus_osd);
629 /*emit*/ textReady((const char*)rtplus_osd);
630 if (rass_imode_active != 1)
632 if (wasVisible & 8)
633 wasVisible |= 2;
634 else
635 rtp_text->show();
639 state=0;
640 break;
644 p1=ptr;
645 p2=-1;
647 ++ptr;
649 if (p1 != -1 && (263-(p1)) != 263)
651 bytesread=ptr=263-(p1);
652 memcpy(buf, buf+p1, ptr);
653 p1=0;
655 else
656 bytesread=0;ptr=0;
661 // Rass InteractiveMode
662 void RDSTextDecoder::rass_interactive()
664 RassInteractivemode rass;
665 m_interactive=&rass;
667 rass_imode_active=1;
669 if (!qdarmvi_show)
670 eStreamWatchdog::getInstance()->reloadSettings(3); // set mpeg decoder to 16:9
671 Decoder::displayIFrameFromFile("/tmp/Rass0000.mvi");
673 rass_logo.hide();
674 rass_logo.move( ePoint( 50, 180 ) );
675 rass_logo.resize( eSize( 100, 21 ) );
676 rass_logo.show();
678 rass.show();
679 rass.exec();
680 m_interactive=0;
681 rass.hide();
683 int x = eSkin::getActive()->queryValue("rass_logo.pos.x", 0);
684 int y = eSkin::getActive()->queryValue("rass_logo.pos.y", 0);
685 rass_logo.hide();
686 rass_logo.move( ePoint( x, y ) );
687 rass_logo.resize( eSize( 50, 21 ) );
688 rass_logo.show();
690 rass_imode_active=0;
691 Decoder::displayIFrameFromFile("/tmp/RassLast.mvi");
694 void RDSTextDecoder::globalFocusHasChanged(const eWidget* newFocus)
696 if ( !sn ) // not running
697 return;
698 if ( newFocus )
700 wasVisible |= 8;
701 if (rds_text->isVisible())
703 wasVisible |= 1;
704 rds_text->hide();
706 if (rtp_text->isVisible())
708 wasVisible |= 2;
709 rtp_text->hide();
711 if (!rass_imode_active && rass_logo.isVisible())
713 wasVisible |= 4;
714 rass_logo.hide();
718 else
720 wasVisible &= ~8;
721 if (wasVisible & 1)
723 wasVisible &= ~1;
724 rds_text->show();
726 if (wasVisible & 2)
728 wasVisible &= ~2;
729 rtp_text->show();
731 if (wasVisible & 4)
733 wasVisible &= ~4;
734 rass_logo.show();
739 RassInteractivemode::RassInteractivemode()
740 :eWidget(0,1), active_slide(0), active_slide_sub(-1)
742 gFont rds_font = eSkin::getActive()->queryFont("rass");
744 cmove(ePoint(50,201)); cresize(eSize(100,254));
745 setProperty("backgroundColor","rass_bg");
746 setProperty("foregroundColor","rass_fg");
747 setFont(rds_font);
749 int i=0;
750 char c[3];
752 while (i < 10)
754 sprintf(c,"%01d",i);
755 rass_page[i]=new eLabel(this);
756 rass_page[i]->setText(c);
757 rass_page[i]->move(ePoint(5, (25*i)+4));
758 rass_page[i]->resize(eSize(70, 25));
759 i++;
762 sprintf(c,"%01d >",0); //set marker
763 rass_page[0]->setText(c);
765 rass_pm1 = eSkin::getActive()->queryImage("rass_page1");
766 rass_pm2 = eSkin::getActive()->queryImage("rass_page2");
767 rass_pm3 = eSkin::getActive()->queryImage("rass_page3");
768 rass_pm4 = eSkin::getActive()->queryImage("rass_page4");
770 rass_page_sub[0]=new eLabel(this);
771 rass_page_sub[0]->setText("Index");
772 rass_page_sub[0]->move( ePoint(36, 4));
773 rass_page_sub[0]->resize( eSize( 50, 25 ) );
775 i=1;
776 while (i < 10)
778 rass_page_sub[i]=new eLabel(this);
779 update_avail(i);
780 rass_page_sub[i]->move( ePoint(35, (25*i)+6));
781 rass_page_sub[i]->resize( eSize( 36, 20 ) );
782 rass_page_sub[i]->pixmap_position = ePoint(0,0);
783 rass_page_sub[i]->setBlitFlags( BF_ALPHATEST );
784 i++;
787 addActionMap(&i_shortcutActions->map);
788 addActionMap(&i_cursorActions->map);
791 RassInteractivemode::~RassInteractivemode()
793 int i=0;
794 while (i < 10)
796 delete rass_page[i];
797 if (i)
798 delete rass_page_sub[i];
799 ++i;
804 void RassInteractivemode::sel_entry(int val)
806 char fname[50];
807 int file[4];
808 int i=1;
809 int tmp=0;
811 while(i < 10) // update availability
812 update_avail(i++);
814 i=0;
816 if (val == 0xFF) // up
818 val=active_slide;
819 while (tmp == 0)
821 if (--val < 0)
822 val=9;
823 tmp=check_avail(val);
827 if (val == 0xFE) // down
829 val=active_slide;
830 while (tmp == 0)
832 if (++val > 9)
833 val=0;
834 tmp=check_avail(val);
838 if (val == 0xFD) // left
840 val=active_slide;
841 i=3;
844 if (val == 0xFC) // right
845 val=active_slide;
847 sprintf(fname,"/tmp/Rass%04d.mvi",val*1000);
848 file[0]=check_file(fname);
849 sprintf(fname,"/tmp/Rass%04d.mvi",val*1100);
850 file[1]=check_file(fname);
851 sprintf(fname,"/tmp/Rass%04d.mvi",val*1110);
852 file[2]=check_file(fname);
853 sprintf(fname,"/tmp/Rass%04d.mvi",val*1111);
854 file[3]=check_file(fname);
856 if ((file[0] + file[1] + file[2] + file[3]) == 0)
857 return;
859 if (active_slide != val)
861 active_slide_sub=-1;
863 char c[3];
864 sprintf(c,"%01d",active_slide);
865 rass_page[active_slide]->setText(c);
866 sprintf(c,"%01d >",val);
867 rass_page[val]->setText(c);
870 tmp=active_slide_sub;
871 active_slide_sub=-1;
873 if (i == 0) //next subslide (right)
875 while(i < 4)
877 if (active_slide_sub == -1 && file[i] == 1)
878 active_slide_sub=i;
879 if (file[i] == 1 && i > tmp)
881 active_slide_sub=i;
882 break;
884 i++;
887 else //last subslide (left)
889 while(i >= 0)
891 if (active_slide_sub == -1 && file[i] == 1)
892 active_slide_sub=i;
893 if (file[i] == 1 && i < tmp)
895 active_slide_sub=i;
896 break;
898 i--;
901 active_slide=val;
903 switch(active_slide_sub)
905 case 0:
906 val=active_slide*1000;
907 break;
908 case 1:
909 val=active_slide*1100;
910 break;
911 case 2:
912 val=active_slide*1110;
913 break;
914 case 3:
915 val=active_slide*1111;
916 break;
917 default:
918 return;
921 sprintf(fname,"/tmp/Rass%04d.mvi",val);
922 Decoder::displayIFrameFromFile(fname);
925 void RassInteractivemode::update_avail(int i)
927 if (i < 1 || i > 9)
928 return;
929 switch(check_avail(i))
931 case 1:
932 rass_page_sub[i]->setPixmap(rass_pm1);
933 break;
934 case 2:
935 rass_page_sub[i]->setPixmap(rass_pm2);
936 break;
937 case 3:
938 rass_page_sub[i]->setPixmap(rass_pm3);
939 break;
940 case 4:
941 rass_page_sub[i]->setPixmap(rass_pm4);
942 break;
943 default:
944 rass_page_sub[i]->setPixmap(0);
948 int RassInteractivemode::check_file(char* fname)
950 FILE * f= fopen (fname,"r");
951 if (!f)
952 return 0;
953 else
955 fclose(f);
956 return 1;
960 int RassInteractivemode::check_avail(int page)
962 if (page == 0)
963 return 1;
965 char fname[50];
966 int tmp=0;
968 sprintf(fname,"/tmp/Rass%04d.mvi",page*1000);
969 tmp+=check_file(fname);
970 sprintf(fname,"/tmp/Rass%04d.mvi",page*1100);
971 tmp+=check_file(fname);
972 sprintf(fname,"/tmp/Rass%04d.mvi",page*1110);
973 tmp+=check_file(fname);
974 sprintf(fname,"/tmp/Rass%04d.mvi",page*1111);
975 tmp+=check_file(fname);
977 return tmp;
980 int RassInteractivemode::eventHandler( const eWidgetEvent &e )
982 switch( e.type )
984 case eWidgetEvent::evtAction:
985 if ( e.action == &i_shortcutActions->number0)
986 sel_entry(0);
987 else if ( e.action == &i_shortcutActions->number1)
988 sel_entry(1);
989 else if ( e.action == &i_shortcutActions->number2)
990 sel_entry(2);
991 else if ( e.action == &i_shortcutActions->number3)
992 sel_entry(3);
993 else if ( e.action == &i_shortcutActions->number4)
994 sel_entry(4);
995 else if ( e.action == &i_shortcutActions->number5)
996 sel_entry(5);
997 else if ( e.action == &i_shortcutActions->number6)
998 sel_entry(6);
999 else if ( e.action == &i_shortcutActions->number7)
1000 sel_entry(7);
1001 else if ( e.action == &i_shortcutActions->number8)
1002 sel_entry(8);
1003 else if ( e.action == &i_shortcutActions->number9)
1004 sel_entry(9);
1005 else if ( e.action == &i_cursorActions->up)
1006 sel_entry(0xFF);
1007 else if ( e.action == &i_cursorActions->down)
1008 sel_entry(0xFE);
1009 else if ( e.action == &i_cursorActions->left)
1010 sel_entry(0xFD);
1011 else if ( e.action == &i_cursorActions->right)
1012 sel_entry(0xFC);
1013 else if ( e.action == &i_cursorActions->cancel)
1014 close(0);
1015 else
1016 break;
1017 return 1;
1018 default:
1019 break;
1021 return eWidget::eventHandler(e);