Пример #1
0
int wm_window_close_exec(bContext *C, wmOperator *UNUSED(op))
{
    wmWindowManager *wm = CTX_wm_manager(C);
    wmWindow *win = CTX_wm_window(C);
    wm_window_close(C, wm, win);
    return OPERATOR_FINISHED;
}
Пример #2
0
/* operator entry */
int wm_homefile_write_exec(bContext *C, wmOperator *op)
{
	wmWindowManager *wm = CTX_wm_manager(C);
	wmWindow *win = CTX_wm_window(C);
	char filepath[FILE_MAX];
	int fileflags;

	/* check current window and close it if temp */
	if (win && win->screen->temp)
		wm_window_close(C, wm, win);
	
	/* update keymaps in user preferences */
	WM_keyconfig_update(wm);
	
	BLI_make_file_string("/", filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE);
	printf("trying to save homefile at %s ", filepath);
	
	/*  force save as regular blend file */
	fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY);

	if (BLO_write_file(CTX_data_main(C), filepath, fileflags | G_FILE_USERPREFS, op->reports, NULL) == 0) {
		printf("fail\n");
		return OPERATOR_CANCELLED;
	}
	
	printf("ok\n");

	G.save_over = 0;

	return OPERATOR_FINISHED;
}
Пример #3
0
/**
 * Call after #wm_window_ghostwindows_ensure or #WM_check
 * (after loading a new file) in the unlikely event a window couldn't be created.
 */
void wm_window_ghostwindows_remove_invalid(bContext *C, wmWindowManager *wm)
{
    wmWindow *win, *win_next;

    BLI_assert(G.background == false);

    for (win = wm->windows.first; win; win = win_next) {
        win_next = win->next;
        if (win->ghostwin == NULL) {
            wm_window_close(C, wm, win);
        }
    }
}
Пример #4
0
int wm_stereo3d_set_exec(bContext *C, wmOperator *op)
{
	wmWindowManager *wm = CTX_wm_manager(C);
	wmWindow *win = CTX_wm_window(C);
	const bool is_fullscreen = WM_window_is_fullscreen(win);
	char display_mode = win->stereo3d_format->display_mode;

	if (G.background)
		return OPERATOR_CANCELLED;

	if (op->customdata) {
		Stereo3dData *s3dd = op->customdata;
		*win->stereo3d_format = s3dd->stereo3d_format;
	}

	/* pageflip requires a new window to be created with the proper OS flags */
	if (win->stereo3d_format->display_mode == S3D_DISPLAY_PAGEFLIP) {
		if (wm_stereo3d_quadbuffer_supported() == false) {
			BKE_report(op->reports, RPT_ERROR, "Quad-buffer not supported by the system");
			win->stereo3d_format->display_mode = display_mode;
			return OPERATOR_CANCELLED;
		}
		if (wm_window_duplicate_exec(C, op) == OPERATOR_FINISHED) {
			wm_window_close(C, wm, win);
			win = wm->windows.last;
		}
		else {
			BKE_report(op->reports, RPT_ERROR,
			           "Fail to create a window compatible with time sequential (page-flip) display method");
			win->stereo3d_format->display_mode = display_mode;
			return OPERATOR_CANCELLED;
		}
	}

	if (wm_stereo3d_is_fullscreen_required(win->stereo3d_format->display_mode)) {
		if (!is_fullscreen) {
			BKE_report(op->reports, RPT_INFO, "Stereo 3D Mode requires the window to be fullscreen");
		}
	}

	if (op->customdata) {
		MEM_freeN(op->customdata);
	}

	WM_event_add_notifier(C, NC_WINDOW, NULL);
	return OPERATOR_FINISHED;
}
Пример #5
0
/**
 * A higher level version of copy that tests the new window can be added.
 * (called from the operator directly)
 */
