Button.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /******************************************************************************
  24. *******************************************************************************
  25. *
  26. * (c) Copyright 1992 HEWLETT-PACKARD COMPANY
  27. * ALL RIGHTS RESERVED
  28. *
  29. *******************************************************************************
  30. ******************************************************************************/
  31. #include <stdio.h>
  32. #include <X11/cursorfont.h>
  33. #include "ButtonP.h"
  34. #include <Xm/ManagerP.h>
  35. #include <Xm/DrawP.h>
  36. #include <Dt/Control.h>
  37. #include <Dt/MacrosP.h>
  38. #include <Dt/DtStrDefs.h>
  39. #include "DtSvcInternal.h" /* _DtGetMask */
  40. #include <Xm/XmPrivate.h> /* _XmFocusInGadget, _XmFocusOutGadget, _XmSocorro */
  41. #define DELAY_DEFAULT 100
  42. static void Initialize(
  43. Widget request_w,
  44. Widget new_w) ;
  45. static void GetGCs(
  46. Widget w) ;
  47. static void UpdateGCs(
  48. Widget w) ;
  49. static void Redisplay(
  50. Widget w,
  51. XEvent *event,
  52. Region region) ;
  53. static Boolean SetValues(
  54. Widget current_w,
  55. Widget request_w,
  56. Widget new_w) ;
  57. static void Arm(
  58. Widget w,
  59. XEvent *event,
  60. String *params,
  61. Cardinal *num_params) ;
  62. static void Disarm(
  63. Widget w,
  64. XEvent *event,
  65. String *params,
  66. Cardinal *num_params) ;
  67. static void Activate(
  68. Widget w,
  69. XEvent *event,
  70. String *params,
  71. Cardinal *num_params) ;
  72. static void ArmAndActivate(
  73. Widget w,
  74. XEvent *event,
  75. String *params,
  76. Cardinal *num_params) ;
  77. static void InputDispatch(
  78. Widget w,
  79. XButtonEvent *event,
  80. Mask event_mask) ;
  81. static Boolean VisualChange(
  82. Widget w,
  83. Widget current_w,
  84. Widget new_w) ;
  85. static void ArmTimeout(
  86. Widget w,
  87. XtIntervalId *id) ;
  88. static void Enter(
  89. Widget wid,
  90. XEvent *event,
  91. String *params,
  92. Cardinal *num_params) ;
  93. static void Leave(
  94. Widget wid,
  95. XEvent *event,
  96. String *params,
  97. Cardinal *num_params) ;
  98. static void CallCallback(
  99. DtButtonGadget g,
  100. XtCallbackList cb,
  101. int reason,
  102. XEvent *event) ;
  103. static void DefaultSelectColor(
  104. Widget widget,
  105. int offset,
  106. XrmValue *value) ;
  107. /* Resource list for button */
  108. #define R_Offset(field) \
  109. XtOffset (DtButtonGadget, button.field)
  110. static XtResource resources[] =
  111. {
  112. {
  113. XmNcursorFont,
  114. XmCCursorFont, XmRInt, sizeof (int),
  115. R_Offset (cursor_font),
  116. XmRImmediate, (XtPointer) 1
  117. },
  118. {
  119. XmNarmColor,
  120. XmCArmColor, XmRPixel, sizeof (Pixel),
  121. R_Offset (arm_color),
  122. XmRCallProc, (XtPointer) DefaultSelectColor
  123. },
  124. {
  125. XmNsubpanel,
  126. XmCSubpanel, XmRWidget, sizeof (Widget),
  127. R_Offset (subpanel),
  128. XmRImmediate, (XtPointer) NULL
  129. },
  130. {
  131. XmNpushFunction,
  132. XmCPushFunction, XmRFunction, sizeof (XtPointer),
  133. R_Offset (push_function),
  134. XmRImmediate, (XtPointer) NULL
  135. },
  136. {
  137. XmNpushArgument,
  138. XmCPushArgument, XmRPointer, sizeof (XtPointer),
  139. R_Offset (push_argument),
  140. XmRImmediate, (XtPointer) NULL
  141. },
  142. {
  143. XmNimageName,
  144. XmCString, XmRString, sizeof (String),
  145. R_Offset (image_name),
  146. XmRImmediate, (XtPointer) ""
  147. },
  148. {
  149. XmNcallback,
  150. XmCCallback, XmRCallback, sizeof(XtCallbackList),
  151. R_Offset (callback),
  152. XmRImmediate, (caddr_t) NULL
  153. },
  154. {
  155. XmNmultiClick,
  156. XmCMultiClick, XmRMultiClick, sizeof (unsigned char),
  157. R_Offset (multiClick),
  158. XmRImmediate, (XtPointer) XmMULTICLICK_KEEP
  159. }
  160. };
  161. /* The button class record definition */
  162. externaldef (dtbuttongadgetclassrec)
  163. DtButtonGadgetClassRec dtButtonGadgetClassRec=
  164. {
  165. {
  166. (WidgetClass) &xmGadgetClassRec, /* superclass */
  167. "DtButton", /* class_name */
  168. sizeof(DtButtonGadgetRec), /* widget_size */
  169. NULL, /* class_initialize */
  170. NULL, /* class_part_initialize */
  171. FALSE, /* class_inited */
  172. (XtInitProc) Initialize, /* initialize */
  173. NULL, /* initialize_hook */
  174. NULL, /* realize */
  175. NULL, /* actions */
  176. 0, /* num_actions */
  177. resources, /* resources */
  178. XtNumber(resources), /* num_resources */
  179. NULLQUARK, /* xrm_class */
  180. TRUE, /* compress_motion */
  181. XtExposeCompressMaximal, /* compress_exposure */
  182. TRUE, /* compress_enterleave */
  183. FALSE, /* visible_interest */
  184. NULL, /* destroy */
  185. NULL, /* resize */
  186. (XtExposeProc) Redisplay, /* expose */
  187. (XtSetValuesFunc) SetValues, /* set_values */
  188. NULL, /* set_values_hook */
  189. XtInheritSetValuesAlmost, /* set_values_almost */
  190. NULL, /* get_values_hook */
  191. NULL, /* accept_focus */
  192. XtVersion, /* version */
  193. NULL, /* callback private */
  194. NULL, /* tm_table */
  195. NULL, /* query_geometry */
  196. NULL, /* display_accelerator */
  197. NULL, /* extension */
  198. },
  199. /* XmGadget Part */
  200. {
  201. (XtWidgetProc) _XtInherit, /* Gadget border_highlight */
  202. (XtWidgetProc) _XtInherit, /* Gadget border_unhighlight */
  203. ArmAndActivate, /* arm_and_activate */
  204. (XmWidgetDispatchProc)InputDispatch, /* input_dispatch */
  205. VisualChange, /* visual_change */
  206. NULL, /* get resources */
  207. 0, /* num get_resources */
  208. NULL, /* class_cache_part */
  209. NULL, /* extension */
  210. }
  211. };
  212. externaldef(dtbuttonwidgetclass) WidgetClass dtButtonGadgetClass =
  213. (WidgetClass) &dtButtonGadgetClassRec;
  214. /************************************************************************
  215. *
  216. * Initialize
  217. * The main widget instance initialization routine.
  218. *
  219. ************************************************************************/
  220. static void
  221. Initialize(
  222. Widget request_w,
  223. Widget new_w )
  224. {
  225. DtButtonGadget request = (DtButtonGadget) request_w ;
  226. DtButtonGadget new_g = (DtButtonGadget) new_w ;
  227. XmManagerWidget mw = (XmManagerWidget) XtParent(new_w) ;
  228. new_g->button.timer = 0;
  229. new_g->button.click_count = 0;
  230. new_g->button.armTimeStamp = 0;
  231. new_g->button.activateTimeStamp = 0;
  232. B_Armed (new_g) = False;
  233. /* Set the input mask for events handled by Manager.
  234. */
  235. G_EventMask (new_g) = (XmARM_EVENT | XmACTIVATE_EVENT |
  236. XmMULTI_ARM_EVENT | XmMULTI_ACTIVATE_EVENT |
  237. XmHELP_EVENT | XmFOCUS_IN_EVENT |
  238. XmFOCUS_OUT_EVENT | XmENTER_EVENT | XmLEAVE_EVENT);
  239. /* Get pixmap and mask, get pixmap geometry, get gcs.
  240. */
  241. if (B_ImageName (new_g) != NULL)
  242. {
  243. String str = B_ImageName (new_g);
  244. B_ImageName (new_g) = XtMalloc (strlen (str) + 1);
  245. strcpy (B_ImageName (new_g), str);
  246. B_Pixmap (new_g) =
  247. XmGetPixmap (XtScreen (new_g), B_ImageName (new_g),
  248. M_BottomShadowColor (mw),
  249. M_TopShadowColor (mw));
  250. B_Mask (new_g) =
  251. _DtGetMask (XtScreen (new_g), B_ImageName (new_g));
  252. if (B_Pixmap (new_g) != XmUNSPECIFIED_PIXMAP)
  253. {
  254. Window root;
  255. int int_x = 0, int_y = 0;
  256. unsigned int int_w = 0, int_h = 0,
  257. int_bw, depth;
  258. XGetGeometry (XtDisplay (new_g), B_Pixmap (new_g),
  259. &root, &int_x, &int_y, &int_w, &int_h,
  260. &int_bw, &depth);
  261. B_PixmapWidth (new_g) = (Dimension) int_w;
  262. B_PixmapHeight (new_g) = (Dimension) int_h;
  263. }
  264. else
  265. {
  266. B_PixmapWidth (new_g) = 0;
  267. B_PixmapHeight (new_g) = 0;
  268. }
  269. }
  270. else
  271. {
  272. B_Pixmap (new_g) = XmUNSPECIFIED_PIXMAP;
  273. B_Mask (new_g) = XmUNSPECIFIED_PIXMAP;
  274. B_PixmapWidth (new_g) = 0;
  275. B_PixmapHeight (new_g) = 0;
  276. }
  277. GetGCs (new_w);
  278. /* Set widget geometry.
  279. */
  280. new_g -> gadget.shadow_thickness = 1;
  281. new_g -> gadget.highlight_thickness = 1;
  282. if (G_Width(request) == 0)
  283. {
  284. if (B_PixmapWidth (new_g) > 0)
  285. G_Width(new_g) = B_PixmapWidth (new_g) + 4;
  286. else
  287. G_Width(new_g) = 10;
  288. }
  289. if (G_Height(request) == 0)
  290. {
  291. if (B_PixmapHeight (new_g) > 0)
  292. G_Height(new_g) = B_PixmapHeight (new_g) + 4;
  293. else
  294. G_Height(new_g) = 10;
  295. }
  296. }
  297. /************************************************************************
  298. *
  299. * GetGCs
  300. * Get the graphics context used for drawing the button.
  301. *
  302. ************************************************************************/
  303. static void
  304. GetGCs(
  305. Widget w )
  306. {
  307. DtButtonGadget bg = (DtButtonGadget) w ;
  308. XmManagerWidget mw = (XmManagerWidget) XtParent(w) ;
  309. XGCValues values;
  310. XtGCMask valueMask;
  311. valueMask = GCForeground | GCBackground;
  312. values.foreground = M_Foreground(mw);
  313. values.background = M_Background(mw);
  314. bg -> button.gc_normal = XtGetGC ((Widget) mw, valueMask, &values);
  315. values.foreground = B_ArmColor (bg);
  316. bg -> button.gc_armed_bg = XtGetGC ((Widget) mw, valueMask, &values);
  317. values.foreground = M_Background(mw);
  318. values.background = M_Foreground(mw);
  319. bg -> button.gc_background = XtGetGC ((Widget) mw, valueMask, &values);
  320. /* Get Clip GC
  321. */
  322. if (B_Mask(bg) != XmUNSPECIFIED_PIXMAP)
  323. {
  324. valueMask = GCForeground | GCBackground | GCClipMask;
  325. values.clip_mask = B_Mask(bg);
  326. values.foreground = M_Foreground (mw);
  327. values.background = M_Background (mw);
  328. bg->button.gc_clip = XtGetGC ((Widget) mw, valueMask, &values);
  329. }
  330. else
  331. bg->button.gc_clip = NULL;
  332. }
  333. static void
  334. UpdateGCs(
  335. Widget w )
  336. {
  337. DtButtonGadget bg = (DtButtonGadget) w ;
  338. XmManagerWidget mw = (XmManagerWidget) XtParent(w) ;
  339. XtReleaseGC ((Widget) mw, bg->button.gc_normal);
  340. XtReleaseGC ((Widget) mw, bg->button.gc_background);
  341. XtReleaseGC ((Widget) mw, bg->button.gc_armed_bg);
  342. if (bg->button.gc_clip != NULL)
  343. XtReleaseGC ((Widget) mw, bg->button.gc_clip);
  344. GetGCs (w);
  345. }
  346. /************************************************************************
  347. *
  348. * Redisplay
  349. * General redisplay function called on exposure events.
  350. *
  351. ************************************************************************/
  352. /* ARGSUSED */
  353. static void
  354. Redisplay(
  355. Widget w,
  356. XEvent *event,
  357. Region region )
  358. {
  359. DtButtonGadget bg = (DtButtonGadget) w;
  360. Dimension s_t = bg -> gadget.shadow_thickness;
  361. Dimension h_t = bg -> gadget.highlight_thickness;
  362. Position x;
  363. Pixmap pix;
  364. GC gc;
  365. gc = (B_Armed (bg)) ? bg -> button.gc_armed_bg : bg -> button.gc_background;
  366. XFillRectangle (XtDisplay (bg), XtWindow (bg),
  367. gc, G_X(bg) +s_t + h_t, G_Y(bg) + s_t + h_t,
  368. G_Width(bg) - 2 * (s_t + h_t),
  369. G_Height(bg) - 2 * (s_t + h_t));
  370. if (s_t > 0)
  371. {
  372. GC gc1, gc2;
  373. if (B_Armed (bg))
  374. {
  375. gc1 = XmParentBottomShadowGC(w);
  376. gc2 = XmParentTopShadowGC(w);
  377. }
  378. else
  379. {
  380. gc1 = bg -> button.gc_background;
  381. gc2 = bg -> button.gc_background;
  382. }
  383. XmeDrawShadows (XtDisplay(bg), XtWindow (bg), gc1, gc2,
  384. G_X(bg) + h_t, G_Y(bg) + h_t,
  385. G_Width(bg) - 2 * h_t, G_Height(bg) - 2 * h_t,
  386. s_t,XmSHADOW_OUT);
  387. }
  388. x = G_X(bg) + ((Position)(G_Width(bg) - B_PixmapWidth (bg))/2);
  389. if (x % 2 == 1)
  390. x++;
  391. if (B_Mask (bg) != XmUNSPECIFIED_PIXMAP)
  392. {
  393. gc = bg->button.gc_clip;
  394. XSetClipMask (XtDisplay(bg), gc, B_Mask (bg));
  395. XSetClipOrigin (XtDisplay(bg), gc,
  396. x, G_Y(bg) + (Position)(G_Height(bg) - B_PixmapHeight (bg))/2);
  397. }
  398. else
  399. gc = bg->button.gc_normal;
  400. pix = B_Pixmap (bg);
  401. if ((gc != NULL) && (pix != XmUNSPECIFIED_PIXMAP))
  402. {
  403. XCopyArea (XtDisplay ((Widget) bg), pix, XtWindow ((Widget) bg), gc, 0, 0,
  404. B_PixmapWidth (bg), B_PixmapHeight (bg),
  405. x, G_Y(bg) + (Position)(G_Height(bg) - B_PixmapHeight (bg))/2);
  406. }
  407. if (bg -> gadget.highlighted)
  408. (*(xmGadgetClassRec.gadget_class.border_highlight))((Widget) bg);
  409. }
  410. /************************************************************************
  411. *
  412. * Destroy
  413. * Clean up allocated resources when the widget is destroyed.
  414. *
  415. ************************************************************************/
  416. #if 0
  417. static void
  418. Destroy(
  419. Widget w )
  420. {
  421. DtButtonGadget bg = (DtButtonGadget) w ;
  422. if (bg->button.timer)
  423. XtRemoveTimeOut (bg->button.timer);
  424. XtReleaseGC (w, bg -> button.gc_normal);
  425. XtReleaseGC (w, bg -> button.gc_background);
  426. XtReleaseGC (w, bg -> button.gc_armed_bg);
  427. if (bg -> button.gc_clip != NULL)
  428. XtReleaseGC (w, bg -> button.gc_clip);
  429. XtRemoveAllCallbacks (w, "callback");
  430. }
  431. #endif /* 0 */
  432. /************************************************************************
  433. *
  434. * SetValues
  435. * Note: The only implementation within this function is to
  436. * support the resetting of the image, cursor, and functions
  437. * as needed by the front panel.
  438. *
  439. ************************************************************************/
  440. /* ARGSUSED */
  441. static Boolean
  442. SetValues(
  443. Widget current_w,
  444. Widget request_w,
  445. Widget new_w )
  446. {
  447. DtButtonGadget current = (DtButtonGadget) current_w;
  448. DtButtonGadget new_g = (DtButtonGadget) new_w;
  449. XmManagerWidget mw = (XmManagerWidget) XtParent(new_w);
  450. Boolean returnFlag = FALSE;
  451. G_EventMask (new_g) = (XmARM_EVENT | XmACTIVATE_EVENT |
  452. XmMULTI_ARM_EVENT | XmMULTI_ACTIVATE_EVENT |
  453. XmHELP_EVENT | XmFOCUS_IN_EVENT |
  454. XmFOCUS_OUT_EVENT | XmENTER_EVENT | XmLEAVE_EVENT);
  455. /* Change the image */
  456. if (strcmp (B_ImageName (current), B_ImageName (new_g)) != 0)
  457. {
  458. String str = B_ImageName (new_g);
  459. XtFree (B_ImageName (current));
  460. B_ImageName (new_g) = XtMalloc (strlen (str) + 1);
  461. strcpy (B_ImageName (new_g), str);
  462. B_Pixmap (new_g) =
  463. XmGetPixmap (XtScreen (new_g), B_ImageName (new_g),
  464. M_BottomShadowColor (mw),
  465. M_TopShadowColor (mw));
  466. B_Mask (new_g) =
  467. _DtGetMask (XtScreen (new_g), B_ImageName (new_g));
  468. if (B_Pixmap (new_g) != XmUNSPECIFIED_PIXMAP)
  469. {
  470. Window root;
  471. int int_x = 0, int_y = 0;
  472. unsigned int int_w = 0, int_h = 0,
  473. int_bw, depth;
  474. XGetGeometry (XtDisplay (new_g), B_Pixmap (new_g),
  475. &root, &int_x, &int_y, &int_w, &int_h, &int_bw, &depth);
  476. B_PixmapWidth (new_g) = (Dimension) int_w;
  477. B_PixmapHeight (new_g) = (Dimension) int_h;
  478. }
  479. else
  480. {
  481. B_PixmapWidth (new_g) = 0;
  482. B_PixmapHeight (new_g) = 0;
  483. }
  484. UpdateGCs(new_w);
  485. returnFlag = TRUE;
  486. }
  487. else
  488. {
  489. if (B_ImageName (new_g) != B_ImageName (current))
  490. {
  491. String str = B_ImageName (new_g);
  492. XtFree (B_ImageName (current));
  493. B_ImageName (new_g) = XtMalloc (strlen (str) + 1);
  494. strcpy (B_ImageName (new_g), str);
  495. }
  496. }
  497. return (returnFlag);
  498. }
  499. /************************************************************************
  500. *
  501. * arm
  502. * This function processes button 1 down occurring on the button.
  503. *
  504. ************************************************************************/
  505. static void
  506. Arm(
  507. Widget w,
  508. XEvent *event,
  509. String *params,
  510. Cardinal *num_params )
  511. {
  512. DtButtonGadget bg = (DtButtonGadget) w ;
  513. (void) XmProcessTraversal((Widget) bg, XmTRAVERSE_CURRENT);
  514. B_Armed (bg) = True;
  515. if ((event->xbutton.time - bg->button.armTimeStamp) >
  516. XtGetMultiClickTime(XtDisplay(bg)))
  517. {
  518. bg -> button.armTimeStamp = event->xbutton.time;
  519. B_Expose ( w, event, NULL);
  520. }
  521. }
  522. /************************************************************************
  523. *
  524. * disarm
  525. * This function processes button 1 up occurring on the button.
  526. *
  527. ************************************************************************/
  528. static void
  529. Disarm(
  530. Widget w,
  531. XEvent *event,
  532. String *params,
  533. Cardinal *num_params )
  534. {
  535. DtButtonGadget bg = (DtButtonGadget) w ;
  536. B_Armed (bg) = False;
  537. B_Expose (w, event, NULL);
  538. }
  539. /************************************************************************
  540. *
  541. * activate
  542. * This function processes button 1 up occurring on the button.
  543. * If the button 1 up occurred inside the button the activate
  544. * callbacks are called.
  545. *
  546. ************************************************************************/
  547. static void
  548. Activate(
  549. Widget w,
  550. XEvent *event,
  551. String *params,
  552. Cardinal *num_params )
  553. {
  554. DtButtonGadget bg = (DtButtonGadget) w ;
  555. DtButtonCallbackStruct call_value;
  556. if (!B_Armed (bg))
  557. return;
  558. if ((event->xbutton.time - bg->button.activateTimeStamp) >
  559. XtGetMultiClickTime(XtDisplay(bg)))
  560. {
  561. bg -> button.activateTimeStamp = event->xbutton.time;
  562. bg->button.click_count = 1;
  563. }
  564. else
  565. bg->button.click_count++;
  566. B_Armed (bg) = False;
  567. if (bg->button.callback)
  568. {
  569. call_value.reason = XmCR_ACTIVATE;
  570. call_value.event = event;
  571. call_value.click_count = bg->button.click_count;
  572. if ((bg->button.multiClick == XmMULTICLICK_DISCARD) &&
  573. (call_value.click_count > 1)) {
  574. return;
  575. }
  576. XFlush(XtDisplay(bg));
  577. CallCallback (bg, B_Callback (bg), XmCR_ACTIVATE, event);
  578. }
  579. }
  580. /************************************************************************
  581. *
  582. * ArmAndActivate
  583. *
  584. ************************************************************************/
  585. static void
  586. ArmAndActivate(
  587. Widget w,
  588. XEvent *event,
  589. String *params,
  590. Cardinal *num_params )
  591. {
  592. DtButtonCallbackStruct call_value;
  593. DtButtonGadget bg = (DtButtonGadget) w ;
  594. B_Armed (bg) = True;
  595. Redisplay ( w, event, FALSE);
  596. XFlush (XtDisplay (bg));
  597. call_value.reason = XmCR_ACTIVATE;
  598. call_value.event = event;
  599. call_value.click_count = 1; /* always 1 in kselect */
  600. if (bg->button.callback)
  601. {
  602. XFlush (XtDisplay (bg));
  603. CallCallback (bg, B_Callback (bg), XmCR_ACTIVATE, event);
  604. }
  605. B_Armed (bg) = False;
  606. /* If the button is still around, show it released, after a short delay */
  607. if (bg->object.being_destroyed == False)
  608. {
  609. bg->button.timer = XtAppAddTimeOut(
  610. XtWidgetToApplicationContext((Widget)bg),
  611. (unsigned long) DELAY_DEFAULT,
  612. (XtTimerCallbackProc)ArmTimeout,
  613. (caddr_t)bg);
  614. }
  615. }
  616. /* ARGSUSED */
  617. static void
  618. ArmTimeout(
  619. Widget w,
  620. XtIntervalId *id )
  621. {
  622. DtButtonGadget bg = (DtButtonGadget) w ;
  623. bg -> button.timer = 0;
  624. if (XtIsRealized ((Widget)bg) && XtIsManaged ((Widget)bg)) {
  625. Redisplay ( w, NULL, FALSE);
  626. XFlush (XtDisplay (bg));
  627. }
  628. return;
  629. }
  630. /*-------------------------------------------------------------
  631. ** InputDispatch
  632. ** Process event dispatched from parent or event handler.
  633. */
  634. static void
  635. InputDispatch(
  636. Widget w,
  637. XButtonEvent *event,
  638. Mask event_mask )
  639. {
  640. DtButtonGadget bg = (DtButtonGadget) w ;
  641. if (event_mask & XmARM_EVENT ||
  642. event_mask & XmMULTI_ARM_EVENT)
  643. {
  644. if (event->button == Button1)
  645. Arm (w, (XEvent*) event, (String *)NULL, (Cardinal*)NULL);
  646. }
  647. else if (event_mask & XmACTIVATE_EVENT ||
  648. event_mask & XmMULTI_ACTIVATE_EVENT)
  649. {
  650. if (event->button == Button1)
  651. {
  652. if (event->x >= G_X (bg) &&
  653. event->x <= (Position)(G_X (bg) + G_Width (bg)) &&
  654. event->y >= G_Y (bg) &&
  655. event->y <= (Position)(G_Y (bg) + G_Height (bg)))
  656. {
  657. Activate (w, (XEvent*) event,
  658. (String *)NULL, (Cardinal*)NULL);
  659. Disarm (w, (XEvent*) event,
  660. (String *)NULL, (Cardinal*)NULL);
  661. }
  662. else
  663. Disarm (w, (XEvent*) event,
  664. (String *)NULL, (Cardinal*)NULL);
  665. }
  666. }
  667. else if (event_mask & XmHELP_EVENT)
  668. _XmSocorro (w, (XEvent *)event,
  669. (String *)NULL,(Cardinal*)NULL);
  670. else if (event_mask & XmENTER_EVENT)
  671. Enter (w, (XEvent *)event, (String *)NULL,(Cardinal*)NULL);
  672. else if (event_mask & XmLEAVE_EVENT)
  673. Leave (w, (XEvent *)event, (String *)NULL,(Cardinal*)NULL);
  674. else if (event_mask & XmFOCUS_IN_EVENT)
  675. _XmFocusInGadget (w, (XEvent *)event,
  676. (String *)NULL,(Cardinal*)NULL);
  677. else if (event_mask & XmFOCUS_OUT_EVENT)
  678. _XmFocusOutGadget (w, (XEvent *)event,
  679. (String *)NULL,(Cardinal*)NULL);
  680. }
  681. /*-------------------------------------------------------------
  682. ** VisualChange
  683. ** Update GCs when parent visuals change.
  684. */
  685. static Boolean
  686. VisualChange(
  687. Widget w,
  688. Widget current_w,
  689. Widget new_w )
  690. {
  691. XmManagerWidget current = (XmManagerWidget) current_w;
  692. XmManagerWidget new_m = (XmManagerWidget) new_w;
  693. DtButtonGadget bg = (DtButtonGadget) w ;
  694. Boolean update = False;
  695. /* If the parent foreground or background has changed,
  696. * then update gcs and pixmap.
  697. */
  698. if (M_Foreground (current) != M_Foreground (new_m) ||
  699. M_Background (current) != M_Background (new_m))
  700. {
  701. UpdateGCs(w);
  702. update = True;
  703. }
  704. if (update)
  705. {
  706. if (B_ImageName (bg) != NULL)
  707. {
  708. if (B_Mask(bg) != XmUNSPECIFIED_PIXMAP)
  709. XmDestroyPixmap (XtScreen(bg), B_Mask(bg));
  710. if (B_Pixmap(bg) != XmUNSPECIFIED_PIXMAP)
  711. XmDestroyPixmap (XtScreen(w), B_Pixmap (bg));
  712. B_Pixmap (bg) = XmGetPixmap (XtScreen (bg), B_ImageName (bg),
  713. M_TopShadowColor (new_m),
  714. M_BottomShadowColor (new_m));
  715. if (B_Pixmap (bg) != XmUNSPECIFIED_PIXMAP)
  716. B_Mask(bg) = (Pixmap)_DtGetMask(XtScreen(bg), B_ImageName(bg));
  717. return (True);
  718. }
  719. else
  720. return (False);
  721. }
  722. return (False);
  723. }
  724. /************************************************************************
  725. *
  726. * Enter
  727. *
  728. ************************************************************************/
  729. static void
  730. Enter(
  731. Widget wid,
  732. XEvent *event,
  733. String *params,
  734. Cardinal *num_params )
  735. {
  736. DtButtonGadget bg = (DtButtonGadget) wid ;
  737. _XmEnterGadget (wid, (XEvent *)event, (String *)NULL,(Cardinal *)NULL);
  738. if (B_Armed (bg))
  739. B_Expose (wid, event, NULL);
  740. }
  741. /************************************************************************
  742. *
  743. * Leave
  744. *
  745. ************************************************************************/
  746. static void
  747. Leave(
  748. Widget wid,
  749. XEvent *event,
  750. String *params,
  751. Cardinal *num_params )
  752. {
  753. DtButtonGadget bg = (DtButtonGadget) wid ;
  754. _XmLeaveGadget (wid, (XEvent *)event, (String *)NULL, (Cardinal *)0);
  755. if (B_Armed (bg))
  756. {
  757. B_Armed (bg) = False;
  758. B_Expose (wid, event, NULL);
  759. B_Armed (bg) = True;
  760. }
  761. }
  762. /*-------------------------------------------------------------
  763. ** CallCallback
  764. ** Call callback, if any, with reason and event.
  765. */
  766. static void
  767. CallCallback(
  768. DtButtonGadget w,
  769. XtCallbackList cb,
  770. int reason,
  771. XEvent *event )
  772. {
  773. DtControlCallbackStruct cb_data;
  774. if (cb != NULL)
  775. {
  776. cb_data.reason = reason;
  777. cb_data.event = event;
  778. cb_data.control_type = XmCONTROL_BUTTON;
  779. cb_data.set = False;
  780. cb_data.subpanel = B_Subpanel (w);
  781. cb_data.push_function = B_PushFunction (w);
  782. cb_data.push_argument = B_PushArgument (w);
  783. cb_data.file_size = 0;
  784. XtCallCallbackList ((Widget) w, cb, &cb_data);
  785. }
  786. }
  787. /*-------------------------------------------------------------
  788. ** DefaultSelectColor
  789. ** Resource proc. to determine the default select color.
  790. ** (Formerly _XmSelectColorDefault).
  791. */
  792. static void
  793. DefaultSelectColor(
  794. Widget widget,
  795. int offset,
  796. XrmValue *value )
  797. {
  798. XmeGetDefaultPixel (widget, XmSELECT, offset, value);
  799. }
  800. /************************************************************************
  801. *
  802. * DtCreateButtonGadget
  803. * Create an instance of an button and return the widget id.
  804. *
  805. ************************************************************************/
  806. Widget
  807. DtCreateButtonGadget(
  808. Widget parent,
  809. char *name,
  810. ArgList arglist,
  811. Cardinal argcount )
  812. {
  813. return (XtCreateWidget (name, dtButtonGadgetClass,
  814. parent, arglist, argcount));
  815. }