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