wmWindow *wm_window_copy_test(bContext *C, wmWindow *win_src)
{
    wmWindowManager *wm = CTX_wm_manager(C);
    wmWindow *win_dst;

    win_dst = wm_window_copy(C, win_src);

    WM_check(C);

    if (win_dst->ghostwin) {
        WM_event_add_notifier(C, NC_WINDOW | NA_ADDED, NULL);
        return win_dst;
    }
    else {
        wm_window_close(C, wm, win_dst);
        return NULL;
    }
}
Пример #6
0
/* operator entry */
int WM_write_homefile(bContext *C, wmOperator *op)
{
	wmWindowManager *wm= CTX_wm_manager(C);
	wmWindow *win= CTX_wm_window(C);
	char tstr[FILE_MAXDIR+FILE_MAXFILE];
	int fileflags;
	
	/* check current window and close it if temp */
	if(win->screen->full == SCREENTEMP)
		wm_window_close(C, wm, win);
	
	BLI_make_file_string("/", tstr, BLI_gethome(), ".B25.blend");
	
	/*  force save as regular blend file */
	fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN);

	BLO_write_file(CTX_data_main(C), tstr, fileflags, op->reports);
	
	G.save_over= 0;
	
	return OPERATOR_FINISHED;
}
Пример #7
0
/**
 * new window, no screen yet, but we open ghostwindow for it,
 * also gets the window level handlers
 * \note area-rip calls this.
 * \return the window or NULL.
 */
