Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Thu, 7 Jun 2018 14:45:10 +0000 (16:45 +0200)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 7 Jun 2018 14:45:34 +0000 (16:45 +0200)
18 files changed:
1  2 
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/WM_keymap.h
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm.c
source/blender/windowmanager/intern/wm_cursors.c
source/blender/windowmanager/intern/wm_dragdrop.c
source/blender/windowmanager/intern/wm_draw.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_files.c
source/blender/windowmanager/intern/wm_files_link.c
source/blender/windowmanager/intern/wm_gesture.c
source/blender/windowmanager/intern/wm_init_exit.c
source/blender/windowmanager/intern/wm_keymap.c
source/blender/windowmanager/intern/wm_operators.c
source/blender/windowmanager/intern/wm_playanim.c
source/blender/windowmanager/intern/wm_window.c
source/blender/windowmanager/wm.h
source/blender/windowmanager/wm_event_types.h

@@@ -142,7 -104,10 +142,7 @@@ enum 
  struct wmWindow       *WM_window_open(struct bContext *C, const struct rcti *rect);
  struct wmWindow *WM_window_open_temp(struct bContext *C, int x, int y, int sizex, int sizey, int type);
  void             WM_window_set_dpi(wmWindow *win);
-                       
 -                      /* returns true if draw method is triple buffer */
 -bool          WM_is_draw_triple(struct wmWindow *win);
 -
  bool          WM_stereo3d_enabled(struct wmWindow *win, bool only_fullscreen_test);
  
  
@@@ -211,14 -199,15 +211,14 @@@ typedef enum eOperatorPropTags 
  
  typedef struct wmNotifier {
        struct wmNotifier *next, *prev;
-       
        struct wmWindowManager *wm;
        struct wmWindow *window;
-       
 -      int swinid;                     /* can't rely on this, notifiers can be added without context, swinid of 0 */
        unsigned int category, data, subtype, action;
-       
        void *reference;
-       
  } wmNotifier;
  
  
