1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2007 Blender Foundation.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup DNA
22  */
23 
24 #pragma once
25 
26 #include "DNA_listBase.h"
27 #include "DNA_screen_types.h"
28 #include "DNA_userdef_types.h"
29 #include "DNA_vec_types.h"
30 #include "DNA_xr_types.h"
31 
32 #include "DNA_ID.h"
33 
34 /* defined here: */
35 struct wmWindow;
36 struct wmWindowManager;
37 
38 struct wmEvent;
39 struct wmGesture;
40 struct wmKeyConfig;
41 struct wmKeyMap;
42 struct wmMsgBus;
43 struct wmOperator;
44 struct wmOperatorType;
45 
46 /* forwards */
47 struct PointerRNA;
48 struct Report;
49 struct ReportList;
50 struct Stereo3dFormat;
51 struct bContext;
52 struct bScreen;
53 struct uiLayout;
54 struct wmTimer;
55 
56 #define OP_MAX_TYPENAME 64
57 #define KMAP_MAX_NAME 64
58 
59 /* keep in sync with 'rna_enum_wm_report_items' in wm_rna.c */
60 typedef enum ReportType {
61   RPT_DEBUG = (1 << 0),
62   RPT_INFO = (1 << 1),
63   RPT_OPERATOR = (1 << 2),
64   RPT_PROPERTY = (1 << 3),
65   RPT_WARNING = (1 << 4),
66   RPT_ERROR = (1 << 5),
67   RPT_ERROR_INVALID_INPUT = (1 << 6),
68   RPT_ERROR_INVALID_CONTEXT = (1 << 7),
69   RPT_ERROR_OUT_OF_MEMORY = (1 << 8),
70 } ReportType;
71 
72 #define RPT_DEBUG_ALL (RPT_DEBUG)
73 #define RPT_INFO_ALL (RPT_INFO)
74 #define RPT_OPERATOR_ALL (RPT_OPERATOR)
75 #define RPT_PROPERTY_ALL (RPT_PROPERTY)
76 #define RPT_WARNING_ALL (RPT_WARNING)
77 #define RPT_ERROR_ALL \
78   (RPT_ERROR | RPT_ERROR_INVALID_INPUT | RPT_ERROR_INVALID_CONTEXT | RPT_ERROR_OUT_OF_MEMORY)
79 
80 enum ReportListFlags {
81   RPT_PRINT = (1 << 0),
82   RPT_STORE = (1 << 1),
83   RPT_FREE = (1 << 2),
84   RPT_OP_HOLD = (1 << 3), /* don't move them into the operator global list (caller will use) */
85 };
86 
87 /* These two Lines with # tell makesdna this struct can be excluded. */
88 #
89 #
90 typedef struct Report {
91   struct Report *next, *prev;
92   /** ReportType. */
93   short type;
94   short flag;
95   /** `strlen(message)`, saves some time calculating the word wrap . */
96   int len;
97   const char *typestr;
98   const char *message;
99 } Report;
100 
101 /* saved in the wm, don't remove */
102 typedef struct ReportList {
103   ListBase list;
104   /** ReportType. */
105   int printlevel;
106   /** ReportType. */
107   int storelevel;
108   int flag;
109   char _pad[4];
110   struct wmTimer *reporttimer;
111 } ReportList;
112 
113 /* timer customdata to control reports display */
114 /* These two Lines with # tell makesdna this struct can be excluded. */
115 #
116 #
117 typedef struct ReportTimerInfo {
118   float col[4];
119   float widthfac;
120 } ReportTimerInfo;
121 
122 //#ifdef WITH_XR_OPENXR
123 typedef struct wmXrData {
124   /** Runtime information for managing Blender specific behaviors. */
125   struct wmXrRuntimeData *runtime;
126   /** Permanent session settings (draw mode, feature toggles, etc). Stored in files and accessible
127    * even before the session runs. */
128   XrSessionSettings session_settings;
129 } wmXrData;
130 //#endif
131 
132 /* reports need to be before wmWindowManager */
133 
134 /* windowmanager is saved, tag WMAN */
135 typedef struct wmWindowManager {
136   ID id;
137 
138   /** Separate active from drawable. */
139   struct wmWindow *windrawable, *winactive;
140   ListBase windows;
141 
142   /** Set on file read. */
143   short initialized;
144   /** Indicator whether data was saved. */
145   short file_saved;
146   /** Operator stack depth to avoid nested undo pushes. */
147   short op_undo_depth;
148 
149   /** Set after selection to notify outliner to sync. Stores type of selection */
150   short outliner_sync_select_dirty;
151 
152   /** Operator registry. */
153   ListBase operators;
154 
155   /** Refresh/redraw wmNotifier structs. */
156   ListBase queue;
157 
158   /** Information and error reports. */
159   struct ReportList reports;
160 
161   /** Threaded jobs manager. */
162   ListBase jobs;
163 
164   /** Extra overlay cursors to draw, like circles. */
165   ListBase paintcursors;
166 
167   /** Active dragged items. */
168   ListBase drags;
169 
170   /** Known key configurations. */
171   ListBase keyconfigs;
172   /** Default configuration. */
173   struct wmKeyConfig *defaultconf;
174   /** Addon configuration. */
175   struct wmKeyConfig *addonconf;
176   /** User configuration. */
177   struct wmKeyConfig *userconf;
178 
179   /** Active timers. */
180   ListBase timers;
181   /** Timer for auto save. */
182   struct wmTimer *autosavetimer;
183 
184   /** All undo history (runtime only). */
185   struct UndoStack *undo_stack;
186 
187   /** Indicates whether interface is locked for user interaction. */
188   char is_interface_locked;
189   char _pad[7];
190 
191   struct wmMsgBus *message_bus;
192 
193   //#ifdef WITH_XR_OPENXR
194   wmXrData xr;
195   //#endif
196 } wmWindowManager;
197 
198 /* wmWindowManager.initialized */
199 enum {
200   WM_WINDOW_IS_INIT = (1 << 0),
201   WM_KEYCONFIG_IS_INIT = (1 << 1),
202 };
203 
204 /* wmWindowManager.outliner_sync_select_dirty */
205 enum {
206   WM_OUTLINER_SYNC_SELECT_FROM_OBJECT = (1 << 0),
207   WM_OUTLINER_SYNC_SELECT_FROM_EDIT_BONE = (1 << 1),
208   WM_OUTLINER_SYNC_SELECT_FROM_POSE_BONE = (1 << 2),
209   WM_OUTLINER_SYNC_SELECT_FROM_SEQUENCE = (1 << 3),
210 };
211 
212 #define WM_OUTLINER_SYNC_SELECT_FROM_ALL \
213   (WM_OUTLINER_SYNC_SELECT_FROM_OBJECT | WM_OUTLINER_SYNC_SELECT_FROM_EDIT_BONE | \
214    WM_OUTLINER_SYNC_SELECT_FROM_POSE_BONE | WM_OUTLINER_SYNC_SELECT_FROM_SEQUENCE)
215 
216 #define WM_KEYCONFIG_STR_DEFAULT "blender"
217 
218 /* IME is win32 only! */
219 #if !defined(WIN32) && !defined(DNA_DEPRECATED)
220 #  ifdef __GNUC__
221 #    define ime_data ime_data __attribute__((deprecated))
222 #  endif
223 #endif
224 
225 /* the saveable part, rest of data is local in ghostwinlay */
226 typedef struct wmWindow {
227   struct wmWindow *next, *prev;
228 
229   /** Don't want to include ghost.h stuff. */
230   void *ghostwin;
231   /** Don't want to include gpu stuff. */
232   void *gpuctx;
233 
234   /** Parent window. */
235   struct wmWindow *parent;
236 
237   /** Active scene displayed in this window. */
238   struct Scene *scene;
239   /** Temporary when switching. */
240   struct Scene *new_scene;
241   /** Active view layer displayed in this window. */
242   char view_layer_name[64];
243 
244   struct WorkSpaceInstanceHook *workspace_hook;
245 
246   /** Global areas aren't part of the screen, but part of the window directly.
247    * \note Code assumes global areas with fixed height, fixed width not supported yet */
248   ScrAreaMap global_areas;
249 
250   struct bScreen *screen DNA_DEPRECATED;
251 
252   /** Window coords. */
253   short posx, posy, sizex, sizey;
254   /** Borderless, full. */
255   char windowstate;
256   /** Set to 1 if an active window, for quick rejects. */
257   char active;
258   char _pad0[4];
259   /** Current mouse cursor type. */
260   short cursor;
261   /** Previous cursor when setting modal one. */
262   short lastcursor;
263   /** The current modal cursor. */
264   short modalcursor;
265   /** Cursor grab mode. */
266   short grabcursor;
267   /** Internal: tag this for extra mouse-move event,
268    * makes cursors/buttons active on UI switching. */
269   char addmousemove;
270   char tag_cursor_refresh;
271 
272   /** Winid also in screens, is for retrieving this window after read. */
273   int winid;
274 
275   /** Internal, lock pie creation from this event until released. */
276   short lock_pie_event;
277   /**
278    * Exception to the above rule for nested pies, store last pie event for operators
279    * that spawn a new pie right after destruction of last pie.
280    */
281   short last_pie_event;
282 
283   /** Storage for event system. */
284   struct wmEvent *eventstate;
285 
286   /** Internal for wm_operators.c. */
287   struct wmGesture *tweak;
288 
289   /* Input Method Editor data - complex character input (especially for Asian character input)
290    * Currently WIN32, runtime-only data. */
291   struct wmIMEData *ime_data;
292 
293   /** All events (ghost level events were handled). */
294   ListBase queue;
295   /** Window+screen handlers, handled last. */
296   ListBase handlers;
297   /** Priority handlers, handled first. */
298   ListBase modalhandlers;
299 
300   /** Gesture stuff. */
301   ListBase gesture;
302 
303   /** Properties for stereoscopic displays. */
304   struct Stereo3dFormat *stereo3d_format;
305 
306   /* custom drawing callbacks */
307   ListBase drawcalls;
308 
309   /* Private runtime info to show text in the status bar. */
310   void *cursor_keymap_status;
311 } wmWindow;
312 
313 #ifdef ime_data
314 #  undef ime_data
315 #endif
316 
317 /* These two Lines with # tell makesdna this struct can be excluded. */
318 /* should be something like DNA_EXCLUDE
319  * but the preprocessor first removes all comments, spaces etc */
320 #
321 #
322 typedef struct wmOperatorTypeMacro {
323   struct wmOperatorTypeMacro *next, *prev;
324 
325   /* operator id */
326   char idname[64];
327   /* rna pointer to access properties, like keymap */
328   /** Operator properties, assigned to ptr->data and can be written to a file. */
329   struct IDProperty *properties;
330   struct PointerRNA *ptr;
331 } wmOperatorTypeMacro;
332 
333 /* Partial copy of the event, for matching by event handler. */
334 typedef struct wmKeyMapItem {
335   struct wmKeyMapItem *next, *prev;
336 
337   /* operator */
338   /** Used to retrieve operator type pointer. */
339   char idname[64];
340   /** Operator properties, assigned to ptr->data and can be written to a file. */
341   IDProperty *properties;
342 
343   /* modal */
344   /** Runtime temporary storage for loading. */
345   char propvalue_str[64];
346   /** If used, the item is from modal map. */
347   short propvalue;
348 
349   /* event */
350   /** Event code itself. */
351   short type;
352   /** KM_ANY, KM_PRESS, KM_NOTHING etc. */
353   short val;
354   /** Oskey is apple or windowskey, value denotes order of pressed. */
355   short shift, ctrl, alt, oskey;
356   /** Rawkey modifier. */
357   short keymodifier;
358 
359   /* flag: inactive, expanded */
360   short flag;
361 
362   /* runtime */
363   /** Keymap editor. */
364   short maptype;
365   /** Unique identifier. Positive for kmi that override builtins, negative otherwise. */
366   short id;
367   char _pad[2];
368   /** Rna pointer to access properties. */
369   struct PointerRNA *ptr;
370 } wmKeyMapItem;
371 
372 /** Used instead of wmKeyMapItem for diff keymaps. */
373 typedef struct wmKeyMapDiffItem {
374   struct wmKeyMapDiffItem *next, *prev;
375 
376   wmKeyMapItem *remove_item;
377   wmKeyMapItem *add_item;
378 } wmKeyMapDiffItem;
379 
380 /** #wmKeyMapItem.flag */
381 enum {
382   KMI_INACTIVE = (1 << 0),
383   KMI_EXPANDED = (1 << 1),
384   KMI_USER_MODIFIED = (1 << 2),
385   KMI_UPDATE = (1 << 3),
386   /**
387    * When set, ignore events with #wmEvent.is_repeat enabled.
388    *
389    * \note this flag isn't cleared when editing/loading the key-map items,
390    * so it may be set in cases which don't make sense (modifier-keys or mouse-motion for example).
391    *
392    * Knowing if an event may repeat is something set at the operating-systems event handling level
393    * so rely on #wmEvent.is_repeat being false non keyboard events instead of checking if this
394    * flag makes sense.
395    *
396    * Only used when: `ISKEYBOARD(kmi->type) || (kmi->type == KM_TEXTINPUT)`
397    * as mouse, 3d-mouse, timer... etc never repeat.
398    */
399   KMI_REPEAT_IGNORE = (1 << 4),
400 };
401 
402 /** #wmKeyMapItem.maptype */
403 enum {
404   KMI_TYPE_KEYBOARD = 0,
405   KMI_TYPE_MOUSE = 1,
406   KMI_TYPE_TWEAK = 2,
407   KMI_TYPE_TEXTINPUT = 3,
408   KMI_TYPE_TIMER = 4,
409   KMI_TYPE_NDOF = 5,
410 };
411 
412 /* stored in WM, the actively used keymaps */
413 typedef struct wmKeyMap {
414   struct wmKeyMap *next, *prev;
415 
416   ListBase items;
417   ListBase diff_items;
418 
419   /** Global editor keymaps, or for more per space/region. */
420   char idname[64];
421   /** Same IDs as in DNA_space_types.h. */
422   short spaceid;
423   /** See above. */
424   short regionid;
425   /** Optional, see: #wmOwnerID. */
426   char owner_id[64];
427 
428   /** General flags. */
429   short flag;
430   /** Last kmi id. */
431   short kmi_id;
432 
433   /* runtime */
434   /** Verify if enabled in the current context, use #WM_keymap_poll instead of direct calls. */
435   bool (*poll)(struct bContext *);
436   bool (*poll_modal_item)(const struct wmOperator *op, int value);
437 
438   /** For modal, #EnumPropertyItem for now. */
439   const void *modal_items;
440 } wmKeyMap;
441 
442 /** #wmKeyMap.flag */
443 enum {
444   KEYMAP_MODAL = (1 << 0), /* modal map, not using operatornames */
445   KEYMAP_USER = (1 << 1),  /* user keymap */
446   KEYMAP_EXPANDED = (1 << 2),
447   KEYMAP_CHILDREN_EXPANDED = (1 << 3),
448   KEYMAP_DIFF = (1 << 4),          /* diff keymap for user preferences */
449   KEYMAP_USER_MODIFIED = (1 << 5), /* keymap has user modifications */
450   KEYMAP_UPDATE = (1 << 6),
451   KEYMAP_TOOL = (1 << 7), /* keymap for active tool system */
452 };
453 
454 /**
455  * This is similar to addon-preferences,
456  * however unlike add-ons key-config's aren't saved to disk.
457  *
458  * #wmKeyConfigPref is written to DNA,
459  * #wmKeyConfigPrefType_Runtime has the RNA type.
460  */
461 typedef struct wmKeyConfigPref {
462   struct wmKeyConfigPref *next, *prev;
463   /** Unique name. */
464   char idname[64];
465   IDProperty *prop;
466 } wmKeyConfigPref;
467 
468 typedef struct wmKeyConfig {
469   struct wmKeyConfig *next, *prev;
470 
471   /** Unique name. */
472   char idname[64];
473   /** Idname of configuration this is derives from, "" if none. */
474   char basename[64];
475 
476   ListBase keymaps;
477   int actkeymap;
478   short flag;
479   char _pad0[2];
480 } wmKeyConfig;
481 
482 /** #wmKeyConfig.flag */
483 enum {
484   KEYCONF_USER = (1 << 1),         /* And what about (1 << 0)? */
485   KEYCONF_INIT_DEFAULT = (1 << 2), /* Has default keymap been initialized? */
486 };
487 
488 /**
489  * This one is the operator itself, stored in files for macros etc.
490  * operator + operator-type should be able to redo entirely, but for different context's.
491  */
492 typedef struct wmOperator {
493   struct wmOperator *next, *prev;
494 
495   /* saved */
496   /** Used to retrieve type pointer. */
497   char idname[64];
498   /** Saved, user-settable properties. */
499   IDProperty *properties;
500 
501   /* runtime */
502   /** Operator type definition from idname. */
503   struct wmOperatorType *type;
504   /** Custom storage, only while operator runs. */
505   void *customdata;
506   /** Python stores the class instance here. */
507   void *py_instance;
508 
509   /** Rna pointer to access properties. */
510   struct PointerRNA *ptr;
511   /** Errors and warnings storage. */
512   struct ReportList *reports;
513 
514   /** List of operators, can be a tree. */
515   ListBase macro;
516   /** Current running macro, not saved. */
517   struct wmOperator *opm;
518   /** Runtime for drawing. */
519   struct uiLayout *layout;
520   short flag;
521   char _pad[6];
522 } wmOperator;
523 
524 /**
525  * Operator type return flags: exec(), invoke() modal(), return values.
526  */
527 enum {
528   OPERATOR_RUNNING_MODAL = (1 << 0),
529   OPERATOR_CANCELLED = (1 << 1),
530   OPERATOR_FINISHED = (1 << 2),
531   /* add this flag if the event should pass through */
532   OPERATOR_PASS_THROUGH = (1 << 3),
533   /* in case operator got executed outside WM code... like via fileselect */
534   OPERATOR_HANDLED = (1 << 4),
535   /* used for operators that act indirectly (eg. popup menu)
536    * note: this isn't great design (using operators to trigger UI) avoid where possible. */
537   OPERATOR_INTERFACE = (1 << 5),
538 };
539 #define OPERATOR_FLAGS_ALL \
540   (OPERATOR_RUNNING_MODAL | OPERATOR_CANCELLED | OPERATOR_FINISHED | OPERATOR_PASS_THROUGH | \
541    OPERATOR_HANDLED | OPERATOR_INTERFACE | 0)
542 
543 /* sanity checks for debug mode only */
544 #define OPERATOR_RETVAL_CHECK(ret) \
545   (void)ret, BLI_assert(ret != 0 && (ret & OPERATOR_FLAGS_ALL) == ret)
546 
547 /** #wmOperator.flag */
548 enum {
549   /** low level flag so exec() operators can tell if they were invoked, use with care.
550    * Typically this shouldn't make any difference, but it rare cases its needed
551    * (see smooth-view) */
552   OP_IS_INVOKE = (1 << 0),
553   /** So we can detect if an operators exec() call is activated by adjusting the last action. */
554   OP_IS_REPEAT = (1 << 1),
555   /**
556    * So we can detect if an operators exec() call is activated from #SCREEN_OT_repeat_last.
557    *
558    * This difference can be important because previous settings may be used,
559    * even with #PROP_SKIP_SAVE the repeat last operator will use the previous settings.
560    * Unlike #OP_IS_REPEAT the selection (and context generally) may be different each time.
561    * See T60777 for an example of when this is needed.
562    */
563   OP_IS_REPEAT_LAST = (1 << 1),
564 
565   /** When the cursor is grabbed */
566   OP_IS_MODAL_GRAB_CURSOR = (1 << 2),
567 
568   /** Allow modal operators to have the region under the cursor for their context
569    * (the regiontype is maintained to prevent errors) */
570   OP_IS_MODAL_CURSOR_REGION = (1 << 3),
571 };
572