wmWindow *WM_window_open(bContext *C, const rcti *rect)
{
    wmWindow *win_prev = CTX_wm_window(C);
    wmWindow *win = wm_window_new(C);

    win->posx = rect->xmin;
    win->posy = rect->ymin;
    win->sizex = BLI_rcti_size_x(rect);
    win->sizey = BLI_rcti_size_y(rect);

    win->drawmethod = U.wmdrawmethod;

    WM_check(C);

    if (win->ghostwin) {
        return win;
    }
    else {
        wm_window_close(C, CTX_wm_manager(C), win);
        CTX_wm_window_set(C, win_prev);
        return NULL;
    }
}
Пример #8
0
int wm_stereo3d_set_exec(bContext *C, wmOperator *op)
{
	wmWindowManager *wm = CTX_wm_manager(C);
	wmWindow *win_src = CTX_wm_window(C);
	wmWindow *win_dst = NULL;
	const bool is_fullscreen = WM_window_is_fullscreen(win_src);
	char prev_display_mode = win_src->stereo3d_format->display_mode;
	Stereo3dData *s3dd;
	bool ok = true;

	if (G.background)
		return OPERATOR_CANCELLED;

	if (op->customdata == NULL) {
		/* no invoke means we need to set the operator properties here */
		wm_stereo3d_set_init(C, op);
		wm_stereo3d_set_properties(C, op);
	}

	s3dd = op->customdata;
	*win_src->stereo3d_format = s3dd->stereo3d_format;

	if (prev_display_mode == S3D_DISPLAY_PAGEFLIP &&
	    prev_display_mode != win_src->stereo3d_format->display_mode)
	{
		/* in case the hardward supports pageflip but not the display */
		if ((win_dst = wm_window_copy_test(C, win_src))) {
			/* pass */
		}
		else {
			BKE_report(op->reports, RPT_ERROR,
			           "Failed to create a window without quad-buffer support, you may experience flickering");
			ok = false;
		}
	}
	else if (win_src->stereo3d_format->display_mode == S3D_DISPLAY_PAGEFLIP) {
		/* ED_screen_duplicate() can't handle other cases yet T44688 */
		if (win_src->screen->state != SCREENNORMAL) {
			BKE_report(op->reports, RPT_ERROR,
			           "Failed to switch to Time Sequential mode when in fullscreen");
			ok = false;
		}
		/* pageflip requires a new window to be created with the proper OS flags */
		else if ((win_dst = wm_window_copy_test(C, win_src))) {
			if (wm_stereo3d_quadbuffer_supported()) {
				BKE_report(op->reports, RPT_INFO, "Quad-buffer window successfully created");
			}
			else {
				wm_window_close(C, wm, win_dst);
				win_dst = NULL;
				BKE_report(op->reports, RPT_ERROR, "Quad-buffer not supported by the system");
				ok = false;
			}
		}
		else {
			BKE_report(op->reports, RPT_ERROR,
			           "Failed to create a window compatible with the time sequential display method");
			ok = false;
		}
	}

	if (wm_stereo3d_is_fullscreen_required(s3dd->stereo3d_format.display_mode)) {
		if (!is_fullscreen) {
			BKE_report(op->reports, RPT_INFO, "Stereo 3D Mode requires the window to be fullscreen");
		}
	}

	MEM_freeN(op->customdata);

	if (ok) {
		if (win_dst) {
			wm_window_close(C, wm, win_src);
		}

		WM_event_add_notifier(C, NC_WINDOW, NULL);
		return OPERATOR_FINISHED;
	}
	else {
		/* without this, the popup won't be freed freed properly T44688 */
		CTX_wm_window_set(C, win_src);
		win_src->stereo3d_format->display_mode = prev_display_mode;
		return OPERATOR_CANCELLED;
	}
}
Пример #9
0
/* called by ghost, here we handle events for windows themselves or send to event system */
static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr)
{
	bContext *C = C_void_ptr;
	wmWindowManager *wm = CTX_wm_manager(C);
	GHOST_TEventType type = GHOST_GetEventType(evt);
	int time = GHOST_GetEventTime(evt);
	
	if (type == GHOST_kEventQuit) {
		WM_exit(C);
	}
	else {
		GHOST_WindowHandle ghostwin = GHOST_GetEventWindow(evt);
		GHOST_TEventDataPtr data = GHOST_GetEventData(evt);
		wmWindow *win;
		
		if (!ghostwin) {
			/* XXX - should be checked, why are we getting an event here, and */
			/* what is it? */
			puts("<!> event has no window");
			return 1;
		}
		else if (!GHOST_ValidWindow(g_system, ghostwin)) {
			/* XXX - should be checked, why are we getting an event here, and */
			/* what is it? */
			puts("<!> event has invalid window");			
			return 1;
		}
		else {
			win = GHOST_GetWindowUserData(ghostwin);
		}
		
		switch (type) {
			case GHOST_kEventWindowDeactivate:
				wm_event_add_ghostevent(wm, win, type, time, data);
				win->active = 0; /* XXX */
				break;
			case GHOST_kEventWindowActivate: 
			{
				GHOST_TEventKeyData kdata;
				wmEvent event;
				int cx, cy, wx, wy;
				
				wm->winactive = win; /* no context change! c->wm->windrawable is drawable, or for area queues */
				
				win->active = 1;
//				window_handle(win, INPUTCHANGE, win->active);
				
				/* bad ghost support for modifier keys... so on activate we set the modifiers again */
				kdata.ascii = '\0';
				kdata.utf8_buf[0] = '\0';
				if (win->eventstate->shift && !query_qual(SHIFT)) {
					kdata.key = GHOST_kKeyLeftShift;
					wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata);
				}
				if (win->eventstate->ctrl && !query_qual(CONTROL)) {
					kdata.key = GHOST_kKeyLeftControl;
					wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata);
				}
				if (win->eventstate->alt && !query_qual(ALT)) {
					kdata.key = GHOST_kKeyLeftAlt;
					wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata);
				}
				if (win->eventstate->oskey && !query_qual(OS)) {
					kdata.key = GHOST_kKeyOS;
					wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata);
				}
				/* keymodifier zero, it hangs on hotkeys that open windows otherwise */
				win->eventstate->keymodifier = 0;
				
				/* entering window, update mouse pos. but no event */
				GHOST_GetCursorPosition(g_system, &wx, &wy);
				
				GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy);
				win->eventstate->x = cx;
				win->eventstate->y = (win->sizey - 1) - cy;
				
				win->addmousemove = 1;   /* enables highlighted buttons */
				
				wm_window_make_drawable(C, win);

				/* window might be focused by mouse click in configuration of window manager
				 * when focus is not following mouse
				 * click could have been done on a button and depending on window manager settings
				 * click would be passed to blender or not, but in any case button under cursor
				 * should be activated, so at max next click on button without moving mouse
				 * would trigger it's handle function
				 * currently it seems to be common practice to generate new event for, but probably
				 * we'll need utility function for this? (sergey)
				 */
				event = *(win->eventstate);
				event.type = MOUSEMOVE;
				event.prevx = event.x;
				event.prevy = event.y;

				wm_event_add(win, &event);

				break;
			}
			case GHOST_kEventWindowClose: {
				wm_window_close(C, wm, win);
				break;
			}
			case GHOST_kEventWindowUpdate: {
				if (G.debug & G_DEBUG_EVENTS) {
					printf("%s: ghost redraw %d\n", __func__, win->winid);
				}
				
				wm_window_make_drawable(C, win);
				WM_event_add_notifier(C, NC_WINDOW, NULL);

				break;
			}
			case GHOST_kEventWindowSize:
			case GHOST_kEventWindowMove: {
				GHOST_TWindowState state;
				state = GHOST_GetWindowState(win->ghostwin);
				win->windowstate = state;

				/* win32: gives undefined window size when minimized */
				if (state != GHOST_kWindowStateMinimized) {
					GHOST_RectangleHandle client_rect;
					int l, t, r, b, scr_w, scr_h;
					int sizex, sizey, posx, posy;
					
					client_rect = GHOST_GetClientBounds(win->ghostwin);
					GHOST_GetRectangle(client_rect, &l, &t, &r, &b);
					
					GHOST_DisposeRectangle(client_rect);
					
					wm_get_screensize(&scr_w, &scr_h);
					sizex = r - l;
					sizey = b - t;
					posx = l;
					posy = scr_h - t - win->sizey;

					/*
					 * Ghost sometimes send size or move events when the window hasn't changed.
					 * One case of this is using compiz on linux. To alleviate the problem
					 * we ignore all such event here.
					 * 
					 * It might be good to eventually do that at Ghost level, but that is for 
					 * another time.
					 */
					if (win->sizex != sizex ||
					    win->sizey != sizey ||
					    win->posx != posx ||
					    win->posy != posy)
					{
						win->sizex = sizex;
						win->sizey = sizey;
						win->posx = posx;
						win->posy = posy;

						/* debug prints */
						if (G.debug & G_DEBUG_EVENTS) {
							const char *state_str;
							state = GHOST_GetWindowState(win->ghostwin);

							if (state == GHOST_kWindowStateNormal) {
								state_str = "normal";
							}
							else if (state == GHOST_kWindowStateMinimized) {
								state_str = "minimized";
							}
							else if (state == GHOST_kWindowStateMaximized) {
								state_str = "maximized";
							}
							else if (state == GHOST_kWindowStateFullScreen) {
								state_str = "fullscreen";
							}
							else {
								state_str = "<unknown>";
							}

							printf("%s: window %d state = %s\n", __func__, win->winid, state_str);

							if (type != GHOST_kEventWindowSize) {
								printf("win move event pos %d %d size %d %d\n",
								       win->posx, win->posy, win->sizex, win->sizey);
							}
						}
					
						wm_window_make_drawable(C, win);
						wm_draw_window_clear(win);
						WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
						WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL);
					}
				}
				break;
			}
				
			case GHOST_kEventOpenMainFile:
			{
				PointerRNA props_ptr;
				wmWindow *oldWindow;
				char *path = GHOST_GetEventData(evt);
				
				if (path) {
					/* operator needs a valid window in context, ensures
					 * it is correctly set */
					oldWindow = CTX_wm_window(C);
					CTX_wm_window_set(C, win);
					
					WM_operator_properties_create(&props_ptr, "WM_OT_open_mainfile");
					RNA_string_set(&props_ptr, "filepath", path);
					WM_operator_name_call(C, "WM_OT_open_mainfile", WM_OP_EXEC_DEFAULT, &props_ptr);
					WM_operator_properties_free(&props_ptr);
					
					CTX_wm_window_set(C, oldWindow);
				}
				break;
			}
			case GHOST_kEventDraggingDropDone:
			{
				wmEvent event;
				GHOST_TEventDragnDropData *ddd = GHOST_GetEventData(evt);
				int cx, cy, wx, wy;
				
				/* entering window, update mouse pos */
				GHOST_GetCursorPosition(g_system, &wx, &wy);
				
				GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy);
				win->eventstate->x = cx;
				win->eventstate->y = (win->sizey - 1) - cy;
				
				event = *(win->eventstate);  /* copy last state, like mouse coords */
				
				/* activate region */
				event.type = MOUSEMOVE;
				event.prevx = event.x;
				event.prevy = event.y;
				
				wm->winactive = win; /* no context change! c->wm->windrawable is drawable, or for area queues */
				win->active = 1;
				
				wm_event_add(win, &event);
				
				
				/* make blender drop event with custom data pointing to wm drags */
				event.type = EVT_DROP;
				event.val = KM_RELEASE;
				event.custom = EVT_DATA_LISTBASE;
				event.customdata = &wm->drags;
				event.customdatafree = 1;
				
				wm_event_add(win, &event);
				
				/* printf("Drop detected\n"); */
				
				/* add drag data to wm for paths: */
				
				if (ddd->dataType == GHOST_kDragnDropTypeFilenames) {
					GHOST_TStringArray *stra = ddd->data;
					int a, icon;
					
					for (a = 0; a < stra->count; a++) {
						printf("drop file %s\n", stra->strings[a]);
						/* try to get icon type from extension */
						icon = ED_file_extension_icon((char *)stra->strings[a]);
						
						WM_event_start_drag(C, icon, WM_DRAG_PATH, stra->strings[a], 0.0);
						/* void poin should point to string, it makes a copy */
						break; /* only one drop element supported now */
					}
				}
				
				
				
				break;
			}
			
			default:
				wm_event_add_ghostevent(wm, win, type, time, data);
				break;
		}

	}
	return 1;
}
Пример #10
0
/* mouse coordinate converversion happens here */
static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr)
{
    bContext *C = C_void_ptr;
    wmWindowManager *wm = CTX_wm_manager(C);
    GHOST_TEventType type = GHOST_GetEventType(evt);
    int time = GHOST_GetEventTime(evt);

    if (type == GHOST_kEventQuit) {
        WM_exit(C);
    }
    else {
        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) {
            return 1;
        }
        if (!ghostwin) {
            /* XXX - should be checked, why are we getting an event here, and */
            /* what is it? */
            puts("<!> event has no window");
            return 1;
        }
        else if (!GHOST_ValidWindow(g_system, ghostwin)) {
            /* XXX - should be checked, why are we getting an event here, and */
            /* what is it? */
            puts("<!> event has invalid window");
            return 1;
        }
        else {
            win = GHOST_GetWindowUserData(ghostwin);
        }

        switch (type) {
        case GHOST_kEventWindowDeactivate:
            wm_event_add_ghostevent(wm, win, type, time, data);
            win->active = 0; /* XXX */

            /* clear modifiers for inactive windows */
            win->eventstate->alt = 0;
            win->eventstate->ctrl = 0;
            win->eventstate->shift = 0;
            win->eventstate->oskey = 0;
            win->eventstate->keymodifier = 0;

            break;
        case GHOST_kEventWindowActivate:
        {
            GHOST_TEventKeyData kdata;
            wmEvent event;
            int wx, wy;
            const int keymodifier = ((query_qual(SHIFT)     ? KM_SHIFT : 0) |
                                     (query_qual(CONTROL)   ? KM_CTRL  : 0) |
                                     (query_qual(ALT)       ? KM_ALT   : 0) |
                                     (query_qual(OS)        ? KM_OSKEY : 0));

            /* Win23/GHOST modifier bug, see T40317 */
#ifndef WIN32
//#  define USE_WIN_ACTIVATE
#endif

            wm->winactive = win; /* no context change! c->wm->windrawable is drawable, or for area queues */

            win->active = 1;
//				window_handle(win, INPUTCHANGE, win->active);

            /* bad ghost support for modifier keys... so on activate we set the modifiers again */

            /* TODO: This is not correct since a modifier may be held when a window is activated...
             * better solve this at ghost level. attempted fix r54450 but it caused bug [#34255]
             *
             * For now don't send GHOST_kEventKeyDown events, just set the 'eventstate'.
             */
            kdata.ascii = '\0';
            kdata.utf8_buf[0] = '\0';

            if (win->eventstate->shift) {
                if ((keymodifier & KM_SHIFT) == 0) {
                    kdata.key = GHOST_kKeyLeftShift;
                    wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata);
                }
            }
#ifdef USE_WIN_ACTIVATE
            else {
                if (keymodifier & KM_SHIFT) {
                    win->eventstate->shift = KM_MOD_FIRST;
                }
            }
#endif
            if (win->eventstate->ctrl) {
                if ((keymodifier & KM_CTRL) == 0) {
                    kdata.key = GHOST_kKeyLeftControl;
                    wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata);
                }
            }
#ifdef USE_WIN_ACTIVATE
            else {
                if (keymodifier & KM_CTRL) {
                    win->eventstate->ctrl = KM_MOD_FIRST;
                }
            }
#endif
            if (win->eventstate->alt) {
                if ((keymodifier & KM_ALT) == 0) {
                    kdata.key = GHOST_kKeyLeftAlt;
                    wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata);
                }
            }
