|
Blender
V2.59
|
00001 00028 #define FALSE 0 00029 00030 #ifdef WIN32 00031 00032 #pragma warning(disable: 4244 4305) 00033 #endif 00034 00035 #include <stdlib.h> 00036 #include <string.h> 00037 #include <stdio.h> 00038 #include <math.h> 00039 00040 #include "GL.h" 00041 00042 #include "MEM_guardedalloc.h" 00043 00044 #include "GHOST_C-api.h" 00045 00046 #ifdef USE_BMF 00047 # include "BMF_Api.h" 00048 #else 00049 # include "BLF_api.h" 00050 extern int datatoc_bfont_ttf_size; 00051 extern char datatoc_bfont_ttf[]; 00052 00053 // XXX, bad, but BLI uses these 00054 char bprogname[160]= ""; 00055 char U[1024]= {0}; 00056 #endif 00057 00058 #include "Util.h" 00059 #include "Basic.h" 00060 #include "ScrollBar.h" 00061 #include "EventToBuf.h" 00062 00063 #include "WindowData.h" 00064 00065 /***/ 00066 00067 typedef struct _MultiTestApp MultiTestApp; 00068 typedef struct _LoggerWindow LoggerWindow; 00069 00070 void loggerwindow_log(LoggerWindow *lw, char *line); 00071 00072 void multitestapp_toggle_extra_window(MultiTestApp *app); 00073 void multitestapp_free_extrawindow(MultiTestApp *app); 00074 LoggerWindow *multitestapp_get_logger(MultiTestApp *app); 00075 GHOST_SystemHandle multitestapp_get_system(MultiTestApp *app); 00076 void multitestapp_exit(MultiTestApp *app); 00077 00078 00079 00080 void rect_bevel_side(int rect[2][2], int side, float *lt, float *dk, float *col, int width) { 00081 int ltidx= (side/2)%4; 00082 int dkidx= (ltidx + 1 + (side&1))%4; 00083 int i, corner; 00084 00085 glBegin(GL_LINES); 00086 for (i=0; i<width; i++) { 00087 float ltf= pow(lt[i], 1.0/2.2), dkf= pow(dk[i], 1.0/2.2); 00088 float stf= (dkidx>ltidx)?dkf:ltf; 00089 int lx= rect[1][0]-i-1; 00090 int ly= rect[0][1]+i; 00091 00092 glColor3f(col[0]*stf, col[1]*stf, col[2]*stf); 00093 for (corner=0; corner<4; corner++) { 00094 int x= (corner==0 || corner==1)?(rect[0][0]+i):(rect[1][0]-i-1); 00095 int y= (corner==0 || corner==3)?(rect[0][1]+i):(rect[1][1]-i-1); 00096 00097 if (ltidx==corner) 00098 glColor3f(col[0]*ltf, col[1]*ltf, col[2]*ltf); 00099 if (dkidx==corner) 00100 glColor3f(col[0]*dkf, col[1]*dkf, col[2]*dkf); 00101 00102 glVertex2i(lx, ly); 00103 glVertex2i(lx= x, ly= y); 00104 } 00105 } 00106 glEnd(); 00107 00108 glColor3fv(col); 00109 glRecti(rect[0][0]+width, rect[0][1]+width, rect[1][0]-width, rect[1][1]-width); 00110 } 00111 00112 void rect_bevel_smooth(int rect[2][2], int width) { 00113 float *lt= malloc(sizeof(*lt)*width); 00114 float *dk= malloc(sizeof(*dk)*width); 00115 float col[4]; 00116 int i; 00117 00118 for (i=0; i<width; i++) { 00119 float v= width-1?((float) i/(width-1)):0; 00120 lt[i]= 1.2 + (1.0-1.2)*v; 00121 dk[i]= 0.2 + (1.0-0.2)*v; 00122 } 00123 00124 glGetFloatv(GL_CURRENT_COLOR, col); 00125 00126 rect_bevel_side(rect, 3, lt, dk, col, width); 00127 00128 free(lt); 00129 free(dk); 00130 } 00131 00132 /* 00133 * MainWindow 00134 */ 00135 00136 typedef struct { 00137 MultiTestApp *app; 00138 00139 GHOST_WindowHandle win; 00140 00141 int size[2]; 00142 00143 int lmouse[2], lmbut[3]; 00144 00145 int tmouse[2]; 00146 } MainWindow; 00147 00148 static void mainwindow_log(MainWindow *mw, char *str) { 00149 loggerwindow_log(multitestapp_get_logger(mw->app), str); 00150 } 00151 00152 static void mainwindow_do_draw(MainWindow *mw) { 00153 GHOST_ActivateWindowDrawingContext(mw->win); 00154 00155 if (mw->lmbut[0]) { 00156 glClearColor(0.5, 0.5, 0.5, 1); 00157 } else { 00158 glClearColor(1, 1, 1, 1); 00159 } 00160 glClear(GL_COLOR_BUFFER_BIT); 00161 00162 glColor3f(0.5, 0.6, 0.8); 00163 glRecti(mw->tmouse[0]-5, mw->tmouse[1]-5, mw->tmouse[0]+5, mw->tmouse[1]+5); 00164 00165 GHOST_SwapWindowBuffers(mw->win); 00166 } 00167 00168 static void mainwindow_do_reshape(MainWindow *mw) { 00169 GHOST_RectangleHandle bounds= GHOST_GetClientBounds(mw->win); 00170 00171 GHOST_ActivateWindowDrawingContext(mw->win); 00172 00173 mw->size[0]= GHOST_GetWidthRectangle(bounds); 00174 mw->size[1]= GHOST_GetHeightRectangle(bounds); 00175 00176 glViewport(0, 0, mw->size[0], mw->size[1]); 00177 00178 glMatrixMode(GL_PROJECTION); 00179 glLoadIdentity(); 00180 glOrtho(0, mw->size[0], 0, mw->size[1], -1, 1); 00181 glTranslatef(0.375, 0.375, 0.0); 00182 00183 glMatrixMode(GL_MODELVIEW); 00184 glLoadIdentity(); 00185 } 00186 00187 static void mainwindow_do_key(MainWindow *mw, GHOST_TKey key, int press) { 00188 switch(key) { 00189 case GHOST_kKeyC: 00190 if (press) 00191 GHOST_SetCursorShape(mw->win, (GHOST_TStandardCursor) (rand()%(GHOST_kStandardCursorNumCursors))); 00192 break; 00193 case GHOST_kKeyLeftBracket: 00194 if (press) 00195 GHOST_SetCursorVisibility(mw->win, 0); 00196 break; 00197 case GHOST_kKeyRightBracket: 00198 if (press) 00199 GHOST_SetCursorVisibility(mw->win, 1); 00200 break; 00201 case GHOST_kKeyE: 00202 if (press) 00203 multitestapp_toggle_extra_window(mw->app); 00204 break; 00205 case GHOST_kKeyQ: 00206 if (press) 00207 multitestapp_exit(mw->app); 00208 break; 00209 case GHOST_kKeyT: 00210 if (press) 00211 mainwindow_log(mw, "TextTest~|`hello`\"world\",<>/"); 00212 break; 00213 case GHOST_kKeyR: 00214 if (press) { 00215 int i; 00216 00217 mainwindow_log(mw, "Invalidating window 10 times"); 00218 for (i=0; i<10; i++) 00219 GHOST_InvalidateWindow(mw->win); 00220 } 00221 break; 00222 case GHOST_kKeyF11: 00223 if (press) { 00224 GHOST_SetWindowOrder(mw->win, GHOST_kWindowOrderBottom); 00225 } 00226 break; 00227 } 00228 } 00229 00230 static void mainwindow_do_move(MainWindow *mw, int x, int y) { 00231 mw->lmouse[0]= x, mw->lmouse[1]= y; 00232 00233 if (mw->lmbut[0]) { 00234 mw->tmouse[0]= x, mw->tmouse[1]= y; 00235 GHOST_InvalidateWindow(mw->win); 00236 } 00237 } 00238 00239 static void mainwindow_do_button(MainWindow *mw, int which, int press) { 00240 if (which==GHOST_kButtonMaskLeft) { 00241 mw->lmbut[0]= press; 00242 mw->tmouse[0]= mw->lmouse[0], mw->tmouse[1]= mw->lmouse[1]; 00243 GHOST_InvalidateWindow(mw->win); 00244 } else if (which==GHOST_kButtonMaskLeft) { 00245 mw->lmbut[1]= press; 00246 } else if (which==GHOST_kButtonMaskLeft) { 00247 mw->lmbut[2]= press; 00248 } 00249 } 00250 00251 static void mainwindow_handle(void *priv, GHOST_EventHandle evt) { 00252 MainWindow *mw= priv; 00253 GHOST_TEventType type= GHOST_GetEventType(evt); 00254 char buf[256]; 00255 00256 event_to_buf(evt, buf); 00257 mainwindow_log(mw, buf); 00258 00259 switch (type) { 00260 case GHOST_kEventCursorMove: { 00261 GHOST_TEventCursorData *cd= GHOST_GetEventData(evt); 00262 int x, y; 00263 GHOST_ScreenToClient(mw->win, cd->x, cd->y, &x, &y); 00264 mainwindow_do_move(mw, x, mw->size[1]-y-1); 00265 break; 00266 } 00267 case GHOST_kEventButtonDown: 00268 case GHOST_kEventButtonUp: { 00269 GHOST_TEventButtonData *bd= GHOST_GetEventData(evt); 00270 mainwindow_do_button(mw, bd->button, (type == GHOST_kEventButtonDown)); 00271 break; 00272 } 00273 case GHOST_kEventKeyDown: 00274 case GHOST_kEventKeyUp: { 00275 GHOST_TEventKeyData *kd= GHOST_GetEventData(evt); 00276 mainwindow_do_key(mw, kd->key, (type == GHOST_kEventKeyDown)); 00277 break; 00278 } 00279 00280 case GHOST_kEventWindowUpdate: 00281 mainwindow_do_draw(mw); 00282 break; 00283 case GHOST_kEventWindowSize: 00284 mainwindow_do_reshape(mw); 00285 break; 00286 } 00287 } 00288 00289 00290 00291 static void mainwindow_timer_proc(GHOST_TimerTaskHandle task, GHOST_TUns64 time) { 00292 MainWindow *mw= GHOST_GetTimerTaskUserData(task); 00293 char buf[64]; 00294 00295 sprintf(buf, "timer: %6.2f", (double) ((GHOST_TInt64) time)/1000); 00296 mainwindow_log(mw, buf); 00297 } 00298 00299 MainWindow *mainwindow_new(MultiTestApp *app) { 00300 GHOST_SystemHandle sys= multitestapp_get_system(app); 00301 GHOST_WindowHandle win; 00302 00303 win= GHOST_CreateWindow(sys, "MultiTest:Main", 40, 40, 400, 400, 00304 GHOST_kWindowStateNormal, GHOST_kDrawingContextTypeOpenGL, 00305 FALSE, FALSE); 00306 00307 if (win) { 00308 MainWindow *mw= MEM_callocN(sizeof(*mw), "mainwindow_new"); 00309 mw->app= app; 00310 mw->win= win; 00311 00312 GHOST_SetWindowUserData(mw->win, windowdata_new(mw, mainwindow_handle)); 00313 00314 GHOST_InstallTimer(sys, 1000, 10000, mainwindow_timer_proc, mw); 00315 00316 return mw; 00317 } else { 00318 return NULL; 00319 } 00320 } 00321 00322 void mainwindow_free(MainWindow *mw) { 00323 GHOST_SystemHandle sys= multitestapp_get_system(mw->app); 00324 00325 windowdata_free(GHOST_GetWindowUserData(mw->win)); 00326 GHOST_DisposeWindow(sys, mw->win); 00327 MEM_freeN(mw); 00328 } 00329 00330 /* 00331 * LoggerWindow 00332 */ 00333 00334 struct _LoggerWindow { 00335 MultiTestApp *app; 00336 00337 GHOST_WindowHandle win; 00338 00339 #ifdef USE_BMF 00340 BMF_Font *font; 00341 #else 00342 int font; 00343 #endif 00344 int fonttexid; 00345 int fontheight; 00346 00347 int size[2]; 00348 00349 int ndisplines; 00350 int textarea[2][2]; 00351 ScrollBar *scroll; 00352 00353 char **loglines; 00354 int nloglines, logsize; 00355 00356 int lmbut[3]; 00357 int lmouse[2]; 00358 }; 00359 00360 #define SCROLLBAR_PAD 2 00361 #define SCROLLBAR_WIDTH 14 00362 #define TEXTAREA_PAD 2 00363 static void loggerwindow_recalc_regions(LoggerWindow *lw) { 00364 int nscroll[2][2]; 00365 00366 nscroll[0][0]= SCROLLBAR_PAD; 00367 nscroll[0][1]= SCROLLBAR_PAD; 00368 nscroll[1][0]= nscroll[0][0] + SCROLLBAR_WIDTH; 00369 nscroll[1][1]= lw->size[1] - SCROLLBAR_PAD - 1; 00370 00371 lw->textarea[0][0]= nscroll[1][0] + TEXTAREA_PAD; 00372 lw->textarea[0][1]= TEXTAREA_PAD; 00373 lw->textarea[1][0]= lw->size[0] - TEXTAREA_PAD - 1; 00374 lw->textarea[1][1]= lw->size[1] - TEXTAREA_PAD - 1; 00375 00376 lw->ndisplines= (lw->textarea[1][1]-lw->textarea[0][1])/lw->fontheight; 00377 00378 scrollbar_set_thumbpct(lw->scroll, (float) lw->ndisplines/lw->nloglines); 00379 scrollbar_set_rect(lw->scroll, nscroll); 00380 } 00381 00382 static void loggerwindow_setup_window_gl(LoggerWindow *lw) { 00383 glViewport(0, 0, lw->size[0], lw->size[1]); 00384 00385 glMatrixMode(GL_PROJECTION); 00386 glLoadIdentity(); 00387 glOrtho(0, lw->size[0], 0, lw->size[1], -1, 1); 00388 glTranslatef(0.375, 0.375, 0.0); 00389 00390 glMatrixMode(GL_MODELVIEW); 00391 glLoadIdentity(); 00392 } 00393 00394 static void loggerwindow_do_reshape(LoggerWindow *lw) { 00395 GHOST_RectangleHandle bounds= GHOST_GetClientBounds(lw->win); 00396 00397 GHOST_ActivateWindowDrawingContext(lw->win); 00398 00399 lw->size[0]= GHOST_GetWidthRectangle(bounds); 00400 lw->size[1]= GHOST_GetHeightRectangle(bounds); 00401 00402 loggerwindow_recalc_regions(lw); 00403 loggerwindow_setup_window_gl(lw); 00404 } 00405 00406 static void loggerwindow_do_draw(LoggerWindow *lw) { 00407 int i, ndisplines, startline; 00408 int sb_rect[2][2], sb_thumb[2][2]; 00409 00410 GHOST_ActivateWindowDrawingContext(lw->win); 00411 00412 glClearColor(1, 1, 1, 1); 00413 glClear(GL_COLOR_BUFFER_BIT); 00414 00415 glColor3f(0.8, 0.8, 0.8); 00416 rect_bevel_smooth(lw->textarea, 4); 00417 00418 scrollbar_get_rect(lw->scroll, sb_rect); 00419 scrollbar_get_thumb(lw->scroll, sb_thumb); 00420 00421 glColor3f(0.6, 0.6, 0.6); 00422 rect_bevel_smooth(sb_rect, 1); 00423 00424 if (scrollbar_is_scrolling(lw->scroll)) { 00425 glColor3f(0.6, 0.7, 0.5); 00426 } else { 00427 glColor3f(0.9, 0.9, 0.92); 00428 } 00429 rect_bevel_smooth(sb_thumb, 1); 00430 00431 startline= scrollbar_get_thumbpos(lw->scroll)*(lw->nloglines-1); 00432 ndisplines= min_i(lw->ndisplines, lw->nloglines-startline); 00433 00434 if (lw->fonttexid!=-1) { 00435 glBindTexture(GL_TEXTURE_2D, lw->fonttexid); 00436 00437 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 00438 glEnable(GL_BLEND); 00439 glEnable(GL_TEXTURE_2D); 00440 } 00441 glColor3f(0, 0, 0); 00442 for (i=0; i<ndisplines; i++) { 00443 /* stored in reverse order */ 00444 char *line= lw->loglines[(lw->nloglines-1)-(i+startline)]; 00445 int x_pos= lw->textarea[0][0] + 4; 00446 int y_pos= lw->textarea[0][1] + 4 + i*lw->fontheight; 00447 00448 #ifdef USE_BMF 00449 if (lw->fonttexid==-1) { 00450 glRasterPos2i(x_pos, y_pos); 00451 BMF_DrawString(lw->font, line); 00452 } else { 00453 BMF_DrawStringTexture(lw->font, line, x_pos, y_pos, 0.0); 00454 } 00455 #else 00456 BLF_position(lw->font, x_pos, y_pos, 0.0); 00457 BLF_draw(lw->font, line, 256); // XXX 00458 #endif 00459 } 00460 00461 #ifdef USE_BMF 00462 if (lw->fonttexid!=-1) { 00463 glDisable(GL_TEXTURE_2D); 00464 glDisable(GL_BLEND); 00465 } 00466 #endif 00467 00468 GHOST_SwapWindowBuffers(lw->win); 00469 } 00470 00471 static void loggerwindow_do_move(LoggerWindow *lw, int x, int y) { 00472 lw->lmouse[0]= x, lw->lmouse[1]= y; 00473 00474 if (scrollbar_is_scrolling(lw->scroll)) { 00475 scrollbar_keep_scrolling(lw->scroll, y); 00476 GHOST_InvalidateWindow(lw->win); 00477 } 00478 } 00479 00480 static void loggerwindow_do_button(LoggerWindow *lw, int which, int press) { 00481 if (which==GHOST_kButtonMaskLeft) { 00482 lw->lmbut[0]= press; 00483 00484 if (press) { 00485 if (scrollbar_contains_pt(lw->scroll, lw->lmouse)) { 00486 scrollbar_start_scrolling(lw->scroll, lw->lmouse[1]); 00487 GHOST_SetCursorShape(lw->win, GHOST_kStandardCursorUpDown); 00488 GHOST_InvalidateWindow(lw->win); 00489 } 00490 } else { 00491 if (scrollbar_is_scrolling(lw->scroll)) { 00492 scrollbar_stop_scrolling(lw->scroll); 00493 GHOST_SetCursorShape(lw->win, GHOST_kStandardCursorDefault); 00494 GHOST_InvalidateWindow(lw->win); 00495 } 00496 } 00497 } else if (which==GHOST_kButtonMaskMiddle) { 00498 lw->lmbut[1]= press; 00499 } else if (which==GHOST_kButtonMaskRight) { 00500 lw->lmbut[2]= press; 00501 } 00502 } 00503 00504 static void loggerwindow_do_key(LoggerWindow *lw, GHOST_TKey key, int press) { 00505 switch (key) { 00506 case GHOST_kKeyQ: 00507 if (press) 00508 multitestapp_exit(lw->app); 00509 break; 00510 } 00511 } 00512 00513 static void loggerwindow_handle(void *priv, GHOST_EventHandle evt) { 00514 LoggerWindow *lw= priv; 00515 GHOST_TEventType type= GHOST_GetEventType(evt); 00516 00517 switch(type) { 00518 case GHOST_kEventCursorMove: { 00519 GHOST_TEventCursorData *cd= GHOST_GetEventData(evt); 00520 int x, y; 00521 GHOST_ScreenToClient(lw->win, cd->x, cd->y, &x, &y); 00522 loggerwindow_do_move(lw, x, lw->size[1]-y-1); 00523 break; 00524 } 00525 case GHOST_kEventButtonDown: 00526 case GHOST_kEventButtonUp: { 00527 GHOST_TEventButtonData *bd= GHOST_GetEventData(evt); 00528 loggerwindow_do_button(lw, bd->button, (type == GHOST_kEventButtonDown)); 00529 break; 00530 } 00531 case GHOST_kEventKeyDown: 00532 case GHOST_kEventKeyUp: { 00533 GHOST_TEventKeyData *kd= GHOST_GetEventData(evt); 00534 loggerwindow_do_key(lw, kd->key, (type == GHOST_kEventKeyDown)); 00535 break; 00536 } 00537 00538 case GHOST_kEventWindowUpdate: 00539 loggerwindow_do_draw(lw); 00540 break; 00541 case GHOST_kEventWindowSize: 00542 loggerwindow_do_reshape(lw); 00543 break; 00544 } 00545 } 00546 00547 00548 00549 LoggerWindow *loggerwindow_new(MultiTestApp *app) { 00550 GHOST_SystemHandle sys= multitestapp_get_system(app); 00551 GHOST_TUns32 screensize[2]; 00552 GHOST_WindowHandle win; 00553 00554 GHOST_GetMainDisplayDimensions(sys, &screensize[0], &screensize[1]); 00555 win= GHOST_CreateWindow(sys, "MultiTest:Logger", 40, screensize[1]-432, 00556 800, 300, GHOST_kWindowStateNormal, 00557 GHOST_kDrawingContextTypeOpenGL, FALSE, FALSE); 00558 00559 if (win) { 00560 LoggerWindow *lw= MEM_callocN(sizeof(*lw), "loggerwindow_new"); 00561 int bbox[2][2]; 00562 lw->app= app; 00563 lw->win= win; 00564 00565 #ifdef USE_BMF 00566 lw->font= BMF_GetFont(BMF_kScreen12); 00567 lw->fonttexid= BMF_GetFontTexture(lw->font); 00568 00569 BMF_GetBoundingBox(lw->font, &bbox[0][0], &bbox[0][1], &bbox[1][0], &bbox[1][1]); 00570 lw->fontheight= rect_height(bbox); 00571 #else 00572 lw->font= BLF_load_mem("default", (unsigned char*)datatoc_bfont_ttf, datatoc_bfont_ttf_size); 00573 BLF_size(lw->font, 11, 72); 00574 lw->fontheight= BLF_height(lw->font, "A_"); 00575 #endif 00576 00577 lw->nloglines= lw->logsize= 0; 00578 lw->loglines= MEM_mallocN(sizeof(*lw->loglines)*lw->nloglines, "loglines"); 00579 00580 lw->scroll= scrollbar_new(2, 40); 00581 00582 GHOST_SetWindowUserData(lw->win, windowdata_new(lw, loggerwindow_handle)); 00583 00584 loggerwindow_do_reshape(lw); 00585 00586 return lw; 00587 } else { 00588 return NULL; 00589 } 00590 } 00591 00592 void loggerwindow_log(LoggerWindow *lw, char *line) { 00593 if (lw->nloglines==lw->logsize) { 00594 lw->loglines= memdbl(lw->loglines, &lw->logsize, sizeof(*lw->loglines)); 00595 } 00596 00597 lw->loglines[lw->nloglines++]= string_dup(line); 00598 scrollbar_set_thumbpct(lw->scroll, (float) lw->ndisplines/lw->nloglines); 00599 00600 GHOST_InvalidateWindow(lw->win); 00601 } 00602 00603 void loggerwindow_free(LoggerWindow *lw) { 00604 GHOST_SystemHandle sys= multitestapp_get_system(lw->app); 00605 int i; 00606 00607 for (i=0; i<lw->nloglines; i++) { 00608 MEM_freeN(lw->loglines[i]); 00609 } 00610 MEM_freeN(lw->loglines); 00611 00612 windowdata_free(GHOST_GetWindowUserData(lw->win)); 00613 GHOST_DisposeWindow(sys, lw->win); 00614 MEM_freeN(lw); 00615 } 00616 00617 /* 00618 * ExtraWindow 00619 */ 00620 00621 00622 typedef struct { 00623 MultiTestApp *app; 00624 00625 GHOST_WindowHandle win; 00626 00627 int size[2]; 00628 } ExtraWindow; 00629 00630 static void extrawindow_do_draw(ExtraWindow *ew) { 00631 GHOST_ActivateWindowDrawingContext(ew->win); 00632 00633 glClearColor(1, 1, 1, 1); 00634 glClear(GL_COLOR_BUFFER_BIT); 00635 00636 glColor3f(0.8, 0.8, 0.8); 00637 glRecti(10, 10, ew->size[0]-10, ew->size[1]-10); 00638 00639 GHOST_SwapWindowBuffers(ew->win); 00640 } 00641 00642 static void extrawindow_do_reshape(ExtraWindow *ew) { 00643 GHOST_RectangleHandle bounds= GHOST_GetClientBounds(ew->win); 00644 00645 GHOST_ActivateWindowDrawingContext(ew->win); 00646 00647 ew->size[0]= GHOST_GetWidthRectangle(bounds); 00648 ew->size[1]= GHOST_GetHeightRectangle(bounds); 00649 00650 glViewport(0, 0, ew->size[0], ew->size[1]); 00651 00652 glMatrixMode(GL_PROJECTION); 00653 glLoadIdentity(); 00654 glOrtho(0, ew->size[0], 0, ew->size[1], -1, 1); 00655 glTranslatef(0.375, 0.375, 0.0); 00656 00657 glMatrixMode(GL_MODELVIEW); 00658 glLoadIdentity(); 00659 } 00660 00661 static void extrawindow_do_key(ExtraWindow *ew, GHOST_TKey key, int press) { 00662 switch (key) { 00663 case GHOST_kKeyE: 00664 if (press) 00665 multitestapp_toggle_extra_window(ew->app); 00666 break; 00667 } 00668 } 00669 00670 static void extrawindow_spin_cursor(ExtraWindow *ew, GHOST_TUns64 time) { 00671 GHOST_TUns8 bitmap[16][2]; 00672 GHOST_TUns8 mask[16][2]; 00673 double ftime= (double) ((GHOST_TInt64) time)/1000; 00674 float angle= fmod(ftime, 1.0) * 3.1415*2; 00675 int i; 00676 00677 memset(&bitmap, 0, sizeof(bitmap)); 00678 memset(&mask, 0, sizeof(mask)); 00679 00680 bitmap[0][0] |= mask[0][0] |= 0xF; 00681 bitmap[1][0] |= mask[1][0] |= 0xF; 00682 bitmap[2][0] |= mask[2][0] |= 0xF; 00683 bitmap[3][0] |= mask[3][0] |= 0xF; 00684 00685 for (i=0; i<7; i++) { 00686 int x = 7 + cos(angle)*i; 00687 int y = 7 + sin(angle)*i; 00688 00689 mask[y][x/8] |= (1 << (x%8)); 00690 } 00691 for (i=0; i<64; i++) { 00692 float v= (i/63.0) * 3.1415*2; 00693 int x = 7 + cos(v)*7; 00694 int y = 7 + sin(v)*7; 00695 00696 mask[y][x/8] |= (1 << (x%8)); 00697 } 00698 00699 GHOST_SetCustomCursorShape(ew->win, bitmap, mask, 0, 0); 00700 } 00701 00702 static void extrawindow_handle(void *priv, GHOST_EventHandle evt) { 00703 ExtraWindow *ew= priv; 00704 GHOST_TEventType type= GHOST_GetEventType(evt); 00705 char buf[256]; 00706 00707 event_to_buf(evt, buf); 00708 loggerwindow_log(multitestapp_get_logger(ew->app), buf); 00709 00710 switch (type) { 00711 case GHOST_kEventKeyDown: 00712 case GHOST_kEventKeyUp: { 00713 GHOST_TEventKeyData *kd= GHOST_GetEventData(evt); 00714 extrawindow_do_key(ew, kd->key, (type == GHOST_kEventKeyDown)); 00715 break; 00716 } 00717 00718 case GHOST_kEventCursorMove: { 00719 extrawindow_spin_cursor(ew, GHOST_GetEventTime(evt)); 00720 break; 00721 } 00722 00723 case GHOST_kEventWindowClose: 00724 multitestapp_free_extrawindow(ew->app); 00725 break; 00726 case GHOST_kEventWindowUpdate: 00727 extrawindow_do_draw(ew); 00728 break; 00729 case GHOST_kEventWindowSize: 00730 extrawindow_do_reshape(ew); 00731 break; 00732 } 00733 } 00734 00735 00736 00737 ExtraWindow *extrawindow_new(MultiTestApp *app) { 00738 GHOST_SystemHandle sys= multitestapp_get_system(app); 00739 GHOST_WindowHandle win; 00740 00741 win= GHOST_CreateWindow(sys, "MultiTest:Extra", 500, 40, 400, 400, 00742 GHOST_kWindowStateNormal, GHOST_kDrawingContextTypeOpenGL, 00743 FALSE, FALSE); 00744 00745 if (win) { 00746 ExtraWindow *ew= MEM_callocN(sizeof(*ew), "mainwindow_new"); 00747 ew->app= app; 00748 ew->win= win; 00749 00750 GHOST_SetWindowUserData(ew->win, windowdata_new(ew, extrawindow_handle)); 00751 00752 return ew; 00753 } else { 00754 return NULL; 00755 } 00756 } 00757 00758 void extrawindow_free(ExtraWindow *ew) { 00759 GHOST_SystemHandle sys= multitestapp_get_system(ew->app); 00760 00761 windowdata_free(GHOST_GetWindowUserData(ew->win)); 00762 GHOST_DisposeWindow(sys, ew->win); 00763 MEM_freeN(ew); 00764 } 00765 00766 /* 00767 * MultiTestApp 00768 */ 00769 00770 struct _MultiTestApp { 00771 GHOST_SystemHandle sys; 00772 MainWindow *main; 00773 LoggerWindow *logger; 00774 ExtraWindow *extra; 00775 00776 int exit; 00777 }; 00778 00779 static int multitest_event_handler(GHOST_EventHandle evt, GHOST_TUserDataPtr data) { 00780 MultiTestApp *app= data; 00781 GHOST_WindowHandle win; 00782 00783 win= GHOST_GetEventWindow(evt); 00784 if (win && !GHOST_ValidWindow(app->sys, win)) { 00785 loggerwindow_log(app->logger, "WARNING: bad event, non-valid window\n"); 00786 return 1; 00787 } 00788 00789 if (win) { 00790 WindowData *wb= GHOST_GetWindowUserData(win); 00791 00792 windowdata_handle(wb, evt); 00793 } else { 00794 GHOST_TEventType type= GHOST_GetEventType(evt); 00795 00796 /* GHOST_kEventQuit are the only 'system' events, 00797 * that is, events without a window. 00798 */ 00799 switch(type) { 00800 case GHOST_kEventQuit: 00801 app->exit= 1; 00802 break; 00803 00804 default: 00805 fatal("Unhandled system event: %d (%s)\n", type, eventtype_to_string(type)); 00806 break; 00807 } 00808 } 00809 00810 return 1; 00811 } 00812 00813 00814 00815 MultiTestApp *multitestapp_new(void) { 00816 MultiTestApp *app= MEM_mallocN(sizeof(*app), "multitestapp_new"); 00817 GHOST_EventConsumerHandle consumer= GHOST_CreateEventConsumer(multitest_event_handler, app); 00818 00819 app->sys= GHOST_CreateSystem(); 00820 if (!app->sys) 00821 fatal("Unable to create ghost system"); 00822 00823 if (!GHOST_AddEventConsumer(app->sys, consumer)) 00824 fatal("Unable to add multitest event consumer "); 00825 00826 app->main= mainwindow_new(app); 00827 if (!app->main) 00828 fatal("Unable to create main window"); 00829 00830 app->logger= loggerwindow_new(app); 00831 if (!app->logger) 00832 fatal("Unable to create logger window"); 00833 00834 app->extra= NULL; 00835 app->exit= 0; 00836 00837 return app; 00838 } 00839 00840 LoggerWindow *multitestapp_get_logger(MultiTestApp *app) { 00841 return app->logger; 00842 } 00843 00844 GHOST_SystemHandle multitestapp_get_system(MultiTestApp *app) { 00845 return app->sys; 00846 } 00847 00848 void multitestapp_free_extrawindow(MultiTestApp *app) { 00849 extrawindow_free(app->extra); 00850 app->extra= NULL; 00851 } 00852 00853 void multitestapp_toggle_extra_window(MultiTestApp *app) { 00854 if (app->extra) { 00855 multitestapp_free_extrawindow(app); 00856 } else { 00857 app->extra= extrawindow_new(app); 00858 } 00859 } 00860 00861 void multitestapp_exit(MultiTestApp *app) { 00862 app->exit= 1; 00863 } 00864 00865 void multitestapp_run(MultiTestApp *app) { 00866 while (!app->exit) { 00867 GHOST_ProcessEvents(app->sys, 1); 00868 GHOST_DispatchEvents(app->sys); 00869 } 00870 } 00871 00872 void multitestapp_free(MultiTestApp *app) { 00873 mainwindow_free(app->main); 00874 loggerwindow_free(app->logger); 00875 GHOST_DisposeSystem(app->sys); 00876 MEM_freeN(app); 00877 } 00878 00879 /***/ 00880 00881 int main(int argc, char **argv) { 00882 #ifndef USE_BMF 00883 BLF_init(11, 72); 00884 #endif 00885 00886 MultiTestApp *app= multitestapp_new(); 00887 00888 multitestapp_run(app); 00889 multitestapp_free(app); 00890 00891 return 0; 00892 }