home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume15 / olvwm-3.0 / part15 < prev    next >
Internet Message Format  |  1992-02-03  |  57KB

  1. Path: uunet!sun-barr!ames!pasteur!nntp
  2. From: scott.oaks@East.Sun.COM (Scott Oaks)
  3. Newsgroups: comp.sources.x
  4. Subject: v15i161: OpenLook Virtual Window Mgr (3.0), Part15/21
  5. Message-ID: <1992Feb4.135917.7948@pasteur.Berkeley.EDU>
  6. Date: 4 Feb 92 13:59:17 GMT
  7. References: <csx-15i147-olvwm-3.0@uunet.UU.NET>
  8. Sender: dcmartin@msi.com (David C. Martin - Moderator)
  9. Organization: University of California, at Berkeley
  10. Lines: 1973
  11. Approved: dcmartin@msi.com
  12. Nntp-Posting-Host: postgres.berkeley.edu
  13.  
  14. Submitted-by: scott.oaks@East.Sun.COM (Scott Oaks)
  15. Posting-number: Volume 15, Issue 161
  16. Archive-name: olvwm-3.0/part15
  17.  
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  22. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  23. # If this archive is complete, you will see the following message at the end:
  24. #        "End of archive 15 (of 21)."
  25. # Contents:  st.h winicon.c winpinmenu.c winroot.c
  26. # Wrapped by dcmartin@fascet on Tue Jan 14 05:54:46 1992
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'st.h' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'st.h'\"
  30. else
  31. echo shar: Extracting \"'st.h'\" \(1252 characters\)
  32. sed "s/^X//" >'st.h' <<'END_OF_FILE'
  33. X
  34. X/* This is a general purpose hash table package written by Peter Moore @ UCB. */
  35. X#ident    "@(#)st.h    26.5    91/09/14 SMI"
  36. X
  37. X#ifndef ST_INCLUDED
  38. X
  39. X#define ST_INCLUDED
  40. X
  41. Xtypedef struct st_table_entry st_table_entry;
  42. X
  43. Xstruct st_table_entry {
  44. X    char *key;
  45. X    char *record;
  46. X    st_table_entry *next;
  47. X};
  48. X
  49. Xtypedef struct st_table st_table;
  50. X
  51. Xstruct st_table {
  52. X    int (*compare)();
  53. X    int (*hash)();
  54. X    int num_bins;
  55. X    int num_entries;
  56. X    int max_density;
  57. X    int reorder_flag;
  58. X    double grow_factor;
  59. X    st_table_entry **bins;
  60. X};
  61. X
  62. X#define st_is_member(table,key) st_lookup(table,key,(char **) 0)
  63. X
  64. Xenum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE};
  65. X
  66. Xint st_delete(), st_insert(), st_foreach(), st_free_table();
  67. Xint st_lookup(), st_find_or_add(), st_add_direct();
  68. Xst_table *st_init_table(), *st_init_table_with_params();
  69. X
  70. X#define ST_NUMCMP    ((int (*)()) 0)
  71. X#define ST_NUMHASH    ((int (*)()) -2)
  72. X
  73. X#define ST_PTRCMP    ((int (*)()) 0)
  74. X#define ST_PTRHASH    ((int (*)()) -1)
  75. X
  76. X#define st_numcmp    ST_NUMCMP
  77. X#define st_numhash    ST_NUMHASH
  78. X#define st_ptrcmp    ST_PTRCMP
  79. X#define st_ptrhash    ST_PTRHASH
  80. X
  81. X#define ST_DEFAULT_MAX_DENSITY 5
  82. X#define ST_DEFAULT_INIT_TABLE_SIZE 11
  83. X#define ST_DEFAULT_GROW_FACTOR 2.0
  84. X#define ST_DEFAULT_REORDER_FLAG 0
  85. X
  86. Xint st_strhash();
  87. X
  88. X#endif ST_INCLUDED
  89. END_OF_FILE
  90. if test 1252 -ne `wc -c <'st.h'`; then
  91.     echo shar: \"'st.h'\" unpacked with wrong size!
  92. fi
  93. # end of 'st.h'
  94. fi
  95. if test -f 'winicon.c' -a "${1}" != "-c" ; then 
  96.   echo shar: Will not clobber existing file \"'winicon.c'\"
  97. else
  98. echo shar: Extracting \"'winicon.c'\" \(21256 characters\)
  99. sed "s/^X//" >'winicon.c' <<'END_OF_FILE'
  100. X/*
  101. X *      (c) Copyright 1989, 1990 Sun Microsystems, Inc. Sun design patents
  102. X *      pending in the U.S. and foreign countries. See LEGAL_NOTICE
  103. X *      file for terms of the license.
  104. X */
  105. X
  106. X#ident    "@(#)winicon.c    1.1 olvwm version 1/3/92"
  107. X
  108. X/*
  109. X * Based on
  110. X#ident    "@(#)winicon.c    26.27    91/09/14 SMI"
  111. X *
  112. X */
  113. X
  114. X#include <errno.h>
  115. X#include <stdio.h>
  116. X#include <string.h>
  117. X#include <X11/Xos.h>
  118. X#include <X11/Xlib.h>
  119. X#include <X11/Xutil.h>
  120. X#include <X11/Xatom.h>
  121. X#include <olgx/olgx.h>
  122. X
  123. X#include "i18n.h"
  124. X#include "ollocale.h"
  125. X#include "mem.h"
  126. X#include "olwm.h"
  127. X#include "win.h"
  128. X#include "menu.h"
  129. X#include "globals.h"
  130. X#include "slots.h"
  131. X#include "group.h"
  132. X
  133. Xextern     Bool    PropGetWMName();
  134. Xextern     Bool    PropGetWMIconName();
  135. X
  136. X/***************************************************************************
  137. X* private data
  138. X***************************************************************************/
  139. X
  140. X/* events in the icon window that are interesting */
  141. X#define ICON_EVENT_MASK        (ButtonPressMask | ButtonReleaseMask | \
  142. X                ExposureMask | ButtonMotionMask | \
  143. X                EnterWindowMask | FocusChangeMask)
  144. X
  145. X/* Class function vector */
  146. Xstatic ClassIconFrame classIconFrame;
  147. X
  148. X/***************************************************************************
  149. X* forward-declared functions
  150. X***************************************************************************/
  151. X
  152. X/***************************************************************************
  153. X* private event functions
  154. X***************************************************************************/
  155. X
  156. Xstatic int
  157. XmenuPressIcon(dpy,event,iconInfo)
  158. XDisplay *dpy;
  159. XXEvent *event;
  160. XWinIconFrame *iconInfo;
  161. X{
  162. X    if (iconInfo->core.client->wmDecors->menu_type != MENU_NONE)
  163. X    ShowStandardMenu(iconInfo, event, False);
  164. X}
  165. X
  166. Xstatic int
  167. XselectDoubleClickIcon(dpy,event,iconInfo)
  168. XDisplay *dpy;
  169. XXEvent *event;
  170. XWinIconFrame *iconInfo;
  171. X{
  172. X    StateIconNorm(iconInfo->core.client);
  173. X}
  174. X
  175. Xstatic int
  176. XadjustClickIcon(dpy,event,iconInfo)
  177. XDisplay *dpy;
  178. XXEvent *event;
  179. XWinIconFrame *iconInfo;
  180. X{
  181. X        ToggleSelection(iconInfo->core.client, event->xbutton.time);
  182. X}
  183. X
  184. X/***************************************************************************
  185. X* private functions
  186. X***************************************************************************/
  187. X
  188. X/*
  189. X * iconCalcName - calc position/size of icon name
  190. X */
  191. Xstatic void
  192. XiconCalcName(winIcon,pane)
  193. X    WinIconFrame *winIcon;
  194. X    Window     pane;
  195. X{
  196. X    Display *dpy = winIcon->core.client->dpy;
  197. X
  198. X    winIcon->nameLength = strlen(winIcon->fcore.name);
  199. X    winIcon->nameWidth = XTextWidth(GRV.IconFontInfo, winIcon->fcore.name, 
  200. X        winIcon->nameLength);
  201. X    winIcon->nameX = (winIcon->core.width - winIcon->nameWidth)/2;
  202. X
  203. X    /* 
  204. X     * Position the text one pixel above the ICON_VERTBORDER and
  205. X     * the descent of the font
  206. X     */
  207. X    winIcon->nameY = winIcon->core.height - ICON_VERTBORDER - 1
  208. X                - GRV.IconFontInfo->max_bounds.descent;
  209. X}
  210. X
  211. X/* 
  212. X * iconSetName -- set the icon name and possibly redraw
  213. X */
  214. Xstatic void
  215. XiconSetName(winIcon,pane)
  216. X    WinIconFrame *winIcon;
  217. X    Window pane;
  218. X{
  219. X    Display *dpy = winIcon->core.client->dpy;
  220. X
  221. X    if (winIcon->fcore.name)
  222. X        MemFree(winIcon->fcore.name);
  223. X
  224. X    if (!PropGetWMIconName(dpy,pane,&(winIcon->fcore.name)) &&
  225. X        !PropGetWMName(dpy,pane,&(winIcon->fcore.name))) {
  226. X        winIcon->fcore.name = MemNewString(GRV.DefaultWinName);
  227. X    }
  228. X
  229. X    iconCalcName(winIcon,pane);
  230. X
  231. X    if (!winIcon->core.dirtyconfig)
  232. X        (WinFunc(winIcon,core.drawfunc))(dpy,winIcon);
  233. X}
  234. X
  235. X/* selectDragIcon -- the user has held the select button down long enough
  236. X * to initiate a drag.  Unpin the icon slot and start a window-move.
  237. X */
  238. Xstatic int
  239. XselectDragIcon(dpy, ev, iframe, lastpress)
  240. XDisplay *dpy;
  241. XXEvent *ev;
  242. XWinIconFrame *iframe;
  243. XXButtonEvent *lastpress;
  244. X{
  245. X    SlotFree(iframe);
  246. X    iframe->fManuallyPositioned = True;
  247. X    ClientMove(iframe->core.client,lastpress);
  248. X}
  249. X
  250. X
  251. X/*
  252. X * newconfigIcon -- compute a new configuration of icon window
  253. X */
  254. Xstatic int
  255. XnewconfigIcon(winInfo, pxcre)
  256. XWinIconFrame *winInfo;
  257. XXConfigureRequestEvent *pxcre;
  258. X{
  259. X        Client     *cli = winInfo->core.client;
  260. X        WinPane *winPane = (WinPane *)winInfo->fcore.panewin;
  261. X        int     neww,newh;
  262. X
  263. X        neww = winInfo->fcore.panewin->core.width + 2*widthBothIcon(winInfo);
  264. X        newh = winInfo->fcore.panewin->core.height + heightTopIcon(winInfo) +
  265. X            heightBottomIcon(winInfo);
  266. X
  267. X        if (neww != winInfo->core.width)
  268. X        {
  269. X                winInfo->core.width = neww;
  270. X                winInfo->core.dirtyconfig |= CWWidth;
  271. X        }
  272. X
  273. X        if (newh != winInfo->core.height)
  274. X        {
  275. X                winInfo->core.height = newh;
  276. X                winInfo->core.dirtyconfig |= CWHeight;
  277. X        }
  278. X
  279. X        if (winInfo->core.dirtyconfig)
  280. X        {
  281. X                (WinFunc(winPane,core.newposfunc))(winPane, 
  282. X            widthBothIcon(winInfo), heightTopIcon(winInfo));
  283. X        }
  284. X
  285. X    if (winInfo->core.dirtyconfig & (CWWidth | CWHeight))
  286. X    {
  287. X                iconCalcName(winInfo,PANEWINOFCLIENT(cli));
  288. X    }
  289. X
  290. X    return winInfo->core.dirtyconfig;
  291. X}
  292. X
  293. X/*
  294. X * The icon is being moved to a new (x,y) location.  If the icon slot has not
  295. X * yet been allocated, do so if appropriate.  Otherwise, blindly accept the
  296. X * (x,y) position.
  297. X */
  298. Xstatic int
  299. XnewposIcon(winInfo,x,y)
  300. XWinIconFrame *winInfo;
  301. Xint x,y;
  302. X{
  303. X    WinNewPosFunc(winInfo,x,y);
  304. X    if (winInfo->iconslot == NULL &&
  305. X        !ClientIsPinnable(winInfo->core.client) &&
  306. X        winInfo->core.client->transientFor == 0) {
  307. X        SlotAlloc(winInfo, winInfo->fManuallyPositioned, GRV.FSnapToGrid);
  308. X    }
  309. X    return winInfo->core.dirtyconfig;
  310. X}
  311. X
  312. X
  313. Xstatic void
  314. XdrawDashedRect(dpy, winInfo, win, x, y, w, h)
  315. X    Display *dpy;
  316. X    WinIconFrame *winInfo;
  317. X    Window win;
  318. X    int x, y, w, h;
  319. X{
  320. X    XPoint pts[5];
  321. X
  322. X    pts[0].x = x;    pts[0].y = y;
  323. X    pts[1].x = x;    pts[1].y = y + h;
  324. X    pts[2].x = x + w;    pts[2].y = y + h;
  325. X    pts[3].x = x + w;    pts[3].y = y;
  326. X    pts[4].x = x;    pts[4].y = y;
  327. X
  328. X    /*
  329. X     * The following is necessary because IconBorderGC uses the LineOnOffDash
  330. X     * line-style, which is faster than LineDoubleDash on some servers.
  331. X     */
  332. X    XDrawLines(dpy, win, WinGC(winInfo,WORKSPACE_GC),
  333. X        pts, 5, CoordModeOrigin);
  334. X    XDrawLines(dpy, win, WinGC(winInfo,ICON_BORDER_GC),
  335. X        pts, 5, CoordModeOrigin);
  336. X}
  337. X
  338. X/*
  339. X * drawIconBorder -- based on the value of select, draw the border for an icon
  340. X */
  341. Xstatic void
  342. XdrawIconBorder(dpy, winInfo, select)
  343. XDisplay *dpy;
  344. XWinIconFrame *winInfo;
  345. XBool    select;
  346. X{
  347. X    int     x, y;           /* values for use with */
  348. X    unsigned int width, height;  /* rectangle drawn for border */
  349. X    Window     w = winInfo->core.self;
  350. X    GC    borderGC = WinGC(winInfo,BORDER_GC);
  351. X    GC    workspaceGC = WinGC(winInfo,WORKSPACE_GC);
  352. X    
  353. X    x = y = 0;
  354. X    width = winInfo->core.width - 1;
  355. X    height = winInfo->core.height - 1;
  356. X
  357. X    /*
  358. X     * If 3D is used, give "borderless" icons.  Otherwise, give black and 
  359. X     * white borders.
  360. X     */
  361. X    if (select) {
  362. X        XDrawRectangle(dpy, w, borderGC,
  363. X               x, y, width, height );
  364. X        XDrawRectangle(dpy, w, borderGC,
  365. X               x+1, y+1, width-2, height-2 );
  366. X        XDrawRectangle(dpy, w, borderGC,
  367. X               x+2, y+2, width-4, height-4 );
  368. X    } else {
  369. X        XDrawRectangle(dpy, w, workspaceGC,
  370. X               x, y, width, height);
  371. X        if (Win3D(winInfo)) {
  372. X        XDrawRectangle(dpy, w, workspaceGC, 
  373. X                   x+1, y+1, width-2, height-2);
  374. X        } else {
  375. X#ifdef notdef
  376. X        XDrawRectangle(dpy, w, IconBorderGC, 
  377. X                   x+1, y+1, width-2, height-2);
  378. X#endif /* notdef */
  379. X        drawDashedRect(dpy, winInfo, w, x+1, y+1, width-2, height-2);
  380. X        }
  381. X
  382. X        XDrawRectangle(dpy, w, workspaceGC,
  383. X               x+2, y+2, width-4, height-4);
  384. X    }
  385. X
  386. X#ifdef notdef
  387. X/*
  388. X * This stuff was used for the attempt at 3D-look icons.
  389. X * It has been abandoned in favor of the "borderless" icon look.
  390. X */
  391. X
  392. X        /* initial values for first rectangle */
  393. X        x = 0;
  394. X        y = 0;
  395. X        /* need to subtract one, based on how XDrawRectangle works */
  396. X        width = winInfo->core.width - 1;
  397. X        height = winInfo->core.height - 1;
  398. X
  399. X        /* draw three rectangles for border */
  400. X    for ( rectangle = 0 ; rectangle < 3 ; rectangle++ )
  401. X    {
  402. X              switch( rectangle )
  403. X              {
  404. X              case 0:         /* outermost rectangle */
  405. X                      if (Win3D(winInfo))
  406. X                      {
  407. X                              if ( select )
  408. X                                      olgxState = OLGX_INVOKED;
  409. X                              else
  410. X                                      olgxState = OLGX_NORMAL;
  411. X
  412. X                              olgx_draw_box( olgx_gisnormal,
  413. X                                             winInfo->core.self,
  414. X                                             x, y, width+1, height+1,
  415. X                                             olgxState, 0 );
  416. X                              drawRectangle = False;
  417. X                      }
  418. X                      else
  419. X                      {
  420. X                              highlightGC = select
  421. X                                              ? DrawSelectedGC
  422. X                                              : DrawBackgroundGC;
  423. X                              drawRectangle = True;
  424. X                      }
  425. X                      break;
  426. X              case 1:         /* middle rectangle */
  427. X                      if ( select )
  428. X                                      highlightGC = DrawSelectedGC;
  429. X                      else if (Win3D(winInfo))
  430. X                              highlightGC = DrawBackgroundGC;
  431. X                      else    /* REMIND eventually need to handle
  432. X                               * IconBorder resource when 2d & ColorDisplay
  433. X                               */
  434. X                              highlightGC = IconBorderGC;
  435. X                      drawRectangle = True;
  436. X                      break;
  437. X              case 2:         /* innermost rectangle */
  438. X              default:
  439. X                      highlightGC = select ? DrawSelectedGC
  440. X                                           : DrawBackgroundGC;
  441. X                      drawRectangle = True;
  442. X                      break;
  443. X              }
  444. X
  445. X              if ( drawRectangle )
  446. X                      XDrawRectangle( dpy, winInfo->core.self, highlightGC,
  447. X                                      x, y, width, height );
  448. X              x++;
  449. X              y++;
  450. X              width -= 2;
  451. X              height -= 2;
  452. X      }
  453. X#endif /* notdef */
  454. X}
  455. X
  456. X/*
  457. X * drawIcon -- draw the icon window
  458. X */
  459. X/*ARGSUSED*/  /* dpy arg will be used when multiple Displays supported */
  460. Xstatic int
  461. XdrawIcon(dpy, winInfo)
  462. XDisplay       *dpy;
  463. XWinIconFrame *winInfo;
  464. X{
  465. X    Window        frameWin = winInfo->core.self;
  466. X
  467. X    XFillRectangle(dpy, frameWin, WinGC(winInfo,WORKSPACE_GC),
  468. X        0, 0, winInfo->core.width, winInfo->core.height);
  469. X
  470. X    /* draw icon name */
  471. X    if (winInfo->core.client->wmDecors->flags & WMDecorationIconName)
  472. X        XDrawString(dpy, frameWin, WinGC(winInfo,ICON_NORMAL_GC),
  473. X        winInfo->nameX, winInfo->nameY, 
  474. X        winInfo->fcore.name, winInfo->nameLength);
  475. X
  476. X    /* draw border */
  477. X    drawIconBorder(dpy, winInfo, winInfo->core.client->isSelected);
  478. X}
  479. X
  480. X
  481. X/*
  482. X * DestroyIcon -- destroy the icon window resources and free any allocated
  483. X *    data.
  484. X */
  485. Xstatic int
  486. XdestroyIcon(dpy, winInfo)
  487. XDisplay       *dpy;
  488. XWinIconFrame *winInfo;
  489. X{
  490. X    /* 
  491. X     * Free our data and throw away window
  492. X     */
  493. X    SlotFree(winInfo);
  494. X    ListDestroy(winInfo->core.children);
  495. X    MemFree(winInfo->fcore.name);
  496. X    XUndefineCursor(dpy, winInfo->core.self);
  497. X    DestroyWindow(winInfo);
  498. X    MemFree(winInfo);
  499. X}
  500. X
  501. X/*
  502. X * heightIconName - returns the height of the icon name portion of
  503. X *    the total icon height.
  504. X */
  505. Xstatic int
  506. XheightIconName(win)
  507. XWinIconFrame    *win;
  508. X{
  509. X    if (win->core.client->wmDecors->flags & WMDecorationIconName)
  510. X    {
  511. X        return (GRV.IconFontInfo->max_bounds.ascent +
  512. X                   GRV.IconFontInfo->max_bounds.descent + 
  513. X            ICON_VERTBORDER);
  514. X    } else {
  515. X        return 0;
  516. X    }
  517. X}
  518. X
  519. X/*
  520. X * heightTopIcon - returns the height of the top portion of the icon window.
  521. X *    If the IconPane (image/window) is too small then increase the
  522. X *    the top height to bring total height to the minimal icon
  523. X *    window size of ICON_WIN_HEIGHT.  Otherwise use the default
  524. X *    border size.
  525. X */
  526. Xstatic int
  527. XheightTopIcon(win)
  528. XWinIconFrame    *win;
  529. X{
  530. X    WinIconPane *winPane = (WinIconPane *)(win->fcore.panewin);
  531. X    int availHeight,basicbottom;
  532. X
  533. X    availHeight = ICON_WIN_HEIGHT - heightIconName(win);
  534. X
  535. X    if (winPane->core.height < availHeight) {
  536. X        return (availHeight-winPane->core.height)/2;
  537. X    } else {
  538. X        return ICON_VERTBORDER;
  539. X    }
  540. X}
  541. X
  542. X/*
  543. X * heightBottomIcon - returns the height of the bottom portion of
  544. X *    the icon window - which includes the icon name string (if any).
  545. X *    If the IconPane (image/window) is too small then increase the
  546. X *    the bottom height to bring total height to the minimal icon
  547. X *    window size of ICON_WIN_HEIGHT.  Otherwise use the default
  548. X *    border size.
  549. X */
  550. Xstatic int
  551. XheightBottomIcon(win)
  552. XWinIconFrame    *win;
  553. X{
  554. X    WinIconPane *winPane = (WinIconPane *)(win->fcore.panewin);
  555. X    int nameHeight,availHeight;
  556. X
  557. X    nameHeight = heightIconName(win);
  558. X
  559. X    availHeight = ICON_WIN_HEIGHT - nameHeight;
  560. X
  561. X    if (winPane->core.height < availHeight) {
  562. X        return (availHeight - winPane->core.height)/2 + nameHeight;
  563. X    } else {
  564. X        return nameHeight + ICON_VERTBORDER;
  565. X    }
  566. X}
  567. X
  568. X/* The icon pane has the same border width on either side, so this function
  569. X * is used to calculate both border widths.
  570. X */
  571. Xstatic int
  572. XwidthBothIcon(win)
  573. XWinIconFrame    *win;
  574. X{
  575. X    WinIconPane *winPane = (WinIconPane *)(win->fcore.panewin);
  576. X
  577. X    if (winPane->iconClientWindow)
  578. X    {
  579. X        return ICON_HORZBORDER;
  580. X    }
  581. X    else
  582. X    {
  583. X        if (winPane->core.width < ICON_WIN_WIDTH - 2*ICON_HORZBORDER)
  584. X        {
  585. X        return (ICON_WIN_WIDTH-winPane->core.width)/2;
  586. X        }
  587. X        else
  588. X        return ICON_HORZBORDER;
  589. X    }
  590. X}
  591. X
  592. X/* 
  593. X * fullrestoreIcon
  594. X *    Switch icon menus and if this client is iconic then
  595. X *    open it.
  596. X */
  597. Xstatic int
  598. XfullrestoreIcon(client)
  599. XClient    *client;
  600. X{
  601. X    WinIconFrame    *iconInfo = client->iconwin;
  602. X
  603. X    if (client->wmState == IconicState)
  604. X        StateIconNorm(client);
  605. X
  606. X    iconInfo->fcore.fullsize = !iconInfo->fcore.fullsize;
  607. X}
  608. X
  609. X
  610. X/***************************************************************************
  611. X* global functions
  612. X***************************************************************************/
  613. X
  614. X/*
  615. X * MakeIcon  -- create the icon window. Return a WinIconFrame structure.
  616. X *    Note that unlike most Make functions, icons are not mapped right
  617. X *    away.
  618. X */
  619. XWinIconFrame *
  620. XMakeIcon(cli,panewin,paneattrs)
  621. XClient *cli;
  622. XWindow panewin;        
  623. XXWindowAttributes *paneattrs;
  624. X{
  625. X    Display        *dpy = cli->dpy;
  626. X    WinIconFrame    *w;
  627. X        XSetWindowAttributes attributes;
  628. X        unsigned long   valuemask;
  629. X    XWMHints    *wmHints = cli->wmHints;
  630. X
  631. X    /* create the window structure */
  632. X    w = MemNew(WinIconFrame);
  633. X    w->core.kind = WIN_ICON;
  634. X    w->class = &classIconFrame;
  635. X    w->core.parent = NULL;
  636. X    w->core.children = NULL;
  637. X    w->core.client = cli;
  638. X    w->core.width = ICON_WIN_WIDTH;
  639. X    w->core.height = ICON_WIN_HEIGHT;
  640. X
  641. X    /* fill out  the associated structure */
  642. X    w->core.dirtyconfig = CWX|CWY|CWWidth|CWHeight;
  643. X    w->core.colormap = None;
  644. X    w->core.exposures = NULL;
  645. X    w->core.helpstring = "olwm:Icon";
  646. X
  647. X    /* create the icon frame */
  648. X    attributes.border_pixel = 0;
  649. X    attributes.colormap = cli->scrInfo->colormap;
  650. X    attributes.event_mask = ICON_EVENT_MASK;
  651. X    valuemask = CWBorderPixel | CWColormap | CWEventMask;
  652. X    w->core.self = XCreateWindow(dpy, 
  653. X        cli->scrInfo->rootid,
  654. X        w->core.x, w->core.y, 1, 1, 0,
  655. X        cli->scrInfo->depth,
  656. X        InputOutput,
  657. X        cli->scrInfo->visual,
  658. X        valuemask, &attributes);
  659. X
  660. X    /* install icon frame in client */
  661. X    cli->iconwin = w;    /* REMIND: should be called cli->iconframe */
  662. X    
  663. X    /* set the position - either from position or icon slot */
  664. X    if (wmHints && (wmHints->flags & IconPositionHint)) 
  665. X    {
  666. X        w->core.x = wmHints->icon_x;
  667. X        w->core.y = wmHints->icon_y;
  668. X        w->fManuallyPositioned = True;
  669. X    }
  670. X    else
  671. X    {
  672. X        /* to be fixed up at config time */
  673. X        w->core.x = w->core.y = 0;
  674. X        w->fManuallyPositioned = False;
  675. X    }
  676. X
  677. X    /* register the window */
  678. X    WIInstallInfo(w);
  679. X
  680. X    /* set cursor for frame */
  681. X    XDefineCursor( dpy, w->core.self, GRV.IconPointer );
  682. X
  683. X    iconSetName(w,panewin);
  684. X
  685. X    w->fcore.fullsize = False;
  686. X
  687. X    return w;
  688. X}
  689. X
  690. Xvoid
  691. XIconInit(dpy)
  692. XDisplay *dpy;
  693. X{
  694. X    classIconFrame.core.kind = WIN_ICON;
  695. X    classIconFrame.core.xevents[Expose] = WinEventExpose;
  696. X    classIconFrame.core.xevents[ButtonRelease] = GFrameEventButtonRelease;
  697. X    classIconFrame.core.xevents[MotionNotify] = GFrameEventMotionNotify;
  698. X    classIconFrame.core.xevents[ButtonPress] = GFrameEventButtonPress;
  699. X    classIconFrame.core.xevents[EnterNotify] = GFrameEventEnterNotify;
  700. X    classIconFrame.core.xevents[FocusIn] = GFrameEventFocus;
  701. X    classIconFrame.core.xevents[FocusOut] = GFrameEventFocus;
  702. X    classIconFrame.core.focusfunc = GFrameFocus;
  703. X    classIconFrame.core.drawfunc = drawIcon;
  704. X    classIconFrame.core.destroyfunc = destroyIcon;
  705. X    classIconFrame.core.selectfunc = GFrameSelect;
  706. X    classIconFrame.core.newconfigfunc = newconfigIcon;
  707. X    classIconFrame.core.newposfunc = newposIcon;
  708. X    classIconFrame.core.setconfigfunc = GFrameSetConfigFunc;
  709. X    classIconFrame.core.createcallback = NULL;
  710. X    classIconFrame.core.heightfunc = NULL;
  711. X    classIconFrame.core.widthfunc =  NULL;
  712. X    classIconFrame.fcore.heighttop = heightTopIcon;
  713. X    classIconFrame.fcore.heightbottom = heightBottomIcon;
  714. X    classIconFrame.fcore.widthleft = widthBothIcon;
  715. X    classIconFrame.fcore.widthright = widthBothIcon;
  716. X    classIconFrame.fcore.menuPress = menuPressIcon;
  717. X    classIconFrame.fcore.adjustPress = NULL;
  718. X    classIconFrame.fcore.adjustClick = adjustClickIcon;
  719. X    classIconFrame.fcore.selectPress = NULL;
  720. X    classIconFrame.fcore.selectClick = NULL;
  721. X    classIconFrame.fcore.selectDoubleClick = selectDoubleClickIcon;
  722. X    classIconFrame.fcore.selectDrag = selectDragIcon;
  723. X    classIconFrame.fcore.fullrestoreToggle = fullrestoreIcon;
  724. X}
  725. X
  726. X/*
  727. X * DrawIconToWindowLines -- draw the open (close) lines when a window is
  728. X *      becoming an icon or vice-versa
  729. X */
  730. Xvoid
  731. XDrawIconToWindowLines(dpy, iconInfo, winInfo)
  732. XDisplay *dpy;
  733. XWinPaneFrame *winInfo;
  734. XWinIconFrame *iconInfo;
  735. X{
  736. X        int     ii;
  737. X    GC    rootGC = WinGC(winInfo,ROOT_GC);
  738. X    Window    root = WinRootID(winInfo);
  739. X
  740. X        XGrabServer(dpy);
  741. X
  742. X        for(ii=0; ii < GRV.IconFlashCount ; ii++)
  743. X        {
  744. X                /* draw the close lines */
  745. X                XDrawLine(dpy, root, rootGC,
  746. X            iconInfo->core.x, 
  747. X            iconInfo->core.y,
  748. X            winInfo->core.x, 
  749. X            winInfo->core.y);
  750. X                XDrawLine(dpy, root, rootGC,
  751. X            iconInfo->core.x,
  752. X            (int)(iconInfo->core.y + iconInfo->core.height),
  753. X            winInfo->core.x,
  754. X            (int)(winInfo->core.y + winInfo->core.height));
  755. X                XDrawLine(dpy, root, rootGC,
  756. X            (int)(iconInfo->core.x + iconInfo->core.width),
  757. X            iconInfo->core.y,
  758. X            (int)(winInfo->core.x + winInfo->core.width),
  759. X            winInfo->core.y);
  760. X                XDrawLine(dpy, root, rootGC,
  761. X            (int)(iconInfo->core.x + iconInfo->core.width),
  762. X            (int)(iconInfo->core.y + iconInfo->core.height),
  763. X            (int)(winInfo->core.x + winInfo->core.width),
  764. X            (int)(winInfo->core.y + winInfo->core.height));
  765. X
  766. X                XFlush(dpy);
  767. X        olwm_usleep((unsigned) GRV.IconFlashOnTime);
  768. X
  769. X                /* erase the close lines */
  770. X                XDrawLine(dpy, root, rootGC,
  771. X            iconInfo->core.x,
  772. X            iconInfo->core.y,
  773. X            winInfo->core.x,
  774. X            winInfo->core.y);
  775. X                XDrawLine(dpy, root, rootGC,
  776. X            iconInfo->core.x,
  777. X            (int)(iconInfo->core.y + iconInfo->core.height),
  778. X            winInfo->core.x,
  779. X            (int)(winInfo->core.y + winInfo->core.height));
  780. X                XDrawLine(dpy, root, rootGC,
  781. X            (int)(iconInfo->core.x + iconInfo->core.width),
  782. X            iconInfo->core.y,
  783. X            (int)(winInfo->core.x + winInfo->core.width),
  784. X            winInfo->core.y);
  785. X                XDrawLine(dpy, root, rootGC,
  786. X            (int)(iconInfo->core.x + iconInfo->core.width),
  787. X            (int)(iconInfo->core.y + iconInfo->core.height),
  788. X            (int)(winInfo->core.x + winInfo->core.width),
  789. X            (int)(winInfo->core.y + winInfo->core.height));
  790. X                XFlush(dpy);
  791. X        olwm_usleep((unsigned) GRV.IconFlashOffTime);
  792. X        }
  793. X
  794. X        XUngrabServer(dpy);
  795. X}
  796. X
  797. X/* 
  798. X * IconUpdateName -- the icon name property has been changed
  799. X */
  800. Xvoid
  801. XIconUpdateName(cli,event)
  802. X    Client        *cli;
  803. X    XPropertyEvent    *event;
  804. X{
  805. X    iconSetName(cli->iconwin,PANEWINOFCLIENT(cli));
  806. X}
  807. X
  808. X/*
  809. X * Set the icon's (x,y) location explicitly.  This information is typically
  810. X * taken from the WM_HINTS structure.  Since the coordinates specify the 
  811. X * absolute position of the icon pane, we must subtract the icon border to get 
  812. X * the position if the icon frame.
  813. X */
  814. Xvoid
  815. XIconSetPos(win,x,y)
  816. XWinIconFrame *win;
  817. Xint x,y;
  818. X{
  819. X    (WinFunc(win,core.newposfunc))(win,x-ICON_HORZBORDER,y-ICON_VERTBORDER);
  820. X}
  821. X
  822. X/*
  823. X * IconShow -- map an icon onto the screen, handling reparenting and
  824. X * save-sets for icon panes.
  825. X */
  826. Xvoid
  827. XIconShow(cli, winIcon)
  828. X    Client *cli;
  829. X    WinIconFrame *winIcon;
  830. X{
  831. X    WinIconPane *pane = (WinIconPane *)winIcon->fcore.panewin;
  832. X
  833. X    XReparentWindow(cli->dpy, pane->core.self, winIcon->core.self,
  834. X            pane->core.x, pane->core.y);
  835. X    XMapWindow(cli->dpy, pane->core.self);
  836. X    if (pane->iconClientWindow && !(cli->flags & CLOlwmOwned))
  837. X        XChangeSaveSet(cli->dpy, pane->core.self, SetModeInsert);
  838. X    MapWindow(winIcon);
  839. X}
  840. X
  841. X
  842. X/*
  843. X * IconHide -- remove an icon from the screen, handling reparenting and
  844. X * save-sets for icon panes.
  845. X */
  846. Xvoid
  847. XIconHide(cli, winIcon)
  848. X    Client *cli;
  849. X    WinIconFrame *winIcon;
  850. X{
  851. X    WinIconPane *pane = (WinIconPane *)winIcon->fcore.panewin;
  852. X
  853. X    UnmapWindow(winIcon);
  854. X    XUnmapWindow(cli->dpy, pane->core.self);
  855. X    XReparentWindow(cli->dpy, pane->core.self, cli->scrInfo->rootid,
  856. X            winIcon->core.x + pane->core.x,
  857. X            winIcon->core.y + pane->core.y);
  858. X    if (pane->iconClientWindow && !(cli->flags & CLOlwmOwned))
  859. X        XChangeSaveSet(cli->dpy, pane->core.self, SetModeDelete);
  860. X}
  861. END_OF_FILE
  862. if test 21256 -ne `wc -c <'winicon.c'`; then
  863.     echo shar: \"'winicon.c'\" unpacked with wrong size!
  864. fi
  865. # end of 'winicon.c'
  866. fi
  867. if test -f 'winpinmenu.c' -a "${1}" != "-c" ; then 
  868.   echo shar: Will not clobber existing file \"'winpinmenu.c'\"
  869. else
  870. echo shar: Extracting \"'winpinmenu.c'\" \(10976 characters\)
  871. sed "s/^X//" >'winpinmenu.c' <<'END_OF_FILE'
  872. X/*
  873. X *      (c) Copyright 1989, 1990 Sun Microsystems, Inc. Sun design patents
  874. X *      pending in the U.S. and foreign countries. See LEGAL_NOTICE
  875. X *      file for terms of the license.
  876. X */
  877. X
  878. X#ident    "@(#)winpinmenu.c    1.1 olvwm version 1/3/92"
  879. X
  880. X/*
  881. X * Based on
  882. X#ident    "@(#)winpinmenu.c    26.25    91/09/14 SMI"
  883. X *
  884. X */
  885. X
  886. X#include <errno.h>
  887. X#include <stdio.h>
  888. X#include <X11/Xos.h>
  889. X#include <X11/Xlib.h>
  890. X#include <X11/Xutil.h>
  891. X#include <X11/Xatom.h>
  892. X#include <olgx/olgx.h>
  893. X
  894. X#include "i18n.h"
  895. X#include "ollocale.h"
  896. X#include "mem.h"
  897. X#include "olwm.h"
  898. X#include "win.h"
  899. X#include "menu.h"
  900. X#include "globals.h"
  901. X
  902. X/***************************************************************************
  903. X* global data
  904. X***************************************************************************/
  905. X
  906. Xextern Atom AtomDecorAdd;
  907. Xextern Atom AtomDecorHeader;
  908. Xextern Atom AtomDecorPin;
  909. Xextern Atom AtomDeleteWindow;
  910. Xextern Atom AtomMenuLimited;
  911. Xextern Atom AtomProtocols;
  912. Xextern Atom AtomPushpinState;
  913. Xextern Atom AtomWinAttr;
  914. Xextern Atom AtomWTOther;
  915. X
  916. X/***************************************************************************
  917. X* private data
  918. X***************************************************************************/
  919. X
  920. X/* function vector for menu windows */
  921. Xstatic ClassPinMenu classPinMenu;
  922. X
  923. X/***************************************************************************
  924. X* private functions
  925. X***************************************************************************/
  926. X
  927. X/*
  928. X * afterMenuShow - called after MenuShowSync has finished showing
  929. X *           and possibly executing the menu.
  930. X */
  931. Xstatic void
  932. XafterMenuShow(win)
  933. X    WinPinMenu    *win;
  934. X{
  935. X    MenuInfo *mInfo = win->menuInfo;
  936. X    Display *dpy = win->core.client->dpy;
  937. X
  938. X    if (BUTTON_INDEX_OK(mInfo, mInfo->litButton)) {
  939. X    DrawLocCursor(dpy, mInfo, mInfo->litButton, False);
  940. X    SetButton(dpy, mInfo, mInfo->litButton, False, False);
  941. X    }
  942. X    SetButton(dpy, mInfo, mInfo->menu->buttonDefault, True, True);
  943. X}
  944. X
  945. X/***************************************************************************
  946. X*  private event functions
  947. X***************************************************************************/
  948. X
  949. X/* 
  950. X * eventButtonPress  - a button has gone down.
  951. X */
  952. Xstatic int
  953. XeventButtonPress(dpy, event, winInfo)
  954. X    Display        *dpy;
  955. X    XEvent        *event;
  956. X    WinPinMenu        *winInfo;
  957. X{
  958. X    if (! StartMenuGrabs(dpy, winInfo))
  959. X    return;
  960. X
  961. X    MenuMakeFirst(winInfo->menuInfo, afterMenuShow, winInfo);
  962. X
  963. X    MenuTrack(dpy, event, winInfo, winInfo);
  964. X}
  965. X
  966. X
  967. Xstatic int
  968. XeventKeyEvent(dpy, event, winInfo)
  969. X    Display        *dpy;
  970. X    XEvent        *event;
  971. X    WinPinMenu        *winInfo;
  972. X{
  973. X    MenuMakeFirst(winInfo->menuInfo, afterMenuShow, winInfo);
  974. X
  975. X    if (MenuHandleKeyEvent(dpy, event, winInfo, winInfo)) {
  976. X    if (! StartMenuGrabs(dpy, winInfo))
  977. X        return;
  978. X    }
  979. X}
  980. X
  981. X/* 
  982. X * eventClientMessage  - handle a DELETE_WINDOW message.
  983. X */
  984. X/*ARGSUSED*/
  985. Xstatic int
  986. XeventClientMessage(dpy, event, winInfo)
  987. X    Display        *dpy;
  988. X    XEvent        *event;
  989. X    WinPinMenu    *winInfo;
  990. X{
  991. X        if ((event->xclient.message_type == AtomProtocols) &&
  992. X            (event->xclient.data.l[0] == AtomDeleteWindow))
  993. X        {
  994. X        DestroyClient(winInfo->core.client);
  995. X        }
  996. X}
  997. X
  998. X
  999. Xstatic int
  1000. XeventEnterNotify(dpy, event, winInfo)
  1001. XDisplay        *dpy;
  1002. XXEvent        *event;
  1003. XWinPinMenu    *winInfo;
  1004. X{
  1005. X    if (event->xany.type == EnterNotify)
  1006. X        ColorWindowCrossing(dpy, event, winInfo);
  1007. X}
  1008. X
  1009. X
  1010. Xstatic int
  1011. XfocusMenuFunc(dpy, winInfo, focus)
  1012. X    Display *dpy;
  1013. X    WinPinMenu *winInfo;
  1014. X    Bool focus;
  1015. X{
  1016. X    MenuInfo *mInfo = winInfo->menuInfo;
  1017. X
  1018. X    if (mInfo->litButton != NOBUTTON && focus) {
  1019. X    SetButton(dpy, mInfo, mInfo->menu->buttonDefault, False, True);
  1020. X    SetButton(dpy, mInfo, mInfo->litButton, True, False);
  1021. X    DrawLocCursor(dpy, mInfo, mInfo->litButton, True);
  1022. X    } else if (! focus) {
  1023. X    if (BUTTON_INDEX_OK(mInfo, mInfo->litButton)) {
  1024. X        DrawLocCursor(dpy, mInfo, mInfo->litButton, False);
  1025. X        SetButton(dpy, mInfo, mInfo->litButton, False, False);
  1026. X    }
  1027. X    SetButton(dpy, mInfo, mInfo->menu->buttonDefault, True, True);
  1028. X    }
  1029. X}
  1030. X
  1031. X
  1032. X/*
  1033. X * destroyMenu -- destroy the menu window resources and free any allocated
  1034. X *    data.
  1035. X */
  1036. Xstatic int
  1037. XdestroyMenu(dpy, winInfo)
  1038. X    Display        *dpy;
  1039. X    WinPinMenu     *winInfo;
  1040. X{
  1041. X    MenuInfo    *menuInfo = (MenuInfo *)(winInfo->menuInfo);
  1042. X
  1043. X    /* tell the original menu that we're gone */
  1044. X    menuInfo->origmenuInfo->pinnedBrother = NULL;
  1045. X
  1046. X    /* remove window */
  1047. X    XUndefineCursor(dpy, winInfo->core.self);
  1048. X    DestroyWindow(winInfo);
  1049. X
  1050. X    /* free memory */
  1051. X    MemFree(menuInfo);
  1052. X    MemFree(winInfo);
  1053. X}
  1054. X
  1055. X/*
  1056. X * newconfigMenu - recomputes the size of the menu window
  1057. X *    Note that menus don't change size, so this is a no-op.
  1058. X */
  1059. X/*ARGSUSED*/
  1060. Xstatic int 
  1061. XnewconfigMenu(win, pxcre)
  1062. X    WinPinMenu     *win;
  1063. X    XConfigureRequestEvent *pxcre;
  1064. X{
  1065. X    return win->core.dirtyconfig;
  1066. X}
  1067. X
  1068. X/* menuSetParent -- callback during creation.  Since menus are internally-
  1069. X *     created windows we must fix up certain fields that are only available
  1070. X *    after the window is mapped.
  1071. X */
  1072. Xstatic int
  1073. XmenuSetParent(winInfo,cli,par)
  1074. X    WinGeneric     *winInfo;
  1075. X    Client         *cli;
  1076. X    WinGenericFrame *par;
  1077. X{
  1078. X    MenuInfo *mInfo;
  1079. X    /* mark this client as owned by olwm itself */
  1080. X    cli->flags = CLOlwmOwned;
  1081. X    winInfo->core.client = cli;
  1082. X    WinAddChild((WinGeneric *)par, winInfo);
  1083. X    XReparentWindow(cli->dpy, winInfo->core.self, par->core.self, 
  1084. X            winInfo->core.x, winInfo->core.y);
  1085. X    par->fcore.panewin = (WinGenericPane *)winInfo;
  1086. X    mInfo = ((WinPinMenu *) winInfo)->menuInfo;
  1087. X    winInfo->core.helpstring = mInfo->menu->helpstring;
  1088. X    par->core.helpstring = mInfo->menu->helpstring;
  1089. X}
  1090. X
  1091. X/***************************************************************************
  1092. X* global functions
  1093. X***************************************************************************/
  1094. X
  1095. X/*
  1096. X * MakePinMenu  -- create the pinned menu's menu window (around which we'll put
  1097. X *    a frame).    The window is mapped during the transition to normal
  1098. X *    state.
  1099. X */
  1100. XWinPinMenu *
  1101. XMakePinMenu(dpy, winInfo, origMenuInfo)
  1102. X    Display        *dpy;
  1103. X    WinGeneric     *winInfo;
  1104. X    MenuInfo     *origMenuInfo;
  1105. X{
  1106. X    WinPinMenu     *w;
  1107. X    Window         win;
  1108. X    Window        rootWin;
  1109. X        unsigned long     valuemask;
  1110. X        XSetWindowAttributes attributes;
  1111. X    Atom atomList[3];
  1112. X    XSizeHints     sizeHints;
  1113. X    XWMHints     wmHints;
  1114. X    MenuInfo    *newMenuInfo;
  1115. X
  1116. X    /* Make a copy of the original MenuInfo
  1117. X     * the main difference is that a pinned menu does not have a title
  1118. X      * in itself since the frame takes care of the title for us.
  1119. X      * Also adjust our height to remove the title height
  1120. X     */
  1121. X    newMenuInfo = MemNew(MenuInfo);
  1122. X    *newMenuInfo = *origMenuInfo;
  1123. X    newMenuInfo->menu = origMenuInfo->menu;
  1124. X    newMenuInfo->titleWidth = 0;
  1125. X    newMenuInfo->titleHeight = 0;
  1126. X    newMenuInfo->menuHeight = origMenuInfo->menuHeight - origMenuInfo->titleHeight;
  1127. X    newMenuInfo->buttonOffset = newMenuInfo->notitleOffset;
  1128. X
  1129. X    newMenuInfo->childActive = False;
  1130. X    newMenuInfo->pinIn = False;
  1131. X    newMenuInfo->litButton = NOBUTTON;
  1132. X    newMenuInfo->ringedButton = newMenuInfo->menu->buttonDefault;
  1133. X
  1134. X    /* save a back pointer to the original and mark it pinned */
  1135. X    newMenuInfo->origmenuInfo = origMenuInfo;
  1136. X    newMenuInfo->pinnedBrother = NULL;
  1137. X    origMenuInfo->pinnedBrother = newMenuInfo;
  1138. X
  1139. X    /* create the associated structure */
  1140. X    w = MemNew(WinPinMenu);
  1141. X    w->class = &classPinMenu;
  1142. X    w->core.kind = WIN_PINMENU;
  1143. X    w->core.children = NULL;
  1144. X    w->core.client = winInfo->core.client;
  1145. X    w->core.x = newMenuInfo->menuX;    
  1146. X    w->core.y = newMenuInfo->menuY;
  1147. X    w->core.width = newMenuInfo->menuWidth;
  1148. X    w->core.height = newMenuInfo->menuHeight;
  1149. X    w->core.dirtyconfig = CWX|CWY|CWWidth|CWHeight;
  1150. X    w->core.exposures = NULL;
  1151. X    w->core.helpstring = (char *)0;
  1152. X    w->core.colormap = winInfo->core.client->scrInfo->colormap;
  1153. X
  1154. X    /* create the actual window */
  1155. X        attributes.event_mask = ButtonReleaseMask | ButtonPressMask | 
  1156. X        ExposureMask | PropertyChangeMask | ButtonMotionMask |
  1157. X        KeyPressMask | KeyReleaseMask | EnterWindowMask;
  1158. X        attributes.background_pixel = 
  1159. X        winInfo->core.client->scrInfo->colorInfo.bg1Color;
  1160. X    attributes.border_pixel = 0;
  1161. X    attributes.colormap = w->core.colormap;
  1162. X    attributes.cursor = GRV.MenuPointer;
  1163. X        valuemask = CWEventMask | CWBackPixel | CWBorderPixel |
  1164. X        CWColormap | CWCursor;
  1165. X
  1166. X        win = XCreateWindow(dpy, WinRootID(winInfo),
  1167. X                        w->core.x, w->core.y,
  1168. X            w->core.width, w->core.height,
  1169. X                        0,
  1170. X                        WinDepth(winInfo),
  1171. X                        InputOutput,
  1172. X                        WinVisual(winInfo),
  1173. X                        valuemask,
  1174. X                        &attributes);
  1175. X    w->core.self = win;
  1176. X
  1177. X    /* register the window */
  1178. X    WIInstallInfo((WinGeneric *)w);
  1179. X
  1180. X    /* first we set the properties defining what kind of 
  1181. X       OpenLook window it is */
  1182. X    atomList[0] = AtomWTOther;
  1183. X    atomList[1] = AtomMenuLimited;
  1184. X    atomList[2] = (Atom) PIN_IN;
  1185. X    XChangeProperty(dpy, win, AtomWinAttr, AtomWinAttr,
  1186. X        32, PropModeReplace, (unsigned char *)atomList, 3);
  1187. X
  1188. X    /* add a push-pin */
  1189. X    atomList[0] = AtomDecorPin;
  1190. X    atomList[1] = AtomDecorHeader;
  1191. X    XChangeProperty(dpy, win, AtomDecorAdd, XA_ATOM,
  1192. X        32, PropModeReplace, (unsigned char *)atomList, 2);
  1193. X
  1194. X    /* set protocols */
  1195. X    atomList[0] = AtomDeleteWindow;
  1196. X    XChangeProperty(dpy, win, AtomProtocols, XA_ATOM,
  1197. X        32, PropModeReplace, (unsigned char *)atomList, 1);
  1198. X
  1199. X    /* now set the size hints */
  1200. X    sizeHints.flags = USPosition | USSize;
  1201. X    XChangeProperty(dpy, win, XA_WM_NORMAL_HINTS, XA_WM_SIZE_HINTS, 
  1202. X        32, PropModeReplace, (unsigned char *)&sizeHints,
  1203. X        sizeof(XSizeHints)/sizeof(long));
  1204. X
  1205. X    /* and the wmHints */
  1206. X    wmHints.flags = InputHint | StateHint;
  1207. X    wmHints.initial_state = NormalState;
  1208. X    wmHints.input = True;
  1209. X
  1210. X    if (winInfo->core.kind == WIN_VIRTUAL) {
  1211. X        wmHints.flags |= WindowGroupHint;
  1212. X        wmHints.window_group = winInfo->core.self;
  1213. X    }
  1214. X
  1215. X    XChangeProperty(dpy, win, XA_WM_HINTS, XA_WM_HINTS, 
  1216. X        32, PropModeReplace, (unsigned char *)&wmHints,
  1217. X        sizeof(XWMHints)/sizeof(long));
  1218. X
  1219. X    /* put the title into the header */
  1220. X    XStoreName(dpy, win, newMenuInfo->menu->title);
  1221. X
  1222. X    newMenuInfo->menuWin = (WinGeneric *)w;
  1223. X    w->menuInfo = newMenuInfo;
  1224. X
  1225. X    rootWin = w->core.client->scrInfo->rootid;
  1226. X    StateNew(dpy, rootWin, win, False, (WinPane *)w);
  1227. X
  1228. X    return w;
  1229. X}
  1230. X
  1231. X/*
  1232. X * PinMenuInit - initializes class functions
  1233. X */
  1234. X/*ARGSUSED*/
  1235. Xint
  1236. XPinMenuInit(dpy)
  1237. XDisplay *dpy;
  1238. X{
  1239. X    classPinMenu.core.kind = WIN_PINMENU;
  1240. X    classPinMenu.core.xevents[ButtonPress] = eventButtonPress;
  1241. X    classPinMenu.core.xevents[ClientMessage] = eventClientMessage;
  1242. X    classPinMenu.core.xevents[KeyPress] = eventKeyEvent;
  1243. X    classPinMenu.core.xevents[KeyRelease] = eventKeyEvent;
  1244. X    classPinMenu.core.xevents[EnterNotify] = eventEnterNotify;
  1245. X    classPinMenu.core.xevents[Expose] = MenuEventExpose;
  1246. X    classPinMenu.core.focusfunc = focusMenuFunc;
  1247. X    classPinMenu.core.drawfunc = MenuEventDrawMenu;
  1248. X    classPinMenu.core.destroyfunc = destroyMenu;
  1249. X    classPinMenu.core.selectfunc = NULL;
  1250. X    classPinMenu.core.newconfigfunc = newconfigMenu;
  1251. X    classPinMenu.core.newposfunc = WinNewPosFunc;
  1252. X    classPinMenu.core.setconfigfunc = WinSetConfigFunc;
  1253. X    classPinMenu.core.createcallback = menuSetParent;
  1254. X    classPinMenu.core.heightfunc = NULL;
  1255. X    classPinMenu.core.widthfunc = NULL;
  1256. X    classPinMenu.pcore.setsizefunc = NULL;
  1257. X}
  1258. END_OF_FILE
  1259. if test 10976 -ne `wc -c <'winpinmenu.c'`; then
  1260.     echo shar: \"'winpinmenu.c'\" unpacked with wrong size!
  1261. fi
  1262. # end of 'winpinmenu.c'
  1263. fi
  1264. if test -f 'winroot.c' -a "${1}" != "-c" ; then 
  1265.   echo shar: Will not clobber existing file \"'winroot.c'\"
  1266. else
  1267. echo shar: Extracting \"'winroot.c'\" \(17999 characters\)
  1268. sed "s/^X//" >'winroot.c' <<'END_OF_FILE'
  1269. X/*
  1270. X *      (c) Copyright 1989, 1990 Sun Microsystems, Inc. Sun design patents
  1271. X *      pending in the U.S. and foreign countries. See LEGAL_NOTICE
  1272. X *      file for terms of the license.
  1273. X */
  1274. X
  1275. X#ident    "@(#)winroot.c    1.1 olvwm version 1/3/92"
  1276. X
  1277. X/*
  1278. X * Based on
  1279. X#ident    "@(#)winroot.c    26.48    91/09/20 SMI"
  1280. X *
  1281. X */
  1282. X
  1283. X#include <errno.h>
  1284. X#include <stdio.h>
  1285. X#include <X11/Xos.h>
  1286. X#include <X11/Xlib.h>
  1287. X#include <X11/Xutil.h>
  1288. X#include <X11/Xatom.h>
  1289. X#include <olgx/olgx.h>
  1290. X
  1291. X#include "i18n.h"
  1292. X#include "ollocale.h"
  1293. X#include "mem.h"
  1294. X#include "olwm.h"
  1295. X#include "win.h"
  1296. X#include "menu.h"
  1297. X#include "globals.h"
  1298. X#include "group.h"
  1299. X#include "events.h"
  1300. X#include "virtual.h"
  1301. X
  1302. X/***************************************************************************
  1303. X* global data
  1304. X***************************************************************************/
  1305. X
  1306. Xextern Time    SelectionTime;
  1307. Xextern Atom    AtomSunWMProtocols;
  1308. Xextern Atom    AtomSunWindowState;
  1309. Xextern Atom    AtomSunOLWinAttr5;
  1310. Xextern Bool    DoingWindowState;
  1311. X
  1312. X/***************************************************************************
  1313. X* private data
  1314. X***************************************************************************/
  1315. X
  1316. Xstatic ClassRoot classRoot;
  1317. X
  1318. X/***************************************************************************
  1319. X* private functions
  1320. X***************************************************************************/
  1321. X
  1322. Xstatic Window
  1323. XfindLeafWindow(dpy,win,srcx,srcy,dstx,dsty)
  1324. X    Display    *dpy;
  1325. X    Window    win;
  1326. X    int    srcx,srcy;
  1327. X    int    *dstx,*dsty;
  1328. X{
  1329. X    Window    childwin,dstwin,srcwin;
  1330. X
  1331. X    srcwin = dstwin = win;
  1332. X    while (1) {
  1333. X        XTranslateCoordinates(dpy,srcwin,dstwin,srcx,srcy,
  1334. X            dstx,dsty,&childwin);
  1335. X        if (childwin == None)
  1336. X            break;
  1337. X        srcx = *dstx; srcy = *dsty;
  1338. X        srcwin = dstwin;
  1339. X        dstwin = childwin;
  1340. X    }
  1341. X    return dstwin;
  1342. X}
  1343. X
  1344. Xstatic void
  1345. XredistributeKeystroke(dpy,key,dstwin,dstx,dsty )
  1346. X    Display *dpy;
  1347. X    XKeyEvent *key;
  1348. X    Window    dstwin;
  1349. X    int    dstx,dsty;
  1350. X{
  1351. X    static Bool    pressreceived = False;
  1352. X    static XKeyEvent pressevent;
  1353. X    Window        childwin;
  1354. X
  1355. X    if (key->type == KeyPress) {
  1356. X        if (pressreceived == False) {
  1357. X            pressevent = *key;
  1358. X            pressevent.x = dstx;
  1359. X            pressevent.y = dsty;
  1360. X            pressevent.window = dstwin;
  1361. X            pressevent.subwindow = None;
  1362. X            XSendEvent( dpy, pressevent.window, True, 
  1363. X                KeyPressMask, (XEvent *)&pressevent );
  1364. X            pressreceived = True;
  1365. X        }
  1366. X        } else {
  1367. X        if (key->window != pressevent.window) {
  1368. X            XTranslateCoordinates(dpy,key->window,pressevent.window,
  1369. X                key->x,key->y,&dstx,&dsty,&childwin );
  1370. X                    key->window = pressevent.window;
  1371. X                    key->x = dstx;
  1372. X                    key->y = dsty;
  1373. X        }
  1374. X            key->subwindow = None;
  1375. X            XSendEvent(dpy,pressevent.window,True,
  1376. X                KeyPressMask,(XEvent *)key);
  1377. X        if (key->type == KeyRelease)
  1378. X                pressreceived = False;
  1379. X        }
  1380. X}
  1381. X
  1382. X
  1383. X/*
  1384. X * HandleHelpKey - Figure out what window should really get the Help key.
  1385. X *    If it's not an olwm window or a pane window then send the key event
  1386. X *    onto that window.  If it's an olwm window then bring up the help
  1387. X *    info window with the window kind specific help.  If it is a
  1388. X *    WIN_ROOT window we need to use key->root since it is the root
  1389. X *    window that the pointer was on when the event happened while
  1390. X *    key->window is the window that the grab was made on.
  1391. X */
  1392. Xvoid
  1393. XHandleHelpKey(dpy, pEvent)
  1394. X    Display    *dpy;
  1395. X    XEvent    *pEvent;
  1396. X{
  1397. X    static WinGeneric    *olwmWin = (WinGeneric *)0;
  1398. X    XKeyEvent        *key = (XKeyEvent *)pEvent;
  1399. X    static Window        dstwin = None;
  1400. X    int            dstx,dsty;
  1401. X    
  1402. X    if (key->type == KeyPress) {
  1403. X
  1404. X        dstwin = findLeafWindow(dpy,key->window,
  1405. X                    key->x_root,key->y_root,&dstx,&dsty);
  1406. X        olwmWin = WIGetInfo(dstwin);
  1407. X        if (!olwmWin) {
  1408. X        olwmWin = VGetInfo(dstwin);
  1409. X        if (olwmWin && olwmWin->core.client)
  1410. X            olwmWin = (WinGeneric *)
  1411. X        olwmWin->core.client->scrInfo->vdm->client->framewin->fcore.panewin;
  1412. X        }
  1413. X
  1414. X        /* send the help key to the client window */
  1415. X        if (olwmWin == NULL || olwmWin->core.kind == WIN_PANE) {
  1416. X        redistributeKeystroke(dpy,key,dstwin,dstx,dsty);
  1417. X        olwmWin = (WinGeneric *)0;
  1418. X
  1419. X        /* find out which root window is really happened on */
  1420. X        } else if (olwmWin->core.kind == WIN_ROOT) {
  1421. X        if (dstwin != key->root)
  1422. X                olwmWin = WIGetInfo(key->root);
  1423. X        WinShowHelp(dpy,olwmWin,key->x_root,key->y_root);
  1424. X
  1425. X        /* it belongs to a decoration window (frame/resize/whatever) */
  1426. X        } else {
  1427. X        WinShowHelp(dpy,olwmWin,key->x_root,key->y_root);
  1428. X        }
  1429. X        } else { /* if KeyRelease */
  1430. X        if (olwmWin == NULL && dstwin != None)
  1431. X        redistributeKeystroke(dpy,key,dstwin,0,0);
  1432. X        dstwin = None;
  1433. X        }
  1434. X}
  1435. X
  1436. Xstatic Bool
  1437. XmatchKeystrokeToSpec(event,spec)
  1438. X    XEvent *event;
  1439. X    KeySpec *spec;
  1440. X{
  1441. X        return (spec->keycode == event->xkey.keycode &&
  1442. X            (spec->modmask == AnyModifier ||
  1443. X             spec->modmask == event->xkey.state));
  1444. X}
  1445. X
  1446. X/***************************************************************************
  1447. X* event functions
  1448. X***************************************************************************/
  1449. X
  1450. X/* 
  1451. X * eventEnterNotify - the pointer has entered the root window
  1452. X */
  1453. Xstatic int
  1454. XeventEnterNotify(dpy, pEvent, winInfo)
  1455. X    Display        *dpy;
  1456. X    XEvent        *pEvent;
  1457. X    WinRoot        *winInfo;
  1458. X{
  1459. X    ColorWindowCrossing(dpy, pEvent, winInfo);
  1460. X
  1461. X    if (GRV.FocusFollowsMouse)
  1462. X        NoFocusTakeFocus(dpy, pEvent->xcrossing.time,
  1463. X                 winInfo->core.client->scrInfo);
  1464. X}
  1465. X
  1466. X/* 
  1467. X * eventConfigureRequest - a client wants to change configuration
  1468. X */
  1469. Xstatic int
  1470. XeventConfigureRequest(dpy, pEvent, winInfo)
  1471. X    Display        *dpy;
  1472. X    XEvent        *pEvent;
  1473. X    WinRoot        *winInfo;
  1474. X{
  1475. X    WinGeneric    *clientInfo;
  1476. X#define ConfEvent    (pEvent->xconfigurerequest)
  1477. X
  1478. X    if ((clientInfo = WIGetInfo(ConfEvent.window)) == NULL)
  1479. X    {
  1480. X        /* we don't know about this window, so let it go */
  1481. X        ClientConfigure(NULL,NULL,pEvent);
  1482. X    }
  1483. X    else /* OBSOLETE: if (ConfEvent.value_mask & (CWX | CWY | CWWidth | CWHeight)) */
  1484. X    {
  1485. X        /* configure the window and its frame */
  1486. X        ClientConfigure(clientInfo->core.client,clientInfo,pEvent);
  1487. X    }
  1488. X    /* REMIND doesn't handle stacking or border width yet */
  1489. X}
  1490. X
  1491. X/* 
  1492. X * eventMapRequest - a new client is mapping
  1493. X */
  1494. Xstatic int
  1495. XeventMapRequest(dpy, pEvent, winInfo)
  1496. X    Display        *dpy;
  1497. X    XEvent        *pEvent;
  1498. X    WinRoot        *winInfo;
  1499. X{
  1500. X#ifdef GPROF_HOOKS
  1501. X    moncontrol(1);
  1502. X#endif /* GPROF_HOOKS */
  1503. X    StateNew(dpy,winInfo->core.self,pEvent->xmaprequest.window,False,NULL);
  1504. X#ifdef GPROF_HOOKS
  1505. X    moncontrol(0);
  1506. X#endif /* GPROF_HOOKS */
  1507. X}
  1508. X
  1509. X
  1510. Xstatic void
  1511. XselectInBox(dpy, winInfo, boxX, boxY, boxW, boxH, timestamp, closure)
  1512. X    Display        *dpy;
  1513. X    WinRoot        *winInfo;
  1514. X    int            boxX, boxY;
  1515. X    unsigned int    boxW, boxH;
  1516. X    Time        timestamp;
  1517. X    void        *closure;
  1518. X{
  1519. X    ClientInBoxClosure cibclosure;
  1520. X    int        fuzz = GRV.SelectionFuzz;
  1521. X
  1522. X    /* 
  1523. X     * Apply selectFunc to all clients in the box.
  1524. X     * Widen the box slightly to make selections easier.
  1525. X     */
  1526. X    cibclosure.dpy = dpy;
  1527. X    cibclosure.screen = WinScreen(winInfo);
  1528. X    cibclosure.func = (int (*)()) closure;
  1529. X    cibclosure.bx = boxX - fuzz;
  1530. X    cibclosure.by = boxY - fuzz;
  1531. X    cibclosure.bw = boxW + 2 * fuzz;
  1532. X    cibclosure.bh = boxH + 2 * fuzz;
  1533. X    cibclosure.timestamp = timestamp;
  1534. X    ListApply(ActiveClientList, ClientInBox, &cibclosure);
  1535. X}
  1536. X
  1537. X
  1538. X/* 
  1539. X * eventMotionNotify - the pointer is moving
  1540. X */
  1541. Xstatic int
  1542. XeventMotionNotify(dpy, pEvent, winInfo)
  1543. X    Display        *dpy;
  1544. X    XEvent        *pEvent;
  1545. X    WinRoot        *winInfo;
  1546. X{
  1547. X    short            boxX, boxY, boxW, boxH;
  1548. X    int            (*selectFunc)();
  1549. X
  1550. X    if (!pEvent->xmotion.same_screen)
  1551. X        return;
  1552. X
  1553. X    /* If the user hasn't moved more than the threshold
  1554. X     * amount, break out of here.  REMIND  Also, if we get a 
  1555. X     * MotionNotify event with no buttons down, we ignore it.
  1556. X     * Ideally this shouldn't happen, but some areas of the code
  1557. X     * still leave the pointer grabbed even after all the buttons
  1558. X     * have gone up.
  1559. X     */
  1560. X    if ((ABS(pEvent->xmotion.x - winInfo->buttonPressEvent.xbutton.x) < 
  1561. X         GRV.MoveThreshold) &&
  1562. X        (ABS(pEvent->xmotion.y - winInfo->buttonPressEvent.xbutton.y) < 
  1563. X         GRV.MoveThreshold))
  1564. X        return;
  1565. X    if (pEvent->xmotion.state == 0)
  1566. X       return;
  1567. X    
  1568. X    /*
  1569. X     * On Select: Clear existing selected clients and add new ones
  1570. X     * On Adjust: Toggle selections on/off
  1571. X     */
  1572. X    switch(winInfo->currentAction) {
  1573. X    case ACTION_SELECT:    
  1574. X        ClearSelections(dpy);
  1575. X        selectFunc = AddSelection;
  1576. X        break;
  1577. X    case ACTION_ADJUST:    
  1578. X        selectFunc = ToggleSelection;
  1579. X        break;
  1580. X    default:
  1581. X        selectFunc = NULL;
  1582. X        break;
  1583. X    }
  1584. X
  1585. X    if (selectFunc)
  1586. X        TraceRootBox(dpy, winInfo, &(winInfo->buttonPressEvent),
  1587. X                 selectInBox, selectFunc);
  1588. X}
  1589. X
  1590. X/* 
  1591. X * eventButtonRelease - handle a click in the root.
  1592. X *
  1593. X * If the user clicks in the window, the focus is set to the no-focus window, 
  1594. X * and the PRIMARY selection is acquired and nulled.
  1595. X */
  1596. Xstatic int
  1597. XeventButtonRelease(dpy, pEvent, winInfo)
  1598. X    Display        *dpy;
  1599. X    XEvent        *pEvent;
  1600. X    WinRoot        *winInfo;
  1601. X{
  1602. X    if (!AllButtonsUp(pEvent))
  1603. X        return;
  1604. X
  1605. X    /*
  1606. X     * This only happens if we did NOT get a motion notify
  1607. X     * after the last button press. 
  1608. X     */
  1609. X    if (winInfo->currentAction == ACTION_SELECT) {
  1610. X        NoFocusTakeFocus(dpy,pEvent->xbutton.time,
  1611. X                 winInfo->core.client->scrInfo);
  1612. X        ClearSelections(dpy);
  1613. X        XSetSelectionOwner(dpy, XA_PRIMARY, NoFocusWin,
  1614. X                   pEvent->xbutton.time);
  1615. X        SelectionTime = pEvent->xbutton.time;
  1616. X    }
  1617. X    winInfo->currentAction = ACTION_NONE;
  1618. X}
  1619. X        
  1620. X/* 
  1621. X * eventButtonPress - handle a button press.  If the WMGRAB modifier is down,
  1622. X * we've received this event by virtue of a passive, synchronous button grab
  1623. X * on the root.  We need to (1) propagate the event to the window underneath,
  1624. X * if it's a frame or an icon, (2) unfreeze the pointer either by regrabbing
  1625. X * or by issuing an AllowEvents request, and (3) ungrab the pointer if the
  1626. X * child's handler didn't issue a grab of its own.
  1627. X */
  1628. Xstatic int
  1629. XeventButtonPress(dpy, pEvent, winInfo)
  1630. X    Display        *dpy;
  1631. X    XEvent        *pEvent;
  1632. X    WinRoot        *winInfo;
  1633. X{
  1634. X    SemanticAction a;
  1635. X    WinGeneric *child;
  1636. X
  1637. X    if (pEvent->xbutton.state & ModMaskMap[MOD_WMGRAB]) {
  1638. X        /* redistribute to child */
  1639. X        if (pEvent->xbutton.subwindow != NULL &&
  1640. X        (child = WIGetInfo(pEvent->xbutton.subwindow)) != NULL &&
  1641. X        (child->core.kind == WIN_FRAME ||
  1642. X         child->core.kind == WIN_ICON) &&
  1643. X        (GrabSuccess == XGrabPointer(dpy, child->core.self, False,
  1644. X            ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
  1645. X            GrabModeAsync, GrabModeAsync, None, None,
  1646. X            pEvent->xbutton.time)))
  1647. X        {
  1648. X        PropagatePressEventToChild(dpy, pEvent, child);
  1649. X        return;
  1650. X        }
  1651. X
  1652. X        /*
  1653. X         * If the window under the pointer isn't a frame or icon, or if we 
  1654. X         * failed to grab the pointer, simply unfreeze the pointer and try 
  1655. X         * to process the event normally.
  1656. X         */
  1657. X        XAllowEvents(dpy, AsyncBoth, pEvent->xbutton.time);
  1658. X    }
  1659. X
  1660. X    a = ResolveMouseBinding(dpy, pEvent, ModMaskMap[MOD_CONSTRAIN]);
  1661. X
  1662. X    winInfo->buttonPressEvent = *pEvent;
  1663. X
  1664. X    switch (a) {
  1665. X    case ACTION_MENU:
  1666. X            RootMenuShow(dpy, winInfo, pEvent);
  1667. X            /* FALL THRU */
  1668. X    case ACTION_SELECT:
  1669. X    case ACTION_ADJUST:
  1670. X            winInfo->currentAction = a;
  1671. X            break;
  1672. X    }
  1673. X}
  1674. X
  1675. X
  1676. X/* 
  1677. X * eventKeyPressRelease - a keystroke has happened in the root window
  1678. X */
  1679. Xstatic int
  1680. XeventKeyPressRelease(dpy, pEvent, winInfo)
  1681. X    Display        *dpy;
  1682. X    XEvent        *pEvent;
  1683. X    WinRoot        *winInfo;
  1684. X{
  1685. X
  1686. X    Window        child;
  1687. X    WinGeneric    *childInfo;
  1688. X    Client        *childClient;
  1689. X    Bool        samescreen;
  1690. X    int        destX, destY;
  1691. X    extern Bool    ExecuteKeyboardFunction();
  1692. X    Bool        isbound;
  1693. X
  1694. X    isbound = ExecuteKeyboardFunction(dpy, pEvent);
  1695. X
  1696. X    if (!isbound && GRV.ArrowInRoot)
  1697. X        isbound = KeyMoveVDM(dpy, pEvent);
  1698. X
  1699. X    if (!isbound && pEvent->type == KeyPress)
  1700. X        KeyBeep(dpy,pEvent);
  1701. X
  1702. X#ifdef notdef
  1703. X    samescreen = XTranslateCoordinates(dpy,
  1704. X                pEvent->xkey.root, pEvent->xkey.root,
  1705. X                pEvent->xkey.x_root, pEvent->xkey.y_root, 
  1706. X                &destX, &destY, &child );
  1707. X
  1708. X    if (!samescreen)
  1709. X        return;
  1710. X
  1711. X    if (pEvent->type == KeyPress && child != None &&
  1712. X        matchKeystrokeToSpec(pEvent, &(GRV.FrontKey))) {
  1713. X
  1714. X        XWindowChanges xwc;
  1715. X        xwc.stack_mode = Opposite; NOT DEF
  1716. X        XConfigureWindow( dpy, child, CWStackMode, &xwc );
  1717. X
  1718. X    } else if (matchKeystrokeToSpec(pEvent, &(GRV.HelpKey))) {
  1719. X
  1720. X        handleHelpKey(dpy,pEvent);
  1721. X
  1722. X    } else if (pEvent->type == KeyPress && child != None &&
  1723. X           matchKeystrokeToSpec(pEvent, &(GRV.OpenKey))) {
  1724. X
  1725. X        childInfo = WIGetInfo(child);
  1726. X        if ( childInfo ) {
  1727. X            childClient = childInfo->core.client;
  1728. X            if (childClient != NULL) {
  1729. X                ClientOpenCloseToggle(childClient);
  1730. X            }
  1731. X        }
  1732. X    } else if (pEvent->type == KeyPress &&
  1733. X           matchKeystrokeToSpec(pEvent, &(GRV.ColorLockKey))) {
  1734. X
  1735. X        InstallPointerColormap(dpy, pEvent->xkey.root, 
  1736. X            pEvent->xkey.x_root, pEvent->xkey.y_root, True);
  1737. X
  1738. X    } else if (pEvent->type == KeyPress &&
  1739. X           matchKeystrokeToSpec(pEvent, &(GRV.ColorUnlockKey))) {
  1740. X
  1741. X        UnlockColormap(dpy,winInfo);
  1742. X    }
  1743. X#endif /* notdef */
  1744. X}
  1745. X
  1746. X/* 
  1747. X * eventPropertyNotify - a root property has changed
  1748. X */
  1749. Xstatic int
  1750. XeventPropertyNotify(dpy, pEvent, winInfo)
  1751. X    Display        *dpy;
  1752. X    XEvent        *pEvent;
  1753. X    WinRoot        *winInfo;
  1754. X{
  1755. X    unsigned long    nitems, remain;
  1756. X    char         *resourceString;
  1757. X
  1758. X    /* make sure that the property was the one we care about and
  1759. X     * changed (as opposed to deleted)
  1760. X     */
  1761. X    if ( (pEvent->xproperty.atom != XA_RESOURCE_MANAGER) 
  1762. X         || (pEvent->xproperty.state != PropertyNewValue) )
  1763. X        return;
  1764. X
  1765. X    resourceString = GetWindowProperty(dpy, WinRootID(winInfo),
  1766. X        XA_RESOURCE_MANAGER, 0L, 100000000L, 
  1767. X        /* REMIND use ENTIRE_CONTENTS */
  1768. X        XA_STRING, 0, &nitems, &remain);
  1769. X    if (resourceString != NULL) {
  1770. X        UpdateGlobals(dpy, resourceString);
  1771. X        XFree( resourceString );
  1772. X        }
  1773. X}
  1774. X
  1775. X/* 
  1776. X * eventUnmapNotify - an unreparented pane is going away
  1777. X */
  1778. Xstatic int
  1779. XeventUnmapNotify(dpy, pEvent, winInfo)
  1780. X    Display        *dpy;
  1781. X    XEvent        *pEvent;
  1782. X    WinRoot        *winInfo;
  1783. X{
  1784. X    WinGeneric *wg;
  1785. X
  1786. X    wg = WIGetInfo(pEvent->xunmap.window);
  1787. X    if (wg != NULL) {
  1788. X        StateWithdrawn(wg->core.client);
  1789. X    }
  1790. X}
  1791. X
  1792. X/*
  1793. X * destroyRoot -- destroy the root window resources and free any allocated
  1794. X *    data.
  1795. X */
  1796. Xstatic int
  1797. XdestroyRoot(dpy, winInfo)
  1798. X    Display        *dpy;
  1799. X    WinRoot     *winInfo;
  1800. X{
  1801. X    /* delete the _SUN_WM_PROTOCOLS property */
  1802. X    XDeleteProperty(dpy,winInfo->core.self,AtomSunWMProtocols);
  1803. X
  1804. X    /* delete the WM_ICON_SIZE property */
  1805. X    XDeleteProperty(dpy,winInfo->core.self,XA_WM_ICON_SIZE);
  1806. X
  1807. X    /* free our data and throw away window */
  1808. X    WIUninstallInfo(winInfo->core.self);
  1809. X    MemFree(winInfo);
  1810. X}
  1811. X
  1812. X/*
  1813. X * writeProtocols - write the _SUN_WM_PROTOCOLS property on the root win,
  1814. X *            which advertises the capabilities of the window manager.
  1815. X */
  1816. Xstatic void
  1817. XwriteProtocols(dpy,rootwin)
  1818. X    Display        *dpy;
  1819. X    Window        rootwin;
  1820. X{
  1821. X    unsigned int    data[10];
  1822. X    int        nitems = 0;
  1823. X    
  1824. X    /* conditionally support the _SUN_WINDOW_STATE protocol */
  1825. X    if (DoingWindowState)
  1826. X        data[nitems++] = AtomSunWindowState;
  1827. X
  1828. X    /* support 5-word-long _OL_WIN_ATTR property */
  1829. X    data[nitems++] = AtomSunOLWinAttr5;
  1830. X
  1831. X    if (nitems == 0)
  1832. X        return;
  1833. X
  1834. X    XChangeProperty(dpy,rootwin,AtomSunWMProtocols,XA_ATOM,32,
  1835. X            PropModeReplace,(unsigned char *)data,nitems);
  1836. X}
  1837. X
  1838. X/*
  1839. X * writeIconSize - write the WM_ICON_SIZE property on the root window.
  1840. X */
  1841. Xstatic void
  1842. XwriteIconSize(dpy,rootwin)
  1843. X    Display        *dpy;
  1844. X    Window        rootwin;
  1845. X{
  1846. X    XIconSize    iconSize;
  1847. X
  1848. X    iconSize.min_width = ICON_MIN_WIDTH;
  1849. X    iconSize.min_height = ICON_MIN_HEIGHT;
  1850. X    iconSize.max_width = ICON_MAX_WIDTH;
  1851. X    iconSize.max_height = ICON_MAX_HEIGHT;
  1852. X    iconSize.width_inc = ICON_WIDTH_INC;
  1853. X    iconSize.height_inc = ICON_HEIGHT_INC;
  1854. X
  1855. X    XSetIconSizes(dpy,rootwin,&iconSize,1);
  1856. X}
  1857. X
  1858. X/***************************************************************************
  1859. X* global functions
  1860. X***************************************************************************/
  1861. X
  1862. X/*
  1863. X * MakeRoot  -- create the root window. Return a WinGeneric structure.
  1864. X */
  1865. XWinRoot *
  1866. XMakeRoot(dpy, cli)
  1867. X    Display    *dpy;
  1868. X    Client    *cli;
  1869. X{
  1870. X    XWindowAttributes attr;
  1871. X    WinRoot *w;
  1872. X    Window win;
  1873. X
  1874. X    win = cli->scrInfo->rootid;
  1875. X
  1876. X    /*
  1877. X      * Tell the server we need to get mapping requests.
  1878. X     * ErrorSensitive will force an exit if this fails
  1879. X     * (ie another window manager is running).
  1880. X     *
  1881. X     * REMIND: instead of exiting, MakeRoot should probably just
  1882. X     * return NULL, and callers to MakeRoot should check the return
  1883. X     * value.
  1884. X     */
  1885. X    ErrorSensitive(
  1886. X        gettext("Perhaps there is another window manager running?"));
  1887. X    XSelectInput(dpy,win,
  1888. X        KeyPressMask | SubstructureRedirectMask |
  1889. X        ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
  1890. X        EnterWindowMask | PropertyChangeMask | OwnerGrabButtonMask);
  1891. X    XSync(dpy, False);
  1892. X    ErrorInsensitive(dpy);
  1893. X
  1894. X    if (XGetWindowAttributes(dpy, win, &attr) == 0) {
  1895. X        ErrorGeneral(gettext("Could not get attributes of root window"));
  1896. X        /*NOTREACHED*/
  1897. X    }
  1898. X
  1899. X    /* mark the client as olwm owned */
  1900. X    cli->flags = CLOlwmOwned;
  1901. X
  1902. X    /* create the associated structure */
  1903. X    w = MemNew(WinRoot);
  1904. X    w->core.self = win;
  1905. X    w->class = &classRoot;
  1906. X    w->core.kind = WIN_ROOT;
  1907. X    w->core.parent = NULL;
  1908. X    w->core.children = NULL;
  1909. X    w->core.client = cli;
  1910. X    w->core.x = 0;
  1911. X    w->core.y = 0;
  1912. X    w->core.width = attr.width;
  1913. X    w->core.height = attr.height;
  1914. X    w->core.dirtyconfig = False;
  1915. X    w->core.colormap = cli->scrInfo->colormap;
  1916. X    w->core.exposures = NULL;
  1917. X    w->core.helpstring = "olwm:Workspace";
  1918. X    w->currentAction = ACTION_NONE;
  1919. X
  1920. X    /* Write properties on the root window */
  1921. X    writeProtocols(dpy,win);
  1922. X    writeIconSize(dpy,win);
  1923. X
  1924. X    /* register the window */
  1925. X    WIInstallInfo((WinGeneric *)w);
  1926. X
  1927. X    return w;
  1928. X}
  1929. X
  1930. X/*
  1931. X * RootInit - init the WinRoot class function vector
  1932. X */
  1933. Xvoid
  1934. XRootInit(dpy)
  1935. XDisplay *dpy;
  1936. X{
  1937. X    classRoot.core.kind = WIN_ROOT;
  1938. X    classRoot.core.xevents[ConfigureRequest] = eventConfigureRequest;
  1939. X    classRoot.core.xevents[EnterNotify] = eventEnterNotify;
  1940. X    classRoot.core.xevents[MapRequest] = eventMapRequest;
  1941. X    classRoot.core.xevents[MotionNotify] = eventMotionNotify;
  1942. X    classRoot.core.xevents[ButtonRelease] = eventButtonRelease;
  1943. X    classRoot.core.xevents[ButtonPress] = eventButtonPress;
  1944. X    classRoot.core.xevents[KeyPress] = eventKeyPressRelease;
  1945. X    classRoot.core.xevents[KeyRelease] = eventKeyPressRelease;
  1946. X    classRoot.core.xevents[PropertyNotify] = eventPropertyNotify;
  1947. X    classRoot.core.xevents[UnmapNotify] = eventUnmapNotify;
  1948. X    classRoot.core.focusfunc = NULL;
  1949. X    classRoot.core.drawfunc = NULL;
  1950. X    classRoot.core.destroyfunc = destroyRoot;
  1951. X    classRoot.core.selectfunc = NULL;
  1952. X    classRoot.core.newconfigfunc = NULL;
  1953. X    classRoot.core.newposfunc = NULL;
  1954. X    classRoot.core.setconfigfunc = NULL;
  1955. X    classRoot.core.createcallback = NULL;
  1956. X    classRoot.core.heightfunc = NULL;
  1957. X    classRoot.core.widthfunc = NULL;
  1958. X}
  1959. END_OF_FILE
  1960. if test 17999 -ne `wc -c <'winroot.c'`; then
  1961.     echo shar: \"'winroot.c'\" unpacked with wrong size!
  1962. fi
  1963. # end of 'winroot.c'
  1964. fi
  1965. echo shar: End of archive 15 \(of 21\).
  1966. cp /dev/null ark15isdone
  1967. MISSING=""
  1968. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
  1969.     if test ! -f ark${I}isdone ; then
  1970.     MISSING="${MISSING} ${I}"
  1971.     fi
  1972. done
  1973. if test "${MISSING}" = "" ; then
  1974.     echo You have unpacked all 21 archives.
  1975.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1976. else
  1977.     echo You still need to unpack the following archives:
  1978.     echo "        " ${MISSING}
  1979. fi
  1980. ##  End of shell archive.
  1981. exit 0
  1982. --
  1983. Molecular Simulations, Inc.             mail: dcmartin@postgres.berkeley.edu
  1984. 796 N. Pastoria Avenue                  uucp: uwvax!ucbvax!dcmartin
  1985. Sunnyvale, California 94086             at&t: 408/522-9236
  1986.