#ifdef USE_WIN_ACTIVATE
            else {
                if (keymodifier & KM_ALT) {
                    win->eventstate->alt = KM_MOD_FIRST;
                }
            }
#endif
            if (win->eventstate->oskey) {
                if ((keymodifier & KM_OSKEY) == 0) {
                    kdata.key = GHOST_kKeyOS;
                    wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata);
                }
            }
#ifdef USE_WIN_ACTIVATE
            else {
                if (keymodifier & KM_OSKEY) {
                    win->eventstate->oskey = KM_MOD_FIRST;
                }
            }
#endif

#undef USE_WIN_ACTIVATE


            /* keymodifier zero, it hangs on hotkeys that open windows otherwise */
            win->eventstate->keymodifier = 0;

            /* entering window, update mouse pos. but no event */
            wm_get_cursor_position(win,  &wx, &wy);

            win->eventstate->x = wx;
            win->eventstate->y = wy;

            win->addmousemove = 1;   /* enables highlighted buttons */

            wm_window_make_drawable(wm, win);

            /* window might be focused by mouse click in configuration of window manager
             * when focus is not following mouse
             * click could have been done on a button and depending on window manager settings
             * click would be passed to blender or not, but in any case button under cursor
             * should be activated, so at max next click on button without moving mouse
             * would trigger it's handle function
             * currently it seems to be common practice to generate new event for, but probably
             * we'll need utility function for this? (sergey)
             */
            wm_event_init_from_window(win, &event);
            event.type = MOUSEMOVE;
            event.prevx = event.x;
            event.prevy = event.y;

            wm_event_add(win, &event);

            break;
        }
        case GHOST_kEventWindowClose:
        {
            wm_window_close(C, wm, win);
            break;
        }
        case GHOST_kEventWindowUpdate:
        {
            if (G.debug & G_DEBUG_EVENTS) {
                printf("%s: ghost redraw %d\n", __func__, win->winid);
            }

            wm_window_make_drawable(wm, win);
            WM_event_add_notifier(C, NC_WINDOW, NULL);

            break;
        }
        case GHOST_kEventWindowSize:
        case GHOST_kEventWindowMove:
        {
            GHOST_TWindowState state;
            state = GHOST_GetWindowState(win->ghostwin);
            win->windowstate = state;

            /* stop screencast if resize */
            if (type == GHOST_kEventWindowSize) {
                WM_jobs_stop(wm, win->screen, NULL);
            }

            /* win32: gives undefined window size when minimized */
            if (state != GHOST_kWindowStateMinimized) {
                GHOST_RectangleHandle client_rect;
                int l, t, r, b, scr_w, scr_h;
                int sizex, sizey, posx, posy;

                client_rect = GHOST_GetClientBounds(win->ghostwin);
                GHOST_GetRectangle(client_rect, &l, &t, &r, &b);

                GHOST_DisposeRectangle(client_rect);

                wm_get_desktopsize(&scr_w, &scr_h);
                sizex = r - l;
                sizey = b - t;
                posx = l;
                posy = scr_h - t - win->sizey;

                /*
                 * Ghost sometimes send size or move events when the window hasn't changed.
                 * One case of this is using compiz on linux. To alleviate the problem
                 * we ignore all such event here.
                 *
                 * It might be good to eventually do that at Ghost level, but that is for
                 * another time.
                 */
                if (win->sizex != sizex ||
                        win->sizey != sizey ||
                        win->posx != posx ||
                        win->posy != posy)
                {
                    win->sizex = sizex;
                    win->sizey = sizey;
                    win->posx = posx;
                    win->posy = posy;

                    /* debug prints */
                    if (G.debug & G_DEBUG_EVENTS) {
                        const char *state_str;
                        state = GHOST_GetWindowState(win->ghostwin);

                        if (state == GHOST_kWindowStateNormal) {
                            state_str = "normal";
                        }
                        else if (state == GHOST_kWindowStateMinimized) {
                            state_str = "minimized";
                        }
                        else if (state == GHOST_kWindowStateMaximized) {
                            state_str = "maximized";
                        }
                        else if (state == GHOST_kWindowStateFullScreen) {
                            state_str = "fullscreen";
                        }
                        else {
                            state_str = "<unknown>";
                        }

                        printf("%s: window %d state = %s\n", __func__, win->winid, state_str);

                        if (type != GHOST_kEventWindowSize) {
                            printf("win move event pos %d %d size %d %d\n",
                                   win->posx, win->posy, win->sizex, win->sizey);
                        }
                    }

                    wm_window_make_drawable(wm, win);
                    wm_draw_window_clear(win);
                    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_handlers(C);
                    wm_event_do_notifiers(C);
                    wm_draw_update(C);
#endif
                }
            }
            break;
        }

        case GHOST_kEventOpenMainFile:
        {
            PointerRNA props_ptr;
            wmWindow *oldWindow;
            const char *path = GHOST_GetEventData(evt);

            if (path) {
                wmOperatorType *ot = WM_operatortype_find("WM_OT_open_mainfile", false);
                /* operator needs a valid window in context, ensures
                 * it is correctly set */
                oldWindow = CTX_wm_window(C);
                CTX_wm_window_set(C, win);

                WM_operator_properties_create_ptr(&props_ptr, ot);
                RNA_string_set(&props_ptr, "filepath", path);
                WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &props_ptr);
                WM_operator_properties_free(&props_ptr);

                CTX_wm_window_set(C, oldWindow);
            }
            break;
        }
        case GHOST_kEventDraggingDropDone:
        {
            wmEvent event;
            GHOST_TEventDragnDropData *ddd = GHOST_GetEventData(evt);
            int wx, wy;

            /* entering window, update mouse pos */
            wm_get_cursor_position(win, &wx, &wy);
            win->eventstate->x = wx;
            win->eventstate->y = wy;

            wm_event_init_from_window(win, &event);  /* copy last state, like mouse coords */

            /* activate region */
            event.type = MOUSEMOVE;
            event.prevx = event.x;
            event.prevy = event.y;

            wm->winactive = win; /* no context change! c->wm->windrawable is drawable, or for area queues */
            win->active = 1;

            wm_event_add(win, &event);


            /* make blender drop event with custom data pointing to wm drags */
            event.type = EVT_DROP;
            event.val = KM_RELEASE;
            event.custom = EVT_DATA_DRAGDROP;
            event.customdata = &wm->drags;
            event.customdatafree = 1;

            wm_event_add(win, &event);

            /* printf("Drop detected\n"); */

            /* add drag data to wm for paths: */

            if (ddd->dataType == GHOST_kDragnDropTypeFilenames) {
                GHOST_TStringArray *stra = ddd->data;
                int a, icon;

                for (a = 0; a < stra->count; a++) {
                    printf("drop file %s\n", stra->strings[a]);
                    /* try to get icon type from extension */
                    icon = ED_file_extension_icon((char *)stra->strings[a]);

                    WM_event_start_drag(C, icon, WM_DRAG_PATH, stra->strings[a], 0.0, WM_DRAG_NOP);
                    /* void poin should point to string, it makes a copy */
                    break; /* only one drop element supported now */
                }
            }

            break;
        }
        case GHOST_kEventNativeResolutionChange:
            // printf("change, pixel size %f\n", GHOST_GetNativePixelSize(win->ghostwin));

            U.pixelsize = wm_window_pixelsize(win);
            BKE_userdef_state();
            WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
            WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL);

            break;
        case GHOST_kEventTrackpad:
        {
            GHOST_TEventTrackpadData *pd = data;

            wm_convert_cursor_position(win, &pd->x, &pd->y);
            wm_event_add_ghostevent(wm, win, type, time, data);
            break;
        }
        case GHOST_kEventCursorMove:
        {
            GHOST_TEventCursorData *cd = data;

            wm_convert_cursor_position(win, &cd->x, &cd->y);
            wm_event_add_ghostevent(wm, win, type, time, data);
            break;
        }
        default:
            wm_event_add_ghostevent(wm, win, type, time, data);
            break;
        }

    }
    return 1;
}
Пример #11
0
/**
 * Uses `screen->temp` tag to define what to do, currently it limits
 * to only one "temp" window for render out, preferences, filewindow, etc...
 *
 * \param type: WM_WINDOW_RENDER, WM_WINDOW_USERPREFS...
 * \return the window or NULL.
 */
