static void loggerwindow_handle(void *priv, GHOST_EventHandle evt) { LoggerWindow *lw= priv; GHOST_TEventType type= GHOST_GetEventType(evt); switch(type) { case GHOST_kEventCursorMove: { GHOST_TEventCursorData *cd= GHOST_GetEventData(evt); int x, y; GHOST_ScreenToClient(lw->win, cd->x, cd->y, &x, &y); loggerwindow_do_move(lw, x, lw->size[1]-y-1); break; } case GHOST_kEventButtonDown: case GHOST_kEventButtonUp: { GHOST_TEventButtonData *bd= GHOST_GetEventData(evt); loggerwindow_do_button(lw, bd->button, (type == GHOST_kEventButtonDown)); break; } case GHOST_kEventKeyDown: case GHOST_kEventKeyUp: { GHOST_TEventKeyData *kd= GHOST_GetEventData(evt); loggerwindow_do_key(lw, kd->key, (type == GHOST_kEventKeyDown)); break; } case GHOST_kEventWindowUpdate: loggerwindow_do_draw(lw); break; case GHOST_kEventWindowSize: loggerwindow_do_reshape(lw); break; } }
static void extrawindow_handle(void *priv, GHOST_EventHandle evt) { ExtraWindow *ew= priv; GHOST_TEventType type= GHOST_GetEventType(evt); char buf[256]; event_to_buf(evt, buf); loggerwindow_log(multitestapp_get_logger(ew->app), buf); switch (type) { case GHOST_kEventKeyDown: case GHOST_kEventKeyUp: { GHOST_TEventKeyData *kd= GHOST_GetEventData(evt); extrawindow_do_key(ew, kd->key, (type == GHOST_kEventKeyDown)); break; } case GHOST_kEventCursorMove: { extrawindow_spin_cursor(ew, GHOST_GetEventTime(evt)); break; } case GHOST_kEventWindowClose: multitestapp_free_extrawindow(ew->app); break; case GHOST_kEventWindowUpdate: extrawindow_do_draw(ew); break; case GHOST_kEventWindowSize: extrawindow_do_reshape(ew); break; } }
static void mainwindow_handle(void *priv, GHOST_EventHandle evt) { MainWindow *mw= priv; GHOST_TEventType type= GHOST_GetEventType(evt); char buf[256]; event_to_buf(evt, buf); mainwindow_log(mw, buf); switch (type) { case GHOST_kEventCursorMove: { GHOST_TEventCursorData *cd= GHOST_GetEventData(evt); int x, y; GHOST_ScreenToClient(mw->win, cd->x, cd->y, &x, &y); mainwindow_do_move(mw, x, mw->size[1]-y-1); break; } case GHOST_kEventButtonDown: case GHOST_kEventButtonUp: { GHOST_TEventButtonData *bd= GHOST_GetEventData(evt); mainwindow_do_button(mw, bd->button, (type == GHOST_kEventButtonDown)); break; } case GHOST_kEventKeyDown: case GHOST_kEventKeyUp: { GHOST_TEventKeyData *kd= GHOST_GetEventData(evt); mainwindow_do_key(mw, kd->key, (type == GHOST_kEventKeyDown)); break; } case GHOST_kEventWindowUpdate: mainwindow_do_draw(mw); break; case GHOST_kEventWindowSize: mainwindow_do_reshape(mw); break; } }
void event_to_buf(GHOST_EventHandle evt, char buf[128]) { GHOST_TEventType type= GHOST_GetEventType(evt); double time= (double) ((GHOST_TInt64) GHOST_GetEventTime(evt))/1000; GHOST_WindowHandle win= GHOST_GetEventWindow(evt); void *data= GHOST_GetEventData(evt); char *pos= buf; pos+= sprintf(pos, "event: %6.2f, %16s", time, eventtype_to_string(type)); if (win) { char *s= GHOST_GetTitle(win); pos+= sprintf(pos, " - win: %s", s); free(s); } else { pos+= sprintf(pos, " - sys evt"); } switch (type) { case GHOST_kEventCursorMove: { GHOST_TEventCursorData *cd= data; pos+= sprintf(pos, " - pos: (%d, %d)", cd->x, cd->y); break; } case GHOST_kEventButtonDown: case GHOST_kEventButtonUp: { GHOST_TEventButtonData *bd= data; pos+= sprintf(pos, " - but: %d", bd->button); break; } case GHOST_kEventKeyDown: case GHOST_kEventKeyUp: { GHOST_TEventKeyData *kd= data; pos+= sprintf(pos, " - key: %s (%d)", keytype_to_string(kd->key), kd->key); if (kd->ascii) pos+= sprintf(pos, " ascii: '%c' (%d)", kd->ascii, kd->ascii); break; } } }
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; }
int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData) { int handled = 1; int cursor; int visibility; GHOST_TEventKeyData *keyData = NULL; GHOST_TEventWheelData *wheelData = NULL; GHOST_DisplaySetting setting; GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent); switch (GHOST_GetEventType(hEvent)) { #if 0 case GHOST_kEventUnknown: break; case GHOST_kEventCursorButton: break; case GHOST_kEventCursorMove: break; #endif case GHOST_kEventWheel: { wheelData = (GHOST_TEventWheelData *)GHOST_GetEventData(hEvent); if (wheelData->z > 0) { view_rotz += 5.f; } else { view_rotz -= 5.f; } } break; case GHOST_kEventKeyUp: break; case GHOST_kEventKeyDown: { keyData = (GHOST_TEventKeyData *)GHOST_GetEventData(hEvent); switch (keyData->key) { case GHOST_kKeyC: { cursor = sCursor; cursor++; if (cursor >= GHOST_kStandardCursorNumCursors) { cursor = GHOST_kStandardCursorFirstCursor; } sCursor = (GHOST_TStandardCursor)cursor; GHOST_SetCursorShape(window, sCursor); } break; case GHOST_kKeyF: if (!GHOST_GetFullScreen(shSystem)) { /* Begin fullscreen mode */ setting.bpp = 24; setting.frequency = 85; setting.xPixels = 640; setting.yPixels = 480; /* * setting.bpp = 16; * setting.frequency = 75; * setting.xPixels = 640; * setting.yPixels = 480; */ sFullScreenWindow = GHOST_BeginFullScreen(shSystem, &setting, FALSE /* stereo flag */); } else { GHOST_EndFullScreen(shSystem); sFullScreenWindow = 0; } break; case GHOST_kKeyH: { visibility = GHOST_GetCursorVisibility(window); GHOST_SetCursorVisibility(window, !visibility); } break; case GHOST_kKeyQ: if (GHOST_GetFullScreen(shSystem)) { GHOST_EndFullScreen(shSystem); sFullScreenWindow = 0; } sExitRequested = 1; case GHOST_kKeyT: if (!sTestTimer) { sTestTimer = GHOST_InstallTimer(shSystem, 0, 1000, testTimerProc, NULL); } else { GHOST_RemoveTimer(shSystem, sTestTimer); sTestTimer = 0; } break; case GHOST_kKeyW: { if (sMainWindow) { char *title = GHOST_GetTitle(sMainWindow); char *ntitle = malloc(strlen(title) + 2); sprintf(ntitle, "%s-", title); GHOST_SetTitle(sMainWindow, ntitle); free(ntitle); free(title); } } break; default: break; } } break; case GHOST_kEventWindowClose: { GHOST_WindowHandle window2 = GHOST_GetEventWindow(hEvent); if (window2 == sMainWindow) { sExitRequested = 1; } else { if (sGearsTimer) { GHOST_RemoveTimer(shSystem, sGearsTimer); sGearsTimer = 0; } GHOST_DisposeWindow(shSystem, window2); } } break; case GHOST_kEventWindowActivate: handled = 0; break; case GHOST_kEventWindowDeactivate: handled = 0; break; case GHOST_kEventWindowUpdate: { GHOST_WindowHandle window2 = GHOST_GetEventWindow(hEvent); if (!GHOST_ValidWindow(shSystem, window2)) break; setViewPortGL(window2); drawGL(); GHOST_SwapWindowBuffers(window2); } break; default: handled = 0; break; } return handled; }
/* 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; }
/* 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; }