home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume20 / pexdraw / part06 < prev    next >
Encoding:
Text File  |  1993-06-07  |  59.6 KB  |  2,204 lines

  1. Newsgroups: comp.sources.x
  2. From: jch@okimicro.oki.com (Jan Hardenbergh)
  3. Subject: v20i016:  pexdraw - A PEX drawing program, Part06/14
  4. Message-ID: <1993Jun8.150134.18945@sparky.imd.sterling.com>
  5. X-Md4-Signature: fbf5447011e56f846fe9e26210cf9536
  6. Sender: chris@sparky.imd.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Tue, 8 Jun 1993 15:01:34 GMT
  9. Approved: chris@sparky.imd.sterling.com
  10.  
  11. Submitted-by: jch@okimicro.oki.com (Jan Hardenbergh)
  12. Posting-number: Volume 20, Issue 16
  13. Archive-name: pexdraw/part06
  14. Environment: X11R5, PEX
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then feed it
  18. # into a shell via "sh file" or similar.  To overwrite existing files,
  19. # type "sh file -c".
  20. # Contents:  util/pexutcmapint.c wks.c
  21. # Wrapped by chris@sparky on Tue Jun  8 09:46:32 1993
  22. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  23. echo If this archive is complete, you will see the following message:
  24. echo '          "shar: End of archive 6 (of 14)."'
  25. if test -f 'util/pexutcmapint.c' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'util/pexutcmapint.c'\"
  27. else
  28.   echo shar: Extracting \"'util/pexutcmapint.c'\" \(41041 characters\)
  29.   sed "s/^X//" >'util/pexutcmapint.c' <<'END_OF_FILE'
  30. X/******************************************************************************/
  31. X/*                                                                            */
  32. X/*  (c) Copyright Hewlett-Packard Company, 1992, Fort Collins, Colorado       */
  33. X/*                                                                            */
  34. X/*                            All Rights Reserved                             */
  35. X/*                                                                            */
  36. X/*  Permission to use, copy, modify, and distribute this software and its     */
  37. X/*  documentation for any purpose and without fee is hereby granted,          */
  38. X/*  provided that the above copyright notices appear in all copies and that   */
  39. X/*  both the copyright notices and this permission notice appear in           */
  40. X/*  supporting documentation, and that the name of Hewlett-Packard not be     */
  41. X/*  used in advertising or publicity pertaining to distribution of the        */
  42. X/*  software without specific, written prior permission.                      */
  43. X/*                                                                            */
  44. X/*  HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THIS         */
  45. X/*  SOFTWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
  46. X/*  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  Hewlett-Packard    */
  47. X/*  shall not be liable for errors contained herein or direct, indirect,      */
  48. X/*  special, incidental or consequential damages in connection with the       */
  49. X/*  furnishing, performance or use of this software.                          */
  50. X/*                                                                            */
  51. X/******************************************************************************/
  52. X
  53. X/******************************************************************************/
  54. X/*                                                                            */
  55. X/* $Source: /users/waitz/work/tmp/RCS/pexutcmapint.c,v $                         */
  56. X/* $Date: 93/04/01 13:30:40 $                                                 */
  57. X/* $Revision: 1.2 $                                                   */
  58. X/*                                                                            */
  59. X/* Description:                                                               */
  60. X/*   Internal routine implementation file for PEXUt colormap/visual utilities.*/
  61. X/*                                                                            */
  62. X/* Notes:                                                                     */
  63. X/*                                                                            */
  64. X/******************************************************************************/
  65. X
  66. X
  67. X#include <math.h>
  68. X#include <stdio.h>
  69. X#include <stdlib.h>
  70. X
  71. X#include <X11/Xlib.h>
  72. X#include <X11/Xutil.h>
  73. X#include <X11/Xatom.h>
  74. X#include <X11/PEX5/PEXlib.h>
  75. X#include "pexutext.h"
  76. X
  77. X#include "pexutcmap.h"
  78. X#include "pexutcmapint.h"
  79. X
  80. X#ifndef MBX_HEADER_FILE_NOT_INSTALLED /* [ */
  81. X#include <X11/extensions/multibuf.h>
  82. X#endif /* !MBX_HEADER_FILE_NOT_INSTALLED ] */
  83. X#include "pexutdbint.h"
  84. X
  85. X
  86. Xint pexut_get_standard_cmap_property (
  87. X        display,
  88. X        screen,
  89. X        property_info,
  90. X        property_atom_return,
  91. X        property_count_return,
  92. X        property_data_return
  93. X        )
  94. X
  95. X        Display                *display;
  96. X        int                screen;
  97. X        interop_property_type        *property_info;
  98. X        Atom                *property_atom_return;
  99. X        int                *property_count_return;
  100. X        XStandardColormap        **property_data_return;
  101. X{
  102. X    Atom                actual_type;
  103. X    int            actual_format;
  104. X    unsigned long       item_count;
  105. X    unsigned long       item_count_return, bytes_unread;
  106. X    int            result;
  107. X
  108. X
  109. X    if ( !property_info->is_standard) {
  110. X
  111. X        if (property_info->have_atom)
  112. X        *property_atom_return = property_info->property_atom;
  113. X        else {
  114. X        /*
  115. X            Get the atom from the X server.  If it doesn't exist,
  116. X            neither does the property.  This should not be considered
  117. X            a fatal error.
  118. X        */
  119. X
  120. X        *property_atom_return = XInternAtom(display, 
  121. X                            property_info->property_name, 
  122. X                            True);
  123. X        if (*property_atom_return == None) {
  124. X            *property_count_return = 0;
  125. X            return PEXUtSuccess;
  126. X        }
  127. X        }
  128. X
  129. X
  130. X        /* 
  131. X        Property atom exists - fetch the property.
  132. X        */
  133. X
  134. X        bytes_unread = 0;
  135. X        item_count = sizeof(XStandardColormap)/4;
  136. X        do {
  137. X        item_count += (bytes_unread+3)/4;
  138. X        result = XGetWindowProperty (display, 
  139. X                    RootWindow(display, screen),
  140. X                    *property_atom_return,
  141. X                    0, item_count, False, 
  142. X                    *property_atom_return,
  143. X                    &actual_type, &actual_format, 
  144. X                    &item_count_return, &bytes_unread,
  145. X                    (unsigned char **) 
  146. X                        property_data_return);
  147. X
  148. X        } while ((result == Success) && (bytes_unread > 0));
  149. X
  150. X        if (result != Success)
  151. X        return PEXUtXFailure;
  152. X
  153. X        *property_count_return = 
  154. X        item_count_return/(sizeof(XStandardColormap)/4);
  155. X
  156. X        return PEXUtSuccess;
  157. X    }
  158. X    else {
  159. X
  160. X        /*
  161. X        Note that XGetRGBColormaps returns a zero status even
  162. X        if nothing is wrong but the property doesn't exist.
  163. X        */
  164. X
  165. X        *property_atom_return = property_info->property_atom;
  166. X
  167. X        result = XGetRGBColormaps (display, 
  168. X                    RootWindow(display, screen),
  169. X                    property_data_return, 
  170. X                    property_count_return, 
  171. X                    *property_atom_return);
  172. X        if (!result) 
  173. X        *property_count_return = 0;
  174. X        return PEXUtSuccess;
  175. X    }
  176. X    
  177. X} /* pexut_get_standard_cmap_property */
  178. X        
  179. X
  180. Xint pexut_get_overlay_visuals_property (
  181. X        display,
  182. X        screen,
  183. X        property_count_return,
  184. X        property_data_return
  185. X        )
  186. X
  187. X        Display                *display;
  188. X        int                screen;
  189. X        int                *property_count_return;
  190. X        overlay_visuals_type        **property_data_return;
  191. X{
  192. X    Atom            property_atom;
  193. X    Atom                actual_type;
  194. X    int            actual_format;
  195. X    unsigned long       item_count;
  196. X    unsigned long       item_count_return, bytes_unread;
  197. X    int            result;
  198. X
  199. X    /*
  200. X        Get the atom from the X server.  If it doesn't exist,
  201. X        neither does the property.
  202. X    */
  203. X
  204. X    property_atom = XInternAtom(display, "SERVER_OVERLAY_VISUALS", True);
  205. X    if (property_atom == None) {
  206. X        return PEXUtXFailure;
  207. X    }
  208. X
  209. X
  210. X    /* 
  211. X        Property atom exists - fetch the property.
  212. X    */
  213. X
  214. X    bytes_unread = 0;
  215. X    item_count = sizeof(overlay_visuals_type)/4;
  216. X    do {
  217. X        item_count += (bytes_unread+3)/4;
  218. X        result = XGetWindowProperty (display, 
  219. X                    RootWindow(display, screen),
  220. X                    property_atom,
  221. X                    0, item_count, False, 
  222. X                    property_atom,
  223. X                    &actual_type, &actual_format, 
  224. X                    &item_count_return, &bytes_unread,
  225. X                    (unsigned char **) property_data_return);
  226. X
  227. X    } while ((result == Success) && (bytes_unread > 0));
  228. X
  229. X    if (result != Success)
  230. X        return PEXUtXFailure;
  231. X
  232. X    *property_count_return = item_count_return/(sizeof(overlay_visuals_type)/4);
  233. X
  234. X    return PEXUtSuccess;
  235. X
  236. X} /* pexut_get_overlay_visuals_property */
  237. X        
  238. X
  239. Xint pexut_evaluate_color_criteria (
  240. X        display,
  241. X        criteria,
  242. X        vis_info,
  243. X        p_info
  244. X        )
  245. X
  246. X        Display                *display;
  247. X        PEXUtVisualCriteria        *criteria;
  248. X        XVisualInfo            *vis_info;
  249. X        visual_info_type        *p_info;
  250. X
  251. X/*
  252. X    Algorithm:
  253. X
  254. X    Section I:    Compute the color resolution numbers.
  255. X            If we have a property entry, use it to do this,
  256. X            otherwise use the Visual description.
  257. X
  258. X    Section II:    Mark the information block as criteria are tested
  259. X            for satisfaction.  Also, keep numbers for the
  260. X            degree to which the available colors surpass the
  261. X            specified minima.
  262. X
  263. X    Section III:    Compute an overall color rating based on to what
  264. X            degree the colors exceed the minima.  If no color
  265. X            criteria were specified, this rating comes out zero.
  266. X
  267. X            If sharable_colormap was a criterion, Visuals that
  268. X            are not named in properties lose their color rating.
  269. X            Visuals that were named in a property, but whose
  270. X            ramps do not meet the criteria, also lose.
  271. X*/
  272. X{
  273. X    PEXEnumTypeIndex    color_approx_type;
  274. X    int            avail_reds, avail_greens, avail_blues;
  275. X    int            avail_colors;
  276. X    int            colors_excess, 
  277. X                total_excess, 
  278. X                reds_excess, 
  279. X                greens_excess, 
  280. X                blues_excess;
  281. X    unsigned long        temp;
  282. X    XStandardColormap    *cmap_info;
  283. X
  284. X
  285. X    /*
  286. X    -----------------------------------------------------------------------
  287. X    Section I:        Compute the color resolution numbers.
  288. X            If we have a property entry, use it to do this,
  289. X            otherwise use the Visual description.
  290. X    -----------------------------------------------------------------------
  291. X    */
  292. X
  293. X    if (PEXUtColorApproxType &
  294. X        (criteria->hard_criteria_mask|criteria->soft_criteria_mask))
  295. X        color_approx_type = criteria->color_approx_type;
  296. X    else
  297. X        color_approx_type = PEXColorSpace;
  298. X
  299. X    if ((p_info->property_ptr != NULL) &&
  300. X        (color_approx_type == PEXColorSpace)) {
  301. X
  302. X        cmap_info = p_info->property_ptr;
  303. X
  304. X        avail_reds = cmap_info->red_max + 1;
  305. X        avail_greens = cmap_info->green_max + 1;
  306. X        avail_blues = cmap_info->blue_max + 1;
  307. X        avail_colors = avail_reds * avail_greens * avail_blues;
  308. X    }
  309. X    else {
  310. X        switch (vis_info->class) {
  311. X
  312. X        case PseudoColor:
  313. X        case StaticColor:
  314. X        case GrayScale:
  315. X        case StaticGray:
  316. X
  317. X        avail_colors = vis_info->colormap_size;
  318. X        avail_reds = vis_info->colormap_size;
  319. X        avail_greens = vis_info->colormap_size;
  320. X        avail_blues = vis_info->colormap_size;
  321. X        break;
  322. X
  323. X        case DirectColor:
  324. X        case TrueColor:
  325. X
  326. X        avail_reds = 1;
  327. X        for (temp = vis_info->red_mask; temp > 0; temp >>= 1) {
  328. X            if (temp & 1)
  329. X            avail_reds *= 2;
  330. X        }
  331. X
  332. X        avail_greens = 1;
  333. X        for (temp = vis_info->green_mask; temp > 0; temp >>= 1) {
  334. X            if (temp & 1)
  335. X            avail_greens *= 2;
  336. X        }
  337. X
  338. X        avail_blues = 1;
  339. X        for (temp = vis_info->blue_mask; temp > 0; temp >>= 1) {
  340. X            if (temp & 1)
  341. X            avail_blues *= 2;
  342. X        }
  343. X        avail_colors = avail_reds * avail_greens * avail_blues;
  344. X        break;
  345. X        }
  346. X    }
  347. X    
  348. X
  349. X    /*
  350. X    -----------------------------------------------------------------------
  351. X    Section II:        Mark the information block as criteria are tested
  352. X            for satisfaction.  Also, keep numbers for the
  353. X            degree to which the available colors surpass the
  354. X            specified minima.
  355. X    -----------------------------------------------------------------------
  356. X    */
  357. X
  358. X    if (PEXUtMinColors &
  359. X        (criteria->hard_criteria_mask | criteria->soft_criteria_mask)) {
  360. X
  361. X        if (avail_colors < criteria->min_colors) {
  362. X        p_info->unmet_hard_criteria |= 
  363. X            (criteria->hard_criteria_mask & PEXUtMinColors);
  364. X        p_info->unmet_soft_criteria |= 
  365. X            (criteria->soft_criteria_mask & PEXUtMinColors);
  366. X        colors_excess = criteria->min_colors - avail_colors;
  367. X        }
  368. X        else
  369. X        colors_excess = avail_colors - criteria->min_colors;
  370. X    }
  371. X    else
  372. X        colors_excess = avail_colors;
  373. X
  374. X    if (PEXUtMinRed &
  375. X        (criteria->hard_criteria_mask | criteria->soft_criteria_mask)) {
  376. X
  377. X        if (avail_reds < criteria->min_red) {
  378. X        p_info->unmet_hard_criteria |= 
  379. X            (criteria->hard_criteria_mask & PEXUtMinRed);
  380. X        p_info->unmet_soft_criteria |= 
  381. X            (criteria->soft_criteria_mask & PEXUtMinRed);
  382. X        reds_excess = criteria->min_red - avail_reds;
  383. X        }
  384. X        else
  385. X        reds_excess =  avail_reds - criteria->min_red;
  386. X    }
  387. X    else
  388. X        reds_excess = 0;
  389. X
  390. X    if (PEXUtMinGreen &
  391. X        (criteria->hard_criteria_mask | criteria->soft_criteria_mask)) {
  392. X
  393. X        if (avail_greens < criteria->min_green) {
  394. X        p_info->unmet_hard_criteria |= 
  395. X            (criteria->hard_criteria_mask & PEXUtMinGreen);
  396. X        p_info->unmet_soft_criteria |= 
  397. X            (criteria->soft_criteria_mask & PEXUtMinGreen);
  398. X        greens_excess = criteria->min_green - avail_greens;
  399. X        }
  400. X        else
  401. X        greens_excess = avail_greens - criteria->min_green;
  402. X    }
  403. X    else
  404. X        greens_excess = 0;
  405. X
  406. X    if (PEXUtMinBlue &
  407. X        (criteria->hard_criteria_mask | criteria->soft_criteria_mask)) {
  408. X
  409. X        if (avail_blues < criteria->min_blue) {
  410. X        p_info->unmet_hard_criteria |= 
  411. X            (criteria->hard_criteria_mask & PEXUtMinBlue);
  412. X        p_info->unmet_soft_criteria |= 
  413. X            (criteria->soft_criteria_mask & PEXUtMinBlue);
  414. X        blues_excess = criteria->min_blue- avail_blues;
  415. X        }
  416. X        else
  417. X        blues_excess = avail_blues - criteria->min_blue;
  418. X    }
  419. X    else
  420. X        blues_excess = 0;
  421. X
  422. X    /*
  423. X    -----------------------------------------------------------------------
  424. X    Section III:    Compute an overall color rating based on to what
  425. X            degree the colors exceed the minima.  If no color
  426. X            criteria were specified, this rating comes out zero.
  427. X
  428. X            If sharable_colormap was a criterion, Visuals that
  429. X            are not named in properties lose their color rating.
  430. X            Visuals that were named in a property, but whose
  431. X            ramps do not meet the criteria, also lose.
  432. X    -----------------------------------------------------------------------
  433. X    */
  434. X
  435. X    total_excess = colors_excess + reds_excess + 
  436. X            greens_excess + blues_excess;
  437. X
  438. X    if (total_excess >= 0xFF0000)         /* 24 bits */
  439. X        p_info->color_rating = MAX_COLOR_RATING;
  440. X    else if (total_excess >= 0xF000)     /* 16 bits */
  441. X        p_info->color_rating = MAX_COLOR_RATING - 1;
  442. X    else if (total_excess >= 0xF00)     /* 12 bits */
  443. X        p_info->color_rating = MAX_COLOR_RATING - 2;
  444. X    else 
  445. X        p_info->color_rating = total_excess;
  446. X
  447. X    /*
  448. X        If caller asked for colormap to NOT be sharable, criteria are
  449. X        met, since any Visual supports private colormaps.
  450. X    */
  451. X
  452. X    if  ((PEXUtSharableColormap &
  453. X        (criteria->hard_criteria_mask | criteria->soft_criteria_mask)) &&
  454. X        (criteria->sharable_colormap)) {
  455. X
  456. X        if ((colors_excess < 0) ||
  457. X        (reds_excess < 0) ||
  458. X        (greens_excess < 0) ||
  459. X        (blues_excess < 0) ||
  460. X        (p_info->property_ptr == NULL)) {
  461. X
  462. X        p_info->unmet_hard_criteria |= 
  463. X            (criteria->hard_criteria_mask & PEXUtSharableColormap);
  464. X        p_info->unmet_soft_criteria |= 
  465. X            (criteria->soft_criteria_mask & PEXUtSharableColormap);
  466. X        p_info->color_rating = 0;
  467. X        }
  468. X    }
  469. X
  470. X    return PEXUtSuccess;
  471. X
  472. X} /* pexut_evaluate_color_criteria */
  473. X
  474. X
  475. Xstatic Bool pexut_is_pex_db_supported(
  476. X        dpy, 
  477. X        win, 
  478. X        db_x )
  479. X
  480. X        Display             *dpy;
  481. X        Window              win;
  482. X        int                 db_x;
  483. X{
  484. X    PEXExtensionInfo    *pexinfo;
  485. X    XWindowAttributes   wattrs;
  486. X    unsigned long       count;
  487. X    PEXRenderingTarget  *target;
  488. X    
  489. X    /*
  490. X    ** Verify the PEX server is major version 5.
  491. X    */
  492. X    pexinfo = PEXGetExtensionInfo( dpy );
  493. X    if ( pexinfo == (PEXExtensionInfo *)NULL )
  494. X        return( False );
  495. X    if ( pexinfo->major_version != 5 )
  496. X        return( False );
  497. X
  498. X    /*
  499. X    ** Get the window attributes for use in later inquiries.
  500. X    */
  501. X    if ( ! XGetWindowAttributes( dpy, win, &wattrs ) )
  502. X        return( False );
  503. X
  504. X    /*
  505. X    ** Try MBX.
  506. X    **
  507. X    ** Verify rendering to MBX buffers is supported.
  508. X    ** Verify the MBX extension is supported and that it is major version 3.
  509. X    ** Verify the MBX extension supports at least 2 buffers for this drawable.
  510. X    */
  511. X    {
  512. X        int first_event, first_error, num, dc;
  513. X    XmbufBufferInfo  *buf_info, *dc_info;
  514. X        
  515. X        if ( ( pexinfo->minor_version == 0 ) ||
  516. X             ( ( pexinfo->minor_version >= 1 ) &&
  517. X           PEXMatchRenderingTargets( dpy, win, wattrs.depth,
  518. X                                         PEXBufferDrawable, wattrs.visual, 1,
  519. X                                         &count, &target ) &&
  520. X               ( count == 1 ) ) ) {
  521. X            if ( XmbufQueryExtension( dpy, &first_event, &first_error ) ) {
  522. X        if ( XmbufGetScreenInfo( dpy, win, &num, &buf_info,
  523. X                     &dc, &dc_info ) ) {
  524. X            if ( buf_info->max_buffers >= 2 )
  525. X            return( True );
  526. X        }
  527. X            }
  528. X        }
  529. X    }
  530. X    
  531. X    /*
  532. X    ** MBX not available, so try double-buffer escapes.
  533. X    **
  534. X    ** The escapes are not usable if db_x;
  535. X    ** the escapes are not available on pre-5.1 servers (unless server is Sun).
  536. X    ** Verify the double-buffer escape is supported.
  537. X    */
  538. X    if ( ! db_x ) {
  539. X        
  540. X        if ( ( pexinfo->minor_version == 1 ) ||
  541. X         (strncmp( pexinfo->vendor_name, "SunPEX 2.0", 10 ) == 0 ) ) {
  542. X
  543. X            int                     enumtypes, i;
  544. X            unsigned long           *enum_counts;
  545. X            PEXEnumTypeDesc         *enum_info;
  546. X
  547. X            enumtypes = PEXETEscape;
  548. X            if ( PEXGetEnumTypeInfo( dpy, win, 1, &enumtypes, PEXETIndex,
  549. X                                     &enum_counts, &enum_info ) ) {
  550. X                for ( i = 0;  i < *enum_counts;  i++ ) {
  551. X                    if ( (short)enum_info[i].index ==
  552. X                         (short)ES_ESCAPE_ET_DBLBUFFER )
  553. X                        return( True );         /* assume rest of E&S escapes */
  554. X                }
  555. X            }
  556. X        }
  557. X    }
  558. X    
  559. X    /*
  560. X    ** Pixmaps are not considered support for double-buffering; rather, pixmaps
  561. X    ** are a mechanism for doing smooth animation when double-buffering is not
  562. X    ** supported.
  563. X    **
  564. X    ** However, return True if rendering to pixmaps is supported
  565. X    ** this is acceptable because the PEXUtDB utilities will double-buffer
  566. X    ** using pixmaps if rendering to pixmaps is supported.
  567. X    */
  568. X    if ( PEXMatchRenderingTargets( dpy, win, wattrs.depth, PEXPixmapDrawable,
  569. X                                   wattrs.visual, 1, &count, &target ) &&
  570. X         ( count == 1 ) ) {
  571. X    return( True );
  572. X    }
  573. X    
  574. X
  575. X    /*
  576. X    ** No double-buffering is supported.
  577. X    */
  578. X    return( False );
  579. X
  580. X} /* pexut_is_pex_db_supported */
  581. X
  582. Xint pexut_evaluate_double_buffering_capability (
  583. X        display,
  584. X        criteria,
  585. X        vis_info,
  586. X        p_info
  587. X        )
  588. X
  589. X        Display                *display;
  590. X        PEXUtVisualCriteria        *criteria;
  591. X        XVisualInfo            *vis_info;
  592. X        visual_info_type        *p_info;
  593. X{
  594. X    int            actual_capabilities;
  595. X    Window            window;
  596. X    int            db_x;
  597. X    int            result;
  598. X
  599. X
  600. X    if  (PEXUtDoubleBufferingCapability &
  601. X        (criteria->hard_criteria_mask | criteria->soft_criteria_mask)) {
  602. X
  603. X        /*
  604. X        Create a temporary unmapped window in the visual.
  605. X        */
  606. X        pexut_create_temporary_window (display, vis_info, &window);
  607. X
  608. X
  609. X        /*
  610. X        Determine if the window's visual supports the desired
  611. X        capabilities.
  612. X        */
  613. X
  614. X        db_x = (criteria->double_buffering_capability 
  615. X            == PEXUtDbufferPEXAndX);
  616. X        result = pexut_is_pex_db_supported (display, window, db_x);
  617. X        if (result)
  618. X        actual_capabilities = db_x ?     PEXUtDbufferPEXAndX: 
  619. X                        PEXUtDbufferPEX;
  620. X        else
  621. X        actual_capabilities = PEXUtDbufferNone;
  622. X
  623. X        /*
  624. X        Destroy the temporary window.
  625. X        */
  626. X        pexut_destroy_temporary_window (display, vis_info, window);
  627. X
  628. X        if (actual_capabilities != criteria->double_buffering_capability) {
  629. X        p_info->unmet_hard_criteria |= 
  630. X            (criteria->hard_criteria_mask & 
  631. X            PEXUtDoubleBufferingCapability);
  632. X        p_info->unmet_soft_criteria |= 
  633. X            (criteria->soft_criteria_mask & 
  634. X            PEXUtDoubleBufferingCapability);
  635. X        }
  636. X    }
  637. X
  638. X    return PEXUtSuccess;
  639. X
  640. X} /* pexut_evaluate_double_buffering_capability */
  641. X
  642. X
  643. Xint pexut_evaluate_color_approx_type (
  644. X        display,
  645. X        criteria,
  646. X        vis_info,
  647. X        p_info
  648. X        )
  649. X
  650. X        Display                *display;
  651. X        PEXUtVisualCriteria        *criteria;
  652. X        XVisualInfo            *vis_info;
  653. X        visual_info_type        *p_info;
  654. X{
  655. X    Window            window;
  656. X    int            found;
  657. X    int            result;
  658. X
  659. X
  660. X    if (PEXUtColorApproxType &
  661. X        (criteria->hard_criteria_mask | criteria->soft_criteria_mask)) {
  662. X
  663. X        /*
  664. X        Create a temporary unmapped window in the visual.
  665. X        */
  666. X        pexut_create_temporary_window (display, vis_info, &window);
  667. X
  668. X        /*
  669. X        Determine support for the color approx type 
  670. X        using GetEnumTypeInfo.
  671. X        */
  672. X        result = pexut_verify_color_approx_type (display, window, 
  673. X                        criteria->color_approx_type);
  674. X
  675. X        /*
  676. X        Destroy the temporary window.
  677. X        */
  678. X        pexut_destroy_temporary_window (display, vis_info, window);
  679. X
  680. X        if (result == PEXUtSuccess)
  681. X        found = True;
  682. X        else if (result == PEXUtCriteriaFailure)
  683. X        found = False;
  684. X        else
  685. X        return result;
  686. X
  687. X        if (!found) {
  688. X        p_info->unmet_hard_criteria |= 
  689. X            (criteria->hard_criteria_mask & PEXUtColorApproxType);
  690. X        p_info->unmet_soft_criteria |= 
  691. X            (criteria->soft_criteria_mask & PEXUtColorApproxType);
  692. X        }
  693. X    }
  694. X
  695. X    return PEXUtSuccess;
  696. X
  697. X} /* pexut_evaluate_color_approx_type */
  698. X
  699. X
  700. X
  701. X
  702. Xunsigned int pexut_compute_overall_rating (
  703. X        p_info
  704. X        )
  705. X
  706. X        visual_info_type    *p_info;
  707. X{
  708. X    unsigned int rating;
  709. X
  710. X    rating = (p_info->order_rating << ORDER_SHIFT) +
  711. X         (p_info->soft_rating << SOFT_SHIFT) +
  712. X         (p_info->class_rating << CLASS_SHIFT) +
  713. X         (p_info->color_rating << COLOR_SHIFT);
  714. X
  715. X    return rating;
  716. X
  717. X} /* pexut_compute_overall_rating */
  718. X
  719. X
  720. Xint pexut_create_temporary_window (
  721. X        display,
  722. X        vis_info,
  723. X        window_return
  724. X        )
  725. X
  726. X        Display                *display;
  727. X        XVisualInfo            *vis_info;
  728. X        Window                *window_return;
  729. X{
  730. X    unsigned long         window_mask;
  731. X    XSetWindowAttributes     window_attrs;
  732. X    Colormap        cmap_id;
  733. X
  734. X
  735. X    /*
  736. X        Create a window using override-redirect.  Do not map it.
  737. X        If the visual is the default, use the root window.
  738. X        Otherwise, create a colormap to use.
  739. X    */
  740. X
  741. X    if (vis_info->visual == DefaultVisual (display, vis_info->screen)) {
  742. X
  743. X        *window_return = RootWindow (display, vis_info->screen);
  744. X        return PEXUtSuccess;
  745. X    }
  746. X    else {
  747. X        cmap_id = XCreateColormap (display, 
  748. X                    RootWindow(display, vis_info->screen),
  749. X                    vis_info->visual, AllocNone );
  750. X        if (cmap_id == None)
  751. X        return PEXUtXFailure;
  752. X
  753. X        window_attrs.colormap = cmap_id;
  754. X        window_mask = CWColormap;
  755. X
  756. X        window_attrs.override_redirect = True;
  757. X        window_mask |= CWOverrideRedirect;
  758. X
  759. X        window_attrs.background_pixel = 0;
  760. X        window_mask |= CWBackPixel;
  761. X
  762. X        window_attrs.border_pixel = 0;
  763. X        window_mask |= CWBorderPixel;
  764. X
  765. X        *window_return = XCreateWindow (display, 
  766. X                    RootWindow (display, vis_info->screen),
  767. X                    10, 10, 1, 1, 0,
  768. X                    vis_info->depth, 
  769. X                    InputOutput,
  770. X                    vis_info->visual,
  771. X                    window_mask,
  772. X                    &(window_attrs));
  773. X
  774. X        if (*window_return == None)
  775. X        return PEXUtXFailure;
  776. X        else
  777. X        return PEXUtSuccess;
  778. X    }
  779. X    
  780. X} /* pexut_create_temporary_window */
  781. X
  782. Xint pexut_destroy_temporary_window (
  783. X        display,
  784. X        vis_info,
  785. X        window
  786. X        )
  787. X
  788. X        Display                *display;
  789. X        XVisualInfo            *vis_info;
  790. X        Window                window;
  791. X{
  792. X    XWindowAttributes    window_attrs;
  793. X
  794. X    /*
  795. X        If this window is not in the default Visual, 
  796. X        the Colormap and Window need to be freed.
  797. X    */
  798. X
  799. X    if (vis_info->visual != DefaultVisual (display, vis_info->screen)) {
  800. X
  801. X        if (XGetWindowAttributes (display, window, &window_attrs))
  802. X        XFreeColormap (display, window_attrs.colormap);
  803. X
  804. X        XDestroyWindow (display, window);
  805. X    }
  806. X
  807. X        return PEXUtSuccess;
  808. X
  809. X} /* pexut_destroy_temporary_window */
  810. X
  811. X
  812. Xint pexut_verify_color_approx_type
  813. X#if NeedFunctionPrototypes
  814. X        (
  815. X        Display                *display,
  816. X        Window                window,
  817. X        PEXEnumTypeIndex        color_approx_type
  818. X        )
  819. X#else
  820. X        (
  821. X        display,
  822. X        window,
  823. X        color_approx_type
  824. X        )
  825. X
  826. X        Display                *display;
  827. X        Window                window;
  828. X        PEXEnumTypeIndex        color_approx_type;
  829. X#endif
  830. X{
  831. X    int            enum_types[1];
  832. X    unsigned long         *count;
  833. X    PEXEnumTypeDesc        *enum_data;
  834. X    int            enum_index;
  835. X    int            found;
  836. X
  837. X    /*
  838. X        Verify that specified color approx type is supported
  839. X        using PEXGetEnumTypeInfo.  If not, return failure.
  840. X    */
  841. X
  842. X    enum_types[0] = PEXETColorApproxType;
  843. X    if (!PEXGetEnumTypeInfo (display, window, 1, enum_types, PEXETIndex, 
  844. X                &count, &enum_data)) {
  845. X
  846. X        return PEXUtPEXFailure;
  847. X    }
  848. X
  849. X    found = False;
  850. X    for (enum_index = 0; enum_index < *count; enum_index++) {
  851. X        if (enum_data[enum_index].index == color_approx_type) {
  852. X        found = True;
  853. X        break;
  854. X        }
  855. X    }
  856. X    PEXFreeEnumInfo (1, count, enum_data);
  857. X
  858. X    if (found)
  859. X        return PEXUtSuccess;
  860. X    else
  861. X        return PEXUtCriteriaFailure;
  862. X
  863. X} /* pexut_verify_color_approx_type */
  864. X
  865. X
  866. Xint pexut_synthesize_cmap_from_visual (
  867. X        vis_info,
  868. X        cmap_info_return
  869. X        )
  870. X
  871. X        XVisualInfo            *vis_info;
  872. X        XStandardColormap        *cmap_info_return;
  873. X{
  874. X    int         num_reds, red_shift, red_mult;
  875. X    int         num_greens, green_shift, green_mult;
  876. X    int         num_blues, blue_shift, blue_mult;
  877. X    int         base_pixel;
  878. X
  879. X    unsigned long     temp;
  880. X    int        depth;
  881. X    int        trial_value, overrun;
  882. X
  883. X
  884. X    switch (vis_info->class) {
  885. X
  886. X    case PseudoColor:
  887. X    case StaticColor:
  888. X        /* 
  889. X        Divide the number of planes into thirds, and then favor
  890. X        equal numbers of red and green planes at the expense
  891. X        of blue planes.  Favor green at the expense of red in tight
  892. X        situations.  This yields 121 in depth 4, 332 in depth 8,
  893. X        444 in depth 12, and 888 in depth 24.
  894. X        */
  895. X
  896. X        depth = vis_info->depth;
  897. X        trial_value = depth / 3;
  898. X        overrun = depth % 3;
  899. X        if (overrun)
  900. X        trial_value += 1;
  901. X        num_greens = (1 << trial_value);
  902. X        num_reds = (1 << trial_value);
  903. X        if ((num_reds * num_greens) >= vis_info->colormap_size)
  904. X        num_reds = (1 << (trial_value-1));
  905. X        num_blues = vis_info->colormap_size / (num_reds * num_greens);
  906. X        red_mult = num_greens * num_blues;
  907. X        green_mult = num_blues;
  908. X        blue_mult = 1;
  909. X        base_pixel = 0;
  910. X        break;
  911. X
  912. X    case GrayScale:
  913. X    case StaticGray:
  914. X
  915. X        /*
  916. X        PEXColorRange is advantageous in gray Visuals 
  917. X        since it uses less cells to achieve the same effect.
  918. X        Here, use the entire colormap for gray levels.
  919. X        */
  920. X
  921. X        num_reds = vis_info->colormap_size;
  922. X        num_greens = vis_info->colormap_size;
  923. X        num_blues = vis_info->colormap_size;
  924. X        red_mult = 1;
  925. X        green_mult = 1;
  926. X        blue_mult = 1;
  927. X        base_pixel = 0;
  928. X        break;
  929. X
  930. X    case DirectColor:
  931. X    case TrueColor:
  932. X
  933. X        /* 
  934. X        Determine the maximum number of color values for each of
  935. X        red, green, and blue, and the corresponding shifts.
  936. X        */
  937. X        num_reds = 1;
  938. X        red_shift = 0;
  939. X        for (temp = vis_info->red_mask; temp > 0; temp >>= 1) {
  940. X        if (temp & 1)
  941. X            num_reds *= 2;
  942. X        else
  943. X            red_shift++;
  944. X        }
  945. X        red_mult = 1 << red_shift;
  946. X
  947. X        num_greens = 1;
  948. X        green_shift = 0;
  949. X        for (temp = vis_info->green_mask; temp > 0; temp >>= 1) {
  950. X        if (temp & 1)
  951. X            num_greens *= 2;
  952. X        else
  953. X            green_shift++;
  954. X        }
  955. X        green_mult = 1 << green_shift;
  956. X
  957. X        num_blues = 1;
  958. X        blue_shift = 0;
  959. X        for (temp = vis_info->blue_mask; temp > 0; temp >>= 1) {
  960. X        if (temp & 1)
  961. X            num_blues *= 2;
  962. X        else
  963. X            blue_shift++;
  964. X        }
  965. X        blue_mult = 1 << blue_shift;
  966. X
  967. X        base_pixel = 0;
  968. X        break;
  969. X    }
  970. X
  971. X    cmap_info_return->colormap = None;
  972. X    cmap_info_return->visualid = vis_info->visualid;
  973. X    cmap_info_return->killid = None;
  974. X
  975. X    cmap_info_return->red_max = num_reds - 1;
  976. X    cmap_info_return->green_max = num_greens - 1;
  977. X    cmap_info_return->blue_max = num_blues - 1;
  978. X    cmap_info_return->red_mult = red_mult;
  979. X    cmap_info_return->green_mult = green_mult;
  980. X    cmap_info_return->blue_mult = blue_mult;
  981. X    cmap_info_return->base_pixel = base_pixel;
  982. X
  983. X    return PEXUtSuccess;
  984. X
  985. X} /* pexut_synthesize_cmap_from_visual */
  986. X
  987. X
  988. Xint pexut_load_color_approx_from_std_cmap (
  989. X        color_approx_type,
  990. X        vis_info,
  991. X        cmap_info,
  992. X        capx_info_return
  993. X        )
  994. X
  995. X        int                color_approx_type;
  996. X        XVisualInfo            *vis_info;
  997. X        XStandardColormap        *cmap_info;
  998. X        PEXColorApproxEntry        *capx_info_return;
  999. X{
  1000. X    /*
  1001. X        If color approx type was not specified, decide it
  1002. X        based on the Visual class.
  1003. X    */
  1004. X
  1005. X    if (color_approx_type == -1) {
  1006. X
  1007. X        if ((vis_info->class == GrayScale) ||
  1008. X        (vis_info->class == StaticGray))
  1009. X        color_approx_type = PEXColorRange;
  1010. X        else
  1011. X        color_approx_type = PEXColorSpace;
  1012. X    }
  1013. X
  1014. X
  1015. X    /*
  1016. X        Transfer information from the standard colormap
  1017. X        property structure into the color approximation entry.
  1018. X    */
  1019. X
  1020. X    if (color_approx_type == PEXColorRange) {
  1021. X
  1022. X        capx_info_return->type = PEXColorRange;
  1023. X        capx_info_return->model = PEXColorApproxRGB;
  1024. X        capx_info_return->dither = PEXOn;
  1025. X        capx_info_return->base_pixel = 0;
  1026. X        capx_info_return->max1 = vis_info->colormap_size-1;
  1027. X        capx_info_return->max2 = 0;
  1028. X        capx_info_return->max3 = 0;
  1029. X        capx_info_return->weight1 = 0.299;
  1030. X        capx_info_return->weight2 = 0.587;
  1031. X        capx_info_return->weight3 = 0.114;
  1032. X        capx_info_return->mult1 = 1;
  1033. X        capx_info_return->mult2 = 0;
  1034. X        capx_info_return->mult3 = 0;
  1035. X    }
  1036. X    else {
  1037. X
  1038. X        capx_info_return->type = PEXColorSpace;
  1039. X        capx_info_return->model = PEXColorApproxRGB;
  1040. X        capx_info_return->dither = PEXOn;
  1041. X        capx_info_return->base_pixel = cmap_info->base_pixel;
  1042. X        capx_info_return->max1 = cmap_info->red_max;
  1043. X        capx_info_return->max2 = cmap_info->green_max;
  1044. X        capx_info_return->max3 = cmap_info->blue_max;
  1045. X        capx_info_return->weight1 = 0.0;
  1046. X        capx_info_return->weight2 = 0.0;
  1047. X        capx_info_return->weight3 = 0.0;
  1048. X        capx_info_return->mult1 = cmap_info->red_mult;
  1049. X        capx_info_return->mult2 = cmap_info->green_mult;
  1050. X        capx_info_return->mult3 = cmap_info->blue_mult;
  1051. X    }
  1052. X
  1053. X    return PEXUtSuccess;
  1054. X
  1055. X} /* pexut_load_color_approx_from_std_cmap */
  1056. X
  1057. X
  1058. Xint pexut_match_color_approx_entry (
  1059. X        entry1,
  1060. X        entry2
  1061. X        )
  1062. X
  1063. X        PEXColorApproxEntry        *entry1;
  1064. X        PEXColorApproxEntry        *entry2;
  1065. X{
  1066. X    int match = 1;
  1067. X
  1068. X
  1069. X    match &= (entry1->type == entry2->type);
  1070. X    match &= (entry1->model == entry2->model);
  1071. X    match &= (entry1->base_pixel == entry2->base_pixel);
  1072. X    match &= (entry1->max1 == entry2->max1);
  1073. X
  1074. X    if (entry1->type == PEXColorSpace) {
  1075. X        match &= (entry1->mult1 == entry2->mult1);
  1076. X        match &= (entry1->max2 == entry2->max2);
  1077. X        match &= (entry1->mult2 == entry2->mult2);
  1078. X        match &= (entry1->max3 == entry2->max3);
  1079. X        match &= (entry1->mult3 == entry2->mult3);
  1080. X    }
  1081. X    else if (entry1->type == PEXColorRange) {
  1082. X        /*
  1083. X        Issue:  how flexible are implementations on the
  1084. X        values of mults or of weights?
  1085. X        We'll be lax and pass everything.
  1086. X        */
  1087. X        ;
  1088. X    }
  1089. X
  1090. X    if (match)
  1091. X        return True;
  1092. X    else
  1093. X        return False;
  1094. X
  1095. X} /* pexut_match_color_approx_entry */
  1096. X
  1097. X
  1098. Xint pexut_create_one_channel_map (
  1099. X        display,
  1100. X        vis_info,
  1101. X        capx_info,
  1102. X        colormap_id_return
  1103. X        )
  1104. X
  1105. X        Display                *display;
  1106. X        XVisualInfo            *vis_info;
  1107. X        PEXColorApproxEntry        *capx_info;
  1108. X        Colormap            *colormap_id_return;
  1109. X
  1110. X/*
  1111. X    Algorithm:
  1112. X
  1113. X    Section I:    Create a Colormap and capture the default values.
  1114. X            Compute the number of cells in the color 
  1115. X            approximation region.
  1116. X    
  1117. X    Section II:    Allocate all the cells in the Colormap read-write.
  1118. X            Load the color approximation region with the
  1119. X            correct colors.
  1120. X*/
  1121. X{
  1122. X    Colormap    cmap_id;
  1123. X    int        num_reds, num_greens, num_blues, num_colors;
  1124. X    unsigned long    *pixels, pixel_value;
  1125. X    XColor        *colors, *p_color;
  1126. X    int        i, j, k;
  1127. X    int        result;
  1128. X
  1129. X
  1130. X    /*
  1131. X    -----------------------------------------------------------------------
  1132. X    Section I:        Create a Colormap and capture the default values.
  1133. X            Compute the number of cells in the color 
  1134. X            approximation region.
  1135. X    -----------------------------------------------------------------------
  1136. X    */
  1137. X
  1138. X    /*
  1139. X        Create the colormap with AllocNone.
  1140. X    */
  1141. X
  1142. X    cmap_id = XCreateColormap ( display, 
  1143. X                    RootWindow (display, vis_info->screen),
  1144. X                    vis_info->visual, AllocNone );
  1145. X    if (cmap_id == None)
  1146. X        return PEXUtXFailure;
  1147. X
  1148. X
  1149. X    /*
  1150. X        If color approx type is PEXColorRange, compute the number of 
  1151. X        cells from max1, typical for GrayScale.
  1152. X
  1153. X        If color approx type is PEXColorSpace, compute the number of 
  1154. X        cells from all three maxes, typical for PseudoColor.
  1155. X    */
  1156. X
  1157. X    if (capx_info->type == PEXColorRange) {
  1158. X
  1159. X        num_colors = capx_info->max1 + 1;
  1160. X    }
  1161. X    else { /* assume PEXColorSpace */
  1162. X
  1163. X        num_reds = capx_info->max1 + 1;
  1164. X        num_greens = capx_info->max2 + 1;
  1165. X        num_blues = capx_info->max3 + 1;
  1166. X        num_colors = num_reds * num_greens * num_blues;
  1167. X    }
  1168. X
  1169. X    if (capx_info->base_pixel >= vis_info->colormap_size) {
  1170. X        XFreeColormap (display, cmap_id);
  1171. X        return PEXUtXFailure;
  1172. X    }
  1173. X    if (capx_info->base_pixel + num_colors > vis_info->colormap_size)
  1174. X        num_colors = vis_info->colormap_size - capx_info->base_pixel;
  1175. X
  1176. X
  1177. X    /*
  1178. X        Query the default colors, or the default Colormap if we're in
  1179. X        that Visual; we will preserve the colors in cells outside the ramp.
  1180. X    */
  1181. X
  1182. X    colors = (XColor *) malloc (vis_info->colormap_size * sizeof(XColor));
  1183. X
  1184. X    if (colors == NULL) {
  1185. X        XFreeColormap (display, cmap_id);
  1186. X        return PEXUtXFailure;
  1187. X    }
  1188. X
  1189. X    for (pixel_value = 0, p_color = colors; 
  1190. X        pixel_value < vis_info->colormap_size;
  1191. X        pixel_value++, p_color++) {
  1192. X
  1193. X        p_color->pixel = pixel_value;
  1194. X    }
  1195. X
  1196. X    if (vis_info->visualid == 
  1197. X        XVisualIDFromVisual(DefaultVisual(display, vis_info->screen)))
  1198. X        XQueryColors (display, DefaultColormap(display, vis_info->screen), 
  1199. X            colors, vis_info->colormap_size);
  1200. X    else
  1201. X        XQueryColors (display, cmap_id, 
  1202. X            colors, vis_info->colormap_size);
  1203. X
  1204. X
  1205. X    /*
  1206. X    -----------------------------------------------------------------------
  1207. X    Section II:        Allocate all the cells in the Colormap read-write.
  1208. X            Load the color approximation region with the
  1209. X            correct colors.
  1210. X    -----------------------------------------------------------------------
  1211. X    */
  1212. X
  1213. X    /*
  1214. X        Allocate all cells read/write using XAllocColorCells.
  1215. X    */
  1216. X
  1217. X    pixels = (unsigned long *) 
  1218. X            malloc (vis_info->colormap_size * sizeof(unsigned long));
  1219. X    if (pixels == NULL) {
  1220. X        XFreeColormap (display, cmap_id);
  1221. X        return PEXUtXFailure;
  1222. X    }
  1223. X
  1224. X    result = XAllocColorCells ( display, cmap_id, True,
  1225. X                    (unsigned long *) NULL, 0, 
  1226. X                    pixels, vis_info->colormap_size);
  1227. X    free (pixels);
  1228. X    if (! result) {
  1229. X        XFreeColormap (display, cmap_id);
  1230. X        return PEXUtXFailure;
  1231. X    }
  1232. X
  1233. X
  1234. X    /*
  1235. X        Load the colors into the cells.  Even if the visual
  1236. X        is PseudoColor, if the color approx type is PEXColorRange,
  1237. X        we will load a ramp of gray values (since we have no idea
  1238. X        what the colors should be).  Similarly, even for GrayScale,
  1239. X        PEXColorSpace will load a color space sampling.
  1240. X    */
  1241. X
  1242. X    for (pixel_value = 0, p_color = colors;
  1243. X        pixel_value < capx_info->base_pixel;
  1244. X        pixel_value++, p_color++) {
  1245. X
  1246. X        p_color->flags = DoRed | DoGreen | DoBlue;
  1247. X    }
  1248. X
  1249. X    if (capx_info->type == PEXColorRange) {
  1250. X
  1251. X        pixel_value = capx_info->base_pixel;
  1252. X        p_color = colors + capx_info->base_pixel;
  1253. X        for (i = 0; i < num_colors; i++) {
  1254. X
  1255. X        p_color->flags = DoRed | DoGreen | DoBlue;
  1256. X        p_color->pixel = pixel_value++;
  1257. X        p_color->red =
  1258. X        p_color->green =
  1259. X        p_color->blue = i * 65535 / (num_colors - 1);
  1260. X        p_color++;
  1261. X        }
  1262. X    }
  1263. X    else { /* assume PEXColorSpace */
  1264. X
  1265. X        pixel_value = capx_info->base_pixel;
  1266. X        p_color = colors + capx_info->base_pixel;
  1267. X
  1268. X        /*
  1269. X        The following logic can be coded more generally 
  1270. X        but hasn't been, yet.
  1271. X        */
  1272. X
  1273. X        if (capx_info->mult1 > capx_info->mult3) {
  1274. X        if (capx_info->mult2 > capx_info->mult1) {
  1275. X
  1276. X            /* 
  1277. X            Set up GBR ramp, as on Sun.
  1278. X            */
  1279. X            for (i = 0; (i < num_greens) && 
  1280. X            (pixel_value < vis_info->colormap_size); i++) {
  1281. X            for (j = 0; (j < num_blues) && 
  1282. X                (pixel_value < vis_info->colormap_size); j++) {
  1283. X                for (k = 0; (k < num_reds) && 
  1284. X                (pixel_value < vis_info->colormap_size); k++) {
  1285. X
  1286. X                p_color->flags = DoRed | DoGreen | DoBlue;
  1287. X                p_color->pixel = pixel_value++;
  1288. X                p_color->red = k * 65535 / capx_info->max1;
  1289. X                p_color->green = i * 65535 / capx_info->max2;
  1290. X                p_color->blue = j * 65535 / capx_info->max3;
  1291. X                p_color++;
  1292. X
  1293. X                if (pixel_value == vis_info->colormap_size) 
  1294. X                    break;
  1295. X                }
  1296. X            }
  1297. X            }
  1298. X        }
  1299. X        else {
  1300. X
  1301. X            /* 
  1302. X            Set up RGB ramp, as on HP, DEC, Kubota Pacific, 
  1303. X            Oki, some NCD.
  1304. X            */
  1305. X            for (i = 0; (i < num_reds) && 
  1306. X            (pixel_value < vis_info->colormap_size); i++) {
  1307. X            for (j = 0; (j < num_greens) && 
  1308. X                (pixel_value < vis_info->colormap_size); j++) {
  1309. X                for (k = 0; (k < num_blues) && 
  1310. X                (pixel_value < vis_info->colormap_size); k++) {
  1311. X
  1312. X                p_color->flags = DoRed | DoGreen | DoBlue;
  1313. X                p_color->pixel = pixel_value++;
  1314. X                p_color->red = i * 65535 / capx_info->max1;
  1315. X                p_color->green = j * 65535 / capx_info->max2;
  1316. X                p_color->blue = k * 65535 / capx_info->max3;
  1317. X                p_color++;
  1318. X
  1319. X                if (pixel_value == vis_info->colormap_size) 
  1320. X                    break;
  1321. X                }
  1322. X            }
  1323. X            }
  1324. X        }
  1325. X        }
  1326. X        else {
  1327. X
  1328. X        /* 
  1329. X            Set up BGR ramp, as on IBM, SHOgraphics, Tektronix, 
  1330. X            some NCD.
  1331. X        */
  1332. X        for (i = 0; (i < num_blues) && 
  1333. X            (pixel_value < vis_info->colormap_size); i++) {
  1334. X            for (j = 0; (j < num_greens) && 
  1335. X                (pixel_value < vis_info->colormap_size); j++) {
  1336. X            for (k = 0; (k < num_reds) && 
  1337. X                (pixel_value < vis_info->colormap_size); k++) {
  1338. X
  1339. X                p_color->flags = DoRed | DoGreen | DoBlue;
  1340. X                p_color->pixel = pixel_value++;
  1341. X                p_color->red = k * 65535 / capx_info->max1;
  1342. X                p_color->green = j * 65535 / capx_info->max2;
  1343. X                p_color->blue = i * 65535 / capx_info->max3;
  1344. X                p_color++;
  1345. X
  1346. X                if (pixel_value == vis_info->colormap_size) break;
  1347. X            }
  1348. X            }
  1349. X        }
  1350. X        }
  1351. X    }
  1352. X
  1353. X    for (pixel_value = capx_info->base_pixel + num_colors, 
  1354. X        p_color = colors;
  1355. X        pixel_value < vis_info->colormap_size;
  1356. X        pixel_value++, p_color++) {
  1357. X
  1358. X        p_color->flags = DoRed | DoGreen | DoBlue;
  1359. X    }
  1360. X
  1361. X    XStoreColors (display, cmap_id, colors, vis_info->colormap_size);
  1362. X    free (colors);
  1363. X
  1364. X
  1365. X    /*
  1366. X        Optional:  could free cells outside the ramp at this
  1367. X        point, and/or reallocate cells as read-only so 
  1368. X        XAllocColor might work.  At the very least, should
  1369. X        make sure that black and white can be found.  However,
  1370. X        currently leaving implementation of policy to the caller.
  1371. X        See PEXUtCopyColormapAsReadOnly().
  1372. X    */
  1373. X
  1374. X    *colormap_id_return = cmap_id;
  1375. X    return PEXUtSuccess;
  1376. X
  1377. X} /* pexut_create_one_channel_map */
  1378. X
  1379. X
  1380. Xint pexut_create_three_channel_map (
  1381. X        display,
  1382. X        vis_info,
  1383. X        capx_info,
  1384. X        colormap_id_return
  1385. X        )
  1386. X
  1387. X        Display                *display;
  1388. X        XVisualInfo            *vis_info;
  1389. X        PEXColorApproxEntry        *capx_info;
  1390. X        Colormap            *colormap_id_return;
  1391. X{
  1392. X    Colormap    cmap_id;
  1393. X    int        num_colors;
  1394. X    int        num_reds, num_greens, num_blues;
  1395. X    int        red_shift, green_shift, blue_shift;
  1396. X    int        vis_red_shift, vis_green_shift, vis_blue_shift;
  1397. X    unsigned long    temp;
  1398. X    unsigned long    *pixels;
  1399. X    XColor        *colors, *p_color;
  1400. X    int        i;
  1401. X    int        result;
  1402. X
  1403. X
  1404. X    /*
  1405. X        Create the colormap with AllocNone.
  1406. X    */
  1407. X
  1408. X    cmap_id = XCreateColormap ( display, 
  1409. X                    RootWindow (display, vis_info->screen),
  1410. X                    vis_info->visual, AllocNone );
  1411. X    if (cmap_id == None)
  1412. X        return PEXUtXFailure;
  1413. X
  1414. X
  1415. X    /*
  1416. X        Compute the color shifts for r, g, b.
  1417. X        Making an major assumption that the number of levels of
  1418. X        each component are all powers of two.
  1419. X        Compute the number of cells to write as the maximum
  1420. X        count for any of the three channels.
  1421. X    */
  1422. X
  1423. X    num_reds = capx_info->max1 + 1;
  1424. X    for (red_shift = 0, temp = capx_info->mult1;
  1425. X        temp > 1; red_shift++, temp >>= 1);
  1426. X    vis_red_shift = 0;
  1427. X    temp = vis_info->red_mask;
  1428. X    while (!(temp & 0x1)) {
  1429. X        vis_red_shift++;
  1430. X        temp >>= 1;
  1431. X    }
  1432. X
  1433. X    num_greens = capx_info->max2 + 1;
  1434. X    for (green_shift = 0, temp = capx_info->mult2;
  1435. X        temp > 1; green_shift++, temp >>= 1);
  1436. X    vis_green_shift = 0;
  1437. X    temp = vis_info->green_mask;
  1438. X    while (!(temp & 0x1)) {
  1439. X        vis_green_shift++;
  1440. X        temp >>= 1;
  1441. X    }
  1442. X
  1443. X    num_blues = capx_info->max3 + 1;
  1444. X    for (blue_shift = 0, temp = capx_info->mult3;
  1445. X        temp > 1; blue_shift++, temp >>= 1);
  1446. X    vis_blue_shift = 0;
  1447. X    temp = vis_info->blue_mask;
  1448. X    while (!(temp & 0x1)) {
  1449. X        vis_blue_shift++;
  1450. X        temp >>= 1;
  1451. X    }
  1452. X
  1453. X    if ((red_shift != vis_red_shift) ||
  1454. X        (green_shift != vis_green_shift) ||
  1455. X        (blue_shift != vis_blue_shift)) {
  1456. X        XFreeColormap (display, cmap_id);
  1457. X        return PEXUtXFailure;
  1458. X    }
  1459. X    
  1460. X
  1461. X    num_colors = num_reds;
  1462. X    if (num_greens > num_colors) num_colors = num_greens;
  1463. X    if (num_blues > num_colors) num_colors = num_blues;
  1464. X
  1465. X    if (capx_info->base_pixel >= vis_info->colormap_size) {
  1466. X        XFreeColormap (display, cmap_id);
  1467. X        return PEXUtXFailure;
  1468. X    }
  1469. X    if (capx_info->base_pixel + num_colors > vis_info->colormap_size)
  1470. X        num_colors = vis_info->colormap_size - capx_info->base_pixel;
  1471. X
  1472. X
  1473. X    /*
  1474. X        Allocate all cells read/write using XAllocColorCells.
  1475. X    */
  1476. X
  1477. X    pixels = (unsigned long *) 
  1478. X            malloc (vis_info->colormap_size * sizeof(unsigned long));
  1479. X    if (pixels == NULL) {
  1480. X        XFreeColormap (display, cmap_id);
  1481. X        return PEXUtXFailure;
  1482. X    }
  1483. X
  1484. X    result = XAllocColorCells ( display, cmap_id, True,
  1485. X                    (unsigned long *) NULL, 0, 
  1486. X                    pixels, vis_info->colormap_size);
  1487. X    free (pixels);
  1488. X    if (! result) {
  1489. X        XFreeColormap (display, cmap_id);
  1490. X        return PEXUtXFailure;
  1491. X    }
  1492. X
  1493. X
  1494. X    /*
  1495. X        Load the colors into the cells.
  1496. X    */
  1497. X
  1498. X    colors = (XColor *) malloc (num_colors * sizeof(XColor));
  1499. X
  1500. X    if (colors == NULL) {
  1501. X        XFreeColormap (display, cmap_id);
  1502. X        return PEXUtXFailure;
  1503. X    }
  1504. X
  1505. X    for (i = 0, p_color = colors; i < num_colors; i++, p_color++) {
  1506. X
  1507. X        p_color->flags = 0;
  1508. X        p_color->pixel = capx_info->base_pixel;
  1509. X
  1510. X        if (i < num_reds) {
  1511. X        p_color->flags |= DoRed;
  1512. X        p_color->pixel |= (i << red_shift);
  1513. X        p_color->red = i * 65535 / capx_info->max1;
  1514. X        }
  1515. X
  1516. X        if (i < num_greens) {
  1517. X        p_color->flags |= DoGreen;
  1518. X        p_color->pixel |= (i << green_shift);
  1519. X        p_color->green = i * 65535 / capx_info->max2;
  1520. X        }
  1521. X
  1522. X        if (i < num_blues) {
  1523. X        p_color->flags |= DoBlue;
  1524. X        p_color->pixel |= (i << blue_shift);
  1525. X        p_color->blue = i * 65535 / capx_info->max3;
  1526. X        }
  1527. X    }
  1528. X
  1529. X    XStoreColors (display, cmap_id, colors, num_colors);
  1530. X    free (colors);
  1531. X
  1532. X    /*
  1533. X        Optional:  could free cells outside the ramp at this
  1534. X        point, and/or reallocate cells as read-only so 
  1535. X        XAllocColor might work.  At the very least, should
  1536. X        make sure that black and white can be found.  However,
  1537. X        currently leaving implementation of policy to the caller.
  1538. X        See PEXUtCopyColormapAsReadOnly().
  1539. X    */
  1540. X
  1541. X
  1542. X    *colormap_id_return = cmap_id;
  1543. X    return PEXUtSuccess;
  1544. X
  1545. X} /* pexut_create_three_channel_map */
  1546. X
  1547. X
  1548. Xint pexut_create_read_only_map (
  1549. X        display,
  1550. X        vis_info,
  1551. X        capx_info,
  1552. X        colormap_id_return
  1553. X        )
  1554. X
  1555. X        Display                *display;
  1556. X        XVisualInfo            *vis_info;
  1557. X        PEXColorApproxEntry        *capx_info;
  1558. X        Colormap            *colormap_id_return;
  1559. X{
  1560. X    /*
  1561. X        Create the colormap with AllocNone.
  1562. X    */
  1563. X
  1564. X    *colormap_id_return = XCreateColormap ( display, 
  1565. X                    RootWindow (display, vis_info->screen),
  1566. X                    vis_info->visual, AllocNone );
  1567. X
  1568. X    /*
  1569. X        Optional:  could verify that the ramp is actually represented
  1570. X        in the colormap, and return an error if not.  Left as an exercise.
  1571. X        */
  1572. X
  1573. X
  1574. X    if (*colormap_id_return == None)
  1575. X        return PEXUtXFailure;
  1576. X    else
  1577. X        return PEXUtSuccess;
  1578. X
  1579. X} /* pexut_create_read_only_map */
  1580. X
  1581. X
  1582. Xint pexut_count_bits_in_mask (
  1583. X        mask
  1584. X        )
  1585. X
  1586. X        unsigned int mask;
  1587. X{
  1588. X    int count = 0;
  1589. X
  1590. X    while (mask) {
  1591. X    if (mask & 0x1) count++;
  1592. X    mask >>= 1;
  1593. X    }
  1594. X
  1595. X    return count;
  1596. X
  1597. X} /* pexut_count_bits_in_mask */
  1598. X
  1599. END_OF_FILE
  1600.   if test 41041 -ne `wc -c <'util/pexutcmapint.c'`; then
  1601.     echo shar: \"'util/pexutcmapint.c'\" unpacked with wrong size!
  1602.   fi
  1603.   # end of 'util/pexutcmapint.c'
  1604. fi
  1605. if test -f 'wks.c' -a "${1}" != "-c" ; then 
  1606.   echo shar: Will not clobber existing file \"'wks.c'\"
  1607. else
  1608.   echo shar: Extracting \"'wks.c'\" \(15095 characters\)
  1609.   sed "s/^X//" >'wks.c' <<'END_OF_FILE'
  1610. X#ifdef SCCS
  1611. Xstatic char sccsid[]="@(#)wks.c    1.10 Oki 93/05/24";
  1612. X#endif
  1613. X/*
  1614. X            Copyright (c) 1992 by 
  1615. X            Oki Electric Industry Co., Ltd.
  1616. X            All Rights Reserved
  1617. X    
  1618. X    
  1619. X    This file is under sccs control at Oki in:
  1620. X    /nfs/sole/root/sccs1.p/X11R5/mit/demos/pexdraw/s.wks.c
  1621. X*/
  1622. X/*
  1623. X *            Copyright (c) 1992 by
  1624. X *            Oki Electric Industry Co., Ltd.
  1625. X *            All Rights Reserved
  1626. X *
  1627. X * Permission to use, copy, modify, and distribute this software and its
  1628. X * documentation for any purpose and without fee is hereby granted,
  1629. X * provided that the above copyright notice appear in all copies and that
  1630. X * both that copyright notice and this permission notice appear in
  1631. X * supporting documentation, and that the name of Oki Electric not be
  1632. X * used in advertising or publicity pertaining to distribution of the
  1633. X * software without specific, written prior permission. Oki Electric
  1634. X * makes no representations about the suitability of this software for any
  1635. X * purpose.  It is provided "as is" without express or implied warranty.
  1636. X *
  1637. X *************************************************************************
  1638. X * wks.c - the methods for using a PHIGS Workstation resource as the
  1639. X * render object.
  1640. X *
  1641. X *  wksInit
  1642. X *  wksReDraw
  1643. X *  wksMapXtoMC
  1644. X *  wksMapMCtoX
  1645. X *  wksSetView
  1646. X *  wksSetNPCtoDC
  1647. X *  wksPost
  1648. X *  wksDeleteAll
  1649. X *  wksPickOne
  1650. X */
  1651. X
  1652. X
  1653. X#include <stdio.h>
  1654. X
  1655. X#include <math.h>
  1656. X
  1657. X#include <X11/Xlib.h>
  1658. X#include <X11/Xutil.h>
  1659. X#include <X11/Xatom.h>
  1660. X
  1661. X#include <X11/PEX5/PEXlib.h>
  1662. X#include "pexdraw.h"
  1663. X
  1664. X/*************************************************************************
  1665. X * State Variables
  1666. X */
  1667. Xstatic int myMCSeqNo = -1;
  1668. Xstatic int thePickInitFlag = 0;
  1669. X
  1670. X/* L O C A L  P r o c s */
  1671. X/*************************************************************************
  1672. X * MapWcPointsToX
  1673. X *
  1674. X */
  1675. Xstatic int
  1676. XMapWcPointsToX( wkid, view, nCoords, wcPoints, xPoints )
  1677. X     int wkid;
  1678. X     int view;
  1679. X     int nCoords;
  1680. X     PEXCoord *wcPoints;
  1681. X     XPoint *xPoints;
  1682. X{
  1683. X  PEXCoord p, q;
  1684. X  int i;
  1685. X  int error;
  1686. X  unsigned long valueMask[2];
  1687. X  PEXWorkstationAttributes *wksAttrs;
  1688. X  float winWidth, winHeight, winX, winY, XX, XY;
  1689. X  XPoint *xp = xPoints;
  1690. X  float scale;
  1691. X  XWindowAttributes winAttrs;
  1692. X  PEXMatrix WCtoXC, NPCtoXC;
  1693. X
  1694. X  /*
  1695. X   * We rely on the fact that we always use the whole window for the
  1696. X   * Workstation viewport.  Get the information we want, incase this
  1697. X   * scratch area gets creamed.
  1698. X   */
  1699. X  valueMask[0] = valueMask[1] = 0;
  1700. X
  1701. X  PEXSetPWAttributeMask(valueMask,PEXPWCurViewport);
  1702. X  PEXSetPWAttributeMask(valueMask,PEXPWCurNPCSubVolume);
  1703. X  
  1704. X  if (!(wksAttrs = PEXGetWorkstationAttributes(theDisplay, wkid,
  1705. X                           valueMask ))) {
  1706. X    return (-1);
  1707. X  }
  1708. X
  1709. X  XGetWindowAttributes(theDisplay, theWindow, &winAttrs );
  1710. X
  1711. X
  1712. X    /* ???
  1713. X   if (wksAttrs->cur_workstation_viewport.use_drawable) {
  1714. X    wksAttrs->cur_workstation_viewport.max.x = winAttrs.width;
  1715. X    wksAttrs->cur_workstation_viewport.max.y = winAttrs.height;
  1716. X   }
  1717. X     */
  1718. X
  1719. X
  1720. X  error = PEXNPCToXCTransform( &wksAttrs->cur_npc_subvolume, 
  1721. X            (PEXDeviceCoord *)&wksAttrs->cur_workstation_viewport, 
  1722. X                            winAttrs.height, NPCtoXC );
  1723. X  if(error != 0) printf("imagine a Motif alarm, NPCtoXC err = %d\n",error);
  1724. X
  1725. X  PEXMatrixMult( theMatMap, theMatOri, WCtoXC );
  1726. X  PEXMatrixMult( NPCtoXC, WCtoXC, WCtoXC );
  1727. X
  1728. X  for (i = 0; i < nCoords; i++, xp++ ) {
  1729. X    PEXTransformPoints(WCtoXC, 1, &wcPoints[i], &p);
  1730. X    xp->x = (int)p.x;
  1731. X    xp->y = (int)p.y;
  1732. X  }
  1733. X  PEXFreeWorkstationAttributes(wksAttrs);
  1734. X  return (0);
  1735. X}
  1736. X
  1737. X
  1738. X/*************************************************************************
  1739. X * InitPickDevice
  1740. X */
  1741. XPEXPickMeasure
  1742. XInitPickDevice()
  1743. X{
  1744. X  PEXNameSet incl, excl;
  1745. X  PEXName names[3];
  1746. X  PEXBitmask  pickDevMask;
  1747. X  PEXPDAttributes pickDevValues;
  1748. X  PEXPickMeasure pmID;
  1749. X/*
  1750. X * - first we need to setup the device. This is an appendage to the PHIGS
  1751. X *     Workstation. DC_Hit box is required, assume it is there.
  1752. X *   - pick inclusion & pick exclusion NameSets (need to create)
  1753. X *      then we free them, so they just live in the pick device.
  1754. X *   - echo switch, set to no echo.
  1755. X */
  1756. X  incl = PEXCreateNameSet(theDisplay);
  1757. X  names[0] = 1; names[1] = 2; names[2] = 3; /* do an extra, for the heck */
  1758. X  PEXChangeNameSet(theDisplay, incl, PEXNSAdd, 3, names);
  1759. X  excl = PEXCreateNameSet(theDisplay);
  1760. X
  1761. X
  1762. X  pickDevMask = PEXPDPickIncl | PEXPDPickExcl | PEXPDEchoSwitch;
  1763. X  pickDevValues.inclusion = incl;
  1764. X  pickDevValues.exclusion = excl;
  1765. X  pickDevValues.echo_switch = 0;
  1766. X  PEXChangePickDevice(theDisplay, theRenderObj, PEXPickDeviceDCHitBox,
  1767. X               pickDevMask, &pickDevValues);
  1768. X  /* hmm... should free nameSets now...*/
  1769. X
  1770. X  return (pmID);
  1771. X}
  1772. X
  1773. X/*************************************************************************
  1774. X *
  1775. X */
  1776. XXID  wksInit( dpy,  w, colorLUT, lightLUT, textLUT, depthCueLUT,colorApproxLUT)
  1777. X     Display *dpy;
  1778. X     Window w;
  1779. X     PEXLookupTable colorLUT;
  1780. X     PEXLookupTable lightLUT;
  1781. X     PEXLookupTable textLUT;
  1782. X     PEXLookupTable depthCueLUT;
  1783. X     PEXLookupTable colorApproxLUT;
  1784. X{
  1785. X  XID                           renderObj;
  1786. X  PEXLookupTable        lineBT, markerBT, textBT, interiorBT, edgeBT;
  1787. X  PEXLookupTable        patT;
  1788. X  PEXNameSet            incl, excl;
  1789. X  int                           dbflag;
  1790. X
  1791. X  lineBT = PEXCreateLookupTable( dpy, w, PEXLUTLineBundle );
  1792. X  markerBT = PEXCreateLookupTable( dpy, w, PEXLUTMarkerBundle );
  1793. X  textBT = PEXCreateLookupTable( dpy, w, PEXLUTTextBundle );
  1794. X  interiorBT = PEXCreateLookupTable( dpy, w, 
  1795. X                    PEXLUTInteriorBundle );
  1796. X  edgeBT = PEXCreateLookupTable( dpy, w, PEXLUTEdgeBundle );
  1797. X  patT = PEXCreateLookupTable( dpy, w, PEXLUTPattern );
  1798. X  incl = PEXCreateNameSet(dpy);
  1799. X  excl = PEXCreateNameSet(dpy);
  1800. X
  1801. X  if (CheckImpDepInteger(PEXIDDoubleBufferingSupported)) {
  1802. X    dbflag = PEXDoubleBuffered;
  1803. X}  else  {
  1804. X    dbflag = PEXSingleBuffered;
  1805. X}
  1806. X
  1807. X  renderObj =  PEXCreateWorkstation(dpy, w,
  1808. X                          lineBT, markerBT, textBT,
  1809. X                          interiorBT, edgeBT,
  1810. X                          colorLUT,
  1811. X                          patT, textLUT,
  1812. X                          depthCueLUT,
  1813. X                          lightLUT,
  1814. X                          colorApproxLUT,
  1815. X                          incl, excl, incl, excl,
  1816. X                          dbflag );
  1817. X
  1818. X  if (CheckEnumType(PEXETHLHSRMode,PEXHLHSRZBuffer)) {
  1819. X    PEXSetWorkstationHLHSRMode(dpy, renderObj,
  1820. X                   PEXHLHSRZBuffer);
  1821. X  }
  1822. X
  1823. X  PEXSetWorkstationDisplayUpdateMode(dpy, renderObj,
  1824. X                     PEXVisualizeNone);
  1825. X  return (renderObj);
  1826. X}
  1827. X
  1828. X/*************************************************************************
  1829. X * ReDraw - does a redraw for the workstation case.
  1830. X */
  1831. Xvoid  wksReDraw()
  1832. X{
  1833. X  PEXRedrawAllStructures(theDisplay, theRenderObj);
  1834. X  XFlush(theDisplay);
  1835. X}
  1836. X
  1837. X/*************************************************************************
  1838. X * MapPoints 
  1839. X */
  1840. Xint  wksMapXToMC(mc, nCoords, xPoints, mcPoints )
  1841. X     MCMatrix *mc;
  1842. X     int nCoords;
  1843. X     XPoint *xPoints;
  1844. X     PEXCoord **mcPoints;
  1845. X{
  1846. X  PEXCoord *p, *wcPts; 
  1847. X  int i, error;
  1848. X  unsigned int viewIndex;
  1849. X  unsigned long nPts;
  1850. X  PEXDeviceCoord *pdc;
  1851. X  PEXMatrix mci;
  1852. X  PEXCoord q;
  1853. X  Status status;
  1854. X
  1855. X/* hack, hack - this should be in wksSetView but it gets a proto error there ?
  1856. X * ?
  1857. X */
  1858. X  PEXSetWorkstationViewPriority(theDisplay, theRenderObj, 1, 0, PEXHigher);
  1859. X
  1860. X  /* should just do this, but ... */
  1861. X
  1862. X  pdc = (PEXDeviceCoord *)malloc(nCoords*sizeof(PEXDeviceCoord));
  1863. X  if (!pdc) return(0);
  1864. X
  1865. X  for  (i = 0; i < nCoords; i++ ) {
  1866. X    pdc[i].x = xPoints[i].x;
  1867. X    pdc[i].y = theWinHeight - xPoints[i].y;
  1868. X    pdc[i].z = theDepth;
  1869. X  }
  1870. X
  1871. X  status = PEXMapDCToWC(theDisplay, theRenderObj, nCoords, pdc,
  1872. X          &viewIndex, &nPts, mcPoints );
  1873. X  if (!status || (nPts != nCoords )) {
  1874. X    printf("need %d points, got %d\n", nCoords, nPts );
  1875. X    if (*mcPoints) XFree((char *)*mcPoints);
  1876. X    *mcPoints = (PEXCoord *)0;
  1877. X    return (0);
  1878. X  }
  1879. X
  1880. X  error = PEXInvertMatrix( mc->matrix, mci );
  1881. X  if(error != 0) printf("imagine a Motif alarm, Invert err = %d\n",error);
  1882. X
  1883. X  /* take to Model Space BUG!!! 
  1884. X    PEXTransformPoints(mci, nCoords, *mcPoints, *mcPoints);
  1885. X   */
  1886. X  for (i = 0; i < nCoords; i++ ) {
  1887. X    PEXTransformPoints(mci, 1, &((*mcPoints)[i]), &q);
  1888. X    (*mcPoints)[i] = q;
  1889. X  }
  1890. X
  1891. X  return (nCoords);
  1892. X}
  1893. X
  1894. X/*************************************************************************
  1895. X * MapMCToX
  1896. X *
  1897. X * MC xform struct.
  1898. X * count
  1899. X * points in
  1900. X * returns points out.
  1901. X * functions returns count
  1902. X */
  1903. Xint wksMapMCToX( mc, inCount, mcPoints, xPoints )
  1904. X     MCMatrix *mc;
  1905. X     int inCount;
  1906. X     PEXCoord *mcPoints;
  1907. X     XPoint **xPoints;
  1908. X{
  1909. X  int error;
  1910. X
  1911. X  *xPoints = (XPoint *)malloc(inCount*sizeof(XPoint));
  1912. X  if (!xPoints) { return (900); }
  1913. X
  1914. X  /* take to Model Space */
  1915. X  PEXTransformPoints(mc->matrix, inCount, mcPoints, mcPoints);
  1916. X
  1917. X  if (error = MapWcPointsToX(theRenderObj, 1, inCount, mcPoints, *xPoints )) {
  1918. X    printf("dream on wksMapMCToX\n");
  1919. X    return (0);
  1920. X  }
  1921. X
  1922. X  return(inCount);
  1923. X}
  1924. X
  1925. X/*************************************************************************
  1926. X *
  1927. X */
  1928. Xvoid  wksSetView( viewNumber, view)
  1929. X     int viewNumber;
  1930. X     PEXViewEntry *view;
  1931. X{
  1932. X  PEXSetWorkstationViewRep( theDisplay, theRenderObj, viewNumber, view);
  1933. X
  1934. X/*
  1935. X * we want to work in view 1, so when points get mapped make sure they 
  1936. X * have a preference for view 1.
  1937. X * pset_view_tran_in_pri(thePHIGSWorkstation, 1, 0, PPRI_HIGHER );
  1938. X */
  1939. X/*
  1940. X  PEXSetWorkstationViewPriority(theDisplay, theRenderObj, viewNumber, 0,
  1941. X                PEXHigher);
  1942. X*/
  1943. X}
  1944. X
  1945. Xvoid  wksSetNPCToDC( volume, viewport )
  1946. X     PEXNPCSubVolume *volume;
  1947. X     PEXViewport *viewport;
  1948. X{
  1949. X   PEXSetWorkstationViewport(theDisplay, theRenderObj, viewport);
  1950. X
  1951. X   PEXSetWorkstationWindow(theDisplay, theRenderObj, volume);
  1952. X }
  1953. X
  1954. Xvoid  wksPost( struxid )
  1955. X     long struxid;
  1956. X{
  1957. X  PEXPostStructure(theDisplay, theRenderObj, struxid, 0.0);
  1958. X}
  1959. X
  1960. Xvoid  wksUnpost( struxid )
  1961. X     long struxid;
  1962. X{
  1963. X  PEXUnpostStructure(theDisplay, theRenderObj, struxid);
  1964. X}
  1965. X
  1966. X/*************************************************************************
  1967. X *  DeleteAllStrux
  1968. X *
  1969. X *  PHIGS Workstation Version, get all of the posted structres and delete them
  1970. X *  Should probably do a PEXGetDescendants, to be really thorough.
  1971. X */
  1972. Xvoid  wksDeleteAll()
  1973. X{
  1974. X  int i;
  1975. X  PEXBitmask valueMask[2];
  1976. X  PEXWorkstationAttributes *wksAttrs;
  1977. X
  1978. X  /*
  1979. X   * 
  1980. X   */
  1981. X  valueMask[0] = valueMask[1] = 0;
  1982. X  PEXSetPWAttributeMask(valueMask,PEXPWPostedStructures);
  1983. X  if (!(wksAttrs = PEXGetWorkstationAttributes(theDisplay, theRenderObj,
  1984. X                           valueMask ))) {
  1985. X    return;
  1986. X  }
  1987. X
  1988. X  theNewStrux = 0;
  1989. X  theSelectedElement = -1;
  1990. X
  1991. X  /*
  1992. X   * Clear by doing a fill rect, since the SI does not seem to clear when
  1993. X   * there are no structures posted, a bug, I think.
  1994. X   */
  1995. X  for ( i = 0; i < wksAttrs->posted_structures.count; i++ ) {
  1996. X    PEXDestroyStructures(theDisplay, 1,
  1997. X             &wksAttrs->posted_structures.structures[i].sid);
  1998. X  }
  1999. X  PEXFreeWorkstationAttributes(wksAttrs);
  2000. X}
  2001. X
  2002. X
  2003. X/*************************************************************************
  2004. X * PickSomething - returns structure and element, else element == -1
  2005. X */
  2006. X#if NeedFunctionPrototypes
  2007. X/* need to do this to avoid warning about initialization, due to shorts */
  2008. Xvoid  wksPickOne( short x, short y, long *strux, int *element )
  2009. X#else
  2010. Xvoid  wksPickOne( x, y, strux, element )
  2011. X     short x;
  2012. X     short y;
  2013. X     long *strux;
  2014. X     int *element;
  2015. X#endif
  2016. X{
  2017. X  PEXPDDCHitBox hitInfo;
  2018. X  PEXPMAttributes *pickReturn;
  2019. X  int i;
  2020. X  PEXPickMeasure pmID;
  2021. X
  2022. X  if (!thePickInitFlag) {
  2023. X    InitPickDevice();
  2024. X    thePickInitFlag = 1;
  2025. X  }
  2026. X
  2027. X  pmID = PEXCreatePickMeasure( theDisplay, theRenderObj,
  2028. X                  PEXPickDeviceDCHitBox);
  2029. X
  2030. X  hitInfo.position.x = x;
  2031. X  hitInfo.position.y = theWinHeight - y;
  2032. X  hitInfo.distance = 10;
  2033. X  PEXUpdatePickMeasure( theDisplay, pmID,  PEXPickDeviceDCHitBox,
  2034. X               (PEXPickRecord *)&hitInfo);
  2035. X
  2036. X  pickReturn = PEXGetPickMeasure(theDisplay, pmID, (PEXPMStatus|PEXPMPath));
  2037. X
  2038. X  if (pickReturn->status) {
  2039. X    /*
  2040. X     * Get the last struxure/elementent in the pick path
  2041. X     */
  2042. X    *strux = pickReturn->pick_path.elements[pickReturn->pick_path.count-1].sid;
  2043. X    *element = 
  2044. X      pickReturn->pick_path.elements[pickReturn->pick_path.count-1].offset;
  2045. X  } else {
  2046. X    *element = -1;
  2047. X  }
  2048. X  PEXFreePMAttributes(pickReturn);
  2049. X  /*
  2050. X   * No way to set the status and path on this guy, free it */
  2051. X  PEXFreePickMeasure(theDisplay, pmID);
  2052. X}
  2053. X
  2054. X/*************************************************************************
  2055. X * wksPick all not there yet. do a picOne
  2056. X */
  2057. X#if NeedFunctionPrototypes
  2058. X/* need to do this to avoid warning about initialization, due to shorts */
  2059. Xvoid wksPickAll( short x, short y, short x2, short y2,
  2060. X        int *nFound, long **struxArray, int **elemArray )
  2061. X#else
  2062. Xvoid wksPickAll( x, y, x2, y2, nFound, struxArray, elemArray )
  2063. X     short x;
  2064. X     short y;
  2065. X     short x2;
  2066. X     short y2;
  2067. X     int *nFound;
  2068. X     long **struxArray;
  2069. X     int **elemArray;
  2070. X#endif
  2071. X{
  2072. X  long s;
  2073. X  int e;
  2074. X
  2075. X  printf("we don't do no stinkin' pick all in wks\n");
  2076. X  wksPickOne( x, y, &s, &e );
  2077. X  if (e != -1) {
  2078. X    *nFound = 1;
  2079. X    *struxArray = (long *)malloc(sizeof(long));
  2080. X    *elemArray = (int *)malloc(sizeof(int));
  2081. X    (*struxArray)[0] = s;
  2082. X    (*elemArray)[0] = e;
  2083. X  } else *nFound = 0;
  2084. X}
  2085. X
  2086. X
  2087. Xint wksMapXToNPC( count, points)
  2088. X     int count;
  2089. X     PEXCoord *points;
  2090. X{
  2091. X  int i;
  2092. X  PEXMatrix XCtoNPC;
  2093. X  unsigned long valueMask[2];
  2094. X  PEXWorkstationAttributes *wksAttrs;
  2095. X
  2096. X  /*
  2097. X   * We rely on the fact that we always use the whole window for the
  2098. X   * Workstation viewport.  Get the information we want, incase this
  2099. X   * scratch area gets creamed.
  2100. X   */
  2101. X  valueMask[0] = valueMask[1] = 0;
  2102. X
  2103. X  PEXSetPWAttributeMask(valueMask,PEXPWCurViewport);
  2104. X  PEXSetPWAttributeMask(valueMask,PEXPWCurNPCSubVolume);
  2105. X  
  2106. X  if (!(wksAttrs = PEXGetWorkstationAttributes(theDisplay, theRenderObj, valueMask ))) {
  2107. X    return (-1);
  2108. X  }
  2109. X
  2110. X  i = PEXXCToNPCTransform( &wksAttrs->cur_npc_subvolume, 
  2111. X            (PEXDeviceCoord *)&wksAttrs->cur_workstation_viewport, 
  2112. X              theWinHeight, XCtoNPC );
  2113. X  PEXFreeWorkstationAttributes( wksAttrs );
  2114. X  if (i!=0) {printf("rdrPickAll bad XCtoNPC %d\n", i); return (0); }
  2115. X
  2116. X  PEXTransformPoints(XCtoNPC, count, points, points);
  2117. X  return (1);
  2118. X}
  2119. X
  2120. Xint wksReconfigureWindow( wkid, width, height)
  2121. X     long wkid;
  2122. X     int width;
  2123. X     int height;
  2124. X{
  2125. X   if (theWimpyWindow)
  2126. X     XResizeWindow(theDisplay, theWindow, width, height );
  2127. X}
  2128. X
  2129. X/*************************************************************************
  2130. X *
  2131. X */
  2132. Xint wksGetColorFromIndex(cIndex, rgb)
  2133. X     int cIndex;
  2134. X     PEXColorRGB *rgb;
  2135. X{
  2136. X  int table_type;
  2137. X  int defined;
  2138. X  PEXColorSpecifier *entry;
  2139. X  PEXBitmask valueMask[2];
  2140. X  PEXWorkstationAttributes *wksAttrs;
  2141. X
  2142. X  valueMask[0] = valueMask[1] = 0;
  2143. X  PEXSetPWAttributeMask(valueMask,PEXPWColorTable);
  2144. X  if (!(wksAttrs = PEXGetWorkstationAttributes(theDisplay, theRenderObj,
  2145. X                           valueMask ))) {
  2146. X    return (0);
  2147. X  }
  2148. X
  2149. X  entry = (PEXColorSpecifier *)PEXGetTableEntry(theDisplay, wksAttrs->color_table,
  2150. X                        cIndex, PEXSetValue, &defined,
  2151. X                        &table_type);
  2152. X  if (table_type != PEXLUTColor) {
  2153. X    printf("rdrGetColorFromIndex fix it!!!\n");
  2154. X  }
  2155. X  if (entry->type != PEXColorTypeRGB) printf("RGB NOT %d\n");
  2156. X  *rgb = entry->value.rgb;
  2157. X
  2158. X  PEXFreeTableEntries(table_type, 1,(PEXPointer)entry);
  2159. X  PEXFreeWorkstationAttributes(wksAttrs);
  2160. X}
  2161. X
  2162. XrenderProcs wksProcs = { wksInit, wksReDraw, wksMapXToMC, wksMapMCToX, 
  2163. X               wksSetView, wksSetNPCToDC, wksPost, wksDeleteAll,
  2164. X               wksPickOne, wksPickAll, wksMapXToNPC,
  2165. X               wksReconfigureWindow, wksGetColorFromIndex,
  2166. X               wksUnpost };
  2167. X
  2168. END_OF_FILE
  2169.   if test 15095 -ne `wc -c <'wks.c'`; then
  2170.     echo shar: \"'wks.c'\" unpacked with wrong size!
  2171.   fi
  2172.   # end of 'wks.c'
  2173. fi
  2174. echo shar: End of archive 6 \(of 14\).
  2175. cp /dev/null ark6isdone
  2176. MISSING=""
  2177. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
  2178.     if test ! -f ark${I}isdone ; then
  2179.     MISSING="${MISSING} ${I}"
  2180.     fi
  2181. done
  2182. if test "${MISSING}" = "" ; then
  2183.     echo You have unpacked all 14 archives.
  2184.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2185.     echo "concatentating pexdraw.c ..."
  2186.     cat pexdrawc.? > pexdraw.c
  2187.     rm pexdrawc.?
  2188.     echo "concatentating pexdraw.uil ..."
  2189.     cat pexdrawu.? > pexdraw.uil
  2190.     rm pexdrawu.?
  2191.     echo "concatentating teapot.c ..."
  2192.     rm teapotc.?
  2193. else
  2194.     echo You still must unpack the following archives:
  2195.     echo "        " ${MISSING}
  2196. fi
  2197. exit 0
  2198. exit 0 # Just in case...
  2199. -- 
  2200.   // chris@IMD.Sterling.COM       | Send comp.sources.x submissions to:
  2201. \X/  Amiga - The only way to fly! |    sources-x@imd.sterling.com
  2202.  "It's intuitively obvious to the |
  2203.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  2204.