Callback.c 75 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622
  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. * File: Callback.c
  26. *
  27. * Project: CDE
  28. *
  29. * Description: This file contains the user interface behavior processing
  30. * functions for the CDE front panel
  31. *
  32. * (c) Copyright 1993, 1994 Hewlett-Packard Company
  33. * (c) Copyright 1993, 1994 International Business Machines Corp.
  34. * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
  35. * (c) Copyright 1993, 1994 Novell, Inc.
  36. *
  37. ****************************************************************************/
  38. #include <stdint.h>
  39. #include <sys/param.h>
  40. #include <sys/stat.h>
  41. #include <Dt/DtP.h>
  42. #include <Dt/DbReader.h>
  43. #include "PanelSP.h"
  44. #include <Dt/Control.h>
  45. #include <Dt/ControlP.h>
  46. #include <Dt/IconFile.h>
  47. #include <Dt/Icon.h>
  48. #include <Dt/Dnd.h>
  49. #include <Dt/Dts.h>
  50. #include <Dt/Action.h>
  51. #include <Dt/DtNlUtils.h>
  52. #include <Dt/WsmP.h>
  53. #include <Dt/WsmM.h>
  54. #include <Dt/MacrosP.h>
  55. #include <Dt/SharedProcs.h>
  56. #include <Xm/Form.h>
  57. #include <Xm/ToggleBG.h>
  58. #include <Xm/AtomMgr.h>
  59. #include <Xm/TextF.h>
  60. #include <X11/Xatom.h>
  61. #include <X11/keysym.h>
  62. #include "DataBaseLoad.h"
  63. #include "UI.h"
  64. #include "WmGlobal.h"
  65. #include "WmHelp.h"
  66. #include "WmResNames.h"
  67. #include "WmResParse.h"
  68. #include "WmFunction.h"
  69. /************************************************************************
  70. *
  71. * External and static function declarations.
  72. *
  73. ************************************************************************/
  74. extern XtPointer _XmStringUngenerate(XmString, XmStringTag,
  75. XmTextType, XmTextType);
  76. extern void SubpanelControlCreate (SubpanelData *, ControlData *, ControlData *,
  77. Widget, Boolean, Boolean);
  78. extern void WmSubpanelPosted (Display *, Window);
  79. extern int PushRecallGetData (char *);
  80. extern void SwitchButtonCreate (SwitchData *, Boolean);
  81. extern void AddControlActionList (ControlData *);
  82. void ArrowCB (Widget, XtPointer, XtPointer);
  83. void HandleInputCB (Widget, XtPointer, XtPointer);
  84. void MinimizeInputCB (Widget, XtPointer, XtPointer);
  85. void MenuInputCB (Widget, XtPointer, XtPointer);
  86. void SwitchButtonCB (Widget, XtPointer, XtPointer);
  87. void PushCB (Widget, XtPointer, XtPointer);
  88. void SubpanelUnmapCB (Widget, XtPointer, XtPointer);
  89. void SubpanelTornEventHandler (Widget, XtPointer, XEvent *, Boolean *);
  90. Boolean CheckControlTypeFile (ControlData *);
  91. static void SwitchRenameCancel (Widget, XEvent *, String *, Cardinal *);
  92. static void SwitchRenameCB (Widget, XtPointer, XtPointer);
  93. static void GetValuesFromDataType(char *, char *, SubpanelData *,
  94. ElementValue **);
  95. void SwitchRenameLabel (Widget, BoxData *);
  96. void DropCB (Widget, XtPointer, XtPointer);
  97. void TransferDropCB (Widget, XtPointer, XtPointer);
  98. void CustomizeDropCB (Widget, XtPointer, XtPointer);
  99. void CustomizeTransferDropCB (Widget, XtPointer, XtPointer);
  100. /* Translations and action definitions */
  101. /* These are used specifically for the text field overlay */
  102. /* on the switch button for renaming the workspace. They */
  103. /* are necessary for handling escape key processing. */
  104. static char translations_escape[] = "<Key>osfCancel:Escape()";
  105. static XtActionsRec action_table[] = {
  106. {"Escape", SwitchRenameCancel},
  107. };
  108. /************************************************************************
  109. *
  110. * File local globals.
  111. *
  112. ************************************************************************/
  113. extern String post_arrow_image;
  114. extern String unpost_arrow_image;
  115. extern String post_monitor_arrow_image;
  116. extern String unpost_monitor_arrow_image;
  117. extern String blank_arrow_image;
  118. extern String dropzone_image;
  119. extern String indicator_on_image;
  120. extern String indicator_off_image;
  121. /************************************************************************
  122. *
  123. * CallWmFunction
  124. * Call the specified WmFunction function with appropriate args
  125. *
  126. ************************************************************************/
  127. void
  128. CallWmFunction (WmFunction wm_function,
  129. String args,
  130. Widget client,
  131. XEvent * event)
  132. {
  133. WmGlobalData * wm_global_data = (WmGlobalData *) panel.global_data;
  134. ClientData * wm_client_data = NULL;
  135. Display * display = wm_global_data->display;
  136. Window client_window = XtWindow(client);
  137. /*
  138. * Find the window manager client data for this client
  139. */
  140. XFindContext (display, client_window, wm_global_data->windowContextType,
  141. (XtPointer) &wm_client_data);
  142. if (wm_client_data == NULL)
  143. return;
  144. /*
  145. * Execute the window manager function
  146. */
  147. wm_function (args, wm_client_data, event);
  148. }
  149. /************************************************************************
  150. *
  151. * ArrowCB
  152. * Process the callback on the subpanel posting/unposting arrow
  153. *
  154. ************************************************************************/
  155. void
  156. ArrowCB (Widget w,
  157. XtPointer client_data,
  158. XtPointer call_data)
  159. {
  160. ControlData * control_data = (ControlData *) client_data;
  161. SubpanelData * subpanel_data = control_data->subpanel_data;
  162. Arg al[2];
  163. int ac;
  164. /* If the subpanel's shell is not managed, this is a request to post */
  165. /* the subpanel. Otherwise it is an unpost request. */
  166. /* Reset the arrow image after the post or unpost. */
  167. if (!XtIsManaged (subpanel_data->shell))
  168. {
  169. Position x = XtX (control_data->arrow);
  170. Position y = XtY (control_data->arrow);
  171. XtSetMappedWhenManaged (subpanel_data->shell, False);
  172. XtManageChild (subpanel_data->form);
  173. XtTranslateCoords (w, 0, 0, &x, &y);
  174. x--;
  175. XtSetArg (al[0], XmNx, x);
  176. XtSetValues (subpanel_data->form, al, 1);
  177. XtManageChild (subpanel_data->shell);
  178. XtSetMappedWhenManaged (subpanel_data->shell, True);
  179. ac = 0;
  180. XtSetArg (al[ac], XmNimageName, unpost_arrow_image); ac++;
  181. XtSetValues (w, al, ac);
  182. }
  183. else
  184. {
  185. /* Execute the window manager function to unpost the subpanel */
  186. CallWmFunction (F_Kill, NULL, subpanel_data->shell, NULL);
  187. }
  188. }
  189. /************************************************************************
  190. *
  191. * HandleInputTranslations
  192. * Return translation table suitable for HandleInputCB
  193. *
  194. ************************************************************************/
  195. XtTranslations
  196. HandleInputTranslations(void)
  197. {
  198. static XtTranslations handle_translations;
  199. if (handle_translations == NULL)
  200. {
  201. handle_translations = XtParseTranslationTable(
  202. "<BtnDown>: DrawingAreaInput() ManagerGadgetArm()\n\
  203. <BtnUp>: DrawingAreaInput() ManagerGadgetActivate()\n\
  204. <Btn1Motion>: DrawingAreaInput() ManagerGadgetButtonMotion()\n\
  205. <Btn2Motion>: DrawingAreaInput() ManagerGadgetButtonMotion()");
  206. }
  207. return handle_translations;
  208. }
  209. /************************************************************************
  210. *
  211. * HandleInputCB
  212. * Process button events on the frontpanel handles.
  213. *
  214. ************************************************************************/
  215. void
  216. HandleInputCB (Widget w,
  217. XtPointer client_data,
  218. XtPointer call_data)
  219. {
  220. XmAnyCallbackStruct * callback;
  221. XEvent * event;
  222. XButtonEvent * buttonEvent;
  223. XMotionEvent * motionEvent;
  224. callback = (XmAnyCallbackStruct *) call_data;
  225. event = (XEvent *) callback->event;
  226. buttonEvent = (XButtonEvent *) event;
  227. motionEvent = (XMotionEvent *) event;
  228. if (event->type == ButtonPress)
  229. {
  230. if (buttonEvent->button == wmGD.bMenuButton)
  231. {
  232. XUngrabPointer (XtDisplay (w), buttonEvent->time);
  233. XSync (XtDisplay (w), FALSE);
  234. CallWmFunction (F_Post_FpMenu, NULL, panel.shell, event);
  235. }
  236. else
  237. {
  238. wmGD.preMove = True;
  239. wmGD.preMoveX = buttonEvent->x_root;
  240. wmGD.preMoveY = buttonEvent->y_root;
  241. if (buttonEvent->button == Button1)
  242. {
  243. CallWmFunction (F_Raise, NULL, panel.shell, event);
  244. XSync (DISPLAY, FALSE);
  245. XmUpdateDisplay (panel.shell);
  246. }
  247. }
  248. }
  249. else if (event->type == ButtonRelease)
  250. {
  251. wmGD.preMove = False;
  252. }
  253. else if (event->type == MotionNotify && wmGD.preMove)
  254. {
  255. int diffX, diffY;
  256. diffX = motionEvent->x_root - wmGD.preMoveX;
  257. if (diffX < 0) diffX = -diffX;
  258. diffY = motionEvent->y_root - wmGD.preMoveY;
  259. if (diffY < 0) diffY = -diffY;
  260. if (diffX >= wmGD.moveThreshold || diffY >= wmGD.moveThreshold)
  261. {
  262. XUngrabPointer (XtDisplay (w), motionEvent->time);
  263. XSync (XtDisplay (w), FALSE);
  264. CallWmFunction (F_Move, NULL, panel.shell, event);
  265. wmGD.preMove = False;
  266. }
  267. }
  268. }
  269. /************************************************************************
  270. *
  271. * MinimizeInputCB
  272. * Process button events on the frontpanel minimize button.
  273. *
  274. ************************************************************************/
  275. void
  276. MinimizeInputCB (Widget w,
  277. XtPointer client_data,
  278. XtPointer call_data)
  279. {
  280. XmAnyCallbackStruct * callback;
  281. XEvent * event;
  282. XButtonEvent * bevent;
  283. extern Pixmap minimize_normal_pixmap;
  284. extern Pixmap minimize_selected_pixmap;
  285. Arg al[1];
  286. callback = (XmAnyCallbackStruct *) call_data;
  287. event = (XEvent *) callback->event;
  288. bevent = (XButtonEvent *) event;
  289. /* On the BSelect button press, change the image to the selected
  290. * minimize image. On the release, check to see if the release
  291. * occurred within the minimize button before minimizing.
  292. * On BMenu button press, post the front panel menu.
  293. */
  294. if (event->type == ButtonPress)
  295. {
  296. if (bevent->button == Button1)
  297. {
  298. XtSetArg (al[0], XmNbackgroundPixmap, minimize_selected_pixmap);
  299. XtSetValues (w, al, 1);
  300. }
  301. else if (bevent->button == wmGD.bMenuButton)
  302. {
  303. XUngrabPointer (XtDisplay (w), bevent->time);
  304. XSync (XtDisplay (w), FALSE);
  305. CallWmFunction (F_Post_FpMenu, NULL, panel.shell, event);
  306. }
  307. }
  308. else if (event->type == ButtonRelease && bevent->button == Button1)
  309. {
  310. if (bevent->x >= 0 && bevent->x <= (Position) XtWidth(w) &&
  311. bevent->y >= 0 && bevent->y <= (Position) XtHeight(w))
  312. {
  313. CallWmFunction (F_Minimize, NULL, panel.shell, event);
  314. }
  315. XtSetArg (al[0], XmNbackgroundPixmap, minimize_normal_pixmap);
  316. XtSetValues (w, al, 1);
  317. }
  318. }
  319. /************************************************************************
  320. *
  321. * MenuInputCB
  322. * Process button events on the front panel menu button.
  323. *
  324. ************************************************************************/
  325. void
  326. MenuInputCB (Widget w,
  327. XtPointer client_data,
  328. XtPointer call_data)
  329. {
  330. XmAnyCallbackStruct * callback;
  331. XEvent * event;
  332. XButtonEvent * bevent;
  333. callback = (XmAnyCallbackStruct *) call_data;
  334. event = (XEvent *) callback->event;
  335. bevent = (XButtonEvent *) event;
  336. /*
  337. * On BSelect or BMenu button press post the front panel system menu
  338. */
  339. if (event->type == ButtonPress &&
  340. (bevent->button == Button1 || bevent->button == wmGD.bMenuButton))
  341. {
  342. XUngrabPointer (XtDisplay (w), bevent->time);
  343. XSync (XtDisplay (w), FALSE);
  344. CallWmFunction (F_Post_FpMenu, NULL, panel.shell, event);
  345. }
  346. }
  347. /************************************************************************
  348. ************************************************************************
  349. The next block of functions are used for the switch button switching,
  350. renaming functionality, and add and delete of workspaces.
  351. ************************************************************************
  352. ************************************************************************/
  353. /************************************************************************
  354. *
  355. * WorkspaceAdjustPanelPosition
  356. * After a workspace button has been added or deleted, if the panel
  357. * has changed sizes, reposition the panel to keep the same relative
  358. * positioning.
  359. *
  360. * Inputs: x - the original x coordinate of the panel
  361. * y - the original y coordinate of the panel
  362. * width - the original width of the panel
  363. * height - the original height of the panel
  364. *
  365. ************************************************************************/
  366. void
  367. WorkspaceAdjustPanelPosition (Position x,
  368. Position y,
  369. Dimension width,
  370. Dimension height)
  371. {
  372. Dimension screen_width;
  373. Dimension screen_height;
  374. int panel_center;
  375. Dimension new_width;
  376. Dimension new_height;
  377. Position new_x;
  378. Position new_y;
  379. Arg al[2];
  380. int ac;
  381. screen_width = WidthOfScreen (XtScreen (panel.shell));
  382. screen_height = HeightOfScreen (XtScreen (panel.shell));
  383. /* Reposition the panel to keep it centered relative to where */
  384. /* it was positioned before the deletion of the button. */
  385. ac = 0;
  386. new_width = XtWidth (panel.shell);
  387. if (new_width != width || x + (Position) new_width > (Position) screen_width)
  388. {
  389. panel_center = x + width / 2 - 1;
  390. new_x = panel_center - new_width / 2 - 4;
  391. if (new_x < 0)
  392. new_x = 0;
  393. else if (new_x + (Position) new_width > (Position) screen_width)
  394. new_x = screen_width - new_width - 4;
  395. XtSetArg (al[ac], XmNx, new_x); ac++;
  396. }
  397. /* Keep the panel to the bottom of the screen, if it was there. */
  398. /* But make sure that it does not go below the bottom. */
  399. new_height = XtHeight (panel.shell);
  400. if (new_height != height || (Dimension)(new_height + y - 1) > screen_height)
  401. {
  402. if (new_height < height && y > (Position)(screen_height / 2))
  403. {
  404. new_y = y + (Position)(height - new_height - 4);
  405. XtSetArg (al[ac], XmNy, new_y); ac++;
  406. }
  407. else if ((Dimension)(new_height + y - 1) > screen_height)
  408. {
  409. new_y = (Position)(screen_height - new_height - 4);
  410. XtSetArg (al[ac], XmNy, new_y); ac++;
  411. }
  412. }
  413. if (ac != 0)
  414. XtSetValues (panel.shell, al, ac);
  415. }
  416. /************************************************************************
  417. *
  418. * WorkspaceModifyCB
  419. * Called by the workspace manager API to send notification of
  420. * configuration changes to the workspace. The types of changes
  421. * processed by this function are workspace add, delete, and rename.
  422. *
  423. ************************************************************************/
  424. void
  425. WorkspaceModifyCB (Widget w,
  426. Atom atom_name,
  427. int type,
  428. XtPointer client_data)
  429. {
  430. SwitchData * switch_data = (SwitchData *) client_data;
  431. BoxData * box_data = switch_data->box_data;
  432. DtWsmWorkspaceInfo * workspace_info;
  433. Position x;
  434. Position y;
  435. Dimension width;
  436. Dimension height;
  437. Dimension screen_width;
  438. x = XtX (panel.shell);
  439. y = XtY (panel.shell);
  440. width = XtWidth (panel.shell);
  441. height = XtHeight (panel.shell);
  442. screen_width = WidthOfScreen (XtScreen (panel.shell));
  443. DtWsmGetWorkspaceInfo (XtDisplay (w), RootWindowOfScreen (XtScreen (w)),
  444. atom_name, &workspace_info);
  445. switch (type)
  446. {
  447. /* Increase the size of the switch names and button and call */
  448. /* the function to create the new workspace switch button */
  449. case DtWSM_REASON_ADD:
  450. {
  451. int switch_count;
  452. Atom * atom_names;
  453. /* Cancel workspace renaming */
  454. if (XtIsManaged (box_data->switch_edit))
  455. SwitchRenameCancel (box_data->switch_edit, NULL, NULL, NULL);
  456. DtWsmGetWorkspaceList (XtDisplay (switch_data->rc),
  457. RootWindowOfScreen (XtScreen (switch_data->rc)),
  458. &atom_names, &switch_count);
  459. XFree (switch_data->atom_names);
  460. switch_data->atom_names = atom_names;
  461. switch_data->switch_count = switch_count;
  462. switch_data->switch_names =
  463. (char **) XtRealloc ((char *) switch_data->switch_names,
  464. sizeof (char *) * switch_data->switch_count);
  465. switch_data->switch_names[switch_data->switch_count - 1] =
  466. XtNewString (workspace_info->pchTitle);
  467. switch_data->buttons =
  468. (Widget *) XtRealloc ((char *) switch_data->buttons,
  469. sizeof (Widget) * switch_data->switch_count);
  470. SwitchButtonCreate (switch_data, True);
  471. /* When adding a switch buttons, keep the row columns row count */
  472. /* equal to the requested value with small number of buttons */
  473. if (switch_data->switch_count <= (intptr_t)
  474. (switch_data->element_values[SWITCH_NUMBER_OF_ROWS].parsed_value))
  475. {
  476. Arg al[1];
  477. panel.switch_row_count = (intptr_t)
  478. (switch_data->element_values[SWITCH_NUMBER_OF_ROWS].parsed_value);
  479. XtSetArg (al[0], XmNnumColumns, panel.switch_row_count);
  480. XtSetValues (switch_data->rc, al, 1);
  481. }
  482. /* If the fp width is greater than the screen, increase the */
  483. /* row count */
  484. if (XtWidth (panel.shell) > screen_width)
  485. {
  486. Arg al[1];
  487. panel.switch_row_count++;
  488. XtSetArg (al[0], XmNnumColumns, panel.switch_row_count);
  489. XtSetValues (switch_data->rc, al, 1);
  490. }
  491. WorkspaceAdjustPanelPosition (x, y, width, height);
  492. }
  493. break;
  494. /* Loop through the current set of atom names, comparing */
  495. /* them with the atom of the workspace to be deleted. When */
  496. /* free up the associated data and readjust the name, button */
  497. /* and atom lists. */
  498. case DtWSM_REASON_DELETE:
  499. {
  500. int i;
  501. int j;
  502. int switch_count;
  503. Atom * atom_names;
  504. Arg al[1];
  505. Dimension button_spacing;
  506. Dimension button_width;
  507. /* Cancel workspace renaming */
  508. if (XtIsManaged (box_data->switch_edit))
  509. SwitchRenameCancel (box_data->switch_edit, NULL, NULL, NULL);
  510. DtWsmGetWorkspaceList (XtDisplay (switch_data->rc),
  511. RootWindowOfScreen (XtScreen (switch_data->rc)),
  512. &atom_names, &switch_count);
  513. for (i = 0; i < switch_data->switch_count; i++)
  514. {
  515. if (atom_name == switch_data->atom_names[i])
  516. {
  517. if (switch_data->active_switch > i)
  518. switch_data->active_switch--;
  519. XtFree (switch_data->switch_names[i]);
  520. XtDestroyWidget (switch_data->buttons[i]);
  521. XFree (switch_data->atom_names);
  522. switch_data->atom_names = atom_names;
  523. switch_data->switch_count = switch_count;
  524. for (j = i; j < switch_data->switch_count; j++)
  525. {
  526. switch_data->switch_names[j] = switch_data->switch_names[j+1];
  527. switch_data->buttons[j] = switch_data->buttons[j + 1];
  528. }
  529. break;
  530. }
  531. }
  532. /* When deleting a switch button, keep trying to decrease the */
  533. /* row count to the requested value. */
  534. if (panel.switch_row_count > (intptr_t)
  535. (switch_data->element_values[SWITCH_NUMBER_OF_ROWS].parsed_value))
  536. {
  537. button_width = XtWidth (switch_data->buttons[0]);
  538. XtSetArg (al[0], XmNspacing, &button_spacing);
  539. XtGetValues (switch_data->rc, al, 1);
  540. if ((int)(screen_width - (width + button_width + button_spacing)) >
  541. 0)
  542. {
  543. panel.switch_row_count--;
  544. XtSetArg (al[0], XmNnumColumns, panel.switch_row_count);
  545. XtSetValues (switch_data->rc, al, 1);
  546. }
  547. }
  548. WorkspaceAdjustPanelPosition (x, y, width, height);
  549. }
  550. break;
  551. /* Loop through the current set of atom names, comparing */
  552. /* them with the new atom. When a match is found, reset the */
  553. /* the switch name to the new one and update the button label. */
  554. case DtWSM_REASON_TITLE:
  555. {
  556. XmString toggle_string;
  557. Arg al[2];
  558. int i;
  559. for (i = 0; i < switch_data->switch_count; i++)
  560. {
  561. if (atom_name == switch_data->atom_names[i])
  562. {
  563. switch_data->switch_names[i] =
  564. XtNewString (workspace_info->pchTitle);
  565. toggle_string =
  566. XmStringCreateLocalized (workspace_info->pchTitle);
  567. XtSetArg (al[0], XmNstring, toggle_string);
  568. XtSetValues (switch_data->buttons[i], al, 1);
  569. XmStringFree (toggle_string);
  570. XtSetArg (al[0], XmNiconName, workspace_info->pchTitle);
  571. XtSetArg (al[1], XmNtitle, workspace_info->pchTitle);
  572. XtSetValues (panel.shell, al, 2);
  573. break;
  574. }
  575. }
  576. }
  577. break;
  578. /* Loop through the set of switch atom names to find the one */
  579. /* that is now active. Unset the old workspace button and */
  580. /* set the new one referenced by the atom. */
  581. case DtWSM_REASON_CURRENT:
  582. {
  583. int i;
  584. Arg al[2];
  585. for (i = 0; i < switch_data->switch_count; i++)
  586. {
  587. if (switch_data->atom_names[i] == atom_name)
  588. {
  589. XtSetArg (al[0], XmNiconName, switch_data->switch_names[i]);
  590. XtSetArg (al[1], XmNtitle, switch_data->switch_names[i]);
  591. XtSetValues (panel.shell, al, 2);
  592. _DtIconSetState (switch_data->buttons[switch_data->active_switch], False, False);
  593. switch_data->active_switch = i;
  594. _DtIconSetState (switch_data->buttons[switch_data->active_switch], True, False);
  595. break;
  596. }
  597. }
  598. }
  599. break;
  600. }
  601. DtWsmFreeWorkspaceInfo (workspace_info);
  602. }
  603. /************************************************************************
  604. *
  605. * SwitchButtonCB
  606. * Process callbacks on the switch buttons. This function cause
  607. * either the workspace switch to occur or for the switch button
  608. * label to become editable.
  609. *
  610. ************************************************************************/
  611. void
  612. SwitchButtonCB (Widget w,
  613. XtPointer client_data,
  614. XtPointer call_data)
  615. {
  616. DtControlCallbackStruct * callback = (DtControlCallbackStruct *) call_data;
  617. XEvent * event = callback->event;
  618. Widget switch_button = w;
  619. Widget old_switch_button;
  620. BoxData * box_data;
  621. SwitchData * switch_data;
  622. Atom atom_name;
  623. int i;
  624. int ac;
  625. Arg al[2];
  626. if (callback->reason != XmCR_VALUE_CHANGED) return;
  627. ac = 0;
  628. XtSetArg (al[ac], XmNuserData, &box_data); ac++;
  629. XtGetValues (switch_button, al, ac);
  630. switch_data = box_data->switch_data;
  631. old_switch_button = switch_data->buttons[switch_data->active_switch];
  632. /* If the selection occurred on a non-selected button, find the atom */
  633. /* representing the workspace name of the button that was selected */
  634. /* and use it to call the workspace manager API to switch the */
  635. /* workspace. The indication on the buttons occurs out of the */
  636. /* called from the workspace manager API. */
  637. /* */
  638. /* If the selection occurred on the current button, set up the name */
  639. /* change editing functions. */
  640. if (switch_button != old_switch_button)
  641. {
  642. /* See if the workspace name is being edited. If so, call the */
  643. /* callback function to accept the changes. */
  644. if (XtIsManaged (box_data->switch_edit))
  645. {
  646. Widget edit_switch_button;
  647. XtSetArg (al[0], XmNuserData, &edit_switch_button);
  648. XtGetValues (box_data->switch_edit, al, 1);
  649. SwitchRenameCB (box_data->switch_edit,
  650. (XtPointer) edit_switch_button, (XtPointer) NULL);
  651. XmProcessTraversal (w, XmTRAVERSE_CURRENT);
  652. }
  653. if (event->xany.type == ButtonRelease)
  654. switch_data->time_stamp = event->xbutton.time;
  655. for (i = 0; i < switch_data->switch_count; i++)
  656. {
  657. if (switch_button == switch_data->buttons[i])
  658. {
  659. XtSetArg (al[0], XmNiconName, switch_data->switch_names[i]);
  660. XtSetArg (al[1], XmNtitle, switch_data->switch_names[i]);
  661. XtSetValues (panel.shell, al, 2);
  662. DtWsmSetCurrentWorkspace (XtParent (switch_button),
  663. switch_data->atom_names[i]);
  664. break;
  665. }
  666. }
  667. _DtIconSetState (old_switch_button, False, False);
  668. }
  669. else
  670. {
  671. /* Don't do anything on double click */
  672. if (event->xany.type == ButtonRelease)
  673. {
  674. if ((event->xbutton.time - switch_data->time_stamp) >
  675. XtGetMultiClickTime(XtDisplay(panel.shell)))
  676. {
  677. switch_data->time_stamp = event->xbutton.time;
  678. SwitchRenameLabel (w, box_data);
  679. }
  680. }
  681. _DtIconSetState (w, True, False);
  682. }
  683. }
  684. /************************************************************************
  685. *
  686. * SwitchRenameCancel
  687. * This is the XtActionProc that gets called when a user types
  688. * escape in a text widget which has this translation tied to it.
  689. *
  690. ***********************************************************************/
  691. static void
  692. SwitchRenameCancel (Widget w,
  693. XEvent * event,
  694. String * params,
  695. Cardinal * num_params)
  696. {
  697. Widget switch_button;
  698. Arg al[1];
  699. /* Extract the toggle button from the text field's user data */
  700. XtSetArg (al[0], XmNuserData, &switch_button);
  701. XtGetValues (w, al, 1);
  702. /* Remove the callbacks to eliminate double processing */
  703. XtRemoveAllCallbacks (w, XmNactivateCallback);
  704. /* Unmanage the text widget, set the traversal to the button and exit */
  705. XtUnmanageChild (w);
  706. XmProcessTraversal (switch_button, XmTRAVERSE_CURRENT);
  707. }
  708. /************************************************************************
  709. *
  710. * SwitchRenameCB
  711. * Process callbacks on the text field when a switch name is
  712. * being edited.
  713. *
  714. ************************************************************************/
  715. static void
  716. SwitchRenameCB (Widget w,
  717. XtPointer client_data,
  718. XtPointer call_data)
  719. {
  720. Widget switch_button = (Widget) client_data;
  721. char * edit_string;
  722. BoxData * box_data;
  723. SwitchData * switch_data;
  724. Boolean valid;
  725. int current_switch = 0;
  726. int i;
  727. int ac;
  728. Arg al[2];
  729. /* Remove the callbacks to eliminate double processing */
  730. XtRemoveCallback (w, XmNactivateCallback,
  731. SwitchRenameCB, (XtPointer) client_data);
  732. /* If this callback has been called and the text widget is already */
  733. /* unmanaged, it means that the escape key was pressed, so return */
  734. if (XtIsManaged(w) == False) return;
  735. /* Process the two reasons this callback is invoked. A <Return> */
  736. /* key has been pressed or the focus is being moved. Accept the */
  737. /* new name for both conditions. */
  738. ac = 0;
  739. XtSetArg (al[ac], XmNuserData, &box_data); ac++;
  740. XtGetValues (switch_button, al, ac);
  741. switch_data = box_data->switch_data;
  742. for (i = 0; i < switch_data->switch_count; i++)
  743. if (switch_data->buttons[i] == switch_button)
  744. current_switch = i;
  745. /* Get the new name from the text field */
  746. edit_string = (char *) XmTextFieldGetString (w);
  747. /* Verify that title is valid and unique and if so, validate */
  748. /* uniqueness and then change the toggle and workspace internal */
  749. /* information. */
  750. valid = True;
  751. _DtStripSpaces (edit_string);
  752. if (strlen (edit_string) == 0)
  753. valid = False;
  754. else
  755. {
  756. for (i = 0; i < switch_data->switch_count; i++)
  757. {
  758. if (strcmp (switch_data->switch_names[i], edit_string) == 0)
  759. {
  760. if (i == current_switch)
  761. {
  762. XtUnmanageChild (w);
  763. XmProcessTraversal (switch_button, XmTRAVERSE_CURRENT);
  764. XtFree (edit_string);
  765. return;
  766. }
  767. else
  768. {
  769. valid = False;
  770. break;
  771. }
  772. }
  773. }
  774. }
  775. /* If the title is not valid, post and error dialog and */
  776. /* then leave the text field active to allow reediting. */
  777. /* Otherwise, change the title. */
  778. if (!valid)
  779. {
  780. char * s1;
  781. char * s2;
  782. s1 = FPGETMESSAGE (86, 1, "Workspace Manager - Rename Error");
  783. s1 = XtNewString (s1);
  784. s2 = FPGETMESSAGE (86, 2, "Invalid or duplicate workspace name"),
  785. s2 = XtNewString (s2);
  786. _DtMessage (XtParent (w), s1, s2, NULL, NULL);
  787. XtFree (s1);
  788. XtFree (s2);
  789. }
  790. else
  791. _DtWsmSetWorkspaceTitle (panel.shell,
  792. switch_data->atom_names[current_switch],
  793. edit_string);
  794. /* Unmanage the text field and exit */
  795. XtFree (edit_string);
  796. XtUnmanageChild (w);
  797. }
  798. /************************************************************************
  799. *
  800. * SwitchRenameLabel
  801. * Set up the text field and callbacks needed for renaming a
  802. * workspace.
  803. *
  804. ************************************************************************/
  805. void
  806. SwitchRenameLabel (Widget switch_button,
  807. BoxData * box_data)
  808. {
  809. Widget switch_edit = box_data->switch_edit;
  810. static Boolean first = True;
  811. XmString toggle_string;
  812. Position toggle_x;
  813. Position toggle_y;
  814. Dimension toggle_width;
  815. Dimension toggle_height;
  816. XmFontList toggle_font_list;
  817. Pixel toggle_background;
  818. Position switch_rc_x;
  819. Position switch_rc_y;
  820. char * edit_string;
  821. XtTranslations trans_table;
  822. int ac;
  823. Arg al[15];
  824. /* Add the additional actions needed by the panel and */
  825. /* set up translations in main edit widget */
  826. if (first)
  827. {
  828. first = False;
  829. XtAppAddActions(XtWidgetToApplicationContext(panel.shell),action_table,1);
  830. trans_table = XtParseTranslationTable (translations_escape);
  831. XtOverrideTranslations (switch_edit, trans_table);
  832. }
  833. /* Extract the label and toggle position */
  834. ac = 0;
  835. XtSetArg (al[ac], XmNx, &toggle_x); ac++;
  836. XtSetArg (al[ac], XmNy, &toggle_y); ac++;
  837. XtSetArg (al[ac], XmNwidth, &toggle_width); ac++;
  838. XtSetArg (al[ac], XmNheight, &toggle_height); ac++;
  839. XtSetArg (al[ac], XmNstring, &toggle_string); ac++;
  840. XtSetArg (al[ac], XmNfontList, &toggle_font_list); ac++;
  841. XtGetValues (switch_button, al, ac);
  842. /* Extract the switch_rc's position */
  843. switch_rc_x = XtX (XtParent (switch_button));
  844. switch_rc_y = XtY (XtParent (switch_button));
  845. /* Convert the xm string into a char string for editing and */
  846. /* then create the text widget to perform the name editing. */
  847. if ((edit_string =
  848. (char *)_XmStringUngenerate(toggle_string, NULL,
  849. XmCHARSET_TEXT, XmCHARSET_TEXT))
  850. != (char *)NULL)
  851. {
  852. /* Set the switch editing field to the new resource set */
  853. ac = 0;
  854. XtSetArg (al[ac], XmNleftOffset, toggle_x + switch_rc_x); ac++;
  855. XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  856. XtSetArg (al[ac], XmNtopOffset, toggle_y + switch_rc_y); ac++;
  857. XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  858. XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
  859. XtSetArg (al[ac], XmNmarginHeight, 0); ac++;
  860. XtSetArg (al[ac], XmNfontList, toggle_font_list); ac++;
  861. XtSetArg (al[ac], XmNhighlightThickness, 1); ac++;
  862. XtSetArg (al[ac], XmNvalue, edit_string); ac++;
  863. XtSetArg (al[ac], XmNuserData, switch_button); ac++;
  864. XtSetValues (switch_edit, al, ac);
  865. XtFree(edit_string);
  866. ac = 0;
  867. XtSetArg (al[ac], XmNcursorPosition,
  868. XmTextFieldGetLastPosition (switch_edit)); ac++;
  869. XtSetArg (al[ac], XmNwidth, toggle_width); ac++;
  870. XtSetArg (al[ac], XmNheight, toggle_height); ac++;
  871. XtSetValues (switch_edit, al, ac);
  872. /* Add the callbacks for the text input processing */
  873. XtAddCallback (switch_edit, XmNactivateCallback,
  874. SwitchRenameCB, (XtPointer) switch_button);
  875. XtManageChild (switch_edit);
  876. XRaiseWindow (XtDisplay (switch_edit), XtWindow (switch_edit));
  877. XSetInputFocus (XtDisplay (switch_edit), XtWindow (panel.shell),
  878. RevertToParent, CurrentTime);
  879. XmProcessTraversal (switch_edit, XmTRAVERSE_CURRENT);
  880. }
  881. XmStringFree (toggle_string);
  882. }
  883. /************************************************************************
  884. ************************************************************************
  885. The next block of functions are used for the push and drop callbacks
  886. on all of the panel controls.
  887. ************************************************************************
  888. ************************************************************************/
  889. /************************************************************************
  890. *
  891. * CheckControlTypeFile
  892. * Check the control if it is of type "file" that the file exists
  893. * before performing a push or drop action.
  894. *
  895. * Inputs: control_data - the control whose file type and status are
  896. * to be checked.
  897. *
  898. ************************************************************************/
  899. Boolean
  900. CheckControlTypeFile (ControlData * control_data)
  901. {
  902. struct stat stat_info;
  903. char * file_name;
  904. char * title;
  905. char * msg;
  906. char * message;
  907. if ((intptr_t) control_data->element_values[CONTROL_TYPE].parsed_value != CONTROL_FILE)
  908. return (True);
  909. file_name =
  910. (char *) control_data->element_values[CONTROL_FILE_NAME].parsed_value;
  911. if (lstat (file_name, &stat_info) == 0)
  912. return (True);
  913. /* Display an error dialog because the file cannot be found */
  914. title = FPGETMESSAGE (86, 9, "Workspace Manager - Icon Action Error");
  915. title = XtNewString (title);
  916. msg = FPGETMESSAGE (86, 7, "Cannot find the file");
  917. message = XtMalloc (strlen (msg) + strlen (file_name) + 2);
  918. sprintf (message, "%s %s", msg, file_name);
  919. _DtMessage (panel.shell, title, message, NULL, NULL);
  920. XtFree (title);
  921. XtFree (message);
  922. return (False);
  923. }
  924. /************************************************************************
  925. *
  926. * FreeFunctionArg
  927. * Free the function argument
  928. *
  929. ************************************************************************/
  930. static void
  931. FreeFunctionArg (
  932. WmFunction wmFunc,
  933. void *pArg)
  934. {
  935. if (pArg != NULL)
  936. {
  937. if (wmFunc == F_Action)
  938. {
  939. WmActionArg *pAP = (WmActionArg *) pArg;
  940. if (pAP->aap != NULL)
  941. {
  942. int i;
  943. for (i=0; i < pAP->numArgs; i++)
  944. {
  945. if (pAP->aap[i].u.file.name != NULL)
  946. XtFree ((char *) pAP->aap[i].u.file.name);
  947. }
  948. XtFree ((char *) pAP->aap);
  949. }
  950. if (pAP->actionName != NULL)
  951. XtFree ((char *) pAP->actionName);
  952. if (pAP->szExecParms != NULL)
  953. XtFree ((char *) pAP->szExecParms);
  954. }
  955. XtFree ((char *) pArg);
  956. }
  957. }
  958. Boolean
  959. CheckOtherMonitorsOn(SubpanelData * subpanel_data)
  960. {
  961. int i;
  962. ControlData * control_data;
  963. Boolean m_state;
  964. for (i = -1; i < subpanel_data->control_data_count; i++)
  965. {
  966. if (i == -1)
  967. {
  968. m_state = _DtControlGetMonitorState(subpanel_data->main_panel_icon_copy);
  969. }
  970. else
  971. {
  972. control_data = subpanel_data->control_data[i];
  973. m_state = _DtControlGetMonitorState(control_data->icon);
  974. }
  975. if (m_state == DtMONITOR_ON) return True;
  976. }
  977. return False;
  978. }
  979. /************************************************************************
  980. *
  981. * PushCB
  982. * Process the callback on a control.
  983. *
  984. ************************************************************************/
  985. void
  986. PushCB (Widget w,
  987. XtPointer client_data,
  988. XtPointer call_data)
  989. {
  990. int control_behavior;
  991. DtControlCallbackStruct * callback = (DtControlCallbackStruct *) call_data;
  992. XEvent * event = callback->event;
  993. ControlData * control_data = (ControlData *) client_data;
  994. int control_type;
  995. PanelActionData * push_action;
  996. Boolean push_recall;
  997. Boolean unpost_subpanel = True;
  998. BoxData * box_data;
  999. SubpanelData * subpanel_data;
  1000. ControlData * main_control_data = NULL;
  1001. char m_state;
  1002. Widget * pWid;
  1003. Widget monitor_icon;
  1004. Arg al[1];
  1005. int i, j;
  1006. control_behavior = (intptr_t) (panel.element_values[PANEL_CONTROL_BEHAVIOR].parsed_value);
  1007. /* See if the workspace name is being edited. If so, call the */
  1008. /* callback function to accept the changes. */
  1009. for (i = 0; i < panel.box_data_count; i++)
  1010. {
  1011. if (panel.box_data[i]->switch_edit != NULL)
  1012. {
  1013. if (XtIsManaged (panel.box_data[i]->switch_edit))
  1014. {
  1015. Widget switch_button;
  1016. XtSetArg (al[0], XmNuserData, &switch_button);
  1017. XtGetValues (panel.box_data[i]->switch_edit, al, 1);
  1018. SwitchRenameCB (panel.box_data[i]->switch_edit,
  1019. (XtPointer) switch_button, (XtPointer) NULL);
  1020. XmProcessTraversal (w, XmTRAVERSE_CURRENT);
  1021. break;
  1022. }
  1023. }
  1024. }
  1025. /* See if the control action occurred out of a subpanel. If so, */
  1026. /* get the subpanel and set the main control data. */
  1027. if (control_data->parent_type == SUBPANEL)
  1028. {
  1029. subpanel_data = (SubpanelData *) control_data->parent_data;
  1030. main_control_data = subpanel_data->parent_control_data;
  1031. /* This control may have been toggled from the subpanel. If */
  1032. /* so, make sure the subpanel is not reposted. */
  1033. if (XtParent (w) != subpanel_data->form)
  1034. unpost_subpanel = False;
  1035. }
  1036. else
  1037. {
  1038. /* The control may be the main panel icon copy. If so, find */
  1039. /* the subpanel that contains it a set the subpanel data */
  1040. subpanel_data = NULL;
  1041. for (i = 0; i < panel.box_data_count; i++)
  1042. {
  1043. for (j = 0; j < panel.box_data[i]->control_data_count; j++)
  1044. {
  1045. ControlData * box_control;
  1046. box_control = panel.box_data[i]->control_data[j];
  1047. if (box_control->subpanel_data != NULL &&
  1048. box_control->subpanel_data->main_panel_icon_copy == w)
  1049. {
  1050. subpanel_data = box_control->subpanel_data;
  1051. main_control_data = subpanel_data->parent_control_data;
  1052. break;
  1053. }
  1054. }
  1055. if (subpanel_data != NULL)
  1056. break;
  1057. }
  1058. }
  1059. /* If the input occurred out of a subpanel, check to see if */
  1060. /* the input was an escape key. If so, unpost the subpanel */
  1061. /* and return. */
  1062. if (subpanel_data != NULL && event != NULL)
  1063. {
  1064. if (event->xany.type == KeyPress)
  1065. {
  1066. int count;
  1067. char buffer[10];
  1068. int bufsize = 10;
  1069. KeySym keysym;
  1070. XComposeStatus compose;
  1071. static Boolean first = True;
  1072. count = XLookupString ((XKeyEvent *)event, buffer, bufsize,
  1073. &keysym, &compose);
  1074. if (keysym == XK_Escape)
  1075. {
  1076. if (first)
  1077. {
  1078. ArrowCB (main_control_data->arrow,
  1079. (XtPointer)main_control_data, (XtPointer)NULL);
  1080. first = False;
  1081. }
  1082. else
  1083. first = True;
  1084. return;
  1085. }
  1086. }
  1087. }
  1088. /* This function handles four callback reasons. Two of them, */
  1089. /* START and STOP show and remove an hour glass cursor. */
  1090. /* MONITOR modifies subpanel visuals when a file change is */
  1091. /* detected. ACTIVATE/DEFAULT_ACTION handle the activation */
  1092. /* of a control. */
  1093. if (callback->reason == XmCR_BUSY_START)
  1094. {
  1095. XDefineCursor (XtDisplay (panel.shell), XtWindow (panel.shell),
  1096. panel.busy_cursor);
  1097. for (i = 0, pWid = M_PopupList (panel.shell);
  1098. i < M_NumPopups (panel.shell); i++)
  1099. XDefineCursor (XtDisplay (panel.shell), XtWindow (pWid[i]),
  1100. panel.busy_cursor);
  1101. }
  1102. else if (callback->reason == XmCR_BUSY_STOP)
  1103. {
  1104. XUndefineCursor (XtDisplay (panel.shell), XtWindow (panel.shell));
  1105. for (i = 0, pWid = M_PopupList (panel.shell);
  1106. i < M_NumPopups (panel.shell); i++)
  1107. XUndefineCursor (XtDisplay (panel.shell), XtWindow (pWid[i]));
  1108. }
  1109. else if (callback->reason == XmCR_MONITOR)
  1110. {
  1111. /* For a monitor file, turn on the monitor indicator for */
  1112. /* the subpanel control and turn on the arrow to the */
  1113. /* highlighted arrow of the subpanel. */
  1114. if (subpanel_data != NULL)
  1115. {
  1116. monitor_icon = control_data->indicator;
  1117. m_state = _DtControlGetMonitorState(w);
  1118. if (m_state == DtMONITOR_ON)
  1119. XtSetArg (al[0], XmNimageName, indicator_on_image);
  1120. else /* DtMONITOR_OFF */
  1121. XtSetArg (al[0], XmNimageName, indicator_off_image);
  1122. XtSetValues (monitor_icon, al, 1);
  1123. if (XtIsManaged (subpanel_data->shell))
  1124. {
  1125. if (m_state == DtMONITOR_ON)
  1126. {
  1127. XtSetArg (al[0], XmNimageName, unpost_monitor_arrow_image);
  1128. XtSetValues (main_control_data->arrow, al, 1);
  1129. }
  1130. else
  1131. {
  1132. if (!CheckOtherMonitorsOn(subpanel_data))
  1133. {
  1134. XtSetArg (al[0], XmNimageName, unpost_arrow_image);
  1135. XtSetValues (main_control_data->arrow, al, 1);
  1136. }
  1137. }
  1138. }
  1139. else
  1140. {
  1141. if (m_state == DtMONITOR_ON)
  1142. {
  1143. XtSetArg (al[0], XmNimageName, post_monitor_arrow_image);
  1144. XtSetValues (main_control_data->arrow, al, 1);
  1145. }
  1146. else
  1147. {
  1148. if (!CheckOtherMonitorsOn(subpanel_data))
  1149. {
  1150. XtSetArg (al[0], XmNimageName, post_arrow_image);
  1151. XtSetValues (main_control_data->arrow, al, 1);
  1152. }
  1153. }
  1154. }
  1155. }
  1156. }
  1157. else if ((control_behavior == DOUBLE_CLICK &&
  1158. callback->reason == XmCR_DEFAULT_ACTION) ||
  1159. (control_behavior == SINGLE_CLICK &&
  1160. (callback->reason == XmCR_DEFAULT_ACTION ||
  1161. callback->reason == XmCR_SINGLE_SELECT)))
  1162. {
  1163. control_type = (intptr_t) (control_data->element_values[CONTROL_TYPE].parsed_value);
  1164. push_action = (PanelActionData *) (control_data->element_values[CONTROL_PUSH_ACTION].parsed_value);
  1165. push_recall = (Boolean) (intptr_t) (control_data->element_values[CONTROL_PUSH_RECALL].parsed_value);
  1166. switch (control_type)
  1167. {
  1168. case CONTROL_CLIENT:
  1169. case CONTROL_ICON:
  1170. case CONTROL_FILE:
  1171. case CONTROL_DATE:
  1172. {
  1173. /* Turn off the subpanel control monitor indicator */
  1174. if ((char) (intptr_t) control_data->element_values[CONTROL_MONITOR_TYPE].
  1175. parsed_value != MONITOR_NONE)
  1176. {
  1177. if (subpanel_data != NULL)
  1178. {
  1179. monitor_icon = control_data->indicator;
  1180. XtSetArg (al[0], XmNimageName, indicator_off_image);
  1181. XtSetValues (monitor_icon, al, 1);
  1182. }
  1183. }
  1184. if (CheckControlTypeFile (control_data) && push_action != NULL)
  1185. {
  1186. _DtControlDoPushAnimation (w);
  1187. if (push_recall == False)
  1188. {
  1189. /* If the control is of type file, build and object */
  1190. /* list that contains the host and file name to */
  1191. /* pass to the invokation. */
  1192. if (control_type == CONTROL_FILE && !control_data->is_action)
  1193. {
  1194. DtActionArg * aap;
  1195. aap = (DtActionArg *) XtCalloc(1,sizeof(DtActionArg));
  1196. aap->argClass = DtACTION_FILE;
  1197. aap->u.file.name = (char *) control_data->
  1198. element_values[CONTROL_FILE_NAME].parsed_value;
  1199. DtActionInvoke (panel.shell,
  1200. push_action->action_name,
  1201. aap, 1, NULL, NULL, NULL,
  1202. 1, NULL, NULL);
  1203. XtFree ((char *) aap);
  1204. }
  1205. else
  1206. {
  1207. if (strcmp (push_action->action_name, "FPOnItemHelp") == 0)
  1208. {
  1209. WmDtHelpMode();
  1210. unpost_subpanel = False;
  1211. }
  1212. else
  1213. {
  1214. DtActionInvoke (panel.shell,
  1215. push_action->action_name,
  1216. NULL, 0, NULL, NULL, NULL,
  1217. 1, NULL, NULL);
  1218. }
  1219. }
  1220. }
  1221. else
  1222. {
  1223. WmFunction wm_func;
  1224. int function_index;
  1225. String func_arg = NULL;
  1226. String s1, s1save;
  1227. char * client_name;
  1228. char * client_title;
  1229. WmGlobalData * wm_global_data = (WmGlobalData *) panel.global_data;
  1230. ClientData * wm_client_data = NULL;
  1231. WmPushRecallArg push_argument;
  1232. /* Parse out the function and arguments used by the */
  1233. /* window manager to invoke the client. */
  1234. s1save = s1 = XtNewString ("f.action");
  1235. function_index =
  1236. ParseWmFunction ((unsigned char **) &s1, CRS_ANY, &wm_func);
  1237. XtFree (s1save);
  1238. client_name =
  1239. (char *) control_data->element_values[CONTROL_CLIENT_NAME].parsed_value;
  1240. if (client_name == NULL)
  1241. client_name =
  1242. (char *) control_data->element_values[CONTROL_LABEL].parsed_value;
  1243. client_title =
  1244. (char *) control_data->element_values[CONTROL_LABEL].parsed_value;
  1245. if (control_type == CONTROL_FILE && ! control_data->is_action)
  1246. {
  1247. char * file_name;
  1248. file_name = (char *) control_data->
  1249. element_values[CONTROL_FILE_NAME].parsed_value;
  1250. s1 = XtMalloc (strlen (push_action->action_name) + strlen (file_name) + 2);
  1251. strcpy (s1, push_action->action_name);
  1252. strcat (s1, " ");
  1253. strcat (s1, file_name);
  1254. }
  1255. else
  1256. s1 = XtNewString (push_action->action_name);
  1257. ParseWmFunctionArg ((unsigned char **) &s1, function_index,
  1258. wm_func, (void **) &func_arg,
  1259. client_name, client_name);
  1260. /* Set the push argument to the parsed data */
  1261. push_argument.ixReg = PushRecallGetData (client_name);
  1262. push_argument.wmFunc = wm_func;
  1263. push_argument.pArgs = func_arg;
  1264. /* Get the window manager client data for the panel and */
  1265. /* call the push recall function to get the client run. */
  1266. if (subpanel_data != NULL)
  1267. XFindContext (wm_global_data->display,
  1268. XtWindow (subpanel_data->shell),
  1269. wm_global_data->windowContextType,
  1270. (XtPointer) &wm_client_data);
  1271. else
  1272. XFindContext (wm_global_data->display,
  1273. XtWindow (panel.shell),
  1274. wm_global_data->windowContextType,
  1275. (XtPointer) &wm_client_data);
  1276. F_Push_Recall ((String) &push_argument,
  1277. wm_client_data, callback->event);
  1278. FreeFunctionArg (wm_func, func_arg);
  1279. XtFree (s1);
  1280. }
  1281. }
  1282. }
  1283. break;
  1284. case CONTROL_BLANK:
  1285. case CONTROL_BUSY:
  1286. case CONTROL_CLOCK:
  1287. return;
  1288. break;
  1289. }
  1290. /* Call the unposting function and reset the arrow behavior if the */
  1291. /* action occurred out of a subpanel. */
  1292. if (subpanel_data != NULL && unpost_subpanel &&
  1293. (Boolean) (intptr_t) panel.element_values[PANEL_SUBPANEL_UNPOST].parsed_value &&
  1294. subpanel_data->torn == False)
  1295. ArrowCB (main_control_data->arrow,
  1296. (XtPointer)main_control_data, (XtPointer)NULL);
  1297. }
  1298. }
  1299. /************************************************************************
  1300. *
  1301. * DropCB
  1302. * Process the callback for drops on a control
  1303. *
  1304. ************************************************************************/
  1305. void
  1306. DropCB (Widget w,
  1307. XtPointer client_data,
  1308. XtPointer call_data)
  1309. {
  1310. PanelActionData * drop_action = (PanelActionData *) client_data;
  1311. DtDndDropAnimateCallback animate_data =
  1312. (DtDndDropAnimateCallback) call_data;
  1313. ControlData * control_data;
  1314. Arg al[1];
  1315. int i, j, k, l;
  1316. DtActionArg * aap;
  1317. char * save_name = NULL;
  1318. XtSetArg (al[0], XmNuserData, &control_data);
  1319. XtGetValues (w, al, 1);
  1320. if (CheckControlTypeFile (control_data) &&
  1321. (animate_data->dropData->protocol == DtDND_FILENAME_TRANSFER ||
  1322. animate_data->dropData->protocol == DtDND_BUFFER_TRANSFER))
  1323. {
  1324. int numItems;
  1325. intptr_t control_type =
  1326. (intptr_t)control_data->element_values[CONTROL_TYPE].parsed_value;
  1327. char * control_name =
  1328. (char *)control_data->element_values[CONTROL_FILE_NAME].parsed_value;
  1329. Boolean send_control_name = False;
  1330. _DtControlDoDropAnimation (w);
  1331. drop_action = (PanelActionData *)
  1332. control_data->element_values[CONTROL_DROP_ACTION].parsed_value;
  1333. if (control_data->operation == XmDROP_MOVE)
  1334. {
  1335. if (control_data->move_action)
  1336. {
  1337. save_name = drop_action->action_name;
  1338. drop_action->action_name = control_data->move_action;
  1339. }
  1340. }
  1341. else if (control_data->operation == XmDROP_COPY)
  1342. {
  1343. if (control_data->copy_action)
  1344. {
  1345. save_name = drop_action->action_name;
  1346. drop_action->action_name = control_data->copy_action;
  1347. }
  1348. }
  1349. else if (control_data->operation == XmDROP_LINK)
  1350. {
  1351. if (control_data->link_action)
  1352. {
  1353. save_name = drop_action->action_name;
  1354. drop_action->action_name = control_data->link_action;
  1355. }
  1356. }
  1357. numItems = animate_data->dropData->numItems;
  1358. if ((control_type == CONTROL_FILE) &&
  1359. (!control_data->is_action) &&
  1360. (strcmp(control_name, drop_action->action_name) != 0))
  1361. {
  1362. ++numItems;
  1363. send_control_name = True;
  1364. }
  1365. if (animate_data->dropData->protocol == DtDND_FILENAME_TRANSFER)
  1366. {
  1367. char ** file_list = animate_data->dropData->data.files;
  1368. int m = 0;
  1369. aap = (DtActionArg *) XtCalloc (numItems, sizeof (DtActionArg));
  1370. if (send_control_name)
  1371. {
  1372. aap[m].argClass = DtACTION_FILE;
  1373. aap[m++].u.file.name =
  1374. (char *)control_data->element_values[CONTROL_FILE_NAME].parsed_value;
  1375. }
  1376. for (l = 0; m < numItems; l++, m++)
  1377. {
  1378. aap[m].argClass = DtACTION_FILE;
  1379. aap[m].u.file.name = file_list[l];
  1380. }
  1381. }
  1382. else if (animate_data->dropData->protocol == DtDND_BUFFER_TRANSFER)
  1383. {
  1384. DtDndBuffer * buf_list = animate_data->dropData->data.buffers;
  1385. int m = 0;
  1386. aap = (DtActionArg *) XtCalloc (numItems, sizeof (DtActionArg));
  1387. if (send_control_name)
  1388. {
  1389. aap[m].argClass = DtACTION_FILE;
  1390. aap[m++].u.file.name =
  1391. (char *)control_data->element_values[CONTROL_FILE_NAME].parsed_value;
  1392. }
  1393. for (l = 0; m < numItems; l++, m++)
  1394. {
  1395. aap[m].argClass = DtACTION_BUFFER;
  1396. aap[m].u.buffer.bp = buf_list[l].bp;
  1397. aap[m].u.buffer.size = buf_list[l].size;
  1398. aap[m].u.buffer.name = buf_list[l].name;
  1399. }
  1400. }
  1401. else
  1402. {
  1403. if (save_name != NULL)
  1404. drop_action->action_name = save_name;
  1405. control_data->operation = 0;
  1406. return;
  1407. }
  1408. DtActionInvoke (w, drop_action->action_name, aap, numItems,
  1409. NULL, NULL, NULL, 1, NULL, NULL);
  1410. XtFree((char *) aap);
  1411. if (save_name != NULL)
  1412. drop_action->action_name = save_name;
  1413. control_data->operation = 0;
  1414. }
  1415. }
  1416. /************************************************************************
  1417. *
  1418. * TransferDropCB
  1419. * Process the callback for drops on a control
  1420. *
  1421. ************************************************************************/
  1422. void
  1423. TransferDropCB (Widget w,
  1424. XtPointer client_data,
  1425. XtPointer call_data)
  1426. {
  1427. DtDndTransferCallbackStruct * transfer_data =
  1428. (DtDndTransferCallbackStruct *) call_data;
  1429. ControlData * control_data;
  1430. Arg al[1];
  1431. /* Currently only accepts FILE drops */
  1432. if (transfer_data->dropData->protocol == DtDND_FILENAME_TRANSFER ||
  1433. transfer_data->dropData->protocol == DtDND_BUFFER_TRANSFER)
  1434. {
  1435. transfer_data->status = DtDND_SUCCESS;
  1436. XtSetArg (al[0], XmNuserData, &control_data);
  1437. XtGetValues (w, al, 1);
  1438. control_data->operation = transfer_data->operation;
  1439. }
  1440. else
  1441. transfer_data->status = DtDND_FAILURE;
  1442. transfer_data->completeMove = False;
  1443. }
  1444. /************************************************************************
  1445. ************************************************************************
  1446. This block of functions handle the processing of subpanel torn-off
  1447. behavior. Default behavior for a subpanel is to unpost when a
  1448. control is selected. This changes to sticky when the subpanel is torn.
  1449. ************************************************************************
  1450. ************************************************************************/
  1451. /************************************************************************
  1452. *
  1453. * SubpanelUnmapCB
  1454. * Process the callback on the subpanel unposting initiated through
  1455. * the window manager close menu item.
  1456. *
  1457. ************************************************************************/
  1458. void
  1459. SubpanelUnmapCB (Widget w,
  1460. XtPointer client_data,
  1461. XtPointer call_data)
  1462. {
  1463. ControlData * main_control_data = (ControlData *) client_data;
  1464. SubpanelData * subpanel_data = main_control_data->subpanel_data;
  1465. Arg al[1];
  1466. int ac;
  1467. ac = 0;
  1468. XtSetArg (al[ac], XmNimageName, post_arrow_image); ac++;
  1469. XtSetValues (main_control_data->arrow, al, ac);
  1470. XtUnmanageChild (subpanel_data->shell);
  1471. subpanel_data->torn = False;
  1472. /* Remove the event handler from the subpanel */
  1473. XtRemoveEventHandler (subpanel_data->shell, StructureNotifyMask, False,
  1474. (XtEventHandler) SubpanelTornEventHandler,
  1475. (XtPointer) main_control_data);
  1476. /* Reset the active traversal control for the front panel */
  1477. /* We should not have to do this but for unknown reasons, */
  1478. /* the traversal highlight is getting lost. */
  1479. XmProcessTraversal (panel.shell, XmTRAVERSE_NEXT);
  1480. XmProcessTraversal (panel.shell, XmTRAVERSE_PREV);
  1481. }
  1482. /************************************************************************
  1483. *
  1484. * SubpanelTornEventHandler
  1485. * Set a subpanel flag to change its posting behavior when it is
  1486. * torn off.
  1487. *
  1488. ************************************************************************/
  1489. void
  1490. SubpanelTornEventHandler (Widget subpanel_shell,
  1491. XtPointer client_data,
  1492. XEvent * event,
  1493. Boolean * continue_dispatch)
  1494. {
  1495. ControlData * main_control_data = (ControlData *) client_data;
  1496. SubpanelData * subpanel_data = main_control_data->subpanel_data;
  1497. if (subpanel_data->posted_x != 0 &&
  1498. subpanel_data->posted_x != XtX (subpanel_data->shell))
  1499. subpanel_data->torn = True;
  1500. else
  1501. subpanel_data->torn = False;
  1502. *continue_dispatch = True;
  1503. }
  1504. /************************************************************************
  1505. *
  1506. * StartHelpClient
  1507. * Start up the help manager to show the help topic
  1508. *
  1509. * Inputs: widget - the widget for which help was requested
  1510. * help_volume - the help volume that contains the information
  1511. * help_topic - the specific help topic.
  1512. *
  1513. ************************************************************************/
  1514. void StartHelpClient (Widget widget,
  1515. char * help_volume,
  1516. char * help_topic)
  1517. {
  1518. /***** TEMPORARY - Add code to actually invoke the Help Client ****/
  1519. WmDtDisplayTopicHelp (widget, help_volume, help_topic);
  1520. }
  1521. /************************************************************************
  1522. *
  1523. * InvokeHelp
  1524. * Invoke topic help if available otherwise invoke help string if
  1525. * available
  1526. *
  1527. ************************************************************************/
  1528. void InvokeHelp (Widget widget,
  1529. char * help_topic,
  1530. char * help_volume,
  1531. char * help_string)
  1532. {
  1533. if (help_volume == NULL)
  1534. help_volume = FP_HELP_VOLUME;
  1535. if (help_topic != NULL)
  1536. {
  1537. if (strcmp (help_volume, FP_HELP_VOLUME) == 0)
  1538. WmDtDisplayTopicHelp (widget, help_volume, help_topic);
  1539. else
  1540. StartHelpClient (widget, help_volume, help_topic);
  1541. }
  1542. else
  1543. {
  1544. if (help_string != NULL)
  1545. WmDtDisplayStringHelp (widget, help_string);
  1546. }
  1547. }
  1548. /************************************************************************
  1549. *
  1550. * SubpanelTopicHelpCB
  1551. * Process the callback for help on the subpanel
  1552. *
  1553. ************************************************************************/
  1554. void SubpanelTopicHelpCB (Widget widget,
  1555. XtPointer client_data,
  1556. XtPointer call_data)
  1557. {
  1558. SubpanelData * subpanel_data = (SubpanelData *) client_data;
  1559. char * help_volume;
  1560. char * help_topic;
  1561. char * help_string;
  1562. help_volume =
  1563. (char *) subpanel_data->element_values[SUBPANEL_HELP_VOLUME].parsed_value;
  1564. help_topic =
  1565. (char *) subpanel_data->element_values[SUBPANEL_HELP_TOPIC].parsed_value;
  1566. help_string =
  1567. (char *) subpanel_data->element_values[SUBPANEL_HELP_STRING].parsed_value;
  1568. InvokeHelp(widget, help_topic, help_volume, help_string);
  1569. } /* END OF FUNCTION SubpanelTopicHelpCB */
  1570. /************************************************************************
  1571. *
  1572. * SwitchTopicHelpCB
  1573. * Process the callback for help on the switch
  1574. *
  1575. ************************************************************************/
  1576. void SwitchTopicHelpCB (Widget widget,
  1577. XtPointer client_data,
  1578. XtPointer call_data)
  1579. {
  1580. SwitchData * switch_data = (SwitchData *) client_data;
  1581. char * help_volume;
  1582. char * help_topic;
  1583. char * help_string;
  1584. help_volume =
  1585. (char *) switch_data->element_values[SWITCH_HELP_VOLUME].parsed_value;
  1586. help_topic =
  1587. (char *) switch_data->element_values[SWITCH_HELP_TOPIC].parsed_value;
  1588. help_string =
  1589. (char *) switch_data->element_values[SWITCH_HELP_STRING].parsed_value;
  1590. InvokeHelp(widget, help_topic, help_volume, help_string);
  1591. } /* END OF FUNCTION SwitchTopicHelpCB */
  1592. /************************************************************************
  1593. *
  1594. * ControlTopicHelpCB
  1595. * Process the callback for help on the control
  1596. *
  1597. *************************************************************************/
  1598. void ControlTopicHelpCB (Widget widget,
  1599. XtPointer client_data,
  1600. XtPointer call_data)
  1601. {
  1602. ControlData * control_data = (ControlData *) client_data;
  1603. char * help_volume;
  1604. char * help_topic;
  1605. char * help_string;
  1606. help_volume =
  1607. (char *) control_data->element_values[CONTROL_HELP_VOLUME].parsed_value;
  1608. help_topic =
  1609. (char *) control_data->element_values[CONTROL_HELP_TOPIC].parsed_value;
  1610. help_string =
  1611. (char *) control_data->element_values[CONTROL_HELP_STRING].parsed_value;
  1612. InvokeHelp(widget, help_topic, help_volume, help_string);
  1613. } /* END OF FUNCTION ControlTopicHelpCB */
  1614. /************************************************************************
  1615. *
  1616. * GeneralTopicHelpCB
  1617. * Process the callback for help on the control
  1618. *
  1619. ************************************************************************/
  1620. void GeneralTopicHelpCB (Widget widget,
  1621. XtPointer client_data,
  1622. XtPointer call_data)
  1623. {
  1624. char * help_volume;
  1625. char * help_topic;
  1626. help_volume = FP_HELP_VOLUME;
  1627. help_topic = (char *) client_data;
  1628. WmDtDisplayTopicHelp (widget, help_volume, help_topic);
  1629. } /* END OF FUNCTION GeneralTopicHelpCB */
  1630. /************************************************************************
  1631. ************************************************************************
  1632. This block of functions handle the initialization and dynamic
  1633. processing for the subpanel installation area.
  1634. ************************************************************************
  1635. ************************************************************************/
  1636. /************************************************************************
  1637. *
  1638. * GetValuesFromDataType
  1639. * Given and file type index and subpanel data, construct an element
  1640. * values array for a new control that is initialized to the attributes
  1641. * of the file type.
  1642. *
  1643. ************************************************************************/
  1644. static void
  1645. GetValuesFromDataType (char * data_type,
  1646. char * file_name,
  1647. SubpanelData * subpanel_data,
  1648. ElementValue ** element_values)
  1649. {
  1650. char * ptr;
  1651. int i;
  1652. *element_values = (ElementValue *) XtMalloc (sizeof(ElementValue) *
  1653. CONTROL_KEYWORD_COUNT);
  1654. for (i = 0; i < CONTROL_KEYWORD_COUNT; i++)
  1655. {
  1656. (*element_values)[i].use_default = True;
  1657. (*element_values)[i].string_value = NULL;
  1658. (*element_values)[i].parsed_value = NULL;
  1659. }
  1660. (*element_values)[CONTROL_FILE_NAME].string_value = XtNewString (file_name);
  1661. ptr = (char *)strrchr(file_name, '/');
  1662. ptr++;
  1663. (*element_values)[CONTROL_NAME].string_value = XtNewString(ptr);
  1664. (*element_values)[CONTROL_TYPE].string_value = XtNewString("file");
  1665. (*element_values)[CONTROL_CONTAINER_TYPE].string_value =
  1666. XtNewString("SUBPANEL");
  1667. (*element_values)[CONTROL_CONTAINER_NAME].string_value =
  1668. XtNewString(subpanel_data->element_values[0].string_value);
  1669. (*element_values)[CONTROL_POSITION_HINTS].string_value =
  1670. XtNewString("last");
  1671. InitializeControlFields (*element_values, data_type);
  1672. }
  1673. /************************************************************************
  1674. *
  1675. * CustomizeDropCB
  1676. * Process the callback for the drop on the subpanel drop zone for
  1677. * dynamic customization
  1678. *
  1679. ************************************************************************/
  1680. void
  1681. CustomizeDropCB (Widget w,
  1682. XtPointer client_data,
  1683. XtPointer call_data)
  1684. {
  1685. BoxData * box_data;
  1686. ControlData * main_control_data;
  1687. SubpanelData * subpanel_data;
  1688. DtDndDropAnimateCallbackStruct * animate_data =
  1689. (DtDndDropAnimateCallbackStruct *) call_data;
  1690. ControlData * control_data;
  1691. ElementValue * element_values;
  1692. char * data_type;
  1693. Boolean drop_of_fp;
  1694. Boolean bad_control;
  1695. Boolean control_monitor;
  1696. intptr_t position_hints;
  1697. int count;
  1698. char * new_control_name;
  1699. char * control_name;
  1700. Widget attach_widget;
  1701. int i, j, k;
  1702. int file_count;
  1703. char ** file_list;
  1704. Arg al[4];
  1705. int ac;
  1706. /* If this is not a transfer drop, return */
  1707. if (animate_data->dropData->protocol != DtDND_FILENAME_TRANSFER)
  1708. return;
  1709. /* Get the subpanel, box, and main control data */
  1710. XtSetArg (al[0], XmNuserData, &subpanel_data);
  1711. XtGetValues (w, al, 1);
  1712. main_control_data = subpanel_data->parent_control_data;
  1713. box_data = (BoxData *) main_control_data->parent_data;
  1714. file_count = animate_data->dropData->numItems;
  1715. file_list = animate_data->dropData->data.files;
  1716. /* Pop down the subpanel before creating the new control or */
  1717. /* mucking with any of the old controls. */
  1718. if (subpanel_data->torn == False)
  1719. XtUnmanageChild (subpanel_data->shell);
  1720. /* Loop through the set of files (possibly more than one) that */
  1721. /* have been dropped. */
  1722. for (i = 0; i < file_count; i++)
  1723. {
  1724. /* Get the file type of the file and process as either */
  1725. /* a "FrontPanel" file or a normal file type. */
  1726. data_type = DtDtsFileToDataType (file_list[i]);
  1727. if (!strcmp (data_type, "FP"))
  1728. {
  1729. drop_of_fp = True;
  1730. InitParse (file_list[i], &element_values);
  1731. /* Reset the values of the container name and type to this one */
  1732. if (element_values[CONTROL_CONTAINER_NAME].use_default == False)
  1733. {
  1734. if (element_values[CONTROL_CONTAINER_NAME].parsed_value != NULL)
  1735. XtFree (element_values[CONTROL_CONTAINER_NAME].parsed_value);
  1736. if (element_values[CONTROL_CONTAINER_NAME].string_value != NULL)
  1737. XtFree (element_values[CONTROL_CONTAINER_NAME].string_value);
  1738. }
  1739. if (element_values[CONTROL_CONTAINER_TYPE].use_default == False)
  1740. {
  1741. if (element_values[CONTROL_CONTAINER_TYPE].string_value != NULL)
  1742. XtFree (element_values[CONTROL_CONTAINER_TYPE].string_value);
  1743. }
  1744. if (element_values[CONTROL_POSITION_HINTS].use_default == False)
  1745. {
  1746. if (element_values[CONTROL_POSITION_HINTS].string_value != NULL)
  1747. XtFree (element_values[CONTROL_POSITION_HINTS].string_value);
  1748. }
  1749. element_values[CONTROL_CONTAINER_NAME].use_default = False;
  1750. element_values[CONTROL_CONTAINER_NAME].string_value =
  1751. XtNewString (subpanel_data->element_values[SUBPANEL_NAME].parsed_value);
  1752. element_values[CONTROL_CONTAINER_NAME].parsed_value =
  1753. XtNewString (subpanel_data->element_values[SUBPANEL_NAME].parsed_value);
  1754. element_values[CONTROL_CONTAINER_TYPE].use_default = False;
  1755. element_values[CONTROL_CONTAINER_TYPE].string_value =
  1756. XtNewString ("SUBPANEL");
  1757. element_values[CONTROL_CONTAINER_TYPE].parsed_value =
  1758. (char *) SUBPANEL;
  1759. element_values[CONTROL_POSITION_HINTS].use_default = False;
  1760. element_values[CONTROL_POSITION_HINTS].string_value =
  1761. XtNewString ("last");
  1762. element_values[CONTROL_POSITION_HINTS].parsed_value =
  1763. (char *) 100;
  1764. }
  1765. else
  1766. {
  1767. drop_of_fp = False;
  1768. GetValuesFromDataType (data_type, file_list[i],
  1769. subpanel_data, &element_values);
  1770. }
  1771. DtDtsFreeDataType (data_type);
  1772. /* Check for naming conflicts and if found, issue an error and */
  1773. /* clean up. Continue processing subsequent files even if this */
  1774. /* one is not valid. */
  1775. new_control_name = (char *) element_values[CONTROL_NAME].parsed_value;
  1776. bad_control = False;
  1777. for (j = 0; j < subpanel_data->control_data_count; j++)
  1778. {
  1779. control_name = (char *) subpanel_data->control_data[j]->
  1780. element_values[CONTROL_NAME].parsed_value;
  1781. if (strcmp (control_name, new_control_name) == 0)
  1782. {
  1783. ControlData control_data;
  1784. String title, del_ctrl, ctrl_name, del_msg, message;
  1785. /* Display an error dialog for the unusable drop data */
  1786. title = FPGETMESSAGE (86, 3, "Workspace Manager - Install Icon Error");
  1787. title = XtNewString (title);
  1788. del_ctrl = FPGETMESSAGE (86, 4, "Install Icon:");
  1789. del_ctrl = XtNewString (del_ctrl);
  1790. del_msg = FPGETMESSAGE (86, 8, "There is already an icon of this name.");
  1791. del_msg = XtNewString (del_msg);
  1792. message = XtMalloc ((strlen(del_ctrl) + strlen(new_control_name) +
  1793. strlen(del_msg) + 4));
  1794. sprintf(message, "%s %s\n\n%s", del_ctrl, new_control_name, del_msg);
  1795. _DtMessage (panel.shell, title, message, NULL, NULL);
  1796. XtFree (title);
  1797. XtFree (del_ctrl);
  1798. XtFree (del_msg);
  1799. XtFree (message);
  1800. /* Set up a temporary control data structure so that the */
  1801. /* appropriate function can be used to free the allocated */
  1802. /* element values. */
  1803. control_data.element_values = element_values;
  1804. RemoveEntry ((RecordData *)&control_data, CONTROL);
  1805. bad_control = True;
  1806. break;
  1807. }
  1808. }
  1809. if (bad_control) continue;
  1810. if ((intptr_t) element_values[CONTROL_MONITOR_TYPE].parsed_value != MONITOR_NONE)
  1811. control_monitor = True;
  1812. else
  1813. control_monitor = False;
  1814. position_hints = (intptr_t) element_values[CONTROL_POSITION_HINTS].parsed_value;
  1815. /* Initialize the subpanel layout and processing attributes. */
  1816. if ((intptr_t) main_control_data->
  1817. element_values[CONTROL_MONITOR_TYPE].parsed_value != MONITOR_NONE)
  1818. {
  1819. control_monitor = True;
  1820. }
  1821. for (j = 0; j < subpanel_data->control_data_count; j++)
  1822. {
  1823. if ((intptr_t) subpanel_data->control_data[j]->
  1824. element_values[CONTROL_MONITOR_TYPE].parsed_value != MONITOR_NONE)
  1825. {
  1826. control_monitor = True;
  1827. break;
  1828. }
  1829. }
  1830. /* If the new control is a montior, loop through the existing */
  1831. /* control set a adjust the left offset resource to ensure */
  1832. /* that they are all aligned properly. */
  1833. if (control_monitor)
  1834. {
  1835. XtSetArg (al[0], XmNleftOffset, 20);
  1836. for (j = 0; j < subpanel_data->control_data_count; j++)
  1837. XtSetValues (subpanel_data->control_data[j]->icon, al, 1);
  1838. if (subpanel_data->main_panel_icon_copy != NULL)
  1839. XtSetValues (subpanel_data->main_panel_icon_copy, al, 1);
  1840. }
  1841. /* Get the subpanel control data and position the element */
  1842. /* values into the postion hints location. */
  1843. /* The remainder of the positioning code is set up to allow */
  1844. /* placement in non-last positions even though position is */
  1845. /* forced to last. This is here for future use. */
  1846. subpanel_data->control_data_count++;
  1847. count = subpanel_data->control_data_count;
  1848. subpanel_data->control_data =
  1849. (ControlData **) XtRealloc ((char *) subpanel_data->control_data,
  1850. sizeof (ControlData *) * count);
  1851. for (j = count - 2; j >= 0; j--)
  1852. {
  1853. if (position_hints >=
  1854. (intptr_t) subpanel_data->control_data[j]->element_values[CONTROL_POSITION_HINTS].parsed_value)
  1855. break;
  1856. }
  1857. j++;
  1858. for (k = count - 1; k > j; k--)
  1859. subpanel_data->control_data[k] = subpanel_data->control_data[k - 1];
  1860. subpanel_data->control_data[j] = control_data =
  1861. (ControlData *) XtMalloc (sizeof (ControlData));
  1862. control_data->element_values = element_values;
  1863. control_data->parent_data = (XtPointer) subpanel_data;
  1864. control_data->parent_type = SUBPANEL;
  1865. control_data->subpanel_data = NULL;
  1866. control_data->icon = NULL;
  1867. control_data->arrow = NULL;
  1868. control_data->arrow_separator = NULL;
  1869. control_data->indicator = NULL;
  1870. control_data->is_action = False;
  1871. control_data->move_action = NULL;
  1872. control_data->copy_action = NULL;
  1873. control_data->link_action = NULL;
  1874. control_data->operation = 0;
  1875. AddControlActionList (control_data);
  1876. if (j == 0 && subpanel_data->main_panel_icon_copy != NULL)
  1877. attach_widget = subpanel_data->main_panel_icon_copy;
  1878. else
  1879. attach_widget = subpanel_data->control_data[j - 1]->icon;
  1880. /* Reattach the bottom control so the new bottom will appear */
  1881. if (j == count - 1)
  1882. {
  1883. ac = 0;
  1884. XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
  1885. XtSetArg (al[ac], XmNbottomOffset, 0); ac++;
  1886. XtSetValues (attach_widget, al, ac);
  1887. }
  1888. SubpanelControlCreate (subpanel_data, main_control_data,
  1889. control_data, attach_widget, False,
  1890. control_monitor);
  1891. /* Pad the bottom control */
  1892. if (j == count - 1)
  1893. {
  1894. ac = 0;
  1895. XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  1896. XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
  1897. XtSetValues (control_data->icon, al, ac);
  1898. }
  1899. WriteControlComponentFile (control_data);
  1900. }
  1901. /* Pop the subpanel back up and return */
  1902. if (subpanel_data->torn == False)
  1903. ArrowCB (main_control_data->arrow,
  1904. (XtPointer)main_control_data, (XtPointer)NULL);
  1905. }
  1906. /************************************************************************
  1907. *
  1908. * CustomizeTransferDropCB
  1909. * Process the callback for drops on an install zone
  1910. *
  1911. ************************************************************************/
  1912. void
  1913. CustomizeTransferDropCB (Widget w,
  1914. XtPointer client_data,
  1915. XtPointer call_data)
  1916. {
  1917. DtDndTransferCallbackStruct * transfer_data =
  1918. (DtDndTransferCallbackStruct *) call_data;
  1919. /* Currently only accepts FILE drops */
  1920. if (transfer_data->dropData->protocol == DtDND_FILENAME_TRANSFER)
  1921. transfer_data->status = DtDND_SUCCESS;
  1922. else
  1923. transfer_data->status = DtDND_FAILURE;
  1924. transfer_data->completeMove = False;
  1925. }