wmWindow *WM_window_open_temp(bContext *C, const rcti *rect_init, int type)
{
    wmWindow *win_prev = CTX_wm_window(C);
    wmWindow *win;
    ScrArea *sa;
    Scene *scene = CTX_data_scene(C);
    const char *title;
    rcti rect = *rect_init;
    const short px_virtual = (short)wm_window_get_virtual_pixelsize();

    /* 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)
            break;

    /* add new window? */
    if (win == NULL) {
        win = wm_window_new(C);

        win->posx = rect.xmin;
        win->posy = rect.ymin;
    }

    /* multiply with virtual pixelsize, ghost handles native one (e.g. for retina) */
    win->sizex = BLI_rcti_size_x(&rect) * px_virtual;
    win->sizey = BLI_rcti_size_y(&rect) * px_virtual;

    if (win->ghostwin) {
        wm_window_set_size(win, win->sizex, win->sizey);
        wm_window_raise(win);
    }

    if (win->screen == NULL) {
        /* add new screen */
        win->screen = ED_screen_add(win, scene, "temp");
    }
    else {
        /* switch scene for rendering */
        if (win->screen->scene != scene)
            ED_screen_set_scene(C, win->screen, scene);
    }

    win->screen->temp = 1;

    /* make window active, and validate/resize */
    CTX_wm_window_set(C, win);
    WM_check(C);

    /* It's possible `win->ghostwin == NULL`.
     * instead of attempting to cleanup here (in a half finished state),
     * finish setting up the screen, then free it at the end of the function,
     * to avoid having to take into account a partially-created window.
     */

    /* ensure it shows the right spacetype editor */
    sa = win->screen->areabase.first;
    CTX_wm_area_set(C, sa);

    if (type == WM_WINDOW_RENDER) {
        ED_area_newspace(C, sa, SPACE_IMAGE);
    }
    else {
        ED_area_newspace(C, sa, SPACE_USERPREF);
    }

    ED_screen_set(C, win->screen);
    ED_screen_refresh(CTX_wm_manager(C), win); /* test scale */

    if (sa->spacetype == SPACE_IMAGE)
        title = IFACE_("Blender Render");
    else if (ELEM(sa->spacetype, SPACE_OUTLINER, SPACE_USERPREF))
        title = IFACE_("Blender User Preferences");
    else if (sa->spacetype == SPACE_FILE)
        title = IFACE_("Blender File View");
    else
        title = "Blender";

    if (win->ghostwin) {
        GHOST_SetTitle(win->ghostwin, title);
        return win;
    }
    else {
        /* very unlikely! but opening a new window can fail */
        wm_window_close(C, CTX_wm_manager(C), win);
        CTX_wm_window_set(C, win_prev);

        return NULL;
    }
}