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

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_MULTI.C $             
  6.  *
  7.  * Description:
  8.  * ============
  9.  * 
  10.  * 
  11.  * Log:
  12.  * ====
  13.  * $Revision: 7 $
  14.  * Last Modified by $Author: Williaml $ at $Modtime: 04-03-30 11:18 $ 
  15.  ****************************************************************************************
  16.  * Updates:
  17.  ****************************************************************************************
  18.  * $Log: /I76/I76_Common/I76_Reference/UI/Menu_sys/MS_MULTI.C $
  19.  * 
  20.  * 7     04-03-30 11:19 Williaml
  21.  * add the switch D_DIRECTION_KEY_IN_SETUP_MENU for using
  22.  * up/down/left/right keys select or open the set up menu
  23.  * 
  24.  * 5     03-07-10 15:59 Leonm
  25.  * 
  26.  * 4     03-07-09 15:53 Leonm
  27.  * New Pro Logic II setup menu
  28.  * 
  29.  * 3     03-07-06 17:13 Rogerl
  30.  * Force action at last
  31.  * 
  32.  * 11    23/04/02 9:39 Nirm
  33.  * - Added dependency in "Config.h".
  34.  * 
  35.  * 10    11/03/02 12:51 Nirm
  36.  * Debug message in case of memory allocation failure.
  37.  * 
  38.  * 9     2/27/02 7:02a Tomasp
  39.  * Changed get_blk/rel_blk to malloc,free.
  40.  * 
  41.  * 7     16/01/02 8:57 Nirm
  42.  * Fixed debug-messages.
  43.  * 
  44.  * 6     13/01/02 16:38 Atai
  45.  * Remove old Defines
  46.  * 
  47.  * 5     9/01/02 18:23 Nirm
  48.  * Corrected Include-Paths.
  49.  * 
  50.  * 4     30/12/01 10:02 Atai
  51.  * add explicit casting
  52.  * 
  53.  * 3     23/12/01 17:47 Atai
  54.  * 
  55.  * 2     23/12/01 17:43 Atai
  56.  * Code cleaning
  57.  **************************************************************************************** */
  58. #include "Config.h" // Global Configuration - do not remove!
  59. #ifdef _DEBUG
  60. #include "DebugDbgMain.h"
  61. #undef IFTRACE
  62. #define IFTRACE if (gTraceMenu)
  63. #endif //_DEBUG
  64. #include <stdio.h>
  65. #include <stdlib.h>
  66. #include <string.h>
  67. #include "Includesysdefs.h"
  68. #include "Decoderosdrendr.h"
  69. #include "UIMenu_Sysosd_drv.h"
  70. #include "UIMenu_Sysms_wdgt.h"
  71. #include "UIMenu_Sysms_lib.h"
  72. #define CHOICE_HEIGHT MS_LINE_HEIGHT
  73. #define LAST_CHOICE (choice->text_list->size-1)
  74. #ifdef D_DIRECTION_KEY_IN_SETUP_MENU
  75. static BYTE no_change_choice;
  76. #endif
  77. //  Support external display
  78. #ifdef D_MS_EXTENSIONS
  79. void choice_display_open_value(MS_CHOICE *pmsc, WORD wItemNum, char focus )
  80. {
  81.   OSD_PutText(
  82.   pmsc->choice_pos.x,
  83. #ifdef D_MS_EXTENSIONS
  84. MS_CHOICE_OPEN_VALUE_POS_Y(pmsc, wItemNum),
  85. #else
  86.   pmsc->choice_pos.y + CHOICE_HEIGHT * wItemNum,
  87. #endif // D_MS_EXTENSIONS
  88.   pmsc->choice_pos.w,
  89. #ifdef D_MS_EXTENSIONS
  90.   pmsc->choice_pos.h,
  91. #else
  92.   CHOICE_HEIGHT,
  93. #endif // D_MS_EXTENSIONS
  94. #ifdef D_MS_EXTENSIONS
  95.   FORE_COLOR( pmsc, focus ),
  96. #else
  97.   FG_COLOR(pmsc->widget.color),
  98. #endif
  99.   BACK_COLOR((MS_WIDGET *) pmsc, focus ),
  100.   (void *)pmsc->text_list->head[wItemNum],
  101.   MS_JUST(pmsc),
  102.   !C_ASCII);
  103. }
  104. #endif
  105. //  Pass focus, use full color
  106. #ifdef D_MS_EXTENSIONS
  107. void choice_display_closed_value(MS_CHOICE *pmsc, char focus)
  108. #else
  109. void choice_display_closed_value(MS_CHOICE *pmsc, WORD back_color)
  110. #endif // D_MS_EXTENSIONS
  111. {
  112.   OSD_SetOrigin( (MS_WIDGET *) pmsc->widget.parent );
  113.   
  114.   OSD_PutText(
  115.   pmsc->widget.pos.x,
  116.   pmsc->widget.pos.y,
  117.   pmsc->widget.pos.w,
  118.   pmsc->widget.pos.h,
  119. #ifdef D_MS_EXTENSIONS
  120.   FORE_COLOR( pmsc, focus),
  121.   BACK_COLOR( pmsc, focus),
  122. #else
  123.   FG_COLOR(pmsc->widget.color),
  124.   back_color,
  125. #endif
  126.   (void *)pmsc->text_list->head[pmsc->current_choice],
  127.   ALIGN_CENTER,
  128.   !C_ASCII);
  129. }
  130. #ifdef D_MS_EXTENSIONS
  131. static void display_open_choice(MS_CHOICE *choice, char focus)
  132. {
  133. unsigned short i;
  134. // Can only do this if width is specified
  135. if ( IS_OPENABLE_LIST(choice) )
  136. {
  137. OSD_SetOrigin( (MS_WIDGET *) choice->widget.parent );
  138. for (i=0;i < LAST_CHOICE + 1;i++)
  139. {
  140. choice_display_open_value( choice, i, ((choice->current_choice == i) ? focus : !C_FOCUSED) );
  141. }
  142. }
  143. }
  144. static void display_closed_choice (MS_WIDGET *widget, char focus)
  145. {
  146. MS_CHOICE *choice = (MS_CHOICE *)widget;
  147. OSD_PutText(widget->pos.x,
  148. widget->pos.y,
  149. widget->pos.w,
  150. widget->pos.h,
  151. #ifdef D_MS_EXTENSIONS
  152. FORE_COLOR(widget, focus),
  153. #else
  154. FG_COLOR(widget->color),
  155. #endif
  156. BACK_COLOR(widget, focus),
  157. (void *)choice->text_list->head[choice->current_choice],
  158. //  Allow all alignments
  159. #ifdef D_MS_EXTENSIONS
  160. MS_JUST(widget),
  161. #else
  162. ALIGN_CENTER,
  163. #endif // D_MS_EXTENSIONS
  164. !C_ASCII);
  165. }
  166. #endif // D_MS_EXTENSIONS
  167. #ifdef D_MS_EXTENSIONS
  168. static void display (MS_WIDGET *widget, char focus)
  169. {
  170. MS_CHOICE *choice = (MS_CHOICE *)widget;
  171. // Fix display of open toggle
  172. if ( IS_OPENABLE_LIST(choice) && MS_IS_CHOICE_OPEN(choice) )
  173.   display_open_choice(widget, focus);
  174. else
  175.   display_closed_choice(widget, focus);
  176. }
  177. #else
  178. static void display (MS_WIDGET *widget, char focus)
  179. {
  180. MS_CHOICE *choice = (MS_CHOICE *)widget;
  181. OSD_PutText(widget->pos.x,
  182. widget->pos.y,
  183. widget->pos.w,
  184. widget->pos.h,
  185. FG_COLOR(widget->color),
  186. BACK_COLOR(widget, focus),
  187. (void *)choice->text_list->head[choice->current_choice],
  188. // Allow all alignments
  189. #ifdef D_MS_EXTENSIONS
  190. MS_JUST(pmsc),
  191. #else
  192. ALIGN_CENTER,
  193. #endif // D_MS_EXTENSIONS
  194. !C_ASCII);
  195. }
  196. #endif // D_MS_EXTENSIONS
  197. //  Support toggle with arrows, wraparound
  198. #ifdef D_MS_EXTENSIONS
  199. static void increment_choice(MS_CHOICE *choice)
  200. {
  201.   if ( choice->current_choice < LAST_CHOICE )
  202. choice->current_choice ++;
  203.   else
  204. choice->current_choice = 0;
  205. }
  206. static void decrement_choice(MS_CHOICE *choice)
  207. {
  208.   if ( choice->current_choice )
  209. choice->current_choice --;
  210.   else
  211. choice->current_choice = LAST_CHOICE;
  212. }
  213. #endif // D_MS_EXTENSIONS
  214. static int choice_previous(MS_CHOICE *choice)
  215. {
  216. #ifdef D_MS_EXTENSIONS
  217.   if (  IS_OPENABLE_LIST(choice) && !MS_IS_CHOICE_OPEN(choice) )
  218. #else
  219.   if ( !MS_IS_CHOICE_OPEN(choice) )
  220. #endif // D_MS_EXTENSIONS
  221. {
  222. return 0;
  223. }
  224. #ifdef D_MS_EXTENSIONS
  225. if ( !MS_IS_CHOICE_WRAP(choice) && (choice->current_choice == 0) )
  226.   return 0;
  227. #endif // D_MS_EXTENSIONS
  228. if ( IS_OPENABLE_LIST(choice) )
  229. {
  230. #ifdef D_MS_EXTENSIONS
  231. #else
  232. if (choice->current_choice)
  233. #endif // D_MS_EXTENSIONS
  234. {
  235. #ifdef D_MS_EXTENSIONS
  236. choice_display_open_value(choice, choice->current_choice, !C_FOCUSED);
  237. decrement_choice(choice);
  238. choice_display_open_value(choice, choice->current_choice, C_FOCUSED);
  239. // When open, don't perform action on next/previous
  240. #else // D_MS_EXTENSIONS
  241. OSD_PutText(
  242. choice->choice_pos.x,
  243. choice->choice_pos.y + choice->current_choice * CHOICE_HEIGHT,
  244. choice->choice_pos.w,
  245. CHOICE_HEIGHT,
  246. FG_COLOR(choice->widget.color),
  247. BG_COLOR(choice->widget.color),
  248. (void *)choice->text_list->head[choice->current_choice],
  249. MS_JUST(choice),
  250. !C_ASCII);
  251. choice->current_choice --;
  252. OSD_PutText(
  253. choice->choice_pos.x,
  254. choice->choice_pos.y+choice->current_choice * CHOICE_HEIGHT,
  255. choice->choice_pos.w,
  256. CHOICE_HEIGHT,
  257. FG_COLOR(choice->widget.color),
  258. FOCUS_COLOR(choice->widget.color),
  259. (void *)choice->text_list->head[choice->current_choice],
  260. MS_JUST(choice),
  261. !C_ASCII);
  262. #endif // D_MS_EXTENSIONS
  263. }
  264. }
  265. else
  266. {
  267. #ifdef D_MS_EXTENSIONS
  268. decrement_choice(choice);
  269. // Use full color and pass focus
  270. choice_display_closed_value(choice, C_FOCUSED);
  271. //  Perform action on UP/LEFT; Allow NULL actions
  272. if ( !MS_IS_CHOICE_ENTER(choice) && !MS_IS_CHOICE_ACTION_ON_ENTER(choice) )
  273. {
  274.   if ( choice->action )
  275. choice->action(choice->current_choice);
  276. }
  277. #else
  278. if (choice->current_choice) {
  279. choice->current_choice --;
  280. }
  281. else {
  282. choice->current_choice = LAST_CHOICE;
  283. }
  284. OSD_PutText(
  285. choice->widget.pos.x,
  286. choice->widget.pos.y,
  287. choice->widget.pos.w,
  288. choice->widget.pos.h,
  289. FG_COLOR(choice->widget.color),
  290. FOCUS_COLOR(choice->widget.color),
  291. (void *)choice->text_list->head[choice->current_choice],
  292. ALIGN_CENTER,
  293. !C_ASCII);
  294. #endif // D_MS_EXTENSIONS
  295. }
  296. return 1;
  297. }
  298. #ifdef D_MS_EXTENSIONS
  299. #else
  300. #define choice_down   choice_next
  301. #endif // D_MS_EXTENSIONS
  302. static int choice_next(MS_CHOICE *choice)
  303. {
  304. #ifdef D_MS_EXTENSIONS
  305.   if ( IS_OPENABLE_LIST(choice) && !MS_IS_CHOICE_OPEN(choice) )
  306. #else
  307.   if ( !MS_IS_CHOICE_OPEN(choice) )
  308. #endif // D_MS_EXTENSIONS
  309. {
  310. return 0;
  311. }
  312. #ifdef D_MS_EXTENSIONS
  313. if ( !MS_IS_CHOICE_WRAP(choice) && (choice->current_choice == LAST_CHOICE) )
  314.   return 0;
  315. #endif // D_MS_EXTENSIONS
  316.   if ( IS_OPENABLE_LIST(choice) )
  317.   {
  318. #ifdef D_MS_EXTENSIONS
  319. #else
  320. if (choice->current_choice < LAST_CHOICE)
  321. #endif // D_MS_EXTENSIONS
  322. {
  323. #ifdef D_MS_EXTENSIONS
  324. choice_display_open_value(choice, choice->current_choice, !C_FOCUSED);
  325. increment_choice(choice);
  326. choice_display_open_value(choice, choice->current_choice, C_FOCUSED);
  327. #else // D_MS_EXTENSIONS
  328. OSD_PutText(
  329. choice->choice_pos.x,
  330. choice->choice_pos.y + choice->current_choice * CHOICE_HEIGHT,
  331. choice->choice_pos.w,
  332. CHOICE_HEIGHT,
  333. FG_COLOR(choice->widget.color),
  334. BG_COLOR(choice->widget.color),
  335. (void *)choice->text_list->head[choice->current_choice],
  336. MS_JUST(choice),
  337. !C_ASCII);
  338. choice->current_choice ++;
  339. OSD_PutText(
  340. choice->choice_pos.x,
  341. choice->choice_pos.y + choice->current_choice * CHOICE_HEIGHT,
  342. choice->choice_pos.w,
  343. CHOICE_HEIGHT,
  344. FG_COLOR(choice->widget.color),
  345. FOCUS_COLOR(choice->widget.color),
  346. (void *)choice->text_list->head[choice->current_choice],
  347. MS_JUST(choice),
  348. !C_ASCII);
  349. #endif // D_MS_EXTENSIONS
  350. }
  351. }
  352. else
  353. // Choice is a toggle
  354. {
  355. #ifdef D_MS_EXTENSIONS
  356.   increment_choice(choice);
  357.   choice_display_closed_value(choice, C_FOCUSED);
  358. if ( !MS_IS_CHOICE_ENTER(choice) && !MS_IS_CHOICE_ACTION_ON_ENTER(choice) )
  359.     {
  360. if ( choice->action )
  361.   choice->action(choice->current_choice);
  362.   }
  363. #else
  364.   if (choice->current_choice >= LAST_CHOICE) {
  365. choice->current_choice = 0;
  366. }
  367. else {
  368. choice->current_choice ++;
  369. }
  370. OSD_PutText(
  371. choice->widget.pos.x,
  372. choice->widget.pos.y,
  373. choice->widget.pos.w,
  374. choice->widget.pos.h,
  375. FG_COLOR(choice->widget.color),
  376. FOCUS_COLOR(choice->widget.color),
  377. (void *)choice->text_list->head[choice->current_choice],
  378. ALIGN_CENTER,
  379. !C_ASCII);
  380. #endif // D_MS_EXTENSIONS
  381. }
  382. // success
  383. return 1;
  384. }
  385. #ifdef D_MS_EXTENSIONS
  386. static void open_choice(MS_CHOICE *choice, MS_UOP uop)
  387. #else
  388. static void open_choice(MS_CHOICE *choice)
  389. #endif // D_MS_EXTENSIONS
  390. {
  391. #ifdef D_MS_EXTENSIONS
  392. #else
  393. unsigned short i;
  394. #endif // D_MS_EXTENSIONS
  395. ((MS_WIDGET *)choice)->attr |= MS_CHOICE_OPEN;
  396. if ( IS_OPENABLE_LIST(choice) ) {
  397. #ifdef D_MS_EXTENSIONS
  398.   display_open_choice(choice, C_FOCUSED);
  399. #else
  400. OSD_SetOrigin( (MS_WIDGET *) choice->widget.parent );
  401. for (i=0;i<choice->text_list->size;i++) {
  402. OSD_PutText(
  403. choice->choice_pos.x,
  404. choice->choice_pos.y+CHOICE_HEIGHT*i,
  405. choice->choice_pos.w,
  406. CHOICE_HEIGHT,
  407. FG_COLOR(choice->widget.color),
  408. BACK_COLOR((MS_WIDGET *) choice, ((choice->current_choice == i) == C_FOCUSED)),
  409. (void *)choice->text_list->head[i],
  410. MS_JUST(choice),
  411. !C_ASCII);
  412. }
  413. #endif // D_MS_EXTENSIONS
  414. }
  415. else {
  416. #ifdef D_MS_EXTENSIONS
  417.   switch (uop)
  418.   {
  419.   case MS_UOP_LEFT:
  420.   case MS_UOP_UP:
  421. choice_previous(choice);
  422. break;
  423.   case MS_UOP_ENTER:
  424.   case MS_UOP_RIGHT:
  425.   case MS_UOP_DOWN:
  426. choice_next(choice);
  427. break;
  428.   }
  429. #else
  430. choice_next(choice);
  431. #endif // D_MS_EXTENSIONS
  432. }
  433. #ifdef D_DIRECTION_KEY_IN_SETUP_MENU
  434. no_change_choice = choice->current_choice;
  435. #endif
  436. }
  437. static void close_choice(MS_CHOICE *choice)
  438. {
  439. ((MS_WIDGET *)choice)->attr &= (unsigned char) ~MS_CHOICE_OPEN;
  440. if ( IS_OPENABLE_LIST(choice) ) {
  441.   OSD_SetOrigin( (MS_WIDGET*)((MS_WIDGET *) choice)->parent );
  442. OSD_PutRect(
  443. choice->choice_pos.x,
  444. choice->choice_pos.y,
  445. choice->choice_pos.w,
  446. #ifdef D_MS_EXTENSIONS
  447. choice->text_list->size * choice->choice_pos.h,
  448. #else
  449. choice->text_list->size*CHOICE_HEIGHT,
  450. #endif // D_MS_EXTENSIONS
  451. BG_COLOR(((MS_WIDGET *)choice)->parent->widget.color)
  452. );
  453. display((MS_WIDGET *)choice, C_FOCUSED);
  454. }
  455. }
  456. MS_UOP choice_user_op(MS_WIDGET *widget, MS_UOP uop, char param) 
  457. {
  458. MS_CHOICE *choice = (MS_CHOICE *)widget;
  459. switch (uop) {
  460. case MS_UOP_DELETE:
  461.   uop = MS_UOP_NOP;
  462.   break;
  463. case MS_UOP_DISPLAY:
  464.   display(widget,param);
  465.   uop = MS_UOP_NOP;
  466.   break;
  467. case MS_UOP_UP:
  468. #ifdef D_MS_EXTENSIONS
  469. if ( MS_IS_CHOICE_UD(choice) )
  470. {
  471.   if ( MS_IS_CHOICE_OPEN(choice) )
  472. choice_previous(choice);
  473.   else
  474. open_choice(choice, uop);
  475.   uop = MS_UOP_NOP;
  476. }
  477. else
  478. {
  479.   if ( IS_OPENABLE_LIST(choice) )
  480.   {
  481. if ( choice_previous(choice) )
  482. {
  483.   uop = MS_UOP_NOP;
  484. }
  485.   }
  486. }
  487. #else // D_MS_EXTENSIONS
  488. if ( IS_OPENABLE_LIST(choice) )
  489. {
  490. if ( choice_previous(choice) )
  491. {
  492.   uop = MS_UOP_NOP;
  493. }
  494. }
  495. #endif // D_MS_EXTENSIONS
  496. break;
  497. case MS_UOP_RIGHT:
  498. #ifdef D_MS_EXTENSIONS
  499. if ( MS_IS_CHOICE_LR(choice) )
  500. {
  501.   if ( MS_IS_CHOICE_OPEN(choice) )
  502.   {
  503. choice_next(choice);
  504.   }
  505.   else
  506.   {
  507. open_choice(choice, uop);
  508.   }
  509.   uop = MS_UOP_NOP;
  510. }
  511. else
  512. {
  513.   if ( IS_OPENABLE_LIST(choice) )
  514.   {
  515. if ( choice_next(choice) )
  516. {
  517.   uop = MS_UOP_NOP;
  518. }
  519.   }
  520. }
  521. break;
  522. #endif // D_MS_EXTENSIONS
  523. #ifdef D_DIRECTION_KEY_IN_SETUP_MENU
  524. // if(!no_toggle_in_audio&& (IS_SETUP_MENU_ACTIVE) )
  525. if (g_ui_active_menu_id == SETUP_MENU_ID)
  526. {
  527. if (!MS_IS_CHOICE_OPEN(choice))
  528. {
  529. open_choice(choice);
  530. if ( IS_TOGGLE(choice) )
  531. {
  532.   choice->action(choice->current_choice);
  533.   close_choice(choice);
  534. }
  535. }
  536. uop = MS_UOP_NOP;
  537. }else
  538. if(MS_IS_CHOICE_OPEN(choice))
  539. uop=MS_UOP_NOP;
  540. break;
  541. #endif
  542. case MS_UOP_LEFT:
  543. #ifdef D_MS_EXTENSIONS
  544. if ( MS_IS_CHOICE_LR(choice) )
  545. {
  546.   if ( MS_IS_CHOICE_OPEN(choice) )
  547.   {
  548. choice_previous(choice);
  549.   }
  550.   else
  551.   {
  552. open_choice(choice, uop);
  553.   }
  554. //  Prevent further propagation of uop
  555.   uop = MS_UOP_NOP;
  556. }
  557. else
  558. {
  559.   if ( IS_OPENABLE_LIST(choice) )
  560.   {
  561. if ( choice_previous(choice) )
  562. {
  563.   uop = MS_UOP_NOP;
  564. }
  565.   }
  566. }
  567. #else // D_MS_EXTENSIONS
  568. #ifdef D_DIRECTION_KEY_IN_SETUP_MENU
  569. // if(!no_toggle_in_audio&& (IS_SETUP_MENU_ACTIVE) )
  570. if (g_ui_active_menu_id == SETUP_MENU_ID)
  571. {
  572. if (MS_IS_CHOICE_OPEN(choice))
  573. {
  574. choice->current_choice = no_change_choice;
  575. close_choice(choice);
  576. uop = MS_UOP_NOP;
  577. }
  578. else if( IS_TOGGLE(choice) )
  579. {
  580. ((MS_WIDGET *)choice)->attr |= MS_CHOICE_OPEN;
  581. choice_previous(choice);
  582. choice->action(choice->current_choice);
  583. ((MS_WIDGET *)choice)->attr &= (unsigned char) ~MS_CHOICE_OPEN;
  584. uop = MS_UOP_NOP;
  585. }
  586. }else
  587. #endif
  588. if (MS_IS_CHOICE_OPEN(choice)) {
  589. uop=MS_UOP_NOP;
  590. }
  591. #endif // D_MS_EXTENSIONS
  592. break;
  593. case MS_UOP_DOWN:
  594. #ifdef D_MS_EXTENSIONS
  595. if ( MS_IS_CHOICE_UD(choice) )
  596. {
  597.   if ( MS_IS_CHOICE_OPEN(choice) )
  598. choice_next(choice);
  599.   else
  600. open_choice(choice, uop);
  601. //  Prevent further propagation of uop
  602.   uop = MS_UOP_NOP;
  603. }
  604. else
  605. {
  606.   if ( IS_OPENABLE_LIST(choice) )
  607.   {
  608. if ( choice_next(choice) )
  609. {
  610.   uop = MS_UOP_NOP;
  611. }
  612.   }
  613. }
  614. #else // D_MS_EXTENSIONS
  615. if ( IS_OPENABLE_LIST(choice) ) {
  616. #ifdef D_MS_EXTENSIONS
  617. if (choice_next(choice)) {
  618. #else
  619. if (choice_down(choice)) {
  620. #endif // D_MS_EXTENSIONS
  621. uop = MS_UOP_NOP;
  622. }
  623. }
  624. #endif // D_MS_EXTENSIONS
  625. break;
  626. case MS_UOP_ENTER:
  627. #ifdef D_MS_EXTENSIONS
  628. if ( MS_IS_CHOICE_ENTER(choice) && !(MS_IS_CHOICE_KEEP_OPEN(choice)) )
  629. {
  630.   // Choice is ENTER-activated toggle or openable list
  631.   if (MS_IS_CHOICE_OPEN(choice))
  632.   {
  633.   // Choice is open
  634.   if ( IS_TOGGLE(choice) )
  635.   {
  636.   choice_next(choice);
  637.   if ( choice->action )
  638. choice->action(choice->current_choice);
  639.   }
  640.   else
  641.   {
  642. if ( choice->action )
  643.   choice->action(choice->current_choice);
  644.   }
  645.   // Re-test in case the action changed the screen
  646.   if ( MS_IS_CHOICE_OPEN(choice) )
  647.   {
  648. close_choice(choice);
  649.   }
  650.   }
  651.   else // MS_IS_CHOICE_OPEN
  652.   {
  653.   // Choice is not open
  654.   open_choice(choice, uop);
  655.   if ( IS_TOGGLE(choice) )
  656.   {
  657. if ( choice->action )
  658.   choice->action(choice->current_choice);
  659. close_choice(choice);
  660.   }
  661.   }
  662.   uop = MS_UOP_NOP;
  663. }
  664. //  Enable ENTER when choice is open
  665. else // ( MS_IS_CHOICE_ENTER(choice) && !(MS_IS_CHOICE_KEEP_OPEN(choice)) )
  666. {
  667.   // Choice is a UD or LR-activated toggle or always open
  668.   if ( MS_IS_CHOICE_OPEN(choice) )
  669.   {
  670. //  Allow NULL actions
  671. if ( choice->action )
  672.   choice->action(choice->current_choice);
  673. uop = MS_UOP_NOP;
  674.   }
  675. }
  676. #else // D_MS_EXTENSIONS
  677. if (MS_IS_CHOICE_OPEN(choice)) {
  678. if ( IS_TOGGLE(choice) ) {
  679. choice_down(choice);
  680. }
  681. // Re-test in case the action changed the screen
  682. if ( MS_IS_CHOICE_OPEN(choice) )
  683. {
  684.   close_choice(choice);
  685. }
  686. // Force Action at last , RL 070603
  687. choice->action(choice->current_choice);
  688. }
  689. else {
  690.    open_choice(choice);
  691. if ( IS_TOGGLE(choice) )
  692. {
  693.   choice->action(choice->current_choice);
  694.   close_choice(choice);
  695. }
  696. }
  697. uop = MS_UOP_NOP;
  698. #endif // D_MS_EXTENSIONS
  699. break;
  700. }
  701. return uop;
  702. }
  703. MS_CHOICE *MS_create_choice(CONST MS_POS *pos, MS_COLOR color, CONST MS_TEXT_LIST *text_list, CONST MS_POS *choice_pos, void (* action)(int), unsigned char attr)
  704. {
  705. MS_CHOICE *choice;
  706. dbg_printf(("MS_create_choicen"));
  707. choice = (MS_CHOICE *)malloc(sizeof(MS_CHOICE));
  708. #ifdef _DEBUG
  709. if (NULL == choice) {
  710. tr_printf(("FATAL: MS_create_choice() Failed: Low system resources.n"));
  711. return NULL;
  712. }
  713. #endif //_DEBUG
  714. choice->widget.pos = *pos;
  715. choice->widget.parent = NO_PARENT;
  716. choice->widget.color = color;
  717. choice->text_list = text_list;
  718. choice->action = action;
  719. choice->current_choice = 0;
  720. choice->choice_pos = *choice_pos;
  721. choice->widget.user_op = choice_user_op;
  722. choice->widget.attr = attr;
  723. #ifdef D_MS_EXTENSIONS
  724. // Correct attribute assignments
  725. if ( IS_OPENABLE_LIST(choice) )
  726. {
  727.   choice->widget.attr &= ~( MS_IS_CHOICE_LR(choice) | MS_IS_CHOICE_UD(choice) );
  728. }
  729. else
  730. {
  731.   choice->widget.attr |= MS_CHOICE_WRAP;
  732. }
  733. if ( MS_IS_CHOICE_OPEN(choice) )
  734. {
  735.   choice->widget.attr |= MS_CHOICE_KEEP_OPEN;
  736. }
  737. #endif // D_MS_EXTENSIONS
  738. choice->widget.attrh = ALIGN_CENTER;
  739. return choice;
  740. }