Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Tue, 17 Oct 2017 04:18:12 +0000 (15:18 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 17 Oct 2017 04:18:12 +0000 (15:18 +1100)
1  2 
source/blender/windowmanager/CMakeLists.txt
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_operators.c
source/blender/windowmanager/wm.h

index 8a6d4bc95c7c2ae1490a8350d27cce8ffadf8e8f,a8b3c994d24e72d77b6ae5377218a95c5ec75f48..464906dad1e347a3a50adf60c6fb415cf41e9ce7
  
  set(INC
        .
 +      manipulators
 +      manipulators/intern
        ../blenfont
        ../blenkernel
        ../blenlib
        ../blenloader
        ../blentranslation
        ../compositor
 +      ../depsgraph
        ../editors/include
        ../gpu
        ../imbuf
@@@ -63,6 -60,7 +63,7 @@@ set(SR
        intern/wm_files.c
        intern/wm_files_link.c
        intern/wm_gesture.c
+       intern/wm_gesture_ops.c
        intern/wm_init_exit.c
        intern/wm_jobs.c
        intern/wm_keymap.c
        intern/wm_subwindow.c
        intern/wm_window.c
        intern/wm_stereo.c
 +      manipulators/intern/wm_manipulator.c
 +      manipulators/intern/wm_manipulator_group.c
 +      manipulators/intern/wm_manipulator_group_type.c
 +      manipulators/intern/wm_manipulator_map.c
 +      manipulators/intern/wm_manipulator_target_props.c
 +      manipulators/intern/wm_manipulator_type.c
  
        WM_api.h
        WM_keymap.h
        wm_files.h
        wm_subwindow.h
        wm_window.h
 +      manipulators/WM_manipulator_api.h
 +      manipulators/WM_manipulator_types.h
 +      manipulators/wm_manipulator_fn.h
 +      manipulators/wm_manipulator_wmapi.h
 +      manipulators/intern/wm_manipulator_intern.h
  )
  
  if(WITH_AUDASPACE)
 -      add_definitions(${AUDASPACE_DEFINITIONS})
 +      add_definitions(-DWITH_AUDASPACE)
  
        list(APPEND INC_SYS
                ${AUDASPACE_C_INCLUDE_DIRS}
index 8eab8662ea9c26b7bfed5d548c46cd158c944844,e40026880c4a4e82ad9b069af027909e02bb4922..46aea519340aca9b92de7c578686272327fc8754
@@@ -64,17 -64,12 +64,17 @@@ struct wmDrag
  struct ImBuf;
  struct ImageFormatData;
  struct ARegion;
 +struct ScrArea;
 +struct Main;
  
  #ifdef WITH_INPUT_NDOF
  struct wmNDOFMotionData;
  #endif
  
  typedef struct wmJob wmJob;
 +typedef struct wmManipulator wmManipulator;
 +typedef struct wmManipulatorMap wmManipulatorMap;
 +typedef struct wmManipulatorMapType wmManipulatorMapType;
  
  /* general API */
  void          WM_init_state_size_set          (int stax, int stay, int sizx, int sizy);
@@@ -99,22 -94,6 +99,22 @@@ int                 WM_window_pixels_x              (struct wmWin
  int                   WM_window_pixels_y              (struct wmWindow *win);
  bool          WM_window_is_fullscreen (struct wmWindow *win);
  
 +void WM_windows_scene_data_sync(const ListBase *win_lb, struct Scene *scene) ATTR_NONNULL();
 +struct Scene *WM_windows_scene_get_from_screen(const struct wmWindowManager *wm, const struct bScreen *screen) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
 +struct WorkSpace *WM_windows_workspace_get_from_screen(const wmWindowManager *wm, const struct bScreen *screen) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
 +
 +struct Scene *WM_window_get_active_scene(const struct wmWindow *win) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
 +void          WM_window_change_active_scene(struct Main *bmain, struct bContext *C, struct wmWindow *win,
 +                                            struct Scene *scene_new) ATTR_NONNULL();
 +struct WorkSpace *WM_window_get_active_workspace(const struct wmWindow *win) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
 +void              WM_window_set_active_workspace(struct wmWindow *win, struct WorkSpace *workspace) ATTR_NONNULL(1);
 +struct WorkSpaceLayout *WM_window_get_active_layout(const struct wmWindow *win) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
 +void                    WM_window_set_active_layout(
 +        struct wmWindow *win, struct WorkSpace *workspace, struct WorkSpaceLayout *layout) ATTR_NONNULL(1);
 +struct bScreen *WM_window_get_active_screen(const struct wmWindow *win) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
 +void            WM_window_set_active_screen(struct wmWindow *win, struct WorkSpace *workspace, struct bScreen *screen) ATTR_NONNULL(1);
 +bool WM_window_is_temp_screen(const struct wmWindow *win) ATTR_WARN_UNUSED_RESULT;
 +
  /* defines for 'type' WM_window_open_temp */
  enum {
        WM_WINDOW_RENDER = 1,
@@@ -164,7 -143,6 +164,7 @@@ float              WM_cursor_pressure      (const struc
  
                        /* event map */
  int                   WM_userdef_event_map(int kmitype);
 +int                   WM_userdef_event_type_from_keymap_type(int kmitype);
  
                        /* handlers */
  
@@@ -194,9 -172,6 +194,9 @@@ void WM_event_free_ui_handler_all
          wmUIHandlerFunc ui_handle, wmUIHandlerRemoveFunc ui_remove);
  
  struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, struct wmOperator *op);
 +void WM_event_modal_handler_area_replace(wmWindow *win, const struct ScrArea *old_area, struct ScrArea *new_area);
 +void WM_event_modal_handler_region_replace(wmWindow *win, const struct ARegion *old_region, struct ARegion *new_region);
 +
  void          WM_event_remove_handlers(struct bContext *C, ListBase *handlers);
  
  /* handler flag */
@@@ -255,7 -230,6 +255,7 @@@ void               WM_operator_view3d_unit_defaults(
  int                   WM_operator_smooth_viewtx_get(const struct wmOperator *op);
  int                   WM_menu_invoke_ex(struct bContext *C, struct wmOperator *op, int opcontext);
  int                   WM_menu_invoke                  (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
 +int         WM_enum_search_invoke_previews(struct bContext *C, struct wmOperator *op, short prv_cols, short prv_rows);
  int                   WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
                        /* invoke callback, confirm menu + exec */
  int                   WM_operator_confirm             (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
@@@ -405,7 -379,7 +405,7 @@@ bool                WM_menutype_add(str
  void                WM_menutype_freelink(struct MenuType *mt);
  void                WM_menutype_free(void);
  
                      /* default operator callbacks for border/circle/lasso */
/* wm_gesture_ops.c */
  int                   WM_gesture_border_invoke        (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
  int                   WM_gesture_border_modal (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
  void          WM_gesture_border_cancel(struct bContext *C, struct wmOperator *op);
@@@ -449,7 -423,9 +449,7 @@@ ListBase   *WM_dropboxmap_find(const cha
  void          wmSubWindowSet                  (struct wmWindow *win, int swinid);
  void          wmSubWindowScissorSet   (struct wmWindow *win, int swinid, const struct rcti *srct, bool srct_pad);
  
 -                      /* OpenGL utilities with safety check + working in modelview matrix mode */
 -void          wmFrustum                       (float x1, float x2, float y1, float y2, float n, float f);
 -void          wmOrtho                         (float x1, float x2, float y1, float y2, float n, float f);
 +                      /* OpenGL utilities with safety check */
  void          wmOrtho2                        (float x1, float x2, float y1, float y2);
                        /* use for conventions (avoid hard-coded offsets all over) */
  void          wmOrtho2_region_pixelspace(const struct ARegion *ar);
index 77dbecec9f04bc81e0fc6d23508959641bc5985c,2417267397d0c79759dff09b15ea8def654e7f0c..a5b64c051562c5fb5292b9572702d04e74b7624b
@@@ -70,6 -70,7 +70,6 @@@
  #include "BKE_blender_version.h"
  #include "BKE_brush.h"
  #include "BKE_context.h"
 -#include "BKE_depsgraph.h"
  #include "BKE_icons.h"
  #include "BKE_idprop.h"
  #include "BKE_image.h"
  
  #include "BKE_idcode.h"
  
 -#include "BIF_glutil.h" /* for paint cursor */
  #include "BLF_api.h"
  
 +#include "GPU_immediate.h"
 +#include "GPU_immediate_util.h"
 +#include "GPU_matrix.h"
 +
  #include "IMB_imbuf_types.h"
  #include "IMB_imbuf.h"
  
@@@ -99,6 -97,8 +99,6 @@@
  #include "ED_util.h"
  #include "ED_view3d.h"
  
 -#include "GPU_basic_shader.h"
 -
  #include "RNA_access.h"
  #include "RNA_define.h"
  #include "RNA_enum_types.h"
  #include "wm_event_system.h"
  #include "wm_event_types.h"
  #include "wm_files.h"
- #include "wm_subwindow.h"
  #include "wm_window.h"
  
  static GHash *global_ops_hash = NULL;
@@@ -158,20 -157,18 +157,20 @@@ void WM_operatortype_iter(GHashIterato
        BLI_ghashIterator_init(ghi, global_ops_hash);
  }
  
 -/* all ops in 1 list (for time being... needs evaluation later) */
 -void WM_operatortype_append(void (*opfunc)(wmOperatorType *))
 +/** \name Operator Type Append
 + * \{ */
 +
 +static wmOperatorType *wm_operatortype_append__begin(void)
  {
 -      wmOperatorType *ot;
 -      
 -      ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
 +      wmOperatorType *ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
        ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
        /* Set the default i18n context now, so that opfunc can redefine it if needed! */
        RNA_def_struct_translation_context(ot->srna, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
        ot->translation_context = BLT_I18NCONTEXT_OPERATOR_DEFAULT;
 -      opfunc(ot);
 -
 +      return ot;
 +}
 +static void wm_operatortype_append__end(wmOperatorType *ot)
 +{
        if (ot->name == NULL) {
                fprintf(stderr, "ERROR: Operator %s has no name property!\n", ot->idname);
                ot->name = N_("Dummy Name");
        BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
  }
  
 -void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType *, void *), void *userdata)
 +/* all ops in 1 list (for time being... needs evaluation later) */
 +void WM_operatortype_append(void (*opfunc)(wmOperatorType *))
  {
 -      wmOperatorType *ot;
 +      wmOperatorType *ot = wm_operatortype_append__begin();
 +      opfunc(ot);
 +      wm_operatortype_append__end(ot);
 +}
  
 -      ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
 -      ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
 -      /* Set the default i18n context now, so that opfunc can redefine it if needed! */
 -      RNA_def_struct_translation_context(ot->srna, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
 -      ot->translation_context = BLT_I18NCONTEXT_OPERATOR_DEFAULT;
 +void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType *, void *), void *userdata)
 +{
 +      wmOperatorType *ot = wm_operatortype_append__begin();
        opfunc(ot, userdata);
 -      RNA_def_struct_ui_text(ot->srna, ot->name, ot->description ? ot->description : UNDOCUMENTED_OPERATOR_TIP);
 -      RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname);
 -
 -      BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
 +      wm_operatortype_append__end(ot);
  }
  
 +/** \} */
 +
  /* ********************* macro operator ******************** */
  
  typedef struct {
@@@ -1168,70 -1164,46 +1167,70 @@@ int WM_menu_invoke(bContext *C, wmOpera
        return WM_menu_invoke_ex(C, op, WM_OP_INVOKE_REGION_WIN);
  }
  
 +struct EnumSearchMenu {
 +      wmOperator *op; /* the operator that will be executed when selecting an item */
 +
 +      bool use_previews;
 +      short prv_cols, prv_rows;
 +};
  
  /* generic enum search invoke popup */
 -static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op)
 +static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg)
  {
 -      static char search[256] = "";
 -      wmEvent event;
 +      struct EnumSearchMenu *search_menu = arg;
        wmWindow *win = CTX_wm_window(C);
 +      wmOperator *op = search_menu->op;
 +      /* template_ID uses 4 * widget_unit for width, we use a bit more, some items may have a suffix to show */
 +      const int width = search_menu->use_previews ? 5 * U.widget_unit * search_menu->prv_cols : UI_searchbox_size_x();
 +      const int height = search_menu->use_previews ? 5 * U.widget_unit * search_menu->prv_rows : UI_searchbox_size_y();
 +      static char search[256] = "";
        uiBlock *block;
        uiBut *but;
 -      wmOperator *op = (wmOperator *)arg_op;
  
        block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
        UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
  
        search[0] = '\0';
 +      BLI_assert(search_menu->use_previews || (search_menu->prv_cols == 0 && search_menu->prv_rows == 0));
  #if 0 /* ok, this isn't so easy... */
        uiDefBut(block, UI_BTYPE_LABEL, 0, RNA_struct_ui_name(op->type->srna), 10, 10, UI_searchbox_size_x(), UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
  #endif
        but = uiDefSearchButO_ptr(block, op->type, op->ptr->data, search, 0, ICON_VIEWZOOM, sizeof(search),
 -                                10, 10, UI_searchbox_size_x(), UI_UNIT_Y, 0, 0, "");
 +                                10, 10, width, UI_UNIT_Y, search_menu->prv_rows, search_menu->prv_cols, "");
  
        /* fake button, it holds space for search items */
 -      uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 10 - UI_searchbox_size_y(), UI_searchbox_size_x(), UI_searchbox_size_y(), NULL, 0, 0, 0, 0, NULL);
 +      uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 10 - UI_searchbox_size_y(), width, height, NULL, 0, 0, 0, 0, NULL);
  
        UI_block_bounds_set_popup(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
 -
 -      wm_event_init_from_window(win, &event);
 -      event.type = EVT_BUT_OPEN;
 -      event.val = KM_PRESS;
 -      event.customdata = but;
 -      event.customdatafree = false;
 -      wm_event_add(win, &event);
 +      UI_but_focus_on_enter_event(win, but);
  
        return block;
  }
  
 +/**
 + * Similar to #WM_enum_search_invoke, but draws previews. Also, this can't
 + * be used as invoke callback directly since it needs additional info.
 + */
 +int WM_enum_search_invoke_previews(
 +        bContext *C, wmOperator *op, short prv_cols, short prv_rows)
 +{
 +      static struct EnumSearchMenu search_menu;
 +
 +      search_menu.op = op;
 +      search_menu.use_previews = true;
 +      search_menu.prv_cols = prv_cols;
 +      search_menu.prv_rows = prv_rows;
 +
 +      UI_popup_block_invoke(C, wm_enum_search_menu, &search_menu);
 +
 +      return OPERATOR_INTERFACE;
 +}
  
  int WM_enum_search_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
  {
 -      UI_popup_block_invoke(C, wm_enum_search_menu, op);
 +      static struct EnumSearchMenu search_menu;
 +      search_menu.op = op;
 +      UI_popup_block_invoke(C, wm_enum_search_menu, &search_menu);
        return OPERATOR_INTERFACE;
  }
  
@@@ -1887,8 -1859,8 +1886,8 @@@ static uiBlock *wm_block_create_splash(
        if (version_suffix != NULL && version_suffix[0]) {
                /* placed after the version number in the image,
                 * placing y is tricky to match baseline */
 -              int x = 260 * U.pixelsize - (2 * UI_DPI_FAC);
 -              int y = 242 * U.pixelsize + (4 * UI_DPI_FAC);
 +              int x = 236 * U.pixelsize - (2 * UI_DPI_FAC);
 +              int y = 231 * U.pixelsize + (4 * UI_DPI_FAC);
                int w = 240 * U.pixelsize;
  
                /* hack to have text draw 'text_sel' */
  
  #ifdef WITH_BUILDINFO
        if (build_commit_timestamp != 0) {
 -              uiDefBut(block, UI_BTYPE_LABEL, 0, date_buf, U.pixelsize * 494 - date_width, U.pixelsize * 270, date_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
 +              but = uiDefBut(
 +                        block, UI_BTYPE_LABEL, 0, date_buf,
 +                        U.pixelsize * 502 - date_width, U.pixelsize * 267,
 +                        date_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
 +              /* XXX, set internal flag - UI_SELECT */
 +              UI_but_flag_enable(but, 1);
                label_delta = 12;
        }
 -      uiDefBut(block, UI_BTYPE_LABEL, 0, hash_buf, U.pixelsize * 494 - hash_width, U.pixelsize * (270 - label_delta), hash_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
 +      but = uiDefBut(
 +                block, UI_BTYPE_LABEL, 0, hash_buf,
 +                U.pixelsize * 502 - hash_width, U.pixelsize * (267 - label_delta),
 +                hash_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
 +      /* XXX, set internal flag - UI_SELECT */
 +      UI_but_flag_enable(but, 1);
  
        if (!STREQ(build_branch, "master")) {
                char branch_buf[128] = "\0";
                int branch_width;
                BLI_snprintf(branch_buf, sizeof(branch_buf), "Branch: %s", build_branch);
                branch_width = (int)BLF_width(style->widgetlabel.uifont_id, branch_buf, sizeof(branch_buf)) + U.widget_unit;
 -              uiDefBut(block, UI_BTYPE_LABEL, 0, branch_buf, U.pixelsize * 494 - branch_width, U.pixelsize * (258 - label_delta), branch_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
 +              but = uiDefBut(
 +                        block, UI_BTYPE_LABEL, 0, branch_buf,
 +                        U.pixelsize * 502 - branch_width, U.pixelsize * (255 - label_delta),
 +                        branch_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
 +              /* XXX, set internal flag - UI_SELECT */
 +              UI_but_flag_enable(but, 1);
        }
  #endif  /* WITH_BUILDINFO */
        
@@@ -2173,11 -2130,8 +2172,11 @@@ static void WM_OT_call_menu_pie(wmOpera
  static int wm_operator_winactive_normal(bContext *C)
  {
        wmWindow *win = CTX_wm_window(C);
 +      bScreen *screen;
  
 -      if (win == NULL || win->screen == NULL || win->screen->state != SCREENNORMAL)
 +      if (win == NULL)
 +              return 0;
 +      if (!((screen = WM_window_get_active_screen(win)) && (screen->state == SCREENNORMAL)))
                return 0;
  
        return 1;
@@@ -2194,22 -2148,14 +2193,22 @@@ static void WM_OT_window_close(wmOperat
        ot->poll = WM_operator_winactive;
  }
  
 -static void WM_OT_window_duplicate(wmOperatorType *ot)
 +static void WM_OT_window_new(wmOperatorType *ot)
  {
 -      ot->name = "Duplicate Window";
 -      ot->idname = "WM_OT_window_duplicate";
 -      ot->description = "Duplicate the current Blender window";
 -              
 -      ot->exec = wm_window_duplicate_exec;
 +      PropertyRNA *prop;
 +
 +      ot->name = "New Window";
 +      ot->idname = "WM_OT_window_new";
 +      ot->description = "Create a new Blender window";
 +
 +      ot->exec = wm_window_new_exec;
 +      ot->invoke = wm_window_new_invoke;
        ot->poll = wm_operator_winactive_normal;
 +
 +      prop = RNA_def_enum(ot->srna, "screen", DummyRNA_NULL_items, 0, "Screen", "");
 +      RNA_def_enum_funcs(prop, wm_window_new_screen_itemf);
 +      RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
 +      ot->prop = prop;
  }
  
  static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot)
@@@ -2298,792 -2244,6 +2297,6 @@@ void WM_paint_cursor_end(wmWindowManage
        }
  }
  
- /* ************ window gesture operator-callback definitions ************** */
- /*
-  * These are default callbacks for use in operators requiring gesture input
-  */
- static void gesture_modal_state_to_operator(wmOperator *op, int modal_state)
- {
-       PropertyRNA *prop;
-       switch (modal_state) {
-               case GESTURE_MODAL_SELECT:
-               case GESTURE_MODAL_DESELECT:
-                       if ((prop = RNA_struct_find_property(op->ptr, "deselect"))) {
-                               RNA_property_boolean_set(op->ptr, prop, (modal_state == GESTURE_MODAL_DESELECT));
-                       }
-                       break;
-               case GESTURE_MODAL_IN:
-               case GESTURE_MODAL_OUT:
-                       if ((prop = RNA_struct_find_property(op->ptr, "zoom_out"))) {
-                               RNA_property_boolean_set(op->ptr, prop, (modal_state == GESTURE_MODAL_OUT));
-                       }
-                       break;
-       }
- }
- static int gesture_modal_state_from_operator(wmOperator *op)
- {
-       PropertyRNA *prop;
-       if ((prop = RNA_struct_find_property(op->ptr, "deselect"))) {
-               if (RNA_property_is_set(op->ptr, prop)) {
-                       return RNA_property_boolean_get(op->ptr, prop) ? GESTURE_MODAL_DESELECT : GESTURE_MODAL_SELECT;
-               }
-       }
-       if ((prop = RNA_struct_find_property(op->ptr, "zoom_out"))) {
-               if (RNA_property_is_set(op->ptr, prop)) {
-                       return RNA_property_boolean_get(op->ptr, prop) ? GESTURE_MODAL_OUT : GESTURE_MODAL_IN;
-               }
-       }
-       return GESTURE_MODAL_NOP;
- }
- /* **************** Border gesture *************** */
- /**
-  * Border gesture has two types:
-  * -# #WM_GESTURE_CROSS_RECT: starts a cross, on mouse click it changes to border.
-  * -# #WM_GESTURE_RECT: starts immediate as a border, on mouse click or release it ends.
-  *
-  * It stores 4 values (xmin, xmax, ymin, ymax) and event it ended with (event_type)
-  */
- static bool gesture_border_apply_rect(wmOperator *op)
- {
-       wmGesture *gesture = op->customdata;
-       rcti *rect = gesture->customdata;
-       
-       if (rect->xmin == rect->xmax || rect->ymin == rect->ymax)
-               return 0;
-       
-       /* operator arguments and storage. */
-       RNA_int_set(op->ptr, "xmin", min_ii(rect->xmin, rect->xmax));
-       RNA_int_set(op->ptr, "ymin", min_ii(rect->ymin, rect->ymax));
-       RNA_int_set(op->ptr, "xmax", max_ii(rect->xmin, rect->xmax));
-       RNA_int_set(op->ptr, "ymax", max_ii(rect->ymin, rect->ymax));
-       return 1;
- }
- static bool gesture_border_apply(bContext *C, wmOperator *op)
- {
-       wmGesture *gesture = op->customdata;
-       int retval;
-       if (!gesture_border_apply_rect(op)) {
-               return 0;
-       }
-       gesture_modal_state_to_operator(op, gesture->modal_state);
-       retval = op->type->exec(C, op);
-       OPERATOR_RETVAL_CHECK(retval);
-       return 1;
- }
- static void wm_gesture_end(bContext *C, wmOperator *op)
- {
-       wmGesture *gesture = op->customdata;
-       
-       WM_gesture_end(C, gesture); /* frees gesture itself, and unregisters from window */
-       op->customdata = NULL;
-       ED_area_tag_redraw(CTX_wm_area(C));
-       
-       if (RNA_struct_find_property(op->ptr, "cursor")) {
-               WM_cursor_modal_restore(CTX_wm_window(C));
-       }
- }
- int WM_gesture_border_invoke(bContext *C, wmOperator *op, const wmEvent *event)
- {
-       int modal_state = gesture_modal_state_from_operator(op);
-       if (ISTWEAK(event->type) || (modal_state != GESTURE_MODAL_NOP)) {
-               op->customdata = WM_gesture_new(C, event, WM_GESTURE_RECT);
-       }
-       else {
-               op->customdata = WM_gesture_new(C, event, WM_GESTURE_CROSS_RECT);
-       }
-       /* Starting with the mode starts immediately, like having 'wait_for_input' disabled (some tools use this). */
-       if (modal_state == GESTURE_MODAL_NOP) {
-               wmGesture *gesture = op->customdata;
-               gesture->wait_for_input = true;
-       }
-       else {
-               wmGesture *gesture = op->customdata;
-               gesture->modal_state = modal_state;
-       }
-       /* add modal handler */
-       WM_event_add_modal_handler(C, op);
-       wm_gesture_tag_redraw(C);
-       return OPERATOR_RUNNING_MODAL;
- }
- int WM_gesture_border_modal(bContext *C, wmOperator *op, const wmEvent *event)
- {
-       wmGesture *gesture = op->customdata;
-       rcti *rect = gesture->customdata;
-       int sx, sy;
-       
-       if (event->type == MOUSEMOVE) {
-               wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
-               if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->is_active == false) {
-                       rect->xmin = rect->xmax = event->x - sx;
-                       rect->ymin = rect->ymax = event->y - sy;
-               }
-               else {
-                       rect->xmax = event->x - sx;
-                       rect->ymax = event->y - sy;
-               }
-               gesture_border_apply_rect(op);
-               wm_gesture_tag_redraw(C);
-       }
-       else if (event->type == EVT_MODAL_MAP) {
-               switch (event->val) {
-                       case GESTURE_MODAL_BEGIN:
-                               if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->is_active == false) {
-                                       gesture->is_active = true;
-                                       wm_gesture_tag_redraw(C);
-                               }
-                               break;
-                       case GESTURE_MODAL_SELECT:
-                       case GESTURE_MODAL_DESELECT:
-                       case GESTURE_MODAL_IN:
-                       case GESTURE_MODAL_OUT:
-                               if (gesture->wait_for_input) {
-                                       gesture->modal_state = event->val;
-                               }
-                               if (gesture_border_apply(C, op)) {
-                                       wm_gesture_end(C, op);
-                                       return OPERATOR_FINISHED;
-                               }
-                               wm_gesture_end(C, op);
-                               return OPERATOR_CANCELLED;
-                       case GESTURE_MODAL_CANCEL:
-                               wm_gesture_end(C, op);
-                               return OPERATOR_CANCELLED;
-               }
-       }
- #ifdef WITH_INPUT_NDOF
-       else if (event->type == NDOF_MOTION) {
-               return OPERATOR_PASS_THROUGH;
-       }
- #endif
- //    /* Allow view navigation??? */
- //    else {
- //            return OPERATOR_PASS_THROUGH;
- //    }
-       return OPERATOR_RUNNING_MODAL;
- }
- void WM_gesture_border_cancel(bContext *C, wmOperator *op)
- {
-       wm_gesture_end(C, op);
- }
- /* **************** circle gesture *************** */
- /* works now only for selection or modal paint stuff, calls exec while hold mouse, exit on release */
- static void gesture_circle_apply(bContext *C, wmOperator *op);
- int WM_gesture_circle_invoke(bContext *C, wmOperator *op, const wmEvent *event)
- {
-       int modal_state = gesture_modal_state_from_operator(op);
-       op->customdata = WM_gesture_new(C, event, WM_GESTURE_CIRCLE);
-       wmGesture *gesture = op->customdata;
-       rcti *rect = gesture->customdata;
-       
-       /* Default or previously stored value. */
-       rect->xmax = RNA_int_get(op->ptr, "radius");
-       /* Starting with the mode starts immediately, like having 'wait_for_input' disabled (some tools use this). */
-       if (modal_state == GESTURE_MODAL_NOP) {
-               gesture->wait_for_input = true;
-       }
-       else {
-               gesture->is_active = true;
-               gesture->modal_state = modal_state;
-               gesture_circle_apply(C, op);
-       }
-       /* add modal handler */
-       WM_event_add_modal_handler(C, op);
-       
-       wm_gesture_tag_redraw(C);
-       
-       return OPERATOR_RUNNING_MODAL;
- }
- static void gesture_circle_apply(bContext *C, wmOperator *op)
- {
-       wmGesture *gesture = op->customdata;
-       rcti *rect = gesture->customdata;
-       if (gesture->modal_state == GESTURE_MODAL_NOP) {
-               return;
-       }
-       /* operator arguments and storage. */
-       RNA_int_set(op->ptr, "x", rect->xmin);
-       RNA_int_set(op->ptr, "y", rect->ymin);
-       RNA_int_set(op->ptr, "radius", rect->xmax);
-       gesture_modal_state_to_operator(op, gesture->modal_state);
-       if (op->type->exec) {
-               int retval;
-               retval = op->type->exec(C, op);
-               OPERATOR_RETVAL_CHECK(retval);
-       }
- }
- int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
- {
-       wmGesture *gesture = op->customdata;
-       rcti *rect = gesture->customdata;
-       int sx, sy;
-       if (event->type == MOUSEMOVE) {
-               wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
-               rect->xmin = event->x - sx;
-               rect->ymin = event->y - sy;
-               wm_gesture_tag_redraw(C);
-               if (gesture->is_active) {
-                       gesture_circle_apply(C, op);
-               }
-       }
-       else if (event->type == EVT_MODAL_MAP) {
-               bool is_circle_size = false;
-               bool is_finished = false;
-               float fac;
-               
-               switch (event->val) {
-                       case GESTURE_MODAL_CIRCLE_SIZE:
-                               fac = 0.3f * (event->y - event->prevy);
-                               if (fac > 0)
-                                       rect->xmax += ceil(fac);
-                               else
-                                       rect->xmax += floor(fac);
-                               if (rect->xmax < 1) rect->xmax = 1;
-                               is_circle_size = true;
-                               break;
-                       case GESTURE_MODAL_CIRCLE_ADD:
-                               rect->xmax += 2 + rect->xmax / 10;
-                               is_circle_size = true;
-                               break;
-                       case GESTURE_MODAL_CIRCLE_SUB:
-                               rect->xmax -= 2 + rect->xmax / 10;
-                               if (rect->xmax < 1) rect->xmax = 1;
-                               is_circle_size = true;
-                               break;
-                       case GESTURE_MODAL_SELECT:
-                       case GESTURE_MODAL_DESELECT:
-                       case GESTURE_MODAL_NOP:
-                       {
-                               if (gesture->wait_for_input) {
-                                       gesture->modal_state = event->val;
-                               }
-                               if (event->val == GESTURE_MODAL_NOP) {
-                                       /* Single action, click-drag & release to exit. */
-                                       if (gesture->wait_for_input == false) {
-                                               is_finished = true;
-                                       }
-                               }
-                               else {
-                                       /* apply first click */
-                                       gesture_circle_apply(C, op);
-                                       gesture->is_active = true;
-                                       wm_gesture_tag_redraw(C);
-                               }
-                               break;
-                       }
-                       case GESTURE_MODAL_CANCEL:
-                       case GESTURE_MODAL_CONFIRM:
-                               is_finished = true;
-               }
-               if (is_finished) {
-                       wm_gesture_end(C, op);
-                       return OPERATOR_FINISHED; /* use finish or we don't get an undo */
-               }
-               if (is_circle_size) {
-                       wm_gesture_tag_redraw(C);
-                       /* So next use remembers last seen size, even if we didn't apply it. */
-                       RNA_int_set(op->ptr, "radius", rect->xmax);
-               }
-       }
- #ifdef WITH_INPUT_NDOF
-       else if (event->type == NDOF_MOTION) {
-               return OPERATOR_PASS_THROUGH;
-       }
- #endif
-       /* Allow view navigation??? */
-       /* note, this gives issues: 1) other modal ops run on top (border select), 2) middlemouse is used now 3) tablet/trackpad? */
- //    else {
- //            return OPERATOR_PASS_THROUGH;
- //    }
-       return OPERATOR_RUNNING_MODAL;
- }
- void WM_gesture_circle_cancel(bContext *C, wmOperator *op)
- {
-       wm_gesture_end(C, op);
- }
- #if 0
- /* template to copy from */
- void WM_OT_circle_gesture(wmOperatorType *ot)
- {
-       ot->name = "Circle Gesture";
-       ot->idname = "WM_OT_circle_gesture";
-       ot->description = "Enter rotate mode with a circular gesture";
-       
-       ot->invoke = WM_gesture_circle_invoke;
-       ot->modal = WM_gesture_circle_modal;
-       ot->poll = WM_operator_winactive;
-       /* properties */
-       WM_operator_properties_gesture_circle(ot);
- }
- #endif
- /* **************** Tweak gesture *************** */
- static void tweak_gesture_modal(bContext *C, const wmEvent *event)
- {
-       wmWindow *window = CTX_wm_window(C);
-       wmGesture *gesture = window->tweak;
-       rcti *rect = gesture->customdata;
-       int sx, sy, val;
-       
-       switch (event->type) {
-               case MOUSEMOVE:
-               case INBETWEEN_MOUSEMOVE:
-                       
-                       wm_subwindow_origin_get(window, gesture->swinid, &sx, &sy);
-                       
-                       rect->xmax = event->x - sx;
-                       rect->ymax = event->y - sy;
-                       
-                       if ((val = wm_gesture_evaluate(gesture))) {
-                               wmEvent tevent;
-                               wm_event_init_from_window(window, &tevent);
-                               /* We want to get coord from start of drag, not from point where it becomes a tweak event, see T40549 */
-                               tevent.x = rect->xmin + sx;
-                               tevent.y = rect->ymin + sy;
-                               if (gesture->event_type == LEFTMOUSE)
-                                       tevent.type = EVT_TWEAK_L;
-                               else if (gesture->event_type == RIGHTMOUSE)
-                                       tevent.type = EVT_TWEAK_R;
-                               else
-                                       tevent.type = EVT_TWEAK_M;
-                               tevent.val = val;
-                               /* mouse coords! */
-                               /* important we add immediately after this event, so future mouse releases
-                                * (which may be in the queue already), are handled in order, see T44740 */
-                               wm_event_add_ex(window, &tevent, event);
-                               
-                               WM_gesture_end(C, gesture); /* frees gesture itself, and unregisters from window */
-                       }
-                       
-                       break;
-                       
-               case LEFTMOUSE:
-               case RIGHTMOUSE:
-               case MIDDLEMOUSE:
-                       if (gesture->event_type == event->type) {
-                               WM_gesture_end(C, gesture);
-                               /* when tweak fails we should give the other keymap entries a chance */
-                               /* XXX, assigning to readonly, BAD JUJU! */
-                               ((wmEvent *)event)->val = KM_RELEASE;
-                       }
-                       break;
-               default:
-                       if (!ISTIMER(event->type) && event->type != EVENT_NONE) {
-                               WM_gesture_end(C, gesture);
-                       }
-                       break;
-       }
- }
- /* standard tweak, called after window handlers passed on event */
- void wm_tweakevent_test(bContext *C, const wmEvent *event, int action)
- {
-       wmWindow *win = CTX_wm_window(C);
-       
-       if (win->tweak == NULL) {
-               if (CTX_wm_region(C)) {
-                       if (event->val == KM_PRESS) {
-                               if (ELEM(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE)) {
-                                       win->tweak = WM_gesture_new(C, event, WM_GESTURE_TWEAK);
-                               }
-                       }
-               }
-       }
-       else {
-               /* no tweaks if event was handled */
-               if ((action & WM_HANDLER_BREAK)) {
-                       WM_gesture_end(C, win->tweak);
-               }
-               else
-                       tweak_gesture_modal(C, event);
-       }
- }
- /* *********************** lasso gesture ****************** */
- int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
- {
-       PropertyRNA *prop;
-       op->customdata = WM_gesture_new(C, event, WM_GESTURE_LASSO);
-       
-       /* add modal handler */
-       WM_event_add_modal_handler(C, op);
-       
-       wm_gesture_tag_redraw(C);
-       
-       if ((prop = RNA_struct_find_property(op->ptr, "cursor"))) {
-               WM_cursor_modal_set(CTX_wm_window(C), RNA_property_int_get(op->ptr, prop));
-       }
-       
-       return OPERATOR_RUNNING_MODAL;
- }
- int WM_gesture_lines_invoke(bContext *C, wmOperator *op, const wmEvent *event)
- {
-       PropertyRNA *prop;
-       op->customdata = WM_gesture_new(C, event, WM_GESTURE_LINES);
-       
-       /* add modal handler */
-       WM_event_add_modal_handler(C, op);
-       
-       wm_gesture_tag_redraw(C);
-       
-       if ((prop = RNA_struct_find_property(op->ptr, "cursor"))) {
-               WM_cursor_modal_set(CTX_wm_window(C), RNA_property_int_get(op->ptr, prop));
-       }
-       
-       return OPERATOR_RUNNING_MODAL;
- }
- static void gesture_lasso_apply(bContext *C, wmOperator *op)
- {
-       wmGesture *gesture = op->customdata;
-       PointerRNA itemptr;
-       float loc[2];
-       int i;
-       const short *lasso = gesture->customdata;
-       
-       /* operator storage as path. */
-       RNA_collection_clear(op->ptr, "path");
-       for (i = 0; i < gesture->points; i++, lasso += 2) {
-               loc[0] = lasso[0];
-               loc[1] = lasso[1];
-               RNA_collection_add(op->ptr, "path", &itemptr);
-               RNA_float_set_array(&itemptr, "loc", loc);
-       }
-       
-       wm_gesture_end(C, op);
-               
-       if (op->type->exec) {
-               int retval = op->type->exec(C, op);
-               OPERATOR_RETVAL_CHECK(retval);
-       }
- }
- int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
- {
-       wmGesture *gesture = op->customdata;
-       int sx, sy;
-       
-       switch (event->type) {
-               case MOUSEMOVE:
-               case INBETWEEN_MOUSEMOVE:
-                       wm_gesture_tag_redraw(C);
-                       wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
-                       if (gesture->points == gesture->points_alloc) {
-                               gesture->points_alloc *= 2;
-                               gesture->customdata = MEM_reallocN(gesture->customdata, sizeof(short[2]) * gesture->points_alloc);
-                       }
-                       {
-                               int x, y;
-                               short *lasso = gesture->customdata;
-                               lasso += (2 * gesture->points - 2);
-                               x = (event->x - sx - lasso[0]);
-                               y = (event->y - sy - lasso[1]);
-                               /* make a simple distance check to get a smoother lasso
-                                * add only when at least 2 pixels between this and previous location */
-                               if ((x * x + y * y) > 4) {
-                                       lasso += 2;
-                                       lasso[0] = event->x - sx;
-                                       lasso[1] = event->y - sy;
-                                       gesture->points++;
-                               }
-                       }
-                       break;
-               case LEFTMOUSE:
-               case MIDDLEMOUSE:
-               case RIGHTMOUSE:
-                       if (event->val == KM_RELEASE) {   /* key release */
-                               gesture_lasso_apply(C, op);
-                               return OPERATOR_FINISHED;
-                       }
-                       break;
-               case ESCKEY:
-                       wm_gesture_end(C, op);
-                       return OPERATOR_CANCELLED;
-       }
-       return OPERATOR_RUNNING_MODAL;
- }
- int WM_gesture_lines_modal(bContext *C, wmOperator *op, const wmEvent *event)
- {
-       return WM_gesture_lasso_modal(C, op, event);
- }
- void WM_gesture_lasso_cancel(bContext *C, wmOperator *op)
- {
-       wm_gesture_end(C, op);
- }
- void WM_gesture_lines_cancel(bContext *C, wmOperator *op)
- {
-       wm_gesture_end(C, op);
- }
- /**
-  * helper function, we may want to add options for conversion to view space
-  *
-  * caller must free.
-  */
- const int (*WM_gesture_lasso_path_to_array(bContext *UNUSED(C), wmOperator *op, int *mcords_tot))[2]
- {
-       PropertyRNA *prop = RNA_struct_find_property(op->ptr, "path");
-       int (*mcords)[2] = NULL;
-       BLI_assert(prop != NULL);
-       if (prop) {
-               const int len = RNA_property_collection_length(op->ptr, prop);
-               if (len) {
-                       int i = 0;
-                       mcords = MEM_mallocN(sizeof(int) * 2 * len, __func__);
-                       RNA_PROP_BEGIN (op->ptr, itemptr, prop)
-                       {
-                               float loc[2];
-                               RNA_float_get_array(&itemptr, "loc", loc);
-                               mcords[i][0] = (int)loc[0];
-                               mcords[i][1] = (int)loc[1];
-                               i++;
-                       }
-                       RNA_PROP_END;
-               }
-               *mcords_tot = len;
-       }
-       else {
-               *mcords_tot = 0;
-       }
-       /* cast for 'const' */
-       return (const int (*)[2])mcords;
- }
- #if 0
- /* template to copy from */
- static int gesture_lasso_exec(bContext *C, wmOperator *op)
- {
-       RNA_BEGIN (op->ptr, itemptr, "path")
-       {
-               float loc[2];
-               
-               RNA_float_get_array(&itemptr, "loc", loc);
-               printf("Location: %f %f\n", loc[0], loc[1]);
-       }
-       RNA_END;
-       
-       return OPERATOR_FINISHED;
- }
- void WM_OT_lasso_gesture(wmOperatorType *ot)
- {
-       PropertyRNA *prop;
-       
-       ot->name = "Lasso Gesture";
-       ot->idname = "WM_OT_lasso_gesture";
-       ot->description = "Select objects within the lasso as you move the pointer";
-       
-       ot->invoke = WM_gesture_lasso_invoke;
-       ot->modal = WM_gesture_lasso_modal;
-       ot->exec = gesture_lasso_exec;
-       
-       ot->poll = WM_operator_winactive;
-       
-       prop = RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
-       RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
- }
- #endif
- /* *********************** straight line gesture ****************** */
- static int straightline_apply(bContext *C, wmOperator *op)
- {
-       wmGesture *gesture = op->customdata;
-       rcti *rect = gesture->customdata;
-       
-       if (rect->xmin == rect->xmax && rect->ymin == rect->ymax)
-               return 0;
-       
-       /* operator arguments and storage. */
-       RNA_int_set(op->ptr, "xstart", rect->xmin);
-       RNA_int_set(op->ptr, "ystart", rect->ymin);
-       RNA_int_set(op->ptr, "xend", rect->xmax);
-       RNA_int_set(op->ptr, "yend", rect->ymax);
-       if (op->type->exec) {
-               int retval = op->type->exec(C, op);
-               OPERATOR_RETVAL_CHECK(retval);
-       }
-       
-       return 1;
- }
- int WM_gesture_straightline_invoke(bContext *C, wmOperator *op, const wmEvent *event)
- {
-       PropertyRNA *prop;
-       op->customdata = WM_gesture_new(C, event, WM_GESTURE_STRAIGHTLINE);
-       
-       if (ISTWEAK(event->type)) {
-               wmGesture *gesture = op->customdata;
-               gesture->is_active = true;
-       }
-       /* add modal handler */
-       WM_event_add_modal_handler(C, op);
-       
-       wm_gesture_tag_redraw(C);
-       
-       if ((prop = RNA_struct_find_property(op->ptr, "cursor"))) {
-               WM_cursor_modal_set(CTX_wm_window(C), RNA_property_int_get(op->ptr, prop));
-       }
-               
-       return OPERATOR_RUNNING_MODAL;
- }
- int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *event)
- {
-       wmGesture *gesture = op->customdata;
-       rcti *rect = gesture->customdata;
-       int sx, sy;
-       
-       if (event->type == MOUSEMOVE) {
-               wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
-               
-               if (gesture->is_active == false) {
-                       rect->xmin = rect->xmax = event->x - sx;
-                       rect->ymin = rect->ymax = event->y - sy;
-               }
-               else {
-                       rect->xmax = event->x - sx;
-                       rect->ymax = event->y - sy;
-                       straightline_apply(C, op);
-               }
-               
-               wm_gesture_tag_redraw(C);
-       }
-       else if (event->type == EVT_MODAL_MAP) {
-               switch (event->val) {
-                       case GESTURE_MODAL_BEGIN:
-                               if (gesture->is_active == false) {
-                                       gesture->is_active = true;
-                                       wm_gesture_tag_redraw(C);
-                               }
-                               break;
-                       case GESTURE_MODAL_SELECT:
-                               if (straightline_apply(C, op)) {
-                                       wm_gesture_end(C, op);
-                                       return OPERATOR_FINISHED;
-                               }
-                               wm_gesture_end(C, op);
-                               return OPERATOR_CANCELLED;
-                               
-                       case GESTURE_MODAL_CANCEL:
-                               wm_gesture_end(C, op);
-                               return OPERATOR_CANCELLED;
-               }
-               
-       }
-       return OPERATOR_RUNNING_MODAL;
- }
- void WM_gesture_straightline_cancel(bContext *C, wmOperator *op)
- {
-       wm_gesture_end(C, op);
- }
- #if 0
- /* template to copy from */
- void WM_OT_straightline_gesture(wmOperatorType *ot)
- {
-       PropertyRNA *prop;
-       
-       ot->name = "Straight Line Gesture";
-       ot->idname = "WM_OT_straightline_gesture";
-       ot->description = "Draw a straight line as you move the pointer";
-       
-       ot->invoke = WM_gesture_straightline_invoke;
-       ot->modal = WM_gesture_straightline_modal;
-       ot->exec = gesture_straightline_exec;
-       
-       ot->poll = WM_operator_winactive;
-       
-       WM_operator_properties_gesture_straightline(ot, 0);
- }
- #endif
  /* *********************** radial control ****************** */
  
  #define WM_RADIAL_CONTROL_DISPLAY_SIZE (200 * UI_DPI_FAC)
@@@ -3199,8 -2359,8 +2412,8 @@@ static void radial_control_set_tex(Radi
                        if ((ibuf = BKE_brush_gen_radial_control_imbuf(rc->image_id_ptr.data, rc->use_secondary_tex))) {
                                glGenTextures(1, &rc->gltex);
                                glBindTexture(GL_TEXTURE_2D, rc->gltex);
 -                              glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA8, ibuf->x, ibuf->y, 0,
 -                                           GL_ALPHA, GL_FLOAT, ibuf->rect_float);
 +                              glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, ibuf->x, ibuf->y, 0,
 +                                           GL_RED, GL_FLOAT, ibuf->rect_float);
                                MEM_freeN(ibuf->rect_float);
                                MEM_freeN(ibuf);
                        }
@@@ -3233,63 -2393,43 +2446,63 @@@ static void radial_control_paint_tex(Ra
  
                RNA_property_float_get_array(fill_ptr, fill_prop, col);
        }
 -      glColor4f(col[0], col[1], col[2], alpha);
 +              
 +      Gwn_VertFormat *format = immVertexFormat();
 +      unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
  
        if (rc->gltex) {
 +
 +              unsigned int texCoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 +
                glBindTexture(GL_TEXTURE_2D, rc->gltex);
  
 -              glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 -              glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 +              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 +              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 +
 +              GLint swizzleMask[] = {GL_ZERO, GL_ZERO, GL_ZERO, GL_RED};
 +              glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
 +
 +              immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR);
 +
 +              immUniformColor3fvAlpha(col, alpha);
 +              immUniform1i("image", GL_TEXTURE0);
  
                /* set up rotation if available */
                if (rc->rot_prop) {
                        rot = RNA_property_float_get(&rc->rot_ptr, rc->rot_prop);
 -                      glPushMatrix();
 -                      glRotatef(RAD2DEGF(rot), 0, 0, 1);
 +                      gpuPushMatrix();
 +                      gpuRotate2D(RAD2DEGF(rot));
                }
  
                /* draw textured quad */
 -              GPU_basic_shader_bind(GPU_SHADER_TEXTURE_2D | GPU_SHADER_USE_COLOR);
 -              glBegin(GL_QUADS);
 -              glTexCoord2f(0, 0);
 -              glVertex2f(-radius, -radius);
 -              glTexCoord2f(1, 0);
 -              glVertex2f(radius, -radius);
 -              glTexCoord2f(1, 1);
 -              glVertex2f(radius, radius);
 -              glTexCoord2f(0, 1);
 -              glVertex2f(-radius, radius);
 -              glEnd();
 -              GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
 +              immBegin(GWN_PRIM_TRI_FAN, 4);
 +
 +              immAttrib2f(texCoord, 0, 0);
 +              immVertex2f(pos, -radius, -radius);
 +
 +              immAttrib2f(texCoord, 1, 0);
 +              immVertex2f(pos, radius, -radius);
 +              
 +              immAttrib2f(texCoord, 1, 1);
 +              immVertex2f(pos, radius, radius);
 +              
 +              immAttrib2f(texCoord, 0, 1);
 +              immVertex2f(pos, -radius, radius);
 +
 +              immEnd();
  
                /* undo rotation */
                if (rc->rot_prop)
 -                      glPopMatrix();
 +                      gpuPopMatrix();
        }
        else {
                /* flat color if no texture available */
 -              glutil_draw_filled_arc(0, M_PI * 2, radius, 40);
 +              immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +              immUniformColor3fvAlpha(col, alpha);
 +              imm_draw_circle_fill_2d(pos, 0.0f, 0.0f, radius, 40);
        }
 +      
 +      immUnbindProgram();
  }
  
  static void radial_control_paint_cursor(bContext *C, int x, int y, void *customdata)
        /* Keep cursor in the original place */
        x = rc->initial_mouse[0] - ar->winrct.xmin;
        y = rc->initial_mouse[1] - ar->winrct.ymin;
 -      glTranslatef((float)x, (float)y, 0.0f);
 +      gpuTranslate2f((float)x, (float)y);
  
        glEnable(GL_BLEND);
        glEnable(GL_LINE_SMOOTH);
        /* apply zoom if available */
        if (rc->zoom_prop) {
                RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
 -              glScalef(zoom[0], zoom[1], 1);
 +              gpuScale2fv(zoom);
        }
  
        /* draw rotated texture */
        /* set line color */
        if (rc->col_prop)
                RNA_property_float_get_array(&rc->col_ptr, rc->col_prop, col);
 -      glColor4f(col[0], col[1], col[2], 0.5);
 +
 +      Gwn_VertFormat *format = immVertexFormat();
 +      unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 +
 +      immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +      immUniformColor3fvAlpha(col, 0.5f);
  
        if (rc->subtype == PROP_ANGLE) {
 -              glPushMatrix();
 +              gpuPushMatrix();
 +
                /* draw original angle line */
 -              glRotatef(RAD2DEGF(rc->initial_value), 0, 0, 1);
 -              fdrawline((float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f);
 +              gpuRotate2D(RAD2DEGF(rc->initial_value));
 +              immBegin(GWN_PRIM_LINES, 2);
 +              immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f);
 +              immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f);
 +              immEnd();
 +
                /* draw new angle line */
 -              glRotatef(RAD2DEGF(rc->current_value - rc->initial_value), 0, 0, 1);
 -              fdrawline((float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f);
 -              glPopMatrix();
 +              gpuRotate2D(RAD2DEGF(rc->current_value - rc->initial_value));
 +              immBegin(GWN_PRIM_LINES, 2);
 +              immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f);
 +              immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f);
 +              immEnd();
 +
 +              gpuPopMatrix();
        }
  
        /* draw circles on top */
 -      glutil_draw_lined_arc(0.0, (float)(M_PI * 2.0), r1, 40);
 -      glutil_draw_lined_arc(0.0, (float)(M_PI * 2.0), r2, 40);
 +      imm_draw_circle_wire_2d(pos, 0.0f, 0.0f, r1, 40);
 +      imm_draw_circle_wire_2d(pos, 0.0f, 0.0f, r2, 40);
        if (rmin > 0.0f)
 -              glutil_draw_lined_arc(0.0, (float)(M_PI * 2.0), rmin, 40);
 +              imm_draw_circle_wire_2d(pos, 0.0, 0.0f, rmin, 40);
 +      immUnbindProgram();
  
        BLF_size(fontid, 1.5 * fstyle_points * U.pixelsize, U.dpi);
        BLF_enable(fontid, BLF_SHADOW);
  
        glDisable(GL_BLEND);
        glDisable(GL_LINE_SMOOTH);
 +
  }
  
  typedef enum {
@@@ -3992,12 -3116,11 +3205,12 @@@ static void redraw_timer_step
                CTX_wm_window_set(C, win);  /* XXX context manipulation warning! */
        }
        else if (type == eRTDrawWindow) {
 +              bScreen *screen = WM_window_get_active_screen(win);
                ScrArea *sa_iter;
  
                CTX_wm_menu_set(C, NULL);
  
 -              for (sa_iter = win->screen->areabase.first; sa_iter; sa_iter = sa_iter->next) {
 +              for (sa_iter = screen->areabase.first; sa_iter; sa_iter = sa_iter->next) {
                        ARegion *ar_iter;
                        CTX_wm_area_set(C, sa_iter);
  
        }
        else if (type == eRTAnimationStep) {
                scene->r.cfra += (cfra == scene->r.cfra) ? 1 : -1;
 -              BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
 +              BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
        }
        else if (type == eRTAnimationPlay) {
                /* play anim, return on same frame as started with */
                        if (scene->r.cfra > scene->r.efra)
                                scene->r.cfra = scene->r.sfra;
  
 -                      BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay);
 +                      BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene);
                        redraw_timer_window_swap(C);
                }
        }
@@@ -4120,6 -3243,28 +3333,6 @@@ static void WM_OT_memory_statistics(wmO
        ot->exec = memory_statistics_exec;
  }
  
 -/* ************************** memory statistics for testing ***************** */
 -
 -static int dependency_relations_exec(bContext *C, wmOperator *UNUSED(op))
 -{
 -      Main *bmain = CTX_data_main(C);
 -      Scene *scene = CTX_data_scene(C);
 -      Object *ob = CTX_data_active_object(C);
 -
 -      DAG_print_dependencies(bmain, scene, ob);
 -
 -      return OPERATOR_FINISHED;
 -}
 -
 -static void WM_OT_dependency_relations(wmOperatorType *ot)
 -{
 -      ot->name = "Dependency Relations";
 -      ot->idname = "WM_OT_dependency_relations";
 -      ot->description = "Print dependency graph relations to the console";
 -      
 -      ot->exec = dependency_relations_exec;
 -}
 -
  /* *************************** Mat/tex/etc. previews generation ************* */
  
  typedef struct PreviewsIDEnsureData {
@@@ -4366,13 -3511,12 +3579,13 @@@ void wm_operatortype_init(void
        global_ops_hash = BLI_ghash_str_new_ex("wm_operatortype_init gh", 2048);
  
        WM_operatortype_append(WM_OT_window_close);
 -      WM_operatortype_append(WM_OT_window_duplicate);
 +      WM_operatortype_append(WM_OT_window_new);
        WM_operatortype_append(WM_OT_read_history);
        WM_operatortype_append(WM_OT_read_homefile);
        WM_operatortype_append(WM_OT_read_factory_settings);
        WM_operatortype_append(WM_OT_save_homefile);
        WM_operatortype_append(WM_OT_save_userpref);
 +      WM_operatortype_append(WM_OT_save_workspace_file);
        WM_operatortype_append(WM_OT_userpref_autoexec_path_add);
        WM_operatortype_append(WM_OT_userpref_autoexec_path_remove);
        WM_operatortype_append(WM_OT_window_fullscreen_toggle);
        WM_operatortype_append(WM_OT_save_mainfile);
        WM_operatortype_append(WM_OT_redraw_timer);
        WM_operatortype_append(WM_OT_memory_statistics);
 -      WM_operatortype_append(WM_OT_dependency_relations);
        WM_operatortype_append(WM_OT_debug_menu);
        WM_operatortype_append(WM_OT_operator_defaults);
        WM_operatortype_append(WM_OT_splash);
        WM_operatortype_append(WM_OT_previews_ensure);
        WM_operatortype_append(WM_OT_previews_clear);
        WM_operatortype_append(WM_OT_doc_view_manual_ui_context);
 +
 +      /* manipulators */
 +      WM_operatortype_append(MANIPULATORGROUP_OT_manipulator_select);
 +      WM_operatortype_append(MANIPULATORGROUP_OT_manipulator_tweak);
  }
  
  /* circleselect-like modal operators */
@@@ -4609,7 -3750,7 +3822,7 @@@ void wm_window_keymap(wmKeyConfig *keyc
        wmKeyMapItem *kmi;
        
        /* note, this doesn't replace existing keymap items */
 -      WM_keymap_verify_item(keymap, "WM_OT_window_duplicate", WKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
 +      WM_keymap_verify_item(keymap, "WM_OT_window_new", WKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
  #ifdef __APPLE__
        WM_keymap_add_item(keymap, "WM_OT_read_homefile", NKEY, KM_PRESS, KM_OSKEY, 0);
        WM_keymap_add_menu(keymap, "INFO_MT_file_open_recent", OKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0);
        RNA_float_set(kmi->ptr, "value", 1.0f / 1.5f);
  #endif /* WITH_INPUT_NDOF */
  
 +      wm_manipulators_keymap(keyconf);
        gesture_circle_modal_keymap(keyconf);
        gesture_border_modal_keymap(keyconf);
        gesture_zoom_border_modal_keymap(keyconf);
index 01c8d6c1999ff29a2af739591f5660a41337629a,a417a719b8dd1e17ee4b8866eff6c39178aa5e78..83d20aa2612350b8f9045152e30794a401d274a8
@@@ -34,8 -34,6 +34,8 @@@
  struct wmWindow;
  struct ReportList;
  
 +#include "manipulators/wm_manipulator_wmapi.h"
 +
  typedef struct wmPaintCursor {
        struct wmPaintCursor *next, *prev;
  
@@@ -59,13 -57,14 +59,14 @@@ void wm_operatortype_free(void)
  void wm_operatortype_init(void);
  void wm_window_keymap(wmKeyConfig *keyconf);
  
- void wm_tweakevent_test(bContext *C, const wmEvent *event, int action);
  /* wm_gesture.c */
  void wm_gesture_draw(struct wmWindow *win);
  int wm_gesture_evaluate(wmGesture *gesture);
  void wm_gesture_tag_redraw(bContext *C);
  
+ /* wm_gesture_ops.c */
+ void wm_tweakevent_test(bContext *C, const wmEvent *event, int action);
  /* wm_jobs.c */
  void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt);
  void wm_jobs_timer_ended(wmWindowManager *wm, wmTimer *wt);