MS_DLG.C
上传用户:super_houu
上传日期:2008-09-21
资源大小:4099k
文件大小:29k
源码类别:

DVD

开发平台:

Others

  1. /* **************************************************************************************
  2.  *  Copyright (c) 2002 ZORAN Corporation, All Rights Reserved
  3.  *  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF ZORAN CORPORATION
  4.  *
  5.  *  File: $Workfile: MS_DLG.C $             
  6.  *
  7.  * Description:
  8.  * ============
  9.  * Manipulation of menu dialogue
  10.  * 
  11.  * Log:
  12.  * ====
  13.  * $Revision: 14 $
  14.  * Last Modified by $Author: Fwang $ at $Modtime: 2/02/04 2:04p $ 
  15.  ****************************************************************************************
  16.  * Updates:
  17.  ****************************************************************************************
  18.  * $Log: /I76/I76_Common/I76_Reference/UI/Menu_sys/MS_DLG.C $
  19.  * 
  20.  * 14    2/02/04 2:26p Fwang
  21.  * Add OSD_CHECK_PALETTE. Check osd palette before turn on OSD. Rewrite
  22.  * osd palette if error detected.
  23.  * 
  24.  * 13    10/28/03 10:09a Leslie
  25.  * clean up the MS_remove_item_rapidly
  26.  * 
  27.  * 12    8/29/03 11:55a Leonh
  28.  * Clean up clips type and disc type because now add DVD ROM for clips
  29.  * 
  30.  * 11    03-07-24 10:38 Frankm
  31.  * Modify MS_remove_item_rapidly().
  32.  * 
  33.  * 10    03-07-11 15:41 Leonm
  34.  * 
  35.  * 9     03-02-19 15:10 Rogerl
  36.  * Add MS_DIALOG_CYCLIC_SELECTION support
  37.  * 
  38.  * 8     10/30/02 17:49 Rond
  39.  * 
  40.  * 13    5/22/02 8:52a Tomasp
  41.  * Changed include paths.
  42.  * 
  43.  * 12    10/05/02 14:46 Nirm
  44.  * - Corrected debug-messages.
  45.  * 
  46.  * 11    23/04/02 9:39 Nirm
  47.  * - Added dependency in "Config.h".
  48.  * 
  49.  * 10    11/03/02 12:41 Nirm
  50.  * Debug message in case of memory allocation failure.
  51.  * 
  52.  * 9     2/27/02 7:02a Tomasp
  53.  * Changed get_blk/rel_blk to malloc,free.
  54.  * 
  55.  * 8     30/01/02 20:47 Nirm
  56.  * Compilation-Warnings removal.
  57.  * 
  58.  * 6     16/01/02 8:57 Nirm
  59.  * Fixed debug-messages.
  60.  * 
  61.  * 5     13/01/02 16:34 Atai
  62.  * Remove old Defines
  63.  * 
  64.  * 4     9/01/02 18:23 Nirm
  65.  * Corrected Include-Paths.
  66.  * 
  67.  * 3     30/12/01 9:59 Atai
  68.  * remove warning
  69.  * 
  70.  * 2     25/12/01 10:34 Atai
  71.  * Code cleaning
  72.  **************************************************************************************** */
  73. #include "Config.h" // Global Configuration - do not remove!
  74. #ifdef _DEBUG
  75. #include "DebugDbgMain.h"
  76. #undef IFTRACE
  77. #define IFTRACE if (gTraceMenu)
  78. #endif //_DEBUG
  79. #include <stdio.h>
  80. #include <stdlib.h>
  81. #include "Includesysdefs.h"
  82. #include "PlaycoreCoremaincoregdef.h"
  83. #include "UIMenu_Sysms_wdgt.h"
  84. #include "UIMenu_Sysms_lib.h"
  85. #include "UIMenu_Sysosd_drv.h"
  86. #include "decoderOSDLayou.h"
  87. //START of customer specific include files
  88. #include "customer.h"
  89. //END of customer specific include files
  90. #define ROM_START 0x4000
  91. #define MK_FP(seg,ofs) ((void __seg *)(seg) + (void __near *)(ofs))
  92. #define IS_IN_ROM(_fp_) ( (void huge *)(_fp_) >= (void huge *) MK_FP(ROM_START,0) )
  93. //
  94. // Delete an MS_DIALOG
  95. //
  96. // -- Calls the close functions for all sub-dialogs
  97. //   and for the dialog ( or screen ) itself.
  98. //
  99. // -- Destroys the widget list
  100. //
  101. static void delete(MS_WIDGET *widget)
  102. {
  103. WIDGET_LIST_ITEM *curr = ((MS_DIALOG *)widget)->pwli_widget_list;
  104. WIDGET_LIST_ITEM *next;
  105. /* Turn Off OSD when closing menu */
  106. if (widget->parent == NO_PARENT)
  107. {
  108. OSD_TurnOff();
  109. }
  110. // Free the widget list
  111. while (curr)
  112. {
  113. // Remember the next pointer before we dispose its containing item
  114. next = curr->next;
  115. // If the current item's widget is a dialog, call its close function.
  116. // This should free the contained widgets
  117. if (MS_IS_DIALOG_BOX(curr->widget))
  118. {
  119. // Permit null close functions
  120. if ( ((MS_DIALOG *) curr->widget)->on_close )
  121. ((MS_DIALOG *)curr->widget)->on_close();
  122. }
  123. // Dispose the list item (created when the widget was added)
  124. // Note this doesn't dispose the widget itself
  125. free(curr);
  126. // On to the next list item
  127. curr = next;
  128. }
  129. // Support nested dialogs
  130. #ifdef D_MS_EXTENSIONS
  131. #else
  132. // If this is the top level
  133. if (widget->parent == NO_PARENT)
  134. #endif // D_MS_EXTENSIONS
  135. {
  136. // Call the close function
  137. // Permit null close functions
  138. if ( ((MS_DIALOG *) widget)->on_close )
  139. ((MS_DIALOG *)widget)->on_close();
  140. }
  141. }
  142. // Change the focus of a dialog to the specified widget
  143. void MS_change_focus(MS_DIALOG *pDialog, MS_WIDGET *pWidget)
  144. {
  145.   WIDGET_LIST_ITEM *pwli;
  146.   
  147. #ifdef D_MS_EXTENSIONS
  148. #ifdef _DEBUG
  149.   WIDGET_LIST_ITEM *pwli_prev_focused = pDialog->pwli_focus;
  150. #endif // _DEBUG
  151. #else
  152.   pDialog->pwli_prev_focused = pDialog->pwli_focus;
  153. #endif // D_MS_EXTENSIONS
  154. // ZORAN CDE0404 >>>
  155.   pwli = pDialog->pwli_widget_list;
  156.   while ( pwli )
  157.   {
  158. if ( pwli->widget == pWidget )
  159. {
  160.   pDialog->pwli_focus = pwli;
  161.   break;
  162. }
  163. else
  164.   pwli = pwli->next;
  165.   }
  166. #ifdef _DEBUG
  167. #ifdef D_MS_EXTENSIONS
  168.   if ( pwli_prev_focused == pDialog->pwli_focus )
  169. #else
  170.   if ( pDialog->pwli_prev_focused == pDialog->pwli_focus )
  171. #endif // D_MS_EXTENSIONS
  172.   {
  173. dbg_printf(("WARNING: MS_change_focus(): New is the same as the previous focused item!n"));
  174.   }
  175. #endif // _DEBUG
  176. }
  177. static WIDGET_LIST_ITEM *first_selectable( MS_DIALOG *pDialog )
  178. {
  179.   WIDGET_LIST_ITEM *pwli = pDialog->pwli_widget_list;
  180.   while ( pwli )
  181.   {
  182. if ( MS_IS_SELECTABLE(pwli->widget) )
  183.   break;
  184. else
  185.   pwli = pwli->next;
  186.   }
  187.   return pwli;
  188. }
  189. static WIDGET_LIST_ITEM *last_selectable( MS_DIALOG *pDialog )
  190. {
  191.   WIDGET_LIST_ITEM *pwli = pDialog->pwli_widget_list;
  192.   WIDGET_LIST_ITEM *pwliTentative = NULL;
  193.   while ( pwli )
  194.   {
  195. if ( MS_IS_SELECTABLE(pwli->widget) )
  196.   pwliTentative = pwli;
  197. pwli = pwli->next;
  198.   }
  199.   return pwliTentative;
  200. }
  201. // Change the focus of a dialog to the specified widget list item
  202. static void change_focus_wli(MS_DIALOG *pDialog, WIDGET_LIST_ITEM *pwliNewFocus, MS_UOP uop)
  203. {
  204.   WIDGET_LIST_ITEM *pwliFocus = pDialog->pwli_focus;
  205.   MS_WIDGET *pmswFocus = NULL;
  206.   MS_DIALOG *pmsd = NULL;
  207.   MS_WIDGET *widget = NULL;
  208.   MS_DIALOG *pmsdOrigin = NULL;
  209.   if ( pwliFocus )
  210.   {
  211. widget = pwliFocus->widget;
  212. if ( MS_IS_DIALOG_BOX(widget) )
  213. {
  214.   pmsd = pDialog;
  215.   while ( pmsd )
  216.   {
  217. // save current focus
  218. pwliFocus = pmsd->pwli_focus;
  219. #ifdef D_MS_EXTENSIONS
  220. #else
  221.   pmsd->pwli_prev_focused = pwliFocus;
  222. #endif // D_MS_EXTENSIONS
  223. // clear current focus
  224. pmsd->pwli_focus = NULL;
  225. // clear focus in all sub-dialogs
  226. pmsd = NULL;
  227. if ( pwliFocus )
  228. {
  229.   pmswFocus = pwliFocus->widget;
  230.   if ( MS_IS_DIALOG_BOX(pmswFocus) )
  231. pmsd = (MS_DIALOG *) pmswFocus;
  232. } // if ( pwliFocus )
  233.   } // while ( pmsd )
  234. } // if ( MS_IS_DIALOG_BOX(widget) )
  235. else
  236. {
  237.   pDialog->pwli_focus = NULL;
  238. } // if ( MS_IS_DIALOG_BOX(widget) )
  239. OSD_SetOrigin( (MS_WIDGET *) pDialog );
  240. MS_display( widget );
  241. #ifdef D_MS_EXTENSIONS
  242. MS_CALL_USER_OP( widget, MS_UOP_EXT_HELP, !C_FOCUSED );
  243. #endif
  244.   } // if ( pwliFocus )
  245.   pDialog->pwli_focus = pwliNewFocus;
  246.   if ( pwliNewFocus )
  247.   {
  248. pmsdOrigin = pDialog;
  249. widget = pwliNewFocus->widget;
  250. // Set the focus in all sub-dialogs
  251. if ( MS_IS_DIALOG_BOX(pwliNewFocus->widget) )
  252. {
  253.   pmsd = (MS_DIALOG*)pwliNewFocus->widget;
  254.   while ( pmsd )
  255.   {
  256. if ( (uop == MS_UOP_RIGHT) || (uop == MS_UOP_DOWN) )
  257. {
  258.   pwliNewFocus = first_selectable( pmsd );
  259. }
  260. else
  261. {
  262.   pwliNewFocus = last_selectable( pmsd );
  263. } // if ( (uop == MS_UOP_RIGHT) || (uop == MS_UOP_DOWN) )
  264.   #ifdef D_MS_EXTENSIONS
  265.   #else
  266. pmsd->pwli_prev_focused = pmsd->pwli_focus;
  267.   #endif // D_MS_EXTENSIONS
  268. // Set the focus
  269. pmsd->pwli_focus = pwliNewFocus;
  270. // Proceed to next sub-dialog
  271. pmsd = NULL;
  272. if ( pwliNewFocus )
  273. {
  274.   pmswFocus = pwliNewFocus->widget;
  275.   if ( MS_IS_DIALOG_BOX(pmswFocus) )
  276. pmsd = (MS_DIALOG *) pmswFocus;
  277. } // if ( pwliNewFocus )
  278.   } // while ( pmsd )
  279. } // if ( MS_IS_DIALOG_BOX(pwliNewFocus->widget) ) 
  280. OSD_SetOrigin( (MS_WIDGET *) pmsdOrigin );
  281. MS_CALL_USER_OP( widget, MS_UOP_DISPLAY, C_FOCUSED );
  282. #ifdef D_MS_EXTENSIONS
  283. MS_CALL_USER_OP( widget, MS_UOP_EXT_HELP, C_FOCUSED );
  284. #endif // D_MS_EXTENSIONS
  285.   } // if ( pwliNewFocus != NULL )
  286. }
  287. //
  288. // Display a dialog and its contents
  289. //
  290. static int display(MS_WIDGET *widget)
  291. {
  292. MS_DIALOG *msDlg = (MS_DIALOG *) widget;
  293. WIDGET_LIST_ITEM *curr = msDlg->pwli_widget_list;
  294. #ifdef D_MS_EXTENSIONS
  295. char cFocus = !C_FOCUSED;
  296. if ( MS_IS_SELECTABLE(widget) &&
  297.   ( (msDlg->pwli_focus == NULL) || (/*MS_IS_GROUP(widget) && */MS_IS_HIGHLIGHT_AS_GROUP(widget)) ) &&
  298.   ( widget->parent->pwli_focus ) &&
  299.   ( widget->parent->pwli_focus->widget == msDlg )
  300. )
  301. cFocus = C_FOCUSED;
  302. #endif // D_MS_EXTENSIONS
  303. // Erase the dialog when appropriate
  304. if (!MS_HAS_NO_BACKGROUND(widget))
  305. {
  306. OSD_PutRect(widget->pos.x,
  307. widget->pos.y,
  308. widget->pos.w,
  309. widget->pos.h,
  310. // Highlight dialog when selectable and focused and has no focus
  311. #ifdef D_MS_EXTENSIONS
  312. BACK_COLOR(widget, cFocus));
  313. #else
  314. BG_COLOR(widget->color));
  315. #endif // D_MS_EXTENSIONS
  316. }
  317. OSD_SetOrigin(widget);
  318. while (curr)
  319. {
  320. OSD_SetOrigin(widget);
  321. curr->widget->user_op( curr->widget,
  322. MS_UOP_DISPLAY,
  323. //Highlight dialog when selectable and focused and has no focus
  324. #ifdef D_MS_EXTENSIONS
  325. (char)( ((cFocus == C_FOCUSED) || (curr == msDlg->pwli_focus)) ? C_FOCUSED : !C_FOCUSED) );
  326. #else
  327. (char)((curr == msDlg->pwli_focus) ? C_FOCUSED : !C_FOCUSED) );
  328. #endif // D_MS_EXTENSIONS
  329. curr = curr->next;
  330. }
  331. #ifdef D_MS_EXTENSIONS
  332. if ( msDlg->pwli_focus )
  333.   MS_CALL_USER_OP(msDlg->pwli_focus->widget, MS_UOP_EXT_HELP, C_FOCUSED );
  334. #endif // D_MS_EXTENSIONS
  335. return MS_UOP_NOP;
  336. }
  337. static WIDGET_LIST_ITEM *find_up( WIDGET_LIST_ITEM *curr, MS_DIALOG *dialog )
  338. {
  339.   int y = -1;
  340.   MS_WIDGET *loopWidget;
  341.   WIDGET_LIST_ITEM *candidate = NULL;
  342.   while ( curr->prev )
  343.   {
  344. curr = curr->prev;
  345. loopWidget = curr->widget;
  346. if ( MS_IS_SELECTABLE(loopWidget) && (loopWidget->pos.y < dialog->pwli_focus->widget->pos.y))
  347. {
  348.   if (y == -1)
  349.   {
  350. // Found the line above
  351. y = loopWidget->pos.y;
  352.   }
  353.   
  354.   if (y == loopWidget->pos.y)
  355.   {
  356. if ( (loopWidget->pos.x < dialog->pwli_focus->widget->pos.x) && candidate )  //FW0317 Change >= to > for moving in the same column
  357. {
  358.   // Found the above (left) widget
  359.   break;
  360. }
  361. else
  362. {
  363.   candidate = curr;
  364. }
  365.   }
  366.   else
  367.   {
  368. // No more widgets in the above lines
  369. break;
  370.   }
  371. }
  372.   }
  373.   return ( y == -1 ? NULL : candidate );
  374. }
  375. static WIDGET_LIST_ITEM *find_down( WIDGET_LIST_ITEM *curr, MS_DIALOG *dialog )
  376. {
  377.   int y = -1;
  378.   MS_WIDGET *loopWidget;
  379.   WIDGET_LIST_ITEM *candidate = NULL;
  380.   // Look for the widget below the focused widget
  381.   while (curr->next)
  382.   {
  383. curr = curr->next;
  384. loopWidget = curr->widget;
  385. if ( MS_IS_SELECTABLE(loopWidget) && (loopWidget->pos.y > dialog->pwli_focus->widget->pos.y) )
  386. {
  387.   if (y == -1)
  388.   {
  389. // Found the line below
  390. y = loopWidget->pos.y;
  391.   }
  392.   if (y == loopWidget->pos.y)
  393.   {
  394. if ( (loopWidget->pos.x > dialog->pwli_focus->widget->pos.x) && candidate )  //FW0317 Change >= to > for moving in the same column
  395. {
  396.   // Found a widget to the right
  397.   break;
  398. }
  399. else
  400.   candidate = curr;
  401. }
  402.   }
  403.   else
  404.   {
  405. // No more widgets in the line below
  406. break;
  407.   }
  408. }
  409.   }
  410.   return ( y == -1 ? NULL : candidate );
  411. }
  412. MS_UOP dialog_user_op(MS_WIDGET *widget,MS_UOP uop, char param) 
  413. {
  414. MS_UOP dialog_uop =  uop;
  415. MS_DIALOG *dialog = (MS_DIALOG *)widget;
  416. MS_WIDGET *focusWidget;
  417. WIDGET_LIST_ITEM *curr = NULL;
  418. BOOL bFound = FALSE;
  419. // Thes uops are always handled in the standard way
  420. switch (uop)
  421. {
  422.   case MS_UOP_DELETE:
  423.   delete(widget);
  424.   if (widget->parent == NO_PARENT)
  425.   {
  426.   OSD_TurnOff();
  427.   }
  428.   return MS_UOP_NOP;
  429.   case MS_UOP_DISPLAY:
  430.   return display(widget);
  431. #ifdef D_USE_RETURN_IN_MENUS
  432.   case MS_UOP_RETURN:
  433.   if (( widget->parent == NO_PARENT ))//LeonH_0829_2003_a:Clear up
  434.   {
  435.   MS_return_to_menu();
  436.   return MS_UOP_NOP;
  437.   }
  438.   break;
  439. #endif // D_USE_RETURN_IN_MENUS
  440. }
  441. curr = dialog->pwli_focus;
  442. if ( curr == NULL )
  443. {
  444. return uop;
  445. }
  446. focusWidget = curr->widget;
  447. dialog_uop = focusWidget->user_op(focusWidget, uop, param);
  448. #ifdef D_MS_EXTENSIONS
  449. /// Reassign curr in case user_op changed the focus
  450. if ( curr != dialog->pwli_focus )
  451. {
  452. #ifdef NO_C_STDLIB
  453. dbg_printf(("INFO: dialog_user_op(): focus widget's user_op changed the focus!n"));
  454. #endif
  455. curr = dialog->pwli_focus;
  456. }
  457. #endif // D_MS_EXTENSIONS
  458. switch (dialog_uop)
  459. {
  460. case MS_UOP_ENTER:
  461. case MS_UOP_NOP:
  462. return MS_UOP_NOP;
  463. case MS_UOP_UP:
  464. curr = find_up( curr, dialog );
  465. if ( curr == NULL )
  466. {
  467. // No widget above
  468. dbg_printf(("WARNING: dialog_user_op(): Cannot move upn"));
  469. if ( MS_IS_CLOSE_ON_UP(dialog) )
  470. {
  471. MS_remove_item((MS_WIDGET *) dialog);
  472. return MS_UOP_NOP;
  473. }
  474. #ifdef DIALOG_CYCLIC_SELECTION
  475. if ( MS_IS_DIALOG_CYCLIC_SELECTION(dialog) )
  476. {
  477. dbg_printf(("WARNING: dialog_user_op(): Cyclic operation to last selectable n"));
  478.    curr = last_selectable( dialog );
  479.    break;
  480. }
  481. #endif
  482. curr = dialog->pwli_focus;
  483. if ( ((MS_WIDGET *) dialog)->parent == NO_PARENT )
  484.   uop = MS_UOP_NOP;
  485. }
  486. break;
  487. case MS_UOP_DOWN:
  488. curr = find_down( curr, dialog );
  489. if ( curr == NULL )
  490. {
  491. // No widget below
  492. dbg_printf(("WARNING: dialog_user_op(): Cannot move downn"));
  493. #ifdef DIALOG_CYCLIC_SELECTION
  494. if ( MS_IS_DIALOG_CYCLIC_SELECTION(dialog) )
  495. {
  496. dbg_printf(("WARNING: dialog_user_op(): Cyclic operation to first selectable n"));
  497.    curr = first_selectable( dialog );
  498.    break;
  499. }
  500. #endif
  501. curr = dialog->pwli_focus;
  502. if ( ((MS_WIDGET *) dialog)->parent == NO_PARENT )
  503.   uop = MS_UOP_NOP;
  504. }
  505. break;
  506. case MS_UOP_LEFT:
  507. while (curr->prev)
  508. {
  509. curr = curr->prev;
  510. if (MS_IS_SELECTABLE(curr->widget))
  511. {
  512. bFound = TRUE;
  513. break;
  514. }
  515. }
  516. if ( !bFound )
  517. {
  518. dbg_printf(("WARNING: dialog_user_op(): Can't move leftn"));
  519. #ifdef D_MS_EXTENSIONS
  520. if ( MS_IS_DIALOG_WRAP_LR(dialog) )
  521. {
  522.   curr = last_selectable( dialog );
  523. }
  524. else
  525. {
  526.   curr = dialog->pwli_focus;
  527.   if ( (((MS_WIDGET *) dialog)->parent == NO_PARENT) ||
  528. ( MS_IS_CLOSE_ON_UP(dialog) ) )
  529. uop = MS_UOP_NOP;
  530. }
  531. #else // D_MS_EXTENSIONS
  532. #ifdef DIALOG_CYCLIC_SELECTION
  533. if ( MS_IS_DIALOG_CYCLIC_SELECTION(dialog) )
  534. {
  535. dbg_printf(("WARNING: dialog_user_op(): Cyclic operation to last selectable n"));
  536.    curr = last_selectable( dialog );
  537.    break;
  538. }
  539. #endif
  540. curr = dialog->pwli_focus;
  541. if ( (((MS_WIDGET *) dialog)->parent == NO_PARENT) ||
  542.   ( MS_IS_CLOSE_ON_UP(dialog) ) )
  543.   uop = MS_UOP_NOP;
  544. #endif // D_MS_EXTENSIONS
  545. }
  546. break;
  547. case MS_UOP_RIGHT:
  548. while (curr->next)
  549. {
  550. curr = curr->next;
  551. if (MS_IS_SELECTABLE(curr->widget))
  552. {
  553. bFound = TRUE;
  554. break;
  555. }
  556. }
  557. if ( !bFound )
  558. {
  559. dbg_printf(("WARNING: dialog_user_op(): Can't move rightn"));
  560. #ifdef D_MS_EXTENSIONS
  561. if ( MS_IS_DIALOG_WRAP_LR( dialog ) )
  562. {
  563.   curr = first_selectable( dialog );
  564. }
  565. else
  566. {
  567.   curr = dialog->pwli_focus;
  568.   if ( (((MS_WIDGET *) dialog)->parent == NO_PARENT) ||
  569. ( MS_IS_CLOSE_ON_UP(dialog) ) )
  570. uop = MS_UOP_NOP;
  571. }
  572. #else // D_MS_EXTENSIONS
  573. #ifdef DIALOG_CYCLIC_SELECTION
  574. if ( MS_IS_DIALOG_CYCLIC_SELECTION(dialog) )
  575. {
  576. dbg_printf(("WARNING: dialog_user_op(): Cyclic operation to first selectable n"));
  577.    curr = first_selectable( dialog );
  578.    break;
  579. }
  580. #endif
  581. curr = dialog->pwli_focus;
  582. if ( (((MS_WIDGET *) dialog)->parent == NO_PARENT) ||
  583.   ( MS_IS_CLOSE_ON_UP(dialog) ) )
  584.   uop = MS_UOP_NOP;
  585. #endif // D_MS_EXTENSIONS
  586. }
  587. break;
  588. }
  589. if (curr != dialog->pwli_focus)
  590. {
  591. // Focus changed
  592. change_focus_wli( dialog, curr, dialog_uop );
  593. uop = MS_UOP_NOP;
  594. }
  595. return uop;
  596. }
  597. //
  598. // Add a widget to a dialog and set the focus if specified
  599. //
  600. // -- Create a widget list item for the widget
  601. // -- Change the focus to the item, if specified
  602. //
  603. void MS_add_item(MS_DIALOG *dialog, MS_WIDGET *widget, char focus)
  604. {
  605. WIDGET_LIST_ITEM *curr;
  606. WIDGET_LIST_ITEM *last;
  607. WIDGET_LIST_ITEM *new_list_item;
  608. dbg_printf(("malloc WIDGET_LIST_ITEMn"));
  609. // Create a widget_list_item for the widget
  610. new_list_item = malloc(sizeof(WIDGET_LIST_ITEM));
  611. // Set the list item's widget member
  612. new_list_item->widget = widget;
  613. // Change the dialog's focus, if specified
  614. if ( focus == C_FOCUSED )
  615. {
  616. #ifdef D_MS_EXTENSIONS
  617. #else
  618. dialog->pwli_prev_focused = dialog->pwli_focus;
  619. #endif // D_MS_EXTENSIONS
  620. dialog->pwli_focus = new_list_item;
  621. }
  622. // Initialize last and current widget list items for insertion
  623. // to the beginning of the list
  624. last = curr = dialog->pwli_widget_list;
  625. if ( curr == NULL )
  626. {
  627. // List was empty:
  628. // -- Put the new item at the beginning of the list
  629. dialog->pwli_widget_list = new_list_item;
  630. new_list_item->next = new_list_item->prev = curr;
  631. // REMINDER may be responsible for wrong background color (0)
  632. // Otherwise, this may have been put here to distinguish screens from dialogs
  633. // REMINDER This might have been a way of testing whether the item was CONST
  634. // What happens if you assign a value to a ROM location? (hopefully, the location just won't change )
  635. // if (widget->parent != NO_PARENT)
  636. {
  637.          if (!IS_IN_ROM(widget))
  638. widget->parent = dialog;
  639. }
  640. return;
  641. }
  642. // Not the first item:
  643. // -- Find the correct place to insert the item
  644. //   ( before first item with bigger line number, or on same line to the right )
  645. //
  646. while (last)
  647. {
  648. curr = last;
  649. if ( (curr->widget->pos.y > widget->pos.y) || 
  650. ((curr->widget->pos.y == widget->pos.y) && (curr->widget->pos.x > widget->pos.x)) )
  651. {
  652. // link to previous item
  653. new_list_item->prev = curr->prev;
  654. // link to next item
  655. new_list_item->next = curr;
  656. if (curr->prev)
  657. {
  658. // Not the first item
  659. // link as previous item's next item
  660. curr->prev->next = new_list_item;
  661. // link as next item's previous item
  662. curr->prev = new_list_item;
  663. }
  664. else
  665. {
  666. // First item
  667. // No previous item
  668. new_list_item->prev = 0;
  669. // Next item is the former first item
  670. new_list_item->next = dialog->pwli_widget_list;
  671. // Link former first item to new item
  672. dialog->pwli_widget_list->prev = new_list_item;
  673. // Make the new item the first in the list
  674. dialog->pwli_widget_list = new_list_item;
  675. }
  676. // REMINDER may be responsible for wrong background color (0)
  677. // Otherwise, this may have been put here to distinguish screens from dialogs
  678. // if (widget->parent != NO_PARENT)
  679. {
  680.          if (!IS_IN_ROM(widget))
  681. widget->parent = dialog;
  682. }
  683. return;
  684. }
  685. // Advance to next item
  686. last = curr->next;
  687. }
  688. // New item should be the last item in the list
  689. // No next item
  690. new_list_item->next = 0;
  691. // Link as previous item's next item
  692. curr->next = new_list_item;
  693. // Link to previous item
  694. new_list_item->prev = curr;
  695. // REMINDER may be responsible for wrong background color (0)
  696. // Otherwise, this may have been put here to distinguish screens from dialogs
  697. // if (widget->parent != NO_PARENT)
  698. {
  699.          if (!IS_IN_ROM(widget))
  700.   widget->parent = dialog;
  701. }
  702. return;
  703. }
  704. void MS_remove_item_rapidly(MS_DIALOG *dialog, MS_WIDGET *widget)
  705. {
  706. WIDGET_LIST_ITEM *curr;
  707. if ( dialog == NO_PARENT )
  708. {
  709. dbg_printf(("WARNING: MS_remove_item_rapidly(): Item has no parent!n"));
  710. return;
  711. }
  712. if ( dialog->pwli_focus->widget == widget ) {
  713. #ifdef D_MS_EXTENSIONS
  714.   // Clear the focus here
  715.   // The focus item shouldn't be removed while the dialog is active
  716.   // without resetting the focus afterward
  717.   dialog->pwli_focus = NULL;
  718. #else
  719.   dialog->pwli_focus = dialog->pwli_prev_focused;
  720. #endif // D_MS_EXTENSIONS
  721. }
  722. curr = dialog->pwli_widget_list;
  723. while (curr)
  724. {
  725. if (curr->widget == widget)
  726. {
  727. if (!curr->prev)
  728. {
  729. // First item
  730. dialog->pwli_widget_list = curr->next;
  731. }
  732. else
  733. {
  734. curr->prev->next = curr->next;
  735. }
  736. if (curr->next)
  737. {
  738. // Removed item is not the last item
  739. curr->next->prev = curr->prev;
  740. }
  741. // Item has been de-linked, so
  742. // free it
  743. free(curr);
  744. return;
  745. }
  746. curr = curr->next;
  747. }
  748. dbg_printf(("WARNING: MS_remove_item_rapidly(): Item not found in the listn"));
  749. // Item not found in the list
  750. return;
  751. }
  752. void MS_delete(MS_WIDGET *widget)
  753. {
  754. widget->user_op(widget,MS_UOP_DELETE,0);
  755. free(widget);
  756. }
  757. //
  758. // Hide a widget
  759. //
  760. // This just erases the widget's rectangle.
  761. // The menu system doesn't attempt to remember that the widget is hidden.
  762. //
  763. void MS_hide(MS_WIDGET *widget,MS_DIALOG *parent)
  764. {
  765. OSD_PutRect(widget->pos.x, widget->pos.y, widget->pos.w, widget->pos.h,
  766.   BG_COLOR(parent->widget.color));
  767. }
  768. //Implement YesNo dialog for Password Menu
  769. #ifdef ZS5XX_PASSWORD
  770. // Remove a widget from its parent's widget list
  771. //
  772. // Return 1 if the item was found and removed
  773. // Return 0 if the item wasn't found
  774. //
  775. // REMINDER Don't call this from the widget's close function
  776. //
  777. int MS_detach_item(MS_WIDGET *widget)
  778. {
  779. WIDGET_LIST_ITEM *curr;
  780. MS_DIALOG *dialog = widget->parent;
  781. if ( dialog == NO_PARENT )
  782. {
  783. dbg_printf(("WARNING: MS_detach_item(): Item has no parent!n"));
  784. return 0;
  785. }
  786. {
  787.   if ( dialog->pwli_focus->widget == widget )
  788. #ifdef D_MS_EXTENSIONS
  789.   // Clear the focus here
  790.   // The focus item shouldn't be removed while the dialog is active
  791.   // without resetting the focus afterward
  792.   dialog->pwli_focus = NULL;
  793. #else
  794.   dialog->pwli_focus = dialog->pwli_prev_focused;
  795. #endif // D_MS_EXTENSIONS
  796. }
  797. curr = dialog->pwli_widget_list;
  798. while (curr)
  799. {
  800. if (curr->widget == widget)
  801. {
  802. if (!curr->prev)
  803. {
  804. WIDGET_LIST_ITEM *next = curr->next;
  805. // First item
  806. dialog->pwli_widget_list = next;
  807. }
  808. else
  809. {
  810. curr->prev->next = curr->next;
  811. }
  812. if (curr->next)
  813. {
  814. WIDGET_LIST_ITEM *prev = curr->prev;
  815. // Removed item is not the last item
  816. curr->next->prev = prev;
  817. }
  818. // Item has been de-linked, so
  819. // free it
  820. free(curr);
  821. if (widget->parent != NO_PARENT)
  822. {
  823. OSD_SetOrigin((MS_WIDGET *)widget->parent);
  824. }
  825. OSD_PutRect(widget->pos.x,widget->pos.y,widget->pos.w,widget->pos.h,BG_COLOR(widget->parent->widget.color));
  826. // Item is in a dialog or screen
  827. if (widget->parent != NO_PARENT)
  828. {
  829. MS_refresh(widget->parent);
  830. #ifndef ZS5XX //For ZS5, do not execute the following line.
  831. widget->parent = NO_PARENT;
  832. #endif //ZS5XX
  833. }
  834. return 1;
  835. }
  836. curr = curr->next;
  837. }
  838. dbg_printf(("WARNING: MS_detach_item(): Item not found in the listn"));
  839. // Item not found in the list
  840. return 0;
  841. }
  842. #define CALL_ON_CLOSE(_on_close_) if ( _on_close_ ) _on_close_()
  843. int MS_remove_item(MS_WIDGET *widget)
  844. {
  845. int iReturn = MS_detach_item(widget);
  846. if ( iReturn )
  847. {
  848. if (MS_IS_DIALOG_BOX(widget))
  849. {
  850. CALL_ON_CLOSE(((MS_DIALOG *)widget)->on_close);
  851. }
  852. }
  853. return iReturn;
  854. }
  855. #else // ZS5XX_PASSWORD
  856. // Remove a widget from its parent's widget list
  857. // if the item is a dialog, call its close function
  858. //
  859. // Return 1 if the item was found and removed
  860. // Return 0 if the item wasn't found
  861. //
  862. // REMINDER Don't call this from the widget's close function
  863. //
  864. int MS_remove_item(MS_WIDGET *widget)
  865. {
  866. WIDGET_LIST_ITEM *curr;
  867. MS_DIALOG *dialog = widget->parent;
  868. if ( dialog == NO_PARENT )
  869. {
  870. dbg_printf(("WARNING: MS_remove_item(): Item has no parent!n"));
  871. return 0;
  872. }
  873. if ( dialog->pwli_focus->widget == widget ) {
  874. #ifdef D_MS_EXTENSIONS
  875.   // Clear the focus here
  876.   // The focus item shouldn't be removed while the dialog is active
  877.   // without resetting the focus afterward
  878.   dialog->pwli_focus = NULL;
  879. #else
  880.   dialog->pwli_focus = dialog->pwli_prev_focused;
  881. #endif // D_MS_EXTENSIONS
  882. }
  883. curr = dialog->pwli_widget_list;
  884. while (curr)
  885. {
  886. if (curr->widget == widget)
  887. {
  888. if (!curr->prev)
  889. {
  890. // First item
  891. dialog->pwli_widget_list = curr->next;
  892. }
  893. else
  894. {
  895. curr->prev->next = curr->next;
  896. }
  897. if (curr->next)
  898. {
  899. // Removed item is not the last item
  900. curr->next->prev = curr->prev;
  901. }
  902. // Item has been de-linked, so
  903. // free it
  904. free(curr);
  905. if (widget->parent != NO_PARENT)
  906. {
  907. OSD_SetOrigin((MS_WIDGET *)widget->parent);
  908. }
  909. OSD_PutRect(widget->pos.x,widget->pos.y,widget->pos.w,widget->pos.h,BG_COLOR(widget->parent->widget.color));
  910. // Item is in a dialog or screen
  911. if (widget->parent != NO_PARENT)
  912. {
  913. MS_refresh(widget->parent);
  914. }
  915. if (MS_IS_DIALOG_BOX(widget))
  916. {
  917. ((MS_DIALOG *)widget)->on_close();
  918. }
  919. return 1;
  920. }
  921. curr = curr->next;
  922. }
  923. dbg_printf(("WARNING: MS_remove_item(): Item not found in the listn"));
  924. // Item not found in the list
  925. return 0;
  926. }
  927. #endif // ZS5XX_PASSWORD
  928. int MS_refresh(MS_DIALOG *dialog) 
  929. {
  930. WIDGET_LIST_ITEM *curr = dialog->pwli_widget_list;
  931. dbg_printf(("MS_refreshn"));
  932. OSD_SetOrigin((MS_WIDGET *) dialog);
  933. while (curr)
  934. {
  935. curr->widget->user_op(curr->widget, MS_UOP_DISPLAY, (char) ((curr == dialog->pwli_focus) ? C_FOCUSED : !C_FOCUSED));
  936. if ( MS_IS_DIALOG_BOX( curr->widget ) )
  937. {
  938. OSD_SetOrigin((MS_WIDGET *) dialog);
  939. }
  940. curr = curr->next;
  941. }
  942. return 1;
  943. }
  944. void MS_display(MS_WIDGET *widget)
  945. {
  946. widget->user_op(widget,MS_UOP_DISPLAY, !C_FOCUSED);
  947. }
  948. #ifdef OSD_DISPLAY_SPEED_TEST
  949. extern int osd_test_timer;
  950. #endif
  951. void MS_dialog_display(MS_DIALOG *dialog) 
  952. {
  953. #ifdef OSD_DISPLAY_SPEED_TEST
  954. char sz_test[16];
  955. WORD save_menu_id;
  956. osd_test_timer=0;
  957. #endif
  958. if ( dialog->widget.parent == NO_PARENT )
  959. {
  960. OSD_TurnOff();
  961. ((MS_SCREEN *)dialog)->layout();
  962. }
  963. #ifdef OSD_CHECK_PALETTE
  964. if(!OSDCheckPalette()){
  965. OSDSetPalette( OSD_COLOR_PALETTE_0, (OSD_Palette *) go_CurrentLayout.m_pColorPalette );
  966. }
  967. #endif
  968. ((MS_WIDGET*)dialog)->user_op((MS_WIDGET*)dialog,MS_UOP_DISPLAY,1);
  969. if ( dialog->widget.parent == NO_PARENT )
  970. {
  971. OSD_TurnOn();
  972. }
  973. #ifdef OSD_DISPLAY_SPEED_TEST
  974. num_to_str(osd_test_timer,sz_test,3);
  975. save_menu_id = g_ui_active_menu_id;
  976. g_ui_active_menu_id = RUN_TIME_MENU_ID;
  977. ui_tmp_string(sz_test);
  978. g_ui_active_menu_id = save_menu_id;
  979. #endif
  980. }
  981. MS_UOP MS_user_operation(MS_SCREEN *screen,MS_UOP uop, char param)
  982. {
  983. //Enable override of screen user_op
  984. uop = MS_CALL_USER_OP( screen, uop, param );
  985. if ( g_ms_deferred_action )
  986. {
  987. g_ms_deferred_action();
  988. MS_set_deferred_action( NULL );
  989. }
  990. if ( g_ms_bMustClose )
  991. {
  992. #ifdef D_USE_RETURN_IN_MENUS
  993. g_ms_bMustClose = FALSE;
  994. close_menu();
  995. #else
  996. close_menu();
  997. g_ms_bMustClose = FALSE;
  998. #endif // D_USE_RETURN_IN_MENUS
  999. }
  1000. return uop;
  1001. }
  1002. // Optimize screen and dialog creation; prepare for dialog subclassing
  1003. void MS_init_dialog(MS_DIALOG *dialog,
  1004. MS_POS *pos,
  1005. MS_COLOR color,
  1006. MS_DIALOG *parent,
  1007. void (*on_close)(void),
  1008. unsigned short attr)
  1009. {
  1010. MS_WIDGET *widget;
  1011. dbg_printf(("MS_init_dialogn"));
  1012. #ifdef _DEBUG
  1013. if (NULL == dialog) {
  1014. tr_printf(("FATAL: MS_init_dialog() Failed: NULL control.n"));
  1015. return;
  1016. }
  1017. #endif //_DEBUG
  1018. // Use explicit pointer instead of casting
  1019. widget = &dialog->widget;
  1020. widget->pos = *pos;
  1021. widget->attr = attr | MS_DIALOG_BOX;
  1022. widget->color = color;
  1023. widget->user_op = dialog_user_op;
  1024. widget->parent = parent;
  1025. dialog->pwli_widget_list = NULL;
  1026. dialog->pwli_focus = NULL;
  1027. #ifdef D_MS_EXTENSIONS
  1028. #else
  1029. dialog->pwli_prev_focused = NULL;
  1030. #endif // D_MS_EXTENSIONS
  1031. dialog->on_close = on_close;
  1032. widget->attrh = 0;
  1033. return;
  1034. }
  1035. MS_DIALOG *MS_create_dialog(MS_POS *pos,MS_COLOR color,MS_DIALOG *parent,void (*on_close)(void),unsigned short attr)
  1036. {
  1037. MS_DIALOG *dialog;
  1038. dbg_printf(("MS_create_dialogn"));
  1039. dialog = (MS_DIALOG *)malloc(sizeof(MS_DIALOG));
  1040. #ifdef _DEBUG
  1041. if (NULL == dialog) {
  1042. tr_printf(("FATAL: MS_create_dialog() Failed: Low system resources.n"));
  1043. return NULL;
  1044. }
  1045. #endif //_DEBUG
  1046.    
  1047. MS_init_dialog(dialog, pos, color, parent, on_close, attr);
  1048. return dialog;
  1049. }
  1050. MS_SCREEN *MS_create_screen(MS_POS *pos,MS_COLOR color, unsigned short attr,void (*on_close)(void),void(*layout)(void))
  1051. {
  1052. MS_SCREEN *pScreen;
  1053. dbg_printf(("MS_create_screen"));
  1054. pScreen = (MS_SCREEN *)malloc(sizeof(MS_SCREEN));
  1055. #ifdef _DEBUG
  1056. if (NULL == pScreen) {
  1057. tr_printf(("FATAL: MS_create_screen() Failed: Low system resources.n"));
  1058. return NULL;
  1059. }
  1060. #endif //_DEBUG
  1061. MS_init_dialog(&pScreen->dialog, pos, color, NO_PARENT, on_close, (MS_HOT_SPOT | attr));
  1062. pScreen->layout = layout;
  1063. return pScreen;
  1064. }