X11workbench Toolkit  1.0
child_frame.c
1 // _ _ _ _ __ //
3 // ___| |__ (_) | __| | / _|_ __ __ _ _ __ ___ ___ ___ //
4 // / __| '_ \| | |/ _` | | |_| '__/ _` | '_ ` _ \ / _ \ / __| //
5 // | (__| | | | | | (_| | | _| | | (_| | | | | | | __/| (__ //
6 // \___|_| |_|_|_|\__,_|___|_| |_| \__,_|_| |_| |_|\___(_)___| //
7 // |_____| //
8 // //
9 // a window that exists as a tab in a frame window //
10 // //
11 // (part of the 'frame window' support API) //
12 // //
14 
15 /*****************************************************************************
16 
17  X11workbench - X11 programmer's 'work bench' application and toolkit
18  Copyright (c) 2010-2018 by Bob Frazier (aka 'Big Bad Bombastic Bob')
19  all rights reserved
20 
21  DISCLAIMER: The X11workbench application and toolkit software are supplied
22  'as-is', with no warranties, either implied or explicit.
23  Any claims to alleged functionality or features should be
24  considered 'preliminary', and might not function as advertised.
25 
26  BSD-like license:
27 
28  There is no restriction as to what you can do with this software, so long
29  as you include the above copyright notice and DISCLAIMER for any distributed
30  work that is equal to or derived from this one, along with this paragraph
31  that explains the terms of the license if the source is also being made
32  available. A "derived work" describes a work that uses a significant portion
33  of the source files or algorithms that are included with this one.
34  Specifically excluded from this are files that were generated by the software,
35  or anything that is included with the software that is part of another package
36  (such as files that were created or added during the 'configure' process).
37  Specifically included is the use of part or all of any of the X11 workbench
38  toolkit source or header files in your distributed application. If you do not
39  ship the source, the above copyright statement is still required to be placed
40  in a reasonably prominent place, such as documentation, splash screens, and/or
41  'about the application' dialog boxes.
42 
43  Use and distribution are in accordance with GPL, LGPL, and/or the above
44  BSD-like license. See COPYING and README files for more information.
45 
46 
47  Additional information at http://sourceforge.net/projects/X11workbench
48 
49 ******************************************************************************/
50 
51 
52 #include <stdlib.h>
53 #include <unistd.h>
54 #include <memory.h>
55 #include <string.h>
56 #include <strings.h>
57 
58 #include "window_helper.h"
59 #include "font_helper.h"
60 #include "child_frame.h"
61 #include "draw_text.h"
62 #include "menu_popup.h"
63 
64 #include "dialog_window.h" // for message boxen, etc.
65 
66 
67 
68 static int ChildFrameEditCutHandler(XClientMessageEvent *);
69 static int ChildFrameEditCopyHandler(XClientMessageEvent *);
70 static int ChildFrameEditPasteHandler(XClientMessageEvent *);
71 static int ChildFrameEditDeleteHandler(XClientMessageEvent *);
72 static int ChildFrameEditSelectAllHandler(XClientMessageEvent *);
73 static int ChildFrameEditSelectNoneHandler(XClientMessageEvent *);
74 static int ChildFrameEditPropertiesHandler(XClientMessageEvent *);
75 static int ChildFrameEditCutUIHandler(WBMenu *pMenu, WBMenuItem *pMenuItem);
76 static int ChildFrameEditCopyUIHandler(WBMenu *pMenu, WBMenuItem *pMenuItem);
77 static int ChildFrameEditPasteUIHandler(WBMenu *pMenu, WBMenuItem *pMenuItem);
78 static int ChildFrameEditDeleteUIHandler(WBMenu *pMenu, WBMenuItem *pMenuItem);
79 static int ChildFrameEditSelectAllUIHandler(WBMenu *pMenu, WBMenuItem *pMenuItem);
80 static int ChildFrameEditSelectNoneUIHandler(WBMenu *pMenu, WBMenuItem *pMenuItem);
81 static int ChildFrameEditPropertiesUIHandler(WBMenu *pMenu, WBMenuItem *pMenuItem);
82 
92 FW_MENU_HANDLER_BEGIN(aChildFrameMenuHandler)
93 
94  FW_MENU_HANDLER_ENTRY(FW_EDIT_CUT_MENU, ChildFrameEditCutHandler, ChildFrameEditCutUIHandler)
95  FW_MENU_HANDLER_ENTRY(FW_EDIT_COPY_MENU, ChildFrameEditCopyHandler, ChildFrameEditCopyUIHandler)
96  FW_MENU_HANDLER_ENTRY(FW_EDIT_PASTE_MENU, ChildFrameEditPasteHandler, ChildFrameEditPasteUIHandler)
97  FW_MENU_HANDLER_ENTRY(FW_EDIT_DELETE_MENU, ChildFrameEditDeleteHandler, ChildFrameEditDeleteUIHandler)
98  FW_MENU_HANDLER_ENTRY(FW_EDIT_SELECT_ALL_MENU, ChildFrameEditSelectAllHandler, ChildFrameEditSelectAllUIHandler)
99  FW_MENU_HANDLER_ENTRY(FW_EDIT_SELECT_NONE_MENU, ChildFrameEditSelectNoneHandler, ChildFrameEditSelectNoneUIHandler)
100  FW_MENU_HANDLER_ENTRY(FW_EDIT_PROPERTIES_MENU, ChildFrameEditPropertiesHandler, ChildFrameEditPropertiesUIHandler)
101 
103 
104 
105 
106 static int ChildFrameDoPointerEvent(XClientMessageEvent *pEvent, Display *pDisplay,
107  Window wID, WBChildFrame *pC, WBChildFrameUI *pUI);
108 
109 static int ChildFrameDoScrollEvent(XClientMessageEvent *pEvent, Display *pDisplay,
110  Window wID, WBChildFrame *pC, WBChildFrameUI *pUI);
111 
112 static int ChildFrameDoCharEvent(XClientMessageEvent *pEvent, Display *pDisplay,
113  Window wID, WBChildFrame *pC, WBChildFrameUI *pUI);
114 
115 static WBChildFrame *pChildFrames = NULL; // pointer to linked list of 'Child Frame' windows
116 
117 
118 int FWInitChildFrame(WBChildFrame *pChildFrame, WBFrameWindow *pOwner, XFontSet rFontSet,
119  const char *szFocusMenu, const WBFWMenuHandler *pHandlerArray,
120  WBWinEvent pUserCallback, int fFlags)
121 {
122 WBChildFrame *pC;
123 XSetWindowAttributes xswa; /* Temporary Set Window Attribute struct */
124 Display *pDisplay = WBGetDefaultDisplay();
125 int iRval = -1;
126 
127 
128  if(!pChildFrame || !pOwner || pOwner->wID == None)
129  {
130  // TODO: validate 'pOwner' as a valid WBFrameWindow ??
131 
132  WB_ERROR_PRINT("%s - invalid pointers or owner window does not exist\n", __FUNCTION__);
133 
134  return -1;
135  }
136 
137  // zero out entire structure beforehand
138  bzero(pChildFrame, sizeof(*pChildFrame));
139 
140 
141  // FIRST, attach the child frame to my list o' child frames, making sure
142  // that it is not already there [if it is assume this was called twice]
143  // while I'm at it, zero out the structure BEFORE I assign 'pNext'
144 
145  if(!pChildFrames)
146  {
147  pChildFrames = pChildFrame;
148  pChildFrame->pNext = NULL; // make sure
149  }
150  else
151  {
152  pC = pChildFrames;
153 
154  while(pC->pNext)
155  {
156  if(pC == pChildFrame) // just in case
157  {
158  WB_ERROR_PRINT("%s - unexpected error condition, did you call this function before?\n", __FUNCTION__);
159 
160  return -2;
161  }
162 
163  pC = pC->pNext;
164  }
165 
166  if(pC)
167  {
168  // zero out entire structure beforehand
169  bzero(pChildFrame, sizeof(*pChildFrame));
170 
171  pC->pNext = pChildFrame;
172  pChildFrame->pNext = NULL;
173  }
174  else
175  {
176  // internal error, flag it for now and return "fail"
177  WB_ERROR_PRINT("%s - unexpected condition, returning error\n", __FUNCTION__);
178 
179  return -3;
180  }
181  }
182 
183  // initialize scroll info
184  WBInitScrollInfo(&(pChildFrame->scroll)); // re-initialize (TODO: must I do this every time?)
185 
186 
187  // if the owner is valid, but NOT tabbed, and it already has
188  // a WBChildFrame, then I fail to create this one.
189 
190  if((WBFrameWindow_NO_TABS & pOwner->iFlags)) // window has NO tabs
191  {
192  if(FWGetNumContWindows(pOwner)) // error *OR* > 0, doesn't matter, can ONLY have one tab in the frame
193  {
194  FWDestroyChildFrame(pChildFrame); // this unhooks everything (alloc'd things are zero'd by bzero)
195 
196  return -4; // can't create, SDI
197  }
198  }
199 
200 
201  // NEXT, set up all of the various 'things' in the structure that are simple assignments
202  pChildFrame->ulTag = CHILD_FRAME_TAG;
203  pChildFrame->destructor = NULL; // make sure
204 
205  if(rFontSet == None)
206  {
207  pChildFrame->rFontSet = None;
208  }
209  else
210  {
211  pChildFrame->rFontSet = WBCopyModifyFontSet(pDisplay, rFontSet, 0, 0);
212  }
213 
214  if(szFocusMenu)
215  {
216  pChildFrame->pszMenuResource = WBCopyString(szFocusMenu);
217 
218  if(!pChildFrame->pszMenuResource)
219  {
220  FWDestroyChildFrame(pChildFrame); // this unhooks everything (alloc'd things are zero'd by bzero)
221  return -5; // not enough memory
222  }
223  }
224  else
225  {
226  pChildFrame->pszMenuResource = NULL;
227  }
228 
229  pChildFrame->iContextMenuID = -1; // default; use
230 
231  if(pHandlerArray)
232  {
233  const WBFWMenuHandler *pH;
234  int iN;
235 
236  // count the number of entries in the menu handler
237  for(iN=0, pH = pHandlerArray; pH->lMenuID || pH->callback || pH->UIcallback; iN++, pH++)
238  {
239  // NOTHING inside the loop. just count.
240  }
241 
242  // allocate space and make a copy
243 
244  pChildFrame->pMenuHandler = (WBFWMenuHandler *)WBAlloc(sizeof(WBFWMenuHandler)
245  * (iN + 1
246  + sizeof(aChildFrameMenuHandler)
247  / sizeof(aChildFrameMenuHandler[0])
248  )
249  );
250 
251  if(pChildFrame->pMenuHandler)
252  {
253  if(iN > 0)
254  {
255  memcpy(pChildFrame->pMenuHandler, pHandlerArray,
256  sizeof(WBFWMenuHandler) * iN);
257  }
258 
259  memcpy(pChildFrame->pMenuHandler + iN,
260  aChildFrameMenuHandler,
261  sizeof(aChildFrameMenuHandler)); // this includes the NULL entry at the end
262  }
263  else
264  {
265  FWDestroyChildFrame(pChildFrame); // this unhooks everything (alloc'd things are zero'd by bzero)
266  return -5; // not enough memory
267  }
268  }
269 
270  // Next, I need to create the window via 'WBCreateWindow()'
271 
272  bzero(&xswa, sizeof(xswa));
273 
274  xswa.border_pixel = FWGetDefaultBD().pixel;
275  xswa.background_pixel = FWGetDefaultBG().pixel; // typically a 'grey' color
276  xswa.colormap = DefaultColormap(pDisplay, DefaultScreen(pDisplay));
277  xswa.bit_gravity = CenterGravity;
278 
279  pChildFrame->wID = WBCreateWindow(pDisplay, pOwner->wID, FWChildFrameEvent, "ChildFrame",
280  pOwner->iClientX, pOwner->iClientY,
281  pOwner->iClientWidth - 2, pOwner->iClientHeight - 2, // border is 1 pixel, so subtract 2
282  1, InputOutput,
283  CWBorderPixel | CWBackPixel | CWColormap | CWBitGravity,
284  &xswa);
285 
286  if(pChildFrame->wID == None)
287  {
288  FWDestroyChildFrame(pChildFrame);
289  return -6; // could not create the window
290  }
291 
292  // immediately identify this window's data struct using window data
293  WBSetWindowData(pChildFrame->wID, 0, (void *)pChildFrame); // window data is pointer to this struct
294  pChildFrame->pUserCallback = pUserCallback;
295 
296 
297  // create the default graphics context using the frame's color info
298  WBCreateWindowDefaultGC(pChildFrame->wID, FWGetDefaultFG().pixel, FWGetDefaultBG().pixel);
299 
300  // now allow specific kinds of input messages. I won't need 'structure notify' as they won't work
301  // anyway. those end up going to the frame window, and it passes them (as needed) to me.
302  XSelectInput(pDisplay, pChildFrame->wID,
304 
305 
306  // FINALLY, inform the frame window, which will set up some other stuff for me
307 
308  pChildFrame->pOwner = pOwner;
309  iRval = FWAddContainedWindow(pOwner, pChildFrame); // TODO: make THIS assign the owner pointer?
310 
311  if(iRval < 0) // error? (returns negative on error, otherwise the tab index)
312  {
313  FWDestroyChildFrame(pChildFrame); // this frees up all of the resources (but does not free the mem block)
314  }
315 
316  // TODO: other things
317 
318  return iRval;
319 }
320 
322 {
323 WBChildFrame *pC, *pC2;
324 Window wID;
325 
326 
327  if(!pChildFrame)
328  {
329  WB_ERROR_PRINT("ERROR: %s - pChildFrame not valid\n", __FUNCTION__);
330 
331  return;
332  }
333 
334  wID = pChildFrame->wID; // make a copy of it
335 
336  // FIRST, tell the owner to remove me from the list
337 
338  if(pChildFrame->pOwner)
339  {
340  FWRemoveContainedWindow(pChildFrame->pOwner, pChildFrame);
341 
342  if(pChildFrame->pOwner != NULL)
343  {
344  WB_ERROR_PRINT("ERROR: %s - owner pointer was nut 'NULL'd out\n", __FUNCTION__);
345  }
346 
347  pChildFrame->pOwner = NULL;
348  }
349 
350  // NOW, free up any resources that were WBAlloc'd - they must also be free'd
351 
352  if(pChildFrame->szDisplayName)
353  {
354  WBFree(pChildFrame->szDisplayName);
355  pChildFrame->szDisplayName = NULL;
356  }
357 
358  if(pChildFrame->rFontSet)
359  {
360  XFreeFontSet(WBGetDefaultDisplay(), pChildFrame->rFontSet);
361  pChildFrame->rFontSet = None;
362  }
363 
364  if(pChildFrame->pMenuHandler)
365  {
366  WBFree(pChildFrame->pMenuHandler);
367  pChildFrame->pMenuHandler = NULL;
368  }
369 
370  if(pChildFrame->szStatusText)
371  {
372  WBFree(pChildFrame->szStatusText);
373  pChildFrame->szStatusText = NULL;
374  }
375 
376  if(pChildFrame->pszMenuResource)
377  {
378  WBFree(pChildFrame->pszMenuResource);
379  pChildFrame->pszMenuResource = NULL;
380  }
381 
382  // And, NOW, destroy the window itself [if it's valid]
383  //
384  // NOTE: to prevent recursion problems, a 'DestroyNotify' would mark the window ID 'None'
385  // before calling this function. this will happen within my OWN proc, if the superclass doesn't do it
386 
387  if(pChildFrame->wID != None) // if there's a chance of recursion, I detect it here
388  {
389  WBDestroyWindow(pChildFrame->wID);
390  pChildFrame->wID = None; // make sure
391  }
392 
393  // FINALLY, unlink this object from the child frame list. Do it by walking the list, looking for
394  // this entry in the list. If I find it, I unlink it [otherwise, the 'pNext' link might be *stale*]
395 
396  if(pChildFrames) // just in case, walk the list - do not rely on possibly stale pointers
397  {
398  pC2 = NULL;
399  pC = pChildFrames;
400 
401  while(pC)
402  {
403  if(pC == pChildFrame) // just in case
404  {
405  if(pC2)
406  {
407  pC2->pNext = pC->pNext; // remove from link list
408  }
409  else
410  {
411  pChildFrames = pC->pNext; // it was the head of the chain
412  }
413 
414  pC->pNext = NULL;
415 
416  break;
417  }
418 
419  pC2 = pC;
420  pC = pC->pNext;
421  }
422  }
423 
424  pChildFrame->pNext = NULL; // make sure it's not a pointer someplace that can cause problems
425 
426  // if the 'superclass' destructor was specified, call it NOW.
427 
428  if(pChildFrame->destructor)
429  {
430  // at this point, we ALWAYS destroy the callback function.
431  // "it is assumed" that I won't be needing 'DestroyNotify' to
432  // trigger any destruction. That happens *AFTER* the window was
433  // destroyed, and happens asynchronously, typically before the
434  // frame window was destroyed.
435 
436  // so, to make sure that I don't get an event callback that references
437  // the window object after it's free'd, I need to remove the callback.
438 
439  if(wID != None)
440  {
441  WBUnregisterWindowCallback(wID); // no more event handling
442  WBSetWindowData(wID, 0, (void *)NULL); // window data is no longer pointing here
443  }
444 
445  // and THEN, it's safe to call the destructor on the original object.
446  pChildFrame->destructor(pChildFrame); // this should auto-delete as well
447  }
448  else
449  {
450  // TODO: should I perform a 'Destroy Notify' callback of my own?
451 
452  // NOTE: NOT calling 'WBunregisterWindowCallback()' so 'Destroy Notify' does its job. hopefully.
453  }
454 
455  // NOTE: I have to leave the tag alone at this point, to validate that it's
456  // a 'Child Frame' structure. But everything else needs to be zero'd out
457  // (I used to use 'bzero' but I'm just commenting it here, for reference)
458  // so... make sure everything that's free'd gets ZERO'd as well. this is
459  // because a 'DestroyNotify' handler that frees up the memory (and destroys
460  // any 'superclass') will probably call this function again, and it might
461  // happen asynchronously. In fact, it probably WILL happen asynchronously.
462 
463  // bzero(pChildFrame, sizeof(*pChildFrame)); // zero it out (as a matter of course)
464 
465  // note that I do *NOT* free the WBChildFrame HERE - this simply releases all resources for it.
466  // If there is NO DESTRUCTOR, the 'Destroy Notify' handler needs to do that, or at least SOMETHING.
467  // *NOT* handling this properly can result in 'use after free' problems.
468 }
469 
470 void FWSetChildFrameMenu(WBChildFrame *pChildFrame, const char *szFocusMenu)
471 {
472  if(!pChildFrame || pChildFrame->ulTag != CHILD_FRAME_TAG)
473  {
474  WB_ERROR_PRINT("ERROR: %s - pChildFrame not valid\n", __FUNCTION__);
475 
476  return;
477  }
478 
479  if(pChildFrame->pszMenuResource)
480  {
481  WBFree(pChildFrame->pszMenuResource);
482  }
483 
484  if(szFocusMenu)
485  {
486  pChildFrame->pszMenuResource = WBCopyString(szFocusMenu);
487  }
488  else
489  {
490  pChildFrame->pszMenuResource = NULL;
491  }
492 
493 }
494 
495 void FWSetChildFrameContextMenuID(WBChildFrame *pChildFrame, int nID)
496 {
497  if(!pChildFrame || pChildFrame->ulTag != CHILD_FRAME_TAG)
498  {
499  WB_ERROR_PRINT("ERROR: %s - pChildFrame not valid\n", __FUNCTION__);
500 
501  return;
502  }
503 
504  pChildFrame->iContextMenuID = nID;
505 }
506 
507 void FWSetChildFrameMenuHandlers(WBChildFrame *pChildFrame, const WBFWMenuHandler *pHandlerArray)
508 {
509  if(!pChildFrame || pChildFrame->ulTag != CHILD_FRAME_TAG)
510  {
511  WB_ERROR_PRINT("ERROR: %s - pChildFrame not valid\n", __FUNCTION__);
512 
513  return;
514  }
515 
516  if(pChildFrame->pMenuHandler)
517  {
518  WBFree(pChildFrame->pMenuHandler);
519  }
520 
521  if(pHandlerArray)
522  {
523  const WBFWMenuHandler *pH;
524  int iN;
525 
526  // count the number of entries in the menu handler
527  for(iN=0, pH = pHandlerArray; pH->lMenuID || pH->callback || pH->UIcallback; iN++, pH++)
528  {
529  // NOTHING inside the loop. just count.
530  }
531 
532  // allocate space and make a copy
533 
534  pChildFrame->pMenuHandler = (WBFWMenuHandler *)WBAlloc(sizeof(WBFWMenuHandler)
535  * (iN + 1
536  + sizeof(aChildFrameMenuHandler)
537  / sizeof(aChildFrameMenuHandler[0])
538  )
539  );
540 
541  if(pChildFrame->pMenuHandler)
542  {
543  if(iN > 0)
544  {
545  memcpy(pChildFrame->pMenuHandler, pHandlerArray,
546  sizeof(WBFWMenuHandler) * iN);
547  }
548 
549  // this adds MY menu default handlers to the end of the list
550  // so it's possible to override them, if the owner wants to
551 
552  memcpy(pChildFrame->pMenuHandler + iN,
553  aChildFrameMenuHandler,
554  sizeof(aChildFrameMenuHandler)); // this includes the NULL entry at the end
555  }
556  }
557  else
558  {
559  pChildFrame->pMenuHandler = NULL;
560  }
561 }
562 
563 void FWSetChildFrameDisplayName(WBChildFrame *pChildFrame, const char *szDisplayName)
564 {
565  if(!pChildFrame || pChildFrame->ulTag != CHILD_FRAME_TAG)
566  {
567  WB_ERROR_PRINT("ERROR: %s - pChildFrame not valid\n", __FUNCTION__);
568 
569  return;
570  }
571 
572  if(pChildFrame->szDisplayName)
573  {
574  WBFree(pChildFrame->szDisplayName);
575  }
576 
577  if(!szDisplayName)
578  {
579  return;
580  }
581 
582  pChildFrame->szDisplayName = WBCopyString(szDisplayName);
583 }
584 
585 void FWSetChildFrameImageAtom(WBChildFrame *pChildFrame, Atom aImage)
586 {
587  if(!pChildFrame || pChildFrame->ulTag != CHILD_FRAME_TAG)
588  {
589  WB_ERROR_PRINT("ERROR: %s - pChildFrame not valid\n", __FUNCTION__);
590 
591  return;
592  }
593 
594  pChildFrame->aImageAtom = aImage;
595 }
596 
597 
598 #if 0 // this function probably won't be used nor implemented; left anyway (reserved)
599 static void InternalSetChildFrameScrollInfo(WBChildFrame *pChildFrame, int iRow, int iMaxRow, int iCol, int iMaxCol,
600  int iRowHeight, int iColWidth)
601 {
602 
603 // NOTE: iTop, iHeight, etc. are "cached" values. use scroll [, iSplit, and scrollSplit] as "official" values
604 
605 // int iTop;
606 // // cached 0-based position of the top of the current viewport (in lines or pixels)
607 // int iHeight;
608 // // cached 0-based height of the current viewport (in lines or pixels)
609 // int iLeft;
610 // // cached 0-based position of the left of the current viewport (in characters or pixels)
611 // int iWidth;
612 // // cached 0-based width of the current viewport (in characters or pixels)
613 //
614 // int iXExtent;
615 // // cached X extent for the display surface (determines scrolling behavior)
616 // int iYExtent;
617 // // cached Y extent for the display surface (determines scrolling behavior)
618 //
619 // WB_SCROLLINFO scroll;
620 // // 'scroll info' (horizontal and vertical min/max/pos and other details)
621 //
622 // int iSplit;
623 // // reserved - position for 'split' (-1 for 'no split')
624 //
625 // WB_SCROLLINFO scrollSplit;
626 // // reserved - 'scroll info' for 'split' area (implementation-defined)
627 //
628 
629 // So, if the window/viewport is too small for the document extents, then I need scrollbars
630 
631 
632 
633 
634 }
635 #endif // 0
636 
637 void FWSetChildFrameExtent(WBChildFrame *pChildFrame, int iXExtent, int iYExtent)
638 {
639  if(!pChildFrame || pChildFrame->ulTag != CHILD_FRAME_TAG)
640  {
641  WB_ERROR_PRINT("ERROR: %s - pChildFrame not valid\n", __FUNCTION__);
642 
643  return;
644  }
645 
646 
647 
648 
649  // NOTE: see (and maybe call something *like* it) FWChildFrameRecalcLayout, below
650 
651  FWChildFrameRecalcLayout(pChildFrame); // for now, do it [later change mind?]
652 }
653 
654 
655 // this function calculates 'pChildFrame->geom' correctly
656 static void InternalChildFrameRecalcGeom(WBChildFrame *pChildFrame, int bResize)
657 {
658 WBFrameWindow *pOwner;
659 Display *pDisplay;
660 int iL, iT, iW, iH;
661 int nL, nL2, nC, nC2;
662 
663 
664  pDisplay = WBGetWindowDisplay(pChildFrame->wID);
665  pOwner = pChildFrame->pOwner;
666 
667  if(!pOwner) // irrelevant if NULL. TODO: properly validate this (anal retentive if DEBUG build)
668  {
669  WB_ERROR_PRINT("ERROR: %s - pOwner is NULL for Child Frame\n", __FUNCTION__);
670 
671  return;
672  }
673 
674  iL = pOwner->iClientX;
675  iT = pOwner->iClientY;
676  iW = pOwner->iClientWidth;
677  iH = pOwner->iClientHeight;
678 
679  if(bResize) // I called this because I resized the owner window
680  {
681  // resize the window accordingly
682  XMoveWindow(pDisplay, pChildFrame->wID, iL, iT);
683  XResizeWindow(pDisplay, pChildFrame->wID, iW - 2, iH - 2); // allow 1 pixel for border
684  }
685 
686  // calculate new client 'geom', backing out 2 additional pixels in all 4 directions
687 
688  pChildFrame->geom.x = 2;
689  pChildFrame->geom.y = 2;
690  pChildFrame->geom.width = iW - 6;
691  pChildFrame->geom.height = iH - 6; // the new width/height of client area
692 
693  // cache this value for later, when I paint
694  memcpy(&(pChildFrame->geomEntire), &(pChildFrame->geom), sizeof(pChildFrame->geomEntire));
695 
696  // NEXT, calculate the total height in rows, and width in cols, and determine whether
697  // the scroll bars need to be made visible.
698 
699  if(pChildFrame->iRowHeight <= 0 || pChildFrame->iColWidth <= 0)
700  {
701  nL2 = WBTextObjectCalculateLineHeight(WBFontSetAscent(pDisplay, pChildFrame->rFontSet),
702  WBFontSetDescent(pDisplay, pChildFrame->rFontSet));
703  nC2 = WBFontSetAvgCharWidth(pDisplay, pChildFrame->rFontSet);
704 
705  if(nL2 < 0)
706  {
707  nL2 = 16; // for now just use this
708  }
709  if(nC2 < 0)
710  {
711  nC2 = 8; // for now just use this
712  }
713 // pChildFrame->iRowHeight = nL2; // TODO: do this?
714 // pChildFrame->iColWidth = nC2; // TODO: do this?
715  }
716  else
717  {
718  nL2 = pChildFrame->iRowHeight;
719  nC2 = pChildFrame->iColWidth;
720  }
721 
722  nL = pChildFrame->geom.height - nL2 - 4; // the size if there were scroll bars
723  nC = pChildFrame->geom.width - nC2 - 4;
724 
725  nL /= nL2; // total number of lines displayed (if scroll bars present)
726  nC /= nC2; // total number of columns displayed (if scroll bars present)
727 
728  if((nL > 0 && nL <= pChildFrame->extent.height) || // # lines on screen > 0 and less than the extent's height?
729  (nC > 0 && nC <= pChildFrame->extent.width)) // # cols on screen > 0 and less than the extent's width?
730  {
731  // set up the scroll bar ranges correctly
732 
733  if(nC > 0 && nC <= pChildFrame->extent.width)
734  {
735  WBSetHScrollRange(&(pChildFrame->scroll), 0, pChildFrame->extent.width); // use entire width for range
736  }
737  else
738  {
739  WBSetHScrollRange(&(pChildFrame->scroll), 0, 0); // disabled
740  }
741 
742  if((nL - 2) < pChildFrame->extent.height) // brings vert scroll into place if H scroll came into place
743  {
744  if(WBSetVScrollRange(&(pChildFrame->scroll), 0,
745  pChildFrame->extent.height - (nL - 2))) // 2 extra line - scroll is for the top
746  {
747  nC--; // subtract an extra column when VScroll is visible
748 
749 reset_hscroll_range:
750  // if I changed the vscroll info, use this to re-set the hscroll info
751 
752  if(nC > 0 && nC <= pChildFrame->extent.width)
753  {
754  WBSetHScrollRange(&(pChildFrame->scroll), 0, pChildFrame->extent.width); // use entire width for range
755  }
756  else
757  {
758  WBSetHScrollRange(&(pChildFrame->scroll), 0, 0); // disabled
759  }
760  }
761  }
762  else
763  {
764  if(WBSetVScrollRange(&(pChildFrame->scroll), 0, 0)) // disable vertical scrollbar
765  {
766  goto reset_hscroll_range;
767  }
768  }
769 
770  // set the HPos and VPos based on what's currently visible (upper left corner)
771 
772  pChildFrame->scroll.iHPos = pChildFrame->origin.x;
773  pChildFrame->scroll.iVPos = pChildFrame->origin.y;
774  }
775  else
776  {
777  WBSetHScrollRange(&(pChildFrame->scroll), 0, 0); // thus disabling them
778  WBSetVScrollRange(&(pChildFrame->scroll), 0, 0);
779  }
780 
781  // TODO: anything ELSE that I need to do when re-calculating the layout, scrollbars, whatever
782  // just apply that to geom so that it reflects the correct viewpoirt in pixels
783  // minus any border, decorations, scrollbars, whatever, with 0,0 being top,left
784  // for the window [in this case, border is 1 pixel already]
785 
786 
787 
788  // TODO: if I need to show scrollbars, subtract height/width of bar (plus border) from
789  // the geometry width and height, as needed
790 
791 
792  WBUpdateScrollBarGeometry(&(pChildFrame->scroll), pChildFrame->rFontSet, // for now do this
793  &(pChildFrame->geom), &(pChildFrame->geom));
794 }
795 
796 void FWSetChildFrameScrollInfo(WBChildFrame *pChildFrame, int iRow, int iMaxRow, int iCol, int iMaxCol,
797  int iRowHeight, int iColWidth)
798 {
799  if(!pChildFrame || pChildFrame->ulTag != CHILD_FRAME_TAG)
800  {
801  WB_ERROR_PRINT("ERROR: %s - pChildFrame not valid\n", __FUNCTION__);
802 
803  return;
804  }
805 
806  pChildFrame->origin.y = iRow;
807  pChildFrame->origin.x = iCol;
808 
809  pChildFrame->extent.width = iMaxCol;
810  pChildFrame->extent.height = iMaxRow;
811  pChildFrame->iRowHeight = iRowHeight;
812  pChildFrame->iColWidth = iColWidth;
813 
814  // NOTE: this function must *NOT* call FWChildFrameRecalcLayout, nor FWSetChildFrameExtent, in
815  // order to prevent problems with recursion. Instead, it must 'nuke out' (aka 'derive')
816  // all of those things, independently.
817 
818  InternalChildFrameRecalcGeom(pChildFrame, 0); // re-calculate geom but do NOT re-size window
819 
820  // Need for scroll bars (and window shrinkage) was determined by InternalChildFrameRecalcGeom().
821 
822  // at this point the scroll bars will be correctly drawn, and the display area appropriately "shrunk"
823  // when re-painting the client area, using 'pChildFrame->extent' and 'pChildFrame->geom'.
824 
825 
826 
827  // FINALLY, auto-scroll iRow and iCol into view [as needed]
828 
829 
830  WB_WARN_PRINT("TODO: %s - implement. %p %u (%08xH) %d, %d, %d, %d, %d, %d\n", __FUNCTION__,
831  pChildFrame, (int)pChildFrame->wID, (int)pChildFrame->wID,
832  iRow, iMaxRow, iCol, iMaxCol, iRowHeight, iColWidth);
833 }
834 
835 
836 
838 {
839  if(!pChildFrame || pChildFrame->ulTag != CHILD_FRAME_TAG)
840  {
841  WB_ERROR_PRINT("ERROR: %s - pChildFrame not valid\n", __FUNCTION__);
842 
843  return;
844  }
845 
846  // before I begin, recalculate the geometry and account for scroll bars
847 
848  InternalChildFrameRecalcGeom(pChildFrame, 1); // re-calculate geom and re-size window
849 
850  // TODO:
851  // pChildFrame->iLeft = iL converted to correct units and scrolled;
852  // pChildFrame->iTop = iT converted to correct units and scrolled;
853  // pChildRrame->iWidth = iW converted to correct units;
854  // pChildFrame->iHeight = iH converted to correct units;
855 
856 
857  // NOW, tell the user callback function (if any) what's happening.
858  // I must assume that the owning frame is valid and has already re-calc'd its layout
859 
860  if(pChildFrame->pUserCallback)
861  {
862  Display *pDisplay;
863  XClientMessageEvent evt;
864 
865  pDisplay = WBGetWindowDisplay(pChildFrame->wID);
866 
867  bzero(&evt, sizeof(evt));
868  evt.type = ClientMessage;
869 
870  evt.display = pDisplay;
871  evt.window = pChildFrame->wID;
872  evt.message_type = aRESIZE_NOTIFY;
873  evt.format = 32; // always
874  evt.data.l[0] = pChildFrame->geom.x; // left
875  evt.data.l[1] = pChildFrame->geom.y; // top
876  evt.data.l[2] = pChildFrame->geom.x + pChildFrame->geom.width; // right
877  evt.data.l[3] = pChildFrame->geom.y + pChildFrame->geom.height; // bottom
878 
879  // required implementation. superclass must process this and fix up scroll info
880  pChildFrame->pUserCallback(evt.window, (XEvent *)&evt);
881  }
882 
883  // TODO: fix the scrollbars and invalidate rectangles
884 
885  WBInvalidateRect(pChildFrame->wID, NULL, 1); // for now, do this
886 
887 }
888 
890 {
891  if(!pChildFrame || pChildFrame->ulTag != CHILD_FRAME_TAG)
892  {
893  WB_ERROR_PRINT("ERROR: %s - pChildFrame not valid\n", __FUNCTION__);
894 
895  return;
896  }
897 
898  // for now, don't mess with the tabs, just set the text
899  // later, I may need to store the tab info.
900 
901  FWSetStatusText(pChildFrame->pOwner, pChildFrame->szStatusText);
902 }
903 
904 
906 {
907 Display *pDisplay;
908 XClientMessageEvent evt;
909 
910 
911  if(!pChildFrame || pChildFrame->ulTag != CHILD_FRAME_TAG)
912  {
913  WB_ERROR_PRINT("ERROR: %s - pChildFrame not valid\n", __FUNCTION__);
914 
915  return -1; // an error
916  }
917 
918  if(!pChildFrame->pUserCallback)
919  {
920  return 0; // return 'ok to close' when there's no 'user callback' function to query
921  }
922 
923  pDisplay = WBGetWindowDisplay(pChildFrame->wID);
924 
925  bzero(&evt, sizeof(evt));
926  evt.type = ClientMessage;
927 
928  evt.display = pDisplay;
929  evt.window = pChildFrame->wID;
930  evt.message_type = aQUERY_CLOSE;
931  evt.format = 32; // always
932 
933  return pChildFrame->pUserCallback(evt.window, (XEvent *)&evt);
934 }
935 
936 
937 // DEFAULT WINDOW EVENT HANDLER FOR CHILD FRAME
938 
939 int FWChildFrameEvent(Window wID, XEvent *pEvent)
940 {
941 int iRval = 0;
942 WBChildFrame *pC;
943 WBFrameWindow *pFW;
944 Display *pDisplay;
945 #ifndef NO_DEBUG
946 char tbuf[32]; // for keyboard input
947 int nChar = sizeof(tbuf);
948 #endif // NO_DEBUG
949 
950 
951  pDisplay = WBGetWindowDisplay(wID);
952  pC = FWGetChildFrameStruct(wID);
953 
954  if(!pC)
955  {
956 #ifndef NO_DEBUG
957  WB_ERROR_PRINT("ERROR: %s - no child frame structure, window data is %p\n", __FUNCTION__, WBGetWindowData(wID, 0));
958 
959  WBDebugDumpEvent(pEvent);
960 #endif // NO_DEBUG
961 
962  return 0;
963  }
964 
965  pFW = pC->pOwner; // make sure I know my owning frame window
966 
967  // if I have visible scroll bars, paint them on 'Expose'
968  if(pEvent->type == Expose)
969  {
970  WB_GEOM geomTemp;
971  GC gc;
972  XColor clrBG;
973 
974  // first, horizontal bar
975  geomTemp.x = pC->geom.x;
976  geomTemp.y = pC->geom.y + pC->geom.height;
977  geomTemp.width = pC->geom.width;
978  geomTemp.height = pC->geomEntire.height - pC->geom.height;
979 
980  if(geomTemp.width > 0 && geomTemp.height > 0)
981  {
982  gc = WBBeginPaintGeom(pC->wID, &geomTemp);
983 
984  if(gc != None)
985  {
986  WBPaintHScrollBar(&(pC->scroll), pDisplay, wID, gc, &(pC->geomEntire));
987  WBEndPaint(wID, gc);
988  }
989  }
990 
991  // then, vertical bar
992  geomTemp.x = pC->geom.x + pC->geom.width;
993  geomTemp.y = pC->geom.y;
994  geomTemp.width = pC->geomEntire.width - pC->geom.width;
995  geomTemp.height = pC->geom.height;
996 
997  if(geomTemp.width > 0 && geomTemp.height > 0)
998  {
999  gc = WBBeginPaintGeom(pC->wID, &geomTemp);
1000 
1001  if(gc != None)
1002  {
1003  WBPaintVScrollBar(&(pC->scroll), pDisplay, wID, gc, &(pC->geomEntire));
1004  WBEndPaint(wID, gc);
1005  }
1006  }
1007 
1008  // finally, if both bars are visible, I need to paint the square in the lower
1009  // right-hand corner. I'll use the frame background default color for that
1010 
1011  geomTemp.x = pC->geom.x + pC->geom.width;
1012  geomTemp.y = pC->geom.y + pC->geom.height;
1013  geomTemp.width = pC->geomEntire.width - pC->geom.width;
1014  geomTemp.height = pC->geomEntire.height - pC->geom.height;
1015 
1016  if(geomTemp.width > 0 && geomTemp.height > 0)
1017  {
1018  clrBG = FWGetDefaultBG();
1019 
1020  gc = WBBeginPaintGeom(pC->wID, &geomTemp);
1021 
1022  if(gc != None)
1023  {
1024  XSetForeground(pDisplay, gc, clrBG.pixel);
1025  XSetBackground(pDisplay, gc, clrBG.pixel);
1026 
1027  XFillRectangle(pDisplay, wID, gc, geomTemp.x, geomTemp.y, geomTemp.width, geomTemp.height);
1028 
1029  WBEndPaint(wID, gc);
1030  }
1031  }
1032  }
1033  else if(pEvent->type == ClientMessage)
1034  {
1035  iRval = WBScrollBarEvent(wID, pEvent, &(pC->scroll));
1036 
1037  if(iRval)
1038  {
1039  return iRval; // return whatever 'WBScrollBarEvent' says to return
1040  }
1041  }
1042 
1043  // TODO: messages I handle myself, before any user callbacks
1044  // (and perhaps messages that I don't pass to the callback at all)
1045 
1046  if(pC->pUserCallback)
1047  {
1048  iRval = pC->pUserCallback(wID, pEvent);
1049  }
1050 
1051 
1052  // TODO: menu and menu UI handler? For now, no. rely on frame window.
1053 
1054  if(pEvent->type == ClientMessage &&
1055  (pEvent->xclient.message_type == aMENU_COMMAND ||
1056  pEvent->xclient.message_type == aMENU_UI_COMMAND))
1057  {
1058  // TODO: special handling?
1059 
1060  return iRval; // default behavior for these
1061  }
1062 
1064  // //
1065  // _____ _ ___ __ __ _____ _ _ _ _ _ ____ _____ ___ __ __ _ _____ ___ ___ _ _ //
1066  // | ___|/ | / _ \ | \/ || ____|| \ | || | | | / \ / ___||_ _||_ _|\ \ / // \ |_ _||_ _|/ _ \ | \ | | //
1067  // | |_ | || | | | | |\/| || _| | \| || | | | / _ \ | | | | | | \ \ / // _ \ | | | || | | || \| | //
1068  // | _| | || |_| | | | | || |___ | |\ || |_| | / ___ \| |___ | | | | \ V // ___ \ | | | || |_| || |\ | //
1069  // |_| |_| \___/ |_| |_||_____||_| \_| \___/ /_/ \_\\____| |_| |___| \_//_/ \_\|_| |___|\___/ |_| \_| //
1070  // //
1071  // //
1073 
1074  // checking for menu activation
1075 
1076  if(!iRval && !pFW &&
1077  pEvent->type == ClientMessage &&
1078  pEvent->xclient.message_type == aWB_CHAR &&
1079  pEvent->xclient.data.l[0] == XK_F10 && // keystroke is F10
1080  (pEvent->xclient.data.l[1] & WB_KEYEVENT_KEYSYM))
1081  {
1082  // activate the menu in the owning frame (if there is one) or display a popup
1083 
1084  Window wIDMenu = WBGetMenuWindow(pFW->wID);
1085 
1086  int iACS = (int)pEvent->xclient.data.l[1] & WB_KEYEVENT_ACSMASK;
1087 
1088  if(iACS == WB_KEYEVENT_SHIFT)
1089  {
1090  // send a command to pop up the context menu
1091 
1092  return 1; // handled
1093  }
1094  else if(!iACS) // no ctrl+alt+shift
1095  {
1096  if(wIDMenu)
1097  {
1098  // send command to pop up the frame's menu
1099 
1100  XClientMessageEvent evt;
1101 
1102  // post a high-priority message to myself to display the menu
1103 
1104  bzero(&evt, sizeof(evt));
1105  evt.type = ClientMessage;
1106  evt.display = WBGetWindowDisplay(wIDMenu);
1107  evt.window = wIDMenu;
1108  evt.message_type = aMENU_ACTIVATE;
1109  evt.format = 32;
1110  evt.data.l[0] = 0;
1111  evt.data.l[1] = 0;
1112 
1113  WBPostPriorityEvent(wIDMenu, (XEvent *)&evt);
1114 
1115  WB_DEBUG_PRINT(DebugLevel_Chatty | DebugSubSystem_Menu | DebugSubSystem_Frame,
1116  "%s - posting client event message to display menu\n", __FUNCTION__);
1117 
1118  return 1; // handled
1119  }
1120  }
1121  }
1122 
1123 
1124  // regardless, for a 'DestroyNotify, assign wID to 'None' in the ChildFrame class
1125 
1126  if(!iRval)
1127  {
1128  // TODO: default handling of messages NOT handled by user callback
1129 
1130  switch(pEvent->type)
1131  {
1132  case KeyPress:
1133  {
1134 #ifndef NO_DEBUG
1135  int iACS = 0;
1136  int iKey = WBKeyEventProcessKey((XKeyEvent *)pEvent, tbuf, &nChar, &iACS);
1137 
1138  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_Frame | DebugSubSystem_Keyboard,
1139  "%s KEY PRESS for KEY %d KEYCODE %d MASK=%d (%xH)\n",
1140  __FUNCTION__, iKey, ((XKeyEvent *)pEvent)->keycode,
1141  ((XKeyEvent *)pEvent)->state, ((XKeyEvent *)pEvent)->state);
1142 #endif // NO_DEBUG
1143 
1144  // check for menu and hotkey activation.
1145 // if(nChar > 0) // only for "real" characters (i.e. not just the ALT key)
1146  if(pFW)
1147  {
1149 
1150  if(pMenuBar) // menu bar exists?
1151  {
1152  WB_DEBUG_PRINT(DebugLevel_Excessive | DebugSubSystem_Menu | DebugSubSystem_Frame | DebugSubSystem_Keyboard,
1153  "%s call to MBMenuProcessHotKey for menu window %d (%08xH)\n",
1154  __FUNCTION__, (int)pMenuBar->wSelf, (int)pMenuBar->wSelf);
1155 
1156  iRval = MBMenuProcessHotKey(pMenuBar->pMenu, (XKeyEvent *)pEvent);
1157  }
1158  }
1159  }
1160  break;
1161 
1162  case KeyRelease:
1163  {
1164  // KeyRelease
1165 #ifndef NO_DEBUG
1166  int iACS = 0, iKey = WBKeyEventProcessKey((XKeyEvent *)pEvent, tbuf, &nChar, &iACS);
1167 
1168  if(nChar > 0)
1169  {
1170  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_Frame | DebugSubSystem_Keyboard,
1171  "%s KEY RELEASE for KEY %d KEYCODE %d MASK=%d (%xH)\n",
1172  __FUNCTION__, iKey, ((XKeyEvent *)pEvent)->keycode,
1173  ((XKeyEvent *)pEvent)->state, ((XKeyEvent *)pEvent)->state);
1174 
1175  }
1176 #endif // NO_DEBUG
1177 
1178  }
1179 
1180  break;
1181 
1182  case ClientMessage:
1183  if(pEvent->xclient.message_type == aWB_CHAR) // generated by WBDefault
1184  {
1185  if(pC->pUI)
1186  {
1187  iRval = ChildFrameDoCharEvent(&pEvent->xclient, WBGetWindowDisplay(wID), wID, pC, pC->pUI);
1188  }
1189 // else
1190 // {
1191 // WB_ERROR_PRINT("TEMPORARY: %s - WB_CHAR, no UI\n", __FUNCTION__);
1192 // WBDebugDumpEvent((XEvent *)pEvent);
1193 // }
1194  }
1195  else if(pEvent->xclient.message_type == aWB_POINTER) // generated by WBDefault
1196  {
1197  if(pC->pUI)
1198  {
1199  iRval = ChildFrameDoPointerEvent(&pEvent->xclient, WBGetWindowDisplay(wID), wID, pC, pC->pUI);
1200  }
1201 // else
1202 // {
1203 // WB_ERROR_PRINT("TEMPORARY: %s - WB_POINTER, no UI\n", __FUNCTION__);
1204 // WBDebugDumpEvent((XEvent *)pEvent);
1205 // }
1206  }
1207  else if(pEvent->xclient.message_type == aSCROLL_NOTIFY) // generated by WBScrollBarEvent()
1208  {
1209  if(pC->pUI)
1210  {
1211  iRval = ChildFrameDoScrollEvent(&pEvent->xclient, WBGetWindowDisplay(wID), wID, pC, pC->pUI);
1212  }
1213 // else
1214 // {
1215 // WB_ERROR_PRINT("TEMPORARY: %s - SCROLL_NOTIFY, no UI\n", __FUNCTION__);
1216 // WBDebugDumpEvent((XEvent *)pEvent);
1217 // }
1218  }
1219 
1220  break;
1221  }
1222  }
1223 
1224 
1225  if(pEvent->type == DestroyNotify &&
1226  pEvent->xdestroywindow.window == wID)
1227  {
1228  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_Frame,
1229  "%s - DestroyNotify\n", __FUNCTION__);
1230 
1231  if(!iRval)
1232  {
1233  WB_ERROR_PRINT("TEMPORARY: %s - DestroyNotify *NOT* handled by superclass\n", __FUNCTION__);
1234  }
1235 
1236  pC = FWGetChildFrameStruct(wID); // re-get the structure (it may have been deleted, probably SHOULD have been)
1237 
1238  if(pC && pC->wID != None) // haven't called FWDestroyChildFrame yet?
1239  {
1240  // mark window ID 'None', then call FWDestroyChildFrame from here
1241  // by design it's safe to do that...
1242 
1243  pC->wID = None; // since window already 'destroyed' - I'm getting the notification after all
1244 
1245  // set the window callback to NULL - this disconnects me from the message processor also
1246  // as well as freeing up everything
1247 
1248  FWDestroyChildFrame(pC); // make sure it's destroyed, unlinked, etc. (pointer may not be valid now)
1249 
1250  WB_ERROR_PRINT("TEMPORARY: %s - DestroyNotify handled by Child Window base class\n", __FUNCTION__);
1251  }
1252 
1253  WBUnregisterWindowCallback(wID); // prevents any more messages from being dispatched to this function
1254 
1255  WB_DEBUG_PRINT(DebugLevel_ERROR/*DebugLevel_Verbose | DebugSubSystem_Event | DebugSubSystem_Frame*/,
1256  "%s - child frame window destroyed\n", __FUNCTION__);
1257  return 1;
1258  }
1259 
1260 
1261  return iRval;
1262 }
1263 
1264 
1265 static int ChildFrameDoPointerEvent(XClientMessageEvent *pEvent, Display *pDisplay,
1266  Window wID, WBChildFrame *pC, WBChildFrameUI *pUI)
1267 {
1268 int iACS;
1269 int iX, iY;
1270 int iButtonMask;
1271 
1272 
1273  if(wID == None || !pC || !pUI ||
1274  pEvent->type != ClientMessage ||
1275  pEvent->message_type != aWB_POINTER)
1276  {
1277  return 0; // sanity check (temporary?)
1278  }
1279 
1280 //#ifndef NO_DEBUG
1281 // WB_ERROR_PRINT("TEMPORARY: %s - WB_POINTER\n", __FUNCTION__);
1282 // WBDebugDumpEvent((XEvent *)pEvent);
1283 //#endif // NO_DEBUG
1284 
1285 
1286  // left-click - position cursor, cancel selection
1287  // shift-left-click - select from cursor to THIS point
1288  // (other modifiers, ignore the modifier key)
1289  // right-click - drop-down edit menu
1290  // middle click - select word? paste?
1291  // scroll wheel up/down - should be handled by scrollbar thingy
1292  // left-drag - select from starting position
1293  // right-drag - drag/drop?
1294  // middle-drag - ?
1295 
1296  iButtonMask = pEvent->data.l[1]; // WB_POINTER_BUTTON1 through WB_POINTER_BUTTON5 (bitmask)
1297 
1298  iACS = pEvent->data.l[2];
1299 
1300  iX = pEvent->data.l[3];
1301  iY = pEvent->data.l[4];
1302 
1303  WB_DEBUG_PRINT(DebugLevel_Medium | DebugSubSystem_Mouse | DebugSubSystem_Frame | DebugSubSystem_Event,
1304  "INFO: %s EVENT=%lu (%08lxH) iButtonMask=%x iACS=%x iX=%d iY=%d\n",
1305  __FUNCTION__, (unsigned long)pEvent->data.l[0], (unsigned long)pEvent->data.l[0],
1306  iButtonMask, iACS, iX, iY);
1307 
1308  switch(pEvent->data.l[0])
1309  {
1310  case WB_POINTER_CLICK:
1311  if(pUI->mouse_click)
1312  {
1313  pUI->mouse_click(pC, iX, iY, iButtonMask, iACS);
1314  return 1; // handled
1315  }
1316 
1317  break;
1318 
1319  case WB_POINTER_DBLCLICK:
1320  if(pUI->mouse_dblclick)
1321  {
1322  pUI->mouse_dblclick(pC, iX, iY, iButtonMask, iACS);
1323  return 1; // handled
1324  }
1325 
1326  break;
1327 
1328  case WB_POINTER_DRAG:
1329  if(pUI->mouse_drag)
1330  {
1331  pUI->mouse_drag(pC, iX, iY, iButtonMask, iACS);
1332 
1333  return wID; // do this to support pointer drag (it sets up a few things correctly)
1334  // NOTE: if the function isn't NULL it's expected to perform the correct operation
1335  // and if there's an error, it can post a 'DRAG CANCEL' request
1336  }
1337 
1338  break;
1339 
1340  case WB_POINTER_DROP:
1341  if(pUI->mouse_drop)
1342  {
1343  pUI->mouse_drop(pC, iX, iY, iButtonMask, iACS);
1344  return 1; // handled
1345  }
1346 
1347  break;
1348 
1349  case WB_POINTER_MOVE:
1350  if(pUI->mouse_move)
1351  {
1352  pUI->mouse_move(pC, iX, iY); // assumes button/flags haven't changed since last time (useful only for drags)
1353  return 1; // handled
1354  }
1355 
1356  break;
1357 
1358  case WB_POINTER_CANCEL:
1359  if(pUI->mouse_cancel)
1360  {
1361  pUI->mouse_cancel(pC);
1362  return 1; // handled
1363  }
1364 
1365  break;
1366 
1367  case WB_POINTER_SCROLLUP:
1368  if(pUI->scroll_vert)
1369  {
1370  WB_WARN_PRINT("WARNING: %s %d - WB_POINTER_SCROLLUP\n", __FUNCTION__, __LINE__);
1371  pUI->scroll_vert(pC, 1, -1); // scroll up
1372  return 1; // handled
1373  }
1374 
1375  WB_WARN_PRINT("WARNING: %s %d - WB_POINTER_SCROLLUP (not handled)\n", __FUNCTION__, __LINE__);
1376 
1377  break;
1378 
1379  case WB_POINTER_SCROLLDOWN:
1380  if(pUI->scroll_vert)
1381  {
1382  WB_WARN_PRINT("WARNING: %s %d - WB_POINTER_SCROLLDOWN\n", __FUNCTION__, __LINE__);
1383  pUI->scroll_vert(pC, 1, 1); // scroll down
1384  return 1; // handled
1385  }
1386 
1387  WB_WARN_PRINT("WARNING: %s %d - WB_POINTER_SCROLLDOWN (not handled)\n", __FUNCTION__, __LINE__);
1388 
1389  break;
1390 
1391 
1392  default:
1393 
1394  WB_ERROR_PRINT("TEMPORARY - %s - unhandled mousie message\n", __FUNCTION__);
1395  WBDebugDumpEvent((XEvent *)pEvent);
1396 
1397  break;
1398  }
1399 
1400  return 0; // must indicate 'did not handle' if I get here
1401 }
1402 
1403 static int ChildFrameDoScrollEvent(XClientMessageEvent *pEvent, Display *pDisplay,
1404  Window wID, WBChildFrame *pC, WBChildFrameUI *pUI)
1405 {
1406  if(pEvent->data.l[0] == WB_SCROLL_VERTICAL)
1407  {
1408  WB_ERROR_PRINT("TEMPORARY: %s %d - SCROLL_NOTIFY - SCROLL_VERTICAL, %lx, %lx, %lx, %lx\n",
1409  __FUNCTION__, __LINE__,
1410  pEvent->data.l[1],
1411  pEvent->data.l[2],
1412  pEvent->data.l[3],
1413  pEvent->data.l[4]);
1414 
1415  switch(pEvent->data.l[1])
1416  {
1417  case WB_SCROLL_KNOB: // 'knob track' - knob position will be in data.l[2]
1418  if(pUI->scroll_vert)
1419  {
1420  pUI->scroll_vert(pC, 0, (int)pEvent->data.l[2]);
1421  }
1422 
1423  break;
1424 
1425  case WB_SCROLL_FORWARD: // move down, or move right
1426  if(pUI->scroll_vert)
1427  {
1428  pUI->scroll_vert(pC, 1, 1);
1429  }
1430 
1431  break;
1432 
1433  case WB_SCROLL_BACKWARD: // move up, or move left
1434  if(pUI->scroll_vert)
1435  {
1436  pUI->scroll_vert(pC, 1, -1);
1437  }
1438 
1439  break;
1440 
1441  case WB_SCROLL_PAGEFWD: // page down or page right
1442  if(pUI->pgdown)
1443  {
1444  pUI->pgdown(pC, 0);
1445  }
1446 
1447  break;
1448 
1449  case WB_SCROLL_PAGEBACK: // page up or page left
1450  if(pUI->pgup)
1451  {
1452  pUI->pgup(pC, 0);
1453  }
1454 
1455  break;
1456 
1457  case WB_SCROLL_FIRST: // scroll to first entry, i.e. home or top
1458  if(pUI->scroll_vert)
1459  {
1460  pUI->scroll_vert(pC, 0, 0);
1461  }
1462 
1463  break;
1464 
1465  case WB_SCROLL_LAST: // scroll to last entry, i.e. bottom or end
1466  if(pUI->scroll_vert)
1467  {
1468  pUI->scroll_vert(pC, 0, -1); // indicates 'end'
1469  }
1470 
1471  break;
1472 
1473  case WB_SCROLL_DBLCLICK: // double-click detection (no selection info in data.l[2])
1474  return 0; // not handled
1475 
1476  case WB_SCROLL_ABSOLUTE: // absolute scroll, to the absolute position in data.l[2]
1477  case WB_SCROLL_RELATIVE: // relative scroll, relative +/- position in data.l[2]
1478  if(pUI->scroll_vert)
1479  {
1480  pUI->scroll_vert(pC,
1481  pEvent->data.l[1] == WB_SCROLL_ABSOLUTE ? 0 : 1,
1482  (int)pEvent->data.l[2]);
1483  }
1484 
1485  break;
1486 
1487  case WB_SCROLL_NA: // generic 'NA' or 'UNDEFINED' value
1488  WB_DEBUG_PRINT(DebugLevel_WARN | DebugSubSystem_Event | DebugSubSystem_Frame | DebugSubSystem_ScrollBar,
1489  "WARNING: %s %d - SCROLL_NOTIFY - SCROLL_VERTICAL - WB_SCROLL_NA\n", __FUNCTION__, __LINE__);
1490  }
1491 
1492  return 1;
1493  }
1494  else if(pEvent->data.l[0] == WB_SCROLL_HORIZONTAL)
1495  {
1496  WB_ERROR_PRINT("TEMPORARY: %s %d - SCROLL_NOTIFY - SCROLL_HORIZONTAL, %lx, %lx, %lx, %lx\n",
1497  __FUNCTION__, __LINE__,
1498  pEvent->data.l[1],
1499  pEvent->data.l[2],
1500  pEvent->data.l[3],
1501  pEvent->data.l[4]);
1502 
1503  switch(pEvent->data.l[1])
1504  {
1505  case WB_SCROLL_KNOB: // 'knob track' - knob position will be in data.l[2]
1506  if(pUI->scroll_horiz)
1507  {
1508  pUI->scroll_horiz(pC, 0, (int)pEvent->data.l[2]);
1509  }
1510 
1511  break;
1512 
1513  case WB_SCROLL_FORWARD: // move down, or move right
1514  if(pUI->scroll_horiz)
1515  {
1516  pUI->scroll_horiz(pC, 1, 1);
1517  }
1518 
1519  break;
1520 
1521  case WB_SCROLL_BACKWARD: // move up, or move left
1522  if(pUI->scroll_horiz)
1523  {
1524  pUI->scroll_horiz(pC, 1, -1);
1525  }
1526 
1527  break;
1528 
1529  case WB_SCROLL_PAGEFWD: // page down or page right
1530  if(pUI->pgright)
1531  {
1532  pUI->pgright(pC, 0);
1533  }
1534 
1535  break;
1536 
1537  case WB_SCROLL_PAGEBACK: // page up or page left
1538  if(pUI->pgleft)
1539  {
1540  pUI->pgright(pC, 0);
1541  }
1542 
1543  break;
1544 
1545  case WB_SCROLL_FIRST: // scroll to first entry, i.e. home or top
1546  if(pUI->scroll_horiz)
1547  {
1548  pUI->scroll_horiz(pC, 0, 0);
1549  }
1550 
1551  break;
1552 
1553  case WB_SCROLL_LAST: // scroll to last entry, i.e. bottom or end
1554 // if(pUI->end)
1555 // {
1556 // pUI->end(pC, 0);
1557 // }
1558  if(pUI->scroll_horiz)
1559  {
1560  pUI->scroll_horiz(pC, 0, -1); // indicates 'end'
1561  }
1562 
1563  break;
1564 
1565  case WB_SCROLL_DBLCLICK: // double-click detection (no selection info in data.l[2])
1566  return 0; // not handled
1567 
1568  case WB_SCROLL_ABSOLUTE: // absolute scroll, to the absolute position in data.l[2]
1569  case WB_SCROLL_RELATIVE: // relative scroll, relative +/- position in data.l[2]
1570  if(pUI->scroll_horiz)
1571  {
1572  pUI->scroll_horiz(pC,
1573  pEvent->data.l[1] == WB_SCROLL_ABSOLUTE ? 0 : 1,
1574  (int)pEvent->data.l[2]);
1575  }
1576 
1577  break;
1578 
1579  case WB_SCROLL_NA: // generic 'NA' or 'UNDEFINED' value
1580  WB_DEBUG_PRINT(DebugLevel_WARN | DebugSubSystem_Event | DebugSubSystem_Frame | DebugSubSystem_ScrollBar,
1581  "WARNING: %s %d - SCROLL_NOTIFY - SCROLL_HORIZONTAL - WB_SCROLL_NA\n", __FUNCTION__, __LINE__);
1582  }
1583 
1584  return 1;
1585  }
1586 
1587  WB_ERROR_PRINT("WARNING: %s %d - SCROLL_NOTIFY not handled - %lx, %lx, %lx, %lx, %lx\n",
1588  __FUNCTION__, __LINE__,
1589  pEvent->data.l[0],
1590  pEvent->data.l[1],
1591  pEvent->data.l[2],
1592  pEvent->data.l[3],
1593  pEvent->data.l[4]);
1594 
1595  return 0;
1596 }
1597 
1598 
1599 static int ChildFrameDoCharEvent(XClientMessageEvent *pEvent, Display *pDisplay,
1600  Window wID, WBChildFrame *pC, WBChildFrameUI *pUI)
1601 {
1602 int iKey, iACS, nChar;
1603 char *pBuf;
1604 int iRval = 0;
1605 
1606 
1607  if(wID == None || !pC || !pUI ||
1608  pEvent->type != ClientMessage ||
1609  pEvent->message_type != aWB_CHAR)
1610  {
1611  return 0; // sanity check (temporary?)
1612  }
1613 
1614 //#ifndef NO_DEBUG
1615 // WB_ERROR_PRINT("TEMPORARY: %s - WB_CHAR\n", __FUNCTION__);
1616 // WBDebugDumpEvent((XEvent *)pEvent);
1617 //#endif // NO_DEBUG
1618 
1619  iKey = pEvent->data.l[0]; // result from WBKeyEventProcessKey()
1620  iACS = pEvent->data.l[1];
1621  nChar = pEvent->data.l[2];
1622  pBuf = (char *)&(pEvent->data.l[3]);
1623 
1624 
1625  if(nChar > 0) // normal ASCII characters
1626  {
1627  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
1628  "%s KEY RELEASE for KEY %d KEYCODE %d MASK=%d (%xH)\n",
1629  __FUNCTION__, iKey, ((XKeyEvent *)pEvent)->keycode,
1630  ((XKeyEvent *)pEvent)->state, ((XKeyEvent *)pEvent)->state);
1631 
1632  if(iKey == 8) // backspace
1633  {
1634  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
1635  "%s - BACKSPACE key pressed, iACS=%d (%xH)\n", __FUNCTION__, iACS, iACS);
1636 
1637  if(pUI->bkspace)
1638  {
1639  pUI->bkspace(pC, iACS);
1640  }
1641  else
1642  {
1643  XBell(pDisplay, -100);
1644  }
1645 
1646  iRval = 1;
1647  }
1648  else if(iKey == 13) // CR
1649  {
1650  // special handling for ALT+ENTER
1651  if(pUI->properties && (iACS & WB_KEYEVENT_ACSMASK) == WB_KEYEVENT_ALT)
1652  {
1653  pUI->properties(pC);
1654  }
1655  else if(pUI->enter)
1656  {
1657  pUI->enter(pC, iACS);
1658  }
1659  else if(pUI->do_char)
1660  {
1661  pUI->do_char(pC, pEvent);
1662  }
1663  else
1664  {
1665  XBell(pDisplay, -100);
1666  }
1667 
1668  iRval = 1;
1669  }
1670  else if(iKey == 10) // LF
1671  {
1672  if(pUI->do_char)
1673  {
1674  pUI->do_char(pC, pEvent);
1675  }
1676  else if(pUI->enter) // just in case, allow 'LF' to be 'ENTER' if no char handler
1677  {
1678  pUI->enter(pC, iACS);
1679  }
1680  else
1681  {
1682  XBell(pDisplay, -100);
1683  }
1684 
1685  iRval = 1;
1686  }
1687  else if(iKey == 9) // tab
1688  {
1689  if(pUI->tab)
1690  {
1691  pUI->tab(pC, iACS);
1692  }
1693  else if(pUI->do_char)
1694  {
1695  pUI->do_char(pC, pEvent); // treat tab like normal char
1696  }
1697  else
1698  {
1699  XBell(pDisplay, -100);
1700  }
1701 
1702  iRval = 1;
1703  }
1704  else if(iKey == 1) // CTRL+A
1705  {
1706  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
1707  "%s - CTRL+A key pressed, iACS=%d (%xH)\n", __FUNCTION__, iACS, iACS);
1708 
1709  if((iACS & WB_KEYEVENT_ACSMASK) == WB_KEYEVENT_CTRL) // control key will always be pressed, but no shift
1710  {
1711  if(pUI->select_all)
1712  {
1713  pUI->select_all(pC);
1714  }
1715  else
1716  {
1717  XBell(pDisplay, -100);
1718  }
1719 
1720  iRval = 1;
1721  }
1722  else
1723  {
1724  if(pUI->do_char)
1725  {
1726  pUI->do_char(pC, pEvent); // normal 'A' character
1727 
1728  iRval = 1;
1729  }
1730  }
1731  }
1732  else if(iKey == 3) // CTRL+C
1733  {
1734  if((iACS & WB_KEYEVENT_ACSMASK) == WB_KEYEVENT_CTRL) // control key will always be pressed, but no shift
1735  {
1736  if(pUI->has_selection && pUI->copy_to_cb && pUI->has_selection(pC))
1737  {
1738  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
1739  "%s - CTRL+C key pressed, iACS=%d (%xH)\n", __FUNCTION__, iACS, iACS);
1740 
1741  pUI->copy_to_cb(pC);
1742  }
1743  else
1744  {
1745  XBell(pDisplay, -100);
1746  WB_ERROR_PRINT("TEMPORARY - %s - no selection, can't 'COPY'\n", __FUNCTION__);
1747  }
1748 
1749  iRval = 1;
1750  }
1751  else
1752  {
1753  if(pUI->do_char)
1754  {
1755  pUI->do_char(pC, pEvent); // normal 'C' character
1756 
1757  iRval = 1;
1758  }
1759  }
1760  }
1761  else if(iKey == 22) // CTRL+V
1762  {
1763  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
1764  "%s - CTRL+V key pressed, iACS=%d (%xH)\n", __FUNCTION__, iACS, iACS);
1765 
1766  if((iACS & WB_KEYEVENT_ACSMASK) == WB_KEYEVENT_CTRL) // control key will always be pressed, but no shift
1767  {
1768  // TODO: check for valid clipboard selection - see if there's a clipboard owner maybe?
1769 
1770  if(pUI->paste_from_cb)
1771  {
1772  pUI->paste_from_cb(pC);
1773  }
1774 
1775  iRval = 1;
1776  }
1777  else
1778  {
1779  if(pUI->do_char)
1780  {
1781  pUI->do_char(pC, pEvent); // normal 'V' character
1782 
1783  iRval = 1;
1784  }
1785  }
1786  }
1787  else if(iKey == 24) // CTRL+X
1788  {
1789  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
1790  "%s - CTRL+X key pressed, iACS=%d (%xH)\n", __FUNCTION__, iACS, iACS);
1791 
1792  if((iACS & WB_KEYEVENT_ACSMASK) == WB_KEYEVENT_CTRL) // control key will always be pressed, but no shift
1793  {
1794  if(pUI->has_selection && pUI->cut_to_cb && pUI->has_selection(pC))
1795  {
1796  pUI->cut_to_cb(pC);
1797  }
1798  else
1799  {
1800  XBell(pDisplay, -100);
1801  }
1802 
1803  iRval = 1;
1804  }
1805  else
1806  {
1807  if(pUI->do_char)
1808  {
1809  pUI->do_char(pC, pEvent); // normal 'X' character
1810 
1811  iRval = 1;
1812  }
1813  }
1814  }
1815  else if(iKey == 26) // ctrl+Z
1816  {
1817  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
1818  "%s - CTRL+Z key pressed, iACS=%d (%xH)\n", __FUNCTION__, iACS, iACS);
1819 
1820  if((iACS & WB_KEYEVENT_ACSMASK) == WB_KEYEVENT_CTRL) // control key will always be pressed, but no shift
1821  {
1822  if(pUI->can_undo && pUI->undo && pUI->can_undo(pC))
1823  {
1824  pUI->undo(pC);
1825  }
1826  else
1827  {
1828  XBell(pDisplay, -100);
1829  }
1830 
1831  iRval = 1;
1832  }
1833  else if((iACS & WB_KEYEVENT_ACSMASK) == (WB_KEYEVENT_CTRL | WB_KEYEVENT_SHIFT)) // ctrl+shift, no alt
1834  {
1835  if(pUI->can_redo && pUI->redo && pUI->can_redo(pC))
1836  {
1837  pUI->redo(pC);
1838  }
1839  else
1840  {
1841  XBell(pDisplay, -100);
1842  }
1843 
1844  iRval = 1;
1845  }
1846  else
1847  {
1848  if(pUI->do_char)
1849  {
1850  pUI->do_char(pC, pEvent); // normal 'Z' character
1851 
1852  iRval = 1; // "handled"
1853  }
1854 
1855  // ONLY assign 'iRval' if the character was processed
1856  }
1857 
1858  // NOT assigning 'iRval' for all conditions here...
1859  }
1860  else if(iKey == '\x1b') // ESC
1861  {
1862  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
1863  "%s - ESC key pressed, iACS=%d (%xH)\n", __FUNCTION__, iACS, iACS);
1864 
1865  // cancel mousie things and 'select none'
1866 
1867  if(pUI->mouse_cancel)
1868  {
1869  pUI->mouse_cancel(pC);
1870  }
1871 
1872  if(pUI->select_none)
1873  {
1874  pUI->select_none(pC);
1875  }
1876 
1877  if(!pUI->select_none && !pUI->mouse_cancel)
1878  {
1879  XBell(pDisplay, -100);
1880  }
1881 
1882  iRval = 1;
1883  }
1884  else
1885  {
1886  if(pUI->do_char)
1887  {
1888  pUI->do_char(pC, pEvent);
1889 
1890  iRval = 1; // "handled"
1891  }
1892 
1893  // NOTE: don't call 'XBell' if I don't return "handled", and no 'do_char' means "not handled"
1894  }
1895  }
1896  else // SPECIAL characters.
1897  {
1898  if(iACS & WB_KEYEVENT_KEYSYM)
1899  {
1900  // TODO: international, 'dead' and other KEYSYM key assignments
1901 #define KEYSYM_MATCH_CURSOR_NAME(X) (iKey == XK_##X || iKey == XK_KP_##X)
1902 
1903  if(KEYSYM_MATCH_CURSOR_NAME(Home))
1904  {
1905  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
1906  "%s - Home key pressed iACS=%d (%08xH)\n", __FUNCTION__, iACS, iACS);
1907 
1908  if(pUI->home)
1909  {
1910  pUI->home(pC, iACS);
1911  }
1912 
1913  iRval = 1;
1914  }
1915  else if(KEYSYM_MATCH_CURSOR_NAME(End))
1916  {
1917  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
1918  "%s - End key pressed iACS=%d (%08xH)\n", __FUNCTION__, iACS, iACS);
1919 
1920  if(pUI->end)
1921  {
1922  pUI->end(pC, iACS);
1923  }
1924 
1925  iRval = 1;
1926  }
1927  else if(KEYSYM_MATCH_CURSOR_NAME(Left))
1928  {
1929  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
1930  "%s - Left key pressed iACS=%d (%08xH)\n", __FUNCTION__, iACS, iACS);
1931 
1932  if(pUI->leftarrow)
1933  {
1934  pUI->leftarrow(pC, iACS);
1935  }
1936 
1937  iRval = 1;
1938  }
1939  else if(KEYSYM_MATCH_CURSOR_NAME(Right))
1940  {
1941  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
1942  "%s - Right key pressed iACS=%d (%08xH)\n", __FUNCTION__, iACS, iACS);
1943 
1944  if(pUI->rightarrow)
1945  {
1946  pUI->rightarrow(pC, iACS);
1947  }
1948 
1949  iRval = 1;
1950  }
1951  else if(KEYSYM_MATCH_CURSOR_NAME(Up))
1952  {
1953  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
1954  "%s - Up key pressed iACS=%d (%08xH)\n", __FUNCTION__, iACS, iACS);
1955 
1956  if(pUI->uparrow)
1957  {
1958  pUI->uparrow(pC, iACS);
1959  }
1960 
1961  iRval = 1;
1962  }
1963  else if(KEYSYM_MATCH_CURSOR_NAME(Down))
1964  {
1965  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
1966  "%s - Down key pressed iACS=%d (%08xH)\n", __FUNCTION__, iACS, iACS);
1967 
1968  if(pUI->downarrow)
1969  {
1970  pUI->downarrow(pC, iACS);
1971  }
1972  else
1973  {
1974  XBell(pDisplay, -100);
1975  }
1976 
1977  iRval = 1;
1978  }
1979  else if(KEYSYM_MATCH_CURSOR_NAME(Page_Up))
1980  {
1981  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
1982  "%s - Page Up key pressed iACS=%d (%08xH)\n", __FUNCTION__, iACS, iACS);
1983 
1984  if(iACS & WB_KEYEVENT_CTRL) // page left
1985  {
1986  if(pUI->pgleft)
1987  {
1988  pUI->pgleft(pC, iACS /* & ~WB_KEYEVENT_CTRL */); // TODO: turn off 'ctrl' bit?
1989  }
1990  else
1991  {
1992  XBell(pDisplay, -100);
1993  }
1994 
1995  iRval = 1;
1996  }
1997  else
1998  {
1999  if(pUI->pgup)
2000  {
2001  pUI->pgup(pC, iACS);
2002  }
2003  else
2004  {
2005  XBell(pDisplay, -100);
2006  }
2007 
2008  iRval = 1;
2009  }
2010  }
2011  else if(KEYSYM_MATCH_CURSOR_NAME(Page_Down))
2012  {
2013  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
2014  "%s - Page Down key pressed iACS=%d (%08xH)\n", __FUNCTION__, iACS, iACS);
2015 
2016  if(iACS & WB_KEYEVENT_CTRL) // page right
2017  {
2018  if(pUI->pgright)
2019  {
2020  pUI->pgright(pC, iACS /* & ~WB_KEYEVENT_CTRL */); // TODO: turn off 'ctrl' bit?
2021  }
2022  else
2023  {
2024  XBell(pDisplay, -100);
2025  }
2026 
2027  iRval = 1;
2028  }
2029  else
2030  {
2031  if(pUI->pgdown)
2032  {
2033  pUI->pgdown(pC, iACS);
2034  }
2035  else
2036  {
2037  XBell(pDisplay, -100);
2038  }
2039 
2040  iRval = 1;
2041  }
2042  }
2043  else if(KEYSYM_MATCH_CURSOR_NAME(Begin)) // beginning of current line
2044  {
2045  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
2046  "%s - Beginning Of Line key pressed iACS=%d (%08xH)\n", __FUNCTION__, iACS, iACS);
2047 
2048  // treat this as 'home' key
2049 
2050  if((iACS & WB_KEYEVENT_ACSMASK) == WB_KEYEVENT_SHIFT) // shift
2051  {
2052  if(pUI->home)
2053  {
2054  pUI->home(pC, WB_KEYEVENT_SHIFT);
2055  }
2056  else
2057  {
2058  XBell(pDisplay, -100);
2059  }
2060 
2061  iRval = 1;
2062  }
2063  else if((iACS & WB_KEYEVENT_ACSMASK) == 0) // normal
2064  {
2065  if(pUI->home)
2066  {
2067  pUI->home(pC, iACS);
2068  }
2069  else
2070  {
2071  XBell(pDisplay, -100);
2072  }
2073 
2074  iRval = 1;
2075  }
2076  }
2077  else if(KEYSYM_MATCH_CURSOR_NAME(Insert)) // toggle 'insert' mode, copy, or paste
2078  {
2079  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
2080  "%s - Insert key pressed iACS=%d (%08xH)\n", __FUNCTION__, iACS, iACS);
2081 
2082  if((iACS & WB_KEYEVENT_ACSMASK) == 0) // normal
2083  {
2084  if(pUI->toggle_ins_mode)
2085  {
2086  pUI->toggle_ins_mode(pC);
2087 
2088  // TODO: update status bar text
2089  }
2090  else
2091  {
2092  XBell(pDisplay, -100);
2093  }
2094 
2095  iRval = 1;
2096  }
2097  else if((iACS & WB_KEYEVENT_ACSMASK) == WB_KEYEVENT_SHIFT) // SHIFT+insert (paste)
2098  {
2099  if(pUI->paste_from_cb)
2100  {
2101  pUI->paste_from_cb(pC);
2102  }
2103  else
2104  {
2105  XBell(pDisplay, -100);
2106  }
2107 
2108  iRval = 1;
2109  }
2110  else if((iACS & WB_KEYEVENT_ACSMASK) == WB_KEYEVENT_CTRL) // CTRL+insert (copy)
2111  {
2112  if(pUI->has_selection && pUI->copy_to_cb && pUI->has_selection(pC))
2113  {
2114  pUI->copy_to_cb(pC);
2115  }
2116  else
2117  {
2118  XBell(pDisplay, -100);
2119  }
2120 
2121  iRval = 1;
2122  }
2123  }
2124  else if(KEYSYM_MATCH_CURSOR_NAME(Delete)) // delete key (keypad may use this)
2125  {
2126  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
2127  "%s - Delete key pressed iACS=%d (%08xH)\n", __FUNCTION__, iACS, iACS);
2128 
2129  if((iACS & WB_KEYEVENT_ACSMASK) == WB_KEYEVENT_SHIFT) // shift+del (cut)
2130  {
2131  if(pUI->has_selection && pUI->cut_to_cb && pUI->has_selection(pC))
2132  {
2133  pUI->cut_to_cb(pC);
2134  }
2135  else
2136  {
2137  XBell(pDisplay, -100);
2138  }
2139 
2140  iRval = 1;
2141  }
2142  else if(iACS & WB_KEYEVENT_CTRL) // ctrl+del (??) alt+del (??) any other combo?
2143  {
2144  WB_ERROR_PRINT("TEMPORARY: %s - Delete key pressed with iACS=%d (%08xH)\n", __FUNCTION__, iACS, iACS);
2145 
2146  if(pUI->del)
2147  {
2148  pUI->del(pC, iACS);
2149  }
2150  else
2151  {
2152  XBell(pDisplay, -100);
2153  }
2154 
2155  iRval = 1; // for now handle it THIS way
2156  }
2157  else // if((iACS & WB_KEYEVENT_ACSMASK) == 0) // normal or "other flags"
2158  {
2159  if(pUI->del)
2160  {
2161  pUI->del(pC, iACS);
2162  }
2163  else
2164  {
2165  XBell(pDisplay, -100);
2166  }
2167 
2168  iRval = 1;
2169  }
2170  }
2171 #undef KEYSYM_MATCH_CURSOR_NAME
2172  else
2173  {
2174  if(pUI->scancode)
2175  {
2176  pUI->scancode(pC, pEvent);
2177 
2178  iRval = 1; // handled
2179  }
2180  else
2181  {
2182  // is it an unknown cursor key? let's find out (dump it)
2183  WB_DEBUG_PRINT(DebugLevel_WARN | DebugSubSystem_Event | DebugSubSystem_DialogCtrl | DebugSubSystem_Keyboard,
2184  "%s - CURSOR KEY? %d (%08xH) %d (%08xH)\n",
2185  __FUNCTION__, iKey, iKey, iACS, iACS);
2186 
2187  // 'iRval' left at 0 for "not handled"
2188  }
2189  }
2190  }
2191  }
2192 
2193  return 0; // "not handled"
2194 }
2195 
2196 
2197 
2198 static int ChildFrameEditCutHandler(XClientMessageEvent *pEvent)
2199 {
2200 WBChildFrame *pChildFrame;
2201 WBFrameWindow *pFrame;
2202 
2203 
2204  if(!pEvent || pEvent->window == None)
2205  {
2206  WB_ERROR_PRINT("ERROR: %s bad window or event\n", __FUNCTION__);
2207  return -1; // an error
2208  }
2209 
2210  pFrame = FWGetFrameWindowStruct(pEvent->window);
2211 
2212  if(!pFrame)
2213  {
2214  WB_ERROR_PRINT("ERROR: %s bad window (not frame window)\n", __FUNCTION__);
2215  return -1; // an error
2216  }
2217 
2218  pChildFrame = FWGetContainedWindowByIndex(pFrame, -1); // current focus window
2219 
2220  if(!pChildFrame)
2221  {
2222  WB_ERROR_PRINT("ERROR: %s - no child frame has focus\n", __FUNCTION__);
2223  return -1; // an error
2224  }
2225 
2226  if(pChildFrame->pUI && pChildFrame->pUI->has_selection && pChildFrame->pUI->cut_to_cb)
2227  {
2228  if(pChildFrame->pUI->has_selection(pChildFrame))
2229  {
2230  pChildFrame->pUI->cut_to_cb(pChildFrame);
2231 
2232  return 1; // HANDLED
2233  }
2234  }
2235 
2236  return 0; // NOT handled (but not an error)
2237 }
2238 
2239 static int ChildFrameEditCopyHandler(XClientMessageEvent *pEvent)
2240 {
2241 WBChildFrame *pChildFrame;
2242 WBFrameWindow *pFrame;
2243 
2244 
2245  if(!pEvent || pEvent->window == None)
2246  {
2247  WB_ERROR_PRINT("ERROR: %s bad window or event\n", __FUNCTION__);
2248  return -1; // an error
2249  }
2250 
2251  pFrame = FWGetFrameWindowStruct(pEvent->window);
2252 
2253  if(!pFrame)
2254  {
2255  WB_ERROR_PRINT("ERROR: %s bad window (not frame window)\n", __FUNCTION__);
2256  return -1; // an error
2257  }
2258 
2259  pChildFrame = FWGetContainedWindowByIndex(pFrame, -1); // current focus window
2260 
2261  if(!pChildFrame)
2262  {
2263  WB_ERROR_PRINT("ERROR: %s - no child frame has focus\n", __FUNCTION__);
2264  return -1; // an error
2265  }
2266 
2267  if(pChildFrame->pUI && pChildFrame->pUI->has_selection && pChildFrame->pUI->copy_to_cb)
2268  {
2269  if(pChildFrame->pUI->has_selection(pChildFrame))
2270  {
2271  pChildFrame->pUI->copy_to_cb(pChildFrame);
2272 
2273  return 1; // HANDLED
2274  }
2275  }
2276 
2277  return 0; // NOT handled (but not an error)
2278 }
2279 
2280 static int ChildFrameEditPasteHandler(XClientMessageEvent *pEvent)
2281 {
2282 WBChildFrame *pChildFrame;
2283 WBFrameWindow *pFrame;
2284 
2285 
2286  if(!pEvent || pEvent->window == None)
2287  {
2288  WB_ERROR_PRINT("ERROR: %s bad window or event\n", __FUNCTION__);
2289  return -1; // an error
2290  }
2291 
2292  pFrame = FWGetFrameWindowStruct(pEvent->window);
2293 
2294  if(!pFrame)
2295  {
2296  WB_ERROR_PRINT("ERROR: %s bad window (not frame window)\n", __FUNCTION__);
2297  return -1; // an error
2298  }
2299 
2300  pChildFrame = FWGetContainedWindowByIndex(pFrame, -1); // current focus window
2301 
2302  if(!pChildFrame)
2303  {
2304  WB_ERROR_PRINT("ERROR: %s - no child frame has focus\n", __FUNCTION__);
2305  return -1; // an error
2306  }
2307 
2308  if(pChildFrame->pUI && pChildFrame->pUI->paste_from_cb)
2309  {
2310  // TODO: check for valid clipboard contents first?? or assume 'NULL' is ok?
2311 
2312  pChildFrame->pUI->paste_from_cb(pChildFrame);
2313 
2314  return 1; // HANDLED
2315  }
2316 
2317  return 0; // NOT handled (but not an error)
2318 }
2319 
2320 static int ChildFrameEditDeleteHandler(XClientMessageEvent *pEvent)
2321 {
2322 WBChildFrame *pChildFrame;
2323 WBFrameWindow *pFrame;
2324 
2325 
2326  if(!pEvent || pEvent->window == None)
2327  {
2328  WB_ERROR_PRINT("ERROR: %s bad window or event\n", __FUNCTION__);
2329  return -1; // an error
2330  }
2331 
2332  pFrame = FWGetFrameWindowStruct(pEvent->window);
2333 
2334  if(!pFrame)
2335  {
2336  WB_ERROR_PRINT("ERROR: %s bad window (not frame window)\n", __FUNCTION__);
2337  return -1; // an error
2338  }
2339 
2340  pChildFrame = FWGetContainedWindowByIndex(pFrame, -1); // current focus window
2341 
2342  if(!pChildFrame)
2343  {
2344  WB_ERROR_PRINT("ERROR: %s - no child frame has focus\n", __FUNCTION__);
2345  return -1; // an error
2346  }
2347 
2348  if(pChildFrame->pUI && pChildFrame->pUI->has_selection && pChildFrame->pUI->delete_sel)
2349  {
2350  if(pChildFrame->pUI->has_selection(pChildFrame))
2351  {
2352  pChildFrame->pUI->delete_sel(pChildFrame);
2353 
2354  return 1; // HANDLED
2355  }
2356  }
2357 
2358  return 0; // NOT handled (but not an error)
2359 }
2360 
2361 static int ChildFrameEditSelectAllHandler(XClientMessageEvent *pEvent)
2362 {
2363 WBChildFrame *pChildFrame;
2364 WBFrameWindow *pFrame;
2365 
2366 
2367  if(!pEvent || pEvent->window == None)
2368  {
2369  WB_ERROR_PRINT("ERROR: %s bad window or event\n", __FUNCTION__);
2370  return -1; // an error
2371  }
2372 
2373  pFrame = FWGetFrameWindowStruct(pEvent->window);
2374 
2375  if(!pFrame)
2376  {
2377  WB_ERROR_PRINT("ERROR: %s bad window (not frame window)\n", __FUNCTION__);
2378  return -1; // an error
2379  }
2380 
2381  pChildFrame = FWGetContainedWindowByIndex(pFrame, -1); // current focus window
2382 
2383  if(!pChildFrame)
2384  {
2385  WB_ERROR_PRINT("ERROR: %s - no child frame has focus\n", __FUNCTION__);
2386  return -1; // an error
2387  }
2388 
2389  if(pChildFrame->pUI && pChildFrame->pUI->select_all)
2390  {
2391  pChildFrame->pUI->select_all(pChildFrame);
2392 
2393  return 1; // HANDLED
2394  }
2395 
2396  WB_ERROR_PRINT("NOT HANDLED: %s - pChildFrame->pUI = %p, select_all = %p\n",
2397  __FUNCTION__, pChildFrame->pUI,
2398  (void *)(pChildFrame->pUI ? pChildFrame->pUI->select_all : NULL));
2399 
2400  return 0; // NOT handled (but not an error)
2401 }
2402 
2403 static int ChildFrameEditSelectNoneHandler(XClientMessageEvent *pEvent)
2404 {
2405 WBChildFrame *pChildFrame;
2406 WBFrameWindow *pFrame;
2407 
2408 
2409  if(!pEvent || pEvent->window == None)
2410  {
2411  WB_ERROR_PRINT("ERROR: %s bad window or event\n", __FUNCTION__);
2412  return -1; // an error
2413  }
2414 
2415  pFrame = FWGetFrameWindowStruct(pEvent->window);
2416 
2417  if(!pFrame)
2418  {
2419  WB_ERROR_PRINT("ERROR: %s bad window (not frame window)\n", __FUNCTION__);
2420  return -1; // an error
2421  }
2422 
2423  pChildFrame = FWGetContainedWindowByIndex(pFrame, -1); // current focus window
2424 
2425  if(!pChildFrame)
2426  {
2427  WB_ERROR_PRINT("ERROR: %s - no child frame has focus\n", __FUNCTION__);
2428  return -1; // an error
2429  }
2430 
2431  if(pChildFrame->pUI && pChildFrame->pUI->select_none)
2432  {
2433  pChildFrame->pUI->select_none(pChildFrame);
2434 
2435  return 1; // HANDLED
2436  }
2437 
2438  WB_ERROR_PRINT("NOT HANDLED: %s - pChildFrame->pUI = %p, select_none = %p\n",
2439  __FUNCTION__, pChildFrame->pUI,
2440  (void *)(pChildFrame->pUI ? pChildFrame->pUI->select_none : NULL));
2441 
2442  return 0; // NOT handled (but not an error)
2443 }
2444 
2445 static int ChildFrameEditCutUIHandler(WBMenu *pMenu, WBMenuItem *pMenuItem)
2446 {
2447 Window wID;
2448 WBChildFrame *pChildFrame;
2449 WBFrameWindow *pFrame;
2450 WBMenuPopupWindow *pPopup;
2451 
2452 
2453  // pMenu essentially belongs to the frame window. determine which tab has focus, and whether
2454  // or not there's anything selected. if there is something selected, enable the menu.
2455  //
2456  // NOTE: this is called by the popup menu window itself, and so the pointer will not
2457  // be asynchronously destroyed when I call MBFindMenuPopupWindow(), nor will
2458  // the owning frame window be destroyed, either (unless someone seriously
2459  // violated the way these things are supposed to work).
2460 
2461  pPopup = MBFindMenuPopupWindow(pMenu);
2462 
2463  if(pPopup)
2464  {
2465  wID = pPopup->wOwner;
2466 
2467  if(wID != None)
2468  {
2469  pFrame = FWGetFrameWindowStruct(wID);
2470 
2471  if(pFrame)
2472  {
2473  pChildFrame = FWGetContainedWindowByIndex(pFrame, -1); // current focus window
2474 
2475  if(pChildFrame && pChildFrame->pUI && pChildFrame->pUI->has_selection)
2476  {
2477  if(pChildFrame->pUI->has_selection(pChildFrame))
2478  {
2479  return 1; // select this
2480  }
2481  }
2482  }
2483  }
2484  }
2485 
2486  return -1; // disable this menu
2487 }
2488 
2489 static int ChildFrameEditCopyUIHandler(WBMenu *pMenu, WBMenuItem *pMenuItem)
2490 {
2491 Window wID;
2492 WBChildFrame *pChildFrame;
2493 WBFrameWindow *pFrame;
2494 WBMenuPopupWindow *pPopup;
2495 
2496 
2497  // pMenu essentially belongs to the frame window. determine which tab has focus, and whether
2498  // or not there's anything selected. if there is something selected, enable the menu.
2499  //
2500  // NOTE: this is called by the popup menu window itself, and so the pointer will not
2501  // be asynchronously destroyed when I call MBFindMenuPopupWindow(), nor will
2502  // the owning frame window be destroyed, either (unless someone seriously
2503  // violated the way these things are supposed to work).
2504 
2505  pPopup = MBFindMenuPopupWindow(pMenu);
2506 
2507  if(pPopup)
2508  {
2509  wID = pPopup->wOwner;
2510 
2511  if(wID != None)
2512  {
2513  pFrame = FWGetFrameWindowStruct(wID);
2514 
2515  if(pFrame)
2516  {
2517  pChildFrame = FWGetContainedWindowByIndex(pFrame, -1); // current focus window
2518 
2519  if(pChildFrame && pChildFrame->pUI && pChildFrame->pUI->has_selection)
2520  {
2521  if(pChildFrame->pUI->has_selection(pChildFrame))
2522  {
2523  return 1; // select this
2524  }
2525  }
2526  }
2527  }
2528  }
2529 
2530  return -1; // disable this menu
2531 }
2532 
2533 static int ChildFrameEditPasteUIHandler(WBMenu *pMenu, WBMenuItem *pMenuItem)
2534 {
2535 Window wID;
2536 WBChildFrame *pChildFrame;
2537 WBFrameWindow *pFrame;
2538 WBMenuPopupWindow *pPopup;
2539 Display *pDisplay;
2540 
2541  // pMenu essentially belongs to the frame window. determine which tab has focus
2542  // THEN, determine if there's a clipboard owner, and enable if so. Disable if there
2543  // are no child frames with the focus or clipboard owners
2544  //
2545  // NOTE: this is called by the popup menu window itself, and so the pointer will not
2546  // be asynchronously destroyed when I call MBFindMenuPopupWindow(), nor will
2547  // the owning frame window be destroyed, either (unless someone seriously
2548  // violated the way these things are supposed to work).
2549 
2550  pPopup = MBFindMenuPopupWindow(pMenu);
2551 
2552  if(pPopup)
2553  {
2554  wID = pPopup->wOwner;
2555 
2556  if(wID != None)
2557  {
2558  pDisplay = WBGetWindowDisplay(wID);
2559  pFrame = FWGetFrameWindowStruct(wID);
2560 
2561  if(pFrame)
2562  {
2563  pChildFrame = FWGetContainedWindowByIndex(pFrame, -1); // current focus window
2564 
2565  if(pChildFrame && pChildFrame->pUI)
2566  {
2567  if(XGetSelectionOwner(pDisplay, aCLIPBOARD) != None ||
2568  XGetSelectionOwner(pDisplay, aPRIMARY) != None)
2569  {
2570  return 1; // there's a clipboard selection out there, waiting to be pasted
2571  }
2572  }
2573  }
2574  }
2575  }
2576 
2577  return -1; // disable this menu
2578 
2579 }
2580 
2581 static int ChildFrameEditDeleteUIHandler(WBMenu *pMenu, WBMenuItem *pMenuItem)
2582 {
2583 Window wID;
2584 WBChildFrame *pChildFrame;
2585 WBFrameWindow *pFrame;
2586 WBMenuPopupWindow *pPopup;
2587 
2588 
2589  // pMenu essentially belongs to the frame window. determine which tab has focus, and whether
2590  // or not there's anything selected. if there is something selected, enable the menu.
2591  //
2592  // NOTE: this is called by the popup menu window itself, and so the pointer will not
2593  // be asynchronously destroyed when I call MBFindMenuPopupWindow(), nor will
2594  // the owning frame window be destroyed, either (unless someone seriously
2595  // violated the way these things are supposed to work).
2596 
2597  pPopup = MBFindMenuPopupWindow(pMenu);
2598 
2599  if(pPopup)
2600  {
2601  wID = pPopup->wOwner;
2602 
2603  if(wID != None)
2604  {
2605  pFrame = FWGetFrameWindowStruct(wID);
2606 
2607  if(pFrame)
2608  {
2609  pChildFrame = FWGetContainedWindowByIndex(pFrame, -1); // current focus window
2610 
2611  if(pChildFrame && pChildFrame->pUI && pChildFrame->pUI->has_selection)
2612  {
2613  if(pChildFrame->pUI->has_selection(pChildFrame))
2614  {
2615  return 1; // select this
2616  }
2617  }
2618  }
2619  }
2620  }
2621 
2622  return -1; // disable this menu
2623 }
2624 
2625 static int ChildFrameEditSelectAllUIHandler(WBMenu *pMenu, WBMenuItem *pMenuItem)
2626 {
2627 Window wID;
2628 WBChildFrame *pChildFrame;
2629 WBFrameWindow *pFrame;
2630 WBMenuPopupWindow *pPopup;
2631 
2632 
2633  // pMenu essentially belongs to the frame window. determine which tab has focus, and whether
2634  // or not there's anything there. if there is something that CAN be selected, enable the menu.
2635  //
2636  // NOTE: this is called by the popup menu window itself, and so the pointer will not
2637  // be asynchronously destroyed when I call MBFindMenuPopupWindow(), nor will
2638  // the owning frame window be destroyed, either (unless someone seriously
2639  // violated the way these things are supposed to work).
2640 
2641  pPopup = MBFindMenuPopupWindow(pMenu);
2642 
2643  if(!pPopup)
2644  {
2645  WB_ERROR_PRINT("ERROR: %s no popup for menu %p\n", __FUNCTION__, pMenu);
2646  }
2647  else
2648  {
2649  wID = pPopup->wOwner;
2650 
2651  if(wID == None)
2652  {
2653  WB_ERROR_PRINT("ERROR: %s no owner for popup menu %p\n", __FUNCTION__, pPopup);
2654  }
2655  else
2656  {
2657  pFrame = FWGetFrameWindowStruct(wID);
2658 
2659  if(!pFrame)
2660  {
2661  WB_ERROR_PRINT("ERROR: %s no frame for window %u (%08xH)\n", __FUNCTION__, (unsigned int)wID, (unsigned int)wID);
2662  }
2663  else
2664  {
2665  pChildFrame = FWGetContainedWindowByIndex(pFrame, -1); // current focus window
2666 
2667  if(!pChildFrame || !pChildFrame->pUI)
2668  {
2669  WB_ERROR_PRINT("ERROR: %s no child frame %p or UI %p\n", __FUNCTION__,
2670  pChildFrame, pChildFrame ? pChildFrame->pUI : NULL);
2671  }
2672  else
2673  {
2674  if((pChildFrame->pUI->has_selection && pChildFrame->pUI->has_selection(pChildFrame)) ||
2675  (pChildFrame->pUI->is_empty && !pChildFrame->pUI->is_empty(pChildFrame)))
2676  {
2677  return 1; // select this
2678  }
2679  else
2680  {
2681  WB_ERROR_PRINT("TEMPORARY: %s - no selection or is empty\n", __FUNCTION__);
2682 
2683  return -1;
2684  }
2685  }
2686  }
2687  }
2688  }
2689 
2690  return -1; // disable this menu
2691 }
2692 
2693 static int ChildFrameEditSelectNoneUIHandler(WBMenu *pMenu, WBMenuItem *pMenuItem)
2694 {
2695 Window wID;
2696 WBChildFrame *pChildFrame;
2697 WBFrameWindow *pFrame;
2698 WBMenuPopupWindow *pPopup;
2699 
2700 
2701  // pMenu essentially belongs to the frame window. determine which tab has focus, and whether
2702  // or not there's anything selected. if there is something selected, enable the menu.
2703  //
2704  // NOTE: this is called by the popup menu window itself, and so the pointer will not
2705  // be asynchronously destroyed when I call MBFindMenuPopupWindow(), nor will
2706  // the owning frame window be destroyed, either (unless someone seriously
2707  // violated the way these things are supposed to work).
2708 
2709  pPopup = MBFindMenuPopupWindow(pMenu);
2710 
2711  if(pPopup)
2712  {
2713  wID = pPopup->wOwner;
2714 
2715  if(wID != None)
2716  {
2717  pFrame = FWGetFrameWindowStruct(wID);
2718 
2719  if(pFrame)
2720  {
2721  pChildFrame = FWGetContainedWindowByIndex(pFrame, -1); // current focus window
2722 
2723  if(pChildFrame && pChildFrame->pUI && pChildFrame->pUI->has_selection)
2724  {
2725  if(pChildFrame->pUI->has_selection(pChildFrame))
2726  {
2727  return 1; // select this
2728  }
2729  else
2730  {
2731  WB_ERROR_PRINT("TEMPORARY: %s - no selection\n", __FUNCTION__);
2732 
2733  return -1;
2734  }
2735  }
2736  }
2737  }
2738  }
2739 
2740  return -1; // disable this menu
2741 }
2742 
2743 
2744 
2745 
2746 static int ChildFrameEditPropertiesHandler(XClientMessageEvent *pEvent)
2747 {
2748 WBChildFrame *pChildFrame;
2749 WBFrameWindow *pFrame;
2750 
2751 
2752  if(!pEvent || pEvent->window == None)
2753  {
2754  WB_ERROR_PRINT("ERROR: %s bad window or event\n", __FUNCTION__);
2755  return -1; // an error
2756  }
2757 
2758  pFrame = FWGetFrameWindowStruct(pEvent->window);
2759 
2760  if(!pFrame)
2761  {
2762  WB_ERROR_PRINT("ERROR: %s bad window (not frame window)\n", __FUNCTION__);
2763  return -1; // an error
2764  }
2765 
2766  pChildFrame = FWGetContainedWindowByIndex(pFrame, -1); // current focus window
2767 
2768  if(!pChildFrame)
2769  {
2770  WB_ERROR_PRINT("ERROR: %s - no child frame has focus\n", __FUNCTION__);
2771  return -1; // an error
2772  }
2773 
2774  if(pChildFrame->pUI && pChildFrame->pUI->properties)
2775  {
2776  pChildFrame->pUI->properties(pChildFrame);
2777 
2778  return 1; // HANDLED
2779  }
2780 
2781  WB_ERROR_PRINT("NOT HANDLED: %s - pChildFrame->pUI = %p, properties = %p\n",
2782  __FUNCTION__, pChildFrame->pUI,
2783  (void *)(pChildFrame->pUI ? pChildFrame->pUI->select_all : NULL));
2784 
2785  return 0; // NOT handled (but not an error)
2786 }
2787 
2788 static int ChildFrameEditPropertiesUIHandler(WBMenu *pMenu, WBMenuItem *pMenuItem)
2789 {
2790 Window wID;
2791 WBChildFrame *pChildFrame;
2792 WBFrameWindow *pFrame;
2793 WBMenuPopupWindow *pPopup;
2794 
2795 
2796  // pMenu essentially belongs to the frame window. determine which tab has focus, and whether
2797  // or not there's anything selected. if there is something selected, enable the menu.
2798  //
2799  // NOTE: this is called by the popup menu window itself, and so the pointer will not
2800  // be asynchronously destroyed when I call MBFindMenuPopupWindow(), nor will
2801  // the owning frame window be destroyed, either (unless someone seriously
2802  // violated the way these things are supposed to work).
2803 
2804  pPopup = MBFindMenuPopupWindow(pMenu);
2805 
2806  if(pPopup)
2807  {
2808  wID = pPopup->wOwner;
2809 
2810  if(wID != None)
2811  {
2812  pFrame = FWGetFrameWindowStruct(wID);
2813 
2814  if(pFrame)
2815  {
2816  pChildFrame = FWGetContainedWindowByIndex(pFrame, -1); // current focus window
2817 
2818 // if(pChildFrame && pChildFrame->pUI && pChildFrame->pUI->properties)
2819  {
2820  return 1; // select this
2821  }
2822  }
2823  }
2824  }
2825 
2826  return -1; // disable this menu
2827 }
2828 
Atom aPRIMARY
PRIMARY Atom for the clipboard - uses XA_PRIMARY.
struct __WBChildFrameUI__ * pUI
pointer to &#39;WBChildFrameUI&#39; function pointer table (assigned by &#39;superclass&#39;)
Definition: frame_window.h:460
structure for managing menu items
Definition: menu.h:185
2nd parameter (direction) - up, left
Atom aMENU_UI_COMMAND
UI notifications sent by menus to owning Frame windows via ClientMessage using &#39;WBWindowDispatch&#39;.
set this to disable tabs (single child frame only)
Definition: frame_window.h:300
#define WB_POINTER_DBLCLICK
WB_POINTER &#39;double-click&#39; event, send in lieu of WB_POINTER_CLICK for double-click.
&#39;window helper&#39; main header file for the X11workbench Toolkit API
void(* pgleft)(WBChildFrame *, int iACS)
&#39;page left&#39; navigation.
Definition: frame_window.h:695
static __inline__ Display * WBGetDefaultDisplay(void)
Returns the default Display.
#define WB_POINTER_CLICK
Mouse &#39;click&#39; event.
int iClientX
The current X position of the frame window&#39;s client area (relative to the window) ...
Definition: frame_window.h:280
int FWInitChildFrame(WBChildFrame *pChildFrame, WBFrameWindow *pOwner, XFontSet rFontSet, const char *szFocusMenu, const WBFWMenuHandler *pHandlerArray, WBWinEvent pUserCallback, int fFlags)
Initialize a child frame (assumed to be a base &#39;class&#39; for the window)
Definition: child_frame.c:118
void FWRemoveContainedWindow(WBFrameWindow *pFW, WBChildFrame *pCont)
Removes a &#39;contained&#39; window from a frame window. Does not destroy the &#39;contained&#39; window...
int(* can_redo)(WBChildFrame *)
returns non-zero value if &#39;can redo&#39;
Definition: frame_window.h:731
#define WB_DEBUG_PRINT(L,...)
Preferred method of implementing conditional debug output.
Definition: debug_helper.h:299
void * WBGetWindowData(Window wID, int iIndex)
Gets the data associated with this window and the specified index.
void(* downarrow)(WBChildFrame *, int iACS)
&#39;down&#39; arrow navigation.
Definition: frame_window.h:688
#define WB_POINTER_DROP
WB_POINTER &#39;drop&#39; event, only sent if drag/drop supported AND was not &#39;canceled&#39;; see WB_POINTER_CANC...
void(* mouse_click)(WBChildFrame *, int iX, int iY, int iButtonMask, int iACS)
&#39;mouse click&#39; notification.
Definition: frame_window.h:712
void(* home)(WBChildFrame *, int iACS)
&#39;home&#39; arrow navigation.
Definition: frame_window.h:691
Utilities for copying and drawing text, determining text extents, and so on.
void FWSetChildFrameContextMenuID(WBChildFrame *pChildFrame, int nID)
Function to assign the context menu ID (from the menu resource) to a Child Frame. ...
Definition: child_frame.c:495
int WBKeyEventProcessKey(const XKeyEvent *pEvent, char *pBuf, int *pcbLen, int *piAltCtrlShift)
Generic keyboard event translation utility.
Window wID
Window id for the frame window.
Definition: frame_window.h:277
generic &#39;NA&#39; or &#39;UNDEFINED&#39; value
#define WB_POINTER_SCROLLDOWN
WB_POINTER &#39;scroll down&#39; event, caused by mouse button 5.
void(* cut_to_cb)(WBChildFrame *)
delete selection, copying to clipboard first
Definition: frame_window.h:704
void(* scroll_horiz)(WBChildFrame *, int iMode, int iValue)
&#39;scroll vertical&#39; notification.
Definition: frame_window.h:723
char * szDisplayName
display name shown in tab and title bar. You should not alter this member directly.
Definition: frame_window.h:449
int WBScrollBarEvent(Window wID, XEvent *pEvent, WB_SCROLLINFO *pScrollInfo)
Event handler for scroll bars.
#define WB_KEYEVENT_ALT
&#39;AltCtrlShift&#39; bit flag for ALT modifier for WBKeyEventProcessKey()
WBFrameWindow * pOwner
a pointer to the WBFrameWindow owner
Definition: frame_window.h:430
#define FW_EDIT_DELETE_MENU
Definition: child_frame.h:115
void(* pgright)(WBChildFrame *, int iACS)
&#39;page right&#39; navigation.
Definition: frame_window.h:696
WBMenuPopupWindow * MBFindMenuPopupWindow(WBMenu *pMenu)
Find the first WBMenuPopupWindow that references a WBMenu.
Definition: menu_popup.c:457
Definition file for font helper functions and structures.
#define WB_MOUSE_INPUT_MASK
&#39;Mouse&#39; input mask, bit flag for window creation
static __inline__ WBFrameWindow * FWGetFrameWindowStruct(Window wID)
Obtain the associated WBFrameWindow structure pointer for a frame window&#39;s Window ID...
Definition: frame_window.h:835
#define WB_KEYBOARD_INPUT_MASK
&#39;Keyboard&#39; input mask, bit flag for window creation
#define FW_EDIT_SELECT_NONE_MENU
Definition: child_frame.h:117
GC WBBeginPaintGeom(Window wID, WB_GEOM *pgBounds)
&#39;Paint&#39; helper, creates a GC for use in updating the window for a specified rectangular area ...
Structure that defines a Child Frame within a Frame Window.
Definition: frame_window.h:426
structure for managing menu items
Definition: menu.h:127
1st parameter (bar) - The vertical scroll bar for the control or window.
2nd parameter (direction) - &#39;knob track&#39; - pos in data.l[2]
int iVPos
current vertical scroll position (N/A if outside of min/max range)
void(* redo)(WBChildFrame *)
perform a re-do
Definition: frame_window.h:729
structure for managing a popup menu window
Definition: menu_popup.h:108
int WBPostPriorityEvent(Window wID, XEvent *pEvent)
Places a copy of the specified event at the end of the priority (internal) event queue.
int WBTextObjectCalculateLineHeight(int iAscent, int iDescent)
Calculate the correct per-line height (in pixels) for a specified font ascent and descent...
Definition: text_object.c:835
Atom aWB_CHAR
keystroke/character notifications generated by API
void FWChildFrameStatusChanged(WBChildFrame *pChildFrame)
Notify Child Frame to update status text in Frame Window.
Definition: child_frame.c:889
void(* do_char)(WBChildFrame *, XClientMessageEvent *)
handler for regular WB_CHAR Client Messages (typed-in characters).
Definition: frame_window.h:680
void FWSetChildFrameMenu(WBChildFrame *pChildFrame, const char *szFocusMenu)
Function to assign the menu resource to a Child Frame.
Definition: child_frame.c:470
void(* undo)(WBChildFrame *)
perform an undo operation
Definition: frame_window.h:728
void(* properties)(WBChildFrame *)
display the property sheet for the displayed document (optional)
Definition: frame_window.h:686
Atom aWB_POINTER
pointer click/double-click/drag notifications generated by API
XColor FWGetDefaultFG(void)
Get the default foreground color.
Definition: frame_window.c:427
WB_POINT origin
viewport &#39;origin&#39; in &#39;client units&#39; (such as chars and lines) - determines scroll behavior ...
Definition: frame_window.h:435
#define WB_STANDARD_INPUT_MASK
&#39;Standard&#39; input mask, bit flag for window creation
struct __WBChildFrame__ * pNext
&#39;Next Object&#39; pointer in an internally stored linked list (do not alter or use this) ...
Definition: frame_window.h:462
Atom aMENU_COMMAND
commands sent by menus via ClientMessage
int(* is_empty)(WBChildFrame *)
returns non-zero value if contents are &#39;empty&#39;
Definition: frame_window.h:732
void(* mouse_drop)(WBChildFrame *, int iX, int iY, int iButtonMask, int iACS)
&#39;mouse drop&#39; (drag end) notification.
Definition: frame_window.h:718
Atom aSCROLL_NOTIFY
void FWChildFrameRecalcLayout(WBChildFrame *pChildFrame)
Child frame notification callback (called by frame window)
Definition: child_frame.c:837
unsigned int width
the &#39;width&#39; value of the extent.
1st parameter (bar) - The horizontal scroll bar for the control or window
XColor FWGetDefaultBD(void)
Get the default border color.
Definition: frame_window.c:441
int y
the &#39;y&#39; value of the point. can be negative.
char * szStatusText
Status text (&#39;WBAlloc&#39;d) to display when this child frame window has the input focus. Updated by &#39;superclass&#39;. can be NULL.
Definition: frame_window.h:452
Child Frame API functions.
int iHPos
current horozontal scroll position (N/A if outside of min/max range)
void WBCreateWindowDefaultGC(Window wID, unsigned long clrFG, unsigned long clrBG)
creates a default GC for a window
void(* tab)(WBChildFrame *, int iACS)
&#39;tab&#39; char, or tab navigation.
Definition: frame_window.h:684
static __inline__ WBChildFrame * FWGetChildFrameStruct(Window wID)
Obtain the associated WBChildFrame structure pointer for a Window ID.
Definition: child_frame.h:376
void(* destructor)(struct __WBChildFrame__ *)
pointer to a &#39;superclass&#39; destructor. If not NULL, will be called by FWDestroyChildFrame() ...
Definition: frame_window.h:459
2nd parameter (direction) - bottom, end
void(* mouse_move)(WBChildFrame *, int iX, int iY)
&#39;mouse motion&#39; notification.
Definition: frame_window.h:720
void * WBAlloc(int nSize)
High performance memory sub-allocator &#39;allocate&#39;.
int FWAddContainedWindow(WBFrameWindow *pFW, WBChildFrame *pNew)
Adds a &#39;contained&#39; window and returns the tab order index.
unsigned int width
structure for defining a menu bar window
Definition: menu_bar.h:113
static __inline__ WBMenuBarWindow * MBGetMenuBarWindowStruct(Window wID)
Obtain a pointer to the WBMenuBarWindow structure from a Window ID of a Menu Bar window.
Definition: menu_bar.h:191
XFontSet WBCopyModifyFontSet(Display *pDisplay, XFontSet fsOrig, int iFontSize, int iFlags)
copy and modify a font set according to the specified size and flags
Definition: font_helper.c:1441
#define WB_POINTER_SCROLLUP
WB_POINTER &#39;scroll up&#39; event, caused by mouse button 4.
int FWGetNumContWindows(const WBFrameWindow *pFW)
Returns the total number of &#39;contained&#39; windows.
2nd parameter (direction) - relative scroll - rel pos in data.l[2]
int(* has_selection)(WBChildFrame *)
returns non-zero value if there is a selection
Definition: frame_window.h:727
unsigned int height
Window WBGetMenuWindow(Window wID)
Returns the Window ID of the (first) menu window assigned to a (frame) window.
unsigned int ulTag
tag indicating I&#39;m a &#39;Child Frame&#39; window
Definition: frame_window.h:428
#define FW_EDIT_CUT_MENU
Definition: child_frame.h:112
int WBFontSetAvgCharWidth(Display *pDisplay, XFontSet fontSet)
Get the average character width for a font set.
Definition: font_helper.c:1227
#define FW_MENU_HANDLER_BEGIN(X)
Use this macro to begin definition of a WBFWMenuHandler array.
Definition: frame_window.h:893
#define WB_ERROR_PRINT(...)
Preferred method of implementing an &#39;error level&#39; debug message for all subsystems.
Definition: debug_helper.h:356
void FWSetChildFrameMenuHandlers(WBChildFrame *pChildFrame, const WBFWMenuHandler *pHandlerArray)
Function to assign menu handlers to a Child Frame.
Definition: child_frame.c:507
void(* leftarrow)(WBChildFrame *, int iACS)
&#39;left&#39; arrow navigation.
Definition: frame_window.h:689
void(* pgdown)(WBChildFrame *, int iACS)
&#39;page down&#39; navigation.
Definition: frame_window.h:694
XFontSet rFontSet
default font for the window
Definition: frame_window.h:431
void(* end)(WBChildFrame *, int iACS)
&#39;end&#39; arrow navigation.
Definition: frame_window.h:692
void WBFree(void *pBuf)
High performance memory sub-allocator &#39;free&#39;.
static __inline__ void WBInvalidateRect(Window wID, const WB_RECT *pRCT, int bPaintFlag)
&#39;Paint&#39; helper, invalidates a WB_RECT for asynchronous Expose event generation
void WBDestroyWindow(Window wID)
Destroy a window.
2nd parameter (direction) - pgup, pgleft
void(* del)(WBChildFrame *, int iACS)
&#39;delete&#39; char under cursor (delete equivalent), or perform related &#39;delete&#39; operation via ctrl/alt/sh...
Definition: frame_window.h:683
int(* can_undo)(WBChildFrame *)
returns non-zero value if &#39;can undo&#39;
Definition: frame_window.h:730
#define WB_POINTER_CANCEL
WB_POINTER &#39;cancel&#39; event, cancels an ongoing operation, such as drag/drop (useful for resource clean...
structure for managing menu callbacks
Definition: frame_window.h:217
#define WB_KEYEVENT_SHIFT
&#39;AltCtrlShift&#39; bit flag for Shift modifier for WBKeyEventProcessKey()
void(* mouse_dblclick)(WBChildFrame *, int iX, int iY, int iButtonMask, int iACS)
&#39;mouse double click&#39; notification.
Definition: frame_window.h:714
void FWSetChildFrameDisplayName(WBChildFrame *pChildFrame, const char *szDisplayName)
Assign the display name.
Definition: child_frame.c:563
#define FW_MENU_HANDLER_END
Use this macro to complete the definition of a WBFWMenuHandler array.
Definition: frame_window.h:907
#define CHILD_FRAME_TAG
TAG for the WBChildFrame structure.
Definition: child_frame.h:94
void(* select_all)(WBChildFrame *)
select all
Definition: frame_window.h:706
#define FW_EDIT_PROPERTIES_MENU
Definition: child_frame.h:120
void FWSetChildFrameScrollInfo(WBChildFrame *pChildFrame, int iRow, int iMaxRow, int iCol, int iMaxCol, int iRowHeight, int iColWidth)
Set the X,Y extent for the child frame (notifies everything)
Definition: child_frame.c:796
#define WB_POINTER_MOVE
WB_POINTER &#39;move&#39; event, for motion notification during drag/drop.
#define WB_POINTER_DRAG
WB_POINTER &#39;drag&#39; event, window proc MUST return the window ID to auto-support drag/drop.
void FWDestroyChildFrame(WBChildFrame *pChildFrame)
Destroy an Child Frame.
Definition: child_frame.c:321
Atom aMENU_ACTIVATE
Internal Client Message Atom for &#39;ACTIVATE&#39; notification.
Definition: menu_bar.c:150
2nd parameter (direction) - absolute scroll - pos in data.l[2]
Atom aCLIPBOARD
CLIPBOARD Atom for the clipboard.
int iClientWidth
The current width of the frame window&#39;s client area.
Definition: frame_window.h:282
Structure that defines a Child Frame&#39;s UI, mainly for a &#39;superclass&#39;.
Definition: frame_window.h:677
void(* bkspace)(WBChildFrame *, int iACS)
&#39;backspace&#39; delete character (backspace equivalent), or perform related &#39;backspace&#39; operation via ctr...
Definition: frame_window.h:682
int WBSetHScrollRange(WB_SCROLLINFO *pSI, int iMin, int iMax)
Set the scroll range for a horizontal scrollbar in the WB_SCROLLINFO structure.
2nd parameter (direction) - double-clicked item (no selection change info) (sent to list control&#39;s ow...
void WBDebugDumpEvent(XEvent *pEvent)
dumps the contents of an XEvent
void WBUnregisterWindowCallback(Window wID)
un-register the window&#39;s callback function (implies resource destruction)
void(* enter)(WBChildFrame *, int iACS)
&#39;enter&#39; char, or &#39;enter&#39; for navigation.
Definition: frame_window.h:685
#define WB_KEYEVENT_ACSMASK
&#39;AltCtrlShift&#39; bit mask for Alt+Ctrl+Shift bits for WBKeyEventProcessKey()
int WBFontSetDescent(Display *pDisplay, XFontSet fontSet)
Get the maximum character descent from a font set.
Definition: font_helper.c:1094
uintptr_t lMenuID
menu ID (< 0x10000L) or const pointer to string
Definition: frame_window.h:219
int iClientHeight
The current height of the frame window&#39;s client area.
Definition: frame_window.h:283
Window wOwner
window ID for the owner window
Definition: menu_popup.h:113
int(* WBWinEvent)(Window wID, XEvent *pEvent)
event callback function type for window events
2nd parameter (direction) - home, top
void(* copy_to_cb)(WBChildFrame *)
copy selection to clipboard
Definition: frame_window.h:702
Atom aImageAtom
&#39;image&#39; atom for display in tabs. default is &#39;None&#39;. You should not alter this member directly...
Definition: frame_window.h:450
XColor FWGetDefaultBG(void)
Get the default background color.
Definition: frame_window.c:434
void(* rightarrow)(WBChildFrame *, int iACS)
&#39;right&#39; arrow navigation.
Definition: frame_window.h:690
int WBFontSetAscent(Display *pDisplay, XFontSet fontSet)
Get the maximum character ascent from a font set.
Definition: font_helper.c:1136
void(* delete_sel)(WBChildFrame *)
delete selection only
Definition: frame_window.h:705
void(* pgup)(WBChildFrame *, int iACS)
&#39;page up&#39; navigation.
Definition: frame_window.h:693
void(* toggle_ins_mode)(WBChildFrame *)
toggles insert mode on or off
Definition: frame_window.h:701
int MBMenuProcessHotKey(WBMenu *pMenu, XKeyEvent *pEvent)
Event handler for menu hotkeys.
Definition: menu.c:1228
Atom aQUERY_CLOSE
query if it&#39;s ok to close (and optionally destroy yourself if ok) a window
int iRowHeight
cached &#39;row height&#39; (height of line including interline spacing)
Definition: frame_window.h:438
Window wID
window identifier for the &#39;Child Frame&#39; window. may contain &#39;None&#39; while being destroyed ...
Definition: frame_window.h:429
WBChildFrame * FWGetContainedWindowByIndex(const WBFrameWindow *pFW, int iIndex)
Returns the Window ID for the specified &#39;contained&#39; window. The index follows the tab order...
Display * WBGetWindowDisplay(Window wID)
returns the Display associated with a window
WB_EXTENT extent
viewport &#39;extent&#39; in &#39;client units&#39; (such as chars and lines) - determines scroll behavior ...
Definition: frame_window.h:436
void WBPaintVScrollBar(WB_SCROLLINFO *pScrollInfo, Display *pDisplay, Drawable wID, GC gc, WB_GEOM *pgeomClient)
Paint the vertical scroll bar within a window based on WB_SCROLLINFO.
void WBSetWindowData(Window wID, int iIndex, void *pData)
assign &#39;data pointer&#39; for a window and specified index value
char * pszMenuResource
resource string for this child frame&#39;s menu (NULL = &#39;use default&#39;)
Definition: frame_window.h:454
2nd parameter (direction) - pgdn, pgright
int iColWidth
cached &#39;column width&#39; (width of 1 character)
Definition: frame_window.h:439
int FWChildFrameEvent(Window wID, XEvent *pEvent)
Default event handler for Child Frame window.
Definition: child_frame.c:939
void(* paste_from_cb)(WBChildFrame *)
paste from clipboard
Definition: frame_window.h:703
void(* scancode)(WBChildFrame *, XClientMessageEvent *)
handler for &#39;other scan code&#39; WB_CHAR Client Messages.
Definition: frame_window.h:681
WBMenu * pMenu
a pointer to the associated WBMenu structure
Definition: menu_bar.h:119
WB_SCROLLINFO scroll
&#39;scroll info&#39; (horizontal and vertical min/max/pos and other details)
Definition: frame_window.h:441
#define FW_EDIT_SELECT_ALL_MENU
Definition: child_frame.h:116
main controlling structure for frame windows
Definition: frame_window.h:274
int FWChildFrameQueryClose(WBChildFrame *pChildFrame)
Returns if it&#39;s safe to close the child frame; prompts user as needed.
Definition: child_frame.c:905
Window WBCreateWindow(Display *pDisplay, Window wIDParent, WBWinEvent pProc, const char *szClass, int iX, int iY, int iWidth, int iHeight, int iBorder, int iIO, int iFlags, XSetWindowAttributes *pXSWA)
Create a window.
#define WB_KEYEVENT_CTRL
&#39;AltCtrlShift&#39; bit flag for Control modifier for WBKeyEventProcessKey()
int WBSetVScrollRange(WB_SCROLLINFO *pSI, int iMin, int iMax)
Set the scroll range for a vertical scrollbar in the WB_SCROLLINFO structure.
static __inline__ void WBInitScrollInfo(WB_SCROLLINFO *pSI)
Initialization function for a &#39;WB_SCROLLINFO&#39; structure.
void(* scroll_vert)(WBChildFrame *, int iMode, int iValue)
&#39;scroll vertical&#39; notification.
Definition: frame_window.h:722
char * WBCopyString(const char *pSrc)
A simple utility that returns a WBAlloc() copy of a 0-byte terminated string.
unsigned int height
the &#39;height&#39; value of the extent.
WBFWMenuHandler * pMenuHandler
menu handler for this child frame&#39;s menu (NULL = &#39;use default&#39;)
Definition: frame_window.h:455
void(* uparrow)(WBChildFrame *, int iACS)
&#39;up&#39; arrow navigation.
Definition: frame_window.h:687
void FWSetChildFrameExtent(WBChildFrame *pChildFrame, int iXExtent, int iYExtent)
Set the X,Y extent for the child frame (notifies everything)
Definition: child_frame.c:637
WB_GEOM geomEntire
client-area geometry (excludes scroll bars)
Definition: frame_window.h:434
int(* callback)(XClientMessageEvent *)
menu callback (gets pointer to the &#39;XClientMessageEvent&#39;).
Definition: frame_window.h:221
Atom aRESIZE_NOTIFY
notification of window re-size via ClientMessage
int iContextMenuID
menu ID (from pszMenuResource or owning frame&#39;s menu) for context popup, -1 if none ...
Definition: frame_window.h:456
void FWSetStatusText(WBFrameWindow *pFW, const char *szText)
Sets the &#39;status&#39; text for a Frame Window with a status bar, forcing a re-paint.
2nd parameter (direction) - down, right
Window wSelf
The window ID of the menu bar window.
Definition: menu_bar.h:116
#define FW_EDIT_PASTE_MENU
Definition: child_frame.h:114
void(* mouse_cancel)(WBChildFrame *)
&#39;mouse cancel&#39; notification (cancel &#39;drag&#39;, etc.).
Definition: frame_window.h:725
void(* select_none)(WBChildFrame *)
select none
Definition: frame_window.h:707
WBWinEvent pUserCallback
message callback function pointer (can be NULL)
Definition: frame_window.h:458
int iFlags
bitmask of attribute flags (see WBFrameWindow_FLAGS enumeration)
Definition: frame_window.h:278
void(* mouse_drag)(WBChildFrame *, int iX, int iY, int iButtonMask, int iACS)
&#39;mouse drag&#39; (begin) notification.
Definition: frame_window.h:716
internal wrapper struct for X11 &#39;geometry&#39; definition
#define FW_MENU_HANDLER_ENTRY(X, Y, Z)
Use this macro to define an entry for a WBFWMenuHandler array.
Definition: frame_window.h:902
void WBEndPaint(Window wID, GC gc)
&#39;Paint&#39; helper, frees resources and marks the update region &#39;valid&#39;
int(* UIcallback)(WBMenu *, WBMenuItem *)
menu &#39;UI&#39; callback to handle displaying menu states.
Definition: frame_window.h:228
int x
the &#39;x&#39; value of the point. can be negative.
#define WB_WARN_PRINT(...)
Preferred method of implementing a &#39;warning level&#39; debug message for all subsystems.
Definition: debug_helper.h:349
WB_GEOM geom
total client-area geometry (excludes scroll bars) in &#39;pixels&#39;
Definition: frame_window.h:433
void WBUpdateScrollBarGeometry(WB_SCROLLINFO *pSI, XFontSet fontSetRef, WB_GEOM *pgeomClient, WB_GEOM *pgeomUsable)
Update the scroll bar geometry within the WB_SCROLLINFO structure.
void WBPaintHScrollBar(WB_SCROLLINFO *pScrollInfo, Display *pDisplay, Drawable wID, GC gc, WB_GEOM *pgeomClient)
Paint the horizontal scroll bar within a window based on WB_SCROLLINFO.
#define FW_EDIT_COPY_MENU
Definition: child_frame.h:113
#define WB_KEYEVENT_KEYSYM
&#39;AltCtrlShift&#39; bit flag for &#39;VK_&#39; keys for WBKeyEventProcessKey()
void FWSetChildFrameImageAtom(WBChildFrame *pChildFrame, Atom aImage)
Assign the image atom for the child frame. the image appears in the tab associated with the child fra...
Definition: child_frame.c:585
int iClientY
The current Y position of the frame window&#39;s client area (relative to the window) ...
Definition: frame_window.h:281