1: #include <X/mit-copyright.h>
   2: 
   3: /* $Header: XMenuInternal.c,v 10.17 86/02/01 16:15:10 tony Rel $ */
   4: /* Copyright    Massachusetts Institute of Technology    1985	*/
   5: 
   6: /*
   7:  * XMenu:	MIT Project Athena, X Window system menu package
   8:  *
   9:  * 	XMenuInternal.c - XMenu internal (not user visable) routines.
  10:  *
  11:  *	Author:		Tony Della Fera, DEC
  12:  *			November, 1985
  13:  *
  14:  */
  15: 
  16: #include "XMenuInternal.h"
  17: 
  18: /*
  19:  * Toggle color macro.
  20:  */
  21: #define toggle_color(x) \
  22:     ((x) == menu->bkgnd_color ? menu->s_frg_color : menu->bkgnd_color)
  23: 
  24: /*
  25:  * Internal Window creation queue sizes.
  26:  */
  27: #define S_QUE_SIZE  300
  28: #define P_QUE_SIZE  20
  29: #define BUFFER_SIZE (S_QUE_SIZE >= P_QUE_SIZE ? S_QUE_SIZE : P_QUE_SIZE)
  30: 
  31: 
  32: /*
  33:  * XMWinQue - Internal window creation queue datatype.
  34:  */
  35: typedef struct _xm_win_que_def {
  36:     int sq_size;
  37:     XMSelect *sq[S_QUE_SIZE];
  38:     XMSelect **sq_ptr;
  39:     int pq_size;
  40:     XMPane *pq[P_QUE_SIZE];
  41:     XMPane **pq_ptr;
  42: } XMWinQue;
  43: 
  44: /*
  45:  * _XMWinQue - Internal static window creation queue.
  46:  */
  47: static XMWinQue _XMWinQue;
  48: 
  49: /*
  50:  * _XMErrorCode - Global XMenu error code.
  51:  */
  52: int _XMErrorCode = XME_NO_ERROR;
  53: 
  54: /*
  55:  * _XMErrorList - Global XMenu error code discription strings.
  56:  */
  57: char *
  58: _XMErrorList[XME_CODE_COUNT] = {
  59:     "No error",             /* XME_NO_ERROR */
  60:     "Menu not initialized",     /* XME_NOT_INIT */
  61:     "Argument out of bounds",       /* XME_ARG_BOUNDS */
  62:     "Pane not found",           /* XME_P_NOT_FOUND */
  63:     "Selection not found",      /* XME_S_NOT_FOUND */
  64:     "Invalid menu style parameter", /* XME_STYLE_PARAM */
  65:     "Unable to grab mouse",     /* XME_GRAB_MOUSE */
  66:     "Unable to interpret locator",  /* XME_INTERP_LOC */
  67:     "Unable to calloc memory",      /* XME_CALLOC */
  68:     "Unable to create XAssocTable", /* XME_CREATE_ASSOC */
  69:     "Unable to store bitmap",       /* XME_STORE_BITMAP */
  70:     "Unable to make tile pixmaps",  /* XME_MAKE_TILES */
  71:     "Unable to make pixmap",        /* XME_MAKE_PIXMAP */
  72:     "Unable to create cursor",      /* XME_CREATE_CURSOR */
  73:     "Unable to open font",      /* XME_OPEN_FONT */
  74:     "Unable to create windows",     /* XME_CREATE_WINDOW */
  75:     "Unable to create transparencies",  /* XME_CREATE_TRANSP */
  76: };
  77: 
  78: /*
  79:  * _XMEventHandler - Internal event handler variable.
  80:  */
  81: int (*_XMEventHandler)() = NULL;
  82: 
  83: 
  84: 
  85: /*
  86:  * _XMWinQueInit - Internal routine to initialize the window
  87:  *		   queue.
  88:  */
  89: _XMWinQueInit()
  90: {
  91:     /*
  92:      * Blank the queue structure.
  93:      */
  94:     bzero(&_XMWinQue, sizeof(XMWinQue));
  95: 
  96:     /*
  97:      * Initialize the next free location pointers.
  98:      */
  99:     _XMWinQue.sq_ptr = _XMWinQue.sq;
 100:     _XMWinQue.pq_ptr = _XMWinQue.pq;
 101: }
 102: 
 103: 
 104: 
 105: /*
 106:  * _XMWinQueAddPane - Internal routine to add a pane to the pane
 107:  *		      window queue.
 108:  */
 109: int
 110: _XMWinQueAddPane(menu, p_ptr)
 111:     register XMenu *menu;   /* Menu being manipulated. */
 112:     register XMPane *p_ptr; /* XMPane being queued. */
 113: {
 114:     /*
 115:      * If the queue is currently full then flush it.
 116:      */
 117:     if (_XMWinQue.pq_size == P_QUE_SIZE) {
 118:     if (_XMWinQueFlush(menu) == _FAILURE) return(_FAILURE);
 119:     }
 120: 
 121:     /*
 122:      * Insert the new XMPane pointer and increment the queue pointer
 123:      * and the queue size.
 124:      */
 125:     *_XMWinQue.pq_ptr = p_ptr;
 126:     _XMWinQue.pq_ptr++;
 127:     _XMWinQue.pq_size++;
 128: 
 129:     /*
 130:      * All went well, return successfully.
 131:      */
 132:     _XMErrorCode = XME_NO_ERROR;
 133:     return(_SUCCESS);
 134: }
 135: 
 136: 
 137: 
 138: /*
 139:  * _XMWinQueAddSelection - Internal routine to add a selection to
 140:  *			   the selection window queue.
 141:  */
 142: int
 143: _XMWinQueAddSelection(menu, s_ptr)
 144:     register XMenu *menu;   /* Menu being manipulated. */
 145:     register XMSelect *s_ptr;   /* XMSelection being queued. */
 146: {
 147:     /*
 148:      * If this entry will overflow the queue then flush it.
 149:      */
 150:     if (_XMWinQue.sq_size == S_QUE_SIZE) {
 151:     if (_XMWinQueFlush(menu) == _FAILURE) return(_FAILURE);
 152:     }
 153: 
 154:     /*
 155:      * Insert the new XMSelect pointer and increment the queue pointer
 156:      * and the queue size.
 157:      */
 158:     *_XMWinQue.sq_ptr = s_ptr;
 159:     _XMWinQue.sq_ptr++;
 160:     _XMWinQue.sq_size++;
 161: 
 162:     /*
 163:      * All went well, return successfully.
 164:      */
 165:     _XMErrorCode = XME_NO_ERROR;
 166:     return(_SUCCESS);
 167: }
 168: 
 169: 
 170: 
 171: /*
 172:  * _XMWinQueFlush - Internal routine to flush the pane and
 173:  *		    selection window queues.
 174:  */
 175: int
 176: _XMWinQueFlush(menu)
 177:     register XMenu *menu;   /* Menu being manipulated. */
 178: {
 179:     register int pq_index;  /* Pane queue index. */
 180:     register int sq_index;  /* Selection queue index. */
 181:     register XMPane *p_ptr; /* XMPane pointer. */
 182:     register XMSelect *s_ptr;   /* XMSelect pointer. */
 183: 
 184:     int win_count;          /* Count of created windows. */
 185:     Window window;          /* Window id temporary variable. */
 186:     BatchFrame batch_buf[BUFFER_SIZE];  /* Window batch creation buffer. */
 187: 
 188:     /*
 189:      * If the pane window queue is not empty...
 190:      */
 191:     if (_XMWinQue.pq_size > 0) {
 192:     /*
 193: 	 * Pack the window batch buffer.
 194: 	 */
 195:     for (pq_index = 0; pq_index < _XMWinQue.pq_size; pq_index++) {
 196:         /*
 197: 	     * Retrieve the an XMPane pointer.
 198: 	     */
 199:         p_ptr = _XMWinQue.pq[pq_index];
 200: 
 201:         /*
 202: 	     * Pack the next buffer location with the data
 203: 	     * associated with the XMPane.
 204: 	     */
 205:         batch_buf[pq_index].type = IsOpaque;
 206:         batch_buf[pq_index].parent = menu->parent;
 207:         batch_buf[pq_index].x = p_ptr->window_x;
 208:         batch_buf[pq_index].y = p_ptr->window_y;
 209:         batch_buf[pq_index].width = p_ptr->window_w;
 210:         batch_buf[pq_index].height = p_ptr->window_h;
 211:         batch_buf[pq_index].bdrwidth = menu->p_bdr_width;
 212:         batch_buf[pq_index].border = menu->p_bdr_pixmap;
 213:         batch_buf[pq_index].background = menu->inact_pixmap;
 214:     }
 215: 
 216:     /*
 217: 	 * Transmit the pane window buffer.
 218: 	 */
 219:     win_count = XCreateWindowBatch(batch_buf, _XMWinQue.pq_size);
 220:     if (win_count != _XMWinQue.pq_size) {
 221:         _XMErrorCode = XME_CREATE_WINDOW;
 222:         return(_FAILURE);
 223:     }
 224: 
 225:     /*
 226: 	 * Retrieve the resulting window id's.
 227: 	 */
 228:     for (pq_index = 0; pq_index < _XMWinQue.pq_size; pq_index++) {
 229:         window = batch_buf[pq_index].self;
 230:         /*
 231: 	     * Store the window id with its XMPane structure.
 232: 	     */
 233:         p_ptr = _XMWinQue.pq[pq_index];
 234:         p_ptr->window = window;
 235:         /*
 236: 	     * Insert the new window id and its
 237: 	     * associated XMPane structure into the
 238: 	     * assoction table.
 239: 	     */
 240:         XMakeAssoc(menu->assoc_tab, window, p_ptr);
 241:         /*
 242: 	     * Select input events on the new window.
 243: 	     */
 244:         XSelectInput(window, menu->p_events);
 245:     }
 246: 
 247:     /*
 248: 	 * Reset the pane queue pointer and size.
 249: 	 */
 250:     _XMWinQue.pq_size = 0;
 251:     _XMWinQue.pq_ptr = _XMWinQue.pq;
 252:     }
 253: 
 254:     /*
 255:      * If the selection window queue is not empty...
 256:      */
 257:     if (_XMWinQue.sq_size > 0) {
 258:     /*
 259: 	 * Pack the selection transparency buffer.
 260: 	 */
 261:     for (sq_index = 0; sq_index < _XMWinQue.sq_size; sq_index++) {
 262:         /*
 263: 	     * Retrieve the an XMSelect pointer.
 264: 	     */
 265:         s_ptr = _XMWinQue.sq[sq_index];
 266: 
 267:         /*
 268: 	     * Pack the next buffer location with the data
 269: 	     * associated with the XMPane.
 270: 	     */
 271:         batch_buf[sq_index].type = IsTransparent;
 272:         batch_buf[sq_index].parent = s_ptr->parent_p->window;
 273:         batch_buf[sq_index].x = s_ptr->window_x;
 274:         batch_buf[sq_index].y = s_ptr->window_y;
 275:         batch_buf[sq_index].width = s_ptr->window_w;
 276:         batch_buf[sq_index].height = s_ptr->window_h;
 277:     }
 278: 
 279:     /*
 280: 	 * Transmit the selection transparency buffer.
 281: 	 */
 282:     win_count = XCreateWindowBatch(batch_buf, _XMWinQue.sq_size);
 283:     if (win_count != _XMWinQue.sq_size) {
 284:         _XMErrorCode = XME_CREATE_TRANSP;
 285:         return(_FAILURE);
 286:     }
 287: 
 288:     /*
 289: 	 * Retrieve the resulting window id's.
 290: 	 */
 291:     for (sq_index = 0; sq_index < _XMWinQue.sq_size; sq_index++) {
 292:         window = batch_buf[sq_index].self;
 293:         /*
 294: 	     * Store the window id with its XMSelect structure.
 295: 	     */
 296:         s_ptr = _XMWinQue.sq[sq_index];
 297:         s_ptr->window = window;
 298:         /*
 299: 	     * Insert the new window id and its
 300: 	     * associated XMSelect structure into the
 301: 	     * assoction table.
 302: 	     */
 303:         XMakeAssoc(menu->assoc_tab, window, s_ptr);
 304:         /*
 305: 	     * Select input events on the new window.
 306: 	     */
 307:         XSelectInput(window, menu->s_events);
 308:     }
 309: 
 310:     /*
 311: 	 * Reset the selection queue pointer and size.
 312: 	 */
 313:     _XMWinQue.sq_size = 0;
 314:     _XMWinQue.sq_ptr = _XMWinQue.sq;
 315:     }
 316: 
 317:     /*
 318:      * Flush X's internal queues.
 319:      */
 320:     XFlush();
 321: 
 322:     /*
 323:      * All went well, return successfully.
 324:      */
 325:     _XMErrorCode = XME_NO_ERROR;
 326:     return(_SUCCESS);
 327: }
 328: 
 329: 
 330: 
 331: /*
 332:  * _XMGetPanePtr - 	Given a menu pointer and a pane index number, return
 333:  *			a pane pointer that points to the indexed pane.
 334:  */
 335: XMPane *
 336: _XMGetPanePtr(menu, p_num)
 337:     register XMenu *menu;   /* Menu to find the pane in. */
 338:     register int p_num;     /* Index number of pane to find. */
 339: {
 340:     register XMPane *p_ptr; /* Pane pointer to be returned. */
 341:     register int i;     /* Loop counter. */
 342: 
 343:     /*
 344:      * Is the pane number out of range?
 345:      */
 346:     if ((p_num < 0) || (p_num > (menu->p_count - 1))) {
 347:     _XMErrorCode = XME_P_NOT_FOUND;
 348:     return(NULL);
 349:     }
 350: 
 351:     /*
 352:      * Find the right pane.
 353:      */
 354:     p_ptr = menu->p_list->next;
 355:     for (i = 0; i < p_num; i++) p_ptr = p_ptr->next;
 356: 
 357:     /*
 358:      * Return successfully.
 359:      */
 360:     _XMErrorCode = XME_NO_ERROR;
 361:     return(p_ptr);
 362: }
 363: 
 364: 
 365: 
 366: /*
 367:  * _XMGetSelectionPtr -	Given pane pointer and a selection index number,
 368:  *			return a selection pointer that points to the
 369:  *			indexed selection.
 370:  */
 371: XMSelect *
 372: _XMGetSelectionPtr(p_ptr, s_num)
 373:     register XMPane *p_ptr; /* Pane to find the selection in. */
 374:     register int s_num;     /* Index number of the selection to find. */
 375: {
 376:     register XMSelect *s_ptr;   /* Selection pointer to be returned. */
 377:     register int i;     /* Loop counter. *./
 378: 
 379:     /*
 380:      * Is the selection number out of range?
 381:      */
 382:     if ((s_num < 0) || (s_num > (p_ptr->s_count - 1))) {
 383:     _XMErrorCode = XME_S_NOT_FOUND;
 384:     return(NULL);
 385:     }
 386: 
 387:     /*
 388:      * Find the right selection.
 389:      */
 390:     s_ptr = p_ptr->s_list->next;
 391:     for (i = 0; i < s_num; i++) s_ptr = s_ptr->next;
 392: 
 393:     /*
 394:      * Return successfully.
 395:      */
 396:     _XMErrorCode = XME_NO_ERROR;
 397:     return(s_ptr);
 398: }
 399: 
 400: 
 401: 
 402: /*
 403:  * _XMRecomputeGlobals - Internal subroutine to recompute menu wide
 404:  *			 global values.
 405:  */
 406: _XMRecomputeGlobals(menu)
 407:     register XMenu *menu;   /* Menu object to compute from. */
 408: {
 409:     register XMPane *p_ptr; /* Pane pointer. */
 410:     register XMSelect *s_ptr;   /* Selection pointer. */
 411: 
 412:     register int max_p_label = 0;   /* Maximum pane label width. */
 413:     register int max_s_label = 0;   /* Maximum selection label width. */
 414:     register int s_count = 0;       /* Maximum selection count. */
 415: 
 416:     int p_s_pad;        /* Pane <-> selection padding. */
 417:     int p_s_diff;       /* Pane <-> selection seperation. */
 418: 
 419:     int p_height;       /* Pane window height. */
 420:     int p_width;        /* Pane window width. */
 421:     int s_width;        /* Selection window width. */
 422: 
 423:     int seperation;     /* Pane window, selection window seperation. */
 424: 
 425:     /*
 426:      * For each pane...
 427:      */
 428:     for (
 429:     p_ptr = menu->p_list->next;
 430:     p_ptr != menu->p_list;
 431:     p_ptr = p_ptr->next
 432:     ){
 433:     /*
 434: 	 * Recompute maximum pane label width.
 435: 	 */
 436:     max_p_label = max(max_p_label, p_ptr->label_width);
 437: 
 438:     /*
 439: 	 * Recompute maximum selection count.
 440: 	 */
 441:     s_count = max(s_count, p_ptr->s_count);
 442: 
 443:     /*
 444: 	 * For each selection in the current pane...
 445: 	 */
 446:     for (
 447:         s_ptr = p_ptr->s_list->next;
 448:         s_ptr != p_ptr->s_list;
 449:         s_ptr = s_ptr->next
 450:     ){
 451:         /*
 452: 	     * Recompute maximum selection label width.
 453: 	     */
 454:         max_s_label = max(max_s_label, s_ptr->label_width);
 455:     }
 456:     }
 457: 
 458:     /*
 459:      * Recompute pane height.
 460:      */
 461:     p_height = (menu->flag_height << 1) + (menu->s_y_off * s_count);
 462: 
 463:     /*
 464:      * Recompute horizontal padding between the pane window and the
 465:      * selection windows.
 466:      */
 467:     p_s_pad = menu->p_x_off << 1;
 468: 
 469:     /*
 470:      * Recompute pane and selection window widths.
 471:      * This is done by first computing the window sizes from the maximum
 472:      * label widths.  If the spacing between the selection window and the
 473:      * containing pane window is less than the pane selection padding value
 474:      * (twice the pane X offset) then change the size of the pane to be
 475:      * the size of the selection window plus the padding.  If, however the
 476:      * spacing between the selection window and the containing pane window
 477:      * is more than the pane selection padding value increase the size of
 478:      * the selection to its maximum possible value (the pane width minus
 479:      * the pane selection padding value).
 480:      */
 481:     p_width = max_p_label + p_s_pad;
 482:     s_width = max_s_label + (menu->s_fnt_pad << 1) + (menu->s_bdr_width << 1);
 483:     p_s_diff = p_width - s_width;
 484:     if (p_s_diff < p_s_pad) {
 485:     p_width = s_width + p_s_pad;
 486:     }
 487:     else if (p_s_diff > p_s_pad) {
 488:     s_width = p_width - p_s_pad;
 489:     }
 490: 
 491:     /*
 492:      * Reset menu wide global values.
 493:      */
 494:     menu->s_count = s_count;
 495:     menu->p_height = p_height;
 496:     menu->p_width = p_width;
 497:     menu->s_width = s_width;
 498: }
 499: 
 500: 
 501: 
 502: /*
 503:  * _XMRecomputePane - Internal subroutine to recompute pane
 504:  *		      window dependencies.
 505:  */
 506: int
 507: _XMRecomputePane(menu, p_ptr, p_num)
 508:     register XMenu *menu;   /* Menu object being recomputed. */
 509:     register XMPane *p_ptr; /* Pane pointer. */
 510:     register int p_num;     /* Pane sequence number. */
 511: {
 512:     register int window_x;  /* Recomputed window X coordinate. */
 513:     register int window_y;  /* Recomputed window Y coordinate. */
 514: 
 515:     register Bool config_p = FALSE; /* Reconfigure pane window? */
 516: 
 517:     /*
 518:      * Update the pane serial number.
 519:      */
 520:     p_ptr->serial = p_num;
 521: 
 522:     /*
 523:      * Recompute window X and Y coordinates.
 524:      */
 525:     switch (menu->menu_style) {
 526:     case LEFT:
 527:         window_x = menu->p_x_off * ((menu->p_count - 1) - p_num);
 528:         window_y = menu->p_y_off * ((menu->p_count - 1) - p_num);
 529:         break;
 530:     case RIGHT:
 531:         window_x = menu->p_x_off * p_num;
 532:         window_y = menu->p_y_off * ((menu->p_count - 1) - p_num);
 533:         break;
 534:     case CENTER:
 535:         window_x = 0;
 536:         window_y = menu->p_y_off * ((menu->p_count - 1) - p_num);
 537:         break;
 538:     default:
 539:         /* Error! Invalid style parameter. */
 540:         _XMErrorCode = XME_STYLE_PARAM;
 541:         return(_FAILURE);
 542:     }
 543: 
 544:     /*
 545:      * If the newly compute pane coordinates differ from the
 546:      * current coordinates, reset the current coordinates and
 547:      * reconfigure the pane.
 548:      */
 549:     if (
 550:     (window_x != p_ptr->window_x) ||
 551:     (window_y != p_ptr->window_y)
 552:     ){
 553:     /*
 554: 	 * Reset the coordinates and schedule
 555: 	 * the pane for reconfiguration.
 556: 	 */
 557:     p_ptr->window_x = window_x;
 558:     p_ptr->window_y = window_y;
 559:     config_p = TRUE;
 560:     }
 561: 
 562:     /*
 563:      * If the local pane width and height differs from the
 564:      * menu pane width and height, reset the local values.
 565:      */
 566:     if (
 567:     (p_ptr->window_w != menu->p_width) ||
 568:     (p_ptr->window_h != menu->p_height)
 569:     ){
 570:     /*
 571: 	 * Reset window width and height and schedule
 572: 	 * the pane for reconfiguration.
 573: 	 */
 574:     p_ptr->window_w = menu->p_width;
 575:     p_ptr->window_h = menu->p_height;
 576:     config_p = TRUE;
 577:     }
 578: 
 579:     /*
 580:      * If we need to reconfigure the pane window do it now.
 581:      */
 582:     if (config_p == TRUE) {
 583:     /*
 584: 	 * If the pane window has already been created then
 585: 	 * reconfigure the existing window, otherwise queue
 586: 	 * it for creation with the new configuration.
 587: 	 */
 588:     if (p_ptr->window) {
 589:         XConfigureWindow(
 590:         p_ptr->window,
 591:         p_ptr->window_x, p_ptr->window_y,
 592:         p_ptr->window_w, p_ptr->window_h
 593:         );
 594:     }
 595:     else {
 596:         if (_XMWinQueAddPane(menu, p_ptr) == _FAILURE) {
 597:         return(_FAILURE);
 598:         }
 599:     }
 600:     }
 601: 
 602:     /*
 603:      * Recompute label X position.
 604:      */
 605:     switch (menu->p_style) {
 606:     case LEFT:
 607:         p_ptr->label_x = menu->p_x_off + menu->p_fnt_pad;
 608:         break;
 609:     case RIGHT:
 610:         p_ptr->label_x = menu->p_width -
 611:         (p_ptr->label_width + menu->p_x_off + menu->p_fnt_pad);
 612:         break;
 613:     case CENTER:
 614:         p_ptr->label_x = (menu->p_width - p_ptr->label_width) >> 1;
 615:         break;
 616:     default:
 617:         /* Error! Invalid style parameter. */
 618:         _XMErrorCode = XME_STYLE_PARAM;
 619:         return(_FAILURE);
 620:     }
 621:     /*
 622:      * Recompute label Y positions.
 623:      */
 624:     p_ptr->label_uy = menu->p_fnt_pad;
 625:     p_ptr->label_ly = (menu->p_height - menu->flag_height) + menu->p_fnt_pad;
 626: 
 627:     /*
 628:      * All went well, return successfully.
 629:      */
 630:     _XMErrorCode = XME_NO_ERROR;
 631:     return(_SUCCESS);
 632: }
 633: 
 634: 
 635: 
 636: /*
 637:  * _XMRecomputeSelection - Internal subroutine to recompute
 638:  *			   selection window dependencies.
 639:  */
 640: int
 641: _XMRecomputeSelection(menu, s_ptr, s_num)
 642:     register XMenu *menu;   /* Menu object being recomputed. */
 643:     register XMSelect *s_ptr;   /* Selection pointer. */
 644:     register int s_num;     /* Selection sequence number. */
 645: {
 646:     register Bool config_s = FALSE; /* Reconfigure selection window? */
 647: 
 648:     /*
 649:      * If the selection serial numbers are out of order, begin
 650:      * resequencing selections.  Recompute selection window coordinates
 651:      * and serial number.
 652:      *
 653:      * When selections are created they are given a serial number of
 654:      * -1, this causes this routine to give a new selection
 655:      * its initial coordinates and serial number.
 656:      */
 657:     if (s_ptr->serial != s_num) {
 658:     /*
 659: 	 * Fix the sequence number.
 660: 	 */
 661:     s_ptr->serial = s_num;
 662:     /*
 663: 	 * Recompute window X and Y coordinates.
 664: 	 */
 665:     s_ptr->window_x = menu->s_x_off;
 666:     s_ptr->window_y = menu->flag_height + (menu->s_y_off * s_num);
 667:     /*
 668: 	 * We must reconfigure the window.
 669: 	 */
 670:     config_s = TRUE;
 671:     }
 672: 
 673:     /*
 674:      * If the local selection width and height differs from the
 675:      * menu selection width and height, reset the local values.
 676:      */
 677:     if (
 678:     (s_ptr->window_w != menu->s_width) ||
 679:     (s_ptr->window_h != menu->s_height)
 680:     ){
 681:     /*
 682: 	 * We must reconfigure the window.
 683: 	 */
 684:     config_s = TRUE;
 685:     /*
 686: 	 * Reset window width and height.
 687: 	 */
 688:     s_ptr->window_w = menu->s_width;
 689:     s_ptr->window_h = menu->s_height;
 690:     }
 691: 
 692:     /*
 693:      * If we need to reconfigure the selection window do it now.
 694:      */
 695:     if (config_s == TRUE) {
 696:     /*
 697: 	 * If the selection window has already been created then
 698: 	 * reconfigure the existing window, otherwise queue it
 699: 	 * for creation with the new configuration.
 700: 	 */
 701:     if (s_ptr->window) {
 702:         XConfigureWindow(
 703:         s_ptr->window,
 704:         s_ptr->window_x, s_ptr->window_y,
 705:         s_ptr->window_w, s_ptr->window_h
 706:         );
 707:     }
 708:     else {
 709:         if (_XMWinQueAddSelection(menu, s_ptr) == _FAILURE) {
 710:         return(_FAILURE);
 711:         }
 712:     }
 713:     }
 714: 
 715:     /*
 716:      * Recompute label X position.
 717:      */
 718:     switch (menu->s_style) {
 719:     case LEFT:
 720:         s_ptr->label_x = menu->s_bdr_width + menu->s_fnt_pad;
 721:         break;
 722:     case RIGHT:
 723:         s_ptr->label_x = menu->s_width -
 724:         (s_ptr->label_width + menu->s_bdr_width + menu->s_fnt_pad);
 725:         break;
 726:     case CENTER:
 727:         s_ptr->label_x = (menu->s_width - s_ptr->label_width) >> 1;
 728:         break;
 729:     default:
 730:         /* Error! Invaild style parameter. */
 731:         _XMErrorCode = XME_STYLE_PARAM;
 732:         return(_FAILURE);
 733:     }
 734:     /*
 735:      * Recompute label Y position.
 736:      */
 737:     s_ptr->label_y = menu->s_fnt_pad + menu->s_bdr_width;
 738: 
 739:     /*
 740:      * All went well, return successfully.
 741:      */
 742:     _XMErrorCode = XME_NO_ERROR;
 743:     return(_SUCCESS);
 744: }
 745: 
 746: 
 747: 
 748: /*
 749:  * _XMTransToOrigin - Internal subroutine to translate the point at
 750:  *		      the center of the current pane and selection to the
 751:  *		      the menu origin.
 752:  *
 753:  *	WARNING! ******	Be certain that all menu depencies have been
 754:  *			recomputed before calling this routine or
 755:  *			unpredicable results will follow.
 756:  */
 757: _XMTransToOrigin(menu, p_ptr, s_ptr, x_pos, y_pos, orig_x, orig_y)
 758:     register XMenu *menu;   /* Menu being computed against. */
 759:     register XMPane *p_ptr; /* Current pane pointer. */
 760:     register XMSelect *s_ptr;   /* Current selection pointer. */
 761:     int x_pos;          /* X coordinate of point to translate. */
 762:     int y_pos;          /* Y coordinate of point to translate. */
 763:     int *orig_x;        /* Return value X coord. of the menu origin. */
 764:     int *orig_y;        /* Return value Y coord. of the menu origin. */
 765: {
 766:     register int l_orig_x;  /* Local X coordinate of the menu origin. */
 767:     register int l_orig_y;  /* local Y coordinate of the menu origin. */
 768: 
 769:     /*
 770:      * Translate the menu origin such that the cursor hot point will be in the
 771:      * center of the desired current selection and pane.
 772:      */
 773: 
 774:     /*
 775:      * First translate to the upper left of the current selection window.
 776:      */
 777:     l_orig_x = x_pos - (menu->s_width >> 1);
 778:     l_orig_y = y_pos - (menu->s_height >> 1);
 779: 
 780:     /*
 781:      * Then translate to the upper left of the current pane window.
 782:      */
 783:     l_orig_x -= (s_ptr->window_x + menu->p_bdr_width);
 784:     l_orig_y -= (s_ptr->window_y + menu->p_bdr_width);
 785: 
 786:     /*
 787:      * Finally translate to the upper left of the menu.
 788:      */
 789:     l_orig_x -= p_ptr->window_x;
 790:     l_orig_y -= p_ptr->window_y;
 791: 
 792:     /*
 793:      * Set the return values.
 794:      */
 795:     *orig_x = l_orig_x;
 796:     *orig_y = l_orig_y;
 797: }
 798: 
 799: 
 800: 
 801: /*
 802:  * _XMRefreshPaneLabels - Internal subroutine that refreshes
 803:  *			  the labels in a menu pane.
 804:  */
 805: _XMRefreshPaneText(menu, pane)
 806:     register XMenu *menu;
 807:     register XMPane *pane;
 808: {
 809:     /*
 810:      * First clear the pane.
 811:      */
 812:     XClear(pane->window);
 813:     /*
 814:      * Then redraw the label text.
 815:      */
 816:     XTextMask(
 817:     pane->window,
 818:     pane->label_x, pane->label_uy,
 819:     pane->label, pane->label_length,
 820:     menu->p_fnt_info->id,
 821:     menu->p_frg_color
 822:     );
 823:     XTextMask(
 824:     pane->window,
 825:     pane->label_x, pane->label_ly,
 826:     pane->label, pane->label_length,
 827:     menu->p_fnt_info->id,
 828:     menu->p_frg_color
 829:     );
 830: }
 831: 
 832: 
 833: 
 834: /*
 835:  * _XMRefreshPane - Internal subroutine to completely refresh
 836:  *		    the contents of a pane.
 837:  */
 838: _XMRefreshPane(menu,pane)
 839:     register XMenu *menu;
 840:     register XMPane *pane;
 841: {
 842:     register XMSelect *s_list = pane->s_list;
 843:     register XMSelect *s_ptr;
 844: 
 845:     /*
 846:      * First clear the pane.
 847:      */
 848:     XClear(pane->window);
 849:     /*
 850:      * Then redraw the label text.
 851:      */
 852:     XTextMask(
 853:     pane->window,
 854:     pane->label_x, pane->label_uy,
 855:     pane->label, pane->label_length,
 856:     menu->p_fnt_info->id,
 857:     menu->p_frg_color
 858:     );
 859:     XTextMask(
 860:     pane->window,
 861:     pane->label_x, pane->label_ly,
 862:     pane->label, pane->label_length,
 863:     menu->p_fnt_info->id,
 864:     menu->p_frg_color
 865:     );
 866:     /*
 867:      * Finally refresh each selection.
 868:      */
 869:     for (s_ptr = s_list->next; s_ptr != s_list; s_ptr = s_ptr->next){
 870:     _XMRefreshSelection(menu, s_ptr);
 871:     }
 872: }
 873: 
 874: 
 875: 
 876: /*
 877:  * _XMRefreshSelection - Internal subroutine that refreshes
 878:  *			 a single selection window.
 879:  */
 880: _XMRefreshSelection(menu, select)
 881:     register XMenu *menu;
 882:     register XMSelect *select;
 883: {
 884:     register int width = select->window_w;
 885:     register int height = select->window_h;
 886:     register int bdr_width = menu->s_bdr_width;
 887: 
 888:     if (select->activated) {
 889:     if (menu->menu_mode == INVERT) {
 890:         XPixSet(select->window, 0, 0, width, height, menu->s_frg_color);
 891:         XTextMask(
 892:                 select->window,
 893:                 select->label_x, select->label_y,
 894:                 select->label, select->label_length,
 895:                 menu->s_fnt_info->id,
 896:         menu->bkgnd_color
 897:             );
 898:     }
 899:         else {
 900:             /*
 901:              * Since most drawing routines with arbitrary width lines
 902: 	     * are slow compared to raster-ops lets use a raster-op to
 903: 	     * draw the boxes.
 904:              */
 905:         XPixSet(select->window, 0, 0, width, height, menu->bkgnd_color);
 906:             XPixSet(
 907:                 select->window,
 908:                 0, 0,
 909:                 (width - bdr_width), bdr_width,
 910:         menu->s_bdr_color
 911:             );
 912:             XPixSet(
 913:                 select->window,
 914:                 (0 + (width - bdr_width)), 0,
 915:                 bdr_width, (height - bdr_width),
 916:         menu->s_bdr_color
 917:             );
 918:             XPixSet(
 919:                 select->window,
 920:                 (0 + bdr_width), (0 + (height - bdr_width)),
 921:                 (width - bdr_width), bdr_width,
 922:         menu->s_bdr_color
 923:             );
 924:             XPixSet(
 925:                 select->window,
 926:                 0, (0 + bdr_width),
 927:                 bdr_width, (height - bdr_width),
 928:         menu->s_bdr_color
 929:             );
 930:         XTextMask(
 931:                 select->window,
 932:                 select->label_x, select->label_y,
 933:                 select->label, select->label_length,
 934:                 menu->s_fnt_info->id,
 935:         menu->s_frg_color
 936:             );
 937:         }
 938:     }
 939:     else {
 940:     XClear(select->window);
 941:         XTextMask(
 942:             select->window,
 943:             select->label_x, select->label_y,
 944:             select->label, select->label_length,
 945:             menu->s_fnt_info->id,
 946:             menu->s_frg_color
 947:         );
 948:     }
 949: }

Defined functions

_XMRefreshPaneText defined in line 805; used 2 times
_XMRefreshSelection defined in line 880; used 3 times
_XMWinQueAddPane defined in line 109; used 2 times
_XMWinQueAddSelection defined in line 142; used 2 times

Defined variables

_XMErrorList defined in line 58; used 1 times
_XMWinQue defined in line 47; used 33 times

Defined struct's

_xm_win_que_def defined in line 35; never used

Defined typedef's

XMWinQue defined in line 42; used 2 times

Defined macros

BUFFER_SIZE defined in line 29; used 1 times
P_QUE_SIZE defined in line 28; used 4 times
S_QUE_SIZE defined in line 27; used 4 times
toggle_color defined in line 21; never used
Last modified: 1986-02-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2220
Valid CSS Valid XHTML 1.0 Strict