How many buttons does a mouse have?



  • Discovered this while porting an app to Linux. "DEBUG_ERR" is a macro that, in debug mode, terminates the app with a backtrace:


    switch (Event->Button) {
    	case MOUSE_BUT1:
    		S_SetInputStateKbModifiers(S_InputState, Event->Type,
    						KB_MODBUT1);
    		break;
    	case MOUSE_BUT2:
    		S_SetInputStateKbModifiers(S_InputState, Event->Type,
    						KB_MODBUT2);
    		break;
    	case MOUSE_BUT3:
    		S_SetInputStateKbModifiers(S_InputState, Event->Type,
    						KB_MODBUT3);
    		break;
    	default:
    		DBG_ERROR;
    }
    


  •  How old is the app? While not really smart, it might be understandable if it was form <= 2000, before those fancy mouses with extra multimedia buttons came out.

    Furthermore, and cmiiw, those thing's don't work on PS/2 ports, so it might be understandable if the app was created before USB became the standard port for mouses.



  •  It's understandable. As soon as I type switch and press space, my ide automatically adds () { and default: } for me.

     Reason being is that our coding policy states that ALL switch statements MUST have a default case to trap any unknown errors. The WTF is that should any of those errors occur, the program throws up it hands saying "An unknown error occured." or words to that effect, but at least if the program is tested enough, and one of those pops up on the screen, the testers alert us of it (or so they say they would, no one has ever had one appear yet). Our other policies are very similar, such as every "if.. else if" must have a final "else" just in case none of the conditions were suitable (which, in a lot of programs I've seen is along the lines of "else asm ("nop"); // no operation" - it's a computer program that enforces the policies after all. If it says its ok, its ok. 



  • @Carnildo said:

    "DEBUG_ERR" is a macro that, in debug mode, terminates the app with a backtrace:
     

    Don't touch that scroll wheel, as the wheel is buttons 4 and 5! The extra buttons (back/forward) would then be 6 and 7 and if you have horizontal scrolling then you have 8 and 9, AFAICT.



  • At least as far as I know, the scroll wheel is a separate axis and not a pair of buttons. Sure, it might be clickable, but that's not related to the actual scrolling part.



  •  That code doesn't use DEBUG_ERR. It uses DBG_ERROR. And TRWTF is the mouse buttons being "KB modifiers"



  • @Mole said:

     ...the testers alert us of it (or so they say they would, no one has ever had one appear yet).

    We test our test process (and testers) by "accidentally" leaving an example of such a bug (not on a final release build of course) to see if the testers catch it. If you never get an error signal from your test process, how do you know it's working ?



  • @henke37 said:

    At least as far as I know, the scroll wheel is a separate axis and not a pair of buttons. Sure, it might be clickable, but that's not related to the actual scrolling part.

    It is definitely a pair of buttons, that is as far as the X protocol is concerned (Windows have a special message for it). And did I hear anything about "porting to Linux"? However, question is what the toolkit used will pass.



  • @Bulb said:

    @henke37 said:
    At least as far as I know, the scroll wheel is a separate axis and not a pair of buttons. Sure, it might be clickable, but that's not related to the actual scrolling part.

    It is definitely a pair of buttons, that is as far as the X protocol is concerned (Windows have a special message for it). And did I hear anything about "porting to Linux"? However, question is what the toolkit used will pass.

    It's an additional axis, as far as the Intellimouse extensions to the PS/2 protocol are concerned. It has a much smaller range (-8 to +7 every sample) than the X and Y axes (-255 to +255 I think, it's been a while; may be -256 to +255), partially as it also adds support for two extra buttons (4 and 5) in the same byte. These buttons do not correspond to the direction the wheel is rolled in, however; they're proper buttons.



  • @Mole said:

    (which, in a lot of programs I've seen is along the lines of "else asm ("nop"); // no operation")

     

    Ok, this is TRWTF: using inline asm for no-ops. C has several perfectly good no-ops of its own (a single ; is enough, but (void)0; tends to be better if you want to be explicit about what you're doing), and other languages likewise have their own no-ops (I'm guessing C based on your one asm statement, but I might be wrong); why break portability just for a NOP? Not to mention, a NOP in the language you're writing will actually be /faster/ than the inline asm version, as it probably compiles into no commands rather than one command.



  • @ais523 said:

    @Mole said:

    (which, in a lot of programs I've seen is along the lines of "else asm ("nop"); // no operation")

     

    Ok, this is TRWTF: using inline asm for no-ops. C has several perfectly good no-ops of its own (a single ; is enough, but (void)0; tends to be better if you want to be explicit about what you're doing), and other languages likewise have their own no-ops (I'm guessing C based on your one asm statement, but I might be wrong); why break portability just for a NOP? Not to mention, a NOP in the language you're writing will actually be /faster/ than the inline asm version, as it probably compiles into no commands rather than one command.

     

    that's really the best TRWTF you can come up with?  How about this:

    our coding policy states that ALL switch statements MUST have a default case
     

    or even worse:

    Our other policies are very similar, such as every "if.. else if" must have a final "else"



  • Those policies strike me as reasonably useful.

    Your switch statement or if/else ladder is not executing. With a default case or final else, you have somewhere to put the breakpoint and see WTF is going on a little more quickly.

    I would go a little farther and state that if no useful work is being done in this final catch-all step, it should report an error or throw an exception as appropriate to the process.

    I don't know that I would make this a requirement in the policies. More of a helpful guideline that developers can break or ignore if the situation calls for it. I don't like bondage-and-discipline policies that MUST be followed OR ELSE.

    Insert your own silly "else" joke here.



  • @CDarklock said:

    Those policies strike me as reasonably useful.

     

    Then I hope I never work for you.



  • @campkev said:

    Then I hope I never work for you.

    What an odd thing to say. I think a policy is useful but should not be mandatory, so you never want to work for me?

    Do you honestly refuse to work for people when you don't think their recommendations are sufficiently useful?

    Because it seems to me that this is rather a serious attitude problem.



  • @Mole said:

     <snip...> our coding policy states that ALL switch statements MUST have a default case to trap any unknown errors. The WTF is that should any of those errors occur, the program throws up it hands saying "An unknown error occured." or words to that effect, but at least if the program is tested enough, and one of those pops up on the screen, the testers alert us of it (or so they say they would, no one has ever had one appear yet). Our other policies are very similar, such as every "if.. else if" must have a final "else" just in case none of the conditions were suitable (which, in a lot of programs I've seen is along the lines of "else asm ("nop"); // no operation" - it's a computer program that enforces the policies after all. If it says its ok, its ok. 

    That's pretty bad.  Obviously you don't have a policy that all code paths must be 100% tested, since some of those default case CANNOT be hit.


  • Discourse touched me in a no-no place

    @CDarklock said:

    Those policies strike me as reasonably useful.

    "I'll do this stuff if I know about it, but if I don't know about it, I'll barf, crap, and barf again." is reasonable?

    What happened to 'accept crap, understand whateverthefuckIcan from it, but emit RFC complient stuff"?

    Wasn't this the intention of all (most) the RFCs out there?

    (From previous replies I get the vague impression that default: = crash, rather than = "carry on rather reasonably, ignoring that slightly unexpected input we received earlier. After all, we are in the UK. Steed, what are you doing with that umbrella...........")



  • @CDarklock said:

    Because it seems to me that this is rather a serious attitude problem.
     

    Have you forgotten where you're posting?



  • @CDarklock said:

    @campkev said:

    Then I hope I never work for you.

    What an odd thing to say. I think a policy is useful but should not be mandatory, so you never want to work for me?

    Do you honestly refuse to work for people when you don't think their recommendations are sufficiently useful?

    Because it seems to me that this is rather a serious attitude problem.

     

    I never said I refuse to work for people when I don't find their recommendations sufficiently useful.  I was in the Army for 8 years (5 active, 3 reserves) so I have a pretty high tolerance for doing stuff that I don't find particularly useful.  However, there is a difference between refusing to work for  someong and preferring not to. And yes, I prefer not to work for people who find coding standards useful that I find to be borderline retarded. I would assume that everyone would feel the same way, but I guess there are people out there who enjoy working in that situation.  And yes, I find a coding policy that requires, recommends or even hints at putting in useless "case" or "else" statements to be borderline retarded.



  • @Zemm said:

    @Carnildo said:

    "DEBUG_ERR" is a macro that, in debug mode, terminates the app with a backtrace:
     

    Don't touch that scroll wheel, as the wheel is buttons 4 and 5!


    Guess how I found it?



  • @CDarklock said:

    Those policies strike me as reasonably useful.

    Your switch statement or if/else ladder is not executing. With a default case or final else, you have somewhere to put the breakpoint and see WTF is going on a little more quickly.

    I would go a little farther and state that if no useful work is being done in this final catch-all step, it should report an error or throw an exception as appropriate to the process.

    MISRA 2004 (for automotive and similar embedded software, at least in Europe).

    Rule 14.10 (mandatory) for if..else if, Rule 15.3 (mandatory) for switch. In both cases, the explanatory text recommends taking appropriate defensive action, but allows for an empty block with a comment justifying this decision.

    Inserting an asm nop ensures you have an instruction on which to breakpoint; as others have stated, a language NOP may be optimised away.



  • @dtech said:

    Furthermore, and cmiiw, those thing's don't work on PS/2 ports, so it might be understandable if the app was created before USB became the standard port for mouses.
    The mouse I bought in 1996 had a side button and wheel (with the wheel button being separate from the center button). It was serial, with a PS2 adapter included (extra points if you can name the mose model I bought).



  • Yes, on Windows, the scroll wheel is handled through a separate event. In X, it's mapped to buttons 4 and 5 by default.



  • @PJH said:

    @CDarklock said:

    Those policies strike me as reasonably useful.

    "I'll do this stuff if I know about it, but if I don't know about it, I'll barf, crap, and barf again." is reasonable?

    No. Recommending a catch-all "else" on an if-else ladder is reasonable. Recommending a "default" case in a switch is reasonable.

    If you do something stupid in your catch-all else or your default case, that isn't the policy's fault. It's yours, for doing something stupid. The policy doesn't say "your default case MUST puke all over the screen, take a dump on a mass storage peripheral, and puke again before terminating gracelessly". It just says you are encouraged to have a default case, but if you have a good reason not to have one, don't have one.



  • @ender said:

    The mouse I bought in 1996 had a side button and wheel

    That's nice and fancy.  The serial mouse I bought in 1997 just had four buttons.  Oddly enough, it was built with a Sun keyboard/mouse female plug, and shipped with an adapter cable to turn that into serial.  If you converted that to PS/2 and then plugged that into one of Sun's PS/2 to Sun converters, it lost about 90% of its resolution.  However, if you just found the right Sun cable, it worked just fine.  (Too bad I couldn't ever get it hooked up correctly with my ergonomic keyboard - but then, the keyboard was far more important than the mouse, since I mostly just worked out of one terminal window running screen.)

    @ender said:

    It was serial, with a PS2 adapter included (extra points if you can name the mose model I bought).

    Sigh.  I think I considered buying one, but I forget the brand and model.  It's a mini-trackball, if I'm not mistaken.  Personally, I prefer a larger trackball, such that one can manipulate it without using fingers.  But that's just me...



  • @CDarklock said:

    It just says you are encouraged to have a default case, but if you have a good reason not to have one, don't have one.

     

    If your developers need this in a coding policy, you need to fire them and hire better developers.



  • @CDarklock said:

    @PJH said:

    @CDarklock said:

    Those policies strike me as reasonably useful.

    "I'll do this stuff if I know about it, but if I don't know about it, I'll barf, crap, and barf again." is reasonable?

    No. Recommending a catch-all "else" on an if-else ladder is reasonable. Recommending a "default" case in a switch is reasonable.

    That's reasonable, considering that those two structures are basically transforms of each other.

    OTOH I once worked somewhere where, in all seriousness, it was proposed that even plain old if statements should always have an else clause.  The idea was that you wouldn't be allowed to just write

     

        if (do_something_flag)
    {
    do_something();
    }

    oh no, you have to write

     

        if (do_something_flag)
    {
    do_something();
    }
    else
    {
    /* nothing */ ;
    }

    for the purported reason of "making the intent clear".  I suggested that if we were really trying to make the intent clear through the form of the code, we should write:

     

        if (do_something_flag)
    {
    do_something();
    }
    else if (!do_something_flag)
    {
    /* don't do_something */ ;
    }

    Of course, that then becomes an if-else ladder, so then it needs to have a default clause added as well:

     

        if (do_something_flag)
    {
    do_something();
    }
    else if (!do_something_flag)
    {
    /* don't do_something */ ;
    }
    else
    {
    /* FILE_NOT_FOUND? */ ;
    }

    This was the point at which it became clear that requiring default else legs on every if would be a WTF. 



  • @Auction_God said:

    That's pretty bad.  Obviously you don't have a policy that all code paths must be 100% tested, since some of those default case CANNOT be hit.

    Worked in a place that tried to add such a policy to an existing codebase. We had a lot of failure-recovery code that would only get hit if the data was truly fucked. We did not necessarily have instances of fucked data, so that code didn't get hit, and it counted against us. And yet, every so often, a user would manage to corrupt a file in just the right way that they hit the code, which - being fairly simple failure-recovery stuff - did what it was supposed to do and made them happy. (Better to spot your bad photomask data in the processing step than, oh, after a couple of million chips have been installed in computers).

    Yes, our customers liked us much better than our bosses did. But then, our customers weren't terribly fond of our bosses, either.



  • @campkev said:

    If your developers need this in a coding policy, you need to fire them and hire better developers.

    All programming jobs can be divided into two categories.

    1. Jobs that require a highly skilled and therefore highly paid expert in software engineering.

    2. Jobs that could be done by a sufficiently large finite number of monkeys.

    The developers who do type-2 jobs need coding policies like this.



  • I think your missing something:

    Morons usually get promoted to remove them from the productive flow. They normally become leaders or management. 

    Regardless of the skill of the software engineers, management will typically hire consultants (as they usually know nothing themselves) who will not know the skill level of the software engineers, recommended an industry standard such as MISRA, get paid the big bucks for doing so, and thus the coding policy is born. All that management hear is that "these policies will ensure a faster time to market". They think "Faster time to market - bigger bonuses for me.". They don't understand the policies, and they really don't care about them either - it claimed to make more money, and thats all they are interested in.

    Of course, the real WTF is the guidelines laid down by the people who created them. But they don't really care either, as they are being paid regardless of what dribble they write, and you can guarantee that there will not be that many knowledgable people available to discuss and argue some of the absurd ideas. 

    I agree that people say some idiots need to be protected from certain language elements like C/++ pointers and memory allocation, but these people shouldn't be working in the industry to begin with, they should be left alone with Visual Basic to do the front ends, whilst the real work of the backend is done by real software engineers so don't need absurd protection from the parts of the language that make it powerful. 



  • @Mole said:

    Morons usually get promoted to remove them from the productive flow. They normally become leaders or management. 

    However, what should happen is they should be fired. Which also removes them from the productive flow, but has the further benefit of guaranteeing they stay out of it.


Log in to reply