@@@ -372,10 -359,10 +372,10 @@@ void WM_keymap_init(bContext *C
                wm->addonconf = WM_keyconfig_new(wm, "Blender Addon");
        if (!wm->userconf)
                wm->userconf = WM_keyconfig_new(wm, "Blender User");
-       
        /* initialize only after python init is done, for keymaps that
         * use python operators */
 -      if (CTX_py_init_get(C) && (wm->initialized & WM_INIT_KEYMAP) == 0) {
 +      if (CTX_py_init_get(C) && (wm->initialized & WM_KEYMAP_IS_INITIALIZED) == 0) {
                /* create default key config, only initialize once,
                 * it's persistent across sessions */
                if (!(wm->defaultconf->flag & KEYCONF_INIT_DEFAULT)) {
@@@ -487,10 -467,11 +487,10 @@@ void wm_close_and_free(bContext *C, wmW
                wm_autosave_timer_ended(wm);
  
        while ((win = BLI_pophead(&wm->windows))) {
 -              win->screen = NULL; /* prevent draw clear to use screen */
 -              wm_draw_window_clear(win);
 +              WM_window_set_active_workspace(win, NULL); /* prevent draw clear to use screen */
                wm_window_free(C, wm, win);
        }
-       
        while ((op = BLI_pophead(&wm->operators))) {
                WM_operator_free(op);
        }
@@@ -41,8 -41,7 +41,8 @@@
  #include "BLI_sys_types.h"
  
  #include "DNA_listBase.h"
- #include "DNA_userdef_types.h" 
+ #include "DNA_userdef_types.h"
 +#include "DNA_workspace_types.h"
  
  #include "BKE_context.h"
  #include "BKE_global.h"
@@@ -365,10 -361,10 +365,10 @@@ void wm_drags_draw(bContext *C, wmWindo
                        drag_rect_minmax(rect, x, y, x + w, y + iconsize);
                }
                else {
 -                      glColor4ub(255, 255, 255, 255);
 -                      UI_fontstyle_draw_simple(fstyle, x, y, wm_drag_name(drag));
 +                      const unsigned char col[] = {255, 255, 255, 255};
 +                      UI_fontstyle_draw_simple(fstyle, x, y, wm_drag_name(drag), col);
                }
-               
                /* operator name with roundbox */
                if (drag->opname[0]) {
                        if (drag->imb) {
@@@ -801,12 -967,16 +801,12 @@@ void wm_draw_update(bContext *C
                        continue;
                }
  #endif
 -              if (win->drawmethod != U.wmdrawmethod) {
 -                      wm_draw_window_clear(win);
 -                      win->drawmethod = U.wmdrawmethod;
 -              }
  
                if (wm_draw_update_test_window(win)) {
 -                      bScreen *screen = win->screen;
 +                      bScreen *screen = WM_window_get_active_screen(win);
  
                        CTX_wm_window_set(C, win);
-                       
                        /* sets context window+screen */
                        wm_window_make_drawable(wm, win);
  
@@@ -194,12 -190,16 +194,12 @@@ void WM_event_add_notifier(const bConte
                return;
  
        note = MEM_callocN(sizeof(wmNotifier), "notifier");
-       
        note->wm = wm;
        BLI_addtail(&note->wm->queue, note);
-       
        note->window = CTX_wm_window(C);
-       
 -      ar = CTX_wm_region(C);
 -      if (ar)
 -              note->swinid = ar->swinid;
 -
        note->category = type & NOTE_CATEGORY;
        note->data = type & NOTE_DATA;
        note->subtype = type & NOTE_SUBTYPE;
@@@ -357,15 -331,12 +357,15 @@@ void wm_event_do_notifiers(bContext *C
        if (wm == NULL)
                return;
  
 +      /* disable? - keep for now since its used for window level notifiers. */
 +#if 1
        /* cache & catch WM level notifiers, such as frame change, scene/screen set */
        for (win = wm->windows.first; win; win = win->next) {
 +              Scene *scene = WM_window_get_active_scene(win);
                bool do_anim = false;
-               
                CTX_wm_window_set(C, win);
-               
                for (note = wm->queue.first; note; note = next) {
                        next = note->next;
  
                                }
                        }
                }
-               
                MEM_freeN(note);
        }
 +#endif /* if 1 (postpone disabling for in favor of message-bus), eventually. */
 +
 +      /* Handle message bus. */
 +      {
 +              for (win = wm->windows.first; win; win = win->next) {
 +                      CTX_wm_window_set(C, win);
 +                      WM_msgbus_handle(wm->message_bus, C);
 +              }
 +              CTX_wm_window_set(C, NULL);
 +      }
  
        wm_event_do_refresh_wm_and_depsgraph(C);
  }
@@@ -1466,12 -1355,12 +1466,12 @@@ static int wm_operator_call_internal
                                        if (ar1)
                                                CTX_wm_region_set(C, ar1);
                                }
-                               
 -                              retval = wm_operator_invoke(C, ot, event, properties, reports, poll_only);
 +                              retval = wm_operator_invoke(C, ot, event, properties, reports, poll_only, true);
-                               
                                /* set region back */
                                CTX_wm_region_set(C, ar);
-                               
                                return retval;
                        }
                        case WM_OP_EXEC_AREA:
                        }
                        case WM_OP_EXEC_DEFAULT:
                        case WM_OP_INVOKE_DEFAULT:
 -                              return wm_operator_invoke(C, ot, event, properties, reports, poll_only);
 +                              return wm_operator_invoke(C, ot, event, properties, reports, poll_only, true);
                }
        }
-       
        return 0;
  }
  
@@@ -1600,9 -1489,8 +1600,9 @@@ void wm_event_free_handler(wmEventHandl
  /* only set context when area/region is part of screen */
  static void wm_handler_op_context(bContext *C, wmEventHandler *handler, const wmEvent *event)
  {
 +      wmWindow *win = CTX_wm_window(C);
        bScreen *screen = CTX_wm_screen(C);
-       
        if (screen && handler->op) {
                if (handler->op_area == NULL)
                        CTX_wm_area_set(C, NULL);
@@@ -1975,21 -1826,9 +1975,21 @@@ static int wm_handler_operator_call(bCo
        else {
                wmOperatorType *ot = WM_operatortype_find(event->keymap_idname, 0);
  
 -              if (ot) {
 -                      if (wm_operator_check_locked_interface(C, ot)) {
 -                              retval = wm_operator_invoke(C, ot, event, properties, NULL, false);
 +              if (ot && wm_operator_check_locked_interface(C, ot)) {
 +                      bool use_last_properties = true;
 +                      PointerRNA tool_properties = {{0}};
 +                      bool use_tool_properties = (handler->keymap_tool != NULL);
-                       
++
 +                      if (use_tool_properties) {
 +                              WM_toolsystem_ref_properties_init_for_keymap(handler->keymap_tool, &tool_properties, properties, ot);
 +                              properties = &tool_properties;
 +                              use_last_properties = false;
 +                      }
 +
 +                      retval = wm_operator_invoke(C, ot, event, properties, NULL, false, use_last_properties);
 +
 +                      if (use_tool_properties) {
 +                              WM_operator_properties_free(&tool_properties);
                        }
                }
        }
@@@ -2272,7 -2109,6 +2272,7 @@@ static int wm_handlers_do_intern(bConte
                                                        event->keymap_idname = kmi->idname;
  
                                                        action |= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr);
-                                                       
++
                                                        if (action & WM_HANDLER_BREAK) {
                                                                /* not always_pass here, it denotes removed handler */
                                                                CLOG_INFO(WM_LOG_HANDLERS, 2, "handled! '%s'", kmi->idname);
@@@ -2593,15 -2288,13 +2593,15 @@@ static int wm_event_inside_i(wmEvent *e
  
  static ScrArea *area_event_inside(bContext *C, const int xy[2])
  {
 +      wmWindow *win = CTX_wm_window(C);
        bScreen *screen = CTX_wm_screen(C);
-       
 -      ScrArea *sa;
 -      if (screen)
 -              for (sa = screen->areabase.first; sa; sa = sa->next)
 +      if (screen) {
 +              ED_screen_areas_iter(win, screen, sa) {
                        if (BLI_rcti_isect_pt_v(&sa->totrct, xy))
                                return sa;
 +              }
 +      }
        return NULL;
  }
  
@@@ -2664,9 -2355,9 +2664,9 @@@ static void wm_event_drag_test(wmWindow
        if (BLI_listbase_is_empty(&wm->drags)) {
                return;
        }
-       
        if (event->type == MOUSEMOVE || ISKEYMODIFIER(event->type)) {
 -              win->screen->do_draw_drag = true;
 +              screen->do_draw_drag = true;
        }
        else if (event->type == ESCKEY) {
                WM_drag_free_list(&wm->drags);
                event->custom = EVT_DATA_DRAGDROP;
                event->customdata = &wm->drags;
                event->customdatafree = 1;
-               
                /* clear drop icon */
 -              win->screen->do_draw_drag = true;
 +              screen->do_draw_drag = true;
-               
                /* restore cursor (disabled, see wm_dragdrop.c) */
                // WM_cursor_modal_restore(win);
        }
@@@ -2720,30 -2417,24 +2720,30 @@@ void wm_event_do_handlers(bContext *C
  
        /* update key configuration before handling events */
        WM_keyconfig_update(wm);
 +      WM_manipulatorconfig_update(CTX_data_main(C));
  
        for (win = wm->windows.first; win; win = win->next) {
 +              bScreen *screen = WM_window_get_active_screen(win);
                wmEvent *event;
  
 -              if (win->screen == NULL)
 +              /* some safty checks - these should always be set! */
 +              BLI_assert(WM_window_get_active_scene(win));
 +              BLI_assert(WM_window_get_active_screen(win));
 +              BLI_assert(WM_window_get_active_workspace(win));
 +
 +              if (screen == NULL)
                        wm_event_free_all(win);
                else {
 -                      Scene *scene = win->screen->scene;
 +                      Scene *scene = WM_window_get_active_scene(win);
  
                        if (scene) {
 -                              int is_playing_sound = BKE_sound_scene_playing(win->screen->scene);
 +                              int is_playing_sound = BKE_sound_scene_playing(scene);
-                               
                                if (is_playing_sound != -1) {
                                        bool is_playing_screen;
                                        CTX_wm_window_set(C, win);
 -                                      CTX_wm_screen_set(C, win->screen);
                                        CTX_data_scene_set(C, scene);
-                                       
                                        is_playing_screen = (ED_screen_animation_playing(wm) != NULL);
  
                                        if (((is_playing_sound == 1) && (is_playing_screen == 0)) ||
                        wm_tweakevent_test(C, event, action);
  
                        if ((action & WM_HANDLER_BREAK) == 0) {
 -                              ScrArea *sa;
                                ARegion *ar;
-       
                                /* Note: setting subwin active should be done here, after modal handlers have been done */
                                if (event->type == MOUSEMOVE) {
                                        /* state variables in screen, cursors. Also used in wm_draw.c, fails for modal handlers though */
@@@ -3027,13 -2679,13 +3027,13 @@@ void WM_event_add_fileselect(bContext *
        /* only allow 1 file selector open per window */
        for (handler = win->modalhandlers.first; handler; handler = handlernext) {
                handlernext = handler->next;
-               
                if (handler->type == WM_HANDLER_FILESELECT) {
                        bScreen *screen = CTX_wm_screen(C);
 -                      ScrArea *sa;
 +                      bool cancel_handler = true;
  
                        /* find the area with the file selector for this handler */
 -                      for (sa = screen->areabase.first; sa; sa = sa->next) {
 +                      ED_screen_areas_iter(win, screen, sa) {
                                if (sa->spacetype == SPACE_FILE) {
                                        SpaceFile *sfile = sa->spacedata.first;
  
                        }
  
                        /* if not found we stop the handler without changing the screen */
 -                      if (!sa)
 +                      if (cancel_handler) {
                                wm_handler_fileselect_do(C, &win->modalhandlers, handler, EVT_FILESELECT_EXTERNAL_CANCEL);
 +                      }
                }
        }
-       
        handler = MEM_callocN(sizeof(wmEventHandler), "fileselect handler");
-       
        handler->type = WM_HANDLER_FILESELECT;
        handler->op = op;
        handler->op_area = CTX_wm_area(C);
@@@ -169,10 -163,10 +169,10 @@@ static void wm_window_match_init(bConte
                        CTX_wm_window_set(C, win);  /* needed by operator close callbacks */
                        WM_event_remove_handlers(C, &win->handlers);
                        WM_event_remove_handlers(C, &win->modalhandlers);
 -                      ED_screen_exit(C, win, win->screen);
 +                      ED_screen_exit(C, win, WM_window_get_active_screen(win));
                }
        }
-       
        /* reset active window */
        CTX_wm_window_set(C, active_win);
  
@@@ -875,9 -857,9 +875,9 @@@ int wm_homefile_read
                /* check userdef before open window, keymaps etc */
                wm_init_userdef(bmain, read_userdef_from_memory);
        }
-       
        /* match the read WM with current WM */
 -      wm_window_match_do(bmain, C, &wmbase);
 +      wm_window_match_do(C, &wmbase, &bmain->wm, &bmain->wm);
        WM_check(C); /* opens window(s), checks keymaps */
  
        bmain->name[0] = '\0';
@@@ -369,10 -332,10 +369,10 @@@ static int wm_link_append_exec(bContex
  
        /* from here down, no error returns */
  
 -      if (scene && RNA_boolean_get(op->ptr, "autoselect")) {
 -              BKE_scene_base_deselect_all(scene);
 +      if (view_layer && RNA_boolean_get(op->ptr, "autoselect")) {
 +              BKE_view_layer_base_deselect_all(view_layer);
        }
-       
        /* tag everything, all untagged data can be made local
         * its also generally useful to know what is new
         *
@@@ -63,23 -64,26 +63,23 @@@ wmGesture *WM_gesture_new(bContext *C, 
        wmGesture *gesture = MEM_callocN(sizeof(wmGesture), "new gesture");
        wmWindow *window = CTX_wm_window(C);
        ARegion *ar = CTX_wm_region(C);
-       
 -      int sx, sy;
        BLI_addtail(&window->gesture, gesture);
-       
        gesture->type = type;
        gesture->event_type = event->type;
 -      gesture->swinid = ar->swinid;    /* means only in area-region context! */
 +      gesture->winrct = ar->winrct;
        gesture->userdata_free = true;   /* Free if userdata is set. */
        gesture->modal_state = GESTURE_MODAL_NOP;
-       
 -      wm_subwindow_origin_get(window, gesture->swinid, &sx, &sy);
 -
        if (ELEM(type, WM_GESTURE_RECT, WM_GESTURE_CROSS_RECT, WM_GESTURE_TWEAK,
                  WM_GESTURE_CIRCLE, WM_GESTURE_STRAIGHTLINE))
        {
                rcti *rect = MEM_callocN(sizeof(rcti), "gesture rect new");
-               
                gesture->customdata = rect;
 -              rect->xmin = event->x - sx;
 -              rect->ymin = event->y - sy;
 +              rect->xmin = event->x - gesture->winrct.xmin;
 +              rect->ymin = event->y - gesture->winrct.ymin;
                if (type == WM_GESTURE_CIRCLE) {
                        /* caller is responsible for initializing 'xmax' to radius. */
                }
                short *lasso;
                gesture->points_alloc = 1024;
                gesture->customdata = lasso = MEM_mallocN(sizeof(short[2]) * gesture->points_alloc, "lasso points");
 -              lasso[0] = event->x - sx;
 -              lasso[1] = event->y - sy;
 +              lasso[0] = event->x - gesture->winrct.xmin;
 +              lasso[1] = event->y - gesture->winrct.ymin;
                gesture->points = 1;
        }
-       
        return gesture;
  }
  
@@@ -417,11 -362,11 +417,11 @@@ void wm_gesture_draw(wmWindow *win
  {
        wmGesture *gt = (wmGesture *)win->gesture.first;
  
 -      GPU_basic_shader_line_width(1);
 +      glLineWidth(1.0f);
        for (; gt; gt = gt->next) {
                /* all in subwindow space */
 -              wmSubWindowSet(win, gt->swinid);
 +              wmViewport(&gt->winrct);
-               
                if (gt->type == WM_GESTURE_RECT)
                        wm_gesture_draw_rect(gt);
  //            else if (gt->type == WM_GESTURE_TWEAK)
  
  void wm_gesture_tag_redraw(bContext *C)
  {
 -      wmWindow *win = CTX_wm_window(C);
        bScreen *screen = CTX_wm_screen(C);
-       
 -      ARegion *ar = CTX_wm_region(C);
        if (screen)
                screen->do_draw_gesture = true;
 -
 -      wm_tag_redraw_overlay(win, ar);
  }
@@@ -222,15 -176,16 +222,15 @@@ void WM_init(bContext *C, int argc, con
        BKE_library_callback_remap_editor_id_reference_set(WM_main_remap_editor_id_reference);   /* library.c */
        BKE_blender_callback_test_break_set(wm_window_testbreak); /* blender.c */
        BKE_spacedata_callback_id_remap_set(ED_spacedata_id_remap); /* screen.c */
 -      DAG_editors_update_cb(ED_render_id_flush_update,
 -                            ED_render_scene_update,
 -                            ED_render_scene_update_pre); /* depsgraph.c */
 +      DEG_editors_set_update_cb(ED_render_id_flush_update,
 +                                ED_render_scene_update);
-       
        ED_spacetypes_init();   /* editors/space_api/spacetype.c */
-       
        ED_file_init();         /* for fsmenu */
        ED_node_init_butfuncs();
-       
 -      BLF_init(); /* Please update source/gamengine/GamePlayer/GPG_ghost.cpp if you change this */
 +      BLF_init();
        BLT_lang_init();
  
        /* reports cant be initialized before the wm,
@@@ -463,10 -517,15 +463,10 @@@ void WM_exit_ext(bContext *C, const boo
  
        ED_undosys_type_free();
  
 -//    XXX
 -//    BIF_GlobalReebFree();
 -//    BIF_freeRetarget();
 -      BIF_freeTemplates(C);
 -
        free_openrecent();
-       
        BKE_mball_cubeTable_free();
-       
        /* render code might still access databases */
        RE_FreeAllRender();
        RE_engines_exit();
        COM_deinitialize();
  #endif
  
-       
 +      if (opengl_is_init) {
 +#ifdef WITH_OPENSUBDIV
 +              BKE_subsurf_osd_cleanup();
 +#endif
 +
 +              GPU_free_unused_buffers();
 +
 +              GPU_exit();
 +      }
++
        BKE_blender_free();  /* blender.c, does entire library and spacetypes */
  //    free_matcopybuf();
        ANIM_fcurves_copybuf_free();
        wm_ghost_exit();
  
        CTX_free(C);
-       
 -#ifdef WITH_GAMEENGINE
 -      SYS_DeleteSystem(SYS_GetSystem());
 -#endif
        GHOST_DisposeSystemPaths();
  
        DNA_sdna_current_free();
@@@ -1519,10 -1416,9 +1519,10 @@@ static uiBlock *wm_block_create_redo(bC
                }
        }
        else {
 -              uiTemplateOperatorPropertyButs(C, layout, op, NULL, 'H', UI_TEMPLATE_OP_PROPS_SHOW_TITLE);
 +              uiTemplateOperatorPropertyButs(C, layout, op, NULL, UI_BUT_LABEL_ALIGN_SPLIT_COLUMN,
 +                                             UI_TEMPLATE_OP_PROPS_SHOW_TITLE);
        }
-       
        UI_block_bounds_set_popup(block, 4, 0, 0);
  
        return block;
@@@ -1588,10 -1484,9 +1588,10 @@@ static uiBlock *wm_block_dialog_create(
        UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_NUMSELECT);
  
        layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style);
-       
 -      uiTemplateOperatorPropertyButs(C, layout, op, NULL, 'H', UI_TEMPLATE_OP_PROPS_SHOW_TITLE);
 +      uiTemplateOperatorPropertyButs(C, layout, op, NULL, UI_BUT_LABEL_ALIGN_SPLIT_COLUMN,
 +                                     UI_TEMPLATE_OP_PROPS_SHOW_TITLE);
-       
        /* clear so the OK button is left alone */
        UI_block_func_set(block, NULL, NULL, NULL);
  
@@@ -2003,17 -1888,12 +2003,17 @@@ static uiBlock *wm_block_create_splash(
                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 */
-       
        layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, U.pixelsize * 480, U.pixelsize * 110, 0, style);
-       
        UI_block_emboss_set(block, UI_EMBOSS);
        /* show the splash menu (containing interaction presets), using python */
        if (mt) {
@@@ -2563,27 -2397,13 +2563,27 @@@ 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);
 +
 +              glActiveTexture(GL_TEXTURE0);
                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", 0);
  
                /* set up rotation if available */
                if (rc->rot_prop) {
                }
  
                /* 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)
        }
        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)
 +static void radial_control_paint_cursor(bContext *UNUSED(C), int x, int y, void *customdata)
  {
        RadialControl *rc = customdata;
 -      ARegion *ar = CTX_wm_region(C);
        uiStyle *style = UI_style_get();
        const uiFontStyle *fstyle = &style->widget;
        const int fontid = fstyle->uifont_id;
@@@ -3952,9 -3764,9 +3952,9 @@@ void wm_window_keymap(wmKeyConfig *keyc
  {
        wmKeyMap *keymap = WM_keymap_find(keyconf, "Window", 0, 0);
        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);
@@@ -1547,10 -1534,10 +1547,10 @@@ static char *wm_main_playanim_intern(in
                BLI_strncpy(filepath, ps.dropped_file, sizeof(filepath));
                return filepath;
        }
-       
        IMB_exit();
        BKE_images_exit();
 -      DAG_exit();
 +      DEG_free_node_types();
  
        totblock = MEM_get_memory_blocks_in_use();
        if (totblock != 0) {
  #include <stdio.h>
  #include <string.h>
  
- #include "DNA_listBase.h"     
+ #include "DNA_listBase.h"
  #include "DNA_screen_types.h"
  #include "DNA_windowmanager_types.h"
 +#include "DNA_workspace_types.h"
  
  #include "MEM_guardedalloc.h"
  
@@@ -226,12 -206,14 +226,12 @@@ void wm_window_free(bContext *C, wmWind
        }
  
        if (win->eventstate) MEM_freeN(win->eventstate);
-       
        wm_event_free_all(win);
 -      wm_subwindows_free(win);
  
 -      wm_draw_data_free(win);
 -
 -      wm_ghostwindow_destroy(win);
 +      wm_ghostwindow_destroy(wm, win);
  
 +      BKE_workspace_instance_hook_free(G.main, win->workspace_hook);
        MEM_freeN(win->stereo3d_format);
  
        MEM_freeN(win);
@@@ -499,12 -463,13 +499,12 @@@ void wm_window_close(bContext *C, wmWin
                wm_quit_with_optional_confirmation_prompt(C, win);
        }
        else {
 -              /* We're just closing a window */
 -              bScreen *screen = win->screen;
 +              bScreen *screen = WM_window_get_active_screen(win);
 +              WorkSpace *workspace = WM_window_get_active_workspace(win);
 +              WorkSpaceLayout *layout = BKE_workspace_active_layout_get(win->workspace_hook);
  
                BLI_remlink(&wm->windows, win);
-               
 -              wm_draw_window_clear(win);
 -
                CTX_wm_window_set(C, win);  /* needed by handlers */
                WM_event_remove_handlers(C, &win->handlers);
                WM_event_remove_handlers(C, &win->modalhandlers);
@@@ -627,8 -566,16 +627,8 @@@ static void wm_window_ghostwindow_add(w
  {
        GHOST_WindowHandle ghostwin;
        GHOST_GLSettings glSettings = {0};
 -      static int multisamples = -1;
        int scr_w, scr_h, posy;
-       
 -      /* force setting multisamples only once, it requires restart - and you cannot
 -       * mix it, either all windows have it, or none (tested in OSX opengl) */
 -      if (multisamples == -1)
 -              multisamples = U.ogl_multisamples;
 -
 -      glSettings.numOfAASamples = multisamples;
 -
        /* a new window is created when pageflip mode is required for a window */
        if (win->stereo3d_format->display_mode == S3D_DISPLAY_PAGEFLIP)
                glSettings.flags |= GHOST_glStereoVisual;
        if (ghostwin) {
                GHOST_RectangleHandle bounds;
  
-               
 +              /* XXX Fix crash when a new window is created.
 +               * However this should be move somewhere else. (fclem) */
 +              BLF_batch_reset();
 +              gpu_batch_presets_reset();
 +
 +              win->gwnctx = GWN_context_create();
++
                /* the new window has already been made drawable upon creation */
                wm->windrawable = win;
  
                /* needed so we can detect the graphics card below */
                GPU_init();
-               
                win->ghostwin = ghostwin;
                GHOST_SetWindowUserData(ghostwin, win); /* pointer back */
-               
 -              if (win->eventstate == NULL)
 -                      win->eventstate = MEM_callocN(sizeof(wmEvent), "window event state");
 -
 -              /* store multisamples window was created with, in case user prefs change */
 -              win->multisamples = multisamples;
 +              wm_window_ensure_eventstate(win);
  
                /* store actual window size in blender window */
                bounds = GHOST_GetClientBounds(win->ghostwin);
                if (!GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE)) {
                        glClear(GL_COLOR_BUFFER_BIT);
                }
-               
                /* needed here, because it's used before it reads userdef */
                WM_window_set_dpi(win);
-               
                wm_window_swap_buffers(win);
-               
                //GHOST_SetWindowState(ghostwin, GHOST_kWindowStateModified);
-               
                /* standard state vars for window */
 -              glEnable(GL_SCISSOR_TEST);
                GPU_state_init();
        }
  }
@@@ -875,12 -817,12 +875,12 @@@ wmWindow *WM_window_open_temp(bContext 
  
        /* changes rect to fit within desktop */
        wm_window_check_position(&rect);
-       
        /* test if we have a temp screen already */
        for (win = CTX_wm_manager(C)->windows.first; win; win = win->next)
 -              if (win->screen->temp)
 +              if (WM_window_is_temp_screen(win))
                        break;
-       
        /* add new window? */
        if (win == NULL) {
                win = wm_window_new(C);
         */
  
        /* ensure it shows the right spacetype editor */
 -      sa = win->screen->areabase.first;
 +      sa = screen->areabase.first;
        CTX_wm_area_set(C, sa);
-       
        if (type == WM_WINDOW_RENDER) {
                ED_area_newspace(C, sa, SPACE_IMAGE, false);
        }
        else {
                ED_area_newspace(C, sa, SPACE_USERPREF, false);
        }
-       
 -      ED_screen_set(C, win->screen);
 +      ED_screen_change(C, screen);
        ED_screen_refresh(CTX_wm_manager(C), win); /* test scale */
-       
 +      /* do additional setup for specific editor type */
 +      if (type == WM_WINDOW_DRIVERS) {
 +              /* Configure editor - mode, tabs, framing */
 +              SpaceIpo *sipo = (SpaceIpo *)sa->spacedata.first;
 +              sipo->mode = SIPO_MODE_DRIVERS;
-               
++
 +              ARegion *ar_props = BKE_area_find_region_type(sa, RGN_TYPE_UI);
 +              if (ar_props) {
 +                      UI_panel_category_active_set(ar_props, "Drivers");
-                       
++
 +                      ar_props->flag &= ~RGN_FLAG_HIDDEN;
 +                      /* XXX: Adjust width of this too? */
-                       
++
 +                      ED_region_visibility_change_update(C, ar_props);
 +              }
-               
++
 +              ARegion *ar_main = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
 +              if (ar_main) {
 +                      /* XXX: Ideally we recenter based on the range instead... */
 +                      ar_main->v2d.tot.xmin = -2.0f;
 +                      ar_main->v2d.tot.ymin = -2.0f;
 +                      ar_main->v2d.tot.xmax = 2.0f;
 +                      ar_main->v2d.tot.ymax = 2.0f;
-                       
++
 +                      ar_main->v2d.cur = ar_main->v2d.tot;
 +              }
 +      }
-       
++
        if (sa->spacetype == SPACE_IMAGE)
                title = IFACE_("Blender Render");
        else if (ELEM(sa->spacetype, SPACE_OUTLINER, SPACE_USERPREF))
@@@ -1206,10 -1009,8 +1206,10 @@@ static int query_qual(modifierKeyType q
        return val;
  }
  
- void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win) 
+ void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win)
  {
 +      BLI_assert(GPU_framebuffer_current_get() == 0);
 +
        if (win != wm->windrawable && win->ghostwin) {
  //            win->lmbut = 0; /* keeps hanging when mousepressed while other window opened */
  
@@@ -1268,10 -1041,10 +1268,10 @@@ static int ghost_event_proc(GHOST_Event
                GHOST_WindowHandle ghostwin = GHOST_GetEventWindow(evt);
                GHOST_TEventDataPtr data = GHOST_GetEventData(evt);
                wmWindow *win;
-               
                /* Ghost now can call this function for life resizes, but it should return if WM didn't initialize yet.
                 * Can happen on file read (especially full size window)  */
 -              if ((wm->initialized & WM_INIT_WINDOW) == 0) {
 +              if ((wm->initialized & WM_WINDOW_IS_INITIALIZED) == 0) {
                        return 1;
                }
                if (!ghostwin) {
                                                                       win->posx, win->posy, win->sizex, win->sizey);
                                                        }
                                                }
-                                       
                                                wm_window_make_drawable(wm, win);
 -                                              wm_draw_window_clear(win);
 +                                              BKE_icon_changed(screen->id.icon_id);
                                                WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
                                                WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL);
-                                               
  #if defined(__APPLE__) || defined(WIN32)
                                                /* OSX and Win32 don't return to the mainloop while resize */
                                                wm_event_do_notifiers(C);
@@@ -1774,18 -1542,11 +1774,18 @@@ void wm_window_testbreak(void
  void wm_ghost_init(bContext *C)
  {
        if (!g_system) {
 -              GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(ghost_event_proc, C);
 +              GHOST_EventConsumerHandle consumer;
 +
 +              if (C != NULL) {
 +                      consumer = GHOST_CreateEventConsumer(ghost_event_proc, C);
 +              }
-               
                g_system = GHOST_CreateSystem();
 -              GHOST_AddEventConsumer(g_system, consumer);
 +
 +              if (C != NULL) {
 +                      GHOST_AddEventConsumer(g_system, consumer);
 +              }
-               
                if (wm_init_state.native_pixels) {
                        GHOST_UseNativePixels();
                }
@@@ -2120,58 -1887,19 +2120,58 @@@ float WM_cursor_pressure(const struct w
  
  /* support for native pixel size */
  /* mac retina opens window in size X, but it has up to 2 x more pixels */
 -int WM_window_pixels_x(wmWindow *win)
 +int WM_window_pixels_x(const wmWindow *win)
  {
        float f = GHOST_GetNativePixelSize(win->ghostwin);
-       
        return (int)(f * (float)win->sizex);
  }
 -
 -int WM_window_pixels_y(wmWindow *win)
 +int WM_window_pixels_y(const wmWindow *win)
  {
        float f = GHOST_GetNativePixelSize(win->ghostwin);
-       
        return (int)(f * (float)win->sizey);
 +}
  
 +/**
 + * Get boundaries usable by all window contents, including global areas.
 + */
 +void WM_window_rect_calc(const wmWindow *win, rcti *r_rect)
 +{
 +      BLI_rcti_init(r_rect, 0, WM_window_pixels_x(win), 0, WM_window_pixels_y(win));
 +}
 +/**
 + * Get boundaries usable by screen-layouts, excluding global areas.
 + * \note Depends on U.dpi_fac. Should that be outdated, call #WM_window_set_dpi first.
 + */
 +void WM_window_screen_rect_calc(const wmWindow *win, rcti *r_rect)
 +{
 +      rcti rect;
 +
 +      BLI_rcti_init(&rect, 0, WM_window_pixels_x(win), 0, WM_window_pixels_y(win));
 +
 +      /* Substract global areas from screen rectangle. */
 +      for (ScrArea *global_area = win->global_areas.areabase.first; global_area; global_area = global_area->next) {
 +              if (global_area->global->flag & GLOBAL_AREA_IS_HIDDEN) {
 +                      continue;
 +              }
 +
 +              switch (global_area->global->align) {
 +                      case GLOBAL_AREA_ALIGN_TOP:
 +                              rect.ymax -= ED_area_global_size_y(global_area);
 +                              break;
 +                      case GLOBAL_AREA_ALIGN_BOTTOM:
 +                              rect.ymin += ED_area_global_size_y(global_area);
 +                              break;
 +                      default:
 +                              BLI_assert(0);
 +                              break;
 +              }
 +      }
 +
 +      BLI_assert(rect.xmin < rect.xmax);
 +      BLI_assert(rect.ymin < rect.ymax);
 +      *r_rect = rect;
  }
  
  bool WM_window_is_fullscreen(wmWindow *win)
@@@ -52,9 -49,9 +52,9 @@@ void wm_exit_schedule_delayed(const bCo
  extern void wm_close_and_free(bContext *C, wmWindowManager *);
  extern void wm_close_and_free_all(bContext *C, ListBase *);
  
 -extern void wm_add_default(bContext *C);
 +extern void wm_add_default(struct Main *bmain, bContext *C);
  extern void wm_clear_default_size(bContext *C);
-                       
                        /* register to windowmanager for redo or macro */
  void          wm_operator_register(bContext *C, wmOperator *op);