752f4359365c6f1f86c89c326f3d48bdcc3d8ec2
[blender.git] / source / blender / src / toets.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31
32  *
33  *
34  * General blender hot keys (toets = dutch), special hotkeys are in space.c
35  *
36  */
37
38 #include <string.h>
39 #include <math.h>
40
41 #ifdef WIN32
42 #include "BLI_winstuff.h"
43 #endif
44
45 #include "MEM_guardedalloc.h"
46
47 #include "PIL_time.h"
48
49 #include "nla.h"        /* Only for the #ifdef flag - To be removed later */
50
51 #include "BLI_blenlib.h"
52 #include "BLI_arithb.h"
53
54 #include "DNA_object_types.h"
55 #include "DNA_screen_types.h"
56 #include "DNA_space_types.h"
57 #include "DNA_view3d_types.h"
58 #include "DNA_userdef_types.h"
59
60 #include "BKE_action.h"
61 #include "BKE_anim.h"
62 #include "BKE_blender.h"
63 #include "BKE_displist.h"
64 #include "BKE_global.h"
65 #include "BKE_ipo.h"
66 #include "BKE_ika.h"
67 #include "BKE_key.h"
68 #include "BKE_scene.h"
69 #include "BKE_utildefines.h"
70
71 #include "BIF_butspace.h"
72 #include "BIF_editseq.h"
73 #include "BIF_editsound.h"
74 #include "BIF_editmesh.h"
75 #include "BIF_interface.h"
76 #include "BIF_poseobject.h"
77 #include "BIF_renderwin.h"
78 #include "BIF_screen.h"
79 #include "BIF_space.h"
80 #include "BIF_toets.h"
81 #include "BIF_toolbox.h"
82 #include "BIF_usiblender.h"
83
84 #include "BDR_vpaint.h"
85 #include "BDR_editobject.h"
86 #include "BDR_editface.h"
87
88 #include "BSE_filesel.h"        /* For activate_fileselect */
89 #include "BSE_drawview.h"       /* For play_anim */
90 #include "BSE_view.h"
91 #include "BSE_edit.h"
92 #include "BSE_editipo.h"
93 #include "BSE_headerbuttons.h"
94
95 #include "blendef.h"
96 #include "render.h"             // darn schrijfplaatje() (ton)
97
98 #include "IMB_imbuf.h"
99 #include "IMB_imbuf_types.h"
100
101 #include "mydevice.h"
102
103 #include "BIF_poseobject.h"
104
105 /* only used in toets.c and initrender.c */
106 /* this function doesn't really belong here */
107 /* ripped from render module */
108 void schrijfplaatje(char *name);
109
110
111 static void write_imag(char *name)
112 {
113         /* from file select */
114         char str[256];
115
116         strcpy(str, name);
117         BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
118
119         if(saveover(str)) {
120                 if(BLI_testextensie(str,".blend")) {
121                         error("Wrong filename");
122                         return;
123                 }
124                 waitcursor(1); /* from screen.c */
125                 schrijfplaatje(str);
126                 strcpy(G.ima, name);
127                 waitcursor(0);
128         }
129 }
130
131
132 /* From matrix.h: it's really a [4][4]! */
133 /* originally in initrender... maybe add fileControl thingy? */
134
135 /* should be called write_image(char *name) :-) */
136 void schrijfplaatje(char *name)
137 {
138         struct ImBuf *ibuf=0;
139         unsigned int *temprect=0;
140         char str[FILE_MAXDIR+FILE_MAXFILE];
141
142         /* has RGBA been set? If so: use alpha channel for color zero */
143         IMB_alpha_to_col0(FALSE);
144
145         if(R.r.planes == 32) {
146                 /* everything with less than 50 % alpha -> col 0 */
147                 if(R.r.alphamode == R_ALPHAKEY) IMB_alpha_to_col0(2);
148                 /* only when 0 alpha -> col 0 */
149                 else IMB_alpha_to_col0(1);
150         }
151
152         /* Seems to me this is also superfluous.... */
153         if (R.r.imtype==R_FTYPE) {
154                 strcpy(str, R.r.ftype);
155                 BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
156
157                 ibuf = IMB_loadiffname(str, IB_test);
158                 if(ibuf) {
159                         ibuf->x = R.rectx;
160                         ibuf->y = R.recty;
161                 }
162                 else {
163                         error("Can't find filetype");
164                         G.afbreek= 1;
165                         return;
166                 }
167                 /* setdither(2); */
168         }
169
170         if(ibuf == 0) {
171                 ibuf= IMB_allocImBuf(R.rectx, R.recty, R.r.planes, 0, 0);
172         }
173
174         if(ibuf) {
175                 ibuf->rect= (unsigned int *) R.rectot;
176                 ibuf->rect_float = R.rectftot;
177
178                 if(R.r.planes == 8) IMB_cspace(ibuf, rgb_to_bw);
179
180                 if(R.r.imtype== R_IRIS) {
181                         ibuf->ftype= IMAGIC;
182                 }
183                 else if(R.r.imtype==R_IRIZ) {
184                         ibuf->ftype= IMAGIC;
185                         if (ibuf->zbuf == 0) {
186                                 if (R.rectz) {
187                                         ibuf->zbuf = (int *)R.rectz;
188                                 }
189                                 else printf("no zbuf\n");
190                         }
191                 }
192                 else if(R.r.imtype==R_PNG) {
193                         ibuf->ftype= PNG;
194                 }
195 #ifdef WITH_OPENEXR
196                 else if(R.r.imtype==R_OPENEXR) {
197                         ibuf->ftype= OPENEXR;
198                         if (ibuf->zbuf == 0) {
199                                 if (R.rectz) {
200                                         ibuf->zbuf = (int *)R.rectz;
201                                 }
202                                 else printf("Write OPENEXR: no zbuf !\n");
203                         }
204                 }
205 #endif
206                 else if(R.r.imtype==R_BMP) {
207                         ibuf->ftype= BMP;
208                 }
209                 else if((R.r.imtype==R_TARGA) || (R.r.imtype==R_PNG)) {
210                         ibuf->ftype= TGA;
211                 }
212                 else if(R.r.imtype==R_RAWTGA) {
213                         ibuf->ftype= RAWTGA;
214                 }
215                 else if(R.r.imtype==R_HAMX) {
216                         /* make copy */
217                         temprect= MEM_dupallocN(R.rectot);
218                         ibuf->ftype= AN_hamx;
219                 }
220                 else if(ELEM5(R.r.imtype, R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90)) {
221                         if(R.r.quality < 10) R.r.quality= 90;
222
223                         if(R.r.mode & R_FIELDS) ibuf->ftype= JPG_VID|R.r.quality;
224                         else ibuf->ftype= JPG|R.r.quality;
225                 }
226         
227                 RE_make_existing_file(name);
228
229                 if(IMB_saveiff(ibuf, name, IB_rect | IB_zbuf)==0) {
230                         perror(name);
231                         G.afbreek= 1;
232                 }
233
234                 IMB_freeImBuf(ibuf);
235
236                 if (R.r.imtype==R_HAMX) {
237                         MEM_freeN(R.rectot);
238                         R.rectot= temprect;
239                 }
240         }
241         else {
242                 G.afbreek= 1;
243         }
244 }
245
246
247
248 /* ------------------------------------------------------------------------- */
249
250 static int is_an_active_object(void *ob) {
251         Base *base;
252         
253         for (base= FIRSTBASE; base; base= base->next)
254                 if (base->object == ob)
255                         return 1;
256         
257         return 0;
258 }
259
260 void persptoetsen(unsigned short event)
261 {
262         static Object *oldcamera=0;
263         float phi, si, q1[4], vec[3];
264         static int perspo=1;
265         
266         if(event==PADENTER) {
267                 if (G.qual == LR_SHIFTKEY) {
268                         view3d_set_1_to_1_viewborder(G.vd);
269                 } else {
270                         if (G.vd->persp==2) {
271                                 G.vd->camzoom= 0.0;
272                         } else {
273                                 G.vd->dist= 10.0;
274                         }
275                 }
276         }
277         else if((G.qual & (LR_SHIFTKEY | LR_CTRLKEY)) && (event != PAD0)) {
278                 if(event==PAD0) {
279                         /* G.vd->persp= 3; */
280                 }
281                 else if(event==PAD7) {
282                         G.vd->viewquat[0]= 0.0;
283                         G.vd->viewquat[1]= -1.0;
284                         G.vd->viewquat[2]= 0.0;
285                         G.vd->viewquat[3]= 0.0;
286                         G.vd->view= 7;
287                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0; 
288                         else if(G.vd->persp>=2) G.vd->persp= perspo;
289                 }
290                 else if(event==PAD1) {
291                         G.vd->viewquat[0]= 0.0;
292                         G.vd->viewquat[1]= 0.0;
293                         G.vd->viewquat[2]= (float)-cos(M_PI/4.0);
294                         G.vd->viewquat[3]= (float)-cos(M_PI/4.0);
295                         G.vd->view=1;
296                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
297                         else if(G.vd->persp>=2) G.vd->persp= perspo;
298                 }
299                 else if(event==PAD3) {
300                         G.vd->viewquat[0]= 0.5;
301                         G.vd->viewquat[1]= -0.5;
302                         G.vd->viewquat[2]= 0.5;
303                         G.vd->viewquat[3]= 0.5;
304                         G.vd->view=3;
305                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
306                         else if(G.vd->persp>=2) G.vd->persp= perspo;
307                 }
308                 else if(event==PADMINUS) {
309                         /* this min and max is also in viewmove() */
310                         if(G.vd->persp==2) {
311                                         G.vd->camzoom-= 10;
312                                         if(G.vd->camzoom<-30) G.vd->camzoom= -30;
313                                 }
314                         else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f;
315                 }
316                 else if(event==PADPLUSKEY) {
317                         if(G.vd->persp==2) {
318                                         G.vd->camzoom+= 10;
319                                         if(G.vd->camzoom>300) G.vd->camzoom= 300;
320                         }
321                         else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f;
322                 }
323                 else {
324
325                         initgrabz(0.0, 0.0, 0.0);
326                         
327                         if(event==PAD6) window_to_3d(vec, -32, 0);
328                         else if(event==PAD4) window_to_3d(vec, 32, 0);
329                         else if(event==PAD8) window_to_3d(vec, 0, -25);
330                         else if(event==PAD2) window_to_3d(vec, 0, 25);
331                         G.vd->ofs[0]+= vec[0];
332                         G.vd->ofs[1]+= vec[1];
333                         G.vd->ofs[2]+= vec[2];
334                 }
335         }
336         else {
337
338                 if(event==PAD7) {
339                         G.vd->viewquat[0]= 1.0;
340                         G.vd->viewquat[1]= 0.0;
341                         G.vd->viewquat[2]= 0.0;
342                         G.vd->viewquat[3]= 0.0;
343                         G.vd->view=7;
344                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
345                         else if(G.vd->persp>=2) G.vd->persp= perspo;
346                 }
347                 else if(event==PAD1) {
348                         G.vd->viewquat[0]= (float)cos(M_PI/4.0);
349                         G.vd->viewquat[1]= (float)-sin(M_PI/4.0);
350                         G.vd->viewquat[2]= 0.0;
351                         G.vd->viewquat[3]= 0.0;
352                         G.vd->view=1;
353                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
354                         else if(G.vd->persp>=2) G.vd->persp= perspo;
355                 }
356                 else if(event==PAD3) {
357                         G.vd->viewquat[0]= 0.5;
358                         G.vd->viewquat[1]= -0.5;
359                         G.vd->viewquat[2]= -0.5;
360                         G.vd->viewquat[3]= -0.5;
361                         G.vd->view=3;
362                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
363                         else if(G.vd->persp>=2) G.vd->persp= perspo;
364                 }
365                 else if(event==PADMINUS) {
366                         /* this min and max is also in viewmove() */
367                         if(G.vd->persp==2) {
368                                 G.vd->camzoom= MAX2(-30, G.vd->camzoom-5);
369                         }
370                         else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f;
371                 }
372                 else if(event==PADPLUSKEY) {
373                         if(G.vd->persp==2) {
374                                 G.vd->camzoom= MIN2(300, G.vd->camzoom+5);
375                         }
376                         else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f;
377                 }
378                 else if(event==PAD5) {
379                         if(G.vd->persp==1) G.vd->persp=0;
380                         else G.vd->persp=1;
381                 }
382                 else if(event==PAD0) {
383                         if(G.qual==LR_ALTKEY) {
384                                 if(oldcamera && is_an_active_object(oldcamera)) {
385                                         G.vd->camera= oldcamera;
386                                 }
387                                 
388                                 handle_view3d_lock();
389                         }
390                         else if(BASACT) {
391                                 if(G.qual==LR_CTRLKEY) {
392                                         if(G.vd->camera != OBACT) {
393                                                 if(G.vd->camera && G.vd->camera->type==OB_CAMERA)
394                                                         oldcamera= G.vd->camera;
395                                                 
396                                                 G.vd->camera= OBACT;
397                                                 handle_view3d_lock();
398                                         }
399                                 }
400                                 else if(G.vd->camera==0 && OBACT->type==OB_CAMERA) {
401                                         G.vd->camera= OBACT;
402                                         handle_view3d_lock();
403                                 }
404                         }
405                         if(G.vd->camera==0) {
406                                 G.vd->camera= scene_find_camera(G.scene);
407                                 handle_view3d_lock();
408                         }
409                         
410                         if(G.vd->camera) {
411                                 G.vd->persp= 2;
412                                 G.vd->view= 0;
413                                 if(((G.qual & LR_CTRLKEY) && (G.qual & LR_ALTKEY)) || (G.qual & LR_SHIFTKEY)) {
414                                         void setcameratoview3d(void);   // view.c
415                                         setcameratoview3d();
416                                 }                               
417                         }
418                 }
419                 else if(event==PAD9) {
420                         countall();
421                         do_all_ipos();
422                         do_all_keys();
423                         do_all_actions();
424                         do_all_ikas();
425                         test_all_displists();
426                         
427                         reset_slowparents();    /* editobject.c */
428                 }
429                 else if(G.vd->persp<2) {
430                         if(event==PAD4 || event==PAD6) {
431                                 /* z-axis */
432                                 phi= (float)(M_PI/24.0);
433                                 if(event==PAD6) phi= -phi;
434                                 si= (float)sin(phi);
435                                 q1[0]= (float)cos(phi);
436                                 q1[1]= q1[2]= 0.0;
437                                 q1[3]= si;
438                                 QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
439                                 G.vd->view= 0;
440                         }
441                         if(event==PAD2 || event==PAD8) {
442                                 
443                                 /* horizontal axis */
444                                 VECCOPY(q1+1, G.vd->viewinv[0]);
445                                 
446                                 Normalise(q1+1);
447                                 phi= (float)(M_PI/24.0);
448                                 if(event==PAD2) phi= -phi;
449                                 si= (float)sin(phi);
450                                 q1[0]= (float)cos(phi);
451                                 q1[1]*= si;
452                                 q1[2]*= si;
453                                 q1[3]*= si;
454                                 QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
455                                 G.vd->view= 0;
456                         }
457                 }
458
459                 if(G.vd->persp<2) perspo= G.vd->persp;
460         }
461         scrarea_queue_redraw(curarea);
462 }
463
464 int untitled(char * name)
465 {
466         if (G.save_over == 0 ) {
467                 char * c= BLI_last_slash(name);
468                 
469                 if (c)
470                         strcpy(&c[1], "untitled.blend");
471                 else
472                         strcpy(name, "untitled.blend");
473                         
474                 return(TRUE);
475         }
476         
477         return(FALSE);
478 }
479
480 int save_image_filesel_str(char *str)
481 {
482         switch(G.scene->r.imtype) {
483         case R_PNG:
484                 strcpy(str, "Save PNG"); return 1;
485         case R_OPENEXR:
486                 strcpy(str, "Save OPENEXR"); return 1;
487         case R_BMP:
488                 strcpy(str, "Save BMP"); return 1;
489         case R_TARGA:
490                 strcpy(str, "Save Targa"); return 1;
491         case R_RAWTGA:
492                 strcpy(str, "Save Raw Targa"); return 1;
493         case R_IRIS:
494                 strcpy(str, "Save IRIS"); return 1;
495         case R_IRIZ:
496                 strcpy(str, "Save IRIS"); return 1;
497         case R_HAMX:
498                 strcpy(str, "Save HAMX"); return 1;
499         case R_FTYPE:
500                 strcpy(str, "Save Ftype"); return 1;
501         case R_JPEG90:
502                 strcpy(str, "Save JPEG"); return 1;
503         default:
504                 strcpy(str, "Save Image"); return 0;
505         }       
506 }
507
508 void BIF_save_rendered_image(void)
509 {
510         if(!R.rectot) {
511                 error("No image rendered");
512         } else {
513                 char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2];
514
515                 if(G.ima[0]==0) {
516                         strcpy(dir, G.sce);
517                         BLI_splitdirstring(dir, str);
518                         strcpy(G.ima, dir);
519                 }
520                 
521                 R.r.imtype= G.scene->r.imtype;
522                 R.r.quality= G.scene->r.quality;
523                 R.r.planes= G.scene->r.planes;
524         
525                 if (!save_image_filesel_str(str)) {
526                         error("Select an image type in DisplayButtons(F10)");
527                 } else {
528                         activate_fileselect(FILE_SPECIAL, str, G.ima, write_imag);
529                 }
530         }
531 }
532
533 int blenderqread(unsigned short event, short val)
534 {
535         /* here do the general keys handling (not screen/window/space) */
536         /* return 0: do not pass on to the other queues */
537         extern int textediting;
538         ScrArea *sa;
539         Object *ob;
540         int textspace=0;
541         /* Changed str and dir size to 160, to make sure there is enough
542          * space for filenames. */
543         char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2];
544         
545         if(val==0) return 1;
546         if(event==MOUSEY || event==MOUSEX) return 1;
547         if (G.flags & G_FLAGS_AUTOPLAY) return 1;
548
549         if (curarea && curarea->spacetype==SPACE_TEXT) textspace= 1;
550         else if (curarea && curarea->spacetype==SPACE_SCRIPT) textspace= 1;
551
552         switch(event) {
553
554         case F1KEY:
555                 if(G.qual==0) {
556                         /* this exception because of the '?' button */
557                         if(curarea->spacetype==SPACE_INFO) {
558                                 sa= closest_bigger_area();
559                                 areawinset(sa->win);
560                         }
561                         
562                         activate_fileselect(FILE_BLENDER, "Open File", G.sce, BIF_read_file);
563                         return 0;
564                 }
565                 else if(G.qual==LR_SHIFTKEY) {
566                         activate_fileselect(FILE_LOADLIB, "Load Library", G.lib, 0);
567                         return 0;
568                 }
569                 break;
570         case F2KEY:
571                 if(G.qual==0) {
572                         strcpy(dir, G.sce);
573                         untitled(dir);
574                         activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
575                         return 0;
576                 }
577                 else if(G.qual==LR_CTRLKEY) {
578                         write_vrml_fs();
579                         return 0;
580                 }
581                 else if(G.qual==LR_SHIFTKEY) {
582                         write_dxf_fs();
583                         return 0;
584                 }
585                 break;
586         case F3KEY:
587                 if(G.qual==0) {
588                         BIF_save_rendered_image();
589                         return 0;
590                 }
591                 else if(G.qual & LR_CTRLKEY) {
592                         /* all alt+ctrl+shift combos are needed here... */
593                         BIF_screendump(0);
594                 }
595                 break;
596         case F4KEY:
597                 if(G.qual==LR_SHIFTKEY) {
598
599                         memset(str, 0, 16);
600                         ob= OBACT;
601                         if(ob) strcpy(str, ob->id.name);
602
603                         activate_fileselect(FILE_MAIN, "Data Select", str, 0);
604                         return 0;
605                 }
606                 else if(G.qual==0) {
607                         extern_set_butspace(event);
608                 }
609                 break;
610         case F5KEY:
611                 if(G.qual==LR_SHIFTKEY) {
612                         newspace(curarea, SPACE_VIEW3D);
613                         return 0;
614                 }
615                 else if(G.qual==0) {
616                         extern_set_butspace(event);
617                 }
618                 break;
619         case F6KEY:
620                 if(G.qual==LR_SHIFTKEY) {
621                         newspace(curarea, SPACE_IPO);
622                         return 0;
623                 }
624                 else if(G.qual==0) {
625                         extern_set_butspace(event);
626                 }
627                 break;
628         case F7KEY:
629                 if(G.qual==LR_SHIFTKEY) {
630                         newspace(curarea, SPACE_BUTS);
631                         return 0;
632                 }
633                 else if(G.qual==0) {
634                         extern_set_butspace(event);
635                 }
636                 break;
637         case F8KEY:
638                 if(G.qual==LR_SHIFTKEY) {
639                         newspace(curarea, SPACE_SEQ);
640                         return 0;
641                 }
642                 else if(G.qual==0) {
643                         extern_set_butspace(event);
644                 }
645                 break;
646         case F9KEY:
647                 if(G.qual==LR_SHIFTKEY) {
648                         newspace(curarea, SPACE_OOPS);
649                         return 0;
650                 }
651                 else if(G.qual==(LR_SHIFTKEY|LR_ALTKEY)) {
652                         newspace(curarea, SPACE_OOPS+256);
653                         return 0;
654                 }
655                 else if(G.qual==0) {
656                         extern_set_butspace(event);
657                 }
658                 break;
659         case F10KEY:
660                 if(G.qual==LR_SHIFTKEY) {
661                         newspace(curarea, SPACE_IMAGE);
662                         return 0;
663                 }
664                 else if(G.qual==0) {
665                         extern_set_butspace(event);
666                 }
667                 break;
668         case F11KEY:
669                 if(G.qual==LR_SHIFTKEY) {
670                         newspace(curarea, SPACE_TEXT);
671                         return 0;
672                 }
673                 else if(G.qual==0) {
674                         BIF_toggle_render_display();
675                         return 0;
676                 }
677                 break;
678         case F12KEY:
679                 if(G.qual==LR_SHIFTKEY) {
680                         newspace(curarea, SPACE_ACTION);
681                         return 0;
682                 }
683                 else if (G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
684                         newspace(curarea, SPACE_NLA);
685                         return 0;
686                 }
687                 else {
688                         /* ctrl/alt + f12 should render too, for some macs have f12 assigned to cd eject */
689                         BIF_do_render(0);
690                 }
691                 return 0;
692                 break;
693         
694         case LEFTARROWKEY:
695         case DOWNARROWKEY:
696                 if(textediting==0 && textspace==0) {
697
698 #ifdef _WIN32   // FULLSCREEN
699                         if(event==DOWNARROWKEY){
700                                 if (G.qual==LR_ALTKEY)
701                                         mainwindow_toggle_fullscreen(0);
702                                 else if(G.qual==0)
703                                         CFRA-= 10;
704                         }
705 #else
706                         if((event==DOWNARROWKEY)&&(G.qual==0))
707                                 CFRA-= 10;
708 #endif
709                         else if((event==LEFTARROWKEY)&&(G.qual==0))
710                                 CFRA--;
711                         
712                         if(G.qual==LR_SHIFTKEY)
713                                 CFRA= SFRA;
714                         if(CFRA<1) CFRA=1;
715         
716                         update_for_newframe();
717                         return 0;
718                 }
719                 break;
720
721         case RIGHTARROWKEY:
722         case UPARROWKEY:
723                 if(textediting==0 && textspace==0) {
724
725 #ifdef _WIN32   // FULLSCREEN
726                         if(event==UPARROWKEY){ 
727                                 if(G.qual==LR_ALTKEY)
728                                         mainwindow_toggle_fullscreen(1);
729                                 else if(G.qual==0)
730                                         CFRA+= 10;
731                         }
732 #else
733                         if((event==UPARROWKEY)&&(G.qual==0))
734                                 CFRA+= 10;
735 #endif
736                         else if((event==RIGHTARROWKEY)&&(G.qual==0))
737                                 CFRA++;
738
739                         if(G.qual==LR_SHIFTKEY)
740                                 CFRA= EFRA;
741                         
742                         update_for_newframe();
743                 }
744                 break;
745
746         case ESCKEY:
747                 sound_stop_all_sounds();
748                 break;
749         case TABKEY:
750                 if(G.qual==0) {
751                         if(textspace==0) {
752                                 if(curarea->spacetype==SPACE_IPO)
753                                         set_editflag_editipo();
754                                 else if(curarea->spacetype==SPACE_SEQ)
755                                         enter_meta();
756                                 else if(G.vd) {
757                                         /* also when Alt-E */
758                                         if(G.obedit==NULL) {
759                                                 enter_editmode();
760                                                 if(G.obedit) BIF_undo_push("Original"); // here, because all over code enter_editmode is abused
761                                         }
762                                         else
763                                                 exit_editmode(2); // freedata, and undo
764                                 }
765                                 return 0;
766                         }
767                 }
768                 else if(G.qual==LR_CTRLKEY){
769                         Object *ob= OBACT;
770                         if(ob) {
771                                 if(ob->type==OB_ARMATURE) {
772                                         if(G.obpose) exit_posemode(1);
773                                         else enter_posemode();
774                                 }
775                                 else if(ob->type==OB_MESH) {
776                                         if(ob==G.obedit) EM_selectmode_menu();
777                                 }
778                         }
779                 }
780                 else if(G.qual==LR_SHIFTKEY) {
781                         if(G.obedit)
782                                 exit_editmode(2); // freedata, and undo
783                         if(G.f & G_FACESELECT)
784                                 set_faceselect();
785                         if(G.f & G_VERTEXPAINT)
786                                 set_vpaint();
787                         if(G.f & G_TEXTUREPAINT) {
788                                 G.f &= ~G_TEXTUREPAINT;
789                                 allqueue(REDRAWVIEW3D, 0);
790                                 allqueue(REDRAWBUTSEDIT, 0);
791                         }
792                         if(G.f & G_WEIGHTPAINT)
793                                 set_wpaint();
794                         if(G.obpose)
795                                 exit_posemode(1);
796                 }
797                 break;
798
799         case BACKSPACEKEY:
800                 break;
801
802         case AKEY:
803                 if(textediting==0 && textspace==0) {
804                         if(G.qual==(LR_SHIFTKEY|LR_ALTKEY)){
805                                 play_anim(1);
806                                 return 0;
807                         }
808                         else if(G.qual==LR_ALTKEY) {
809                                 play_anim(0);
810                                 return 0;
811                         }
812                 }
813                 break;
814         case EKEY:
815                 if(G.qual==LR_ALTKEY) {
816                         if(G.vd && textspace==0) {
817                                 if(G.obedit==0) {
818                                         enter_editmode();
819                                         BIF_undo_push("Original");
820                                 }
821                                 else
822                                         exit_editmode(2); // freedata, and undo
823                                 return 0;
824                         }                       
825                 }
826                 break;
827         case IKEY:
828                 if(textediting==0 && textspace==0 && curarea->spacetype!=SPACE_FILE && curarea->spacetype!=SPACE_IMASEL) {
829                         if(G.qual==0) {
830                                 common_insertkey();
831                                 return 0;
832                         }
833                 }
834                 break;
835         case JKEY:
836                 if(textediting==0 && textspace==0) {
837                         if(R.rectot && G.qual==0) {
838                                 BIF_swap_render_rects();
839                                 return 0;
840                         }
841                 }
842                 break;
843
844         case NKEY:
845                 if(textediting==0 && textspace==0) {
846                         if(G.qual & LR_CTRLKEY);
847                         else if(G.qual==0 || (G.qual & LR_SHIFTKEY)) {
848                                 if(curarea->spacetype==SPACE_VIEW3D);           // is new panel, in view3d queue
849                                 else if(curarea->spacetype==SPACE_IPO);                 // is new panel, in ipo queue
850                                 else if(curarea->spacetype==SPACE_IMAGE);                       // is new panel, in ipo queue
851                                 else if(curarea->spacetype==SPACE_ACTION);                      // is own queue
852                                 else if(curarea->spacetype==SPACE_NLA);                 // is new panel
853                                 else if(curarea->spacetype==SPACE_SEQ);                 // is new panel
854                                 else {
855                                         clever_numbuts();
856                                         return 0;
857                                 }
858                         }
859                 }
860                 break;
861                 
862         case OKEY:
863                 if(textediting==0) {
864                         if(G.qual==LR_CTRLKEY) {
865                                 /* There seem to be crashes here sometimes.... String
866                                  * bound overwrites? I changed dir and str sizes,
867                                  * let's see if this reoccurs. */
868                                 sprintf(str, "Open file: %s", G.sce);
869                         
870                                 if(okee(str)) {
871                                         strcpy(dir, G.sce);
872                                         BIF_read_file(dir);
873                                 }
874                                 return 0;
875                         }
876                 }
877                 break;
878                 
879         case SKEY:
880                 if(G.obpose==0 && G.obedit==0) {
881                         if(G.qual==LR_CTRLKEY) {
882                                 strcpy(dir, G.sce);
883                                 if (untitled(dir)) {
884                                         activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
885                                 } else {
886                                         BIF_write_file(dir);
887                                         free_filesel_spec(dir);
888                                 }
889                                 return 0;
890                         }
891                 }
892                 break;
893         
894         case TKEY:
895                 if (G.qual==(LR_SHIFTKEY|LR_ALTKEY|LR_CTRLKEY)) {
896                         int a;
897                         double delta, stime;
898
899                         waitcursor(1);
900                         
901                         stime= PIL_check_seconds_timer();
902                         for(a=0; a<100000; a++) {
903                                 scrarea_do_windraw(curarea);
904
905                                 delta= PIL_check_seconds_timer()-stime;
906                                 if (delta>5.0) break;
907                         }
908                         
909                         waitcursor(0);
910                         notice("FPS: %f (%d iterations)", a/delta, a);
911                         return 0;
912                 }
913                 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY)) {
914                         int a;
915                         int event= pupmenu("10 Timer%t|draw|draw+swap|displist|undo");
916                         if(event>0) {
917                                 double stime= PIL_check_seconds_timer();
918                                 char tmpstr[128];
919                                 int time;
920
921                                 waitcursor(1);
922                                 
923                                 for(a=0; a<10; a++) {
924                                         if (event==1) {
925                                                 scrarea_do_windraw(curarea);
926                                         } else if (event==2) {
927                                                 scrarea_do_windraw(curarea);
928                                                 screen_swapbuffers();
929                                         } else if (event==3) {
930                                                 if (OBACT) {
931                                                         makeDispList(OBACT);
932                                                 }
933                                         }
934                                         else if(event==4) {
935                                                 BKE_write_undo("10 timer");
936                                         }
937                                 }
938                         
939                                 time= (PIL_check_seconds_timer()-stime)*1000;
940                                 
941                                 if(event==1) sprintf(tmpstr, "draw %%t|%d ms", time);
942                                 if(event==2) sprintf(tmpstr, "d+sw %%t|%d ms", time);
943                                 if(event==3) sprintf(tmpstr, "displist %%t|%d ms", time);
944                                 if(event==4) sprintf(tmpstr, "undo %%t|%d ms", time);
945                         
946                                 waitcursor(0);
947                                 pupmenu(tmpstr);
948
949                         }
950                         return 0;
951                 }
952                 break;
953                                 
954         case UKEY:
955                 if(textediting==0) {
956                         if(G.qual==LR_CTRLKEY) {
957                                 if(okee("Save user defaults")) {
958                                         BIF_write_homefile();
959                                 }
960                                 return 0;
961                         }
962                         else if(G.qual==LR_ALTKEY) {
963                                 if(curarea->spacetype!=SPACE_TEXT) {
964                                         BIF_undo_menu();
965                                         return 0;
966                                 }
967                         }
968                 }
969                 break;
970                 
971         case WKEY:
972                 if(textediting==0) {
973                         if(G.qual==LR_CTRLKEY) {
974                                 strcpy(dir, G.sce);
975                                 if (untitled(dir)) {
976                                         activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
977                                 } else {
978                                         BIF_write_file(dir);
979                                         free_filesel_spec(dir);
980                                 }
981                                 return 0;
982                         }
983                         else if(G.qual==LR_ALTKEY) {
984                                 write_videoscape_fs();
985                         }
986                 }
987                 break;
988                 
989         case XKEY:
990                 if(textspace==0) {
991                         if(G.qual==LR_CTRLKEY) {
992                                 if(okee("Erase all")) {
993                                         if( BIF_read_homefile()==0) error("No file ~/.B.blend");
994                                 }
995                                 return 0;
996                         }
997                 }
998                 break;
999         case YKEY:      // redo alternative
1000                 if(textspace==0) {
1001                         if(G.qual==LR_CTRLKEY) {
1002                                 BIF_redo(); 
1003                                 return 0;
1004                         }
1005                 }
1006                 break;
1007         case ZKEY:      // undo
1008                 if(textspace==0) {
1009                         if(G.qual & (LR_CTRLKEY|LR_COMMANDKEY)) { // all combos with ctrl/commandkey are accepted
1010                                 if ELEM(G.qual, LR_CTRLKEY, LR_COMMANDKEY) BIF_undo();
1011                                 else BIF_redo(); // all combos with ctrl is redo
1012                                 return 0;
1013                         }
1014                 }
1015                 break; 
1016         }
1017         
1018         return 1;
1019 }
1020
1021 /* eof */