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