Esempio n. 1
0
static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
{
	PlayState *ps = (PlayState *)ps_void;
	GHOST_TEventType type = GHOST_GetEventType(evt);
	int val;

	// print_ps(ps);

	playanim_event_qual_update();

	/* convert ghost event into value keyboard or mouse */
	val = ELEM(type, GHOST_kEventKeyDown, GHOST_kEventButtonDown);

	if (ps->wait2 && ps->stopped) {
		ps->stopped = FALSE;
	}

	if (ps->wait2) {
		pupdate_time();
		ptottime = 0;
	}

	switch (type) {
		case GHOST_kEventKeyDown:
		case GHOST_kEventKeyUp:
		{
			GHOST_TEventKeyData *key_data;

			key_data = (GHOST_TEventKeyData *)GHOST_GetEventData(evt);
			switch (key_data->key) {
				case GHOST_kKeyA:
					if (val) ps->noskip = !ps->noskip;
					break;
				case GHOST_kKeyP:
					if (val) ps->pingpong = !ps->pingpong;
					break;
				case GHOST_kKey1:
				case GHOST_kKeyNumpad1:
					if (val) swaptime = ps->fstep / 60.0;
					break;
				case GHOST_kKey2:
				case GHOST_kKeyNumpad2:
					if (val) swaptime = ps->fstep / 50.0;
					break;
				case GHOST_kKey3:
				case GHOST_kKeyNumpad3:
					if (val) swaptime = ps->fstep / 30.0;
					break;
				case GHOST_kKey4:
				case GHOST_kKeyNumpad4:
					if (g_WS.qual & WS_QUAL_SHIFT)
						swaptime = ps->fstep / 24.0;
					else
						swaptime = ps->fstep / 25.0;
					break;
				case GHOST_kKey5:
				case GHOST_kKeyNumpad5:
					if (val) swaptime = ps->fstep / 20.0;
					break;
				case GHOST_kKey6:
				case GHOST_kKeyNumpad6:
					if (val) swaptime = ps->fstep / 15.0;
					break;
				case GHOST_kKey7:
				case GHOST_kKeyNumpad7:
					if (val) swaptime = ps->fstep / 12.0;
					break;
				case GHOST_kKey8:
				case GHOST_kKeyNumpad8:
					if (val) swaptime = ps->fstep / 10.0;
					break;
				case GHOST_kKey9:
				case GHOST_kKeyNumpad9:
					if (val) swaptime = ps->fstep / 6.0;
					break;
				case GHOST_kKeyLeftArrow:
					if (val) {
						ps->sstep = TRUE;
						ps->wait2 = FALSE;
						if (g_WS.qual & WS_QUAL_SHIFT) {
							ps->picture = picsbase.first;
							ps->next_frame = 0;
						}
						else {
							ps->next_frame = -1;
						}
					}
					break;
				case GHOST_kKeyDownArrow:
					if (val) {
						ps->wait2 = FALSE;
						if (g_WS.qual & WS_QUAL_SHIFT) {
							ps->next_frame = ps->direction = -1;
						}
						else {
							ps->next_frame = -10;
							ps->sstep = TRUE;
						}
					}
					break;
				case GHOST_kKeyRightArrow:
					if (val) {
						ps->sstep = TRUE;
						ps->wait2 = FALSE;
						if (g_WS.qual & WS_QUAL_SHIFT) {
							ps->picture = picsbase.last;
							ps->next_frame = 0;
						}
						else {
							ps->next_frame = 1;
						}
					}
					break;
				case GHOST_kKeyUpArrow:
					if (val) {
						ps->wait2 = FALSE;
						if (g_WS.qual & WS_QUAL_SHIFT) {
							ps->next_frame = ps->direction = 1;
						}
						else {
							ps->next_frame = 10;
							ps->sstep = TRUE;
						}
					}
					break;

				case GHOST_kKeySlash:
				case GHOST_kKeyNumpadSlash:
					if (val) {
						if (g_WS.qual & WS_QUAL_SHIFT) {
							if (ps->curframe_ibuf)
								printf(" Name: %s | Speed: %.2f frames/s\n",
								       ps->curframe_ibuf->name, ps->fstep / swaptime);
						}
						else {
							swaptime = ps->fstep / 5.0;
						}
					}
					break;
				case GHOST_kKey0:
				case GHOST_kKeyNumpad0:
					if (val) {
						if (ps->once) {
							ps->once = ps->wait2 = FALSE;
						}
						else {
							ps->picture = NULL;
							ps->once = TRUE;
							ps->wait2 = FALSE;
						}
					}
					break;
				case GHOST_kKeyEnter:
				case GHOST_kKeyNumpadEnter:
					if (val) {
						ps->wait2 = ps->sstep = FALSE;
					}
					break;
				case GHOST_kKeyPeriod:
				case GHOST_kKeyNumpadPeriod:
					if (val) {
						if (ps->sstep) {
							ps->wait2 = FALSE;
						}
						else {
							ps->sstep = TRUE;
							ps->wait2 = !ps->wait2;
						}
					}
					break;
				case GHOST_kKeyEqual:
				case GHOST_kKeyNumpadPlus:
				{
					if (val == 0) break;
					if (g_WS.qual & WS_QUAL_CTRL) {
						playanim_window_zoom(ps, 1.0f);
					}
					else {
						swaptime /= 1.1;
					}
					break;
				}
				case GHOST_kKeyMinus:
				case GHOST_kKeyNumpadMinus:
				{
					if (val == 0) break;
					if (g_WS.qual & WS_QUAL_CTRL) {
						playanim_window_zoom(ps, -1.0f);
					}
					else {
						swaptime *= 1.1;
					}
					break;
				}
				case GHOST_kKeyEsc:
					ps->go = FALSE;
					break;
				default:
					break;
			}
			break;
		}
		case GHOST_kEventButtonDown:
		case GHOST_kEventButtonUp:
		{
			GHOST_TEventButtonData *bd = GHOST_GetEventData(evt);
			int cx, cy, sizex, sizey, inside_window;
			
			GHOST_GetCursorPosition(g_WS.ghost_system, &cx, &cy);
			GHOST_ScreenToClient(g_WS.ghost_window, cx, cy, &cx, &cy);
			playanim_window_get_size(&sizex, &sizey);

			inside_window = (cx >= 0 && cx < sizex && cy >= 0 && cy <= sizey);
			
			if (bd->button == GHOST_kButtonMaskLeft) {
				if (type == GHOST_kEventButtonDown) {
					if (inside_window)
						g_WS.qual |= WS_QUAL_LMOUSE;
				}
				else
					g_WS.qual &= ~WS_QUAL_LMOUSE;
			}
			else if (bd->button == GHOST_kButtonMaskMiddle) {
				if (type == GHOST_kEventButtonDown) {
					if (inside_window)
						g_WS.qual |= WS_QUAL_MMOUSE;
				}
				else
					g_WS.qual &= ~WS_QUAL_MMOUSE;
			}
			else if (bd->button == GHOST_kButtonMaskRight) {
				if (type == GHOST_kEventButtonDown) {
					if (inside_window)
						g_WS.qual |= WS_QUAL_RMOUSE;
				}
				else
					g_WS.qual &= ~WS_QUAL_RMOUSE;
			}
			break;
		}
		case GHOST_kEventCursorMove:
		{
			if (g_WS.qual & WS_QUAL_LMOUSE) {
				int sizex, sizey;
				int i;

				GHOST_TEventCursorData *cd = GHOST_GetEventData(evt);
				int cx, cy;

				GHOST_ScreenToClient(g_WS.ghost_window, cd->x, cd->y, &cx, &cy);

				playanim_window_get_size(&sizex, &sizey);
				ps->picture = picsbase.first;
				/* TODO - store in ps direct? */
				i = 0;
				while (ps->picture) {
					i++;
					ps->picture = ps->picture->next;
				}
				i = (i * cx) / sizex;
				ps->picture = picsbase.first;
				for (; i > 0; i--) {
					if (ps->picture->next == NULL) break;
					ps->picture = ps->picture->next;
				}
				ps->sstep = TRUE;
				ps->wait2 = FALSE;
				ps->next_frame = 0;
			}
			break;
		}
		case GHOST_kEventWindowActivate:
		case GHOST_kEventWindowDeactivate:
		{
			g_WS.qual &= ~WS_QUAL_MOUSE;
			break;
		}
		case GHOST_kEventWindowSize:
		case GHOST_kEventWindowMove:
		{
			float zoomx, zoomy;
			
			playanim_window_get_size(&ps->win_x, &ps->win_y);
			GHOST_ActivateWindowDrawingContext(g_WS.ghost_window);

			zoomx = (float) ps->win_x / ps->ibufx;
			zoomy = (float) ps->win_y / ps->ibufy;
			
			/* zoom always show entire image */
			ps->zoom = MIN2(zoomx, zoomy);
			
			/* zoom steps of 2 for speed */
			ps->zoom = floor(ps->zoom + 0.5f);
			if (ps->zoom < 1.0f) ps->zoom = 1.0f;
			
			glViewport(0, 0, ps->win_x, ps->win_y);
			glScissor(0, 0, ps->win_x, ps->win_y);
			
			/* unified matrix, note it affects offset for drawing */
			glMatrixMode(GL_PROJECTION);
			glLoadIdentity();
			glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
			glMatrixMode(GL_MODELVIEW);

			glPixelZoom(ps->zoom, ps->zoom);
			ptottime = 0.0;
			playanim_toscreen(ps, ps->picture, ps->curframe_ibuf, ps->fontid, ps->fstep);

			break;
		}
		case GHOST_kEventQuit:
		case GHOST_kEventWindowClose:
		{
			ps->go = FALSE;
			break;
		}
		case GHOST_kEventDraggingDropDone:
		{
			GHOST_TEventDragnDropData *ddd = GHOST_GetEventData(evt);
			
			if (ddd->dataType == GHOST_kDragnDropTypeFilenames) {
				GHOST_TStringArray *stra = ddd->data;
				int a;
				
				for (a = 0; a < stra->count; a++) {
					BLI_strncpy(ps->dropped_file, (char *)stra->strings[a], sizeof(ps->dropped_file));
					ps->go = FALSE;
					printf("drop file %s\n", stra->strings[a]);
					break; /* only one drop element supported now */
				}
			}
			break;
		}
		default:
			/* quiet warnings */
			break;
	}

	return 1;
}
Esempio n. 2
0
void wm_get_cursor_position(wmWindow *win, int *x, int *y)
{
	GHOST_GetCursorPosition(g_system, x, y);
	GHOST_ScreenToClient(win->ghostwin, *x, *y, x, y);
	*y = (win->sizey - 1) - *y;
}
Esempio n. 3
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;
}
void wm_get_cursor_position(wmWindow *win, int *x, int *y)
{
    GHOST_GetCursorPosition(g_system, x, y);
    wm_convert_cursor_position(win, x, y);
}